Skip to content

feat(responses): accept non-standard tool and input item types for Codex compatibility#5456

Open
franciscojavierarceo wants to merge 2 commits intoogx-ai:mainfrom
franciscojavierarceo:codex-compat
Open

feat(responses): accept non-standard tool and input item types for Codex compatibility#5456
franciscojavierarceo wants to merge 2 commits intoogx-ai:mainfrom
franciscojavierarceo:codex-compat

Conversation

@franciscojavierarceo
Copy link
Copy Markdown
Collaborator

Summary

  • Add OpenAIResponseInputToolCustom catch-all model for non-standard tool types (local_shell, tool_search, image_generation, custom) sent by external clients like OpenAI Codex
  • Add OpenAIResponseInputUnknown catch-all model for non-standard input item types (local_shell_call, custom_tool_call, tool_search_call, etc.)
  • Switch OpenAIResponseInputTool and OpenAIResponseTool unions from strict discriminator="type" to union_mode="left_to_right" so known types match first and unknown types are gracefully accepted
  • Add verbosity field to OpenAIResponseText (Codex sends text: {verbosity: "low"})
  • Skip client-side tool types during chat completion conversion
  • Add 30 unit tests covering parsing, union discrimination, tool context, chat conversion, and the verbosity field

Context

When Codex CLI sends requests through Llama Stack as a proxy, it includes tool types and input items that are specific to the OpenAI Responses API but not part of the standard spec that Llama Stack implements. For example, Codex sends {"type": "local_shell"} tools and {"type": "local_shell_call", ...} input items representing shell command executions. Without this change, these cause 422 validation errors.

The fix uses a catch-all pattern: specific types are tried first in the union, and the catch-all model (with extra="allow") matches anything that didn't match above. Client-side items are silently skipped during chat conversion since the model already processed them on previous turns.

Note: The api-conformance pre-commit check reports request-property-one-of-removed because the tool union changed from oneOf (discriminated) to anyOf (left-to-right). This is functionally additive — the endpoint now accepts strictly more inputs than before — so it is not a breaking change in practice.

Test plan

  • 30 new unit tests in test_codex_compat.py covering:
    • Pydantic parsing of all Codex tool types and input item types
    • Union discrimination (known types resolve to specific models, unknown fall through)
    • ToolContext.available_tools() with custom tools
    • convert_response_input_to_chat_messages() skipping unknown items
    • OpenAIResponseText.verbosity field
  • All 263 existing response tests pass
  • All 1902 unit tests pass (excluding pre-existing faiss crash)
  • Manual end-to-end testing with Codex-shaped payloads via curl
uv run pytest tests/unit/providers/responses/builtin/test_codex_compat.py -v
uv run pytest tests/unit/providers/responses/ -x --tb=short -q

🤖 Generated with Claude Code

…dex compatibility

External clients like OpenAI Codex send tool types (local_shell, tool_search,
image_generation, custom) and input item types (local_shell_call,
custom_tool_call, tool_search_call) that are not part of the standard OpenAI
Responses API. Previously these caused 422 validation errors because the
Pydantic unions used strict discriminators.

This adds catch-all models (OpenAIResponseInputToolCustom for tools,
OpenAIResponseInputUnknown for input items) and switches the unions from
discriminated to left-to-right mode so that known types are matched first
and unknown types are gracefully accepted. Client-side tool types are
skipped during chat conversion since the model doesn't need to see them.

Also adds the verbosity field to OpenAIResponseText which Codex sends in
its text configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Apr 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 6, 2026

✱ Stainless preview builds

This PR will update the llama-stack-client SDKs with the following commit message.

feat(responses): accept non-standard tool and input item types for Codex compatibility

Edit this comment to update it. It will appear in the SDK's changelogs.

⚠️ llama-stack-client-go studio · conflict

Your SDK build had at least one new warning diagnostic, which is a regression from the base state.

New diagnostics (1 warning, 3 note)
⚠️ Schema/EnumDescriptionNotValid: Schema contains enum descriptions but doesn't have an enum
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputToolCustom` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputUnknown` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
💡 Go/SchemaUnionDiscriminatorMissing: This union schema has more than one object variant, but no [`discriminator`](https://www.stainless.com/docs/reference/openapi-support#discriminator) property, so deserializing the union may be inefficient or ambiguous.
llama-stack-client-openapi studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️

New diagnostics (2 note)
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputToolCustom` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputUnknown` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
llama-stack-client-python studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅

pip install https://pkg.stainless.com/s/llama-stack-client-python/ff5da08122fac6aa448a391db595940fc2bec848/llama_stack_client-0.7.0a2-py3-none-any.whl
New diagnostics (2 note)
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputToolCustom` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputUnknown` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
llama-stack-client-node studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅

npm install https://pkg.stainless.com/s/llama-stack-client-node/556a4fb5c22acd7fffd45db06e7892a33941bff4/dist.tar.gz
New diagnostics (2 note)
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputToolCustom` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.
💡 Model/Recommended: `#/components/schemas/OpenAIResponseInputUnknown` could potentially be defined as a [model](https://www.stainless.com/docs/guides/configure#models) within `#/resources/responses`.

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-04-06 23:33:02 UTC

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 9, 2026

This pull request has merge conflicts that must be resolved before it can be merged. @franciscojavierarceo please rebase it. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Apr 9, 2026
Copy link
Copy Markdown
Collaborator

@mattf mattf left a comment

Choose a reason for hiding this comment

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

@franciscojavierarceo tool types of local_shell, tool_search, image_generation, custom are standard, see https://developers.openai.com/api/reference/resources/responses/methods/create.

we should definitely recognize them, even if stack shouldn't do anything to implement them, e.g. stack treats them like the function case. if an llm requests local shell or tool search, we need to make sure the client gets a chance to implement them. if they're something we should implement, e.g. web_search w/o a tool_runtime, we should return 501.

@nidhishgajjar

This comment was marked as spam.

1 similar comment
@nidhishgajjar

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs-rebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants