fix(api): treat Responses instructions empty/whitespace as omit - #635
fix(api): treat Responses instructions empty/whitespace as omit#635seonghobae wants to merge 13 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.
…ll as omit SDK optional defaults often send top_logprobs as "" and tool_calls function.arguments as JSON null. Empty/whitespace top_logprobs matches null/0 omit on chat and Completions; null arguments normalizes to empty JSON-text string. Non-zero top_logprobs and non-string arguments stay fail-closed.
SDK optional defaults often send instructions as empty or blank. Match JSON null omit-equivalent behavior so blank instructions do not fail closed as invalid_instructions; non-string and oversized remain rejected.
|
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. |
|
Important Review skippedToo many files! This PR contains 143 files, which is 43 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (143)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Unique tip only (95346e7)
HTTP accept of blank Responses instructions is real: " " is 200, not invalid_instructions. Claimed omit is not real. _validate_responses_instructions returns None and the /v1/responses handler discards that return, so proxy_completion still forwards "instructions": " " (and null / "") to the provider.
Do not merge this 143-file stack onto main. Parent is #626 d8aa84c.
Blocking
- Pop
instructionswhen the value is omit-equivalent, or apply the returnedNoneon the request body before passthrough. - Lock it: mock
echomust includeinstructions, and the HTTP test must assert the key is absent for blank/null and present for a real prompt.
Repair unique tip is #649 85617de (pop + echo + OpenAPI/docs). Review that commit; do not merge #649 as the stack either.
Non-blocking
- JSON
nullalready used accept-without-pop; this tip only widened it to empty/whitespace. - ZWSP-only remains a 1-character accepted instruction (
str.strip()does not clear it). - Independent non-author APPROVE is still required after omit-real lands.
Buyer next action
Do not treat HTTP 200 on instructions: "" / whitespace as omit-equivalent on this head. Wait for #649 (or an equivalent pop + echo lock) before relying on SDK optional defaults.
Sent by Cursor Automation: Fix Issues
| value = body.get("instructions") | ||
| # Explicit JSON null or empty/whitespace string is treat-as-omit. | ||
| if value is None or (isinstance(value, str) and not value.strip()): | ||
| return None |
There was a problem hiding this comment.
This branch returns None but does not remove instructions. The /v1/responses handler ignores the return value and proxy_completion forwards the original body, so "instructions": " " still goes upstream. Pop the key here (or assign the returned None onto body) so omit is real.
| "instructions": " ", | ||
| }, | ||
| ) | ||
| assert status == 200, body |
There was a problem hiding this comment.
HTTP 200 only. This cannot fail if the blank key is still forwarded. Echo instructions from _mock_raw and assert "instructions" not in echo for null/empty/whitespace, and equality for a nonempty prompt.
There was a problem hiding this comment.
Superseded by #649 85617de. Do not merge this stack.
This unique tip (95346e7) made blank instructions HTTP 200, but omit was not real: the key stayed on the body and proxy_completion forwarded "instructions": " ".
Landing is #649 #649 — pop null/empty/whitespace/NBSP, mock echo, HTTP echo locks, OpenAPI create_model_response.
Buyer next action: close or abandon this PR after #649 is independently approved. Point SDKs at /v1/responses on the #649 tip. Do not open a third instructions-omit PR.
Sent by Cursor Automation: Fix Issues
|
Superseded by tip substrate ≥ #691 (cumulative OpenAI/gateway honesty band + auto-merge tip). Closing to free product-gate runners (Full unit + Semgrep). |


Summary
instructions: ""/ whitespace is omit-equivalent (parity with null).Test plan
tests/test_responses_instructions_reasoning_http_honesty.pypython -m pytest tests -q(986 passed)