feat(responses): relay native multi-agent function-result injection - #4858
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
⏳ DRAFT
What to do
Review readiness checklist
2/4 boxes ticked. Automatic draft conversion failed. Please convert this pull request to a draft manually until every box above is ticked. |
|
Publication readback confirmed New-head upstream checks are
Maintainer action is needed for those checks. Parent #4782 has been linked to this follow-up; its code and readiness state were left unchanged. Keep this PR Draft pending the documented parent integration, broader CI, independent review and live compatible-client/backend validation. |
리뷰 · 우선순위 56 / 80이 PR은 Draft이고, 아직 열린 부모 #4782(네이티브 mid-turn steering) 위에 얹은 하는 일은 이렇습니다. 기본값 꺼짐 설정 키는 라인 src/server/index/websocket-handler.ts - inject/steer/create continuation이 모두 메인테이너의 판단이 필요한 지점
너의 추천 이 댓글은 grok-bot이 작성했습니다 |
리뷰 · 우선순위 70 / 80이 PR은 Draft입니다. #4782(네이티브 mid-turn steering) 위에 얹는 follow-up으로, 기본값 꺼짐인 핵심 모듈은 범위 가드도 분명합니다. 초기 create에 작성자 워크플로(run 35178934345)는 포커스 세트 459 pass × 3 OS, typecheck·privacy·structure·docs build를 주장하지만, 본인이 “Keep Draft / full matrix 아님 / live Astra·App·CLI 미검증”이라고 적었습니다. 경로 NativeInjectionChannel - ack가 response 단위라 FIFO 직렬화·in-flight 단일 제출은 프로토콜에 맞다. 연결 로컬 상태(calls/queue/seen) 누수와 90s ack 타이머가 운영에서 실제 상한으로 도는지 Ready 전에 한 번 더 보면 좋다. 메인테이너의 판단이 필요한 지점
너의 추천
이 댓글은 grok-bot이 작성했습니다 |
|
Implemented the next supported extension as #4861, Draft, head The extension adds rich text/image/file and custom-tool saved-result continuations, explicit MCP approval/refusal continuations, call-type/caller provenance matching, execution-mode owner selection, and preservation of hosted/agent items omitted from sparse terminal output. It also refuses premature same-parent continuation rather than letting it cancel the active owner. Exact-source project Bun 1.4.0 verification passed on Linux/macOS/Windows: 515 pass / 1 existing conditional skip / 0 fail per OS, including 56 added tests; type/privacy/architecture/size checks and the 449-page documentation build passed. Run/artifacts: https://github.com/luvs01/opencodex/actions/runs/35182258776 . Negative controls reproduced the missing behavior before the fix. The child description links the extension-only 27-file delta. Please integrate the parent chain first. Latest-base reconciliation, full upstream CI, independent review and live compatible-client/backend testing remain separate gates; no paid API use, tool execution or user runtime deployment was performed. |
|
Author follow-up on the review points, in 7a9a6d2:
|
|
Reviewed as stage 2 of the stack, against the integration contract in #4882 ( A failed In
if (this.everAttached) throw new Error("Native injection transport is already owned.");
Nothing unsafe happens — no credential moves, no acceptance is invented, and the HTTP turn is a legitimate turn — so this is not a blocker. But the fallback is being taken for a reason the comment above it explicitly does not cover, and a client that asked for a multi-agent injection turn gets a non-injection turn with no signal until it tries to use the feature. Catching the
Separately, for the record rather than as a change request: the eligibility widening here is the stack's only route expansion, and it is the leg with the strongest documentation behind it. The exactly-pinned |
|
Fixed in
Noted on the eligibility widening — the pinned |
…lict fix) into steering-stability # Conflicts: # src/server/index/websocket-handler.ts # src/server/responses/codex-ws-exchange.ts
|
Re-cascaded onto new parent #4782 head |
Follow up on lidge-jun#4782 with a separate default-off injection owner, bounded serial acknowledgements, same-account caller continuations, accepted-result replay and regression coverage.
The field now holds either a steering or an injection owner, so the generic name matches the NativeResponseControl contract. Move the response-ownership markers next to the shared interface. Behavior is unchanged.
…tead of falling back to HTTP
01f813d to
92ec363
Compare
…ve hosted output Extend lidge-jun#4858 with rich/custom results and explicit approval continuations, execution-mode selection, structural replay matching and lossless sparse-terminal reconciliation. Keep unsupported inject and mixed-mode operations fail-closed.
…ed output (#4861) * feat(responses): support typed native result continuations and preserve hosted output Extend #4858 with rich/custom results and explicit approval continuations, execution-mode selection, structural replay matching and lossless sparse-terminal reconciliation. Keep unsupported inject and mixed-mode operations fail-closed. * fix(responses): reject continuations that omit pinned injection settings * fix(responses): refund exact injection batch bytes and use site-relative docs link * test(responses): follow the nativeControl field rename in continuation assertions --------- Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Summary
Follow-up to #4782, which has landed on dev as
519db59b3. This adds actualresponse.injecttransport, not just an unsupported-message error. The maintainer rebased this branch onto dev after the parent landed, so the PR diff is now the injection delta alone.Full delta versus the rebase base (dev
41f1832f6): luvs01/opencodex@41f1832...92ec363codexNativeInjectionand a separate native injection owner. Forward saved developer-function results on the original selected account and physical WebSocket. Initialmulti_agent.enabled: trueis required; no capability is inferred from a model name.function_call_outputonly. Reserve each call before submission, copy queued inputs, and reject duplicate, foreign, unsupported or mixed steering/injection input explicitly.response.inject.created/response.inject.failedevents; validate acknowledgement identity, sequence and failed-input correlation. Do not synthesize acceptance.response_already_completedwith its saved outputs. A caller-sent continuation with the same parent, lane and settings supplies outstanding results once on the same account/socket and rechecks normal pacing/auth guards. The proxy never manufactures a recovery create. Accepted outputs cannot be submitted again.responses_multi_agent=v1only to the public API connection, preserving configured beta tokens. Do not move subscription traffic to a separately billed API. Translated providers, arbitrary gateways, sidecars, Combo and HTTP fallback do not gain injection support.Protocol reference: https://developers.openai.com/api/docs/guides/responses-multi-agent (checked 2026-09-17). Public API documentation is not evidence that a particular ChatGPT subscription backend or Codex App/CLI build implements the same execution mode.
Configuration and bounded scope
Merge into the existing OpenCodex configuration and restart before a fresh turn:
{ "websockets": true, "codexNativeInjection": true }The initial create must explicitly include
"multi_agent": { "enabled": true }. Public API use additionally requires anopenai-responsesprovider at exactlyhttps://api.openai.com/v1, normal API-key authentication andupstreamWebsocket: true; use its configured model prefix. No real API requests are made by this PR or its tests.This first implementation is for string-valued developer-function results. Rich result arrays, custom/hosted tool results and simultaneous
response.steerin an injection-owned turn are explicitly unsupported. The existing steering-only route remains available independently.Limits: 32 queued/in-flight injection frames, 8 MiB queued payloads, 1,024 advertised calls / 256 KiB call identities, 32 MiB replay history and 128 responses per owned connection. A sent injection has an absolute 90-second acknowledgement deadline that unrelated stream activity cannot extend. Saved-result waits are capped at 30 minutes. Existing wire and stall bounds still apply. Disable
codexNativeInjectionand restart to roll back without deleting account or conversation files.Verification
Exact source and publication
92ec3630dc6b1d053010bd79d09ca268791d55d8— maintainer rebase onto dev41f1832f6after feat(responses): preserve native mid-turn steering over WebSocket #4782 landed; the branch commits (attach-conflict fail-fast,nativeControlnaming, ws-failure-stage test move) are preserved. Pre-rebase head was01f813d30(re-cascaded onto feat(responses): preserve native mid-turn steering over WebSocket #4782 heada3922b9cf, clean merge). Earlier branch commits fix the reviewer-flagged attach seam (anativeControl.attachownership failure now fails the turn visibly instead of falling back to HTTP) and move the oversized upstream-handler cases intotests/responses/ws-failure-stage.test.tsto satisfy the file-size ratchet. On the pre-merge head78e1a8706,bun run typecheckpassed, the file-size ratchet passed,ws-failure-stage.test.tspassed 18 tests andws-upstream.test.tspassed 126 tests locally (Bun 1.4.2); typecheck was not separately re-run on the merge head.310a428ad9118108a0b8256e339c15ee163dccde(rebased head); earlier hosted verification ran on pre-rebase tree911d26890441dcb105e7b8391b1b94338474711d.519db59b3(2026-09-17); the recorded parent heada3922b9cfis superseded.41f1832f6a893547f253d728bd93607e1793dd13.All verification jobs reconstructed and asserted the exact commit/tree. Their downloaded artifact digests and source identities were checked. A separate publisher, gated on all three operating-system jobs and the documentation build, pushed only the verified new contributor branch without force. It executed no application/dependency code with write credentials. Parent and integration branches were left unchanged.
Completed current-head checks
Run: https://github.com/luvs01/opencodex/actions/runs/35228684916 (in progress on the published head; prior head runs: 35224514834, 35212665696, 35178934345).
01f813d30onto parenta3922b9cf(carrying upstreamdeveca65bd35): clean merge; typecheck was not separately re-run on the merge head — the pre-merge head78e1a8706passed typecheck, the file-size ratchet,ws-failure-stage.test.ts(18 tests) andws-upstream.test.ts(126 tests) locally.Each focused run covers 12 test files and 3,001 assertions. The conditional skip is the existing older-runtime HTTP fallback case, not an injection case. Tests exercise the actual handler/auth/dispatch/relay with synthetic WebSockets and credentials; public API and ChatGPT credential destinations are asserted, and unexpected HTTP fetches fail the fixture. They do not call a live model.
Coverage includes actual frame delivery, terminal-before-ack, late asynchronous results, same-socket caller continuations, queue order, duplicate calls, mismatched/duplicate acknowledgements, two-connection isolation, warmup/disabled paths, unknown delivery, disconnect cleanup, absolute deadlines, size/count limits, replay ordering/deduplication and log privacy.
Before publication, three focused missing-transport regressions were demonstrated failing with the parent handler restored, then the implementation was restored byte-for-byte. The first broader local run caught missing source-oracle registrations for the new modules; those registrations were fixed before the successful three-platform runs. No assertion or size limit was relaxed.
Reproduction:
Remaining gates / not claimed
Checklist
The implementation was checked against existing admission/auth contracts, data-handling constraints and privacy regressions. The unchecked security box reserves independent review of the new long-lived control surface.
Review readiness checklist
Remaining gates: fork CI on the rebased head
92ec3630dis in progress — https://github.com/luvs01/opencodex/actions/runs/35234973443. Forkworkflow_dispatchruns always cancel on the 30-minutemacos-controljob; the meaningful signal is every other lane green.