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:
@@ -44,7 +44,7 @@ export function extractSessionEventText(event: SessionEvent): string {
|
||||
function turnEndText(reason: SessionEvent<'turn/end'>['data']['reason']): string {
|
||||
switch (reason.kind) {
|
||||
case 'error':
|
||||
return joinText(['error', reason.error instanceof Error ? reason.error.message : String(reason.error)])
|
||||
return joinText(['error', reason.error.message])
|
||||
case 'aborted':
|
||||
return 'aborted'
|
||||
case 'max-tokens':
|
||||
|
||||
@@ -119,8 +119,8 @@ describe('session-query semantic extraction', () => {
|
||||
|
||||
it('extracts meaningful turn outcomes and skips structural or unknown events', () => {
|
||||
const reasons: Array<[SessionEvent<'turn/end'>['data']['reason'], string]> = [
|
||||
[{ kind: 'error', error: new Error('boom') }, 'error\nboom'],
|
||||
[{ kind: 'error', error: 'provider boom' }, 'error\nprovider boom'],
|
||||
[{ kind: 'error', error: { message: 'boom', code: 'UNKNOWN' } }, 'error\nboom'],
|
||||
[{ kind: 'error', error: { message: 'provider boom', code: 'UNKNOWN' } }, 'error\nprovider boom'],
|
||||
[{ kind: 'aborted', reason: { kind: 'user' } }, 'aborted'],
|
||||
[{ kind: 'aborted', reason: { kind: 'disposed' } }, 'aborted'],
|
||||
[{ kind: 'max-tokens' }, 'max-tokens'],
|
||||
|
||||
Reference in New Issue
Block a user