Skip to content

fix(codex): consolidate repeated Responses namespaces - #95

Open
matt1060338871-pixel wants to merge 2 commits into
BigStrongSun:mainfrom
matt1060338871-pixel:codex/fix-responses-duplicate-namespaces
Open

fix(codex): consolidate repeated Responses namespaces#95
matt1060338871-pixel wants to merge 2 commits into
BigStrongSun:mainfrom
matt1060338871-pixel:codex/fix-responses-duplicate-namespaces

Conversation

@matt1060338871-pixel

@matt1060338871-pixel matt1060338871-pixel commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary / 概述

Fix native Responses requests rejected with Duplicate namespace name 'mcp__...' after Codex discovers tools in the same namespace more than once, including inherited conversation history.

Root Cause and Scope

Codex retains separate tool_search_output records. OpenCode Go's native Responses gateway registers their namespace declarations request-wide and rejects repeated names. The shared third-party Responses preparer forwarded those declarations unchanged. Its passthrough is traceable to 1fda7d1dafa564481df2fbc717e9c96225da7937 (August 30); this is evidence of a compatibility gap, not proof that that commit introduced the observed regression. The existing namespace-flattening adapter is xAI-specific and should not be broadened for this different error.

This patch runs in the shared production/probe Responses preparer, gated by parsed URLs for OpenCode Go (opencode.ai/zen/go/v1) and direct DeepSeek (api.deepseek.com). Live before/after verification was performed against OpenCode Go; the direct DeepSeek gate has unit/contract coverage and a separately reported matching failure, but was not live-tested with direct DeepSeek credentials.

What Changed

  • Consolidate compatible repeated namespaces across top-level tools and immediate input[].tool_search_output.tools, keeping the union of function declarations at the first occurrence.
  • Preserve all discovery call/output records, IDs, status, execution, qualified function names, and ordinary conversation/tool-result content. Later discovery outputs may have an empty tool list, which the tested gateway accepts.
  • Deduplicate functions with identical callable contracts, retaining the latest function description. Real inherited GitHub discovery history changed only its appended plugin-attribution text; treating that text as a schema conflict would leave a subsequent duplicate namespace unresolved. If namespace metadata, callable definitions, tool kinds, or shapes conflict, leave that entire namespace group unchanged instead of silently discarding or replacing schemas.
  • Keep official/managed routes, other native gateways, and Chat/Anthropic conversion outside this change. No service-name hardcoding, session-file edits, response transformation, or missing-call_id repair.
  • Bump the request-preparer fingerprint version so old compatibility receipts do not describe the previous preparation behavior.

Verification

  • Fresh synthetic requests sent directly to OpenCode Go, without old conversation state: repeated mcp__hindsight, mcp__websearch, and mcp__codex_apps__plugin_management each returned HTTP 400 before normalization and HTTP 200 after normalization. The executable used the production Rust source, not a Python reimplementation.
  • Automatic tool invocation returned HTTP 200 and the expected function_call with namespace: mcp__hindsight, name: read, both for the single-discovery control and normalized repeated discoveries. A normalized request containing prior function-call/output history also returned HTTP 200.
  • Explicit forced tool-choice probes were rejected for both single-discovery controls and normalized requests; these are not counted as successful checks or attributed to this patch. Normal automatic tool selection succeeded.
  • Local replay of the affected task's discovery declarations plus inherited declarations: two Hindsight namespace declarations became one; all six distinct functions and all four discovery-output records remained. No private conversation content was sent in the synthetic live probes.
  • Nine focused unit/contract tests cover union/order/ID preservation, idempotence, top-level collisions, description-only drift, conflict handling, opaque nested data, URL boundaries, runtime/probe parity, and unchanged Chat conversion.
  • cargo fmt --check --manifest-path src-tauri/Cargo.toml passed.
  • cargo clippy --manifest-path src-tauri/Cargo.toml --lib --no-default-features -- -D warnings passed.

The patched desktop executable was installed locally and restarted without a version bump or public binary release. Four raw, unnormalized requests through the installed localhost proxy passed: repeated Hindsight, websearch, and plugin-management discovery each completed with HTTP 200; automatic tool invocation also completed with the expected qualified function call. The provider-module suite passed all 1,101 tests.

After installation, the user retried the original affected desktop task and confirmed that the conversation recovered. This is user-confirmed original-task recovery in addition to the installed-proxy tests above. An earlier CLI resume attempt was blocked locally by the desktop's active-writer lock and did not send an upstream request. No conversation history or writer locks were modified.

Related Issue / 关联 Issue

N/A. User-reported native Responses failure; intentionally separate from malformed delegation outputs missing call_id.

Screenshots / 截图

N/A: protocol-only change. Reproduction and before/after evidence are described above without exposing private task history.

Checklist / 检查清单

  • pnpm typecheck passes / Not run: no frontend changes.
  • pnpm format:check passes / Not run: Rust formatting checked separately.
  • Rust library Clippy passes with -D warnings; full application/binary Clippy was not run.
  • No user-facing text changed; i18n changes are not applicable.

@matt1060338871-pixel
matt1060338871-pixel marked this pull request as ready for review September 11, 2026 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant