Skip to content

fix(proxy): strip replayed tool call namespaces - #1578

Open
codemoo wants to merge 6 commits into
Soju06:mainfrom
codemoo:fix/replayed-namespaced-function-call
Open

fix(proxy): strip replayed tool call namespaces#1578
codemoo wants to merge 6 commits into
Soju06:mainfrom
codemoo:fix/replayed-namespaced-function-call

Conversation

@codemoo

@codemoo codemoo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Strip local-only namespace metadata from replayed Responses tool-call items at the final upstream wire boundary while retaining the original namespaced items for local replay deduplication. This prevents Codex histories from repeatedly failing with Unknown parameter: input[*].namespace over both HTTP and WebSocket transports.

Type of change

  • fix: — bug fix (no behavior change beyond the bug)
  • feat: — new user-facing feature or capability
  • refactor: — internal refactor (no behavior change, no API change)
  • docs: — documentation only
  • chore: / ci: / build: — tooling, CI, packaging
  • test: — test-only change
  • Breaking change

Linked issue: Refs #1450 — partial fix for the replayed input[*].namespace failure family. The separate replayed local item_* ID validation failures reported in #1450 remain out of scope, so this PR intentionally does not auto-close the issue.

Root cause and scope

Responses request parsing intentionally preserves unknown fields for forward compatibility and local proxy behavior. Current Codex histories can replay namespaced function_call and custom_tool_call items, but the upstream Responses input schema rejects namespace on historical call items. Once such an item is retained in history, forwarding it unchanged makes every retry fail at the same input index.

The fix is deliberately type-aware and copy-on-write:

  • Strip namespace only from recognized replayed call items: function_call, custom_tool_call, and apply_patch_call.
  • Normalize only the copied outbound payload; keep the validated request input unchanged so local dedupe and continuity logic retain namespaced call identity.
  • Do not recursively remove namespace, which would corrupt reserved top-level type: "namespace" tool definitions.
  • Do not alter replayed item_* IDs in this PR.

OpenSpec

  • This PR includes / updates an OpenSpec change
  • Not applicable — bug fix that matches the existing spec
  • Not applicable — docs / CI / chore only
  • This PR touches a codex-faithful path (request/response shape and response.create framing) and preserves upstream-equivalent behavior

Change directory: openspec/changes/fix-replayed-namespaced-function-call/

The change records the wire-compatibility requirement, local-identity invariant, HTTP/compact/WebSocket scenarios, design trade-offs, and completed implementation tasks.

Changes

  • Add a shared outbound sanitizer for namespaced replayed tool-call input items.
  • Preserve every field except the unsupported per-item namespace on the upstream copy.
  • Cover standard and compact request serialization.
  • Cover public HTTP /v1/responses forwarding.
  • Cover configured OpenAI-compatible Responses model-source forwarding without removing source-supported fields.
  • Cover the actual backend Codex WebSocket response.create frame.
  • Preserve namespace identity during HTTP bridge account-neutral replay classification so cross-account movement remains fail-closed.
  • Retain existing byte-preservation coverage for top-level namespace tools.

Simplicity

  • Works with zero configuration
  • No new required setup step
  • New setting(s) and why each can't be a default: None.
  • No dependency, migration, schema, README, .env.example, dashboard, or navigation changes

Test plan

PYTHONDONTWRITEBYTECODE=1 .venv/bin/python -B -m pytest -p no:cacheprovider \
  tests/unit/test_openai_requests.py \
  tests/integration/test_proxy_responses.py \
  tests/integration/test_proxy_websocket_responses.py -q
# 312 passed, 1 warning

UV_CACHE_DIR=/tmp/codex-lb-uv-cache uv run pytest tests/unit/test_proxy_http_bridge.py -q
# 389 passed

UV_CACHE_DIR=/tmp/codex-lb-uv-cache uv run pytest tests/integration/test_api_keys_api.py -q
# 82 passed

