| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /** REAL-composition proof for Host authority and the preset model contribution. */
- import { mkdtemp, rm, writeFile } from 'node:fs/promises'
- import { tmpdir } from 'node:os'
- import { join } from 'node:path'
- import { fileURLToPath, pathToFileURL } from 'node:url'
- import { afterEach, describe, expect, it, vi } from 'vitest'
- import { Context } from '@deepseek-ai/cordis'
- import Include from '@deepseek-ai/cordis-plugin-include'
- import Loader from '@deepseek-ai/cordis-plugin-loader'
- import { composeEntries, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot'
- import AgentRegistry from '@deepseek-ai/dsh-agent'
- import type { Agent } from '@deepseek-ai/dsh-agent'
- import { createScope } from '@deepseek-ai/dsh-scope'
- import { SessionId } from '@deepseek-ai/dsh-session'
- import { Session } from '@deepseek-ai/dsh-session'
- import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
- import ToolRuntime from '@deepseek-ai/dsh-tools'
- import VisualizerService from '../src/index.ts'
- import * as VisualizerModel from '../src/model.ts'
- const REPOSITORY_ROOT = fileURLToPath(new URL('../../../../', import.meta.url))
- const bundlePatch = (name: 'base' | 'headless') => loadOverlayPatches(
- 'visualizer composition test',
- join(REPOSITORY_ROOT, 'packages', 'bundle', name, 'cordis.patch.yml'),
- )
- const contexts: Context[] = []
- const roots: string[] = []
- afterEach(async () => {
- await Promise.all(contexts.splice(0).map(async (ctx) => { await ctx.fiber.dispose() }))
- await Promise.all(roots.splice(0).map(async (root) => { await rm(root, { recursive: true, force: true }) }))
- })
- async function boot(rows: string[]): Promise<{ ctx: Context; imports: string[] }> {
- const root = await mkdtemp(join(tmpdir(), 'dsh-visualizer-composition-'))
- roots.push(root)
- const configPath = join(root, 'cordis.yml')
- await writeFile(configPath, `${rows.join('\n')}\n`)
- const ctx = new Context()
- contexts.push(ctx)
- ctx.baseUrl = pathToFileURL(root).href + '/'
- await ctx.plugin(Loader)
- ctx.loader.builtins.include = Include
- const imports: string[] = []
- const modules = new Map<string, unknown>([
- ['@deepseek-ai/dsh-agent', AgentRegistry],
- ['@deepseek-ai/dsh-system-prompt', SystemPrompt],
- ['@deepseek-ai/dsh-tools', ToolRuntime],
- ['@deepseek-ai/dsh-tool-visualizer', VisualizerService],
- ['@deepseek-ai/dsh-tool-visualizer/model', VisualizerModel],
- ])
- ctx.loader.internal = {
- version: 'v2',
- async import(specifier: string) {
- imports.push(specifier)
- if (!modules.has(specifier)) throw new Error(`unexpected Loader import: ${specifier}`)
- return modules.get(specifier)
- },
- } as unknown as NonNullable<typeof ctx.loader.internal>
- await ctx.loader.create({ name: 'cordis:include', config: { path: pathToFileURL(configPath).href } })
- await ctx.loader.await()
- return { ctx, imports }
- }
- async function scopedBase(ctx: Context): Promise<Context> {
- let base: Context | undefined
- await ctx.plugin(Object.assign((inner: Context) => { base = inner }, { inject: ['systemPrompt', 'tools'] }))
- if (base === undefined) throw new Error('missing scoped test base')
- return base
- }
- async function mountPresetModel(ctx: Context) {
- const base = await scopedBase(ctx)
- const presetKey = { agentPreset: 'standard' }
- const presetScope = createScope(base, presetKey)
- const presetRoot = await mkdtemp(join(tmpdir(), 'dsh-visualizer-preset-row-'))
- roots.push(presetRoot)
- const composition = join(presetRoot, 'agent.cordis.yml')
- await writeFile(composition, [
- '- id: tool-visualizer',
- " name: '@deepseek-ai/dsh-tool-visualizer/model'",
- '',
- ].join('\n'))
- const modelTree = presetScope.ctx.plugin(Include, { path: pathToFileURL(composition).href })
- await modelTree.await()
- return { base, presetKey }
- }
- function registerPresetAgent(
- ctx: Context,
- preset: Awaited<ReturnType<typeof mountPresetModel>>,
- id: string,
- ) {
- const session = Session.create(SessionId(id))
- const agent = { id: session.id, session, ctx } as unknown as Agent
- const agentScope = createScope(preset.base, agent, { parent: preset.presetKey })
- Object.assign(agent, { ctx: agentScope.ctx.extend({ agent }) })
- ctx.agents.register(agent)
- return agent
- }
- async function expectVisualizerSurface(ctx: Context, agent: Agent, visible: boolean): Promise<void> {
- await vi.waitFor(async () => {
- expect(ctx.tools.schemas(agent).map(schema => schema.name).sort())
- .toEqual(visible ? ['show_widget', 'widget_guidelines'] : [])
- const prompt = await ctx.systemPrompt.assemble({ agent, scope: agent })
- expect(prompt.sections.some(section => section.name === 'tool:visualizer')).toBe(visible)
- })
- }
- describe('Visualizer Host composition', () => {
- it('keeps headless dormant and mounts the model wrapper only in full presets', () => {
- const headlessEntries = composeEntries([bundlePatch('base'), bundlePatch('headless')])
- expect(headlessEntries.some(entry => entry.name === '@deepseek-ai/dsh-tool-visualizer')).toBe(false)
- const presetModelRows = (id: 'standard' | 'minimal' | 'ptc' | 'cordis') => loadOverlayPatches(
- 'visualizer preset composition test',
- join(REPOSITORY_ROOT, 'packages/preset/agent-presets/presets', id, 'agent.cordis.yml'),
- ).filter(entry => entry.name === '@deepseek-ai/dsh-tool-visualizer/model')
- for (const id of ['standard', 'cordis'] as const) {
- const rows = presetModelRows(id)
- expect(rows).toHaveLength(1)
- expect(rows[0]?.disabled).toBeUndefined()
- }
- expect(presetModelRows('ptc')).toEqual([])
- expect(presetModelRows('minimal')).toEqual([])
- })
- it('boots the test-only Host and model through Loader without global model state', async () => {
- const { ctx, imports } = await boot([
- "- id: agents\n name: '@deepseek-ai/dsh-agent'",
- "- id: system-prompt\n name: '@deepseek-ai/dsh-system-prompt'",
- "- id: tools\n name: '@deepseek-ai/dsh-tools'",
- "- id: tool-visualizer\n name: '@deepseek-ai/dsh-tool-visualizer'",
- ])
- expect(ctx.tools.schemas()).toEqual([])
- expect((await ctx.systemPrompt.assemble()).sections.some(section => section.name === 'tool:visualizer'))
- .toBe(false)
- const preset = await mountPresetModel(ctx)
- const agent = registerPresetAgent(ctx, preset, 'test-standard')
- expect(imports).toContain('@deepseek-ai/dsh-tool-visualizer')
- expect(imports).toContain('@deepseek-ai/dsh-tool-visualizer/model')
- expect(ctx.tools.schemas(agent).map(schema => schema.name).sort())
- .toEqual(['show_widget', 'widget_guidelines'])
- const prompt = await ctx.systemPrompt.assemble({ agent, scope: agent })
- expect(prompt.sections.find(section => section.name === 'tool:visualizer')?.text)
- .toContain('Use show_widget for a temporary inline visual')
- })
- it('loads a dormant model wrapper without Host authority', async () => {
- const { ctx, imports } = await boot([
- "- id: agents\n name: '@deepseek-ai/dsh-agent'",
- "- id: system-prompt\n name: '@deepseek-ai/dsh-system-prompt'",
- "- id: tools\n name: '@deepseek-ai/dsh-tools'",
- ])
- const preset = await mountPresetModel(ctx)
- const agent = registerPresetAgent(ctx, preset, 'dormant-standard')
- expect(imports).toContain('@deepseek-ai/dsh-tool-visualizer/model')
- expect(ctx.get('visualizer')).toBeUndefined()
- expect(ctx.tools.schemas()).toEqual([])
- await expectVisualizerSurface(ctx, agent, false)
- })
- it('activates, withdraws, and reactivates the wrapper for existing and new Agents', async () => {
- const { ctx } = await boot([
- "- id: agents\n name: '@deepseek-ai/dsh-agent'",
- "- id: system-prompt\n name: '@deepseek-ai/dsh-system-prompt'",
- "- id: tools\n name: '@deepseek-ai/dsh-tools'",
- ])
- const preset = await mountPresetModel(ctx)
- const beforeAuthority = registerPresetAgent(ctx, preset, 'before-authority')
- await expectVisualizerSurface(ctx, beforeAuthority, false)
- const firstAuthorityId = await ctx.loader.create({ name: '@deepseek-ai/dsh-tool-visualizer' })
- await ctx.loader.await()
- await expectVisualizerSurface(ctx, beforeAuthority, true)
- const duringAuthority = registerPresetAgent(ctx, preset, 'during-authority')
- await expectVisualizerSurface(ctx, duringAuthority, true)
- await ctx.loader.remove(firstAuthorityId)
- await ctx.loader.await()
- await expectVisualizerSurface(ctx, beforeAuthority, false)
- await expectVisualizerSurface(ctx, duringAuthority, false)
- const betweenAuthorities = registerPresetAgent(ctx, preset, 'between-authorities')
- await expectVisualizerSurface(ctx, betweenAuthorities, false)
- await ctx.loader.create({ name: '@deepseek-ai/dsh-tool-visualizer' })
- await ctx.loader.await()
- await expectVisualizerSurface(ctx, beforeAuthority, true)
- await expectVisualizerSurface(ctx, duringAuthority, true)
- await expectVisualizerSurface(ctx, betweenAuthorities, true)
- const afterReactivation = registerPresetAgent(ctx, preset, 'after-reactivation')
- await expectVisualizerSurface(ctx, afterReactivation, true)
- })
- })
|