From 4a84bc3f7e333821df8cb8dedfbc9cb73293ec29 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Mon, 19 Oct 2026 15:04:34 +0800 Subject: [PATCH] test(tools): migrate remaining executor fixtures and compatibility checks --- package.json | 2 ++ .../core/agent-tool-presentation/src/index.ts | 2 ++ .../tests/agent-tool-presentation.spec.ts | 3 +++ .../tests/loader-composition.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 2 +- .../tests/composition.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 2 +- packages/goal/tool-goal/tests/tool-goal.spec.ts | 3 ++- .../llm-deepseek/tests/account-routing.spec.ts | 4 +++- packages/llm/llm-pi-ai/package.json | 1 + .../tests/completed-tool-arguments.spec.ts | 2 +- .../llm-retry/tests/loader-composition.spec.ts | 2 +- .../tests/tool-workspace-dependencies.spec.ts | 3 ++- .../tool-todo/tests/loader-composition.spec.ts | 4 ++-- pnpm-lock.yaml | 9 +++++++++ scripts/smoke-python-runtime.py | 3 ++- snapshots/sdk/sdk.snapshot.ts | 2 +- snapshots/sdk/tool-error-details/deny.mjs | 4 +++- .../scheduler-failure.mjs | 17 ++++++++--------- .../session/advanced-toolchain/presentation.mjs | 6 +++++- 20 files changed, 51 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 39c7f94f95..c6de85db40 100644 --- a/package.json +++ b/package.json @@ -221,6 +221,8 @@ "devDependencies": { "@deepseek-ai/dsh-hooks-claude-code": "workspace:*", "@deepseek-ai/dsh-hooks-codex": "workspace:*", + "@deepseek-ai/dsh-tool-executor-native": "workspace:*", + "@deepseek-ai/dsh-tool-executor-ptc": "workspace:*", "@deepseek-ai/dsh-tool-ralph": "workspace:*", "@deepseek-ai/dsh-tool-terminal": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:*", diff --git a/packages/core/agent-tool-presentation/src/index.ts b/packages/core/agent-tool-presentation/src/index.ts index 7531ba183e..cc621472e3 100644 --- a/packages/core/agent-tool-presentation/src/index.ts +++ b/packages/core/agent-tool-presentation/src/index.ts @@ -38,6 +38,7 @@ export interface Config { * Runtime schema. * @deprecated Select the native or PTC executor plugin directly instead of configuring a mode. */ +// oxlint-disable-next-line typescript/no-deprecated -- The compatibility schema validates its own deprecated configuration. export const Config: z = z.object({ mode: z.union(['native', 'ptc'] as const).required(), }) @@ -48,6 +49,7 @@ export const Config: z = z.object({ * @param config - the selected presentation. * @deprecated Mount @deepseek-ai/dsh-tool-executor-native or @deepseek-ai/dsh-tool-executor-ptc directly. */ +// oxlint-disable-next-line typescript/no-deprecated -- The compatibility plugin still accepts this configuration. export function apply(ctx: Context, config: Config): void { ctx.plugin(config.mode === 'native' ? NativeToolExecutor : PtcToolExecutor) } diff --git a/packages/core/agent-tool-presentation/tests/agent-tool-presentation.spec.ts b/packages/core/agent-tool-presentation/tests/agent-tool-presentation.spec.ts index c301280d1c..3dcbbc747c 100644 --- a/packages/core/agent-tool-presentation/tests/agent-tool-presentation.spec.ts +++ b/packages/core/agent-tool-presentation/tests/agent-tool-presentation.spec.ts @@ -48,6 +48,7 @@ async function host(options: { runtime?: boolean } = {}) { } /** Mount the row under one agent's scope, as a preset subtree does. */ +// oxlint-disable-next-line typescript/no-deprecated -- Exercise the supported compatibility plugin configuration. async function mount(ctx: Context, config: Config, id = 'agent') { const agent = { id: SessionId(id) } as Agent let inner!: Context @@ -62,6 +63,7 @@ async function mount(ctx: Context, config: Config, id = 'agent') { describe('the tool-presentation row', () => { it('rejects an unsupported presentation mode in configuration', () => { + // oxlint-disable-next-line typescript/no-deprecated -- The compatibility schema must reject unsupported modes. expect(() => Config({ mode: 'both' } as never)).toThrow() }) @@ -119,6 +121,7 @@ describe('the tool-presentation row', () => { it('requires a mode rather than defaulting one', () => { // An omitted value would mean the row was composed for nothing: a preset // without this row already gets the deployment default. + // oxlint-disable-next-line typescript/no-deprecated -- The compatibility schema still requires an explicit mode. expect(() => Config({} as never)).toThrow() }) }) diff --git a/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts b/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts index c02ece4f6f..88dfbf6897 100644 --- a/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts +++ b/packages/experimental/browser-use-stagehand-native/tests/loader-composition.spec.ts @@ -81,7 +81,7 @@ it('loads browser tools from cordis.yml, logs browser results, and admits the sc ['@deepseek-ai/dsh-session-projection', SessionProjectionRegistry], ['@deepseek-ai/dsh-system-prompt', SystemPrompt], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-agent-loop', AgentLoop], ['@deepseek-ai/dsh-attachment-local', LocalAttachmentStore], diff --git a/packages/experimental/claude-code-mods/tests/loader-composition.spec.ts b/packages/experimental/claude-code-mods/tests/loader-composition.spec.ts index 4c1fb0d546..21cf21c7ad 100644 --- a/packages/experimental/claude-code-mods/tests/loader-composition.spec.ts +++ b/packages/experimental/claude-code-mods/tests/loader-composition.spec.ts @@ -46,7 +46,7 @@ it('loads from cordis.yml, counts the model\'s tool calls, and answers /tally th ['@deepseek-ai/dsh-fs-local', LocalFileSystem], ['@deepseek-ai/dsh-working-directory', WorkingDirectory], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-agent-loop', AgentLoop], ['@deepseek-ai/dsh-commands', CommandRuntime], diff --git a/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts b/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts index f23deaa812..e2b123829a 100644 --- a/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts +++ b/packages/experimental/computer-use-cua-driver-mcp/tests/composition.spec.ts @@ -65,7 +65,7 @@ async function load(mode?: string): Promise<{ ctx: Context; root: string; model: ['@deepseek-ai/dsh-computer-use', ComputerUse], ['@deepseek-ai/dsh-system-prompt', SystemPrompt], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-llm', LlmRuntime], ['@deepseek-ai/dsh-session', SessionStore], ['@deepseek-ai/dsh-agent', AgentRegistry], diff --git a/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts b/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts index df447f6810..f3bb7e05b3 100644 --- a/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts +++ b/packages/experimental/computer-use-cua-driver-native/tests/loader-composition.spec.ts @@ -67,7 +67,7 @@ it('loads from cordis.yml and logs the native screenshot before the next model r ['@deepseek-ai/dsh-session-projection', SessionProjectionRegistry], ['@deepseek-ai/dsh-system-prompt', SystemPrompt], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-agent-loop', AgentLoop], ['@deepseek-ai/dsh-attachment-local', LocalAttachmentStore], diff --git a/packages/goal/tool-goal/tests/tool-goal.spec.ts b/packages/goal/tool-goal/tests/tool-goal.spec.ts index e4468c642c..5ef28599a9 100644 --- a/packages/goal/tool-goal/tests/tool-goal.spec.ts +++ b/packages/goal/tool-goal/tests/tool-goal.spec.ts @@ -157,8 +157,9 @@ describe('goal tool registration and presentation', () => { const { ctx, fiber } = await harness({ blockedAfterConsecutiveRounds: 5 }) expect(['create_goal', 'get_goal', 'update_goal'].map(name => ctx.tools.get(name)?.name)) .toEqual(['create_goal', 'get_goal', 'update_goal']) + const pipeline = new ToolExecutionPipeline(ctx, { get: (name, scope) => ctx.tools.get(name, scope) }) for (const name of ['create_goal', 'get_goal', 'update_goal']) { - expect(new ToolExecutionPipeline(ctx, { get: (name, scope) => ctx.tools.get(name, scope) }).executionMode({ signal: testToolSignal, callId: ToolCallId(name), name, arguments: {} })) + expect(pipeline.executionMode({ signal: testToolSignal, callId: ToolCallId(name), name, arguments: {} })) .toEqual({ kind: 'exclusive' }) } const section = (await ctx.systemPrompt.assemble()).sections.find(item => item.name === 'tool:goal') diff --git a/packages/llm/llm-deepseek/tests/account-routing.spec.ts b/packages/llm/llm-deepseek/tests/account-routing.spec.ts index 72e46ed54c..83285250d4 100644 --- a/packages/llm/llm-deepseek/tests/account-routing.spec.ts +++ b/packages/llm/llm-deepseek/tests/account-routing.spec.ts @@ -33,7 +33,9 @@ async function harness() { const ctx = new Context() contexts.push(ctx) installAccountTaskCancellation(ctx) - for (const plugin of [LlmRuntime, SessionStore, SessionProjectionRegistry, SystemPrompt, ToolRuntime, NativeToolExecutor, AgentRegistry]) { + for (const plugin of [ + LlmRuntime, SessionStore, SessionProjectionRegistry, SystemPrompt, ToolRuntime, NativeToolExecutor, AgentRegistry, + ]) { await ctx.plugin(plugin) } await ctx.plugin(AgentLoop, { agents: [] }) diff --git a/packages/llm/llm-pi-ai/package.json b/packages/llm/llm-pi-ai/package.json index 572c90e9fb..22210a134d 100644 --- a/packages/llm/llm-pi-ai/package.json +++ b/packages/llm/llm-pi-ai/package.json @@ -61,6 +61,7 @@ "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-settings": "workspace:*", "@deepseek-ai/dsh-timeout": "workspace:*", + "@deepseek-ai/dsh-tool-testkit": "workspace:*", "@deepseek-ai/dsh-tools": "workspace:*" }, "peerDependenciesMeta": { diff --git a/packages/llm/llm-pi-ai/tests/completed-tool-arguments.spec.ts b/packages/llm/llm-pi-ai/tests/completed-tool-arguments.spec.ts index 9bc6c42757..16b143a4e0 100644 --- a/packages/llm/llm-pi-ai/tests/completed-tool-arguments.spec.ts +++ b/packages/llm/llm-pi-ai/tests/completed-tool-arguments.spec.ts @@ -7,7 +7,7 @@ import type { StreamChunk } from '@deepseek-ai/dsh-llm' import { PiAiAdapter } from '@deepseek-ai/dsh-llm-pi-ai' import { mountAgentLoopTestDependencies, mountAgentLoopTestHarness } from '@deepseek-ai/dsh-agent-loop-testkit' import { SessionId } from '@deepseek-ai/dsh-session' -import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' +import { defineContentToolFixture } from '@deepseek-ai/dsh-tool-testkit' import { resolveProfiles } from '../src/config.ts' import { memoryAuth } from './auth-double.ts' import { anthropicFrame, anthropicMessageStart, closeMockServers, mockServer } from './mock-server.ts' diff --git a/packages/llm/llm-retry/tests/loader-composition.spec.ts b/packages/llm/llm-retry/tests/loader-composition.spec.ts index 851cb0868a..a83ec7f3cb 100644 --- a/packages/llm/llm-retry/tests/loader-composition.spec.ts +++ b/packages/llm/llm-retry/tests/loader-composition.spec.ts @@ -65,7 +65,7 @@ async function loadYaml(lines: readonly string[]): Promise { ['@deepseek-ai/dsh-session-projection', SessionProjectionRegistry], ['@deepseek-ai/dsh-system-prompt', SystemPrompt], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-llm-retry', retry], ['@deepseek-ai/dsh-agent-loop', AgentLoop], diff --git a/packages/skill/tool-workspace-dependencies/tests/tool-workspace-dependencies.spec.ts b/packages/skill/tool-workspace-dependencies/tests/tool-workspace-dependencies.spec.ts index 19d1748725..4e1640c95f 100644 --- a/packages/skill/tool-workspace-dependencies/tests/tool-workspace-dependencies.spec.ts +++ b/packages/skill/tool-workspace-dependencies/tests/tool-workspace-dependencies.spec.ts @@ -251,7 +251,8 @@ it('loads the real tool through Cordis, exposes payload paths in place, and unre await ctx.plugin(Loader) ctx.loader.builtins.include = Include Object.assign(ctx.loader.builtins, { - agents: AgentRegistry, systemPrompt: SystemPrompt, tools: ToolRuntime, toolExecutor: NativeToolExecutor, dependencies: workspaceDependencies, + agents: AgentRegistry, systemPrompt: SystemPrompt, tools: ToolRuntime, + toolExecutor: NativeToolExecutor, dependencies: workspaceDependencies, }) const config = join(directory, 'cordis.yml') await writeFile(config, `- name: cordis:agents\n- name: cordis:systemPrompt\n- name: cordis:tools\n- name: cordis:toolExecutor\n- name: cordis:dependencies\n config:\n source: ${JSON.stringify(source)}\n`) diff --git a/packages/todo/tool-todo/tests/loader-composition.spec.ts b/packages/todo/tool-todo/tests/loader-composition.spec.ts index cc0acfebfa..8f636531ec 100644 --- a/packages/todo/tool-todo/tests/loader-composition.spec.ts +++ b/packages/todo/tool-todo/tests/loader-composition.spec.ts @@ -62,7 +62,7 @@ async function boot(configLines: readonly string[]): Promise { "- name: '@deepseek-ai/dsh-agent'", "- name: '@deepseek-ai/dsh-system-prompt'", "- name: '@deepseek-ai/dsh-tools'", - "- name: '@deepseek-ai/dsh-tool-executor-native'", + "- name: '@deepseek-ai/dsh-tool-executor-native'", "- name: '@deepseek-ai/dsh-session-projection'", "- name: '@deepseek-ai/dsh-tool-todo'", ...configLines.length > 0 ? [' config:', ...configLines] : [], @@ -78,7 +78,7 @@ async function boot(configLines: readonly string[]): Promise { ['@deepseek-ai/dsh-agent', AgentRegistry], ['@deepseek-ai/dsh-system-prompt', SystemPrompt], ['@deepseek-ai/dsh-tools', ToolRuntime], - ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], + ['@deepseek-ai/dsh-tool-executor-native', NativeToolExecutor], ['@deepseek-ai/dsh-session-projection', SessionProjectionRegistry], ['@deepseek-ai/dsh-tool-todo', ToolTodo], ]) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 108496405b..5fe40ee5bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,6 +87,12 @@ importers: '@deepseek-ai/dsh-skill-office': specifier: workspace:* version: link:packages/skill/skill-office + '@deepseek-ai/dsh-tool-executor-native': + specifier: workspace:* + version: link:packages/core/tool-executor-native + '@deepseek-ai/dsh-tool-executor-ptc': + specifier: workspace:* + version: link:packages/core/tool-executor-ptc '@deepseek-ai/dsh-tool-ralph': specifier: workspace:* version: link:packages/experimental/tool-ralph @@ -11685,6 +11691,9 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:* version: link:../../util/timeout + '@deepseek-ai/dsh-tool-testkit': + specifier: workspace:* + version: link:../../test-support/tool-testkit '@deepseek-ai/dsh-tools': specifier: workspace:* version: link:../../core/tools diff --git a/scripts/smoke-python-runtime.py b/scripts/smoke-python-runtime.py index 0d6260b79c..3f4cee6fe4 100644 --- a/scripts/smoke-python-runtime.py +++ b/scripts/smoke-python-runtime.py @@ -252,7 +252,8 @@ def write_advanced_profile_patch( ) -> Path: """Write the shared custom, snapshot, and restart profile patch.""" return write_profile_patch(root, name, sessions, [ - {"id": "tools", "config": {"mode": mode}}, + {"id": "tool-executor-native", "disabled": mode != "native"}, + {"id": "tool-executor-ptc", "disabled": mode != "ptc"}, { "id": "system-prompt", "config": { diff --git a/snapshots/sdk/sdk.snapshot.ts b/snapshots/sdk/sdk.snapshot.ts index 051cfb6026..6f05d3a773 100644 --- a/snapshots/sdk/sdk.snapshot.ts +++ b/snapshots/sdk/sdk.snapshot.ts @@ -1068,7 +1068,7 @@ describe('TypeScript SDK snapshots over the jsonrpc runtime', () => { const events = results.flatMap(result => result.events) const headers = events.filter(event => event.type === 'request/header') .map(event => (event.data.header as { tools: { name: string }[] }).tools.map(tool => tool.name)) - expect(headers).toHaveLength(2) + expect(headers, JSON.stringify(events.filter(event => event.type === 'turn/end' || event.type === 'tool/result'))).toHaveLength(2) expect(headers[0]).toContain('bash') expect(headers[0]).not.toContain('run_code') expect(headers[1]).toEqual(['run_code']) diff --git a/snapshots/sdk/tool-error-details/deny.mjs b/snapshots/sdk/tool-error-details/deny.mjs index 62313c5abe..053818812e 100644 --- a/snapshots/sdk/tool-error-details/deny.mjs +++ b/snapshots/sdk/tool-error-details/deny.mjs @@ -1,4 +1,6 @@ /** A fixed error producer for SDK transport coverage; it does not enable Auto. */ +import { PtcExecutor } from '@deepseek-ai/dsh-tool-executor-ptc' + export const name = 'structured-denial-fixture' export const inject = ['tools'] export function apply(ctx) { @@ -18,6 +20,6 @@ export function apply(ctx) { ctx.on('tools/result', (exec, result) => { if (exec.name !== 'bash' || exec.parent !== undefined || result.error?.info?.code !== 'AUTO_REVIEW_DENIED' || exec.agent === undefined) return - exec.agent.ctx.tools.presentAs('ptc') + exec.agent.ctx.tools.setExecutor(new PtcExecutor(exec.agent.ctx)) }) } diff --git a/snapshots/sdk/tool-scheduler-recovery/scheduler-failure.mjs b/snapshots/sdk/tool-scheduler-recovery/scheduler-failure.mjs index 46761aa98a..765d7f1d23 100644 --- a/snapshots/sdk/tool-scheduler-recovery/scheduler-failure.mjs +++ b/snapshots/sdk/tool-scheduler-recovery/scheduler-failure.mjs @@ -1,15 +1,14 @@ /** Reject one scheduler preparation to exercise the terminal internal-failure path. */ +import { NativeToolExecutor } from '@deepseek-ai/dsh-tool-executor-native' + export const inject = ['tools'] /** @param {import('@deepseek-ai/cordis').Context} ctx - Scenario-owned runtime. */ export function apply(ctx) { - // Inspect the active instance's key so the fixture cannot introduce a second tools module. - const key = Object.getOwnPropertySymbols(ctx.tools) - .find(symbol => symbol.description === '@deepseek-ai/dsh-tools.scheduler') - if (key === undefined) throw new Error('Scheduler failure fixture requires the active tool scheduler') - const scheduler = ctx.tools[key] - const prepare = scheduler.prepare - ctx.effect(() => { + ctx.on('agent/created', ({ agent }) => { + const executor = new NativeToolExecutor(agent.ctx) + const scheduler = executor.pipeline + const prepare = scheduler.prepare scheduler.prepare = async input => { if (input.callId === 'scheduler-fail') { scheduler.prepare = prepare @@ -17,6 +16,6 @@ export function apply(ctx) { } return prepare.call(scheduler, input) } - return () => { scheduler.prepare = prepare } - }, 'scheduler failure fixture') + agent.ctx.tools.setExecutor(executor) + }) } diff --git a/snapshots/session/advanced-toolchain/presentation.mjs b/snapshots/session/advanced-toolchain/presentation.mjs index 13096eabea..073616092b 100644 --- a/snapshots/session/advanced-toolchain/presentation.mjs +++ b/snapshots/session/advanced-toolchain/presentation.mjs @@ -1,4 +1,7 @@ /** Select PTC for the parent program, then restore native calls before child creation. */ +import { NativeToolExecutor } from '@deepseek-ai/dsh-tool-executor-native' +import { PtcExecutor } from '@deepseek-ai/dsh-tool-executor-ptc' + export const name = 'advanced-toolchain-presentation' export const inject = ['tools'] @@ -7,9 +10,10 @@ export function apply(ctx) { ctx.on('tools/result', (exec, result) => { if (exec.agent === undefined || exec.parent !== undefined || result.error !== undefined) return if (exec.name === 'cordis_inspect_list' && !selections.has(exec.agent)) { - selections.set(exec.agent, exec.agent.ctx.tools.presentAs('ptc')) + selections.set(exec.agent, exec.agent.ctx.tools.setExecutor(new PtcExecutor(exec.agent.ctx))) } else if (exec.name === 'run_code') { selections.get(exec.agent)?.() + exec.agent.ctx.tools.setExecutor(new NativeToolExecutor(exec.agent.ctx)) selections.set(exec.agent, null) } })