fix(langgraph): stop concatenating server/tool into connector_type#216
fix(langgraph): stop concatenating server/tool into connector_type#216gzak wants to merge 1 commit into
Conversation
0af0b86 to
5e641fd
Compare
MCPCheckInputRequest/MCPCheckOutputRequest now carry a genuine two-field (server, tool) identity contract (epic #2905, platform sub-issue #2904). Client.mcp_check_input/mcp_check_output gain a `tool` parameter sent as its own wire field instead of being folded into `connector_type`. mcp_tool_interceptor's default connector-type resolution now sends connector_type=request.server_name and tool=request.name as two separate values instead of the dotted "server.tool" string, and this holds even when a caller supplies a custom connector_type_fn. In tool_output_wrapper, ToolNode's call_request carries no server/origin info to improve connector_type's default beyond the bare tool name, but the tool name itself is now always forwarded via the new `tool` field rather than only living inside connector_type. Signed-off-by: Gregory Zak <gzak@getaxonflow.com>
5e641fd to
ad99e32
Compare
|
R3 review (master + independent hostile pass; platform contract verified on enterprise origin/main). Fix direction is right and the tests are strong (both-fields, custom-fn tool preservation, alias forwarding sync+async, real wire capture incl. legacy tool-omitted). Must-fix before this can join the set: BLOCKER — CI is red
MEDIUM — coordinate with #217 (guaranteed conflict)Both PRs edit the same hunks of MEDIUM — changelog gaps (cluster-wide asks)
LOW
Also note the response-plane gap filed from this review: the platform's check-output schema has no |
Summary
The platform's MCP check-input/check-output schema now has a genuine two-field
(server, tool)identity contract (epic #2905, platform sub-issue #2904 — R3-approved, CI-green, not yet merged to axonflow-enterprise but the schema is finalized). Previously this SDK only hadconnector_type, which forced callers to smuggle the tool name in by concatenating it ("server.tool") or dropping it entirely.Fixes #2906 (epic #2905).
axonflow.client.Client.mcp_check_input/mcp_check_output(async and sync) gain atool: str | None = Nonekeyword-only parameter, sent as its owntoolfield on the wire body only when non-empty — same optional-field convention already used forclient_id/tenant_id/etc.MCPCheckInputRequest/MCPCheckOutputRequestpydantic models gain a matching optionaltoolfield.axonflow/adapters/langgraph.py:mcp_tool_interceptor's default connector-type resolution no longer returnsf"{server_name}.{name}". It now sendsconnector_type=request.server_nameandtool=request.nameas two separate values. This holds even when a caller supplies a customconnector_type_fn— the tool name is never folded back intoconnector_typeand is never dropped.tool_output_wrapper():ToolNode'scall_requestdict (from LangGraph'sawrap_tool_call) carries no server/origin metadata to improve on the existingconnector_typedefault (bare tool name) — confirmed by inspecting the call site; there is no tool-registry reference available to derive a better value. Rather than continue using the bare name asconnector_typewith no way to recover the tool identity, the wrapper now also sends the bare name astoolon every call, so tool identity survives explicitly instead of being implicit/ambiguous inconnector_type.MCPInterceptorOptionsdocstring and both methods' docstring examples to show the two-field form instead of the oldconnector_type_fn=lambda call: f"local.{call['name']}"pattern.tests/fixtures/wire_shape_baseline.json: acknowledgedtoolas an SDK-superset field onMCPCheckInputRequest/MCPCheckOutputRequest(mirrors the existingcontent_typeentry) until #2904 merges to axonflow-enterprise and the OpenAPI spec catches up. Per CONTRIBUTING.md's baseline burndown policy — justified rather than burned down, since it's blocked on the platform-side PR landing.Test plan
tests/test_langgraph_adapter.pyassertingconnector_typeandtoolare sent as two separate, correct values (not concatenated, not dropped) for bothmcp_tool_interceptor(default and customconnector_type_fn) andtool_output_wrapper(default and customconnector_type_fn).pytest tests/test_langgraph_adapter.py tests/test_langgraph_wrapper.py— 102 passedpytest— 1050 passed, 29 skippedruff check/ruff format --checkon changed files — cleanmypy axonflow— no new errors (one pre-existing unrelated error inheartbeat.py)