Q87: provider errors keep status and provider code; text never decides recovery

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 14:52:31 -04:00
1 parent 7ecffe84e3
commit 4668396f25
28 files changed
+285 -108

No files matched your search

@@ -3,7 +3,7 @@
* (Codex) and github-copilot turns. Matches Pi's `convertResponsesMessages` /
* `convertResponsesTools` and the Responses streaming event shapes.
*/
import { isRecord, ProviderHttpError, type JsonRecord, type ProviderEventStreamMessage } from "../provider-http";
import { isRecord, ProviderHttpError, readProviderErrorCode, type JsonRecord, type ProviderEventStreamMessage } from "../provider-http";
import { incompleteTurn, replayIn, toolCallFromJson, type AgentTurnMessage, type AgentTurnResult, type AssistantReplay, type ToolCall, type ToolDefinition } from "../provider-tool-turn";
export function responsesToolDefs(tools: ToolDefinition[], strict: boolean | null = false): unknown[] {
@@ -84,9 +84,6 @@ function eventType(message: ProviderEventStreamMessage): string | null {
return typeof type === "string" ? type : message.eventName;
}
/** Responses error codes that name passing provider trouble, as HTTP statuses for failure classification. */
const RESPONSES_ERROR_STATUS: Record<string, number> = { server_error: 500, rate_limit_exceeded: 429 };
/** The error of an `error` event, or of a `response.failed` event's response. */
function streamError(data: JsonRecord): unknown {
return data.error ?? (isRecord(data.response) ? data.response.error : undefined);
@@ -100,10 +97,10 @@ function errorText(data: JsonRecord): string {
return "Provider stream failed.";
}
function errorStatus(data: JsonRecord): number | null {
/** The error's code: the error object's code or type, or the event's own code. */
function errorCode(data: JsonRecord): string | null {
const error = streamError(data);
const code = isRecord(error) ? error.code : data.code;
return typeof code === "string" ? RESPONSES_ERROR_STATUS[code] ?? null : null;
return isRecord(error) ? readProviderErrorCode({ error }) : typeof data.code === "string" ? data.code : null;
}
/**
@@ -123,7 +120,7 @@ export async function accumulateResponsesStream(messages: AsyncIterable<Provider
raw.push(message.rawData);
const type = eventType(message);
if (!type) continue;
if (type === "error" || type === "response.failed") throw new ProviderHttpError(errorText(message.data), null, errorStatus(message.data));
if (type === "error" || type === "response.failed") throw new ProviderHttpError(errorText(message.data), null, null, false, errorCode(message.data));
if (type === "response.output_item.done" && isRecord(message.data.item)) {
streamed.push(message.data.item);
}