import { afterEach, describe, expect, it, vi } from 'vitest'; import { createNotificationTemplateRuntime } from './template-runtime.js'; const originalFetch = globalThis.fetch; const createRuntime = (settings = {}) => createNotificationTemplateRuntime({ readSettingsFromDisk: async () => settings, persistSettings: vi.fn(async () => {}), buildOpenCodeUrl: (path) => path, getOpenCodeAuthHeaders: () => ({}), resolveGitBinaryForSpawn: () => 'git', }); describe('notification template runtime zen models', () => { afterEach(() => { globalThis.fetch = originalFetch; }); it('returns no selectable zen models after provider retirement', async () => { const runtime = createRuntime(); const models = await runtime.fetchFreeZenModels(); expect(models).toEqual([]); }); it('preserves stored zen model value for compatibility without validation', async () => { const runtime = createRuntime({ zenModel: 'trinity-large-preview-free' }); await expect(runtime.resolveZenModel()).resolves.toBe('trinity-large-preview-free'); }); }); describe('notification template message extraction', () => { afterEach(() => { globalThis.fetch = originalFetch; }); it('excludes reasoning parts from payload message text', () => { const runtime = createRuntime(); expect(runtime.extractLastMessageText({ properties: { info: { parts: [ { type: 'reasoning', text: 'private chain of thought' }, { type: 'text', text: 'final answer' }, ], }, }, })).toBe('final answer'); }); it('ignores untyped parts even when they contain text', () => { const runtime = createRuntime(); expect(runtime.extractLastMessageText({ properties: { info: { parts: [ { text: 'untyped text' }, { content: 'untyped content' }, { type: 'text', text: 'typed final answer' }, ], }, }, })).toBe('typed final answer'); }); it('excludes reasoning parts when fetching assistant messages', async () => { const runtime = createRuntime(); globalThis.fetch = vi.fn(async () => new Response(JSON.stringify([ { info: { id: 'msg-1', role: 'assistant', finish: 'stop' }, parts: [ { type: 'reasoning', text: 'private chain of thought' }, { type: 'text', text: 'final answer' }, ], }, ]))); await expect(runtime.fetchLastAssistantMessageText('session-1', 'msg-1')).resolves.toBe('final answer'); }); });