diff --git a/apps/web/tests/core-web-profile.snapshot.ts b/apps/web/tests/core-web-profile.snapshot.ts index 92207de217..1178390837 100644 --- a/apps/web/tests/core-web-profile.snapshot.ts +++ b/apps/web/tests/core-web-profile.snapshot.ts @@ -3,12 +3,14 @@ import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { afterAll, beforeAll, describe, expect, it } from 'vitest' import type { AgentHandle } from '@deepseek-ai/dsh-agent' -import { CallId } from '@deepseek-ai/dsh-llm' +import { CallId, createUserMessage } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' -import { renderPrompt } from '@deepseek-ai/dsh-system-prompt' -import { launchWebScaffold, type WebScaffold } from './scaffold.ts' +import { assertFixtureInventory, launchWebScaffold, type WebScaffold } from './scaffold.ts' const CORE_WEB_OVERLAY = fileURLToPath(new URL('../../cli/config/core-web.cordis.yml', import.meta.url)) +const SNAPSHOT_DIR = fileURLToPath(new URL('./snapshots/core-web-profile', import.meta.url)) +const FIXTURE = join(SNAPSHOT_DIR, 'session.jsonl') +const PROMPT = 'Reply exactly CORE_WEB_REQUEST_OK and stop.' describe('core Web profile', () => { let scaffold: WebScaffold @@ -18,7 +20,7 @@ describe('core Web profile', () => { const systemPrompt = process.env.DSH_SYSTEM_PROMPT Reflect.deleteProperty(process.env, 'DSH_SYSTEM_PROMPT') try { - scaffold = await launchWebScaffold({ extraOverlayPath: CORE_WEB_OVERLAY }) + scaffold = await launchWebScaffold({ extraOverlayPath: CORE_WEB_OVERLAY, replayFixture: FIXTURE }) } finally { if (systemPrompt !== undefined) process.env.DSH_SYSTEM_PROMPT = systemPrompt } @@ -37,7 +39,16 @@ describe('core Web profile', () => { if (failures.length > 1) throw new AggregateError(failures, 'core Web profile smoke teardown failed') }) - it('boots and executes both tools through the shipped Web composition', async () => { + it('sends the RL prompt and tool schemas through a real request, then executes both tools', async () => { + agentHandle.agent.followup(createUserMessage({ + content: [{ type: 'text', text: PROMPT }], + source: { kind: 'user' }, + })) + await agentHandle.agent.whenIdle() + + const requestHeader = agentHandle.agent.session.requestHeader() + if (requestHeader === undefined) throw new Error('the core Web agent issued no model request') + const seedPath = join(scaffold.workspaceCwd, 'profile-smoke.txt') await writeFile(seedPath, 'CORE_WEB_EDITOR_OK\n') const signal = new AbortController().signal @@ -63,10 +74,9 @@ describe('core Web profile', () => { .replaceAll(scaffold.workspaceCwd, '{{cwd}}') .trimEnd() - const prompt = renderPrompt(await scaffold.ctx.systemPrompt.assemble()) expect({ - prompt, - tools: scaffold.ctx.tools.schemas().map(tool => tool.name), + prompt: requestHeader.system, + tools: requestHeader.tools?.map(tool => tool.name), bash: text(bash), editor: text(editor), }).toMatchInlineSnapshot(` @@ -82,6 +92,7 @@ describe('core Web profile', () => { ], } `) + expect(requestHeader.tools).toEqual(scaffold.ctx.tools.schemas(agentHandle.agent)) const entries = [...scaffold.ctx.loader.entries()] expect(entries.find(entry => entry.options.id === 'persistent-bash')?.fiber).toBeDefined() @@ -89,21 +100,37 @@ describe('core Web profile', () => { expect(entries.find(entry => entry.options.id === 'str-replace-editor')?.fiber).toBeDefined() expect(entries.find(entry => entry.options.id === 'web-runtime')?.fiber).toBeDefined() expect(entries.find(entry => entry.options.id === 'workspace-context')?.fiber).toBeUndefined() + await assertFixtureInventory(SNAPSHOT_DIR, ['session.jsonl']) }) it('uses DSH_SYSTEM_PROMPT as the complete prompt when configured', async () => { const previous = process.env.DSH_SYSTEM_PROMPT process.env.DSH_SYSTEM_PROMPT = 'RL prompt override' let overrideScaffold: WebScaffold | undefined + let overrideAgent: AgentHandle | undefined try { - overrideScaffold = await launchWebScaffold({ extraOverlayPath: CORE_WEB_OVERLAY }) - expect(renderPrompt(await overrideScaffold.ctx.systemPrompt.assemble())).toBe('RL prompt override') + overrideScaffold = await launchWebScaffold({ extraOverlayPath: CORE_WEB_OVERLAY, replayFixture: FIXTURE }) + overrideAgent = await overrideScaffold.ctx.agents.create({ + sessionId: SessionId('core-web-profile-override'), + meta: { cwd: overrideScaffold.workspaceCwd }, + agentOptions: { provider: 'deepseek-official', model: 'deepseek-v4-flash' }, + }) + overrideAgent.agent.followup(createUserMessage({ + content: [{ type: 'text', text: PROMPT }], + source: { kind: 'user' }, + })) + await overrideAgent.agent.whenIdle() + expect(overrideAgent.agent.session.requestHeader()?.system).toBe('RL prompt override') } finally { try { - await overrideScaffold?.close() + await overrideAgent?.dispose() } finally { - if (previous === undefined) Reflect.deleteProperty(process.env, 'DSH_SYSTEM_PROMPT') - else process.env.DSH_SYSTEM_PROMPT = previous + try { + await overrideScaffold?.close() + } finally { + if (previous === undefined) Reflect.deleteProperty(process.env, 'DSH_SYSTEM_PROMPT') + else process.env.DSH_SYSTEM_PROMPT = previous + } } } }) diff --git a/apps/web/tests/snapshots/core-web-profile/session.jsonl b/apps/web/tests/snapshots/core-web-profile/session.jsonl new file mode 100644 index 0000000000..04f0d62d15 --- /dev/null +++ b/apps/web/tests/snapshots/core-web-profile/session.jsonl @@ -0,0 +1,7 @@ +{"type":"session","version":0,"id":"{{sessionId}}","createdAt":1785974400000,"cwd":"{{cwd}}"} +{"type":"user/message","seq":0,"time":1785974400001,"data":{"content":[{"type":"text","text":"Reply exactly CORE_WEB_REQUEST_OK and stop."}],"source":{"kind":"user","rpcId":"{{rpcId}}"}},"surfaceOp":"append"} +{"type":"assistant/chunk","seq":1,"time":1785974400002,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":2,"time":1785974400003,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CORE_WEB_REQUEST_OK"}}} +{"type":"assistant/chunk","seq":3,"time":1785974400004,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CORE_WEB_REQUEST_OK"}}}} +{"type":"assistant/chunk","seq":4,"time":1785974400005,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":4}}}} +{"type":"assistant/chunk","seq":5,"time":1785974400006,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}