harness(openai): OpenAI Responses API (/v1/responses) + codex knobs#51
Conversation
Add a second wire shape to OpenAiModel, selected by with_responses_api_primary(): the OpenAI Responses API (/v1/responses), which the codex OAuth path requires. - responses.rs: ResponsesRequest/Response types + translation. build_responses_input folds system messages into and maps user/assistant/tool turns to items (assistant/tool -> output_text, else input_text, matching the API's role/kind rules). extract_responses_text prefers the terminal , else the first output_text content part. parse_responses_response maps onto ModelResponse (text + usage). Unit-tested. - OpenAiModel: with_responses_api_primary(), with_responses_omit_max_output_tokens() (codex rejects the cap), with_extra_query_param() (codex client_version), with_user_agent() (codex CLI UA). authorized() now applies the UA + query params. - invoke() routes to /responses when responses_api_primary; a 400 implicating max_output_tokens retries once without it. stream() surfaces the unary result as a single terminal Completed (true Responses SSE is a follow-up). Text-in/text-out for now (native tools over /responses are a follow-up; the harness embeds tool specs in the prompt). fmt + clippy -D warnings clean; 65 openai tests pass. NOTE: live per-provider validation deferred to a dedicated tinyagents run.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 11 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 949748a074
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| responses::ResponsesRequest { | ||
| model, | ||
| input, | ||
| instructions, | ||
| stream: None, |
There was a problem hiding this comment.
Preserve tool/schema requests on Responses calls
When with_responses_api_primary() is used, this translator only forwards the model/messages-style input and output cap; normal agent runs still populate ModelRequest.tools, tool_choice, and response_format, and the model profile still advertises native tool calling/schema support. In those contexts the resolver will select this model, but the Responses request never tells OpenAI about the available tools or required schema, so tool execution and structured-output extraction can fail even though the capability was advertised. Please serialize the Responses equivalents or reject/disable these capabilities for this mode.
Useful? React with 👍 / 👎.
| let parsed: ResponsesResponse = | ||
| serde_json::from_value(value.clone()).unwrap_or(ResponsesResponse { | ||
| output: Vec::new(), | ||
| output_text: None, | ||
| usage: None, | ||
| }); |
There was a problem hiding this comment.
Propagate malformed Responses bodies instead of blank success
If the Responses endpoint returns a 2xx body with an unexpected shape, the deserialization error is swallowed and callers receive an empty assistant message with finish_reason: "stop". That differs from the chat-completions parser and can turn provider/API drift into a successful blank answer, especially because error_on_empty_response is opt-in. Return a Result from this parser and propagate the serde/model error instead of defaulting to an empty response.
Useful? React with 👍 / 👎.
Summary
Adds a second wire shape to
OpenAiModel, selected bywith_responses_api_primary(): the OpenAI Responses API (/v1/responses), which the OpenAI Codex OAuth path requires.build_responses_inputfolds system messages intoinstructionsand maps user/assistant/tool turns toinputitems (assistant/tool →output_text, elseinput_text, matching the API's role/kind rules);extract_responses_textprefers the terminaloutput_text, else the firstoutput_textcontent part;parse_responses_responsemaps ontoModelResponse(text + usage). Unit-tested.with_responses_api_primary(),with_responses_omit_max_output_tokens()(Codex rejects the cap),with_extra_query_param()(Codexclient_version),with_user_agent()(Codex CLI UA).authorized()now applies the UA + query params./responseswhenresponses_api_primary; a 400 implicatingmax_output_tokensretries once without it. stream() surfaces the unary result as a single terminalCompleted(true Responses SSE is a follow-up).Text-in/text-out for now — native tools over
/responsesare a follow-up; a harness embeds tool specs in the prompt for this path.Commands run
cargo fmt --checkcargo test --lib openai::— 65 passcargo clippy --lib -- -D warnings— cleanNote
Live per-provider validation (real OpenAI
/responses+ Codex OAuth) is deferred to a dedicated run; this lands the translation + wiring.