fix(engine): treat finish_reason=repeat as soft stop
Moonshot/Kimi returns a non-standard finish_reason of "repeat" when its server-side repetition detector trips. pi-ai surfaces this as a fatal session state error, killing the agent heartbeat. Filter that case in promptSessionAndCheck so the truncated turn is logged and the heartbeat continues on the next tick. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
5
.changeset/engine-finish-reason-repeat-soft-stop.md
Normal file
5
.changeset/engine-finish-reason-repeat-soft-stop.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Treat OpenAI-compatible `finish_reason: repeat` (raised by Moonshot/Kimi when its server-side repetition detector trips) as a soft stop in the engine heartbeat instead of a fatal error, so agent runs survive the truncation and can continue on the next tick.
|
||||||
@@ -167,6 +167,16 @@ async function promptSessionAndCheck(session: AgentSession, prompt: string, opti
|
|||||||
piLog.warn(`pi state error — failed to inspect transcript: ${inspectErr instanceof Error ? inspectErr.message : String(inspectErr)}`);
|
piLog.warn(`pi state error — failed to inspect transcript: ${inspectErr instanceof Error ? inspectErr.message : String(inspectErr)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Some OpenAI-compatible providers (notably Moonshot/Kimi) end generation
|
||||||
|
// with a non-standard `finish_reason: repeat` when their server-side
|
||||||
|
// repetition detector trips. pi-ai surfaces this as a fatal state error,
|
||||||
|
// but for our purposes the assistant turn is already complete — treat it
|
||||||
|
// as a soft stop so the heartbeat keeps running.
|
||||||
|
if (/Provider finish_reason:\s*repeat\b/i.test(stateError)) {
|
||||||
|
piLog.warn(`pi state error — treating provider finish_reason=repeat as soft stop: ${stateError}`);
|
||||||
|
clearSessionStateError(session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw new Error(stateError);
|
throw new Error(stateError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user