fix(api): pop blank Responses instructions before passthrough - #649
fix(api): pop blank Responses instructions before passthrough#649cursor[bot] wants to merge 14 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.
SDK null/empty/whitespace instructions are now omit-real: the key is removed so /v1/responses does not forward a blank system prompt. HTTP tests lock the mock echo, and the OpenAPI/docs contract tells callers to send a non-empty string when they want instructions. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
|
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. |
There was a problem hiding this comment.
Unique tip 85617de is SOUND. Do not merge this stack onto main.
#635 accepted blank instructions with HTTP 200 and still forwarded "instructions": " " upstream. This tip closes that gap:
_validate_responses_instructionspops JSONnull/ empty / whitespace (including NBSP) from the samebodythatproxy_completioncopies (minus orchestration-only keys)._mock_rawechoesinstructions, so HTTP tests can lock absence for blanks and equality for a real prompt.- OpenAPI
create_model_response,docs/rest_api_design.md, andCHANGELOG.mdtell callers what to send next.
Local scripts printed ok: test_responses_instructions_reasoning_http_honesty.py, test_sdk_null_object_optional_noop_http_honesty.py, test_openai_passthrough.py, test_api_contract.py, test_product_planning_contract.py, test_self_check.py, test_paper_contracts.py, test_conventions.py.
Merge path (buyer / reviewer)
- Review this commit only (
85617de). The PR vsmainis the 150-file honesty stack — do not merge that ontomain. - Prefer this tip over
#635. Independent non-author APPROVE is required (this automation cannot self-approve acursor[bot]PR). - After parent unique tips land, cherry-pick or rebase
85617de. Then point SDKs at/v1/responses: leaveinstructionsunset, or sendnull/""/ whitespace — the gateway deletes the key. Send a non-empty string when you need a system prompt.invalid_instructionsmeans fix the type or shorten the value; do not retry the same blank payload.
Residual (non-blocking)
- OpenAPI
/v1/responsesonly documentsmodel/input/instructions. Other accepted Responses fields still live in the handler, not the stub schema. test_http_responses_accepts_instructions_omittedlocks HTTP 200 only; blank-value cases already lock echo absence.- Checks were still queued at review time. Queued OpenCode / Strix / Noema is not a unique-tip defect.
- CodeRabbit CLI 0.7.3 is installed here;
coderabbit auth login --agenttimed out (no interactive user). This is not a CodeRabbit result.
Do not open a third instructions-omit PR. Extend #649 only if this slice regresses.
Sent by Cursor Automation: Fix Issues
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
Unique tip on #635 (
95346e7). #635 accepts SDK blankinstructionswith HTTP 200 but still forwards"instructions": " "upstream. This tip makes omit real:_validate_responses_instructionspops null/empty/whitespace (including NBSP) from the request body before/v1/responsespassthrough.echoincludesinstructionsso HTTP tests lock absence for blanks and equality for a real prompt.create_model_response,docs/rest_api_design.md, andCHANGELOG.mdtell callers: send a non-empty string when you want a system prompt; do not retry a blank payload.Review this commit only
85617de— do not merge this 143-file honesty stack ontomain. Parent unique tip is #635 / #626.Test plan
python3 tests/test_responses_instructions_reasoning_http_honesty.pypython3 tests/test_sdk_null_object_optional_noop_http_honesty.pypython3 tests/test_openai_passthrough.pypython3 tests/test_api_contract.pypython3 tests/test_product_planning_contract.pypython3 tests/test_self_check.pypython3 tests/test_paper_contracts.pypython3 tests/test_conventions.pyexercise_request_bodyfor blank/null/non-stringinstructionsBuyer next action
Point SDKs at
/v1/responses. Leaveinstructionsunset, or sendnull/""/ whitespace — the gateway deletes the key. If you need a system prompt, send a non-empty string.invalid_instructionsmeans fix the type or shorten the value.