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:
@@ -361,10 +361,9 @@ describe('request stability across the loop', () => {
|
||||
expect(agent.session.events.findLast(event => event.type === 'turn/end')).toMatchObject({
|
||||
data: {
|
||||
step: 1,
|
||||
reason: {
|
||||
kind: 'error',
|
||||
error: failure instanceof LlmError ? failure.failure : failure.message,
|
||||
},
|
||||
reason: failure instanceof LlmError
|
||||
? { kind: 'error', error: failure.failure }
|
||||
: { kind: 'error', error: { message: failure.message, code: 'UNKNOWN' } },
|
||||
},
|
||||
})
|
||||
expect(adapter.requests).toHaveLength(0)
|
||||
@@ -505,7 +504,7 @@ describe('request stability across the loop', () => {
|
||||
const turnEnd = agent.session.events.findLast(event => event.type === 'turn/end')
|
||||
expect(turnEnd).toMatchObject({ data: { reason: { kind: 'error' } } })
|
||||
if (turnEnd?.type !== 'turn/end' || turnEnd.data.reason.kind !== 'error') throw new Error()
|
||||
expect(turnEnd.data.reason.error).toMatch(/not extensible|frozen|read only|readonly/i)
|
||||
expect(turnEnd.data.reason.error.message).toMatch(/not extensible|frozen|read only|readonly/i)
|
||||
})
|
||||
|
||||
it('a fresh loop instance over a seeded log anchors with a resume snapshot and stays cache-aligned', async () => {
|
||||
|
||||
Reference in New Issue
Block a user