Repository navigation
fix(sse): stamp encrypted_function_args:[] on collaboration function_calls (#14154) - #14447
Merged
diegosouzapw merged 1 commit intoSep 22, 2026
Merged
Conversation
…calls (#14154) Codex MultiAgent V2 treats a collaboration function_call's arguments as backend ciphertext unless the item carries an explicit encrypted_function_args: [] plaintext-delivery marker (codex-rs ToolCall::direct_source). The vendored ChatGPT-web bridge already emitted this marker for spawn_agent/send_message/followup_task via its own local plaintextCollaborationFields() helper, but the three general Responses-API output emitters used for every non-OpenAI chat-format upstream never did: the streaming translator (translator/response/openai-responses.ts), the non-streaming client translator (handlers/chatCore/nonStreamingClientTranslate.ts), and the Responses transformer (transformer/responsesTransformer.ts). Extracts the marker into a shared translator/response/openai-responses/collaborationPlaintextMarker.ts helper (bridge.ts now imports it instead of keeping its own copy) and a functionCallIdentity.ts helper that composes the existing #7936 identity restoration with the new marker for the streaming translator. Wires the Responses transformer with the same requestToolIdentityMap plumbing the other two emitters already had (it previously restored neither namespace nor the marker at all), threading the ledger through from handlers/responsesHandler.ts before handleChatCore deletes the side channel.
diegosouzapw
force-pushed
the
fix/14154-encrypted-args-placeholder
branch
from
September 22, 2026 08:23
944478c to
2e2c76e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #14154
Root cause
Codex MultiAgent V2 treats a collaboration
function_call's arguments as backend ciphertext unless the item carries an explicitencrypted_function_args: []plaintext-delivery marker (codex-rsToolCall::direct_source). The vendored ChatGPT-web bridge (open-sse/vendor/codex-chatgpt-web/bridge.ts) already emitted this marker forspawn_agent/send_message/followup_taskvia its own localplaintextCollaborationFields()helper, but the three general Responses-API output emitters used for every non-OpenAI chat-format upstream never did: the streaming translator (open-sse/translator/response/openai-responses.ts), the non-streaming client translator (open-sse/handlers/chatCore/nonStreamingClientTranslate.ts), and the Responses transformer (open-sse/transformer/responsesTransformer.ts) — the last of which additionally never restored the{namespace, name}identity tuple at all.Fix
open-sse/translator/response/openai-responses/collaborationPlaintextMarker.tsmodule (bridge.tsnow imports it instead of keeping its own local copy — no behavior change to the bridge's 3 existing call sites).open-sse/translator/response/openai-responses/functionCallIdentity.ts, composing the existing [BUG] fix(providers): Responses→Chat namespace flattening is one-directional — return-path tool_call names never recovermcp__prefix, breaking every namespace sub-tool (1mcp, ctx, multi_agent, etc.) #7936{namespace, name}identity restoration with the new marker, used by the streaming translator'sfunction_callclose.nonStreamingClientTranslate.ts: applies the marker after identity restoration in its output-item loop (covers bothresponse.output_item.doneand theresponse.completedoutput array, since the same item objects are reused).responsesTransformer.ts: had no namespace/name identity restoration at all — wired it to the sameresolveRequestToolIdentity/requestToolIdentityMapplumbing the other two emitters already use, then applied the marker on top. The mutatedfuncItemis recorded via the existingrecordCompletedItem()call, soresponse.completed's output array picks up the same fix automatically.responsesHandler.ts: captures the request-side_namespaceToolIdentityMapledger beforehandleChatCoredispatches (that call deletes the side channel viaextractRequestToolIdentityMap()), then threads it intocreateResponsesApiTransformStream(...).Additive-only: the marker is gated on
namespace === "collaboration" && name in {spawn_agent, send_message, followup_task}, so no non-collaboration tool call or OpenAI-native upstream is affected.Regression test
tests/unit/issue-14154-responses-encrypted-function-args-marker.test.ts(3 cases: collaborationspawn_agent, a non-collaboration namespace, and a bare non-namespaced call).RED (pre-fix, verified via
git apply -Ron the fix diff, no stash used):(The namespace/name sanity assertion passed even pre-fix, proving the repro exercises the real identity-restoration path and not a harness miss.)
GREEN (post-fix):
Gates run
npm run typecheck:core→ exit 0node scripts/check/check-open-sse-typecheck.mjs→ OK, 0 errors within frozen baselinenpx eslint --suppressions-location config/quality/eslint-suppressions.json <every changed file>→ exit 0node scripts/check/check-file-size.mjs→ OK, no files touched exceed their frozen baseline (the two new leaf modules avoided growing the frozenopenai-responses.tsgod-file)node scripts/check/check-complexity-ratchets.mjs --base-ref origin/release/v3.8.51→ OK, 0 new violations in touched files vs base (cyclomatic 15/15, cognitive 8/8)node scripts/check/check-changelog-integrity.mjs→ OK, no base bullets lost (branch fast-forwarded onto the current release tip first — see Notes)Existing tests
Ran the full namespace-identity / responses-translator / responses-transformer suite touching these files (85 tests, 0 failures), including
translator-resp-openai-responses-namespace-identity.test.ts,9780-namespace-identity-pivot.test.ts,8295-namespace-leaf-collision.test.ts,non-streaming-client-translate.test.ts,responses-transformer*.test.ts,chatcore-request-tool-identity-contracts.test.ts,chatcore-response-toolname-map-recovery.test.ts,issue-12996-responses-streaming-namespace-followup.test.ts,request-tool-identity-dotted-alias.test.ts,responses-chat-namespace-qualified-name.test.ts,responses-chat-namespace-identity-map.test.ts. No test needed alignment — all pre-existing assertions about{namespace, name}restoration hold unchanged; the new field is additive.Notes
This branch was resumed from a previous worker's uncommitted partial work (killed mid-run by a usage-limit cutoff). The partial diff was audited file-by-file against the plan below and matched it — no drive-by changes, no out-of-scope files. The one gap found (
check-changelog-integrity.mjsreported 474 "lost" bullets purely because the worktree's branch tip was several commits behind the ever-advancing livingCHANGELOG.mdonrelease/v3.8.51) was resolved with a clean fast-forward merge oforigin/release/v3.8.51(single commit, no conflicts, zero overlap with the files this fix touches) rather than editingCHANGELOG.md.Plan-file:
_tasks/pipeline/bugs/2-implementing/14154-fix-api-responses-translator-omits-the-encrypted-function-args.plan.md