fix(computer-use): stop dropping tool name when action is present#217
Conversation
d923bc9 to
fae0a85
Compare
_derive_connector_type(tool_name, action) discarded tool_name whenever
action was present, returning only "computer_use.{action}" — so every
actioned Computer Use tool call collapsed to the same connector_type
shape regardless of which tool (computer vs. any other actioned tool)
triggered it.
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.
_derive_connector_type is removed; ComputerUseGovernor now passes
connector_type=tool_name and tool=action directly to mcp_check_input,
so neither value is discarded. tool_name is chosen as the
connector_type-equivalent (rather than a fixed "computer_use" literal)
because it matches the rest of the SDK's convention of bare category
names for connector_type (e.g. "postgres", "snowflake") with no
namespace prefix, and because action already varies meaningfully within
a single tool (e.g. "left_click" vs "screenshot" for "computer") while
tool_name is the more stable partition key. check_result() has no
action available at its call site, so tool is left unset there,
matching its pre-existing behavior of not being able to distinguish
sub-actions on output checks.
Signed-off-by: Gregory Zak <gzak@getaxonflow.com>
fae0a85 to
92fb7cf
Compare
|
R3 review (master + independent hostile pass). The core fix is verified correct — previously BLOCKER — CI is red
MEDIUM — semantic drift needs an epic-level ruling before mergeThis PR sends MEDIUM — stale contract claims + #216 collision
MEDIUM — hard policy break with no escape hatch
|
|
Delta note — semver (net-new, strongest case in the cluster). This drops the Also still open at head: CI is RED (falsey-clobber baseline line-drift, 12 new + 12 stale — baseline never regenerated in-PR); the |
…ULING 1)
Apply epic #2905 RULING 1 to ComputerUseGovernor so the `tool_name` audit
column means the tool name in every adapter:
- connector_type = the constant "computer_use" connector/domain marker
- tool = the tool NAME ("computer"/"bash"/"text_editor"), never the action
- the action stays in the serialized `statement` (unchanged) — it is NOT
placed in `tool`, nor in `operation` (agent-api constrains operation to
the enum {query, execute})
check_result() now sends the same identity on the response plane so request-
and response-plane rows correlate. Removes _derive_connector_type.
BREAKING: the connector_type wire value changes shape; policies scoped to the
old concatenated value (e.g. "computer_use.left_click", a bare tool name, or a
computer_use.* prefix) stop matching. Re-scope to connector_type=="computer_use"
plus the tool field. No connector_type_fn/tool_fn escape hatch on this adapter.
Requires platform v9.10.0+ to consume `tool` on check-input; check-output does
not consume it on any released version yet (#2955).
Reconciles the shared client.py/types.py/wire_shape_baseline.json hunks with
PR #216 to byte-identical, corrected text (#2916/c8df2006b merged, first
released in v9.10.0); regenerates .lint_baselines/falsey_clobber.json (CI).
Refs #2910, epic #2905.
Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
…2905)
Mark the LangGraph server/tool de-concatenation as a BREAKING change (the
connector_type wire value changes from "{server}.{tool}" to the bare server
name) and document the migration:
- Changelog: move to "Changed (BREAKING)", require a major SDK bump, add the
policy re-scope note (connector_type_fn is the compat lever), the custom-fn
statement-shape change, the missing-server fail-closed edge, and the
platform-version pins (tool consumed on check-input at v9.10.0+; check-output
tracked by #2955).
- Add the missing-server edge test: empty server_name -> connector_type=""
-> platform 400 -> ConnectorError (fail-closed); document + pin the wire.
- Reconcile the shared client.py/types.py/wire_shape_baseline.json hunks with
PR #217 to byte-identical, corrected text (#2916/c8df2006b merged, first
released in v9.10.0); thread `tool` through the check_tool_input/
check_tool_output aliases too. Declare the #216-before-#217 merge order.
- Regenerate .lint_baselines/falsey_clobber.json (line-shift only; CI green).
Refs #2906, epic #2905.
Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
…e-tool-name-fix Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com> # Conflicts: # .lint_baselines/falsey_clobber.json # CHANGELOG.md
Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
|
Follow-up commits (WS-DECONCAT): applied epic #2905 RULING 1 — |
|
Master independent R3: CLEAR-FOR-SET (code). RULING 1 verified correct: MEDIUM (non-code) — update this PR's description. The body still describes the PRE-RULING-1 mapping ( |
Bump pyproject.toml + axonflow/_version.py to 9.0.0 and finalize the tool-identity content under ## [9.0.0] - 2026-07-18 (banner dropped). The LangGraph and Computer Use de-concatenation is described in a single combined entry (byte-identical across #216/#217 — merge #216 first). Changelog scrubbed of internal issue/PR numbers and internal review terminology; minimum platform stated as versions (check-input tool = platform v9.10.0+, response-plane tool = platform v9.11.0+). Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
Bump pyproject.toml + axonflow/_version.py to 9.0.0 and finalize the tool-identity content under ## [9.0.0] - 2026-07-18 (banner dropped). The LangGraph and Computer Use de-concatenation is described in a single combined entry (byte-identical across #216/#217 — merge #216 first). Changelog scrubbed of internal issue/PR numbers and internal review terminology; minimum platform stated as versions (check-input tool = platform v9.10.0+, response-plane tool = platform v9.11.0+). Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
|
Release-ready follow-up: bumped the version to 9.0.0 and finalized the tool-identity content under a real Python: #216 and #217 share one byte-identical, combined |
|
Master re-R3 of the v9.0.0 finalize delta: CLEAR-FOR-SET. Version file 8.5.1 → 9.0.0; correct Keep-a-Changelog shape (empty |
) * fix(langgraph): stop concatenating server/tool into connector_type 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> * fix(langgraph)!: de-concatenate server/tool as breaking major (epic #2905) Mark the LangGraph server/tool de-concatenation as a BREAKING change (the connector_type wire value changes from "{server}.{tool}" to the bare server name) and document the migration: - Changelog: move to "Changed (BREAKING)", require a major SDK bump, add the policy re-scope note (connector_type_fn is the compat lever), the custom-fn statement-shape change, the missing-server fail-closed edge, and the platform-version pins (tool consumed on check-input at v9.10.0+; check-output tracked by #2955). - Add the missing-server edge test: empty server_name -> connector_type="" -> platform 400 -> ConnectorError (fail-closed); document + pin the wire. - Reconcile the shared client.py/types.py/wire_shape_baseline.json hunks with PR #217 to byte-identical, corrected text (#2916/c8df2006b merged, first released in v9.10.0); thread `tool` through the check_tool_input/ check_tool_output aliases too. Declare the #216-before-#217 merge order. - Regenerate .lint_baselines/falsey_clobber.json (line-shift only; CI green). Refs #2906, epic #2905. Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com> * docs(changelog): add blank line before ### Added (MD022) Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com> * release: finalize v9.0.0 — version bump + clean [9.0.0] changelog Bump pyproject.toml + axonflow/_version.py to 9.0.0 and finalize the tool-identity content under ## [9.0.0] - 2026-07-18 (banner dropped). The LangGraph and Computer Use de-concatenation is described in a single combined entry (byte-identical across #216/#217 — merge #216 first). Changelog scrubbed of internal issue/PR numbers and internal review terminology; minimum platform stated as versions (check-input tool = platform v9.10.0+, response-plane tool = platform v9.11.0+). Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com> --------- Signed-off-by: Gregory Zak <gzak@getaxonflow.com> Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com> Co-authored-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
Summary
_derive_connector_type(tool_name, action)inaxonflow/adapters/computer_use.pydiscardedtool_namewheneveractionwas present, returning onlyf"computer_use.{action}". Every actioned Computer Use tool call (e.g.computerwithaction="left_click") collapsed to the sameconnector_typeshape regardless of which actual tool triggered it —connector_typecouldn't distinguish tool identity for any actioned tool.Fixes #2910 (epic #2905). Uses the platform's two-field
(server, tool)identity contract (platform sub-issue #2904, merged to axonflow-enterprise asc8df2006band first released in platform v9.10.0).Design decision (epic #2905, RULING 1)
Per RULING 1 on the epic,
toolcarries the tool name in every adapter so thetool_nameaudit column means the same thing regardless of which adapter emitted it. There were three pieces of information: the"computer_use"domain marker,tool_name("computer"/"bash"/"text_editor"), andaction("left_click"/"screenshot", present only for some tools). They map as:connector_type= the constant"computer_use"— the connector/domain marker, analogous to the LangGraph adapter'sconnector_type = server_name. Restoring"computer_use"as the connector value also keepscomputer_use-scoped policies matchable onconnector_type.tool=tool_name(e.g."computer") — the tool NAME, never the action. This is what makes the identity coherent with the LangGraph adapters (wheretoolis also the tool name).actionstays instatement—json.dumps(tool_input)already serializes theactionkey, and the policy engine evaluates the statement. The action is not placed intool, and not inoperation:operationis a spec-declared enum{query, execute}inagent-api.yaml, so putting"left_click"there would violate our own published contract.operationstays"execute"._derive_connector_typeis removed.check_result()sends the same identity on the response plane (connector_type="computer_use",tool=tool_name) so request- and response-plane rows correlate — the platform doesn't yet consumetoolon check-output (#2955), so it is sent forward-compatibly.This is a breaking change (the
connector_typewire value changes shape) and must ship as a major SDK bump; this adapter has noconnector_type_fnescape hatch, so re-scoping policies is the only migration path — see the CHANGELOG.Also (shared with #2906, byte-identical hunks — merge #216 first):
mcp_check_input/mcp_check_output(and thecheck_tool_input/check_tool_outputaliases), async and sync, gain an optionaltool: str | None = Noneparameter, sent on the wire only when non-empty.MCPCheckInputRequest/MCPCheckOutputRequestgain a matching optionaltoolfield.tests/fixtures/wire_shape_baseline.jsonacknowledgestoolas an SDK-superset field on both request models (the publicagent-api.yamlspec hasn't declared it yet, though the agent consumes it on check-input since v9.10.0).Test plan
TestConnectorTypeToolSplitto assert the RULING-1 mapping:connector_type == "computer_use"(constant) andtool ==the tool name for actioned and non-actioned tools; that two calls to the same tool with different actions carry the same(connector_type, tool)identity while the differing action lives instatement; and thatoperationstays"execute"(spec-compliant, action never smuggled in).TestCheckToolUse/TestCheckResultassertions to the new mapping (connector_type="computer_use", tool=tool name on both planes).runtime-e2e/computer_use_tool_name_split/test.pyfor the new mapping (wire-body capture against a live agent; action asserted present instatement).pytest tests/test_computer_use.py— 30 passed; full suite — 1052 passed, 29 skipped.ruff check/ruff format --checkon changed files — clean;mypy axonflow— no new errors..lint_baselines/falsey_clobber.json(line-shift only). Mergedorigin/main(thecaller_namelegs) in non-destructively; CI green, MERGEABLE/CLEAN.