From adddc4dea69acc8738bd05777748d30ef452b9d4 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Tue, 25 Aug 2026 16:49:18 +0800 Subject: [PATCH] test(history): cover packed record branches --- .../session-history-journal.host.spec.ts | 57 +++++++++++++++++++ .../tests/transport.client.spec.ts | 19 +++++++ 2 files changed, 76 insertions(+) diff --git a/packages/api/session-controller/tests/session-history-journal.host.spec.ts b/packages/api/session-controller/tests/session-history-journal.host.spec.ts index e1741cf4fd..c52dda5b92 100644 --- a/packages/api/session-controller/tests/session-history-journal.host.spec.ts +++ b/packages/api/session-controller/tests/session-history-journal.host.spec.ts @@ -289,6 +289,63 @@ describe('Session history raw journal', () => { } }) + it('encodes reasoning and tool-call runs as aligned chunk events', async () => { + const { ctx } = await harness() + const remote = createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'p', model: 'm' }), cwd: '/tmp' }) + const session = ctx.sessions.create(undefined, { meta: { cwd: '/workspace' } }) + const reasoning = [0, 1, 2].map(index => session.append('assistant/chunk', { + turn: 1, + step: 1, + chunk: { type: 'reasoning-delta', index: 0, text: `r${String(index)}` }, + })) + const callId = CallId('packed-call') + const toolCall = [0, 1, 2].map(index => session.append('assistant/chunk', { + turn: 1, + step: 1, + chunk: { type: 'tool-call-delta', index: 1, id: callId, argumentsDelta: `a${String(index)}` }, + })) + + const response = await remote.page({ + address: { kind: 'session', sessionId: session.id }, + throughSeq: session.seq - 1, + }) + if (!response.ok) throw new Error('unreachable') + expect(response.value.records).toEqual([ + { + type: 'chunks', + event: { + type: 'chunkrow/reasoning-chunks', + seq: reasoning[0]?.seq, + time: reasoning[0]?.time, + data: { + turn: 1, + step: 1, + index: 0, + dt: reasoning.slice(1).map((event, index) => event.time - (reasoning[index]?.time ?? 0)), + texts: ['r0', 'r1', 'r2'], + }, + }, + }, + { + type: 'chunks', + event: { + type: 'chunkrow/tool-call-chunks', + seq: toolCall[0]?.seq, + time: toolCall[0]?.time, + data: { + turn: 1, + step: 1, + index: 1, + id: callId, + dt: toolCall.slice(1).map((event, index) => event.time - (toolCall[index]?.time ?? 0)), + args: ['a0', 'a1', 'a2'], + }, + }, + }, + ]) + await ctx.fiber.dispose() + }) + it('follows a result after turn/end without reading the addressed Session log', async () => { const { ctx } = await harness() const session = ctx.sessions.create(undefined, { meta: { cwd: '/workspace' } }) diff --git a/packages/api/session-controller/tests/transport.client.spec.ts b/packages/api/session-controller/tests/transport.client.spec.ts index 05d4ed21f9..1ad1d4e858 100644 --- a/packages/api/session-controller/tests/transport.client.spec.ts +++ b/packages/api/session-controller/tests/transport.client.spec.ts @@ -164,6 +164,25 @@ describe('Session Client stream adapters', () => { await stream.dispose() }) + it('rejects a packed record emitted by the live follow path', async () => { + const failed = vi.fn() + const remote = new ScriptedSessionRemote( + [{ frames: [snapshot(-1, []), chunks(0) as SessionFollowFrame], hold: true }], + [], + ) + const stream = new SessionEventStream(sessionClient(remote), ADDRESS, { + publish: vi.fn(), + failed, + }) + + await stream.open({}) + await vi.waitFor(() => { expect(failed).toHaveBeenCalledOnce() }) + expect(failed.mock.calls[0]?.[0]).toMatchObject({ + message: 'session live stream emitted a packed history record', + }) + await stream.dispose() + }) + it('binds an event journal to one address and publishes replace, append, and prepend changes', async () => { const remote = new ScriptedSessionRemote( [{