import { describe, expect, test } from 'bun:test'; import type { Message, Part } from '@opencode-ai/sdk/v2'; import { buildTaskSummaryEntriesFromSession, parseTaskMetadataBlock, readTaskSessionIdFromRecord, readTaskSessionIdFromOutput, } from './taskToolModel'; describe('taskToolModel', () => { test('reads the current OpenCode running-state identity contract', () => { expect(readTaskSessionIdFromRecord({ sessionId: 'child-live' })).toBe('child-live'); expect(readTaskSessionIdFromRecord({})).toBe(undefined); }); test('reads authoritative session and summary metadata', () => { const output = 'result\n{"sessionID":"child-1","calls":[{"id":"tool-1","tool":"read","title":"a.ts"}]}'; expect(parseTaskMetadataBlock(output)).toEqual({ sessionId: 'child-1', summaryEntries: [{ id: 'tool-1', tool: 'read', state: { status: undefined, title: 'a.ts', input: undefined } }], }); expect(readTaskSessionIdFromOutput(output)).toBe('child-1'); }); test('projects tool calls while excluding nested task and todo bookkeeping', () => { const message = { info: { id: 'message-1', role: 'assistant' } as Message, parts: [ { id: 'read-1', type: 'tool', tool: 'read', state: { status: 'completed', input: { filePath: 'a.ts' } } }, { id: 'task-1', type: 'tool', tool: 'task', state: { status: 'running' } }, { id: 'todo-1', type: 'tool', tool: 'todowrite', state: { status: 'completed' } }, ] as unknown as Part[], }; expect(buildTaskSummaryEntriesFromSession([message])).toEqual([{ id: 'read-1', tool: 'read', state: { status: 'completed', title: undefined, input: { filePath: 'a.ts' } }, }]); }); });