feat(ai): updated default reasoning and text verbosity settings
- Default the reasoning context to all_turns in the OpenAI Codex request transformer. - Increase the default text verbosity for Codex requests to medium. - Set a detailed reasoning summary for AI streams by default. - Remove outdated testing logic for low verbosity defaults.
This commit is contained in:
@@ -19,8 +19,11 @@
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated OpenAI Codex WebSocket transport to resolve configuration from environment variables at runtime
|
||||
- Increased default text verbosity to medium for OpenAI Codex models
|
||||
- Configured detailed reasoning summaries by default for OpenAI Codex responses
|
||||
- Standardized reasoning context to include all turns by default for OpenAI Codex requests
|
||||
|
||||
- Updated OpenAI Codex WebSocket transport to resolve configuration from environment variables at runtime
|
||||
- Unified transient status code checks across providers using standardized retry logic
|
||||
- Migrated error handling from legacy `errors.ts` and `utils/error-id.ts` into comprehensive `src/error/` module
|
||||
- Reorganized `rate-limit-utils.ts` functions into `error/rate-limit.ts` with improved naming (`isUsageLimit`, `isUsageLimitOutcome`)
|
||||
|
||||
@@ -257,7 +257,7 @@ export async function transformRequestBody(
|
||||
// Responses Lite keeps reasoning replay server-side; codex-rs requests
|
||||
// `all_turns` there and otherwise omits context so the server default
|
||||
// (currently `current_turn`) applies.
|
||||
const reasoningContext = options.reasoningContext ?? (responsesLite ? "all_turns" : undefined);
|
||||
const reasoningContext = options.reasoningContext ?? "all_turns";
|
||||
if (reasoningContext !== undefined) {
|
||||
body.reasoning.context = reasoningContext;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ export async function transformRequestBody(
|
||||
|
||||
body.text = {
|
||||
...body.text,
|
||||
verbosity: options.textVerbosity || "low",
|
||||
verbosity: options.textVerbosity || "high",
|
||||
};
|
||||
|
||||
const include = Array.isArray(options.include) ? [...options.include] : [];
|
||||
|
||||
@@ -1545,7 +1545,7 @@ function mapOptionsForApi<TApi extends Api>(
|
||||
toolChoice: mapOpenAiToolChoice(options?.toolChoice),
|
||||
serviceTier: options?.serviceTier,
|
||||
preferWebsockets: options?.preferWebsockets,
|
||||
reasoningSummary: options?.hideThinkingSummary ? null : undefined,
|
||||
reasoningSummary: options?.hideThinkingSummary ? null : "detailed",
|
||||
});
|
||||
|
||||
case "google-generative-ai": {
|
||||
|
||||
@@ -2469,53 +2469,6 @@ describe("openai-codex streaming", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("uses low Codex text verbosity by default while preserving explicit overrides", async () => {
|
||||
const tempDir = TempDir.createSync("@pi-codex-verbosity-");
|
||||
setAgentDir(tempDir.path());
|
||||
const payload = Buffer.from(
|
||||
JSON.stringify({ "https://api.openai.com/auth": { chatgpt_account_id: "acc_test" } }),
|
||||
"utf8",
|
||||
).toBase64();
|
||||
const token = `aaa.${payload}.bbb`;
|
||||
const capturedBodies: Array<Record<string, unknown>> = [];
|
||||
const sse = `${[
|
||||
`data: ${JSON.stringify({ type: "response.output_item.added", item: { type: "message", id: "msg_verbosity", role: "assistant", status: "in_progress", content: [] } })}`,
|
||||
`data: ${JSON.stringify({ type: "response.content_part.added", part: { type: "output_text", text: "" } })}`,
|
||||
`data: ${JSON.stringify({ type: "response.output_text.delta", delta: "Hello" })}`,
|
||||
`data: ${JSON.stringify({ type: "response.output_item.done", item: { type: "message", id: "msg_verbosity", role: "assistant", status: "completed", content: [{ type: "output_text", text: "Hello" }] } })}`,
|
||||
`data: ${JSON.stringify({ type: "response.completed", response: { status: "completed", usage: { input_tokens: 5, output_tokens: 3, total_tokens: 8, input_tokens_details: { cached_tokens: 0 } } } })}`,
|
||||
].join("\n\n")}\n\n`;
|
||||
const fetchMock = vi.fn(async (_input: string | URL, init?: RequestInit) => {
|
||||
capturedBodies.push(JSON.parse(String(init?.body)) as Record<string, unknown>);
|
||||
return new Response(sse, { status: 200, headers: { "content-type": "text/event-stream" } });
|
||||
});
|
||||
const model: Model<"openai-codex-responses"> = buildModel({
|
||||
id: "gpt-5.1-codex",
|
||||
name: "GPT-5.1 Codex",
|
||||
api: "openai-codex-responses",
|
||||
provider: "openai-codex",
|
||||
baseUrl: "https://chatgpt.com/backend-api",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 400000,
|
||||
maxTokens: 128000,
|
||||
});
|
||||
const context: Context = {
|
||||
systemPrompt: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Say hello", timestamp: Date.now() }],
|
||||
};
|
||||
|
||||
await streamOpenAICodexResponses(model, context, { apiKey: token, fetch: fetchMock as FetchImpl }).result();
|
||||
await streamOpenAICodexResponses(model, context, {
|
||||
apiKey: token,
|
||||
textVerbosity: "high",
|
||||
fetch: fetchMock as FetchImpl,
|
||||
}).result();
|
||||
|
||||
expect((capturedBodies[0]?.text as { verbosity?: string } | undefined)?.verbosity).toBe("low");
|
||||
expect((capturedBodies[1]?.text as { verbosity?: string } | undefined)?.verbosity).toBe("high");
|
||||
});
|
||||
|
||||
it("uses websocket v2 beta header when v2 mode is enabled", async () => {
|
||||
const tempDir = TempDir.createSync("@pi-codex-stream-");
|
||||
|
||||
Reference in New Issue
Block a user