refactor(agent-loop): simplify message machine

This commit is contained in:
_Kerman
2026-07-30 13:49:57 +08:00
parent d554ae3019
commit f2e20c1ef0
212 changed files with 1326 additions and 2382 deletions

View File

@@ -163,7 +163,6 @@ describe('dsh-agent-spine-demo bundle', () => {
const session = ctx.sessions.create(SessionId('configured-title-limits'))
session.append('turn/start', {
turn: 1,
trigger: { kind: 'message', source: { kind: 'user' } },
})
session.append('user/message', createUserMessage({
content: [{ type: 'text', text: 'One two three four' }],
@@ -206,8 +205,8 @@ describe('dsh-agent-spine-demo bundle', () => {
it('mounts package companions and forwards invariant selection config', async () => {
const nestedTurn = (ctx: Context): void => {
const session = ctx.sessions.create()
session.append('turn/start', { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } })
session.append('turn/start', { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } })
session.append('turn/start', { turn: 1 })
session.append('turn/start', { turn: 2 })
}
const enabled = await mount({ workspaceContext: false })

View File

@@ -388,14 +388,14 @@ describe('runOneShot and executeCli', () => {
if (subject !== agent || injected) return
injected = true
agent.inject(createUserMessage({ content: [{ type: 'text', text: 'startup injection' }], source: { kind: 'plugin', plugin: 'test' } }))
other.append('turn/start', { turn: 1, trigger: { kind: 'injection', source: { kind: 'plugin', plugin: 'test' } } })
other.append('turn/start', { turn: 1 })
other.append('turn/end', { turn: 1, reason: { kind: 'completed' } })
})
const output = await invoke(ctx, ['--output-format', 'stream-json', 'task'])
const lines = output.stdout.trimEnd().split('\n').map(line => JSON.parse(line) as Record<string, unknown>)
const events = lines.slice(0, -1).map(line => line['event'] as SessionEvent)
expect(lines.at(-1)).toMatchObject({ type: 'result', success: true, turn: 1, result: 'streamed' })
expect(events[0]).toMatchObject({ type: 'turn/start', data: { turn: 1, trigger: { kind: 'message' } } })
expect(events[0]).toMatchObject({ type: 'turn/start', data: { turn: 1 } })
expect(events.at(-1)).toMatchObject({ type: 'turn/end', data: { turn: 1 } })
expect(lines.slice(0, -1).every(line => line['sessionId'] === agent.session.id)).toBe(true)
expect(events.some(event => event.type === 'user/message'
@@ -510,11 +510,9 @@ describe('formatTurnFailure', () => {
it('diagnoses every durable reason and preserves merge-extensible unknowns', () => {
const cases: [TurnEndReason, string][] = [
[{ kind: 'completed' }, 'completed'],
[{ kind: 'aborted' }, 'was aborted'],
[{ kind: 'aborted' }, 'was aborted'],
[{ kind: 'error', step: 2, message: 'bad' }, 'failed at step 2: bad'],
[{ kind: 'error', step: 3, failure: { message: 'provider bad', code: 'SERVER' } }, 'failed at step 3: provider bad'],
[{ kind: 'disposed' }, 'was disposed'],
[{ kind: 'aborted', reason: { kind: 'user' } }, 'was aborted'],
[{ kind: 'error', error: new Error('bad') }, 'failed: bad'],
[{ kind: 'error', error: { message: 'provider bad', code: 'SERVER' } }, 'provider bad'],
[{ kind: 'max-tokens' }, 'output-token limit'],
[{ kind: 'interrupted' }, 'persistence recovery'],
]