Преглед изворни кода

test(web): cover core profile request header

Yichen Jiang пре 1 месец
родитељ
комит
266629f1c3

+ 40 - 13
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
+        }
       }
     }
   })

+ 7 - 0
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"}}}}