import { Buffer } from 'node:buffer' import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import { createToolResultMessage, ToolCallId } from '@deepseek-ai/dsh-llm' import { createScope, scopeOf, type ScopeKey } from '@deepseek-ai/dsh-scope' import { Session, SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRuntime from '@deepseek-ai/dsh-tools' import { describe, expect, it, vi } from 'vitest' import * as VisualizerClient from '../src/client.ts' import VisualizerService from '../src/index.ts' import * as VisualizerModel from '../src/model.ts' import { visualizerSystemPrompt } from '../src/prompt.ts' const SIGNAL = new AbortController().signal const SCOPED_BASES = new WeakMap() async function captureScopedBase(ctx: Context): Promise { await ctx.plugin(Object.assign((inner: Context) => { SCOPED_BASES.set(ctx, inner) }, { inject: ['systemPrompt', 'tools'] })) } async function mount() { const ctx = new Context() await ctx.plugin(AgentRegistry) await ctx.plugin(SystemPrompt) await ctx.plugin(ToolRuntime) const authorityFiber = await ctx.plugin(VisualizerService) await captureScopedBase(ctx) const base = SCOPED_BASES.get(ctx) if (base === undefined) throw new Error('missing scoped test base') const presetKey: ScopeKey = { agentPreset: 'surface' } const presetScope = createScope(base, presetKey) const modelFiber = await presetScope.ctx.plugin(VisualizerModel) const agent = recordedAgent(ctx, 'surface-agent', undefined, undefined, presetKey) ctx.agents.register(agent) return { ctx, authorityFiber, modelFiber, presetScope, agent } } async function modelFace(ctx: Context, agent: Agent) { const prompt = await ctx.systemPrompt.assemble({ agent, scope: agent }) const names = ['widget_guidelines', 'show_widget'] .filter(name => ctx.tools.get(name, agent) !== undefined) const guidance = await ctx.tools.execute({ signal: SIGNAL, callId: ToolCallId('snapshot-guidance'), name: 'widget_guidelines', arguments: { modules: ['diagram', 'mockup', 'interactive', 'chart', 'illustration'] }, agent, }) const receipt = await ctx.tools.execute({ signal: SIGNAL, callId: ToolCallId('snapshot-widget'), name: 'show_widget', arguments: { title: 'Snapshot', widget_code: '', }, agent, }) return { prompt: prompt.sections.find(section => section.name === 'tool:visualizer')?.text, tools: Object.fromEntries(names.map((name) => { const tool = ctx.tools.get(name, agent) if (tool === undefined) throw new Error(`missing Visualizer tool ${name}`) return [name, { description: tool.description, parameters: tool.parameters, output: tool.output.schema }] })), results: { guidance: guidance.content, show_widget: receipt.content }, } } function recordedAgent( ctx: Context, id: string, followup: Agent['followup'] = vi.fn(), source = '', presetParent?: ScopeKey, ): Agent { const session = Session.create(SessionId(id)) session.append('turn/start', { turn: 1 }) session.append('step/start', { turn: 1, step: 1 }) const call = session.append('tool/call', { turn: 1, step: 1, callId: ToolCallId('widget'), name: 'show_widget', arguments: JSON.stringify({ title: 'Choice', widget_code: source }), }) session.append('tool/result', { turn: 1, step: 1, message: createToolResultMessage({ callId: ToolCallId('widget'), content: [], isError: false }), meta: { kind: /^])/i.test(source.trimStart()) ? 'svg' : 'html' }, }, { surfaceOp: 'append', sourceEventSeqs: [call.seq] }) const agent = { id: session.id, session, ctx, followup } as unknown as Agent const scope = createScope( SCOPED_BASES.get(ctx) ?? ctx, agent, presetParent === undefined ? undefined : { parent: presetParent }, ) Object.assign(agent, { ctx: scope.ctx }) return agent } describe('Visualizer model surface', () => { it('ships one neutral SVG and HTML model surface when mounted', async () => { const { ctx, agent } = await mount() expect(await modelFace(ctx, agent)).toMatchSnapshot() const prompt = await ctx.systemPrompt.assemble({ agent, scope: agent }) expect(prompt.sections.find(section => section.name === 'tool:visualizer')?.text) .toBe(visualizerSystemPrompt()) const guidance = ctx.tools.get('widget_guidelines', agent)! const show = ctx.tools.get('show_widget', agent)! expect(ctx.tools.schemas()).toEqual([]) const mockupGuidelines = await ctx.tools.execute({ signal: SIGNAL, callId: ToolCallId('mockup'), name: 'widget_guidelines', arguments: { modules: ['mockup'] }, agent, }) const mockupGuidelineText = mockupGuidelines.content .flatMap(item => item.type === 'text' ? [item.text] : []) .join('\n') expect(mockupGuidelineText).toContain('native controls') const interactiveGuidelines = await ctx.tools.execute({ signal: SIGNAL, callId: ToolCallId('interactive'), name: 'widget_guidelines', arguments: { modules: ['interactive'] }, agent, }) const interactiveGuidelineText = interactiveGuidelines.content .flatMap(item => item.type === 'text' ? [item.text] : []) .join('\n') expect(interactiveGuidelineText).toContain('window.dshWidget.sendPrompt') expect(interactiveGuidelineText).toContain('Call show_widget next') expect(visualizerSystemPrompt()).toContain('choose presentation details yourself') expect(visualizerSystemPrompt()).toContain('use no file, shell, editing, or preview step') expect(interactiveGuidelineText).toContain('one primary control per value') expect(interactiveGuidelineText).toContain('Give every control a clear label') expect(interactiveGuidelineText).not.toContain('window.dshWidget.onInit') expect(interactiveGuidelineText).not.toContain('window.dshWidget.reportState') expect(guidance.parameters).toEqual({ type: 'object', properties: { modules: { type: 'array', items: { type: 'string', enum: ['diagram', 'mockup', 'interactive', 'chart', 'illustration'] }, description: 'Choose every relevant module; content and behavior are independent, so combine modules when useful. diagram: nodes and relationships. chart: quantitative data. illustration: a scene or image. interactive: motion that contributes to the presentation, or direct manipulation and adjustable inputs requested by the user. mockup: a product surface shown to explain one interaction.', }, }, required: ['modules'], }) expect(show.description) .toBe('Render one temporary inline visual from conversation content or completed tool results. Source beginning with ' }, { kind: 'svg' }, )[0] expect(staticReceipt?.type === 'text' ? staticReceipt.text : '') .toBe('Widget "Static" accepted (svg). It is final for this response; finish with brief supporting prose.') expect((show.output.schema as { properties: { kind: { enum: string[] } } }).properties.kind.enum) .toEqual(['svg', 'html']) const sourceDescription = JSON.stringify(show.parameters) expect(sourceDescription).toContain('For HTML: one fragment') expect(sourceDescription).toContain('inline