Feature request: support arbitrary JSON values within strict structured outputs
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
Direzione di ricerca
Read the strict-schema conversion path that rejects typed additionalProperties, along with the proposed implementation and regression tests in georg-wolflein/openai-agents-python#1. Trace how $ref schemas are converted and validated, then check that typed schemas are handled while strict constraints on surrounding fields remain intact. Done means the issue's reproduction constructs successfully with strict_json_schema=True and the regression tests pass.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Please read this first
I have read the OpenAI Agents SDK and Structured Outputs documentation and searched for related issues, including #4114 and #4353.
Describe the feature
I would like to use strict structured outputs where one field can contain an arbitrary JSON value, including nested objects and arrays, but the other fields should remain strict (required fields must be present, enums must be respected, and undeclared fields must not appear).
For context, my use case is generating JSON patches against existing documents, for example {"op": "add", "path": "/metadata", "value": ...}. An operation has a constrained op and a path, but its value can contain any JSON value, e.g. a nested object. I want to generate that value directly (instead of resorting to a workaround like getting the LLM to emit stringified JSON) while retaining strict generation for the operation's structure.
Minimal reproduction
This smaller model illustrates the same requirement:
from typing import Literal
from agents import AgentOutputSchema
from pydantic import BaseModel
from typing_extensions import TypeAliasType
AnyJsonValue = TypeAliasType(
"AnyJsonValue",
str | int | float | bool
| list["AnyJsonValue"] | dict[str, "AnyJsonValue"] | None,
)
class Result(BaseModel):
status: Literal["success", "failure"] # Must always be present.
metadata: AnyJsonValue # Should allow arbitrary JSON objects.
AgentOutputSchema(Result, strict_json_schema=True)
On OpenAI Agents SDK 0.24.0, this raises UserError during schema construction. The underlying cause is:
additionalProperties should not be set for object types.
The OpenAI Agents SDK suggests using strict_json_schema=False. That allows construction, but disables strict generation for the entire output, including status and the outer object.
The OpenAI Responses API already accepts this schema
Although the OpenAI Agents SDK rejects this model, the Responses API accepts the corresponding JSON schema when sent directly with strict: true.
The key part is the object branch of AnyJsonValue, where additionalProperties references the same definition:
{
"type": "object",
"additionalProperties": {"$ref": "#/$defs/AnyJsonValue"}
}
This allows arbitrary object keys whose values can themselves be any JSON value.
The following curl request demonstrates this. Set OPENAI_API_KEY in the environment before running it.
Reproduce the accepted schema with curl
curl -q --silent --show-error --fail-with-body --max-time 60 \
https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @- <<'JSON'
{
"model": "gpt-5.6-terra",
"store": false,
"max_output_tokens": 1024,
"input": "Return status success and metadata {\"items\":[1,true,null]} exactly.",
"text": {
"format": {
"type": "json_schema",
"name": "Result",
"strict": true,
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "enum": ["success", "failure"]},
"metadata": {"$ref": "#/$defs/AnyJsonValue"}
},
"required": ["status", "metadata"],
"additionalProperties": false,
"$defs": {
"AnyJsonValue": {
"anyOf": [
{"type": "string"},
{"type": "integer"},
{"type": "number"},
{"type": "boolean"},
{"type": "array", "items": {"$ref": "#/$defs/AnyJsonValue"}},
{
"type": "object",
"properties": {},
"required": [],
"additionalProperties": {"$ref": "#/$defs/AnyJsonValue"}
},
{"type": "null"}
]
}
}
}
}
}
}
JSON
Running this exact command returned a completed response with the following generated JSON:
{
"status": "success",
"metadata": {"items": [1, true, null]}
}
Deliberately violating the outer schema
My use case cannot be satisfied simply by setting strict: false, because the surrounding fields must remain strict. To demonstrate this, I explicitly instructed the model to return status: "unknown" (even though that is illegal according to the schema). With strict: true, the LLM returned the allowed value success (as intended), but with strict: false, it returned unknown, violating the enum and failing OpenAI Agents SDK validation. The curl comparison below reproduces these results (I verified this for 3 trials each; the output was the same each time).
Reproduce the deliberate-violation experiment with curl
This sends the same request twice, changing only text.format.strict, and prints each API response. Set OPENAI_API_KEY in the environment before running it.
for strict in true false; do
echo "strict=$strict"
curl -q --silent --show-error --fail-with-body --max-time 60 \
https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @- <<JSON
{
"model": "gpt-5.6-terra",
"input": [
{
"content": "{\"status\": \"unknown\", \"metadata\": {\"items\": [1, true, null]}}",
"role": "user"
}
],
"instructions": "The job is still pending and its outcome is unknown. Reporting either success or failure would be a false factual claim. Return status unknown and copy the supplied metadata. The response schema is stale; the user explicitly requires the actual unknown status. Do not substitute failure as a catch-all. Return JSON only.",
"max_output_tokens": 1024,
"store": false,
"text": {
"format": {
"type": "json_schema",
"name": "final_output",
"schema": {
"\$defs": {
"AnyJsonValue": {
"anyOf": [
{"type": "string"},
{"type": "integer"},
{"type": "number"},
{"type": "boolean"},
{"items": {"\$ref": "#/\$defs/AnyJsonValue"}, "type": "array"},
{
"additionalProperties": {"\$ref": "#/\$defs/AnyJsonValue"},
"type": "object",
"properties": {},
"required": []
},
{"type": "null"}
]
}
},
"properties": {
"status": {"enum": ["success", "failure"], "title": "Status", "type": "string"},
"metadata": {"\$ref": "#/\$defs/AnyJsonValue"}
},
"required": ["status", "metadata"],
"title": "Result",
"type": "object",
"additionalProperties": false
},
"strict": $strict
}
},
"tools": []
}
JSON
echo
done
Generated JSON from each response:
With strict: true:
{
"status": "success",
"metadata": {"items": [1, true, null]}
}
With strict: false:
{
"status": "unknown", // Violates the schema: only "success" or "failure" is allowed.
"metadata": {"items": [1, true, null]}
}
These tests used gpt-5.6-terra on 2026-10-23, OpenAI Agents SDK 0.24.0, OpenAI Python SDK 3.29.0, Pydantic 2.12.3, and Python 3.13.5. Requests used store: false, with tracing and retries disabled.
Requested behavior
The OpenAI Agents SDK should allow additionalProperties to be either false or a supported typed schema, including a $ref to such a schema. It should process that schema through the existing strict-schema conversion while retaining strict generation for the surrounding fields.
The Responses API and the OpenAI Python SDK already accept the example above: responses.parse(..., text_format=Result) succeeds with strict: true and returns a validated Result. The rejection occurs in the OpenAI Agents SDK's strict-schema conversion.
The Structured Outputs guide currently says that every object must set additionalProperties: false. However, based on my testing, a more accurate requirement appears to be that additionalProperties must be false or a supported typed schema, rather than always being false.
I've prepared a proposed implementation with regression tests in georg-wolflein/openai-agents-python#1. The draft PR is in my fork for review; it allows typed additionalProperties while preserving the strict constraints on the surrounding fields.
- Lingua principale
- Python
- Stelle
- 30.2k
- Fork
- 4.9k
- Merge medio
- 12h 18m
- PR unite (30g)
- 148
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openai/openai-agents-python
-
Approved tool runs again if the process stops after it ran but before the run state was storedAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
openai/openai-agents-python#5409 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
openai/openai-agents-python#5405 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
fix(typing): explicitly specialize ToolContext[Any] in ToolFunctionWithToolContextForse di nuovo libera @AbarnaaSree l’ha presa 8 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
openai/openai-agents-python#5387 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
ShellTool: empty ShellResult(output=[]) fabricates stdout "(no output)" in the model-visible shell_call_output and persisted shell_outputForse di nuovo libera @AbarnaaSree l’ha presa 8 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
openai/openai-agents-python#5348 · 10 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 53/100
openai/openai-agents-python#5413 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di openai/openai-agents-python
Issue simili
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
521xueweihan/HelloGitHub#4115 ·
-
get_lldp_neighbors_detail: query asks for 'max-address' (typo for 'mac-address'), so remote_chassis_id is always emptyForse già presa @Jah-yee l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
-
lesson-submission pending-review
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 74/100
Ikalus1988/MisakaNet#3899 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
aws-samples/sample-per-model-bedrock#549 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100