Skip to content

fix: close finished subagents using the active namespace - #928

Open
virajchoudhary wants to merge 3 commits into
duolahypercho:mainfrom
virajchoudhary:fix/azure-subagent-close-namespace
Open

virajchoudhary wants to merge 3 commits into
duolahypercho:mainfrom
virajchoudhary:fix/azure-subagent-close-namespace

Conversation

@virajchoudhary

Copy link
Copy Markdown
Contributor

Summary

A native Sol parent configured with tool_namespace = "agents" completed a child task and issued agents.interrupt_agent for the bare target native_regression_probe. The child's FINAL_ANSWER identified /root/native_regression_probe. The router compared those strings exactly, queued a duplicate close, and injected collaboration.interrupt_agent regardless of the active namespace. Codex rejected the synthetic call with unsupported call: collaborationinterrupt_agent (parent rollout 01a0de21-371f). This is independent of the Azure ciphertext repair in #923 and is deliberately a separate branch.

The router now deduplicates bare/root-qualified child targets, selects one supported native lifecycle namespace (collaboration or agents) from the advertised inventory, or from unambiguous typed history when the inventory is genuinely empty/deferred, and uses it for SSE and JSON synthetic closes. Unknown, conflicting, partial, unrelated MCP/default-function, and flattened-looking unqualified identities fail closed without emitting a guessed call. V2 failover gating remains separate from close-namespace selection: a supported native interrupt_agent keeps v1 fallback out even when an ambiguous inventory prevents injection; spawn-only fixtures retain their prior fallback behavior. No credential handling, user configuration, or installed service source changes are included.

Reproduction and regression

  • Historical live parent: agents.spawn_agent, agents.wait_agent, agents.interrupt_agent({"target":"native_regression_probe"}), followed by a router-generated collaboration.interrupt_agent({"target":"/root/native_regression_probe"}) and Codex output unsupported call: collaborationinterrupt_agent.
  • Red tests on baseline reproduced the bare/root duplicate, wrong namespace, false suppression by unrelated MCP/default functions, inferred namespace from a literal agents__spawn_agent default-function name, and two directions of partial native-inventory ambiguity. The model-failover regression caught a v1 candidate reappearing for a reverse partial split. The focused router E2E exercises native deferred agents history through the HTTP/SSE path.

Verification

  • Serial subagent-completion, namespace-relay, and model-failover suites: 208/208 passed after the final identity/failover changes.
  • model-failover-router.test.mjs: 41/41 passed after narrowing the v2 gate to native interrupt_agent availability; four existing cross-protocol failover tests caught and guided that correction.
  • Selected native router cases, including the new deferred-namespace E2E and encrypted-handoff controls: 3/3 passed.
  • npm run check passed (syntax, seven v2 applications, 18 changelog fragments); git diff --check passed. A fresh independent verifier passed the final focused diff, including the previously failing partial-inventory and literal-name collision cases.
  • Local full Windows suite is not a green result: a four-way attempt encountered unrelated child-process contention (e.g. Antigravity spawnSync status null), and the serial attempt was stopped after 435 passing cases when an unrelated profile-switch file progressed very slowly. Please use the PR's full CI matrix for final suite evidence.

Installed service and SSE boundary

The working router installation was preserved. Its elevated read-only doctor reported the Azure route, service, internal/caller-key ACLs, and router health OK. A fresh read-only CLI session through that installed service ran Azure Sol -> curated Luna Max, a shell tool, and a bare-target close without reproducing a duplicate in that particular turn. It used the existing installed code, not this branch; no patched-service live claim is made.

Synthetic SSE close events can exhibit sequence values 3,4,2. That same ordering occurs on unchanged upstream and this branch. Current Codex's Responses SSE event parser does not deserialize sequence_number, and no failing consumer trace was found; this PR does not expand into a speculative sequencing rewrite. Reviewers using another strict SSE consumer should treat that as a separate compatibility question.

This PR does not change #923 or its Azure-only plaintext transport boundary.

A native agents parent could issue a bare-target interrupt and still receive a synthetic collaboration close for the same child. Resolve target aliases, select a proven native namespace from inventory or deferred typed history, and fail closed on ambiguous identities. Keep v2 failover gating independent from close injection.

