Skip to content

Commit c8a3bd3

Browse files
committed
test(fixtures): document namespace tool compatibility
1 parent d100796 commit c8a3bd3

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

test/fixtures/openai_compatibility/sdk_shapes/MATRIX.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Decisions are limited to `accept`, `translate`, `reject`, or `passthrough`:
1919
| `local-chat.input_fallback.absent_or_empty_messages.v1` | Local compatibility fallback | n/a | `POST /v1/chat/completions`; `POST /backend-api/codex/v1/chat/completions` | Responses-shaped client payload sent to the chat route without usable `messages` | Top-level `input` is accepted only when `messages` is absent or `[]`; non-empty `messages` stays authoritative; omitted fallback `instructions` becomes `""` | `translate` | 5 | `CodexPooler.Gateway.OpenAICompatibility.Chat`; `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler_web/controllers/v1/chat_completions_controller_test.exs`; `test/codex_pooler_web/controllers/runtime/compatibility_contract_test.exs` | This is a codex-pooler local fallback only, not broad Responses-to-chat parity and not an official OpenAI SDK chat request shape |
2020
| `vercel-ai.responses.tool_output_continuation.v1` | Vercel `ai` | `6.0.191` | `POST /v1/responses` | Responses tool-output continuation with stored response state flag and previous response reference | Top-level `previous_response_id`, `store`, `input`, `tools`; input item types include `item_reference`, `function_call_output`, and `message:user`; flat function tool shape | `passthrough` | 4 | `CodexPooler.Gateway.OpenAICompatibility.Responses`; `CodexPooler.Gateway.Payloads.ToolResultShape`; `CodexPooler.Gateway.Payloads.InputShape` | `test/codex_pooler/gateway/openai_compatibility/continuation_test.exs`; `test/codex_pooler/gateway/openai_compatibility/core_test.exs` | Current product boundary accepts the observed narrow continuation shape and forwards `previous_response_id`; fake previous ids may fail upstream with an OpenAI-shaped upstream status rather than local state ownership |
2121
| `vercel-ai-sdk-openai.responses.flat_function_tool.v1` | Vercel OpenAI provider `@ai-sdk/openai` | `3.0.65` | `POST /v1/responses` | Provider-specific Responses request with flat function tool definition | Top-level `model`, `input`, `tools`, `tool_choice`; tool keys are flat `type`, `name`, `description`, `parameters` | `accept` | 5 | `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs` | Responses flat function tools are accepted only for the documented narrow function shape; malformed tool and `tool_choice` variants stay guarded |
22+
| `vercel-ai-sdk-openai.responses.namespace_function_tool.v1` | Vercel OpenAI provider `@ai-sdk/openai` | `3.0.65+` | `POST /v1/responses` | Provider-specific Responses request with function tools grouped by `providerOptions.openai.namespace` | Top-level `tools` entry has `type=namespace`, nonblank `name`, nonblank `description`, and nested function tools with flat `type`, `name`, `description`, `parameters`, optional `strict`, and optional `defer_loading` | `accept` | namespace tool backport | `CodexPooler.Gateway.OpenAICompatibility.Responses`; `CodexPooler.Gateway.Payloads.StrictSchema` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler_web/controllers/v1/responses_controller_test.exs` | Accepted only for namespace entries containing nested function tools. Hosted tools, tool_search namespace markers, top-level deferred function tools, empty namespace labels, empty nested tool lists, malformed nested parameters, and non-boolean nested `strict`/`defer_loading` reject locally |
2223
| `openai-responses.additional_tools.request_input_item.v1` | OpenAI-compatible Responses shape | Node `openai` `6.41.0`; Python `openai` `2.40.0` | `POST /v1/responses`; `POST /v1/chat/completions` fallback input only | Request-shaped Responses `additional_tools` input item | Input item has `type=additional_tools`, `role=developer`, required `tools`, and optional nonblank string `id`; it stays inside `input` | `accept` | 5 | `CodexPooler.Gateway.OpenAICompatibility.Responses.Input` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler_web/controllers/runtime/compatibility_contract_test.exs` | Accepted only as request-shaped Responses input item. It is non-executable, not top-level, not merged into top-level `tools`, and not sufficient for `tool_choice`. Output-shaped `additional_tools` request input remains rejected |
2324
| `opencode.responses.replay_continuation.v1` | OpenCode `opencode-ai` | `1.15.12` | `POST /v1/responses` and `GET /v1/responses` websocket `response.create` | Responses replay continuation with assistant output, reasoning summary, function call with optional `namespace`, and structured tool output item replay | Top-level `previous_response_id`, `store`, `input`, `tools`; input item types include `message:assistant`, `reasoning`, `function_call`, and `function_call_output`; replayed `function_call` may include `namespace`; content part types include `output_text`, `summary_text`, `input_text`, and `input_image` | `translate` | opencode v1 replay fix | `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler/gateway/openai_compatibility/continuation_test.exs`; `test/codex_pooler_web/controllers/v1/responses_controller_test.exs` | Accepts only the narrow opencode replay item shapes; unsupported hosted-tool items and image `file_id` references remain rejected locally |
2425
| `hermes.responses.assistant_tool_call_replay.v1` | Hermes Agent | observed 2026-06-08 local state shape | `POST /v1/responses` | Chat-style assistant tool-call replay followed by a role=tool terminal result | Top-level `previous_response_id`, `store`, `input`; assistant item has `role=assistant`, empty `content`, and `tool_calls` with nested `function.name`/`function.arguments`; tool item has `role=tool`, `tool_call_id`, and object `content.output` | `translate` | Hermes replay fix | `CodexPooler.Gateway.OpenAICompatibility.Responses.Input` | `test/codex_pooler/gateway/openai_compatibility/continuation_test.exs`; `test/codex_pooler_web/controllers/runtime/compatibility_contract_test.exs` | Translates only the observed narrow replay: assistant `tool_calls` become Responses `function_call` input items and role=tool object content uses the string `output` field. Raw terminal output remains metadata-only and unsupported tool-call variants still reject locally |
@@ -27,7 +28,7 @@ Decisions are limited to `accept`, `translate`, `reject`, or `passthrough`:
2728
| `openclaw.responses.assistant_thinking_replay.v1` | OpenClaw | observed 2026-06-09 OpenClaw 2026.6.1 session state shape | `POST /v1/responses` | Ordinary replay without `previous_response_id` during a second `--session-key` turn where the prior assistant message contributes a reasoning replay item and assistant text replay | Top-level `model`, `store`, `input`; OpenClaw session state contains assistant `thinking` plus `text`, while the transport sends `reasoning` with `content: []` plus assistant `message` with `output_text` annotations | `translate` | OpenClaw replay fix | `CodexPooler.Gateway.OpenAICompatibility.Responses.Input` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler/gateway/openai_compatibility/continuation_test.exs` | Drops raw assistant `thinking` replay metadata, removes unsupported reasoning `content: []`, and strips assistant `output_text` annotations before upstream dispatch. Raw prompts, thinking content, signatures, and transport bodies remain metadata-only |
2829
| `openai-responses.web_search_preview.type_only.v1` | OpenAI-compatible Responses shape | n/a | `POST /v1/responses` | Advanced hosted web search tool with no local options | Tool entry contains only `type=web_search_preview` | `passthrough` | 9 | `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs` | Exact type-only passthrough remains allowed; configured hosted web search options are rejected until codex-pooler owns their semantics |
2930
| `openai-responses.image_generation.exact_known.v1` | OpenAI-compatible Responses shape | n/a | `POST /v1/responses` | Advanced image_generation tool on Responses compatibility surface | Tool entry is either type-only passthrough or the exact `/v1/images/*` translated keys `type`, `model`, `size`, `quality`, optional `background`, optional `input_fidelity`, optional `output_format` | `passthrough` | 9 | `CodexPooler.Gateway.OpenAICompatibility.Responses`; `CodexPooler.Gateway.OpenAICompatibility.Images` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs`; `test/codex_pooler_web/controllers/v1/images_controller_test.exs` | Task 9 does not broaden direct Responses image tool options beyond exact known shapes; media/image routes keep their existing exact translation contract |
30-
| `openai-responses.advanced_hosted_tools.unsupported.v1` | OpenAI-compatible Responses shape | n/a | `POST /v1/responses` | Unsupported hosted/advanced tool families including file_search, code_interpreter, computer_use, MCP, shell, local shell, apply_patch, tool_search, namespace, and deferred variants | Tool entries use hosted tool `type` values or namespace/deferred markers rather than flat function-tool contracts | `reject` | 9 | `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs` | Unknown hosted tool runtime semantics are not implemented and are rejected locally before upstream dispatch with deterministic `invalid_request` errors |
31+
| `openai-responses.advanced_hosted_tools.unsupported.v1` | OpenAI-compatible Responses shape | n/a | `POST /v1/responses` | Unsupported hosted/advanced tool families including file_search, code_interpreter, computer_use, MCP, shell, local shell, apply_patch, tool_search, and deferred variants | Tool entries use hosted tool `type` values or deferred markers rather than flat function-tool or accepted namespace-function contracts | `reject` | 9 | `CodexPooler.Gateway.OpenAICompatibility.Responses` | `test/codex_pooler/gateway/openai_compatibility/core_test.exs` | Unknown hosted tool runtime semantics are not implemented and are rejected locally before upstream dispatch with deterministic `invalid_request` errors |
3132
| `unsupported.v1.responses.retrieve.v1` | SDK-probed OpenAI public route | n/a | `GET /v1/responses/:id` | Response retrieval endpoint exposed by SDKs but not implemented by codex-pooler | Path-only unsupported route; no request body is parsed after auth and compatibility gates | `reject` | 8 | `CodexPoolerWeb.V1.UnsupportedRoutes`; `CodexPoolerWeb.V1.UnsupportedController` | `test/codex_pooler_web/controllers/v1/route_auth_test.exs` | Expected status `404`; OpenAI-shaped error code `unsupported_endpoint`; codex-pooler does not own public `/v1` response retrieval state |
3233
| `unsupported.v1.responses.cancel.v1` | SDK-probed OpenAI public route | n/a | `POST /v1/responses/:id/cancel` | Response cancellation endpoint exposed by SDKs but not implemented by codex-pooler | Path-only unsupported route; malformed JSON is not parsed after auth and compatibility gates | `reject` | 8 | `CodexPoolerWeb.V1.UnsupportedRoutes`; `CodexPoolerWeb.V1.UnsupportedController` | `test/codex_pooler_web/controllers/v1/route_auth_test.exs` | Expected status `404`; OpenAI-shaped error code `unsupported_endpoint`; cancellation is not implemented for public `/v1` response ids |
3334
| `unsupported.v1.responses.delete.v1` | SDK-probed OpenAI public route | n/a | `DELETE /v1/responses/:id` | Response deletion endpoint exposed by SDKs but not implemented by codex-pooler | Path-only unsupported route; no upstream dispatch or gateway reservation | `reject` | 8 | `CodexPoolerWeb.V1.UnsupportedRoutes`; `CodexPoolerWeb.V1.UnsupportedController` | `test/codex_pooler_web/controllers/v1/route_auth_test.exs` | Expected status `404`; OpenAI-shaped error code `unsupported_endpoint`; deletion is not implemented for public `/v1` response ids |

test/support/compatibility_matrix.ex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ defmodule CodexPooler.CompatibilityMatrix do
7575
future_routes: [],
7676
fixture: :responses_chat,
7777
contract:
78-
"Responses and chat completions proxy JSON/SSE through the shared gateway accounting path; chat completions use messages when present and fall back to top-level input only when messages is absent or empty, with omitted fallback instructions defaulting to a blank string; request-shaped additional_tools input items are preserved as non-executable input, never merged into executable tools, and never used to satisfy tool_choice; Responses truncation accepts auto and disabled locally but is not forwarded upstream; compaction_trigger payloads pass through unchanged on backend Responses, while context-overflow recovery stays client/upstream-owned with no server-side compaction, hidden replay, or stored prompt/frame reconstruction; Hermes assistant replay may include safe assistant status metadata; OpenClaw assistant replay drops thinking metadata and normalizes text before upstream dispatch; safe OpenAI Responses fields, prompt-cache locality, SDK-control rejection, and backend-only control stripping stay scope-specific"
78+
"Responses and chat completions proxy JSON/SSE through the shared gateway accounting path; chat completions use messages when present and fall back to top-level input only when messages is absent or empty, with omitted fallback instructions defaulting to a blank string; request-shaped additional_tools input items are preserved as non-executable input, never merged into executable tools, and never used to satisfy tool_choice; Responses namespace tool definitions are accepted only for non-empty namespace name/description values and nested function tools; Responses truncation accepts auto and disabled locally but is not forwarded upstream; compaction_trigger payloads pass through unchanged on backend Responses, while context-overflow recovery stays client/upstream-owned with no server-side compaction, hidden replay, or stored prompt/frame reconstruction; Hermes assistant replay may include safe assistant status metadata; OpenClaw assistant replay drops thinking metadata and normalizes text before upstream dispatch; safe OpenAI Responses fields, prompt-cache locality, SDK-control rejection, and backend-only control stripping stay scope-specific"
7979
},
8080
%{
8181
slug: :backend_v1_alias_surface,
@@ -258,7 +258,7 @@ defmodule CodexPooler.CompatibilityMatrix do
258258
future_routes: [],
259259
fixture: :v1_supported_surface,
260260
contract:
261-
"OpenAI-compatible /v1 routes are default-on for pools, require bearer API-key auth, return OpenAI-shaped errors without anonymous local or CIDR bypasses, include narrow GET /v1/responses Responses websocket compatibility only, exclude broad /v1/realtime routes, consume continuity headers using the documented local precedence without forwarding session-id or x-session-affinity upstream, fail closed for pinned /v1/responses continuations whose upstream account needs revoked-refresh-token reauthentication with the shared restart_with_full_context recovery guidance, allow prompt-cache routing locality only on POST responses and chat completions, accept Responses truncation auto and disabled locally without forwarding it upstream, translate chat-style role=tool continuation messages and Hermes assistant tool-call replays into Responses function_call/function_call_output input items before validation, accept safe Hermes assistant replay status values, translate OpenClaw assistant thinking replays before validation, and keep chat input fallback plus Responses additional_tools support narrow and non-executable"
261+
"OpenAI-compatible /v1 routes are default-on for pools, require bearer API-key auth, return OpenAI-shaped errors without anonymous local or CIDR bypasses, include narrow GET /v1/responses Responses websocket compatibility only, exclude broad /v1/realtime routes, consume continuity headers using the documented local precedence without forwarding session-id or x-session-affinity upstream, fail closed for pinned /v1/responses continuations whose upstream account needs revoked-refresh-token reauthentication with the shared restart_with_full_context recovery guidance, allow prompt-cache routing locality only on POST responses and chat completions, accept Responses truncation auto and disabled locally without forwarding it upstream, translate chat-style role=tool continuation messages and Hermes assistant tool-call replays into Responses function_call/function_call_output input items before validation, accept safe Hermes assistant replay status values, translate OpenClaw assistant thinking replays before validation, and keep chat input fallback, Responses additional_tools support narrow and non-executable, and Responses namespace-tool support narrow"
262262
},
263263
%{
264264
slug: :v1_unsupported_public_surface,
@@ -330,6 +330,13 @@ defmodule CodexPooler.CompatibilityMatrix do
330330
merges_into_tools: false,
331331
satisfies_tool_choice: false
332332
},
333+
namespace_tool: %{
334+
shape: "top_level_namespace_tool",
335+
required: ["type", "name", "description", "tools"],
336+
nested_tool_types: ["function"],
337+
nested_optional: ["strict", "defer_loading"],
338+
satisfies_tool_choice: true
339+
},
333340
responses_truncation: %{
334341
accepted_values: ["auto", "disabled"],
335342
forwarded_upstream: false

0 commit comments

Comments
 (0)