fix(api): accept official Responses text.format omit-real - #657
fix(api): accept official Responses text.format omit-real#657cursor[bot] wants to merge 16 commits into
Conversation
…closed otherwise Chat history: message-level audio and legacy function_call are null/empty omit no-ops; non-empty fail closed with named errors (including tools passthrough). Tip substrate from #577 assistant refusal/annotations honesty. Local full unit: 940 passed.
…ed otherwise OpenAI fine-tune style message weight is not applied on this gateway. Accept null/0/1 as honest no-ops; reject other types and values with invalid_message_weight. Tip substrate from #578. Local full unit: 943 passed.
…ion role Reject unsupported message keys with named unknown_message_fields (not silent strip or tools-passthrough smuggle). Reject legacy function role with invalid_message_role migration to tool. Tip substrate from #579. Local full unit: 947 passed.
OpenAI partial-assistant prefix flag is not applied on this gateway. null/false are honest no-ops; true and non-booleans fail closed with invalid_message_prefix. Tip substrate from #580. Local full unit: 950 passed.
…therwise Named invalid_max_tool_calls on /v1/chat/completions instead of opaque unknown_fields. Aligns with Responses max_tool_calls honesty; gateway has no multi-step tool loop.
…losed otherwise Legacy /v1/completions treated max_tool_calls as unknown_fields. Accept the key for named invalid_max_tool_calls (null/empty/whitespace omit-equivalent), matching chat/Responses honesty so SDKs get a clear migration path.
SDK clients often send include_usage/include_obfuscation as JSON null. Drop null flag values before validation so null (and null+false mixes) match omit / all-false no-ops on chat, Completions, and Responses. True flags remain fail-closed with invalid_stream_options.
…or Responses parallel true SDK optional defaults often send function.strict and json_schema.strict as null — treat as omit rather than type errors. Align Responses parallel_tool_calls=true with chat by requiring a non-empty tools array.
SDK optional defaults often send description and parameters as JSON null. Treat null as omit rather than type errors; non-null non-string/object values remain fail-closed with invalid_tools.
OpenAI-style tool descriptions are at most 1024 characters. Over-long descriptions fail closed with named invalid_tools so SDKs never believe a truncated description was accepted.
SDK optional participant name blanks ("" / whitespace) are omit-equivalent
like JSON null. Non-string, over-long, and invalid charset names remain
fail-closed with invalid_message_name.
SDK optional defaults serialize omitted tool.function description/parameters/strict as JSON null. Accepting those keys without popping them is not omit-equivalent: proxy_completion forwards the body and several providers reject null parameters. Pop in place so passthrough matches omit; keep non-null wrong types on invalid_tools. Also pop response_format.json_schema.strict null. Tip substrate from #614. Local full unit: 989 passed.
…n keys SDK optional defaults serialize omitted response_format.json_schema description/strict as JSON null or blank. Leave those keys and the gateway forwards them; several providers reject strict: null. Pop in place so passthrough matches omit. Unknown inner keys and non-string descriptions stay invalid_response_format. HTTP echo tests cover chat and Responses. Docs cite OpenAI structured outputs and IETF JSON Schema 2020-12 in APA 7th. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
SDK optional defaults serialize omitted function descriptions as empty or whitespace-only strings. Leaving those keys is not omit-equivalent: proxy_completion forwards them and several providers reject a blank description. Pop in place so passthrough matches omit; keep non-empty strings and fail-closed non-string values. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Official SDKs send text: {format: {type: text}} on every /v1/responses
call. Wholesale invalid_text was a buyer-visible outage. Accept text /
json_object / json_schema formats, pop null/blank description and null
strict before proxy, and fail closed on verbosity, unknown keys, and
text plus response_format. Mock echo.text makes omit-real assertable.
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
There was a problem hiding this comment.
Unique tip review (8fd294f on #646 b09aac3)
Verdict: SOUND for the official Responses text.format slice. Do not merge this honesty stack onto main.
Compared against a concurrent same-slice branch (a46e15e). Prefer this PR as the landing vehicle: it fail-closes text.verbosity with a named next action, reject dual text + response_format, and locks in-place pop on both the validator and mock echo.text. Do not open a second text.format PR.
What the unique tip does
- Accepts official
text.format(text/json_object/ flatjson_schema) so the Responses SDK default is no longer400 invalid_text. - Pops JSON-null / blank
descriptionand JSON-nullstricton the same dictproxy_completionforwards. - Fail-closes unknown keys, missing schema, non-applied
verbosity, and two structured-output planes.
Reviewer next action
Review 8fd294f only. Independent non-author APPROVE is still required. Do not APPROVE the 153-file substrate as a main merge. Mark ready for review when the unique tip is the review surface.
Residual (later unique tips, not this PR)
json_schema.namecharset/length stays on #654.- Official
text.verbositypassthrough (low/medium/high) if a future SDK default starts sending it; today buyers omit it and retry. - Envelope work stays on #628/#648. Instructions omit stays on #649.
Sent by Cursor Automation: Fix Issues
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Pull request was closed
|
Superseded by tip substrate ≥ #691 (cumulative OpenAI/gateway honesty band + auto-merge tip). Closing to free product-gate runners (Full unit + Semgrep). |


Summary
text: {format: {type: text}}on every/v1/responsescall. Wholesaleinvalid_textwas a buyer-visible outage.text.formatshapes:text,json_object, and flatjson_schema(type/name/schema/ optionaldescription/strict).descriptionand JSON-nullstrictin place so proxy matches omit. Mockecho.textmakes that assertable.text.verbosity(not applied), unknowntext/formatkeys, and sending bothtextandresponse_format.8fd294fon the fix(api): pop null json_schema description/strict omit-real before proxy #646 honesty substrate. Do not merge this stack ontomain.Test plan
python3 tests/test_responses_text_format_http_honesty.py(ok)python3 tests/test_responses_conversation_controls_http_honesty.py(ok)python3 tests/test_json_schema_inner_fields_omit_http_honesty.py(ok)python3 tests/test_responses_response_format_http_honesty.py(ok)python3 tests/test_sdk_null_legacy_controls_noop_http_honesty.py(ok)python3 tests/test_empty_string_reasoning_text_include_noop_http_honesty.py(ok)python3 tests/test_function_call_reasoning_empty_noop_http_honesty.py(ok)python3 tests/test_paper_contracts.py(ok)python3 tests/test_conventions.py(ok)Reviewer next action
Review the unique tip (
8fd294f) only. Do not APPROVE the honesty stack as amainmerge. Independent non-author APPROVE is still required for the unique commit. Name-pattern landing stays #237/#654. Envelope stays #628/#648. Instructions omit stays #649.