fix: include provider and model name in billing error message (#20510)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 40dbdf62e8
Co-authored-by: echoVic <16428813+echoVic@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
青雲
2026-02-19 10:56:00 +08:00
committed by GitHub
parent 2bb8ead187
commit 3d4ef56044
9 changed files with 141 additions and 15 deletions

View File

@@ -160,6 +160,17 @@ const toNormalizedUsage = (usage: UsageAccumulator) => {
};
};
function resolveActiveErrorContext(params: {
lastAssistant: { provider?: string; model?: string } | undefined;
provider: string;
model: string;
}): { provider: string; model: string } {
return {
provider: params.lastAssistant?.provider ?? params.provider,
model: params.lastAssistant?.model ?? params.model,
};
}
export async function runEmbeddedPiAgent(
params: RunEmbeddedPiAgentParams,
): Promise<EmbeddedPiRunResult> {
@@ -549,11 +560,17 @@ export async function runEmbeddedPiAgent(
const lastTurnTotal = lastAssistantUsage?.total ?? attemptUsage?.total;
const attemptCompactionCount = Math.max(0, attempt.compactionCount ?? 0);
autoCompactionCount += attemptCompactionCount;
const activeErrorContext = resolveActiveErrorContext({
lastAssistant,
provider,
model: modelId,
});
const formattedAssistantErrorText = lastAssistant
? formatAssistantErrorText(lastAssistant, {
cfg: params.config,
sessionKey: params.sessionKey ?? params.sessionId,
provider,
provider: activeErrorContext.provider,
model: activeErrorContext.model,
})
: undefined;
const assistantErrorText =
@@ -919,7 +936,8 @@ export async function runEmbeddedPiAgent(
? formatAssistantErrorText(lastAssistant, {
cfg: params.config,
sessionKey: params.sessionKey ?? params.sessionId,
provider,
provider: activeErrorContext.provider,
model: activeErrorContext.model,
})
: undefined) ||
lastAssistant?.errorMessage?.trim() ||
@@ -928,7 +946,10 @@ export async function runEmbeddedPiAgent(
: rateLimitFailure
? "LLM request rate limited."
: billingFailure
? formatBillingErrorMessage(provider)
? formatBillingErrorMessage(
activeErrorContext.provider,
activeErrorContext.model,
)
: authFailure
? "LLM request unauthorized."
: "LLM request failed.");
@@ -937,8 +958,8 @@ export async function runEmbeddedPiAgent(
(isTimeoutErrorMessage(message) ? 408 : undefined);
throw new FailoverError(message, {
reason: assistantFailoverReason ?? "unknown",
provider,
model: modelId,
provider: activeErrorContext.provider,
model: activeErrorContext.model,
profileId: lastProfileId,
status,
});
@@ -973,7 +994,8 @@ export async function runEmbeddedPiAgent(
lastToolError: attempt.lastToolError,
config: params.config,
sessionKey: params.sessionKey ?? params.sessionId,
provider,
provider: activeErrorContext.provider,
model: activeErrorContext.model,
verboseLevel: params.verboseLevel,
reasoningLevel: params.reasoningLevel,
toolResultFormat: resolvedToolResultFormat,

View File

@@ -96,17 +96,19 @@ describe("buildEmbeddedRunPayloads", () => {
expect(payloads.some((payload) => payload.text?.includes("request_id"))).toBe(false);
});
it("includes provider context for billing errors", () => {
it("includes provider and model context for billing errors", () => {
const payloads = buildPayloads({
lastAssistant: makeAssistant({
model: "claude-3-5-sonnet",
errorMessage: "insufficient credits",
content: [{ type: "text", text: "insufficient credits" }],
}),
provider: "Anthropic",
model: "claude-3-5-sonnet",
});
expect(payloads).toHaveLength(1);
expect(payloads[0]?.text).toBe(formatBillingErrorMessage("Anthropic"));
expect(payloads[0]?.text).toBe(formatBillingErrorMessage("Anthropic", "claude-3-5-sonnet"));
expect(payloads[0]?.isError).toBe(true);
});

View File

@@ -72,6 +72,7 @@ export function buildEmbeddedRunPayloads(params: {
config?: OpenClawConfig;
sessionKey: string;
provider?: string;
model?: string;
verboseLevel?: VerboseLevel;
reasoningLevel?: ReasoningLevel;
toolResultFormat?: ToolResultFormat;
@@ -104,6 +105,7 @@ export function buildEmbeddedRunPayloads(params: {
cfg: params.config,
sessionKey: params.sessionKey,
provider: params.provider,
model: params.model,
})
: undefined;
const rawErrorMessage = lastAssistantErrored