Copy link
Copy Markdown
Contributor Author

CI triage for #928 at 7d815139: the Linux, Windows, and macOS Electron control-center jobs all fail the same unchanged renderer test, fallback-only splits do not claim account breakdown or a complete range mix, waiting for .us-chart-token-bars rect.router-fallback (10s timeout). Its fixture in apps/control-center/test/renderer.test.mjs hard-codes the fallback bucket to 2026-08-28 (around line 413). bucketRange in apps/control-center/src/lib.ts walks the last 30 UTC dates ending today; on the 2026-09-27 CI runners, that range begins 2026-08-29. The expected fallback bucket is outside the range, so the bar cannot render. This appears to be a date-expired test fixture, not a change in this PR (which touches no Control Center files). The Ubuntu and macOS full router npm test jobs have passed; Windows full router npm test is still running as I write this. I cannot rerun the failed Actions jobs through my GitHub integration (403), and I have not expanded this router PR with an unrelated UI test change.

Copy link
Copy Markdown
Contributor Author

Follow-up to the CI diagnosis above: #927 is the independent, one-file test-only fix for this exact date-expired renderer fixture. Its patch pins the page clock to 2026-09-10 before navigation; it does not change production code. #927 is currently draft with workflows action_required, so it needs maintainer review/Actions approval and merge. I will keep #928's close-namespace diff separate and draft; after #927 lands on main, #928 can be updated against that base and its full CI rerun. The Ubuntu/macOS/Windows router npm test jobs on #928 already passed.

Copy link
Copy Markdown
Contributor Author

Dependency update: #927 was closed without merging in favor of the maintainer's #929, which fixes the same rolling-date renderer fixture by deriving bucket days from today. #929 is now on main. I merged current main into this separate branch at 5407dea8; GitHub shows a mergeable seven-file #928 diff with no Control Center files. Focused checks on the combined tree passed (208/208 helper/relay/failover, 41/41 router failover, 3/3 selected native routing, and npm run check). Fresh CI is running on the new head; #928 remains draft pending its result. No production installation or #923 files were changed.

Copy link
Copy Markdown
Contributor Author

Final CI update for head a143d296 (merged with upstream main including #923 and the independent renderer fixture fix #929): CI run 2386 completed successfully. The Ubuntu, macOS, and Windows test jobs each passed npm run check and full npm test; Linux and Windows Electron control-center jobs and the unified native macOS app job passed. Provider model discovery and Grok apply_patch protocol workflows also passed. The PR-relative diff remains the same seven close-namespace files and contains no Control Center changes. The working router installation was not replaced; its read-only doctor reports the service running and healthy, but that installed source differs from this branch, so this is not a live patched-installation claim. The pre-existing SSE sequence-ordering caveat remains documented in the PR body.

@virajchoudhary
virajchoudhary marked this pull request as ready for review September 28, 2026 04:34

Copy link
Copy Markdown
Contributor Author

Additional validation on the unchanged a143d296 branch: I ran src/router.mjs as a separate loopback-only process on a disposable port with temporary router state and generated test-only local keys. Fresh Codex CLI gpt-5.6-sol Medium sessions used a session-only openai_base_url override and tool_namespace="agents"; the installed service and saved Codex config were not switched. In one canary the parent spawned a child, waited, and issued agents.interrupt_agent with the bare task name exactly once (no duplicate). In a complementary canary the parent record had a single root-qualified agents.interrupt_agent after the child result and no unsupported-call/decryption error; deterministic HTTP/SSE tests, not the live trace alone, establish router-injection attribution. Both children ran gpt-6-luna / Max under read-only sandbox, made a real exec call, completed, and returned their expected markers. The separate branch router was stopped afterward; the installed source hash and user config modification time were unchanged, and the installed service's read-only doctor remained healthy. An independent read-only review of the current seven-file diff passed Standards and Spec; it reproduced the documented pre-existing SSE sequence values 3,4,2, which remain a compatibility caveat for strict consumers rather than a new regression in this PR. This validates patched branch behavior live without claiming the patch was installed into the production router.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant