mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
e6d3629445
## Summary Frontend SDK Actions intercepted by `CopilotKitMiddleware` could disappear before the client received a tool-call lifecycle, leaving the handler uncalled and the conversation without a tool result or follow-up answer. The bridge now consumes the middleware's authoritative intercepted-call state and publishes each call through the AG-UI adapter at most once. The focused intercepted file has 8 tests and the manual AG-UI file has 30 tests; the combined run is 38 tests, with the supported-version matrix remaining CI-owned. ## Root cause `CopilotKitMiddleware.after_model()` removes frontend calls before LangChain's backend tool node and records those exact calls for final-message restoration. The previous adapter fallback ignored that state and reconstructed frontend ownership from `on_chat_model_end` plus the run's action catalog. That duplicated classification, failed when an action carried `function: None`, and never ran on Python 3.10 because the async LangChain path emitted no model callbacks there. ## Changes - `sdk-python/copilotkit/langgraph_agui_agent.py` - publish middleware-classified calls from the existing chain-state event path - reuse one lifecycle materializer and the parent adapter's per-run ID ledger - remove raw model-end/action-schema reconstruction and the duplicate logger assignment - `sdk-python/tests/test_intercepted_tool_call_events.py` - exercise the real `create_agent(..., tools=[])` middleware and AG-UI path in streaming and non-streaming modes - cover exactly-once identity, Python 3.10 restoration, multiple IDs, metadata opt-out, backend negative space, and malformed action/state shapes ## What is not changed - backend tools still use LangChain's normal tool node - `after_agent` still restores intercepted calls into the final assistant snapshot - tool-call emission metadata still controls streamed lifecycle visibility - explicit `copilotkit_emit_tool_call()` calls keep their existing caller-controlled semantics ## Related PRs and Issues Closes #4342. ## Test plan - [x] Focused intercepted SDK Action regression file, 8 passed on Python 3.12. Covers the real `create_agent(..., tools=[])` path, streaming, restoration, mixed ownership, chain metadata suppression, malformed state, and action-shape isolation. - [x] Existing manual tool-call materialization file, 30 passed on Python 3.12. - [x] Combined focused selection, 38 passed on Python 3.12, counted once rather than adding a second 38-test total. - [x] Ruff check and format check on both changed files, both passed. - [ ] Python SDK CI matrix green on Python 3.10, 3.11, 3.12, 3.13, and 3.14