Description
@ai-sdk/open-responses@2.0.35 added the experimental extension codec registry from #18899 / #18900. The registry safely solves request encoding, response and event decoding, and history replay for normative namespaced Open Responses extensions.
Some public Responses-compatible implementations expose documented implementation extensions using legacy OpenAI-style bare discriminators instead of <implementor>:<type>. Examples include hosted-search and custom-tool families such as:
- request tools:
web_search, custom
- output/input items:
web_search_call, custom_tool_call, custom_tool_call_output
- streaming events:
response.web_search_call.*, response.custom_tool_call_input.*
These types are not Open Responses core types and should not become portable defaults. However, an application also cannot explicitly register their wire semantics today: OpenResponsesNamespacedType requires ${string}:${string}, and registry validation requires the wire namespace to match the extension ID namespace.
As a result, the safe codec seam exists, but documented Responses-compatible extensions using bare discriminators still require a provider fork or a request/response-mutating fetch wrapper.
Expected behavior
Would you be open to an explicit opt-in mechanism for codecs to register exact bare tool, item, and event discriminators?
The API shape is open, but it should preserve the current safety properties:
- Registration remains explicit and package-local.
- Every accepted bare discriminator is exactly allowlisted by a codec.
- Unknown tool, item, and event types remain unsupported; there is no arbitrary JSON passthrough.
- Duplicate registrations and ambiguous ownership are rejected.
- The same codec continues to own request encoding, non-streaming decoding, streaming decoding, and lossless history replay.
- Namespaced extensions remain the default and retain their current namespace validation.
Possible shapes include an explicit allowBareTypes capability on an extension, separate bareToolType / bareItemTypes / bareEventTypes fields, or another API that makes the non-portable opt-in visible.
Why this is distinct from existing requests
Reproduction
A codec whose provider-tool ID is acme.web_search cannot register the implementation wire type web_search:
const extension: Experimental_OpenResponsesExtension = {
id: "acme.web_search",
toolType: "web_search", // rejected by the public type
itemTypes: ["web_search_call"], // rejected by the public type
eventTypes: ["response.web_search_call.completed"], // rejected by the public type
encodeTool: () => ({}),
decodeItem: () => [],
decodeEvent: () => [],
};
Casting around the TypeScript constraint still fails registry validation at runtime because each wire type lacks the required acme: namespace.
Non-goals
- Do not classify bare
web_search, custom, or related item names as Open Responses core types.
- Do not add vendor/model capability detection to
@ai-sdk/open-responses.
- Do not pass through arbitrary unknown JSON.
- Do not weaken validation for existing namespaced registrations.
AI SDK Version
Code of Conduct
Description
@ai-sdk/open-responses@2.0.35added the experimental extension codec registry from #18899 / #18900. The registry safely solves request encoding, response and event decoding, and history replay for normative namespaced Open Responses extensions.Some public Responses-compatible implementations expose documented implementation extensions using legacy OpenAI-style bare discriminators instead of
<implementor>:<type>. Examples include hosted-search and custom-tool families such as:web_search,customweb_search_call,custom_tool_call,custom_tool_call_outputresponse.web_search_call.*,response.custom_tool_call_input.*These types are not Open Responses core types and should not become portable defaults. However, an application also cannot explicitly register their wire semantics today:
OpenResponsesNamespacedTyperequires${string}:${string}, and registry validation requires the wire namespace to match the extension ID namespace.As a result, the safe codec seam exists, but documented Responses-compatible extensions using bare discriminators still require a provider fork or a request/response-mutating fetch wrapper.
Expected behavior
Would you be open to an explicit opt-in mechanism for codecs to register exact bare tool, item, and event discriminators?
The API shape is open, but it should preserve the current safety properties:
Possible shapes include an explicit
allowBareTypescapability on an extension, separatebareToolType/bareItemTypes/bareEventTypesfields, or another API that makes the non-portable opt-in visible.Why this is distinct from existing requests
unsupported-tool#10771 asks to pass unknown provider-defined tools through to providers. This request does not ask for unknown passthrough: unregistered values must continue to fail closed.Reproduction
A codec whose provider-tool ID is
acme.web_searchcannot register the implementation wire typeweb_search:Casting around the TypeScript constraint still fails registry validation at runtime because each wire type lacks the required
acme:namespace.Non-goals
web_search,custom, or related item names as Open Responses core types.@ai-sdk/open-responses.AI SDK Version
@ai-sdk/open-responses: 2.0.35Code of Conduct