From 2548bb4acfbb7e63d6fa78e30cd34a7f6b9c1929 Mon Sep 17 00:00:00 2001 From: Yichen Jiang Date: Wed, 21 Oct 2026 14:53:05 +0800 Subject: [PATCH] test(web-search): adapt fixtures to master's model selection and projections Master moved the step's model route into the assembly context: the agent loop fixes it per step and registers the prompt's provider variable from it, and installModelSelection no longer takes a mutable selection. The tool-web readiness fixture now registers that variable and passes the step's modelSelection to each assembly. AgentRegistry now needs the session projection registry, so the web-search-deepseek initiator fixtures and the Loader composition in chat-endpoint.spec.ts mount it, as master's own fixtures in this package do. --- packages/web/tool-web/tests/tool-web.spec.ts | 21 ++++++++----------- .../tests/chat-endpoint.spec.ts | 3 +++ .../tests/deepseek.spec.ts | 2 ++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/web/tool-web/tests/tool-web.spec.ts b/packages/web/tool-web/tests/tool-web.spec.ts index dc40344ddb..8c552c1b3d 100644 --- a/packages/web/tool-web/tests/tool-web.spec.ts +++ b/packages/web/tool-web/tests/tool-web.spec.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import { installModelSelection, type ModelSelectionRef } from '@deepseek-ai/dsh-agent' +import type { ModelSelection } from '@deepseek-ai/dsh-agent' import { createScope, type Scope } from '@deepseek-ai/dsh-scope' import TurndownService from 'turndown' import { ToolCallId } from '@deepseek-ai/dsh-llm' @@ -1086,26 +1086,23 @@ describe('web_search offering per model request', () => { } /** - * Mount the real prompt, tool, and web services with tool-web. Model selection is - * installed first, the order a tool-web reload produces once a Session exists. + * Mount the real prompt, tool, and web services with tool-web. The prompt's `provider` + * variable comes from the step's model selection, as the agent loop registers it. * @param setup - registered providers, the configured search provider, and the selected route. - * @returns the Session's model selection, tool-web's fiber, and a reader for one model request. + * @returns the step's model selection, tool-web's fiber, and a reader for one model request. */ async function compose(setup: { providers: WebSearchProvider[]; searchProvider?: string; route?: string }) { const ctx = new Context() mounted.push(ctx) - const selection: ModelSelectionRef = { - current: { provider: setup.route ?? 'deepseek-official', model: 'deepseek-v4-flash' }, - assembled: undefined, - } - installModelSelection(ctx, selection) + const selection: ModelSelection = { provider: setup.route ?? 'deepseek-official', model: 'deepseek-v4-flash' } await ctx.plugin(SystemPrompt) + ctx.systemPrompt.variable('provider', context => context.modelSelection?.provider) await ctx.plugin(ToolRuntime) await ctx.plugin(WebRuntime, setup.searchProvider === undefined ? {} : { searchProvider: setup.searchProvider }) for (const provider of setup.providers) ctx.web.registerSearchProvider(provider) const fiber = await ctx.plugin(ToolWeb, {}) const request = async (): Promise<{ tools: string[]; prompt: string }> => { - const assembly = await ctx.systemPrompt.assemble({}) + const assembly = await ctx.systemPrompt.assemble({ modelSelection: { ...selection } }) return { tools: assembly.tools.map(tool => tool.name), prompt: renderPrompt(assembly) } } return { ctx, selection, fiber, request } @@ -1141,9 +1138,9 @@ describe('web_search offering per model request', () => { it('follows the model selected for each request', async () => { const { selection, request } = await compose({ providers: [routeProvider('deepseek', ['deepseek-account'])], route: 'deepseek-account' }) expect((await request()).tools).toContain('web_search') - selection.current = { provider: 'deepseek-official', model: 'deepseek-v4-flash' } + selection.provider = 'deepseek-official' expect((await request()).tools).not.toContain('web_search') - selection.current = { provider: 'deepseek-account', model: 'deepseek-v4-flash' } + selection.provider = 'deepseek-account' expect((await request()).tools).toContain('web_search') }) diff --git a/packages/web/web-search-deepseek/tests/chat-endpoint.spec.ts b/packages/web/web-search-deepseek/tests/chat-endpoint.spec.ts index 208031f641..61552e159a 100644 --- a/packages/web/web-search-deepseek/tests/chat-endpoint.spec.ts +++ b/packages/web/web-search-deepseek/tests/chat-endpoint.spec.ts @@ -17,6 +17,7 @@ import { createLaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environ import LlmRuntime from '@deepseek-ai/dsh-llm' import * as Official from '@deepseek-ai/dsh-llm-deepseek-api-key' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' +import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import WebRuntime from '@deepseek-ai/dsh-web' import * as deepseekPlugin from '@deepseek-ai/dsh-web-search-deepseek' @@ -55,6 +56,7 @@ async function compose(composition: Composition): Promise { const rows = [ { id: 'llm', name: '@deepseek-ai/dsh-llm' }, { id: 'session', name: '@deepseek-ai/dsh-session' }, + { id: 'session-projection', name: '@deepseek-ai/dsh-session-projection' }, { id: 'agents', name: '@deepseek-ai/dsh-agent' }, { id: 'llm-deepseek', name: '@deepseek-ai/dsh-llm-deepseek-api-key', @@ -67,6 +69,7 @@ async function compose(composition: Composition): Promise { await writeFile(configPath, JSON.stringify(rows)) const modules = new Map([ ['@deepseek-ai/dsh-llm', LlmRuntime], ['@deepseek-ai/dsh-session', SessionStore], + ['@deepseek-ai/dsh-session-projection', SessionProjectionRegistry], ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-llm-deepseek-api-key', Official], ['@deepseek-ai/dsh-web', WebRuntime], ['@deepseek-ai/dsh-web-search-deepseek', deepseekPlugin], ]) diff --git a/packages/web/web-search-deepseek/tests/deepseek.spec.ts b/packages/web/web-search-deepseek/tests/deepseek.spec.ts index 76e0bf56a6..57837e4fb3 100644 --- a/packages/web/web-search-deepseek/tests/deepseek.spec.ts +++ b/packages/web/web-search-deepseek/tests/deepseek.spec.ts @@ -913,6 +913,7 @@ describe('web-search-deepseek search readiness', () => { expect(await ctx.web.searchReady('deepseek-account')).toBe(false) // A search on that route reads the same grant before any key and fails instead of trying the key. await ctx.plugin(SessionStore) + await ctx.plugin(SessionProjectionRegistry) await ctx.plugin(AgentRegistry) const session = ctx.sessions.create(SessionId('web-search-unreadable-grant')) session.append('turn/start', { turn: 1 }) @@ -939,6 +940,7 @@ describe('web-search-deepseek route policy', () => { const ctx = new Context() try { await ctx.plugin(SessionStore) + await ctx.plugin(SessionProjectionRegistry) await ctx.plugin(AgentRegistry) await ctx.plugin(WebRuntime, { searchProvider: DEEPSEEK_PROVIDER_ID }) await ctx.plugin(deepseekPlugin, config)