fix(session): type turn/end error as one structured failure
TurnEndReasonMap.error now carries a single `error: LlmFailure` field: an LlmError keeps its structured facts, any other error flattens to errorChain text under the UNKNOWN code. Consumers read message/code directly instead of defending against an unknown union — this also fixes errorChain() rendering structured failures as '[object Object]' in the TUI and ACP error paths. Document the turn-stopping contract: a concludesTurn result never short-circuits already-submitted next-step work (same-step additionalContexts or racing steering still runs), data decides.
This commit is contained in:
@@ -60,6 +60,20 @@ function requestProposal(header: EpochHeader): LlmCallConfig {
|
||||
}
|
||||
|
||||
/** Drives one session through turn and step boundaries. */
|
||||
/**
|
||||
* Shape a caught turn error into its durable reason: every failure is a
|
||||
* structured LlmFailure — an `LlmError` keeps its facts, anything else
|
||||
* flattens to `errorChain` text under the `UNKNOWN` code.
|
||||
*/
|
||||
function turnErrorReason(error: unknown): Extract<TurnEndReason, { kind: 'error' }> {
|
||||
return {
|
||||
kind: 'error',
|
||||
error: error instanceof LlmError
|
||||
? error.failure
|
||||
: { message: errorChain(error), code: 'UNKNOWN' },
|
||||
}
|
||||
}
|
||||
|
||||
export class ReactLoopAgent implements Agent {
|
||||
readonly inbox: Inbox
|
||||
private phase: Phase
|
||||
@@ -279,10 +293,7 @@ export class ReactLoopAgent implements Agent {
|
||||
turnEnds = { kind: 'aborted', reason: signal.reason as AgentCancelCause }
|
||||
throw error
|
||||
}
|
||||
turnEnds = {
|
||||
kind: 'error',
|
||||
error: error instanceof LlmError ? error.failure : errorChain(error),
|
||||
}
|
||||
turnEnds = turnErrorReason(error)
|
||||
this.throwError(error)
|
||||
} finally {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user