fix(core): retry on failed as well as timeout; only auth stops the run (#104)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -372,7 +372,7 @@ export class TraceService {
|
||||
if (pendingFrom === null) pendingFrom = mi;
|
||||
// A user Prompt **always starts a new turn**: judging continuation solely
|
||||
// by "did the previous turn call a tool" isn't enough — if the previous
|
||||
// turn ended in timeout/malformed (given up after exhausting retries),
|
||||
// turn ended in a retryable status (given up after exhausting retries),
|
||||
// retryable would leave continuation at true, and this new message would
|
||||
// get merged into that failed turn, smearing the two turns' messages /
|
||||
// Tokens / TPS / duration together.
|
||||
@@ -437,11 +437,21 @@ export class TraceService {
|
||||
}
|
||||
} else if (p.type === "request_end") {
|
||||
const status = typeof p.status === "string" ? p.status : undefined;
|
||||
// timeout/malformed is automatically reconnected by core within the same
|
||||
// run (context-engine's retry loop); the resent Request still belongs to
|
||||
// **the same user turn**: it must continue the turn, otherwise a single
|
||||
// timeout would split that turn's Tokens/duration/TPS across two Tasks.
|
||||
const retryable = status === "timeout" || status === "malformed";
|
||||
// A status core reconnects on within the same run (context-engine's retry
|
||||
// loop) leaves the resent Request in **the same user turn**: it must
|
||||
// continue the turn, otherwise a single blip would split that turn's
|
||||
// Tokens/duration/TPS across two Tasks and inflate the Task count.
|
||||
//
|
||||
// This list must track the engine's, and the engine's differs by loop:
|
||||
// the turn loop retries `failed` too, while compaction deliberately fails
|
||||
// fast and stops on it (core's TURN_RETRY_STATUSES vs
|
||||
// COMPACTION_RETRY_STATUSES). Hence the compactionActive guard — a failed
|
||||
// compaction request really is the end of that request, and counting it
|
||||
// as a reconnect would invent an attempt that never happened.
|
||||
const retryable =
|
||||
status === "timeout" ||
|
||||
status === "malformed" ||
|
||||
(status === "failed" && !compactionActive);
|
||||
if (!hasOrigin) {
|
||||
prevSerialTs = null;
|
||||
continuation = sawToolCallThisRequest || retryable;
|
||||
|
||||
Reference in New Issue
Block a user