PYTHONDONTWRITEBYTECODE=1 .venv/bin/python -B -m pytest -p no:cacheprovider \
  tests/unit/test_openai_requests.py::test_responses_to_payload_strips_replayed_tool_call_namespaces_only_on_wire \
  tests/unit/test_openai_requests.py::test_compact_to_payload_strips_replayed_tool_call_namespaces_only_on_wire \
  tests/integration/test_proxy_responses.py::test_v1_responses_strips_replayed_tool_call_namespaces_upstream \
  tests/integration/test_proxy_websocket_responses.py::test_backend_responses_websocket_strips_replayed_tool_call_namespaces \
  tests/integration/test_proxy_websocket_responses.py::test_backend_responses_websocket_forwards_client_tools_byte_identical -q
# 5 passed, 1 warning

.venv/bin/ruff format --check app/core/openai/requests.py tests/unit/test_openai_requests.py tests/integration/test_proxy_responses.py tests/integration/test_proxy_websocket_responses.py
# 4 files already formatted

.venv/bin/ruff check --no-cache app/core/openai/requests.py tests/unit/test_openai_requests.py tests/integration/test_proxy_responses.py tests/integration/test_proxy_websocket_responses.py
# All checks passed!

.venv/bin/ty check app/core/openai/requests.py
# All checks passed!

openspec validate fix-replayed-namespaced-function-call --strict
# Change 'fix-replayed-namespaced-function-call' is valid

openspec status --change fix-replayed-namespaced-function-call --json
openspec instructions apply --change fix-replayed-namespaced-function-call --json
# artifacts complete; tasks 11/11; state=all_done

git diff --check
# passed

openspec validate --specs reports 47 passing specs and two pre-existing failures in unchanged main specs:

  • api-keys requirement 45 lacks a SHALL/MUST keyword.
  • conversations-api requirements 4 and 5 lack SHALL/MUST keywords.

This PR does not modify either capability.

Live verification

The originally failing path was exercised against the local codex-lb WebSocket route with model=codex-auto-review:

before:
{"type":"error","error":{"type":"invalid_request_error","message":"Unknown parameter: 'input[1].namespace'."}}

after restart with this patch:
{"type":"response.completed","error":null,"status":"completed"}

An actual escalated git fetch upstream main then passed automatic approval and executed successfully. Subsequent codex-auto-review request-log rows were recorded with transport=websocket and status=success.

Screenshots / output

Not applicable — backend-only proxy wire-compatibility fix with no dashboard-visible changes. The before/after live output is included above.

Checklist

  • Title is in Conventional Commits format (<type>(<scope>)?: <subject>).
  • Linked bug(proxy): compacted/replayed Codex histories can enter permanent 400 loops on item_* ids and namespace #1450 and explicitly documented that this is a partial fix.
  • Added regression coverage at the externally failing HTTP and WebSocket product paths.
  • Ran the relevant lint, format, type-check, unit, integration, and strict OpenSpec validation.
  • openspec validate --specs passes and /opsx:verify is clean — blocked only by the two unchanged baseline spec errors documented above; strict change validation and task verification pass.
  • Simplicity gates reviewed: PRINCIPLES.md P1-P5.
  • CHANGELOG.md is not edited by hand.

@codemoo codemoo changed the title fix(proxy): strip replayed function call namespaces fix(proxy): strip replayed tool call namespaces Aug 3, 2026
@codemoo

codemoo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 723199c44f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/core/openai/requests.py Outdated
@codemoo

codemoo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d360e9b5d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/unit/test_openai_requests.py
@codemoo

codemoo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: a4dd36a2fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Komzpa Komzpa added 🤖 codex: ok [@codex review] says no issues found. and removed 🤖 codex: ok [@codex review] says no issues found. labels Aug 3, 2026
@codemoo
codemoo marked this pull request as ready for review August 4, 2026 03:55

codemoo commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: e64eddfdc0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

2 participants