mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
Merge remote-tracking branch 'origin/master' into turtle/plugin-sticky-header-29bfdb179e18
This commit is contained in:
commit
a3b26c896b
970 files changed
+10686
-4443
No files matched your search
+2
-2
@@ -24,8 +24,8 @@
|
||||
en: 26e4b71366bebd1b
|
||||
zh: 10598e12b28c586e
|
||||
/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/verification:
|
||||
en: fbd101d4576afa92
|
||||
zh: 35f5d3c2f6cad6a8
|
||||
en: 983da6d0c09f5c10
|
||||
zh: ca7c86117a1a4d5f
|
||||
/agent-note-cooperative-tool-cancellation-at-the-registry-boundary/alternatives-considered:
|
||||
en: c4d86feb135d2ac4
|
||||
zh: 67c56c0bc2213949
|
||||
|
||||
@@ -46,7 +46,7 @@ This decision requires cancellation at the tool invocation boundary only. Making
|
||||
|
||||
## Verification
|
||||
|
||||
[`execution-signal-types.spec.ts`](../../../../packages/core/tools/tests/execution-signal-types.spec.ts) proves the required exact signal types, readonly observer and tool views, mutable-but-required around-dispatch view, and `defineTool()` inference. [`tools.spec.ts`](../../../../packages/core/tools/tests/tools.spec.ts) covers pre-aborted materialization, phase skipping, policy and wrapper races, body invocation classification, caller-signal fusion, error precedence, context retention, and quiescent drainage. [`tool-calls.spec.ts`](../../../../packages/core/agent-loop/tests/tool-calls.spec.ts) and [`contract-regressions.spec.ts`](../../../../packages/core/agent-loop/tests/contract-regressions.spec.ts) cover balanced durable results for undispatched siblings. [`ptc.spec.ts`](../../../../packages/core/tools/tests/ptc.spec.ts) and first-party integration suites cover explicit forwarding, while [`timeout-policy.spec.ts`](../../../../packages/guard/timeout-policy/tests/timeout-policy.spec.ts) preserves timeout ownership.
|
||||
[`execution-signal-types.spec.ts`](../../../../packages/core/tools/tests/execution-signal-types.spec.ts) proves the required exact signal types, readonly observer and tool views, mutable-but-required around-dispatch view, and `defineTool()` inference. [`tools.spec.ts`](../../../../packages/core/tools/tests/tools.spec.ts) covers pre-aborted materialization, phase skipping, policy and wrapper races, body invocation classification, caller-signal fusion, error precedence, context retention, and quiescent drainage. [`tool-calls.spec.ts`](../../../../packages/core/agent-loop/tests/tool-calls.spec.ts) and [`contract-regressions.spec.ts`](../../../../packages/core/agent-loop/tests/contract-regressions.spec.ts) cover balanced durable results for undispatched siblings. [`ptc.spec.ts`](../../../../packages/core/tool-executor-ptc/tests/ptc.spec.ts) and first-party integration suites cover explicit forwarding, while [`timeout-policy.spec.ts`](../../../../packages/guard/timeout-policy/tests/timeout-policy.spec.ts) preserves timeout ownership.
|
||||
|
||||
No registry test can prove that arbitrary third-party same-process code observes the signal or stops in bounded time. Capability tests continue to prove cancellation and quiescence at the boundary that owns each side effect.
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ Status: implemented
|
||||
|
||||
## 验证
|
||||
|
||||
[`execution-signal-types.spec.ts`](../../../../packages/core/tools/tests/execution-signal-types.spec.ts) 证明必填的精确信号类型、观察者与工具的只读视图、环绕调度可替换但不可删除的视图,以及 `defineTool()` 推断。[`tools.spec.ts`](../../../../packages/core/tools/tests/tools.spec.ts) 覆盖进入时已中止的物化与阶段跳过、策略和包装层竞态、工具主体调用分类、调用方信号融合、错误优先级、上下文保留和完全停稳。[`tool-calls.spec.ts`](../../../../packages/core/agent-loop/tests/tool-calls.spec.ts) 与 [`contract-regressions.spec.ts`](../../../../packages/core/agent-loop/tests/contract-regressions.spec.ts) 覆盖为未调度的同批调用补齐持久化结果。[`ptc.spec.ts`](../../../../packages/core/tools/tests/ptc.spec.ts) 和第一方集成测试覆盖显式转发,[`timeout-policy.spec.ts`](../../../../packages/guard/timeout-policy/tests/timeout-policy.spec.ts) 保持超时归属。
|
||||
[`execution-signal-types.spec.ts`](../../../../packages/core/tools/tests/execution-signal-types.spec.ts) 证明必填的精确信号类型、观察者与工具的只读视图、环绕调度可替换但不可删除的视图,以及 `defineTool()` 推断。[`tools.spec.ts`](../../../../packages/core/tools/tests/tools.spec.ts) 覆盖进入时已中止的物化与阶段跳过、策略和包装层竞态、工具主体调用分类、调用方信号融合、错误优先级、上下文保留和完全停稳。[`tool-calls.spec.ts`](../../../../packages/core/agent-loop/tests/tool-calls.spec.ts) 与 [`contract-regressions.spec.ts`](../../../../packages/core/agent-loop/tests/contract-regressions.spec.ts) 覆盖为未调度的同批调用补齐持久化结果。[`ptc.spec.ts`](../../../../packages/core/tool-executor-ptc/tests/ptc.spec.ts) 和第一方集成测试覆盖显式转发,[`timeout-policy.spec.ts`](../../../../packages/guard/timeout-policy/tests/timeout-policy.spec.ts) 保持超时归属。
|
||||
|
||||
任何注册表测试都无法证明任意第三方同进程代码会观察信号或在有界时间内停止。各能力的测试仍需在拥有相应副作用的边界证明取消与完全停稳。
|
||||
|
||||
|
||||
@@ -188,6 +188,10 @@ flowchart LR
|
||||
cfg --> plugin_dsh_base_mcp_resources
|
||||
plugin_dsh_base_tools["tools<br/>@deepseek-ai/dsh-tools"]
|
||||
cfg --> plugin_dsh_base_tools
|
||||
plugin_dsh_base_tool_executor_native["tool-executor-native<br/>@deepseek-ai/dsh-tool-executor-native"]
|
||||
cfg --> plugin_dsh_base_tool_executor_native
|
||||
plugin_dsh_base_tool_executor_ptc["tool-executor-ptc<br/>@deepseek-ai/dsh-tool-executor-ptc"]
|
||||
cfg --> plugin_dsh_base_tool_executor_ptc
|
||||
plugin_dsh_base_system_prompt["system-prompt<br/>@deepseek-ai/dsh-system-prompt"]
|
||||
cfg --> plugin_dsh_base_system_prompt
|
||||
plugin_dsh_base_agent_loop["agent-loop<br/>@deepseek-ai/dsh-agent-loop"]
|
||||
@@ -292,6 +296,8 @@ flowchart LR
|
||||
| `tool-web` | `@deepseek-ai/dsh-tool-web` |
|
||||
| `mcp-resources` | `@deepseek-ai/dsh-mcp-resources` |
|
||||
| `tools` | `@deepseek-ai/dsh-tools` |
|
||||
| `tool-executor-native` | `@deepseek-ai/dsh-tool-executor-native` |
|
||||
| `tool-executor-ptc` | `@deepseek-ai/dsh-tool-executor-ptc` |
|
||||
| `system-prompt` | `@deepseek-ai/dsh-system-prompt` |
|
||||
| `agent-loop` | `@deepseek-ai/dsh-agent-loop` |
|
||||
| `fs-sandbox` | `@deepseek-ai/dsh-fs-sandbox` |
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
- id: tool-executor-native
|
||||
disabled: true
|
||||
|
||||
- id: tool-executor-ptc
|
||||
disabled: false
|
||||
@@ -155,6 +155,7 @@
|
||||
"@deepseek-ai/dsh-subagent-spawn-in-process": "workspace:*",
|
||||
"@deepseek-ai/dsh-subprocess-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-system-prompt": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-testkit": "workspace:*",
|
||||
"@deepseek-ai/dsh-tools": "workspace:*",
|
||||
"@deepseek-ai/dsh-user-approval": "workspace:*",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
en: 8d2cfff9bab7327f
|
||||
zh: 21515ab6e6798504
|
||||
/dsh-cli-behavior-reference/web-profile:
|
||||
en: 850434e8ca162221
|
||||
zh: 4893613f97a21eb8
|
||||
en: 149c5571acd51baf
|
||||
zh: 300e3c2425273a92
|
||||
/dsh-cli-behavior-reference/shared-deployment-behavior:
|
||||
en: f40edcf903a51f3f
|
||||
zh: 8a9a915451047c8b
|
||||
|
||||
@@ -130,7 +130,7 @@ The base-backed modes treat the invoking directory as the default workspace root
|
||||
|
||||
New sessions in base-backed profiles default to the `workspace-write` permission preset. Bash and filesystem mutations are restricted to the session workspace and platform temporary roots; reads and network access are not confined, while process visibility depends on the selected sandbox backend — bwrap runs commands in a private PID namespace that hides host processes, and Landlock and Seatbelt leave host process visibility unchanged. `DSH_PERMISSION_MODE` changes the process fallback. Stored General-settings permissions affect later Web sessions, not an already-open one. The standalone `sdk-minimal` tree instead pins `danger-full-access` and mounts no approval or permission-settings service.
|
||||
|
||||
`DSH_TOOLS_MODE` selects `native` or `ptc` for the process; another value fails at boot. The shipped `minimal` agent preset keeps that deployment presentation, fixes the complete system prompt to `You are a helpful software engineer assistant.`, and provides the platform-selected persistent shell, `read_image`, and `working_directory`. It supports automatic context compaction and the human `/compact` command. Select 极简模式 when creating a Web session; the shared browser, workspace, persistence, sandbox, and permission host remains in place.
|
||||
Web, headless, and SDK inherit native tool execution from the base bundle; use a [PTC overlay](../config/examples/ptc.yml) to select PTC. The shipped `minimal` agent preset keeps that deployment presentation, fixes the complete system prompt to `You are a helpful software engineer assistant.`, and provides the platform-selected persistent shell, `read_image`, and `working_directory`. It supports automatic context compaction and the human `/compact` command. Select 极简模式 when creating a Web session; the shared browser, workspace, persistence, sandbox, and permission host remains in place.
|
||||
|
||||
## Shared deployment behavior
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ dsh web --help
|
||||
|
||||
基于 base 的 profile 中,新会话默认使用 `workspace-write` 权限预设。Bash 和文件系统修改仅限于会话 workspace 与平台临时根目录;读取和网络访问不受限制,进程可见性则取决于所选沙箱后端——bwrap 在私有 PID 命名空间中运行命令并隐藏宿主进程,Landlock 与 Seatbelt 保持宿主进程可见性不变。`DSH_PERMISSION_MODE` 更改进程后备值。General settings 中存储的权限影响后续 Web 会话,不改变已打开的会话。独立的 `sdk-minimal` 配置树则固定为 `danger-full-access`,且不挂载 approval 或权限 settings 服务。
|
||||
|
||||
`DSH_TOOLS_MODE` 为进程选择 `native` 或 `ptc`;其他值会导致启动失败。随附的 `minimal` agent preset 会保留该部署的呈现方式,将完整系统提示词固定为 `You are a helpful software engineer assistant.`,并提供按平台选择的持久 shell、`read_image` 和 `working_directory`。它支持自动上下文压缩和用户 `/compact` 命令。创建 Web 会话时请选择极简模式;共享的浏览器、workspace、持久化、沙箱与权限宿主保持不变。
|
||||
Web、headless 与 SDK 继承 base bundle 的原生工具执行;使用 [PTC overlay](../config/examples/ptc.yml) 可选择 PTC。随附的 `minimal` agent preset 会保留该部署的呈现方式,将完整系统提示词固定为 `You are a helpful software engineer assistant.`,并提供按平台选择的持久 shell、`read_image` 和 `working_directory`。它支持自动上下文压缩和用户 `/compact` 命令。创建 Web 会话时请选择极简模式;共享的浏览器、workspace、持久化、沙箱与权限宿主保持不变。
|
||||
|
||||
## 共享部署行为
|
||||
|
||||
|
||||
@@ -1268,6 +1268,7 @@ describe.skipIf(!existsSync(dshBin))('dsh BUILT bin (node lib/bin.js, no tsx)',
|
||||
['session-title', '@deepseek-ai/dsh-session-title'],
|
||||
['system-prompt', '@deepseek-ai/dsh-system-prompt'],
|
||||
['tools', '@deepseek-ai/dsh-tools'],
|
||||
['tool-executor-native', '@deepseek-ai/dsh-tool-executor-native'],
|
||||
['mcp-resources', '@deepseek-ai/dsh-mcp-resources'],
|
||||
['agent', '@deepseek-ai/dsh-agent'],
|
||||
['llm-retry', '@deepseek-ai/dsh-llm-retry'],
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { agentEvents, type Agent } from '@deepseek-ai/dsh-agent'
|
||||
import { ToolCallId } from '@deepseek-ai/dsh-llm'
|
||||
@@ -52,7 +53,7 @@ try {
|
||||
&& message.source.kind === 'skill-catalog')?.content
|
||||
: undefined
|
||||
const summary = (await ctx.skills.list()).find(skill => skill.name === 'dsh-badge')
|
||||
const result = await ctx.tools.execute({
|
||||
const result = await executeToolFixture(ctx, {
|
||||
callId: ToolCallId('dsh-badge-snapshot'),
|
||||
name: 'skill',
|
||||
arguments: { name: 'dsh-badge' },
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/** Optional bundles through the shipped Web Loader, live package manager, and real Agent loop. */
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
@@ -232,7 +233,7 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
|
||||
|
||||
it('loads the actual badge asset only while its bundle is selected', async () => {
|
||||
const owner = await agent()
|
||||
const load = (callId: string) => ctx.tools.execute({
|
||||
const load = (callId: string) => executeToolFixture(ctx, {
|
||||
callId: ToolCallId(callId), name: 'skill', arguments: { name: 'dsh-badge' },
|
||||
agent: owner.agent, signal: new AbortController().signal,
|
||||
})
|
||||
|
||||
@@ -555,7 +555,7 @@ describe('headless stream-json snapshots', () => {
|
||||
'--permission-mode', 'auto', '--approval-policy', 'never', '--json', 'Run the CLI probe.',
|
||||
],
|
||||
tsconfigPath,
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: mode, DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: mode, DSH_TELEMETRY_DISABLED: '1' },
|
||||
inspect: async (cwd) => {
|
||||
const logs = await persistedLogs(cwd, join(cwd, '.dsh', 'sessions'))
|
||||
expect(logs).toHaveLength(1)
|
||||
@@ -605,7 +605,7 @@ describe('headless stream-json snapshots', () => {
|
||||
const first = await runLoaderSmoke({
|
||||
label: 'headless Auto denied wake', cwd, binScript: dshBinScript, configPath: autoReviewOverlayPath,
|
||||
binArgs: [...args, '--permission-mode', 'auto', '--approval-policy', 'never', 'Run the CLI probe.'], tsconfigPath,
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: 'deny', DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: 'deny', DSH_TELEMETRY_DISABLED: '1' },
|
||||
})
|
||||
const sessionId = parseJsonl(first.stdout)[0]?.sessionId
|
||||
if (typeof sessionId !== 'string') throw new Error('missing Auto Session identity')
|
||||
@@ -615,7 +615,7 @@ describe('headless stream-json snapshots', () => {
|
||||
const second = await runLoaderSmoke({
|
||||
label: 'headless Auto authorized wake', cwd, binScript: dshBinScript, configPath: autoReviewOverlayPath,
|
||||
binArgs: [...args, '--session-id', sessionId, 'I authorize the exact CLI probe. Retry it.'], tsconfigPath,
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: 'allow', DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
|
||||
env: { DSH_AUTO_REVIEW_TEST_MODE: 'allow', DSH_TELEMETRY_DISABLED: '1' },
|
||||
inspect: async (directory) => {
|
||||
const logs = await persistedLogs(directory, join(directory, '.dsh', 'sessions'))
|
||||
expect(logs).toHaveLength(1)
|
||||
|
||||
@@ -40,7 +40,7 @@ interface ResolutionEvidence {
|
||||
sourceToolsCjs: string | null
|
||||
sourceLeafCjs: string
|
||||
sourceLeafExplicitCjs: string
|
||||
scheduler: boolean
|
||||
executor: boolean
|
||||
modules: string[]
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export function testProfileResolution(mode: ExampleMode): void {
|
||||
const staleTools = join(root, 'stale-tools')
|
||||
const staleToolsLink = join(sharedModules, '@deepseek-ai', 'dsh-tools')
|
||||
await writePackage(staleTools, { name: '@deepseek-ai/dsh-tools', version: '0.0.0', exports }, {
|
||||
'index.mjs': "export default class Tools {}\nexport const TOOL_RUNTIME_SCHEDULER = Symbol()\nthrow new Error('STALE_DSH_TOOLS')",
|
||||
'index.mjs': "export default class Tools {}\nthrow new Error('STALE_DSH_TOOLS')",
|
||||
'index.cjs': "throw new Error('STALE_DSH_TOOLS')",
|
||||
})
|
||||
const sourceDir = join(sourcePackageDir, 'src')
|
||||
@@ -183,7 +183,7 @@ export function testProfileResolution(mode: ExampleMode): void {
|
||||
'probe.mjs': [
|
||||
"import { createRequire } from 'node:module'",
|
||||
"import { getEnvironmentData } from 'node:worker_threads'",
|
||||
"import Tools, { TOOL_RUNTIME_SCHEDULER } from '@deepseek-ai/dsh-tools'",
|
||||
"import Tools from '@deepseek-ai/dsh-tools'",
|
||||
`import { leaf } from '${leafName}'`,
|
||||
`import { leaf as bridgeLeaf } from '${bridgeName}'`,
|
||||
`import { external } from '${externalName}'`,
|
||||
@@ -214,7 +214,7 @@ export function testProfileResolution(mode: ExampleMode): void {
|
||||
' sourceToolsInstance: ctx.tools instanceof SourceTools,',
|
||||
` profileToolsCjs: ${toolsCjsExpression},`,
|
||||
' sourceToolsCjs, sourceLeafCjs, sourceLeafExplicitCjs,',
|
||||
" scheduler: typeof ctx.tools[TOOL_RUNTIME_SCHEDULER]?.prepare === 'function',",
|
||||
" executor: typeof ctx.tools.execute === 'function',",
|
||||
' modules: [...ctx.loader.internal.loadCache.keys()]',
|
||||
' .filter(url => /\\/packages\\/core\\/(?:tools|agent-loop)\\//.test(url)),',
|
||||
' }',
|
||||
@@ -292,7 +292,7 @@ export function testProfileResolution(mode: ExampleMode): void {
|
||||
expect(evidence.sourceLeafCjs).toBe(evidence.cjs.filename)
|
||||
expect(evidence.sourceLeafExplicitCjs).toBe(realpathSync.native(join(sourceDevLeaf, 'index.cjs')))
|
||||
expect(evidence.sourceLeafCjs).not.toBe(evidence.sourceLeafExplicitCjs)
|
||||
expect(evidence.scheduler).toBe(true)
|
||||
expect(evidence.executor).toBe(true)
|
||||
expect(evidence.execArgv).toEqual(mode === 'src' ? launch.args.slice(0, 2) : [])
|
||||
for (const name of ['tools', 'agent-loop']) {
|
||||
const selected = mode === 'src' ? 'src/index.ts' : 'lib/index.js'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeModelToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
@@ -96,7 +97,7 @@ function runCode(
|
||||
signal: AbortSignal = testToolSignal,
|
||||
agent?: Agent,
|
||||
): Promise<ToolExecutionResult> {
|
||||
return harness.tools.execute({
|
||||
return executeModelToolFixture(harness, {
|
||||
callId: ToolCallId(`keyless-code-${++keylessCall}`),
|
||||
name: RUN_CODE_NAME,
|
||||
arguments: { code, description: 'Run the e2e program' },
|
||||
@@ -308,7 +309,7 @@ describe('PTC mode typed values: keyless real-process contracts', () => {
|
||||
return { provider: provider.id, names: inspected.data.tools.map(tool => tool.name) };
|
||||
`, testToolSignal, agent))
|
||||
|
||||
expect(value).toEqual({ provider: 'Tool', names: ['cordis_inspect_list', 'cordis_inspect_query', 'run_code'] })
|
||||
expect(value).toEqual({ provider: 'Tool', names: ['cordis_inspect_list', 'cordis_inspect_query'] })
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ describe.skipIf(!existsSync(join(repoRoot, 'apps/cli/lib/bin.js')))('dsh SOURCE
|
||||
DSH_HOME: join(root, 'home'),
|
||||
DSH_AGENTS_HOME: join(root, 'agents'),
|
||||
DSH_TELEMETRY_DISABLED: '1',
|
||||
DSH_TOOLS_MODE: 'native',
|
||||
DSH_CLI_MOCK_FAILURE: '0',
|
||||
},
|
||||
input: '',
|
||||
|
||||
@@ -85,7 +85,6 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('SDK native tool updates with rea
|
||||
retryPolicy: { mode: 'normal', maxRetries: 0 } satisfies RetryPolicyConfig,
|
||||
models: [{ id: 'deepseek-flash', systemPromptUpdate: 'in-history', toolUpdate: 'addition-only' }],
|
||||
} },
|
||||
{ id: 'tools', config: { mode: 'native' } },
|
||||
{ id: 'session-log-deepseek', disabled: true },
|
||||
{ id: 'plugin-package-inventory-deepseek', disabled: true },
|
||||
{ insert: [{ id: 'sdk-dynamic-tool-cache-fixture', name: fixturePath, config: { evidencePath, callsPath, sampleLabel, updatePrompt } }] },
|
||||
|
||||
@@ -58,7 +58,7 @@ describe('Python SDK dsh profile keyless smoke', () => {
|
||||
{ label: 'reports max-token turns with mapping enabled through env', envValue: 'true', editorEnabled: false },
|
||||
{ label: 'reports max-token turns with mapping disabled through env', envValue: 'false', editorEnabled: false },
|
||||
{ label: 'allows an explicit patch to enable str_replace_editor', envValue: undefined, editorEnabled: true },
|
||||
{ label: 'uses desktop tools through the PTC environment switch', envValue: undefined, editorEnabled: false, ptc: true },
|
||||
{ label: 'uses the PTC executor overlay despite the retired environment selector', envValue: undefined, editorEnabled: false, ptc: true },
|
||||
])('$label', async (scenario) => {
|
||||
const { envValue, editorEnabled } = scenario
|
||||
const ptc = 'ptc' in scenario && scenario.ptc
|
||||
@@ -92,6 +92,7 @@ describe('Python SDK dsh profile keyless smoke', () => {
|
||||
'--profile',
|
||||
'sdk',
|
||||
...(editorEnabled ? ['--patch', editorPatch] : []),
|
||||
...(ptc ? ['--patch', join(repoRoot, 'apps/cli/config/examples/ptc.yml')] : []),
|
||||
], {
|
||||
cwd: repoRoot,
|
||||
env: {
|
||||
@@ -99,7 +100,7 @@ describe('Python SDK dsh profile keyless smoke', () => {
|
||||
DSH_HOME: join(root, '.dsh'),
|
||||
DSH_PERMISSION_MODE: 'danger-full-access',
|
||||
DSH_TELEMETRY_DISABLED: '1',
|
||||
DSH_TOOLS_MODE: ptc ? 'ptc' : 'native',
|
||||
DSH_TOOLS_MODE: ptc ? 'native' : 'ptc',
|
||||
DEEPSEEK_API_KEY: 'keyless-smoke-no-call',
|
||||
DEEPSEEK_BASE_URL: `http://127.0.0.1:${address.port}`,
|
||||
...(envValue === undefined ? {} : { DSH_MAX_TOKENS_AS_SUCCESS: envValue }),
|
||||
|
||||
@@ -58,7 +58,7 @@ it.skipIf(!process.env.DEEPSEEK_API_KEY || process.platform === 'win32')(`agent
|
||||
], {
|
||||
cwd: root, env: {
|
||||
PATH: path, DSH_HOME: join(root, 'home'), DSH_AGENTS_HOME: join(root, 'agents'),
|
||||
DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1', DSH_TOOLS_MODE: 'native',
|
||||
DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
|
||||
DSH_PRIMARY_RUNTIME: carrier === 'sdk' ? undefined : '',
|
||||
},
|
||||
timeout: 110_000, killSignal: 'SIGKILL', reject: false,
|
||||
|
||||
@@ -49,7 +49,7 @@ it('delivers an overdue reminder with the SDK route and lets the client resume t
|
||||
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve))
|
||||
const address = server.address()
|
||||
if (address === null || typeof address === 'string') throw new Error('model fixture has no port')
|
||||
const env = { ...process.env, DSH_TOOLS_MODE: 'native', DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
|
||||
const env = { ...process.env, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
|
||||
DEEPSEEK_API_KEY: 'keyless-schedule-fixture', DEEPSEEK_BASE_URL: `http://127.0.0.1:${String(address.port)}` }
|
||||
clearAmbientProxyEnv(env)
|
||||
const first = new DeepSeekHarness({ cwd: root, dshHome: join(root, '.dsh'), patches: [patch],
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createServer } from 'node:http'
|
||||
import { mkdtemp, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { DeepSeekHarness, type SdkUserQuestionRequest } from '@deepseek-ai/dsh-sdk-client'
|
||||
import { clearAmbientProxyEnv } from '../../../../../scripts/test-proxy-environment.ts'
|
||||
import { expect, it, onTestFinished } from 'vitest'
|
||||
@@ -47,13 +48,14 @@ it.each([
|
||||
await new Promise<void>(resolve => server.listen(0, '127.0.0.1', resolve))
|
||||
const address = server.address()
|
||||
if (address === null || typeof address === 'string') throw new Error('model fixture has no port')
|
||||
const env = { ...process.env, DSH_TOOLS_MODE: mode, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
|
||||
const env = { ...process.env, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
|
||||
DEEPSEEK_API_KEY: 'keyless-question-fixture', DEEPSEEK_BASE_URL: `http://127.0.0.1:${String(address.port)}` }
|
||||
clearAmbientProxyEnv(env)
|
||||
const seen: SdkUserQuestionRequest[] = []
|
||||
const entered = Promise.withResolvers<AbortSignal>()
|
||||
const harness = state.harness = new DeepSeekHarness({
|
||||
cwd: root, dshHome: join(root, '.dsh'), env, model: 'deepseek-v4-pro', maxTokens: 1234, initializeTimeoutMs: 30_000,
|
||||
patches: mode === 'ptc' ? [fileURLToPath(new URL('../../../config/examples/ptc.yml', import.meta.url))] : [],
|
||||
onUserQuestion: async (request, { signal }) => {
|
||||
expect(signal.aborted).toBe(false)
|
||||
seen.push(request)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/** Test-only IPC assertions over real Creator presets and profile management. */
|
||||
import { executeModelToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
|
||||
export const inject = ['agents', 'agentPresets', 'tools', 'pluginManager', 'permissionPresets']
|
||||
|
||||
export function apply(ctx, config) {
|
||||
@@ -30,7 +32,7 @@ export function apply(ctx, config) {
|
||||
try {
|
||||
const first = await make(`${phase}-first`)
|
||||
const before = names(first)
|
||||
const manage = args => ctx.tools.execute({ name: 'plugin_manager', arguments: args, agent: first,
|
||||
const manage = args => executeModelToolFixture(ctx, { name: 'plugin_manager', arguments: args, agent: first,
|
||||
callId: `${phase}-manage`, signal: new AbortController().signal })
|
||||
ctx.permissionPresets.set(first.session, 'workspace-write')
|
||||
first.session.append('turn/start', { turn: 1 })
|
||||
@@ -45,7 +47,7 @@ export function apply(ctx, config) {
|
||||
const second = await make(`${phase}-second`)
|
||||
const after = names(first)
|
||||
const other = names(second)
|
||||
const ping = await ctx.tools.execute({ name: 'mcp__demo__ping', arguments: {}, agent: first,
|
||||
const ping = await executeModelToolFixture(ctx, { name: 'mcp__demo__ping', arguments: {}, agent: first,
|
||||
callId: `${phase}-ping`, signal: new AbortController().signal })
|
||||
const removed = phase === 'restart'
|
||||
? JSON.parse((await manage({ action: 'remove_bundle', target: '@test/creator-mcp' })).value) : undefined
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { agentPresetProjectionDefinition } from '@deepseek-ai/dsh-agent-preset-registry'
|
||||
import { subagentModelSelectionProjectionDefinition } from '@deepseek-ai/dsh-tool-subagent/src/model-selection-state.ts'
|
||||
import { createRequire } from 'node:module'
|
||||
@@ -629,7 +630,7 @@ describe('the shipped Web composition', () => {
|
||||
expect(scoped).toContain('project-proof')
|
||||
|
||||
// The preset's own loader tool resolves the global-layer skill.
|
||||
const loaded = await ctx.tools.execute({
|
||||
const loaded = await executeToolFixture(ctx, {
|
||||
callId: ToolCallId('preset-skills-load'),
|
||||
name: 'skill',
|
||||
arguments: { name: 'dsh-badge' },
|
||||
@@ -787,7 +788,7 @@ describe('a user preset declared from the shipped cordis rows', () => {
|
||||
]))
|
||||
}
|
||||
const signal = new AbortController().signal
|
||||
const listed = await copyCtx.tools.execute({
|
||||
const listed = await executeToolFixture(copyCtx, {
|
||||
callId: ToolCallId('copied-preset-inspect-list'),
|
||||
name: 'cordis_inspect_list',
|
||||
arguments: {},
|
||||
@@ -802,7 +803,7 @@ describe('a user preset declared from the shipped cordis rows', () => {
|
||||
// The `Tool` provider is the one built over the host context: it
|
||||
// answers with the shared registry's view of the REQUESTING agent,
|
||||
// so the copy sees its own preset's tools, not the host's empty set.
|
||||
const queried = await copyCtx.tools.execute({
|
||||
const queried = await executeToolFixture(copyCtx, {
|
||||
callId: ToolCallId('copied-preset-inspect-tools'),
|
||||
name: 'cordis_inspect_query',
|
||||
arguments: { platform: 'host', provider: 'Tool', method: 'listTools' },
|
||||
@@ -819,12 +820,12 @@ describe('a user preset declared from the shipped cordis rows', () => {
|
||||
expect(queriedText).toContain(`"name": "${toolName}"`)
|
||||
}
|
||||
|
||||
// The `Config` provider reads the booted profile tree: the shipped `tools` row declares a Config,
|
||||
// The `Config` provider reads the booted profile tree: the Agent loop declares a Config,
|
||||
// and the bootstrap include row is a carrier. The name filter keeps each page small.
|
||||
type ConfigRow = { id: string; patchId: string; name: string; status: string }
|
||||
type ConfigPage = { data: { entries: ConfigRow[]; total: number; nextOffset: number | null } }
|
||||
const listConfigs = async (input: Record<string, string | number>, callId: string): Promise<ConfigPage['data']> => {
|
||||
const page = await copyCtx.tools.execute({
|
||||
const page = await executeToolFixture(copyCtx, {
|
||||
callId: ToolCallId(callId),
|
||||
name: 'cordis_inspect_query',
|
||||
arguments: { platform: 'host', provider: 'Config', method: 'listConfigs', input },
|
||||
@@ -834,16 +835,16 @@ describe('a user preset declared from the shipped cordis rows', () => {
|
||||
expect(page.isError, resultText(page)).toBe(false)
|
||||
return (JSON.parse(resultText(page)) as ConfigPage).data
|
||||
}
|
||||
const toolsRows = await listConfigs({ name: '@deepseek-ai/dsh-tools' }, 'copied-preset-inspect-configs')
|
||||
const toolsRows = await listConfigs({ name: '@deepseek-ai/dsh-agent-loop' }, 'copied-preset-inspect-configs')
|
||||
const toolsRow = toolsRows.entries[0]
|
||||
expect(toolsRow).toMatchObject({ patchId: 'tools', status: 'schema' })
|
||||
expect(toolsRow).toMatchObject({ patchId: 'agent-loop', status: 'schema' })
|
||||
expect(toolsRows).toMatchObject({ total: 1, nextOffset: null })
|
||||
const includes = await listConfigs({ name: 'cordis:include' }, 'copied-preset-inspect-includes')
|
||||
expect(includes.entries.find(entry => entry.patchId === 'include')).toMatchObject({ status: 'tree' })
|
||||
const firstPage = await listConfigs({ limit: 5 }, 'copied-preset-inspect-page')
|
||||
expect(firstPage.entries).toHaveLength(5)
|
||||
expect(firstPage.nextOffset).toBe(5)
|
||||
const projected = await copyCtx.tools.execute({
|
||||
const projected = await executeToolFixture(copyCtx, {
|
||||
callId: ToolCallId('copied-preset-inspect-config'),
|
||||
name: 'cordis_inspect_query',
|
||||
arguments: { platform: 'host', provider: 'Config', method: 'listConfigs', input: { entry: toolsRow!.id } },
|
||||
@@ -855,7 +856,7 @@ describe('a user preset declared from the shipped cordis rows', () => {
|
||||
const { data } = JSON.parse(resultText(projected)) as { data: Projected }
|
||||
expect(data.status).toBe('schema')
|
||||
expect(data.schema.$defs).toHaveProperty('loaderExpression')
|
||||
expect(JSON.stringify(data.schema)).toContain('"mode"')
|
||||
expect(JSON.stringify(data.schema)).toContain('"maxParallelToolCalls"')
|
||||
} finally {
|
||||
await copied.dispose()
|
||||
await shipped.dispose()
|
||||
@@ -954,7 +955,7 @@ describe('a delegated child', () => {
|
||||
] as const
|
||||
for (const [name, args] of calls) {
|
||||
expect(toolNames(ctx, child.agent)).toContain(name)
|
||||
const result = await ctx.tools.execute({
|
||||
const result = await executeToolFixture(ctx, {
|
||||
callId: ToolCallId(`child-${name}`), signal: new AbortController().signal,
|
||||
name, arguments: args, agent: child.agent,
|
||||
})
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/cordis-plugin-loader": "workspace:~",
|
||||
"@deepseek-ai/cordis-plugin-include": "workspace:~",
|
||||
"@deepseek-ai/dsh-skill": "workspace:*"
|
||||
"@deepseek-ai/dsh-skill": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-executor-native": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as NativeToolExecutor from '@deepseek-ai/dsh-tool-executor-native'
|
||||
import { cp, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, sep } from 'node:path'
|
||||
@@ -29,7 +30,7 @@ it('loads Desktop Office CLI paths and removes them on disposal', async () => {
|
||||
expect('default' in desktopOffice).toBe(false)
|
||||
expect(ctx.loader.unwrapExports(desktopOffice)).toBe(desktopOffice)
|
||||
const modules = new Map<string, unknown>([
|
||||
['agents', AgentRegistry], ['systemPrompt', SystemPrompt], ['tools', ToolRuntime],
|
||||
['agents', AgentRegistry], ['systemPrompt', SystemPrompt], ['tools', ToolRuntime], ['toolExecutor', NativeToolExecutor],
|
||||
['skills', SkillRegistry], ['office', desktopOffice],
|
||||
])
|
||||
ctx.loader.internal = {
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
en: 372297005b57a08b
|
||||
zh: 074a635ac17e4362
|
||||
/deepseek-harness-desktop/installation-ownership:
|
||||
en: b3cf09d7c901d727
|
||||
zh: 2ec34045a201d8e9
|
||||
en: ae0384d699f55cea
|
||||
zh: ffb879b1d4b08bae
|
||||
/deepseek-harness-desktop/installation-ownership/runtime-and-plugin-activation:
|
||||
en: a1a47b09f4a72ba4
|
||||
zh: 7b1cf27f0b72cf31
|
||||
|
||||
@@ -150,7 +150,7 @@ The product UI retains Web actions, including "Open In..." through the shared au
|
||||
|
||||
Update copy preserves the complete version, including prerelease suffixes, without adding v or V. When no update is available, the dialog title reports the result and the body shows the current version.
|
||||
|
||||
Electron chooses typed English, Chinese, or Japanese shell copy from its application locale and falls back to English. The macOS application bundle declares English, Simplified Chinese, and Japanese in `CFBundleLocalizations`, allowing macOS to match the initial application language to the user’s preferred languages. Saved Client UI language preferences still take precedence for the main interface. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources.
|
||||
Electron chooses typed English, Chinese, or Japanese shell copy from its application locale and falls back to English. The macOS application bundle declares English, Simplified Chinese, and Japanese in `CFBundleLocalizations`, allowing macOS to match the initial application language to the user’s preferred languages. Saved Client UI language preferences still take precedence for the main interface. Windows NSIS installer resources live in one JSON file per language under `installer/locales/`; packaging generates NSIS strings and discovers the installer language list from these files. English, Simplified Chinese, and Japanese resources must have matching keys and format placeholders; `pnpm run check:i18n` validates them. The native installer test builds and exercises each configured language. Platform account pages and onboarding artwork use English for languages other than Chinese. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources.
|
||||
|
||||
Windows and macOS relay native fullscreen transitions and the state after each page load to the renderer, so overlays can adapt their caption clearance.
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ Electron 拥有 `$DSH_HOME/profiles/desktop`。其 `dependencies` 包含 pnpm
|
||||
|
||||
升级文案完整展示版本号(包括预发布后缀),不额外添加 v 或 V。无可用更新时,弹窗标题显示检查结果,正文显示当前版本。
|
||||
|
||||
Electron 根据应用语言选择类型化的英文、中文或日文 shell 文案,并回退到英文。macOS 应用包通过 `CFBundleLocalizations` 声明支持英语、简体中文和日语,让 macOS 根据用户的首选语言匹配初始应用语言。主界面仍优先使用已保存的 Client UI 语言偏好。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。
|
||||
Electron 根据应用语言选择类型化的英文、中文或日文 shell 文案,并回退到英文。macOS 应用包通过 `CFBundleLocalizations` 声明支持英语、简体中文和日语,让 macOS 根据用户的首选语言匹配初始应用语言。主界面仍优先使用已保存的 Client UI 语言偏好。 Windows NSIS 安装器在 `installer/locales/` 下按语言保存独立 JSON 资源;打包从这些文件生成 NSIS 文案和安装器语言清单。英文、简体中文和日语资源的键与格式占位符必须一致,`pnpm run check:i18n` 负责检查。原生安装器测试逐个构建并验证配置中的语言。账户平台页面和引导插图对中文以外的语言使用英文。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。
|
||||
|
||||
Windows 和 macOS 会在原生全屏切换及每次页面加载后向渲染器同步全屏状态,让浮层调整顶栏避让距离。
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export interface DesktopElectronBuilderConfig {
|
||||
readonly perMachine: false
|
||||
readonly allowElevation: false
|
||||
readonly allowToChangeInstallationDirectory: false
|
||||
readonly installerLanguages: readonly ['en_US', 'zh_CN']
|
||||
readonly installerLanguages: readonly string[]
|
||||
}
|
||||
readonly beforeBuild: () => Promise<boolean>
|
||||
readonly beforePack: (context: BeforePackContext) => Promise<void>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"nsisLanguage": "ENGLISH",
|
||||
"strings": {
|
||||
"INSTALLER_INSTALL": "Install now",
|
||||
"INSTALLER_FINISH": "Finish",
|
||||
"INSTALLER_NATIVE_PROGRESS": "Preparing installation… %d%%",
|
||||
"INSTALLER_PROGRESS_EXTRACT": "Extracting files… %d%%",
|
||||
"INSTALLER_PROGRESS_COPY": "Installing files… %d%%",
|
||||
"INSTALLER_PROGRESS_REGISTER": "Finishing installation… %d%%",
|
||||
"INSTALLER_PROGRESS_CLEAN": "Cleaning temporary files… %d%%",
|
||||
"INSTALLER_CHOOSE_PATH": "Choose location",
|
||||
"INSTALLER_BROWSE": "Browse",
|
||||
"INSTALLER_LAUNCH": "Launch now",
|
||||
"INSTALLER_LAUNCH_FAILED": "DeepSeek Harness could not be launched. Retry, or clear Launch now and close the installer.",
|
||||
"INSTALLER_UI_ERROR": "The installer could not initialize its window. Close it and try again.",
|
||||
"INSTALLER_THEME_ERROR": "Use /THEME=auto, /THEME=light or /THEME=dark.",
|
||||
"INSTALLER_FAILED": "Installation did not finish. Close this installer and retry. If the problem persists, download the installer again.",
|
||||
"INSTALLER_RUNNING": "DeepSeek Harness is running. Quit it from the system tray and try again.",
|
||||
"INSTALLER_DIRECTORY_FAILED": "The installation directory could not be replaced.",
|
||||
"INSTALLER_DIRECTORY_HINT": "Check access to the installation directory and close programs using its files, then run the installer again. Copy the error details if the problem persists.",
|
||||
"INSTALLER_DIRECTORY_RESTORE_HINT": "The previous installation could not be restored. Keep the backup directory shown in the error details and contact support before installing again.",
|
||||
"INSTALLER_PATH_INVALID": "Choose a full local folder path. Drive roots, system folders, links and special characters are not supported.",
|
||||
"INSTALLER_PATH_OWNERSHIP": "Choose an empty folder or the registered DeepSeek Harness installation folder.",
|
||||
"INSTALLER_PATH_WRITABLE": "This location is not writable. Choose a folder available to the current user.",
|
||||
"INSTALLER_DISK_SPACE": "There is not enough free disk space. Choose another location.",
|
||||
"INSTALLER_PER_USER": "This installer supports the current user only. Uninstall the existing all-users installation first.",
|
||||
"INSTALLER_EXTRACT_FAILED": "The application files could not be extracted.",
|
||||
"INSTALLER_EXTRACT_HINT": "Security software may have blocked a file, or the disk may be full. Close this installer and try again. If it keeps failing, send us the error details below.",
|
||||
"INSTALLER_EXTRACT_COPY": "Copy error details",
|
||||
"INSTALLER_EXTRACT_EXPAND": "Show details",
|
||||
"INSTALLER_EXTRACT_COLLAPSE": "Hide details",
|
||||
"INSTALLER_EXTRACT_SAVED": "The full report was saved to %s",
|
||||
"INSTALLER_EXTRACT_UNSAVED": "The full report could not be saved. Use Copy error details to keep it.",
|
||||
"INSTALLER_EXTRACT_COPIED": "Error details were copied to the clipboard."
|
||||
},
|
||||
"uninstaller": {
|
||||
"welcome": "Welcome",
|
||||
"finished": "has been uninstalled"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"nsisLanguage": "JAPANESE",
|
||||
"strings": {
|
||||
"INSTALLER_INSTALL": "今すぐインストール",
|
||||
"INSTALLER_FINISH": "完了",
|
||||
"INSTALLER_NATIVE_PROGRESS": "インストールを準備しています… %d%%",
|
||||
"INSTALLER_PROGRESS_EXTRACT": "ファイルを展開しています… %d%%",
|
||||
"INSTALLER_PROGRESS_COPY": "ファイルをインストールしています… %d%%",
|
||||
"INSTALLER_PROGRESS_REGISTER": "インストールを完了しています… %d%%",
|
||||
"INSTALLER_PROGRESS_CLEAN": "一時ファイルを削除しています… %d%%",
|
||||
"INSTALLER_CHOOSE_PATH": "インストール先を選択",
|
||||
"INSTALLER_BROWSE": "参照",
|
||||
"INSTALLER_LAUNCH": "今すぐ起動",
|
||||
"INSTALLER_LAUNCH_FAILED": "DeepSeek Harness を起動できませんでした。再試行するか、「今すぐ起動」のチェックを外してインストーラーを閉じてください。",
|
||||
"INSTALLER_UI_ERROR": "インストーラーのウィンドウを初期化できませんでした。閉じてから再試行してください。",
|
||||
"INSTALLER_THEME_ERROR": "/THEME=auto、/THEME=light、/THEME=dark のいずれかを指定してください。",
|
||||
"INSTALLER_FAILED": "インストールが完了しませんでした。インストーラーを閉じて再試行してください。問題が解決しない場合は、インストーラーを再度ダウンロードしてください。",
|
||||
"INSTALLER_RUNNING": "DeepSeek Harness が実行中です。システムトレイから終了して再試行してください。",
|
||||
"INSTALLER_DIRECTORY_FAILED": "インストール先のディレクトリを置き換えられませんでした。",
|
||||
"INSTALLER_DIRECTORY_HINT": "インストール先へのアクセス権限を確認し、そのファイルを使用しているプログラムを閉じてから、インストーラーを再実行してください。問題が続く場合はエラーの詳細をコピーしてください。",
|
||||
"INSTALLER_DIRECTORY_RESTORE_HINT": "以前のインストールを復元できませんでした。エラーの詳細に表示されたバックアップディレクトリを保持し、再インストール前にサポートへお問い合わせください。",
|
||||
"INSTALLER_PATH_INVALID": "ローカルフォルダーの完全なパスを選択してください。ドライブのルート、システムフォルダー、リンク、特殊文字を含むパスは使用できません。",
|
||||
"INSTALLER_PATH_OWNERSHIP": "空のフォルダー、または登録済みの DeepSeek Harness インストール先を選択してください。",
|
||||
"INSTALLER_PATH_WRITABLE": "この場所には書き込めません。現在のユーザーが書き込めるフォルダーを選択してください。インストーラーは管理者権限を要求しません。",
|
||||
"INSTALLER_DISK_SPACE": "ディスクの空き容量が不足しています。別の場所を選択してください。",
|
||||
"INSTALLER_PER_USER": "このインストーラーは現在のユーザーのみを対象としています。先にすべてのユーザー向けの既存のインストールを削除してください。",
|
||||
"INSTALLER_EXTRACT_FAILED": "アプリケーションのファイルを展開できませんでした。",
|
||||
"INSTALLER_EXTRACT_HINT": "セキュリティソフトがファイルをブロックしたか、ディスクの空き容量が不足している可能性があります。インストーラーを閉じて再試行してください。問題が続く場合は、以下のエラーの詳細をお送りください。",
|
||||
"INSTALLER_EXTRACT_COPY": "エラーの詳細をコピー",
|
||||
"INSTALLER_EXTRACT_EXPAND": "詳細を表示",
|
||||
"INSTALLER_EXTRACT_COLLAPSE": "詳細を非表示",
|
||||
"INSTALLER_EXTRACT_SAVED": "完全なレポートを %s に保存しました",
|
||||
"INSTALLER_EXTRACT_UNSAVED": "完全なレポートを保存できませんでした。「エラーの詳細をコピー」で保存してください。",
|
||||
"INSTALLER_EXTRACT_COPIED": "エラーの詳細をクリップボードにコピーしました。"
|
||||
},
|
||||
"uninstaller": {
|
||||
"welcome": "アンインストール ウィザードへようこそ",
|
||||
"finished": "アンインストールされました"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"nsisLanguage": "SIMPCHINESE",
|
||||
"strings": {
|
||||
"INSTALLER_INSTALL": "立即安装",
|
||||
"INSTALLER_FINISH": "完成",
|
||||
"INSTALLER_NATIVE_PROGRESS": "正在准备安装… %d%%",
|
||||
"INSTALLER_PROGRESS_EXTRACT": "正在解压文件… %d%%",
|
||||
"INSTALLER_PROGRESS_COPY": "正在安装文件… %d%%",
|
||||
"INSTALLER_PROGRESS_REGISTER": "正在完成安装… %d%%",
|
||||
"INSTALLER_PROGRESS_CLEAN": "正在清理临时文件… %d%%",
|
||||
"INSTALLER_CHOOSE_PATH": "选择安装位置",
|
||||
"INSTALLER_BROWSE": "选择",
|
||||
"INSTALLER_LAUNCH": "立即启动",
|
||||
"INSTALLER_LAUNCH_FAILED": "无法启动 DeepSeek Harness。请重试,或取消勾选立即启动后关闭安装程序。",
|
||||
"INSTALLER_UI_ERROR": "无法初始化安装窗口,请关闭后重试。",
|
||||
"INSTALLER_THEME_ERROR": "主题参数须为 /THEME=auto、/THEME=light 或 /THEME=dark。",
|
||||
"INSTALLER_FAILED": "安装未完成,请关闭安装程序后重试。如仍然失败,请重新下载安装包。",
|
||||
"INSTALLER_RUNNING": "DeepSeek Harness 正在运行,请先在系统托盘中退出应用后重试。",
|
||||
"INSTALLER_DIRECTORY_FAILED": "无法替换安装目录。",
|
||||
"INSTALLER_DIRECTORY_HINT": "请检查安装目录的访问权限,关闭占用其中内容的程序后重新运行安装器。如仍失败,请复制错误详情。",
|
||||
"INSTALLER_DIRECTORY_RESTORE_HINT": "未能恢复原安装目录。请保留错误详情中列出的备份目录,联系支持人员后再安装。",
|
||||
"INSTALLER_PATH_INVALID": "请选择本地磁盘上的完整文件夹路径,不能使用磁盘根目录、系统目录、链接目录或包含特殊字符的路径。",
|
||||
"INSTALLER_PATH_OWNERSHIP": "请选择空文件夹,或 DeepSeek Harness 原来的安装目录。",
|
||||
"INSTALLER_PATH_WRITABLE": "无法写入此位置。请选择当前用户可写入的文件夹;安装程序不会申请管理员权限。",
|
||||
"INSTALLER_DISK_SPACE": "此磁盘的可用空间不足,请选择其他位置。",
|
||||
"INSTALLER_PER_USER": "此安装程序仅支持当前用户。请先卸载已有的所有用户安装版本。",
|
||||
"INSTALLER_EXTRACT_FAILED": "无法解压应用程序文件。",
|
||||
"INSTALLER_EXTRACT_HINT": "可能是安全软件拦截了文件,或磁盘空间不足。请关闭安装程序后重试;如仍然失败,请将下方错误信息发送给我们。",
|
||||
"INSTALLER_EXTRACT_COPY": "复制错误信息",
|
||||
"INSTALLER_EXTRACT_EXPAND": "显示详情",
|
||||
"INSTALLER_EXTRACT_COLLAPSE": "隐藏详情",
|
||||
"INSTALLER_EXTRACT_SAVED": "完整错误报告已保存到 %s",
|
||||
"INSTALLER_EXTRACT_UNSAVED": "无法保存完整错误报告,请使用“复制错误信息”保留。",
|
||||
"INSTALLER_EXTRACT_COPIED": "错误信息已复制到剪贴板。"
|
||||
},
|
||||
"uninstaller": {
|
||||
"welcome": "欢迎",
|
||||
"finished": "已从你"
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
; NSIS owns installer localization independently of the Electron application locale.
|
||||
LangString INSTALLER_INSTALL ${LANG_ENGLISH} "Install now"
|
||||
LangString INSTALLER_INSTALL ${LANG_SIMPCHINESE} "立即安装"
|
||||
LangString INSTALLER_FINISH ${LANG_ENGLISH} "Finish"
|
||||
LangString INSTALLER_FINISH ${LANG_SIMPCHINESE} "完成"
|
||||
LangString INSTALLER_NATIVE_PROGRESS ${LANG_ENGLISH} "Preparing installation… %d%%"
|
||||
LangString INSTALLER_NATIVE_PROGRESS ${LANG_SIMPCHINESE} "正在准备安装… %d%%"
|
||||
LangString INSTALLER_PROGRESS_EXTRACT ${LANG_ENGLISH} "Extracting files… %d%%"
|
||||
LangString INSTALLER_PROGRESS_EXTRACT ${LANG_SIMPCHINESE} "正在解压文件… %d%%"
|
||||
LangString INSTALLER_PROGRESS_COPY ${LANG_ENGLISH} "Installing files… %d%%"
|
||||
LangString INSTALLER_PROGRESS_COPY ${LANG_SIMPCHINESE} "正在安装文件… %d%%"
|
||||
LangString INSTALLER_PROGRESS_REGISTER ${LANG_ENGLISH} "Finishing installation… %d%%"
|
||||
LangString INSTALLER_PROGRESS_REGISTER ${LANG_SIMPCHINESE} "正在完成安装… %d%%"
|
||||
LangString INSTALLER_PROGRESS_CLEAN ${LANG_ENGLISH} "Cleaning temporary files… %d%%"
|
||||
LangString INSTALLER_PROGRESS_CLEAN ${LANG_SIMPCHINESE} "正在清理临时文件… %d%%"
|
||||
LangString INSTALLER_CHOOSE_PATH ${LANG_ENGLISH} "Choose location"
|
||||
LangString INSTALLER_CHOOSE_PATH ${LANG_SIMPCHINESE} "选择安装位置"
|
||||
LangString INSTALLER_BROWSE ${LANG_ENGLISH} "Browse"
|
||||
LangString INSTALLER_BROWSE ${LANG_SIMPCHINESE} "选择"
|
||||
LangString INSTALLER_LAUNCH ${LANG_ENGLISH} "Launch now"
|
||||
LangString INSTALLER_LAUNCH ${LANG_SIMPCHINESE} "立即启动"
|
||||
LangString INSTALLER_LAUNCH_FAILED ${LANG_ENGLISH} "DeepSeek Harness could not be launched. Retry, or clear Launch now and close the installer."
|
||||
LangString INSTALLER_LAUNCH_FAILED ${LANG_SIMPCHINESE} "无法启动 DeepSeek Harness。请重试,或取消勾选立即启动后关闭安装程序。"
|
||||
LangString INSTALLER_UI_ERROR ${LANG_ENGLISH} "The installer could not initialize its window. Close it and try again."
|
||||
LangString INSTALLER_UI_ERROR ${LANG_SIMPCHINESE} "无法初始化安装窗口,请关闭后重试。"
|
||||
LangString INSTALLER_THEME_ERROR ${LANG_ENGLISH} "Use /THEME=auto, /THEME=light or /THEME=dark."
|
||||
LangString INSTALLER_THEME_ERROR ${LANG_SIMPCHINESE} "主题参数须为 /THEME=auto、/THEME=light 或 /THEME=dark。"
|
||||
LangString INSTALLER_FAILED ${LANG_ENGLISH} "Installation did not finish. Close this installer and retry. If the problem persists, download the installer again."
|
||||
LangString INSTALLER_FAILED ${LANG_SIMPCHINESE} "安装未完成,请关闭安装程序后重试。如仍然失败,请重新下载安装包。"
|
||||
LangString INSTALLER_RUNNING ${LANG_ENGLISH} "DeepSeek Harness is running. Quit it from the system tray and try again."
|
||||
LangString INSTALLER_RUNNING ${LANG_SIMPCHINESE} "DeepSeek Harness 正在运行,请先在系统托盘中退出应用后重试。"
|
||||
LangString INSTALLER_DIRECTORY_FAILED ${LANG_ENGLISH} "The installation directory could not be replaced."
|
||||
LangString INSTALLER_DIRECTORY_FAILED ${LANG_SIMPCHINESE} "无法替换安装目录。"
|
||||
LangString INSTALLER_DIRECTORY_HINT ${LANG_ENGLISH} "Check access to the installation directory and close programs using its files, then run the installer again. Copy the error details if the problem persists."
|
||||
LangString INSTALLER_DIRECTORY_HINT ${LANG_SIMPCHINESE} "请检查安装目录的访问权限,关闭占用其中内容的程序后重新运行安装器。如仍失败,请复制错误详情。"
|
||||
LangString INSTALLER_DIRECTORY_RESTORE_HINT ${LANG_ENGLISH} "The previous installation could not be restored. Keep the backup directory shown in the error details and contact support before installing again."
|
||||
LangString INSTALLER_DIRECTORY_RESTORE_HINT ${LANG_SIMPCHINESE} "未能恢复原安装目录。请保留错误详情中列出的备份目录,联系支持人员后再安装。"
|
||||
LangString INSTALLER_PATH_INVALID ${LANG_ENGLISH} "Choose a full local folder path. Drive roots, system folders, links and special characters are not supported."
|
||||
LangString INSTALLER_PATH_INVALID ${LANG_SIMPCHINESE} "请选择本地磁盘上的完整文件夹路径,不能使用磁盘根目录、系统目录、链接目录或包含特殊字符的路径。"
|
||||
LangString INSTALLER_PATH_OWNERSHIP ${LANG_ENGLISH} "Choose an empty folder or the registered DeepSeek Harness installation folder."
|
||||
LangString INSTALLER_PATH_OWNERSHIP ${LANG_SIMPCHINESE} "请选择空文件夹,或 DeepSeek Harness 原来的安装目录。"
|
||||
LangString INSTALLER_PATH_WRITABLE ${LANG_ENGLISH} "This location is not writable. Choose a folder available to the current user."
|
||||
LangString INSTALLER_PATH_WRITABLE ${LANG_SIMPCHINESE} "无法写入此位置。请选择当前用户可写入的文件夹;安装程序不会申请管理员权限。"
|
||||
LangString INSTALLER_DISK_SPACE ${LANG_ENGLISH} "There is not enough free disk space. Choose another location."
|
||||
LangString INSTALLER_DISK_SPACE ${LANG_SIMPCHINESE} "此磁盘的可用空间不足,请选择其他位置。"
|
||||
LangString INSTALLER_PER_USER ${LANG_ENGLISH} "This installer supports the current user only. Uninstall the existing all-users installation first."
|
||||
LangString INSTALLER_PER_USER ${LANG_SIMPCHINESE} "此安装程序仅支持当前用户。请先卸载已有的所有用户安装版本。"
|
||||
LangString INSTALLER_EXTRACT_FAILED ${LANG_ENGLISH} "The application files could not be extracted."
|
||||
LangString INSTALLER_EXTRACT_FAILED ${LANG_SIMPCHINESE} "无法解压应用程序文件。"
|
||||
LangString INSTALLER_EXTRACT_HINT ${LANG_ENGLISH} "Security software may have blocked a file, or the disk may be full. Close this installer and try again. If it keeps failing, send us the error details below."
|
||||
LangString INSTALLER_EXTRACT_HINT ${LANG_SIMPCHINESE} "可能是安全软件拦截了文件,或磁盘空间不足。请关闭安装程序后重试;如仍然失败,请将下方错误信息发送给我们。"
|
||||
LangString INSTALLER_EXTRACT_COPY ${LANG_ENGLISH} "Copy error details"
|
||||
LangString INSTALLER_EXTRACT_COPY ${LANG_SIMPCHINESE} "复制错误信息"
|
||||
LangString INSTALLER_EXTRACT_EXPAND ${LANG_ENGLISH} "Show details"
|
||||
LangString INSTALLER_EXTRACT_EXPAND ${LANG_SIMPCHINESE} "显示详情"
|
||||
LangString INSTALLER_EXTRACT_COLLAPSE ${LANG_ENGLISH} "Hide details"
|
||||
LangString INSTALLER_EXTRACT_COLLAPSE ${LANG_SIMPCHINESE} "隐藏详情"
|
||||
LangString INSTALLER_EXTRACT_SAVED ${LANG_ENGLISH} "The full report was saved to %s"
|
||||
LangString INSTALLER_EXTRACT_SAVED ${LANG_SIMPCHINESE} "完整错误报告已保存到 %s"
|
||||
LangString INSTALLER_EXTRACT_UNSAVED ${LANG_ENGLISH} "The full report could not be saved. Use Copy error details to keep it."
|
||||
LangString INSTALLER_EXTRACT_UNSAVED ${LANG_SIMPCHINESE} "无法保存完整错误报告,请使用“复制错误信息”保留。"
|
||||
LangString INSTALLER_EXTRACT_COPIED ${LANG_ENGLISH} "Error details were copied to the clipboard."
|
||||
LangString INSTALLER_EXTRACT_COPIED ${LANG_SIMPCHINESE} "错误信息已复制到剪贴板。"
|
||||
@@ -1,7 +1,8 @@
|
||||
import { readInstallerLocales, renderInstallerStrings } from './installer-locales.mjs'
|
||||
import { officePackageDirectories } from '../../../scripts/libreoffice-packages.mjs'
|
||||
import { X509Certificate } from 'node:crypto'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { join, relative, sep } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { execFile } from 'node:child_process'
|
||||
@@ -129,6 +130,7 @@ export function createElectronBuilderConfig(
|
||||
'-OutputDirectory', join(buildPaths.root, 'installer-ui')], {
|
||||
env: scrubWindowsSigningEnvironment(env), windowsHide: true,
|
||||
})
|
||||
await writeFile(join(buildPaths.root, 'installer-ui', 'strings.nsh'), renderInstallerStrings(readInstallerLocales()), 'utf8')
|
||||
if (windowsSigner !== undefined) {
|
||||
await windowsSigner({ path: join(buildPaths.root, 'installer-ui', 'window-frame.dll'), hash: 'sha256', isNest: false })
|
||||
}
|
||||
@@ -262,7 +264,7 @@ export function createElectronBuilderConfig(
|
||||
perMachine: false,
|
||||
allowElevation: false,
|
||||
allowToChangeInstallationDirectory: false,
|
||||
installerLanguages: ['en_US', 'zh_CN'],
|
||||
installerLanguages: readInstallerLocales().map(locale => locale.id),
|
||||
differentialPackage: true,
|
||||
},
|
||||
detectUpdateChannel: false,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/** One installer language's compiler identifier, UI strings and NSIS Modern UI test expectations. */
|
||||
export interface InstallerLocale {
|
||||
/** electron-builder language and resource filename without its suffix. */
|
||||
id: string
|
||||
/** NSIS LANG_ constant suffix. */
|
||||
nsisLanguage: string
|
||||
/** Custom installer messages, with Windows printf placeholders preserved. */
|
||||
strings: Record<string, string>
|
||||
/** Substrings of the upstream Modern UI uninstaller's welcome and finished pages. */
|
||||
uninstaller: Record<string, string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Read complete per-language JSON resources and reject inconsistent keys or placeholders.
|
||||
* @param directory - Resource directory, defaulting to Desktop installer/locales.
|
||||
* @returns Validated resources, ordered by filename.
|
||||
*/
|
||||
export function readInstallerLocales(directory?: string): InstallerLocale[]
|
||||
|
||||
/**
|
||||
* Generate NSIS LangString declarations from validated resources.
|
||||
* @param locales - All configured languages or one isolated native-test language.
|
||||
* @returns UTF-8 NSIS source with literal text escaped.
|
||||
*/
|
||||
export function renderInstallerStrings(locales: InstallerLocale[]): string
|
||||
@@ -0,0 +1,75 @@
|
||||
/** Per-language JSON resources shared by NSIS packaging, native UI tests and the i18n check. */
|
||||
import { readFileSync, readdirSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const defaultDirectory = fileURLToPath(new URL('../installer/locales/', import.meta.url))
|
||||
|
||||
/**
|
||||
* Read and validate installer translations before generating compiler input.
|
||||
* @param {string} directory - Directory containing one JSON file per installer language.
|
||||
* @returns {{id: string, nsisLanguage: string, strings: Record<string, string>, uninstaller: Record<string, string>}[]} Complete language resources.
|
||||
*/
|
||||
export function readInstallerLocales(directory = defaultDirectory) {
|
||||
const locales = readdirSync(directory).filter(name => name.endsWith('.json')).sort().map(name => {
|
||||
if (!/^[a-z]{2}_[A-Z]{2}\.json$/u.test(name)) throw new Error(`${name}: invalid installer language filename`)
|
||||
/** @type {unknown} */
|
||||
const resource = JSON.parse(readFileSync(`${directory}/${name}`, 'utf8'))
|
||||
if (typeof resource !== 'object' || resource === null || !('nsisLanguage' in resource)
|
||||
|| typeof resource.nsisLanguage !== 'string' || !/^[A-Z]+$/u.test(resource.nsisLanguage)) {
|
||||
throw new Error(`${name}: invalid NSIS language identifier`)
|
||||
}
|
||||
/** @param {unknown} value - Parsed JSON dictionary. @returns {Record<string, string>} Nonempty text values. */
|
||||
const dictionary = (value) => {
|
||||
if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error(`${name}: expected text dictionary`)
|
||||
/** @type {Record<string, string>} */
|
||||
const result = {}
|
||||
for (const [key, text] of Object.entries(value)) {
|
||||
if (typeof text !== 'string' || text.trim() === '') throw new Error(`${name}: ${key} must be nonempty text`)
|
||||
result[key] = text
|
||||
}
|
||||
return result
|
||||
}
|
||||
const strings = dictionary('strings' in resource ? resource.strings : undefined)
|
||||
if (Object.keys(strings).some(key => !/^INSTALLER_[A-Z_]+$/u.test(key))) throw new Error(`${name}: invalid installer string key`)
|
||||
return { id: name.slice(0, -5), nsisLanguage: resource.nsisLanguage, strings,
|
||||
uninstaller: dictionary('uninstaller' in resource ? resource.uninstaller : undefined) }
|
||||
})
|
||||
for (const id of ['en_US', 'zh_CN', 'ja_JP']) {
|
||||
if (!locales.some(locale => locale.id === id)) throw new Error(`installer locales: missing ${id}.json`)
|
||||
}
|
||||
const english = locales.find(locale => locale.id === 'en_US')
|
||||
if (!english || Object.keys(english.strings).length === 0) throw new Error('installer locales: missing English strings')
|
||||
if (Object.keys(english.uninstaller).sort().join(',') !== 'finished,welcome') throw new Error('installer locales: expected uninstaller welcome and finished text')
|
||||
const languages = new Set()
|
||||
for (const locale of locales) {
|
||||
if (languages.has(locale.nsisLanguage)) throw new Error(`${locale.id}: duplicate NSIS language ${locale.nsisLanguage}`)
|
||||
languages.add(locale.nsisLanguage)
|
||||
for (const field of ['strings', 'uninstaller']) {
|
||||
const expected = english[field]
|
||||
const actual = locale[field]
|
||||
if (Object.keys(expected).sort().join(',') !== Object.keys(actual).sort().join(',')) throw new Error(`${locale.id}: ${field} keys differ from English`)
|
||||
for (const [key, text] of Object.entries(expected)) {
|
||||
const placeholders = (/** @type {string} */ value) => (value.match(/%.?/gu) ?? []).join(',')
|
||||
if (placeholders(text) !== placeholders(actual[key])) throw new Error(`${locale.id}: ${key} changes format placeholders`)
|
||||
}
|
||||
}
|
||||
}
|
||||
return locales
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate guarded NSIS LangString declarations from validated JSON resources.
|
||||
* @param {ReturnType<typeof readInstallerLocales>} locales - Resources for all languages or one isolated native-test build.
|
||||
* @returns {string} UTF-8 NSIS source, with literal dollar signs, quotes and line breaks escaped.
|
||||
*/
|
||||
export function renderInstallerStrings(locales) {
|
||||
const escape = (/** @type {string} */ text) => text.replace(/\$|"|\r|\n/gu, character => ({ '$': '$$', '"': '$\\"', '\r': '$\\r', '\n': '$\\n' })[character])
|
||||
return '; Generated from installer/locales/*.json.\n' + locales.map(locale =>
|
||||
`!ifdef LANG_${locale.nsisLanguage}\n` + Object.entries(locale.strings).map(([key, text]) =>
|
||||
`LangString ${key} \${LANG_${locale.nsisLanguage}} "${escape(text)}"\n`).join('') + '!endif\n').join('')
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
const locales = readInstallerLocales()
|
||||
console.log(`verify-installer-locales: ${locales.length} languages have matching keys and format placeholders.`)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ ManifestDPIAware true
|
||||
!endif
|
||||
|
||||
!macro customHeader
|
||||
!define /ifndef INSTALLER_STRINGS_FILE "${INSTALLER_SOURCE_DIR}\strings.nsh"
|
||||
!define /ifndef INSTALLER_STRINGS_FILE "${INSTALLER_BUILD_DIR}\strings.nsh"
|
||||
!include "${INSTALLER_STRINGS_FILE}"
|
||||
!ifdef BUILD_UNINSTALLER
|
||||
BrandingText " "
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/** Builds an isolated native payload through the production NSIS configuration and exercises its UI. */
|
||||
import { readInstallerLocales, renderInstallerStrings } from './installer-locales.mjs'
|
||||
import { execFile } from 'node:child_process'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { mkdir, mkdtemp, readFile, writeFile } from 'node:fs/promises'
|
||||
@@ -107,8 +108,8 @@ SectionEnd
|
||||
const compiler = await getMakeNsisPath()
|
||||
await execute(compiler.path, ['/V2', payloadSource], { ...childOptions, env: { ...childOptions.env, ...compiler.env } })
|
||||
if (sign) await sign({ path: join(payload, `${productName}.exe`), hash: 'sha256', isNest: false })
|
||||
const sourceStrings = await readFile(join(appRoot, 'installer', 'strings.nsh'), 'utf8')
|
||||
for (const language of ['en_US', 'zh_CN']) {
|
||||
for (const locale of readInstallerLocales()) {
|
||||
const language = locale.id
|
||||
const config = createElectronBuilderConfig()
|
||||
if (sign) {
|
||||
config.win.forceCodeSigning = true
|
||||
@@ -117,9 +118,7 @@ SectionEnd
|
||||
const languageOutput = join(output, language)
|
||||
await mkdir(languageOutput)
|
||||
const strings = join(languageOutput, 'strings.nsh')
|
||||
const languageId = language === 'en_US' ? 'ENGLISH' : 'SIMPCHINESE'
|
||||
await writeFile(strings, sourceStrings.split('\n').filter((line) =>
|
||||
!line.startsWith('LangString ') || line.includes(`\${LANG_${languageId}}`)).join('\n'))
|
||||
await writeFile(strings, renderInstallerStrings([locale]), 'utf8')
|
||||
const include = join(languageOutput, 'include.nsh')
|
||||
await writeFile(include, `!define INSTALLER_BUILD_DIR "${join(output, 'ui')}"\n!define INSTALLER_STRINGS_FILE "${strings}"\n!include "${join(appRoot, 'scripts', 'installer.nsh')}"\n`)
|
||||
await build({ projectDir: appRoot, prepackaged: payload, targets: Platform.WINDOWS.createTarget(['nsis'], Arch.x64), publish: 'never',
|
||||
@@ -132,7 +131,7 @@ SectionEnd
|
||||
join(appRoot, 'tests', uninstallOnly ? 'windows-uninstall-smoke.ps1' : 'windows-installer-smoke.ps1'),
|
||||
'-Installer', join(languageOutput, 'installer-test.exe'),
|
||||
'-ProductName', productName, '-RegistryKey', guid, '-OutputDirectory', languageOutput,
|
||||
...uninstallOnly ? ['-Language', languageId, '-PackageName', packageName] : []], childOptions)
|
||||
'-Language', language, ...uninstallOnly ? ['-PackageName', packageName] : []], childOptions)
|
||||
process.stdout.write(`${language}\n${result.stdout}`)
|
||||
}
|
||||
succeeded = true
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/** Per-language installer resources feed both the packaging language list and the NSIS compiler. */
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { expect, it, onTestFinished } from 'vitest'
|
||||
import { readInstallerLocales, renderInstallerStrings } from '../scripts/installer-locales.mjs'
|
||||
|
||||
function fixture(): string {
|
||||
const directory = mkdtempSync(join(tmpdir(), 'dsh-installer-locales-'))
|
||||
onTestFinished(() => { rmSync(directory, { recursive: true, force: true }) })
|
||||
for (const id of ['en_US', 'zh_CN', 'ja_JP']) {
|
||||
writeFileSync(join(directory, `${id}.json`), readFileSync(new URL(`../installer/locales/${id}.json`, import.meta.url)))
|
||||
}
|
||||
return directory
|
||||
}
|
||||
|
||||
it('generates Japanese NSIS strings from the same files that select packaged languages', () => {
|
||||
const locales = readInstallerLocales()
|
||||
expect(locales.map(locale => locale.id)).toEqual(['en_US', 'ja_JP', 'zh_CN'])
|
||||
const source = renderInstallerStrings(locales)
|
||||
expect(source).toContain('LangString INSTALLER_INSTALL ${LANG_JAPANESE} "今すぐインストール"')
|
||||
expect(source).toContain('LangString INSTALLER_NATIVE_PROGRESS ${LANG_JAPANESE} "インストールを準備しています… %d%%"')
|
||||
expect(source).toContain('!ifdef LANG_JAPANESE\n')
|
||||
expect(source.match(/^LangString /gmu)).toHaveLength(93)
|
||||
const japanese = locales.filter(locale => locale.id === 'ja_JP')
|
||||
expect(renderInstallerStrings(japanese)).not.toContain('${LANG_ENGLISH}')
|
||||
})
|
||||
|
||||
it.each(['en_US', 'zh_CN', 'ja_JP'])('rejects a missing %s configuration', (id) => {
|
||||
const directory = fixture()
|
||||
rmSync(join(directory, `${id}.json`))
|
||||
expect(() => readInstallerLocales(directory)).toThrow(`missing ${id}.json`)
|
||||
})
|
||||
|
||||
it.each([
|
||||
['missing key', (resource: ReturnType<typeof readInstallerLocales>[number]) => { delete resource.strings.INSTALLER_INSTALL }, 'keys differ'],
|
||||
['extra key', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.strings.INSTALLER_EXTRA = 'extra' }, 'keys differ'],
|
||||
['empty text', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.strings.INSTALLER_INSTALL = '' }, 'nonempty text'],
|
||||
['changed placeholder', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%s%%' }, 'format placeholders'],
|
||||
['missing percent escape', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%d%' }, 'format placeholders'],
|
||||
['extra format specifier', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%d%% %q' }, 'format placeholders'],
|
||||
['duplicate language', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.nsisLanguage = 'ENGLISH' }, 'duplicate NSIS language'],
|
||||
['invalid compiler token', (resource: ReturnType<typeof readInstallerLocales>[number]) => { resource.nsisLanguage = 'JA\n!error' }, 'invalid NSIS language'],
|
||||
])('rejects %s', (_name, mutate, diagnostic) => {
|
||||
const directory = fixture()
|
||||
const resource = readInstallerLocales(directory).find(locale => locale.id === 'ja_JP')!
|
||||
mutate(resource)
|
||||
writeFileSync(join(directory, 'ja_JP.json'), JSON.stringify(resource))
|
||||
expect(() => readInstallerLocales(directory)).toThrow(diagnostic)
|
||||
})
|
||||
|
||||
it('escapes literal NSIS syntax without changing translated text', () => {
|
||||
const locale = readInstallerLocales()[0]!
|
||||
expect(renderInstallerStrings([{ ...locale, strings: { INSTALLER_INSTALL: '"$name"\nnext\rline' } }]))
|
||||
.toContain('"$\\"$$name$\\"$\\nnext$\\rline"')
|
||||
})
|
||||
@@ -5,13 +5,17 @@ import { AppInfo, Packager } from 'app-builder-lib'
|
||||
import { expandMacro } from 'app-builder-lib/out/util/macroExpander.js'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const { execute } = vi.hoisted(() => ({ execute: vi.fn(async () => undefined) }))
|
||||
const { execute, write } = vi.hoisted(() => ({ execute: vi.fn(async () => undefined), write: vi.fn(async () => undefined) }))
|
||||
vi.mock('node:child_process', async (importOriginal) => {
|
||||
const original = await importOriginal<typeof import('node:child_process')>()
|
||||
const { promisify } = await import('node:util')
|
||||
return { ...original, execFile: Object.assign(vi.fn(), { [promisify.custom]: execute }) }
|
||||
})
|
||||
|
||||
vi.mock('node:fs/promises', async importOriginal => ({
|
||||
...await importOriginal<typeof import('node:fs/promises')>(), writeFile: write,
|
||||
}))
|
||||
|
||||
describe('installer preparation preserves application dependencies', () => {
|
||||
it.each(['win32', 'darwin'] as const)('rejects a missing production policy before signing on %s', async (platform) => {
|
||||
const { createElectronBuilderConfig } = await import('../scripts/electron-builder-config.mjs')
|
||||
@@ -22,6 +26,7 @@ describe('installer preparation preserves application dependencies', () => {
|
||||
})
|
||||
it.each(['win32', 'darwin'] as const)('preserves installer metadata and dependency ownership on %s', async (platform) => {
|
||||
execute.mockClear()
|
||||
write.mockClear()
|
||||
const env = {
|
||||
DSH_DESKTOP_APP_ID: 'com.example.installer',
|
||||
DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN: 'https://policy.example.com',
|
||||
@@ -49,6 +54,7 @@ describe('installer preparation preserves application dependencies', () => {
|
||||
expect(appInfo.copyright).toBe(`Copyright © ${new Date().getFullYear()} DeepSeek Harness`)
|
||||
if (platform === 'win32') {
|
||||
expect(expandMacro(config.nsis.uninstallDisplayName, null, appInfo, {}, false)).toBe('DeepSeek Harness')
|
||||
expect(config.nsis.installerLanguages).toEqual(['en_US', 'ja_JP', 'zh_CN'])
|
||||
}
|
||||
const aboutIcon = config.extraResources.find(resource => resource.to === 'icon.png')
|
||||
expect(aboutIcon).toBeDefined()
|
||||
@@ -71,6 +77,11 @@ describe('installer preparation preserves application dependencies', () => {
|
||||
await packager.installAppDependencies(process.platform === 'win32' ? Platform.LINUX : Platform.WINDOWS, Arch.x64)
|
||||
expect(packager.areNodeModulesHandledExternally).toBe(false)
|
||||
expect(execute).toHaveBeenCalledTimes(platform === 'win32' ? 1 : 0)
|
||||
expect(write).toHaveBeenCalledTimes(platform === 'win32' ? 1 : 0)
|
||||
if (platform === 'win32') {
|
||||
expect(write).toHaveBeenCalledWith(expect.stringMatching(/installer-ui[\\/]strings\.nsh$/u),
|
||||
expect.stringContaining('LangString INSTALLER_INSTALL ${LANG_JAPANESE}'), 'utf8')
|
||||
}
|
||||
} finally {
|
||||
vi.unstubAllEnvs()
|
||||
vi.restoreAllMocks()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[CmdletBinding()]
|
||||
param([Parameter(Mandatory)][string]$Installer, [Parameter(Mandatory)][string]$ProductName,
|
||||
[Parameter(Mandatory)][string]$RegistryKey,
|
||||
[Parameter(Mandatory)][string]$OutputDirectory)
|
||||
[Parameter(Mandatory)][string]$OutputDirectory, [Parameter(Mandatory)][string]$Language)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'windows-installer-ui.ps1')
|
||||
Add-Type -AssemblyName UIAutomationClient, UIAutomationTypes
|
||||
@@ -14,12 +14,8 @@ $uninstaller = Join-Path $installPath ('Uninstall ' + $ProductName + '.exe')
|
||||
$processes = [Collections.Generic.List[Diagnostics.Process]]::new()
|
||||
$results = [Collections.Generic.List[string]]::new()
|
||||
$expected = Get-Content (Join-Path $PSScriptRoot 'expected/windows-installer.json') -Raw | ConvertFrom-Json
|
||||
$localizedCopy = @{ ENGLISH = @{}; SIMPCHINESE = @{} }
|
||||
Get-Content (Join-Path $PSScriptRoot '../installer/strings.nsh') -Encoding UTF8 | ForEach-Object {
|
||||
if ($_ -match '^LangString (INSTALLER_\w+) \$\{LANG_(ENGLISH|SIMPCHINESE)\} "(.*)"$') {
|
||||
$localizedCopy[$Matches[2]][$Matches[1]] = $Matches[3]
|
||||
}
|
||||
}
|
||||
$resource = Get-Content (Join-Path $PSScriptRoot "../installer/locales/$Language.json") -Encoding UTF8 -Raw | ConvertFrom-Json
|
||||
$localizedCopy = @{ $Language = $resource.strings }
|
||||
function Wait-Control([Diagnostics.Process]$Process, [string]$Text, [switch]$Dialog) {
|
||||
$timer = [Diagnostics.Stopwatch]::StartNew()
|
||||
do {
|
||||
|
||||
@@ -4,6 +4,7 @@ param([Parameter(Mandatory)][string]$Installer, [Parameter(Mandatory)][string]$P
|
||||
[Parameter(Mandatory)][string]$RegistryKey, [Parameter(Mandatory)][string]$OutputDirectory,
|
||||
[Parameter(Mandatory)][string]$Language, [Parameter(Mandatory)][string]$PackageName)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$copy = (Get-Content (Join-Path $PSScriptRoot "../installer/locales/$Language.json") -Encoding UTF8 -Raw | ConvertFrom-Json).uninstaller
|
||||
$OutputDirectory = [IO.Path]::GetFullPath($OutputDirectory)
|
||||
. (Join-Path $PSScriptRoot 'windows-installer-ui.ps1')
|
||||
[InstallerCapture]::Initialize()
|
||||
@@ -69,12 +70,12 @@ try {
|
||||
if ($mode -eq 'home-inside') { $env:DSH_HOME = Join-Path $userDataPath 'home' } else { Remove-Item Env:DSH_HOME -ErrorAction SilentlyContinue }
|
||||
$process = Start-Process -FilePath $uninstaller -ArgumentList $arguments -PassThru -WindowStyle ($(if ($mode -eq 'interactive') { 'Normal' } else { 'Hidden' }))
|
||||
if ($mode -eq 'interactive') {
|
||||
$welcomeText = if ($Language -eq 'ENGLISH') { 'Welcome' } else { -join [char[]]@(0x6B22, 0x8FCE) }
|
||||
$welcomeText = $copy.welcome
|
||||
$welcome = Wait-Text $welcomeText
|
||||
$window = [InstallerCapture]::TopLevel($welcome)
|
||||
[void][InstallerCapture]::SaveNative($window, (Join-Path $OutputDirectory 'uninstall-welcome.png'), $false)
|
||||
[InstallerCapture]::Click([InstallerCapture]::GetDlgItem($window, 1))
|
||||
$finishedText = if ($Language -eq 'ENGLISH') { 'has been uninstalled' } else { -join [char[]]@(0x5DF2, 0x4ECE, 0x4F60) }
|
||||
$finishedText = $copy.finished
|
||||
[void](Wait-Text $finishedText)
|
||||
[InstallerCapture]::Click([InstallerCapture]::GetDlgItem($window, 1))
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"@deepseek-ai/dsh-experimental-webworker-runtime": "workspace:*",
|
||||
"@deepseek-ai/dsh-remote-mock": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-projection-cache": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-testkit": "workspace:*",
|
||||
"@deepseek-ai/dsh-util-values": "workspace:*",
|
||||
"@types/node": "^22.20.1",
|
||||
"@types/ws": "8.18.1",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
// Session-header background jobs driven by a real `ctx.jobs` entry. No model
|
||||
// call is involved.
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
@@ -87,7 +88,7 @@ describe.skipIf(MODE === 'record')('web e2e: background job list', () => {
|
||||
const trigger = page.getByRole('button', { name: '1 background job running' })
|
||||
expect(await trigger.count()).toBe(0)
|
||||
|
||||
const started = await scaffold.ctx.tools.execute({
|
||||
const started = await executeToolFixture(scaffold.ctx, {
|
||||
signal: new AbortController().signal,
|
||||
callId: ToolCallId('background-job-list-e2e'),
|
||||
name: 'bash',
|
||||
|
||||
@@ -56,9 +56,9 @@ it.skipIf(process.platform !== 'darwin')('keeps system requests pending until fr
|
||||
await scaffold.ctx.settings.mutate('cua', [{ op: 'set', path: ['allowedApps'], value: [] }])
|
||||
// Application consent remains independent of the session's tool-approval policy.
|
||||
const grant = scaffold.ctx.tools.execute({ agent, signal: new AbortController().signal,
|
||||
callId: ToolCallId('cua-app-approval'), name: 'run_code',
|
||||
arguments: { code: 'return await tools.cua({ method: "getApp", params: { selector: "Fixture" } })',
|
||||
description: 'Request application access' } })
|
||||
calls: [{ type: 'tool-call', id: ToolCallId('cua-app-approval'), name: 'run_code',
|
||||
arguments: JSON.stringify({ code: 'return await tools.cua({ method: "getApp", params: { selector: "Fixture" } })',
|
||||
description: 'Request application access' }) }] })
|
||||
const approval = page.locator('[data-approval-key]')
|
||||
await Promise.race([approval.waitFor(), grant.then((result) => {
|
||||
throw new Error(`Application selection completed before consent: ${JSON.stringify(result)}`)
|
||||
@@ -73,7 +73,7 @@ it.skipIf(process.platform !== 'darwin')('keeps system requests pending until fr
|
||||
await compareOrRefreshGolden(fileURLToPath(new URL('./expected/cua-permissions/application-approval.expected.md', import.meta.url)),
|
||||
await captureStableAria(page, '[data-approval-key]', scaffold.workspaceCwd), webSnapshotMode())
|
||||
await approval.getByRole('button', { name: 'Always allow', exact: true }).click()
|
||||
expect((await grant).isError).toBe(false)
|
||||
expect((await grant).results).toMatchObject([{ result: { isError: false } }])
|
||||
await approval.waitFor({ state: 'hidden' })
|
||||
await page.getByRole('button', { name: 'Plugins', exact: true }).click()
|
||||
const card = page.locator('[data-plugin-package="@deepseek-ai/dsh-cua-bundle"]')
|
||||
|
||||
@@ -103,14 +103,17 @@ describe.skipIf(MODE === 'record')('web e2e: native and Client locale preference
|
||||
await jaDialog.getByRole('button', { name: '日本語', exact: true }).waitFor()
|
||||
await expect.poll(() => reported).toEqual(['ja'])
|
||||
expect(await page.evaluate(() => document.documentElement.lang)).toBe('ja')
|
||||
await page.setViewportSize({ width: 390, height: 844 })
|
||||
const overflows = (): Promise<number> => jaDialog.evaluate((dialog) => {
|
||||
const containers = [dialog, ...dialog.querySelectorAll<HTMLElement>('*')]
|
||||
// The narrow navigation strip scrolls horizontally by design; inspect the panel and section content.
|
||||
const options = dialog.lastElementChild!
|
||||
const containers = [dialog, options, ...options.querySelectorAll<HTMLElement>('*')]
|
||||
.filter(element => element === dialog || ['auto', 'scroll'].includes(getComputedStyle(element).overflowX))
|
||||
return containers.filter(element => element.clientWidth > 0 && element.scrollWidth > element.clientWidth + 1).length
|
||||
})
|
||||
await expect.poll(overflows).toBe(0)
|
||||
await jaDialog.evaluate((dialog) => {
|
||||
const options = dialog.querySelector('nav')!.nextElementSibling!.lastElementChild!
|
||||
const options = dialog.lastElementChild!
|
||||
const probe = document.createElement('div')
|
||||
probe.dataset.localeOverflowProbe = ''
|
||||
probe.style.width = '2000px'
|
||||
|
||||
@@ -76,10 +76,11 @@
|
||||
- text: 共 2 个 · 2 运行中
|
||||
- list:
|
||||
- listitem:
|
||||
- text: "@deepseek-ai/dsh-experimental-translator Machine translation with reusable Session results"
|
||||
- text: 翻译服务 提供机器翻译,并复用会话中已保存的翻译结果。
|
||||
- code: translator
|
||||
- code: "@deepseek-ai/dsh-experimental-translator"
|
||||
- text: 运行中
|
||||
- switch "启用组件 @deepseek-ai/dsh-experimental-translator" [checked]
|
||||
- switch "启用组件 翻译服务" [checked]
|
||||
- listitem:
|
||||
- text: 思考过程机器翻译 将展开的思考内容机器翻译为其他语言。
|
||||
- code: cot-translation
|
||||
|
||||
@@ -73,10 +73,11 @@
|
||||
- text: 共 2 个 · 2 运行中
|
||||
- list:
|
||||
- listitem:
|
||||
- text: "@deepseek-ai/dsh-experimental-translator Machine translation with reusable Session results"
|
||||
- text: 翻译服务 提供机器翻译,并复用会话中已保存的翻译结果。
|
||||
- code: translator
|
||||
- code: "@deepseek-ai/dsh-experimental-translator"
|
||||
- text: 运行中
|
||||
- switch "启用组件 @deepseek-ai/dsh-experimental-translator" [checked]
|
||||
- switch "启用组件 翻译服务" [checked]
|
||||
- listitem:
|
||||
- text: 思考过程机器翻译 将展开的思考内容机器翻译为其他语言。
|
||||
- code: cot-translation
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
- listitem:
|
||||
- button "自動認可レビューを表示": 自動認可レビュー
|
||||
- text: 実験的 各ツール呼び出しの前にモデルが認可を判断する、自動認可レビュー権限モードを提供します。
|
||||
- status
|
||||
- switch "自動認可レビューを有効化"
|
||||
@@ -0,0 +1,32 @@
|
||||
/** Japanese package resources reach the real plugin manager through Host metadata and Client locale resolution. */
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { chromium, type Browser } from 'playwright'
|
||||
import { expect, it, onTestFailed, onTestFinished } from 'vitest'
|
||||
import { captureStableAria, compareOrRefreshGolden, launchWebScaffold, watchConsole, webSnapshotMode, type WebScaffold } from './scaffold.ts'
|
||||
import { saveFailureShot } from './support.ts'
|
||||
|
||||
it('displays Japanese plugin titles and descriptions from package metadata', async () => {
|
||||
const resources: { scaffold?: WebScaffold; browser?: Browser } = {}
|
||||
onTestFinished(async () => {
|
||||
try { await resources.browser?.close() } finally { await resources.scaffold?.close() }
|
||||
})
|
||||
const scaffold = await launchWebScaffold()
|
||||
resources.scaffold = scaffold
|
||||
const browser = await chromium.launch()
|
||||
resources.browser = browser
|
||||
const page = await browser.newPage({ locale: 'ja-JP', viewport: { width: 1440, height: 960 } })
|
||||
const tripwire = watchConsole(page)
|
||||
onTestFailed(() => saveFailureShot(page, 'japanese-plugin-metadata'))
|
||||
await page.goto(scaffold.authenticatedUrl)
|
||||
await page.getByRole('button', { name: 'プラグイン', exact: true }).click()
|
||||
const panel = page.locator('[data-plugin-panel]')
|
||||
const title = panel.getByRole('button', { name: '自動認可レビューを表示', exact: true })
|
||||
await title.waitFor()
|
||||
const card = title.locator('xpath=ancestor::li')
|
||||
await card.getByText('各ツール呼び出しの前にモデルが認可を判断する、自動認可レビュー権限モードを提供します。', { exact: true }).waitFor()
|
||||
const expected = fileURLToPath(new URL('./expected/japanese-plugin-metadata/card.expected.md', import.meta.url))
|
||||
await compareOrRefreshGolden(expected,
|
||||
await captureStableAria(page, '[data-plugin-panel] li:has(button[aria-label="自動認可レビューを表示"])', scaffold.workspaceCwd), webSnapshotMode())
|
||||
expect(tripwire.warnings).toEqual([])
|
||||
expect(tripwire.pageErrors).toEqual([])
|
||||
})
|
||||
@@ -1,4 +1,5 @@
|
||||
/** Background-job menu geometry over the normal Browser dock in the shipped Web composition. */
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { join } from 'node:path'
|
||||
@@ -116,7 +117,7 @@ describe.skipIf(MODE === 'record')('web e2e: jobs menu layering', () => {
|
||||
const opened = scaffold.ctx.agents.get(SEED_ID)
|
||||
if (opened === undefined) throw new Error('opened session has no live Agent')
|
||||
agent = opened
|
||||
const started = await scaffold.ctx.tools.execute({
|
||||
const started = await executeToolFixture(scaffold.ctx, {
|
||||
signal: new AbortController().signal,
|
||||
callId: ToolCallId('jobs-menu-layering-e2e'),
|
||||
name: 'bash',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
// Session-header job list driven by a real background bash run: the job row
|
||||
// arrives over the job roster stream, expanding it opens the output
|
||||
// observation stream, and the panel shows the process's real output while it
|
||||
@@ -87,7 +88,7 @@ describe.skipIf(MODE === 'record')('web e2e: live job stream', () => {
|
||||
const trigger = page.getByRole('button', { name: '1 background job running' })
|
||||
expect(await trigger.count()).toBe(0)
|
||||
|
||||
const started = await scaffold.ctx.tools.execute({
|
||||
const started = await executeToolFixture(scaffold.ctx, {
|
||||
signal: new AbortController().signal,
|
||||
callId: ToolCallId('live-job-stream-e2e'),
|
||||
name: 'bash',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
@@ -97,14 +98,14 @@ describe('minimal agent preset', () => {
|
||||
const stateDir = join(scaffold.workspaceCwd, 'persistent-state')
|
||||
await mkdir(stateDir)
|
||||
const signal = new AbortController().signal
|
||||
await scaffold.ctx.tools.execute({
|
||||
await executeToolFixture(scaffold.ctx, {
|
||||
signal,
|
||||
callId: ToolCallId('minimal-bash-state-setup'),
|
||||
name: 'bash',
|
||||
arguments: { command: `cd ${JSON.stringify(stateDir)} && export DSH_MINIMAL_STATE=PERSISTED` },
|
||||
agent: agentHandle.agent,
|
||||
})
|
||||
const bash = await scaffold.ctx.tools.execute({
|
||||
const bash = await executeToolFixture(scaffold.ctx, {
|
||||
signal,
|
||||
callId: ToolCallId('minimal-bash-state-read'),
|
||||
name: 'bash',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
// Web e2e scenario: fresh round trip. A real chromium types a prompt into the
|
||||
// real composer; the wire, Remote gateway, agent loop, and the REAL bash tool (echo
|
||||
// in the temp workspace) all run; the model adapter is dsh-llm-replay (keyless)
|
||||
@@ -249,7 +250,7 @@ describe('web e2e: fresh round trip through the real assembly', () => {
|
||||
setup: agentCtx => probe.ctx.agentPresets.mount(agentCtx).then(() => undefined),
|
||||
})
|
||||
try {
|
||||
const result = await probe.ctx.tools.execute({
|
||||
const result = await executeToolFixture(probe.ctx, {
|
||||
signal: AbortSignal.timeout(5_000),
|
||||
callId: ToolCallId('web-url-probe'),
|
||||
name: 'bash',
|
||||
|
||||
@@ -384,13 +384,6 @@ export interface LaunchOptions {
|
||||
paceMs?: number
|
||||
/** Synthetic model capacity for UI scenarios whose seeded history must remain uncompacted. */
|
||||
replayContextWindow?: number
|
||||
/**
|
||||
* Tool presentation mode patched onto the shipped `tools` row (`code`
|
||||
* collapses the wire to run_code + the SDK prompt section). Omit for the
|
||||
* yml default. The PTC runtime row is always in the tree, so no extra
|
||||
* insertion is needed.
|
||||
*/
|
||||
toolsMode?: 'native' | 'ptc'
|
||||
/**
|
||||
* Keep the shipped DeepSeek adapter mounted while masking the process
|
||||
* environment's DEEPSEEK_API_KEY for this scaffold lifetime. This is the
|
||||
@@ -689,7 +682,6 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise<We
|
||||
{ id: 'agent-preset-registry', config: { default: options.agentPresets.default } },
|
||||
{ insert: (options.agentPresets.definitions ?? []).map(config => ({ id: `preset-${config.id}`, name: '@deepseek-ai/dsh-agent-preset', config })) },
|
||||
],
|
||||
...options.toolsMode === undefined ? [] : [{ id: 'tools', config: { mode: options.toolsMode } }],
|
||||
...options.deepSeekSearch === undefined
|
||||
? []
|
||||
: [{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/** Keyless assembled-Web evidence for conversational Schedule delivery. */
|
||||
import { executeToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
|
||||
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
@@ -354,7 +355,7 @@ describe.skipIf(MODE === 'record')('web e2e: conversational reminders', () => {
|
||||
source: { kind: 'user' },
|
||||
})
|
||||
await workspace.attachSession(afterHandle.agent.id)
|
||||
const afterCreated = await scaffold.ctx.tools.execute({
|
||||
const afterCreated = await executeToolFixture(scaffold.ctx, {
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
callId: ToolCallId('schedule-after-create'),
|
||||
name: 'schedule_create',
|
||||
@@ -420,7 +421,7 @@ describe.skipIf(MODE === 'record')('web e2e: conversational reminders', () => {
|
||||
})
|
||||
await scaffold.ctx.schedule.delete({ sessionId: everyHandle.agent.id, id: wake.id })
|
||||
await workspace.attachSession(everyHandle.agent.id)
|
||||
const everyListed = await scaffold.ctx.tools.execute({
|
||||
const everyListed = await executeToolFixture(scaffold.ctx, {
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
callId: ToolCallId('schedule-every-list'),
|
||||
name: 'schedule_list',
|
||||
@@ -1181,7 +1182,7 @@ describe.skipIf(MODE === 'record')('web e2e: active Schedule catalog', () => {
|
||||
})
|
||||
const time = clock.format(new Date(Date.now() + 3_600_000))
|
||||
const prompt = 'Inspect the daily calendar rule'
|
||||
const result = await scaffold.ctx.tools.execute({
|
||||
const result = await executeToolFixture(scaffold.ctx, {
|
||||
signal: AbortSignal.timeout(10_000), callId: ToolCallId('schedule-daily-catalog-create'),
|
||||
name: 'schedule_create', arguments: { prompt, title: prompt, daily: { time, time_zone: timeZone } }, agent,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { executeToolFixture, executeModelToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
// Boots the shipped Web composition over the built dist this lane already uses
|
||||
// and asserts its catalog, defaults, Loader lifecycle, and one complete Auto
|
||||
// producer-to-tool path. Browser scenarios in this lane own visual behavior.
|
||||
@@ -679,7 +680,7 @@ it('lets a preset producer reach the background-job registry', async () => {
|
||||
// `tool-bash` is a preset row and `tasks` is a host registry; the producer
|
||||
// resolves it with `ctx.get`, so a registry hidden behind a preset realm
|
||||
// fails here — with every task control still listed in the catalog above.
|
||||
const started = await ctx.tools.execute({
|
||||
const started = await executeModelToolFixture(ctx, {
|
||||
signal,
|
||||
callId: ToolCallId('shipped-bash-background'),
|
||||
name: 'bash',
|
||||
@@ -701,7 +702,7 @@ it('lets a preset producer reach the background-job registry', async () => {
|
||||
|
||||
// The controller reads what the producer started: same registry, one
|
||||
// owner. A per-preset registry would list nothing here even on success.
|
||||
const listed = await ctx.tools.execute({
|
||||
const listed = await executeToolFixture(ctx, {
|
||||
signal,
|
||||
callId: ToolCallId('shipped-task-list'),
|
||||
name: 'job_list',
|
||||
@@ -714,7 +715,7 @@ it('lets a preset producer reach the background-job registry', async () => {
|
||||
|
||||
// The full round trip: the output a host-plane producer wrote is collected
|
||||
// through a preset-plane control, which is the linkage the realm severed.
|
||||
const collected = await ctx.tools.execute({
|
||||
const collected = await executeToolFixture(ctx, {
|
||||
signal,
|
||||
callId: ToolCallId('shipped-task-output'),
|
||||
name: 'job_output',
|
||||
@@ -1036,7 +1037,7 @@ it('rolls back a failed shipped Auto initialization before publishing or interce
|
||||
// contribution performs no review, so success proves the failed shipped
|
||||
// integration left no pre-execute listener behind. It is not supported
|
||||
// Auto execution behavior.
|
||||
const result = await ctx.tools.execute({
|
||||
const result = await executeToolFixture(ctx, {
|
||||
signal: new AbortController().signal,
|
||||
callId: ToolCallId('shipped-auto-init-rollback-write'),
|
||||
name: 'write',
|
||||
|
||||
@@ -603,7 +603,7 @@ describe('dsh web keyless CLI smoke', () => {
|
||||
}
|
||||
}, 120_000)
|
||||
|
||||
it('DSH_TOOLS_MODE=ptc collapses the provider wire tools to run_code with the SDK prompt section', async () => {
|
||||
it.each(['native', 'ptc'] as const)('selects the %s executor through profile overlays and ignores the retired environment selector', async (mode) => {
|
||||
requireDist()
|
||||
const workspace = mkdtempSync(join(tmpdir(), 'dsh-web-ptc-'))
|
||||
|
||||
@@ -632,14 +632,17 @@ describe('dsh web keyless CLI smoke', () => {
|
||||
const tsxLoader = pathToFileURL(createRequire(join(REPO_ROOT, 'package.json')).resolve('tsx')).href
|
||||
const child = spawn(
|
||||
process.execPath,
|
||||
['--import', tsxLoader, join(REPO_ROOT, 'apps/cli/src/bin.ts'), 'web', '--no-open', '--port', '0'],
|
||||
['--import', tsxLoader, join(REPO_ROOT, 'apps/cli/src/bin.ts'), 'web',
|
||||
...mode === 'ptc' ? ['--patch', join(REPO_ROOT, 'apps/cli/config/examples/ptc.yml')] : [],
|
||||
'--no-open', '--port', '0',
|
||||
],
|
||||
{
|
||||
cwd: workspace,
|
||||
env: {
|
||||
...process.env,
|
||||
DEEPSEEK_API_KEY: 'keyless-web-ptc',
|
||||
DEEPSEEK_BASE_URL: `http://127.0.0.1:${address.port}`,
|
||||
DSH_TOOLS_MODE: 'ptc',
|
||||
DSH_TOOLS_MODE: mode === 'native' ? 'ptc' : 'native',
|
||||
DSH_HOME: join(workspace, '.dsh'),
|
||||
DSH_AGENTS_HOME: join(workspace, '.agents'),
|
||||
TSX_TSCONFIG_PATH: join(REPO_ROOT, 'tsconfig.json'),
|
||||
@@ -662,9 +665,15 @@ describe('dsh web keyless CLI smoke', () => {
|
||||
setTimeout(() => { reject(new Error('provider request not received in 10s')) }, 10_000).unref()
|
||||
}),
|
||||
])
|
||||
expect(captured.tools?.map(tool => tool.name)).toEqual(['run_code'])
|
||||
expect(captured.system).toContain('## Writing code for run_code')
|
||||
expect(captured.system).toContain('declare const tools')
|
||||
if (mode === 'ptc') {
|
||||
expect(captured.tools?.map(tool => tool.name)).toEqual(['run_code'])
|
||||
expect(captured.system).toContain('## Writing code for run_code')
|
||||
expect(captured.system).toContain('declare const tools')
|
||||
} else {
|
||||
expect(captured.tools?.map(tool => tool.name)).not.toContain('run_code')
|
||||
expect(captured.tools?.length).toBeGreaterThan(0)
|
||||
expect(captured.system).not.toContain('## Writing code for run_code')
|
||||
}
|
||||
} finally {
|
||||
const closed = child.exitCode === null
|
||||
? new Promise<void>((resolveClose) => { child.once('close', () => { resolveClose() }) })
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// this client-registered project must not also hold them (one program
|
||||
// cannot see both sides of the cordis Context merges).
|
||||
"exclude": [
|
||||
"tests/japanese-plugin-metadata.e2e.ts",
|
||||
"tests/rich-text-quotes.e2e.ts",
|
||||
"tests/hover-input.e2e.ts",
|
||||
"tests/collapse-timing.e2e.ts",
|
||||
|
||||
@@ -10,7 +10,7 @@ import { createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm'
|
||||
import type { GenerateOptions, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm'
|
||||
import { SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session'
|
||||
import * as JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
import { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
|
||||
import { defineContentToolFixture } from '@deepseek-ai/dsh-tool-testkit'
|
||||
import { assertBuiltBenchmarkRuntime } from '../support/built-worker.ts'
|
||||
import { PARENT_ID, response, resultText, syntheticHistory, TIME_ZERO, WORKLOAD } from './workload.ts'
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"@deepseek-ai/dsh-storage-domain": "workspace:*",
|
||||
"@deepseek-ai/dsh-storage-json": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-testkit": "workspace:*",
|
||||
"@deepseek-ai/dsh-tools": "workspace:*",
|
||||
"@deepseek-ai/dsh-token-meter": "workspace:*",
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:*",
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
en: e89802f066e4955d
|
||||
zh: ea2fb4bef94e086d
|
||||
/deepseek-harness-architecture/turn-flow:
|
||||
en: 4151c0b69f563f4e
|
||||
zh: 32c62b6326446c10
|
||||
en: 53db218880e07b3d
|
||||
zh: 17cffbc6258b57a8
|
||||
/deepseek-harness-architecture/session-log:
|
||||
en: 8a7f19b95d426c99
|
||||
zh: d5bb0538404e20ea
|
||||
|
||||
@@ -115,6 +115,8 @@ Failed steps [record missing tool results](../packages/core/agent-loop/README.md
|
||||
|
||||
Details: the [sequence diagram](agent-lifecycle.md), the [tool pipeline](tool-execution-pipeline.md), and [cancellation and error recovery](subsystems/core.md#the-agent-handle).
|
||||
|
||||
[`ctx.tools.execute()`](subsystems/tools.md) receives raw batches and concurrency limits.
|
||||
|
||||
## Session log
|
||||
|
||||
The session log is the source of the context the model sees. `deriveMessages()` projects model history from it. Each `assistant/message` embeds the exact compact timed stream that produced its assembled content; `assistant/attempt` retains settled failed, retried, cancelled, and stream-error attempts without adding model history. Fork, resume, transcripts, telemetry, and persistence all derive from these durable settlements, while live UI incrementality comes from `agent/assistant-stream`; a hard process loss before settlement leaves no durable attempt stream ([decision](../.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.md)).
|
||||
|
||||
@@ -119,6 +119,8 @@ turn/end
|
||||
|
||||
详情见[时序图](agent-lifecycle.zh.md)、[工具流水线](tool-execution-pipeline.zh.md)和[取消与错误恢复](subsystems/core.zh.md#the-agent-handle)。
|
||||
|
||||
[`ctx.tools.execute()`](subsystems/tools.zh.md) 接收原始调用批次和并发上限。
|
||||
|
||||
## 会话日志
|
||||
|
||||
会话日志是模型所见上下文的来源。`deriveMessages()` 从中投影出模型历史。每个 `assistant/message` 都嵌入产生其组装内容的精确紧凑带时间 stream;`assistant/attempt` 保留已到达 settlement 的失败、重试、取消与 stream error attempt,且不添加模型历史。fork、恢复、transcript(文本记录)、遥测与持久化都从这些持久 settlement 派生,实时 UI 增量则来自 `agent/assistant-stream`;如果进程在 settlement 前硬中断,则不会留下持久 attempt stream(见[决策](../.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.zh.md))。
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
en: 41d772192075e133
|
||||
zh: 5ef3da69b4de1d8a
|
||||
/capability-seams-and-core-services:
|
||||
en: 753b3da3abc6aeea
|
||||
zh: aab02ec16c3f744b
|
||||
en: f2546ac3454d220d
|
||||
zh: 642a473c0405e81f
|
||||
@@ -166,7 +166,7 @@ flowchart LR
|
||||
pkg_tools["tools"]
|
||||
pkg_tool_terminal["tool-terminal"]
|
||||
pkg_tool_web["tool-web"]
|
||||
svc_tools["ctx.tools<br/>Tool registry and guarded execution pipeline"]
|
||||
svc_tools["ctx.tools<br/>Scoped tool registry and executor selection"]
|
||||
pkg_tool_ask_user["tool-ask-user"]
|
||||
pkg_tool_cordis["tool-cordis"]
|
||||
pkg_tool_skill["tool-skill"]
|
||||
@@ -235,6 +235,7 @@ flowchart LR
|
||||
svc_ptcRuntime["ctx.ptcRuntime<br/>PTC execution seam"]
|
||||
pkg_ptc_runtime_node["ptc-runtime-node"]
|
||||
pkg_experimental_ptc_runtime_python["experimental-ptc-runtime-python"]
|
||||
pkg_tool_executor_ptc["tool-executor-ptc"]
|
||||
pkg_workflow_ptc["workflow-ptc"]
|
||||
pkg_fs["fs"]
|
||||
svc_fs["ctx.fs<br/>Filesystem provider seam"]
|
||||
@@ -516,7 +517,7 @@ flowchart LR
|
||||
svc_pluginMarket --> pkg_plugin_market
|
||||
svc_pluginRegistryProbe --> pkg_client_ui_plugin_manager
|
||||
svc_profileContext --> pkg_plugin_manager
|
||||
svc_ptcRuntime --> pkg_tools
|
||||
svc_ptcRuntime --> pkg_tool_executor_ptc
|
||||
svc_ptcRuntime --> pkg_workflow_ptc
|
||||
svc_remoteAccess --> pkg_api_gateway
|
||||
svc_remoteAccess --> pkg_api_session_controller
|
||||
@@ -677,7 +678,7 @@ flowchart LR
|
||||
| `ctx.sessionReferenceResolver` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax. |
|
||||
| `ctx.sessionTitle` | `seam` | [`session-title`](../packages/session/session-title) | [`session-title-first-prompt-llm`](../packages/session/session-title-first-prompt-llm), [`session-title-all-prompts-llm`](../packages/experimental/session-title-all-prompts-llm) | - | - | Owns the deterministic fallback, latest-title fold, and sole optional asynchronous provider registration. |
|
||||
| `ctx.systemPrompt` | `core` | [`system-prompt`](../packages/core/system-prompt) | - | [`agent-loop`](../packages/core/agent-loop), [`tools`](../packages/core/tools), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-web`](../packages/web/tool-web) | - | Collects prompt sections and model-facing tool schemas for each step. |
|
||||
| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/interaction/tool-ask-user), [`tool-bash`](../packages/shell/tool-bash), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | Registers capabilities, owns PTC mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation. |
|
||||
| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/interaction/tool-ask-user), [`tool-bash`](../packages/shell/tool-bash), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | Registers capabilities and scoped executors. Native and PTC providers own descriptions and complete raw call batches; their optional shared pipeline handles tool policy and dispatch. |
|
||||
| `ctx.userQuestions` | `seam` | [`user-questions`](../packages/interaction/user-questions) | - | [`tool-ask-user`](../packages/interaction/tool-ask-user) | - | UI front ends provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise. |
|
||||
| `ctx.planMode` | `core` | [`plan-mode`](../packages/plan/plan-mode) | - | - | - | Folds logged plan/mode state, flushes user selections at turn boundaries, renders deployment-owned guidance, registers /plan, and keeps the plan-exit schema stable across transitions. |
|
||||
| `ctx.agentPresets` | `core` | [`agent-preset-registry`](../packages/preset/agent-preset-registry) | - | - | - | Eagerly mounts YAML-declared preset revisions, binds Agents and cold readers to scoped contributions, and retains retired revisions until their last user releases them. |
|
||||
@@ -699,7 +700,7 @@ flowchart LR
|
||||
| `ctx.sandboxPolicy` | `core` | [`sandbox-policy`](../packages/sandbox/sandbox-policy) | - | [`bash-sandbox`](../packages/shell/bash-sandbox), [`fs-sandbox`](../packages/fs/fs-sandbox), [`terminal-bash`](../packages/terminal/terminal-bash) | - | The one home for the deployment default mode + workspace root; only the sandboxed executor and provider read the service (the tool layers use the pure `sandbox/mode` fold it also exports). Both enforcing families read it so bash and fs cannot confine to different roots. |
|
||||
| `ctx.approval` | `seam` | [`user-approval`](../packages/interaction/user-approval) | - | [`tools`](../packages/core/tools), [`tool-bash`](../packages/shell/tool-bash), [`acp`](../packages/acp/acp) | - | One-shot permission decisions dispatched over the `approval/request` waterfall; answerers are listeners (the ACP bridge for its own agents), absence fails closed to `unavailable`. |
|
||||
| `ctx.permissionPresets` | `core` | [`permission-presets`](../packages/interaction/permission-presets) | - | - | - | User-facing preset table (`workspace-write`/`danger-full-access`) bundling the sandbox-mode and approval-policy knobs; a switch writes one `permission/preset` event through to both knob events. |
|
||||
| `ctx.ptcRuntime` | `seam` | [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime) | [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), [`experimental-ptc-runtime-python`](../packages/experimental/ptc-runtime-python) | [`tools`](../packages/core/tools), [`workflow-ptc`](../packages/workflow/workflow-ptc) | - | Runs programs against host-provided async bindings; tools owns PTC presentation and workflow-ptc owns workflow orchestration. |
|
||||
| `ctx.ptcRuntime` | `seam` | [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime) | [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), [`experimental-ptc-runtime-python`](../packages/experimental/ptc-runtime-python) | [`tool-executor-ptc`](../packages/core/tool-executor-ptc), [`workflow-ptc`](../packages/workflow/workflow-ptc) | - | Runs programs against host-provided async bindings; tool-executor-ptc owns PTC presentation and workflow-ptc owns workflow orchestration. |
|
||||
| `ctx.fs` | `seam` | [`fs`](../packages/fs/fs) | [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`fs-ssh`](../packages/ssh/fs-ssh) | [`tool-fs`](../packages/fs/tool-fs) | [`fs-observation-policy`](../packages/fs/fs-observation-policy) | tool-fs executes read/write/edit through ctx.fs; fs-sandbox fences mutations by the shared sandbox mode; fs-observation-policy contributes observed-state checks through the fs/* event gate. |
|
||||
| `ctx.compaction` | `seam` | [`compaction`](../packages/compaction/compaction) | [`compaction-basic`](../packages/compaction/compaction-basic) | [`compaction-basic`](../packages/compaction/compaction-basic) | - | The basic backend consumes post-step pressure and request-error recovery events; there is no model-facing compact tool. |
|
||||
| `ctx.subagents` | `seam` | [`subagent`](../packages/subagent/subagent) | [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process), [`subagent-fork-in-process`](../packages/subagent/subagent-fork-in-process), [`subagent-acp`](../packages/subagent/subagent-acp), [`subagent-codex`](../packages/subagent/subagent-codex), [`subagent-claude-code`](../packages/subagent/subagent-claude-code), [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-subagent-control`](../packages/subagent/tool-subagent-control), [`tool-ralph`](../packages/experimental/tool-ralph) | - | Providers prepare local children or execute external tasks; one activation manager owns both lifecycles. The delegation tool selects a backend, control tools deliver local follow-ups, and workflows await activation results. |
|
||||
|
||||
@@ -168,7 +168,7 @@ flowchart LR
|
||||
pkg_tools["tools"]
|
||||
pkg_tool_terminal["tool-terminal"]
|
||||
pkg_tool_web["tool-web"]
|
||||
svc_tools["ctx.tools<br/>Tool registry and guarded execution pipeline"]
|
||||
svc_tools["ctx.tools<br/>Scoped tool registry and executor selection"]
|
||||
pkg_tool_ask_user["tool-ask-user"]
|
||||
pkg_tool_cordis["tool-cordis"]
|
||||
pkg_tool_skill["tool-skill"]
|
||||
@@ -237,6 +237,7 @@ flowchart LR
|
||||
svc_ptcRuntime["ctx.ptcRuntime<br/>PTC execution seam"]
|
||||
pkg_ptc_runtime_node["ptc-runtime-node"]
|
||||
pkg_experimental_ptc_runtime_python["experimental-ptc-runtime-python"]
|
||||
pkg_tool_executor_ptc["tool-executor-ptc"]
|
||||
pkg_workflow_ptc["workflow-ptc"]
|
||||
pkg_fs["fs"]
|
||||
svc_fs["ctx.fs<br/>Filesystem provider seam"]
|
||||
@@ -518,7 +519,7 @@ flowchart LR
|
||||
svc_pluginMarket --> pkg_plugin_market
|
||||
svc_pluginRegistryProbe --> pkg_client_ui_plugin_manager
|
||||
svc_profileContext --> pkg_plugin_manager
|
||||
svc_ptcRuntime --> pkg_tools
|
||||
svc_ptcRuntime --> pkg_tool_executor_ptc
|
||||
svc_ptcRuntime --> pkg_workflow_ptc
|
||||
svc_remoteAccess --> pkg_api_gateway
|
||||
svc_remoteAccess --> pkg_api_session_controller
|
||||
@@ -679,7 +680,7 @@ flowchart LR
|
||||
| `ctx.sessionReferenceResolver` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | 将当前表层中有界的对话快照投影为持久但不可信的消息上下文;Host 适配器负责提及语法。 |
|
||||
| `ctx.sessionTitle` | `seam` | [`session-title`](../packages/session/session-title) | [`session-title-first-prompt-llm`](../packages/session/session-title-first-prompt-llm), [`session-title-all-prompts-llm`](../packages/experimental/session-title-all-prompts-llm) | - | - | 负责确定性回退、最新标题折叠区,以及唯一的可选异步提供方注册。 |
|
||||
| `ctx.systemPrompt` | `core` | [`system-prompt`](../packages/core/system-prompt) | - | [`agent-loop`](../packages/core/agent-loop), [`tools`](../packages/core/tools), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-web`](../packages/web/tool-web) | - | 为每个步骤收集提示词各部分和面向模型的工具 schema。 |
|
||||
| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/interaction/tool-ask-user), [`tool-bash`](../packages/shell/tool-bash), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | 注册能力,负责 PTC mode 传输,并让调用依次经过策略前处理、单调守卫、环绕分派、策略后处理和最终结果观测。 |
|
||||
| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/interaction/tool-ask-user), [`tool-bash`](../packages/shell/tool-bash), [`tool-cordis`](../packages/extensions/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-terminal`](../packages/experimental/tool-terminal), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | 注册能力和作用域执行器。原生与 PTC 提供者负责工具描述及完整原始调用批次;它们可选用共享流水线处理工具策略和分发。 |
|
||||
| `ctx.userQuestions` | `seam` | [`user-questions`](../packages/interaction/user-questions) | - | [`tool-ask-user`](../packages/interaction/tool-ask-user) | - | UI 前端提供当前生效的人工回答提供方;tool-ask-user 在提供方无关的 ask() promise 上暂停工具调用。 |
|
||||
| `ctx.planMode` | `core` | [`plan-mode`](../packages/plan/plan-mode) | - | - | - | 折叠已记录的计划/模式状态,在轮次边界刷新用户选择,渲染由部署方拥有的指导信息,注册 /plan,并在状态转换期间保持计划退出 schema 稳定。 |
|
||||
| `ctx.agentPresets` | `core` | [`agent-preset-registry`](../packages/preset/agent-preset-registry) | - | - | - | 立即挂载 YAML 声明的 preset 版本,把 Agent 和冷读取绑定到作用域内的贡献,并保留已替换的版本,直到最后一个使用者释放它。 |
|
||||
@@ -701,7 +702,7 @@ flowchart LR
|
||||
| `ctx.sandboxPolicy` | `core` | [`sandbox-policy`](../packages/sandbox/sandbox-policy) | - | [`bash-sandbox`](../packages/shell/bash-sandbox), [`fs-sandbox`](../packages/fs/fs-sandbox), [`terminal-bash`](../packages/terminal/terminal-bash) | - | 统一保存部署默认模式和工作区根目录;只有沙箱执行器和提供方读取该服务(工具层使用它同时导出的纯 `sandbox/mode` 折叠区)。两类强制执行组件都读取该服务,因此 bash 与 fs 不会限制到不同的根目录。 |
|
||||
| `ctx.approval` | `seam` | [`user-approval`](../packages/interaction/user-approval) | - | [`tools`](../packages/core/tools), [`tool-bash`](../packages/shell/tool-bash), [`acp`](../packages/acp/acp) | - | 一次性权限决策通过 `approval/request` waterfall(瀑布式事件)分派;回答方是监听器(即 ACP 为自身 agent 提供的桥接),没有回答方时以 `unavailable` 关闭失败。 |
|
||||
| `ctx.permissionPresets` | `core` | [`permission-presets`](../packages/interaction/permission-presets) | - | - | - | 面向用户的预设表(`workspace-write`/`danger-full-access`),将沙箱模式与审批策略选项组合在一起;一次切换会写入一个 `permission/preset` 事件,并贯通到两个选项事件。 |
|
||||
| `ctx.ptcRuntime` | `seam` | [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime) | [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), [`experimental-ptc-runtime-python`](../packages/experimental/ptc-runtime-python) | [`tools`](../packages/core/tools), [`workflow-ptc`](../packages/workflow/workflow-ptc) | - | 使用 Host 提供的异步绑定运行程序;tools 负责 PTC 呈现,workflow-ptc 负责工作流编排。 |
|
||||
| `ctx.ptcRuntime` | `seam` | [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime) | [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), [`experimental-ptc-runtime-python`](../packages/experimental/ptc-runtime-python) | [`tool-executor-ptc`](../packages/core/tool-executor-ptc), [`workflow-ptc`](../packages/workflow/workflow-ptc) | - | 使用 Host 提供的异步绑定运行程序;tool-executor-ptc 负责 PTC 呈现,workflow-ptc 负责工作流编排。 |
|
||||
| `ctx.fs` | `seam` | [`fs`](../packages/fs/fs) | [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`fs-ssh`](../packages/ssh/fs-ssh) | [`tool-fs`](../packages/fs/tool-fs) | [`fs-observation-policy`](../packages/fs/fs-observation-policy) | tool-fs 通过 ctx.fs 执行读取/写入/编辑;fs-sandbox 按共享沙箱模式限制变更;fs-observation-policy 通过 fs/* 事件门禁贡献基于观测状态的检查。 |
|
||||
| `ctx.compaction` | `seam` | [`compaction`](../packages/compaction/compaction) | [`compaction-basic`](../packages/compaction/compaction-basic) | [`compaction-basic`](../packages/compaction/compaction-basic) | - | 基础后端消费步骤后的压力事件和请求错误恢复事件;不存在面向模型的压缩工具。 |
|
||||
| `ctx.subagents` | `seam` | [`subagent`](../packages/subagent/subagent) | [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process), [`subagent-fork-in-process`](../packages/subagent/subagent-fork-in-process), [`subagent-acp`](../packages/subagent/subagent-acp), [`subagent-codex`](../packages/subagent/subagent-codex), [`subagent-claude-code`](../packages/subagent/subagent-claude-code), [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-subagent-control`](../packages/subagent/tool-subagent-control), [`tool-ralph`](../packages/experimental/tool-ralph) | - | 提供方准备本地子级或执行外部任务;一个 activation 管理器持有两类生命周期。委派工具选择后端,控制工具投递本地后续消息,工作流等待 activation 结果。 |
|
||||
|
||||
+27
-42
@@ -162,11 +162,13 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-agent-tool-presentation`
|
||||
|
||||
- `inject`: `tools`
|
||||
- `refs`: [`ToolPresentationMode`](subsystems/tools.md)
|
||||
- `source`: [`packages/core/agent-tool-presentation/src/index.ts:38`](../packages/core/agent-tool-presentation/src/index.ts)
|
||||
- `source`: [`packages/core/agent-tool-presentation/src/index.ts:25`](../packages/core/agent-tool-presentation/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Plugin config. */
|
||||
/**
|
||||
* Plugin config.
|
||||
* @deprecated Select the native or PTC executor plugin directly instead of configuring a mode.
|
||||
*/
|
||||
export interface Config {
|
||||
/**
|
||||
* The form this agent's model sees. `native` sends every visible schema,
|
||||
@@ -175,7 +177,7 @@ export interface Config {
|
||||
* without this row already gets, so an omitted value would mean the row was
|
||||
* composed for nothing.
|
||||
*/
|
||||
mode: ToolPresentationMode
|
||||
mode: 'native' | 'ptc'
|
||||
}
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-agent-tool-presentation -->
|
||||
@@ -3270,7 +3272,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-spill-policy`
|
||||
|
||||
- `inject`: `tools`
|
||||
- `source`: [`packages/spill/spill-policy/src/index.ts:25`](../packages/spill/spill-policy/src/index.ts)
|
||||
- `source`: [`packages/spill/spill-policy/src/index.ts:26`](../packages/spill/spill-policy/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Optional result-retention budget. */
|
||||
@@ -3849,6 +3851,23 @@ export interface Config {
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-bash-persistent -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tool-executor-ptc -->
|
||||
<a id="deepseek-aidsh-tool-executor-ptc"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tool-executor-ptc`
|
||||
|
||||
- `inject`: `tools` · `systemPrompt` · `ptcRuntime`
|
||||
- `source`: [`packages/core/tool-executor-ptc/src/config.ts:5`](../packages/core/tool-executor-ptc/src/config.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Program execution limits. */
|
||||
export interface Config {
|
||||
/** Maximum overlapping concurrency-safe program subcalls. */
|
||||
maxParallelSubCalls: number
|
||||
}
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-executor-ptc -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tool-fs -->
|
||||
<a id="deepseek-aidsh-tool-fs"></a>
|
||||
|
||||
@@ -4320,43 +4339,6 @@ export interface Config {
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-workspace-dependencies -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tools -->
|
||||
<a id="deepseek-aidsh-tools"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tools`
|
||||
|
||||
- `inject`: `systemPrompt`
|
||||
- `source`: [`packages/core/tools/src/index.ts:675`](../packages/core/tools/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Plugin config: how the registered tools are presented to the model. */
|
||||
export interface Config {
|
||||
/**
|
||||
* Model presentation. `native` (default) sends every visible schema; `ptc`
|
||||
* sends only `run_code` plus a generated SDK prompt and collapses the
|
||||
* executor to the same surface (a model-direct call may only name
|
||||
* `run_code`; `run_code` SDK sub-dispatches keep every visible tool).
|
||||
* PTC mode requires a `ctx.ptcRuntime` whose `language`
|
||||
* has a registered SDK renderer (TypeScript or Python) and fails prompt
|
||||
* assembly when it is absent or has no renderer. Under `ptc`, native names
|
||||
* in `toolOrder` are invalid.
|
||||
*/
|
||||
mode?: ToolPresentationMode
|
||||
/**
|
||||
* Concurrency cap for a `run_code` program's overlapping sub-calls
|
||||
* (default 10, the loop scheduler's own default). Sub-calls follow the
|
||||
* native scheduling contract — only calls whose tools classify
|
||||
* concurrency-safe overlap; exclusive calls form barriers — so `1`
|
||||
* restores strictly serial dispatch. Must be a positive integer.
|
||||
*/
|
||||
maxParallelSubCalls?: number
|
||||
}
|
||||
|
||||
/** How the registry presents its tools to the model (see {@link Config.mode}). */
|
||||
export type ToolPresentationMode = 'native' | 'ptc'
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tools -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-typert-loader -->
|
||||
<a id="deepseek-aidsh-typert-loader"></a>
|
||||
|
||||
@@ -4801,9 +4783,11 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
|
||||
| `@deepseek-ai/dsh-terminal` | — | [`packages/terminal/terminal/src/index.ts`](../packages/terminal/terminal/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-call-timeout-policy` | `tools` | [`packages/guard/timeout-policy/src/index.ts`](../packages/guard/timeout-policy/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-cordis` | `tools` · `cordisInspect` | [`packages/extensions/tool-cordis/src/index.ts`](../packages/extensions/tool-cordis/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-executor-native` | `tools` | [`packages/core/tool-executor-native/src/index.ts`](../packages/core/tool-executor-native/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-schedule` | `tools` | [`packages/schedule/tool-schedule/src/index.ts`](../packages/schedule/tool-schedule/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-subagent-control` | `tools` · `subagents` · `agents` | [`packages/subagent/tool-subagent-control/src/index.ts`](../packages/subagent/tool-subagent-control/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-working-directory` | `tools` · `workingDirectory` | [`packages/session/tool-working-directory/src/index.ts`](../packages/session/tool-working-directory/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tools` | `systemPrompt` | [`packages/core/tools/src/index.ts`](../packages/core/tools/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-user-questions` | — | [`packages/interaction/user-questions/src/index.ts`](../packages/interaction/user-questions/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-webhook` | `agents` · `agentDefaultModel` · `agentPresets` · `permissionPresets` · `sessionTitle` · `workspaceRegistry` | [`packages/experimental/webhook/src/index.ts`](../packages/experimental/webhook/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-workspace` | `storageDomain` · `sessionPersistence` | [`packages/workspace/workspace/src/index.ts`](../packages/workspace/workspace/src/index.ts) |
|
||||
@@ -4900,6 +4884,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them.
|
||||
| `@deepseek-ai/dsh-session-title-llm` | — | [`packages/session/session-title-llm/src/index.ts`](../packages/session/session-title-llm/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-ssh-helper-runtime` | — | [`packages/ssh/ssh-helper-runtime/src/index.ts`](../packages/ssh/ssh-helper-runtime/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-timeout` | — | [`packages/util/timeout/src/index.ts`](../packages/util/timeout/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-testkit` | — | [`packages/test-support/tool-testkit/src/index.ts`](../packages/test-support/tool-testkit/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-generator` | — | [`packages/typert/generator/src/index.ts`](../packages/typert/generator/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-protocol` | — | [`packages/typert/protocol/src/index.ts`](../packages/typert/protocol/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-registry` | — | [`packages/typert/registry/src/index.ts`](../packages/typert/registry/src/index.ts) |
|
||||
|
||||
+27
-42
@@ -164,11 +164,13 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-agent-tool-presentation`
|
||||
|
||||
- `inject`: `tools`
|
||||
- `refs`: [`ToolPresentationMode`](subsystems/tools.zh.md)
|
||||
- `source`: [`packages/core/agent-tool-presentation/src/index.ts:38`](../packages/core/agent-tool-presentation/src/index.ts)
|
||||
- `source`: [`packages/core/agent-tool-presentation/src/index.ts:25`](../packages/core/agent-tool-presentation/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Plugin config. */
|
||||
/**
|
||||
* Plugin config.
|
||||
* @deprecated Select the native or PTC executor plugin directly instead of configuring a mode.
|
||||
*/
|
||||
export interface Config {
|
||||
/**
|
||||
* The form this agent's model sees. `native` sends every visible schema,
|
||||
@@ -177,7 +179,7 @@ export interface Config {
|
||||
* without this row already gets, so an omitted value would mean the row was
|
||||
* composed for nothing.
|
||||
*/
|
||||
mode: ToolPresentationMode
|
||||
mode: 'native' | 'ptc'
|
||||
}
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-agent-tool-presentation -->
|
||||
@@ -3272,7 +3274,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-spill-policy`
|
||||
|
||||
- `inject`: `tools`
|
||||
- `source`: [`packages/spill/spill-policy/src/index.ts:25`](../packages/spill/spill-policy/src/index.ts)
|
||||
- `source`: [`packages/spill/spill-policy/src/index.ts:26`](../packages/spill/spill-policy/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Optional result-retention budget. */
|
||||
@@ -3851,6 +3853,23 @@ export interface Config {
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-bash-persistent -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tool-executor-ptc -->
|
||||
<a id="deepseek-aidsh-tool-executor-ptc"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tool-executor-ptc`
|
||||
|
||||
- `inject`: `tools` · `systemPrompt` · `ptcRuntime`
|
||||
- `source`: [`packages/core/tool-executor-ptc/src/config.ts:5`](../packages/core/tool-executor-ptc/src/config.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Program execution limits. */
|
||||
export interface Config {
|
||||
/** Maximum overlapping concurrency-safe program subcalls. */
|
||||
maxParallelSubCalls: number
|
||||
}
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-executor-ptc -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tool-fs -->
|
||||
<a id="deepseek-aidsh-tool-fs"></a>
|
||||
|
||||
@@ -4322,43 +4341,6 @@ export interface Config {
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tool-workspace-dependencies -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-tools -->
|
||||
<a id="deepseek-aidsh-tools"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tools`
|
||||
|
||||
- `inject`: `systemPrompt`
|
||||
- `source`: [`packages/core/tools/src/index.ts:675`](../packages/core/tools/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Plugin config: how the registered tools are presented to the model. */
|
||||
export interface Config {
|
||||
/**
|
||||
* Model presentation. `native` (default) sends every visible schema; `ptc`
|
||||
* sends only `run_code` plus a generated SDK prompt and collapses the
|
||||
* executor to the same surface (a model-direct call may only name
|
||||
* `run_code`; `run_code` SDK sub-dispatches keep every visible tool).
|
||||
* PTC mode requires a `ctx.ptcRuntime` whose `language`
|
||||
* has a registered SDK renderer (TypeScript or Python) and fails prompt
|
||||
* assembly when it is absent or has no renderer. Under `ptc`, native names
|
||||
* in `toolOrder` are invalid.
|
||||
*/
|
||||
mode?: ToolPresentationMode
|
||||
/**
|
||||
* Concurrency cap for a `run_code` program's overlapping sub-calls
|
||||
* (default 10, the loop scheduler's own default). Sub-calls follow the
|
||||
* native scheduling contract — only calls whose tools classify
|
||||
* concurrency-safe overlap; exclusive calls form barriers — so `1`
|
||||
* restores strictly serial dispatch. Must be a positive integer.
|
||||
*/
|
||||
maxParallelSubCalls?: number
|
||||
}
|
||||
|
||||
/** How the registry presents its tools to the model (see {@link Config.mode}). */
|
||||
export type ToolPresentationMode = 'native' | 'ptc'
|
||||
```
|
||||
<!-- END GENERATED config-catalog:@deepseek-ai/dsh-tools -->
|
||||
|
||||
<!-- BEGIN GENERATED config-catalog:@deepseek-ai/dsh-typert-loader -->
|
||||
<a id="deepseek-aidsh-typert-loader"></a>
|
||||
|
||||
@@ -4803,9 +4785,11 @@ export interface Config {
|
||||
| `@deepseek-ai/dsh-terminal` | — | [`packages/terminal/terminal/src/index.ts`](../packages/terminal/terminal/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-call-timeout-policy` | `tools` | [`packages/guard/timeout-policy/src/index.ts`](../packages/guard/timeout-policy/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-cordis` | `tools` · `cordisInspect` | [`packages/extensions/tool-cordis/src/index.ts`](../packages/extensions/tool-cordis/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-executor-native` | `tools` | [`packages/core/tool-executor-native/src/index.ts`](../packages/core/tool-executor-native/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-schedule` | `tools` | [`packages/schedule/tool-schedule/src/index.ts`](../packages/schedule/tool-schedule/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-subagent-control` | `tools` · `subagents` · `agents` | [`packages/subagent/tool-subagent-control/src/index.ts`](../packages/subagent/tool-subagent-control/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-working-directory` | `tools` · `workingDirectory` | [`packages/session/tool-working-directory/src/index.ts`](../packages/session/tool-working-directory/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tools` | `systemPrompt` | [`packages/core/tools/src/index.ts`](../packages/core/tools/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-user-questions` | — | [`packages/interaction/user-questions/src/index.ts`](../packages/interaction/user-questions/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-webhook` | `agents` · `agentDefaultModel` · `agentPresets` · `permissionPresets` · `sessionTitle` · `workspaceRegistry` | [`packages/experimental/webhook/src/index.ts`](../packages/experimental/webhook/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-workspace` | `storageDomain` · `sessionPersistence` | [`packages/workspace/workspace/src/index.ts`](../packages/workspace/workspace/src/index.ts) |
|
||||
@@ -4902,6 +4886,7 @@ export interface Config {
|
||||
| `@deepseek-ai/dsh-session-title-llm` | — | [`packages/session/session-title-llm/src/index.ts`](../packages/session/session-title-llm/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-ssh-helper-runtime` | — | [`packages/ssh/ssh-helper-runtime/src/index.ts`](../packages/ssh/ssh-helper-runtime/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-timeout` | — | [`packages/util/timeout/src/index.ts`](../packages/util/timeout/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-tool-testkit` | — | [`packages/test-support/tool-testkit/src/index.ts`](../packages/test-support/tool-testkit/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-generator` | — | [`packages/typert/generator/src/index.ts`](../packages/typert/generator/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-protocol` | — | [`packages/typert/protocol/src/index.ts`](../packages/typert/protocol/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-typert-registry` | — | [`packages/typert/registry/src/index.ts`](../packages/typert/registry/src/index.ts) |
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
en: 0894bd9f35430753
|
||||
zh: 2d28090e71134edd
|
||||
/cookbook-adding-a-workspace-package/5-add-optional-plugin-display-metadata:
|
||||
en: cb799f5d561dd917
|
||||
zh: 7739af36ef8ffb3f
|
||||
en: 1238eaea376391d1
|
||||
zh: c7e606f95d8980bf
|
||||
/cookbook-adding-a-workspace-package/6-verify:
|
||||
en: 80c7fb90b1175aae
|
||||
zh: 2ba37962dbc57299
|
||||
@@ -136,7 +136,7 @@ Merge these entries into `package.json`, retaining existing runtime exports and
|
||||
}
|
||||
```
|
||||
|
||||
Keep language files together in `locale/`, with `en.json` as the discovery entry. Fields are optional; present values must be non-empty strings. English `meta.title` and `meta.description` use sentence case: capitalize only the first word, proper nouns, and product names, as in `Git worktrees` ([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location)). Missing files or fields permit fallback, while malformed JSON or invalid fields produce a per-plugin diagnostic.
|
||||
Keep language files together in `locale/`, with `en.json` as the discovery entry. Fields are optional; present values must be non-empty strings. English `meta.title` and `meta.description` use sentence case: capitalize only the first word, proper nouns, and product names, as in `Git worktrees` ([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location)). At runtime, missing files or fields permit fallback, while malformed JSON or invalid fields produce a per-plugin diagnostic. First-party packages and plugin templates must provide `ja.json` covering every field present in `en.json` or optional `zh.json`, preserving placeholders; detail paths may point to the existing English document. Subpath resources under `locale/<subpath>/` follow the same checks. English descriptions explain user-visible behavior and end with sentence punctuation. Run `pnpm run check:i18n` to verify JSON metadata and UI dictionary completeness; the JSON checks also run in `check:all`, CI static checks, and hygiene.
|
||||
|
||||
Fields fall back independently before view-specific name formatting, using the existing locale language chain first:
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ Append-only, prefix-stable, replacing, or independent behavior, including the ex
|
||||
}
|
||||
```
|
||||
|
||||
语言文件统一放在 `locale/`,并保留 `en.json` 作为发现入口。字段可选,填写时必须是非空字符串。英文 `meta.title` 和 `meta.description` 使用 sentence case:只大写首个单词、专有名词和产品名,例如 `Git worktrees`([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location))。文件或字段缺失时允许回退,JSON 损坏或字段无效时显示单插件诊断。
|
||||
语言文件统一放在 `locale/`,并保留 `en.json` 作为发现入口。字段可选,填写时必须是非空字符串。英文 `meta.title` 和 `meta.description` 使用 sentence case:只大写首个单词、专有名词和产品名,例如 `Git worktrees`([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location))。运行时文件或字段缺失时允许回退,JSON 损坏或字段无效时显示单插件诊断。仓库内的包和插件模板必须提供 `ja.json`,覆盖 `en.json` 或可选 `zh.json` 中的全部字段并保留占位符;详情路径可指向现有英文文档。`locale/<subpath>/` 下的子路径资源使用相同检查。英文描述面向产品用户说明可见行为,并以句末标点结束。运行 `pnpm run check:i18n` 检查 JSON 元数据和 UI 字典完整性;JSON 检查也接入 `check:all`、CI 静态检查和 hygiene。
|
||||
|
||||
各字段先独立回退,再按页面规则格式化技术名称;回退优先经过现有 locale 语言链:
|
||||
|
||||
|
||||
@@ -37,12 +37,13 @@ export function apply(ctx: Context) {
|
||||
// the model. ToolCallId brands the correlation id a provider would issue.
|
||||
void (async () => {
|
||||
const result = await ctx.tools.execute({
|
||||
callId: brandString<ToolCallId>('demo-1'),
|
||||
name: 'greet',
|
||||
arguments: { name: 'Cordis' },
|
||||
calls: [{
|
||||
type: 'tool-call', id: brandString<ToolCallId>('demo-1'),
|
||||
name: 'greet', arguments: JSON.stringify({ name: 'Cordis' }),
|
||||
}],
|
||||
signal: new AbortController().signal,
|
||||
})
|
||||
console.log('tool replied:', JSON.stringify(result.content))
|
||||
console.log('tool replied:', JSON.stringify(result.results[0]?.result.content))
|
||||
})()
|
||||
}
|
||||
```
|
||||
|
||||
@@ -37,12 +37,13 @@ export function apply(ctx: Context) {
|
||||
// the model. ToolCallId brands the correlation id a provider would issue.
|
||||
void (async () => {
|
||||
const result = await ctx.tools.execute({
|
||||
callId: brandString<ToolCallId>('demo-1'),
|
||||
name: 'greet',
|
||||
arguments: { name: 'Cordis' },
|
||||
calls: [{
|
||||
type: 'tool-call', id: brandString<ToolCallId>('demo-1'),
|
||||
name: 'greet', arguments: JSON.stringify({ name: 'Cordis' }),
|
||||
}],
|
||||
signal: new AbortController().signal,
|
||||
})
|
||||
console.log('tool replied:', JSON.stringify(result.content))
|
||||
console.log('tool replied:', JSON.stringify(result.results[0]?.result.content))
|
||||
})()
|
||||
}
|
||||
```
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
en: bf79c6acf35c90a5
|
||||
zh: 9f2ce6c7f6493b17
|
||||
/package-surface-rules/package-json-exports-uses-the-standard-key-set:
|
||||
en: 3604bf435be1c430
|
||||
zh: 169621c8a0c2dc4c
|
||||
en: 692ded0ff903609d
|
||||
zh: c871ab58ca92ad70
|
||||
/package-surface-rules/dependency-declarations-and-version-consistency-are-enforced-by-the-dependency-scan:
|
||||
en: e68bfcde70f845b4
|
||||
zh: 73e5c4fb067c4fa1
|
||||
|
||||
@@ -78,6 +78,7 @@ A `package.json` `exports` map uses only the standard key set, in which every ke
|
||||
|
||||
- Standard keys, each with one meaning repo-wide, across `packages/*/*/package.json` and `apps/*/package.json`: `.` (the package entry), `./package.json` (toolchain access, not a semantic export), `./src/*` (source passthrough for tests and tools, whose documented status is still open), `./client` (the browser entry, paired with the `dsh.client` declaration), `./types` (the type entry), `./typert` (the typert type runtime), `./remote` (the `@Remote` call surface), `./locale/*.json` (locale resources), `./cordis.patch.yml` (the bundle patch layer declared by `dsh.bundle`). Counts are not listed here because they rot on the next package; the recompute command below prints them.
|
||||
- Keys outside that set (`./brand` in 5 packages, `./worker` in 4, `./startup`, `./runner`, and `./protocol` in 2 each, plus many one-off keys) have no documented meaning; they are pending review, not a pattern to copy.
|
||||
- `dsh-tools` additionally exposes `./pipeline` for reusable invocation stages and batch scheduling. Its main and pipeline bundles share runtime chunks to preserve error-class identity; workspace constraints check the export targets and publication files.
|
||||
- Judged condition: does a change add an export key outside the standard set?
|
||||
- Exception: none by default; a new key changes the owning document and the check first, with the domain owner's confirmation.
|
||||
- Recompute the distribution:
|
||||
|
||||
@@ -78,6 +78,7 @@ import { isSurfaceEligibleType } from '../../core/session/src/surface.ts'
|
||||
|
||||
- 标准键,每个键在全仓只有一个含义,统计口径是 `packages/*/*/package.json` 与 `apps/*/package.json`:`.`(包主入口)、`./package.json`(工具链访问,不是语义导出)、`./src/*`(测试与工具的源码透传,文档状态仍待定)、`./client`(浏览器入口,与 `dsh.client` 声明配对)、`./types`(类型入口)、`./typert`(typert 类型运行时)、`./remote`(`@Remote` 调用面)、`./locale/*.json`(本地化资源)、`./cordis.patch.yml`(`dsh.bundle` 声明的 bundle 补丁层)。这里不列各键的包数,因为下一个包就会让它过期;下面的复算命令会打印当前数字。
|
||||
- 集合之外的键(`./brand` 5 个包、`./worker` 4 个、`./startup`、`./runner`、`./protocol` 各 2 个,另有大量一次性键)没有文档含义,属待核项,不是可照抄的先例。
|
||||
- `dsh-tools` 另行提供 `./pipeline`,用于复用调用阶段与批量调度。主入口与 pipeline bundle 共享运行时 chunk,以保持错误类的身份一致;工作区检查验证导出目标与发布文件。
|
||||
- 判定条件:改动是否新增了标准集合以外的 export 键?
|
||||
- 例外:无默认例外;新增键须先改正家文档与检查,并取得对应领域专家确认。
|
||||
- 复算分布:
|
||||
|
||||
@@ -65,7 +65,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:44`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`permission-presets`](../packages/interaction/permission-presets), [`schedule`](../packages/schedule/schedule), `server`, `session-controller`, [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:63`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-preset-registry`](../packages/preset/agent-preset-registry), `agent-team`, `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`loader-smoke`](../packages/test-support/loader-smoke), `product-analytics`, [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), `server`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-questions`](../packages/interaction/user-questions), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-preset-registry`](../packages/preset/agent-preset-registry), `agent-team`, `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`loader-smoke`](../packages/test-support/loader-smoke), `product-analytics`, [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), `server`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter), [`tool-executor-ptc`](../packages/core/tool-executor-ptc), [`user-questions`](../packages/interaction/user-questions), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:82`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:75`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`emit`) | `remotes` |
|
||||
| `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:296`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - |
|
||||
@@ -75,12 +75,12 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:158`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | `browser-use-runtime`, [`working-directory`](../packages/session/working-directory) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:209`](../packages/core/tools/src/index.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:165`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `claude-code-mods`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:177`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `claude-code-mods`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:154`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:191`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:199`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`subagent`](../packages/subagent/subagent), [`tool-present`](../packages/deliverables/tool-present) |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/events.ts:56`](../packages/core/tools/src/events.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/events.ts:29`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `claude-code-mods`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/events.ts:41`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `claude-code-mods`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/events.ts:18`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tool-executor-ptc/src/runtime-types.ts:46`](../packages/core/tool-executor-ptc/src/runtime-types.ts) | [`tool-executor-ptc`](../packages/core/tool-executor-ptc) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/events.ts:49`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`subagent`](../packages/subagent/subagent), [`tool-present`](../packages/deliverables/tool-present) |
|
||||
| `user-questions/request` | `waterfall` | [`packages/interaction/user-questions/src/types.ts:174`](../packages/interaction/user-questions/src/types.ts) | [`user-questions`](../packages/interaction/user-questions) (`waterfall`) | `remotes`, `server` |
|
||||
| `webserver/index-inject` | `emit` | [`packages/host/webserver/src/index.ts:39`](../packages/host/webserver/src/index.ts) | `webserver` (`emit`) | `connection`, `inspector`, `modules`, `remote-access`, `shortcuts`, `ui-sidebar-documentpreview`, `ui-theme` |
|
||||
| `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:79`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow) |
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
| `session-telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:44`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:54`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`permission-presets`](../packages/interaction/permission-presets), [`schedule`](../packages/schedule/schedule), `server`, `session-controller`, [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:63`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `agent-team`, `file-upload`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-preset-registry`](../packages/preset/agent-preset-registry), `agent-team`, `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`loader-smoke`](../packages/test-support/loader-smoke), `product-analytics`, [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), `server`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-questions`](../packages/interaction/user-questions), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-instructions`](../packages/context/agent-instructions), [`agent-loop`](../packages/core/agent-loop), [`agent-preset-registry`](../packages/preset/agent-preset-registry), `agent-team`, `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`file-reference-local`](../packages/context/file-reference-local), `file-upload`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), [`loader-smoke`](../packages/test-support/loader-smoke), `product-analytics`, [`ptc-runtime-node`](../packages/ptc-runtime/ptc-runtime-node), `server`, `session-controller`, [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter), [`tool-executor-ptc`](../packages/core/tool-executor-ptc), [`user-questions`](../packages/interaction/user-questions), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:82`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-telemetry`](../packages/session/session-telemetry) |
|
||||
| `settings/document-updated` | `emit` | [`packages/settings/settings/src/types.ts:75`](../packages/settings/settings/src/types.ts) | [`settings`](../packages/settings/settings) (`emit`) | `remotes` |
|
||||
| `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:296`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - |
|
||||
@@ -77,12 +77,12 @@
|
||||
| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:158`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | `browser-use-runtime`, [`working-directory`](../packages/session/working-directory) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:209`](../packages/core/tools/src/index.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:165`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `claude-code-mods`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:177`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `claude-code-mods`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:154`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:191`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:199`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`subagent`](../packages/subagent/subagent), [`tool-present`](../packages/deliverables/tool-present) |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/events.ts:56`](../packages/core/tools/src/events.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`), [`tools`](../packages/core/tools) (`emit`) | `browser-use-runtime`, [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/events.ts:29`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `browser-use-runtime`, `browser-use-stagehand-native`, `claude-code-mods`, `computer-use-cua-driver-native`, [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `timeout-policy` |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/events.ts:41`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `claude-code-mods`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`spill-policy`](../packages/spill/spill-policy), [`tool-fs-search`](../packages/fs/tool-fs-search) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/events.ts:18`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`waterfall`) | `auto-review`, [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`tool-jobs`](../packages/jobs/tool-jobs), [`workspace-changes`](../packages/deliverables/workspace-changes) |
|
||||
| `tools/ptc-dispatch-log` | `waterfall` | [`packages/core/tool-executor-ptc/src/runtime-types.ts:46`](../packages/core/tool-executor-ptc/src/runtime-types.ts) | [`tool-executor-ptc`](../packages/core/tool-executor-ptc) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/events.ts:49`](../packages/core/tools/src/events.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`subagent`](../packages/subagent/subagent), [`tool-present`](../packages/deliverables/tool-present) |
|
||||
| `user-questions/request` | `waterfall` | [`packages/interaction/user-questions/src/types.ts:174`](../packages/interaction/user-questions/src/types.ts) | [`user-questions`](../packages/interaction/user-questions) (`waterfall`) | `remotes`, `server` |
|
||||
| `webserver/index-inject` | `emit` | [`packages/host/webserver/src/index.ts:39`](../packages/host/webserver/src/index.ts) | `webserver` (`emit`) | `connection`, `inspector`, `modules`, `remote-access`, `shortcuts`, `ui-sidebar-documentpreview`, `ui-theme` |
|
||||
| `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:79`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow) |
|
||||
|
||||
+20
-5
@@ -47,6 +47,8 @@ flowchart TD
|
||||
pkg_scope["scope"]
|
||||
pkg_session["session"]
|
||||
pkg_system_prompt["system-prompt"]
|
||||
pkg_tool_executor_native["tool-executor-native"]
|
||||
pkg_tool_executor_ptc["tool-executor-ptc"]
|
||||
pkg_tools["tools"]
|
||||
end
|
||||
subgraph group_goal["packages/goal"]
|
||||
@@ -445,6 +447,7 @@ flowchart TD
|
||||
pkg_loader_smoke["loader-smoke"]
|
||||
pkg_remote_mock["remote-mock"]
|
||||
pkg_session_snapshot["session-snapshot"]
|
||||
pkg_tool_testkit["tool-testkit"]
|
||||
end
|
||||
subgraph group_typert["packages/typert"]
|
||||
pkg_typert_generator["typert-generator"]
|
||||
@@ -726,14 +729,10 @@ flowchart TD
|
||||
pkg_llm_deepseek_account --> pkg_timeout
|
||||
pkg_tools --> pkg_agent
|
||||
pkg_tools --> pkg_llm
|
||||
pkg_tools --> pkg_ptc_runtime
|
||||
pkg_tools --> pkg_sandbox
|
||||
pkg_tools --> pkg_sandbox_policy
|
||||
pkg_tools --> pkg_scope
|
||||
pkg_tools --> pkg_session
|
||||
pkg_tools --> pkg_system_prompt
|
||||
pkg_tools --> pkg_user_approval
|
||||
pkg_tools --> pkg_working_directory
|
||||
pkg_command_goal --> pkg_commands
|
||||
pkg_command_goal --> pkg_goal
|
||||
pkg_command_goal --> pkg_llm
|
||||
@@ -829,6 +828,17 @@ flowchart TD
|
||||
pkg_agent_loop --> pkg_system_prompt
|
||||
pkg_agent_loop --> pkg_tools
|
||||
pkg_agent_tool_presentation --> pkg_tools
|
||||
pkg_tool_executor_native --> pkg_tools
|
||||
pkg_tool_executor_ptc --> pkg_agent
|
||||
pkg_tool_executor_ptc --> pkg_llm
|
||||
pkg_tool_executor_ptc --> pkg_ptc_runtime
|
||||
pkg_tool_executor_ptc --> pkg_sandbox
|
||||
pkg_tool_executor_ptc --> pkg_sandbox_policy
|
||||
pkg_tool_executor_ptc --> pkg_scope
|
||||
pkg_tool_executor_ptc --> pkg_session
|
||||
pkg_tool_executor_ptc --> pkg_tools
|
||||
pkg_tool_executor_ptc --> pkg_user_approval
|
||||
pkg_tool_executor_ptc --> pkg_working_directory
|
||||
pkg_tool_goal --> pkg_agent
|
||||
pkg_tool_goal --> pkg_goal
|
||||
pkg_tool_goal --> pkg_llm
|
||||
@@ -1040,6 +1050,8 @@ flowchart TD
|
||||
pkg_llm_replay --> pkg_deepseek_llm_api_extensions
|
||||
pkg_llm_replay --> pkg_llm
|
||||
pkg_llm_replay --> pkg_session
|
||||
pkg_tool_testkit --> pkg_llm
|
||||
pkg_tool_testkit --> pkg_tools
|
||||
pkg_tool_workflow --> pkg_agent
|
||||
pkg_tool_workflow --> pkg_jobs
|
||||
pkg_tool_workflow --> pkg_llm
|
||||
@@ -1672,7 +1684,7 @@ flowchart TD
|
||||
| [`loader-smoke`](../packages/test-support/loader-smoke) | `test-support` | [`agent`](../packages/core/agent), [`http-proxy`](../packages/util/http-proxy), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`workflow`](../packages/workflow/workflow) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`llm-deepseek-account`](../packages/llm/llm-deepseek-account) | `llm` | [`deepseek-account`](../packages/credentials/deepseek-account), [`launch-environment`](../packages/util/launch-environment), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`timeout`](../packages/util/timeout) |
|
||||
| [`tools`](../packages/core/tools) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tools`](../packages/core/tools) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| [`command-goal`](../packages/goal/command-goal) | `goal` | [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm) |
|
||||
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
|
||||
| [`web-deepseek-api`](../packages/web/web-deepseek-api) | `web` | [`agent`](../packages/core/agent), [`credentials`](../packages/credentials/credentials), [`deepseek-account`](../packages/credentials/deepseek-account), [`launch-environment`](../packages/util/launch-environment), [`session`](../packages/core/session), [`web`](../packages/web/web) |
|
||||
@@ -1693,6 +1705,8 @@ flowchart TD
|
||||
| [`terminal-bash`](../packages/terminal/terminal-bash) | `terminal` | [`agent`](../packages/core/agent), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess), [`terminal`](../packages/terminal/terminal), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`agent-tool-presentation`](../packages/core/agent-tool-presentation) | `core` | [`tools`](../packages/core/tools) |
|
||||
| [`tool-executor-native`](../packages/core/tool-executor-native) | `core` | [`tools`](../packages/core/tools) |
|
||||
| [`tool-executor-ptc`](../packages/core/tool-executor-ptc) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tool-fs-search`](../packages/fs/tool-fs-search) | `fs` | [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
@@ -1734,6 +1748,7 @@ flowchart TD
|
||||
| [`tool-pwsh-persistent`](../packages/shell/tool-pwsh-persistent) | `shell` | [`agent`](../packages/core/agent), [`output-retention`](../packages/util/output-retention), [`terminal`](../packages/terminal/terminal), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`ssh`](../packages/ssh/ssh) | `ssh` | [`brand`](../packages/util/brand), [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-local`](../packages/sandbox/sandbox-local), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session-projection`](../packages/session/session-projection), [`subprocess`](../packages/subprocess/subprocess), [`subprocess-local`](../packages/subprocess/subprocess-local), [`util-values`](../packages/util/values) |
|
||||
| [`llm-replay`](../packages/test-support/llm-replay) | `test-support` | [`compaction`](../packages/compaction/compaction), [`deepseek-llm-api-extensions`](../packages/llm/deepseek-llm-api-extensions), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`tool-testkit`](../packages/test-support/tool-testkit) | `test-support` | [`llm`](../packages/llm/llm), [`tools`](../packages/core/tools) |
|
||||
| [`tool-workflow`](../packages/workflow/tool-workflow) | `workflow` | [`agent`](../packages/core/agent), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`plugin-package-inventory-deepseek`](../packages/llm/plugin-package-inventory-deepseek) | `llm` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`deepseek-llm-api-extensions`](../packages/llm/deepseek-llm-api-extensions), [`session`](../packages/core/session) |
|
||||
| [`token-meter`](../packages/llm/token-meter) | `llm` | [`compaction`](../packages/compaction/compaction), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection) |
|
||||
|
||||
+20
-5
@@ -49,6 +49,8 @@ flowchart TD
|
||||
pkg_scope["scope"]
|
||||
pkg_session["session"]
|
||||
pkg_system_prompt["system-prompt"]
|
||||
pkg_tool_executor_native["tool-executor-native"]
|
||||
pkg_tool_executor_ptc["tool-executor-ptc"]
|
||||
pkg_tools["tools"]
|
||||
end
|
||||
subgraph group_goal["packages/goal"]
|
||||
@@ -447,6 +449,7 @@ flowchart TD
|
||||
pkg_loader_smoke["loader-smoke"]
|
||||
pkg_remote_mock["remote-mock"]
|
||||
pkg_session_snapshot["session-snapshot"]
|
||||
pkg_tool_testkit["tool-testkit"]
|
||||
end
|
||||
subgraph group_typert["packages/typert"]
|
||||
pkg_typert_generator["typert-generator"]
|
||||
@@ -728,14 +731,10 @@ flowchart TD
|
||||
pkg_llm_deepseek_account --> pkg_timeout
|
||||
pkg_tools --> pkg_agent
|
||||
pkg_tools --> pkg_llm
|
||||
pkg_tools --> pkg_ptc_runtime
|
||||
pkg_tools --> pkg_sandbox
|
||||
pkg_tools --> pkg_sandbox_policy
|
||||
pkg_tools --> pkg_scope
|
||||
pkg_tools --> pkg_session
|
||||
pkg_tools --> pkg_system_prompt
|
||||
pkg_tools --> pkg_user_approval
|
||||
pkg_tools --> pkg_working_directory
|
||||
pkg_command_goal --> pkg_commands
|
||||
pkg_command_goal --> pkg_goal
|
||||
pkg_command_goal --> pkg_llm
|
||||
@@ -831,6 +830,17 @@ flowchart TD
|
||||
pkg_agent_loop --> pkg_system_prompt
|
||||
pkg_agent_loop --> pkg_tools
|
||||
pkg_agent_tool_presentation --> pkg_tools
|
||||
pkg_tool_executor_native --> pkg_tools
|
||||
pkg_tool_executor_ptc --> pkg_agent
|
||||
pkg_tool_executor_ptc --> pkg_llm
|
||||
pkg_tool_executor_ptc --> pkg_ptc_runtime
|
||||
pkg_tool_executor_ptc --> pkg_sandbox
|
||||
pkg_tool_executor_ptc --> pkg_sandbox_policy
|
||||
pkg_tool_executor_ptc --> pkg_scope
|
||||
pkg_tool_executor_ptc --> pkg_session
|
||||
pkg_tool_executor_ptc --> pkg_tools
|
||||
pkg_tool_executor_ptc --> pkg_user_approval
|
||||
pkg_tool_executor_ptc --> pkg_working_directory
|
||||
pkg_tool_goal --> pkg_agent
|
||||
pkg_tool_goal --> pkg_goal
|
||||
pkg_tool_goal --> pkg_llm
|
||||
@@ -1042,6 +1052,8 @@ flowchart TD
|
||||
pkg_llm_replay --> pkg_deepseek_llm_api_extensions
|
||||
pkg_llm_replay --> pkg_llm
|
||||
pkg_llm_replay --> pkg_session
|
||||
pkg_tool_testkit --> pkg_llm
|
||||
pkg_tool_testkit --> pkg_tools
|
||||
pkg_tool_workflow --> pkg_agent
|
||||
pkg_tool_workflow --> pkg_jobs
|
||||
pkg_tool_workflow --> pkg_llm
|
||||
@@ -1674,7 +1686,7 @@ flowchart TD
|
||||
| [`loader-smoke`](../packages/test-support/loader-smoke) | `test-support` | [`agent`](../packages/core/agent), [`http-proxy`](../packages/util/http-proxy), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`workflow`](../packages/workflow/workflow) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`llm-deepseek-account`](../packages/llm/llm-deepseek-account) | `llm` | [`deepseek-account`](../packages/credentials/deepseek-account), [`launch-environment`](../packages/util/launch-environment), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`timeout`](../packages/util/timeout) |
|
||||
| [`tools`](../packages/core/tools) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tools`](../packages/core/tools) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`user-approval`](../packages/interaction/user-approval) |
|
||||
| [`command-goal`](../packages/goal/command-goal) | `goal` | [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm) |
|
||||
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
|
||||
| [`web-deepseek-api`](../packages/web/web-deepseek-api) | `web` | [`agent`](../packages/core/agent), [`credentials`](../packages/credentials/credentials), [`deepseek-account`](../packages/credentials/deepseek-account), [`launch-environment`](../packages/util/launch-environment), [`session`](../packages/core/session), [`web`](../packages/web/web) |
|
||||
@@ -1695,6 +1707,8 @@ flowchart TD
|
||||
| [`terminal-bash`](../packages/terminal/terminal-bash) | `terminal` | [`agent`](../packages/core/agent), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess), [`terminal`](../packages/terminal/terminal), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`agent-tool-presentation`](../packages/core/agent-tool-presentation) | `core` | [`tools`](../packages/core/tools) |
|
||||
| [`tool-executor-native`](../packages/core/tool-executor-native) | `core` | [`tools`](../packages/core/tools) |
|
||||
| [`tool-executor-ptc`](../packages/core/tool-executor-ptc) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`ptc-runtime`](../packages/ptc-runtime/ptc-runtime), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`tool-fs-search`](../packages/fs/tool-fs-search) | `fs` | [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
@@ -1736,6 +1750,7 @@ flowchart TD
|
||||
| [`tool-pwsh-persistent`](../packages/shell/tool-pwsh-persistent) | `shell` | [`agent`](../packages/core/agent), [`output-retention`](../packages/util/output-retention), [`terminal`](../packages/terminal/terminal), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`ssh`](../packages/ssh/ssh) | `ssh` | [`brand`](../packages/util/brand), [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-local`](../packages/sandbox/sandbox-local), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session-projection`](../packages/session/session-projection), [`subprocess`](../packages/subprocess/subprocess), [`subprocess-local`](../packages/subprocess/subprocess-local), [`util-values`](../packages/util/values) |
|
||||
| [`llm-replay`](../packages/test-support/llm-replay) | `test-support` | [`compaction`](../packages/compaction/compaction), [`deepseek-llm-api-extensions`](../packages/llm/deepseek-llm-api-extensions), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`tool-testkit`](../packages/test-support/tool-testkit) | `test-support` | [`llm`](../packages/llm/llm), [`tools`](../packages/core/tools) |
|
||||
| [`tool-workflow`](../packages/workflow/tool-workflow) | `workflow` | [`agent`](../packages/core/agent), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`plugin-package-inventory-deepseek`](../packages/llm/plugin-package-inventory-deepseek) | `llm` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`deepseek-llm-api-extensions`](../packages/llm/deepseek-llm-api-extensions), [`session`](../packages/core/session) |
|
||||
| [`token-meter`](../packages/llm/token-meter) | `llm` | [`compaction`](../packages/compaction/compaction), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection) |
|
||||
|
||||
@@ -249,11 +249,11 @@
|
||||
en: 03f36237cbf9e267
|
||||
zh: 83fe2e69bbbfd3c1
|
||||
/session-persistence-event-catalog/events/tool/tool-ptc-dispatch-log-only:
|
||||
en: 3d5d72b99e702a8c
|
||||
zh: e8c3b82cd5361c4a
|
||||
en: a62b38c00afed655
|
||||
zh: 793bef93e856eafa
|
||||
/session-persistence-event-catalog/events/tool/tool-ptc-dispatch-start-log-only:
|
||||
en: de38cf70d81ad7c3
|
||||
zh: dd0a2a8be099271d
|
||||
en: da841b1ed3b22c87
|
||||
zh: 4c9a4d4bc5bd76b6
|
||||
/session-persistence-event-catalog/events/tool/tool-result-surface:
|
||||
en: 283e3cf1fdd57f05
|
||||
zh: 0bc3a15ae4f47aaf
|
||||
@@ -1164,14 +1164,14 @@
|
||||
en: bb11552744e477b8
|
||||
zh: afb881f3ebf97e68
|
||||
/session-persistence-event-catalog/resolved-persistence-types/principal:
|
||||
en: d1e45e03f161dc7c
|
||||
zh: 4f80af59ca4967c5
|
||||
en: 6d0d81e0e833403e
|
||||
zh: fa47cd75ee75f948
|
||||
/session-persistence-event-catalog/resolved-persistence-types/ptcdispatcheventdata:
|
||||
en: 81e66c5a07e17dd6
|
||||
zh: 0ecf3cfceba14d2b
|
||||
en: c0f7b22b41cb0608
|
||||
zh: de14a1b5cac17665
|
||||
/session-persistence-event-catalog/resolved-persistence-types/ptcdispatchstarteventdata:
|
||||
en: fbbf650635960ec8
|
||||
zh: 9457953f4cbe07c6
|
||||
en: aca35dac4f9d2add
|
||||
zh: 6a4bdb95e3c7b0ce
|
||||
/session-persistence-event-catalog/resolved-persistence-types/reasoningblock:
|
||||
en: 07e04c3e336f880f
|
||||
zh: 6f8986ede9994fa1
|
||||
@@ -1284,11 +1284,11 @@
|
||||
en: 036b2595215410bb
|
||||
zh: 41792808ebac1fa3
|
||||
/session-persistence-event-catalog/resolved-persistence-types/toolremovalblock:
|
||||
en: f43a635a14568780
|
||||
zh: 8d22226b045122eb
|
||||
en: fdac0df45529e14c
|
||||
zh: c5e38de83a0e0a42
|
||||
/session-persistence-event-catalog/resolved-persistence-types/toolrestriction:
|
||||
en: d7d3c0238d9b373e
|
||||
zh: f49d93ee54e7a780
|
||||
en: 9d64c653e33bf2b6
|
||||
zh: 7bb427b48756f30f
|
||||
/session-persistence-event-catalog/resolved-persistence-types/toolresultmessage:
|
||||
en: 2258683c3cfa4ce3
|
||||
zh: 5663aa76c911761b
|
||||
@@ -1443,8 +1443,8 @@
|
||||
en: a1f188c9058cf621
|
||||
zh: eb43c0f045fb9afb
|
||||
/session-persistence-event-catalog/resolved-persistence-types/code-name-reason:
|
||||
en: 404a76066a59f3c6
|
||||
zh: ec9d510bdbac9786
|
||||
en: 39c67256532a22f9
|
||||
zh: 59f823e98630c5e2
|
||||
/session-persistence-event-catalog/resolved-persistence-types/commandid-kind-sourceeventseq-text:
|
||||
en: 87b03e1c73d2a326
|
||||
zh: d7b9f06863cad891
|
||||
@@ -1674,8 +1674,8 @@
|
||||
en: c53129cf7214286c
|
||||
zh: 8c5183b6dabbf714
|
||||
/session-persistence-event-catalog/resolved-persistence-types/kind-ptc-mode:
|
||||
en: 8de77980e11a0562
|
||||
zh: 6de199e70a666a71
|
||||
en: b4fd9b219667fb26
|
||||
zh: bc56baa64fd7ffd8
|
||||
/session-persistence-event-catalog/resolved-persistence-types/kind-repeat-tool-reminder:
|
||||
en: e3a0ef98a197374e
|
||||
zh: 95e9363529a62cc3
|
||||
@@ -1830,8 +1830,8 @@
|
||||
en: 08be4349548406a9
|
||||
zh: 8e7cf9966198ef78
|
||||
/session-persistence-event-catalog/resolved-persistence-types/kind-tool-registry:
|
||||
en: 809a23c25ded8497
|
||||
zh: e9cd23e281f8d31f
|
||||
en: c59d020828d8211f
|
||||
zh: 154a30cb69e79489
|
||||
/session-persistence-event-catalog/resolved-persistence-types/kind-user:
|
||||
en: 43f0c6042d410afd
|
||||
zh: a0b68de4e5d220bd
|
||||
|
||||
+11
-11
@@ -1116,7 +1116,7 @@ Source: [`packages/core/session/src/types.ts:362`](../packages/core/session/src/
|
||||
'tool/ptc-dispatch': PtcDispatchEventData
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/types.ts:61`](../packages/core/tools/src/types.ts)
|
||||
Source: [`packages/core/tool-executor-ptc/src/types.ts:61`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
<a id="toolptc-dispatch-start--log-only"></a>
|
||||
|
||||
@@ -1139,7 +1139,7 @@ Source: [`packages/core/tools/src/types.ts:61`](../packages/core/tools/src/types
|
||||
'tool/ptc-dispatch-start': PtcDispatchStartEventData
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/types.ts:45`](../packages/core/tools/src/types.ts)
|
||||
Source: [`packages/core/tool-executor-ptc/src/types.ts:45`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
<a id="toolresult--surface"></a>
|
||||
|
||||
@@ -4442,7 +4442,7 @@ Sources: [`packages/typert/protocol/src/types.ts:457`](../packages/typert/protoc
|
||||
|
||||
<a id="persistence-type-sha256-cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrctypestsptcdispatcheventdata"></a>
|
||||
<a id="persistence-type-packagescoretool-executor-ptcsrctypestsptcdispatcheventdata"></a>
|
||||
|
||||
<a id="persistence-type-ptcdispatcheventdata"></a>
|
||||
|
||||
@@ -4450,7 +4450,7 @@ Sources: [`packages/typert/protocol/src/types.ts:457`](../packages/typert/protoc
|
||||
|
||||
SHA-256: `cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6`
|
||||
|
||||
Sources: [`packages/core/tools/src/types.ts:21`](../packages/core/tools/src/types.ts)
|
||||
Sources: [`packages/core/tool-executor-ptc/src/types.ts:21`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
@@ -4466,7 +4466,7 @@ Sources: [`packages/core/tools/src/types.ts:21`](../packages/core/tools/src/type
|
||||
|
||||
<a id="persistence-type-sha256-2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata"></a>
|
||||
<a id="persistence-type-packagescoretool-executor-ptcsrctypestsptcdispatchstarteventdata"></a>
|
||||
|
||||
<a id="persistence-type-ptcdispatchstarteventdata"></a>
|
||||
|
||||
@@ -4474,7 +4474,7 @@ Sources: [`packages/core/tools/src/types.ts:21`](../packages/core/tools/src/type
|
||||
|
||||
SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f`
|
||||
|
||||
Sources: [`packages/core/tools/src/types.ts:12`](../packages/core/tools/src/types.ts)
|
||||
Sources: [`packages/core/tool-executor-ptc/src/types.ts:12`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
@@ -5185,7 +5185,7 @@ Sources: [`packages/llm/llm/src/types.ts:127`](../packages/llm/llm/src/types.ts)
|
||||
|
||||
<a id="persistence-type-sha256-3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrcindextstoolrestriction"></a>
|
||||
<a id="persistence-type-packagescoretoolssrccontractststoolrestriction"></a>
|
||||
|
||||
<a id="persistence-type-toolrestriction"></a>
|
||||
|
||||
@@ -5193,7 +5193,7 @@ Sources: [`packages/llm/llm/src/types.ts:127`](../packages/llm/llm/src/types.ts)
|
||||
|
||||
SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f`
|
||||
|
||||
Sources: [`packages/core/tools/src/index.ts:701`](../packages/core/tools/src/index.ts)
|
||||
Sources: [`packages/core/tools/src/contracts.ts:326`](../packages/core/tools/src/contracts.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
@@ -5979,7 +5979,7 @@ SHA-256: `cbbe8377ee744964537dbafd83607219e58ba79a13f6db0d0645c7ad3d5e8a09`
|
||||
|
||||
SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735`
|
||||
|
||||
Sources: [`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:27`](../packages/core/tools/src/types.ts)
|
||||
Sources: [`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts) · [`packages/core/tool-executor-ptc/src/types.ts:27`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
@@ -6960,7 +6960,7 @@ Sources: [`packages/session/session-title/src/types.ts:30`](../packages/session/
|
||||
|
||||
SHA-256: `dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd`
|
||||
|
||||
Sources: [`packages/core/tools/src/ptc.ts:15`](../packages/core/tools/src/ptc.ts)
|
||||
Sources: [`packages/core/tool-executor-ptc/src/types.ts:68`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
@@ -7542,7 +7542,7 @@ SHA-256: `c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49`
|
||||
|
||||
SHA-256: `8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543`
|
||||
|
||||
Sources: [`packages/core/tools/src/index.ts:35`](../packages/core/tools/src/index.ts)
|
||||
Sources: [`packages/core/tools/src/index.ts:18`](../packages/core/tools/src/index.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
|
||||
@@ -1118,7 +1118,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
'tool/ptc-dispatch': PtcDispatchEventData
|
||||
```
|
||||
|
||||
来源:[`packages/core/tools/src/types.ts:61`](../packages/core/tools/src/types.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/types.ts:61`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
<a id="toolptc-dispatch-start--log-only"></a>
|
||||
|
||||
@@ -1141,7 +1141,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
'tool/ptc-dispatch-start': PtcDispatchStartEventData
|
||||
```
|
||||
|
||||
来源:[`packages/core/tools/src/types.ts:45`](../packages/core/tools/src/types.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/types.ts:45`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
<a id="toolresult--surface"></a>
|
||||
|
||||
@@ -4444,7 +4444,7 @@ SHA-256: `deebfc7c62177ea840f23c6362b8615bc78ffa93377dd5d243c04e541c413af5`
|
||||
|
||||
<a id="persistence-type-sha256-cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrctypestsptcdispatcheventdata"></a>
|
||||
<a id="persistence-type-packagescoretool-executor-ptcsrctypestsptcdispatcheventdata"></a>
|
||||
|
||||
<a id="persistence-type-ptcdispatcheventdata"></a>
|
||||
|
||||
@@ -4452,7 +4452,7 @@ SHA-256: `deebfc7c62177ea840f23c6362b8615bc78ffa93377dd5d243c04e541c413af5`
|
||||
|
||||
SHA-256: `cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6`
|
||||
|
||||
来源:[`packages/core/tools/src/types.ts:21`](../packages/core/tools/src/types.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/types.ts:21`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
@@ -4468,7 +4468,7 @@ SHA-256: `cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6`
|
||||
|
||||
<a id="persistence-type-sha256-2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrctypestsptcdispatchstarteventdata"></a>
|
||||
<a id="persistence-type-packagescoretool-executor-ptcsrctypestsptcdispatchstarteventdata"></a>
|
||||
|
||||
<a id="persistence-type-ptcdispatchstarteventdata"></a>
|
||||
|
||||
@@ -4476,7 +4476,7 @@ SHA-256: `cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6`
|
||||
|
||||
SHA-256: `2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f`
|
||||
|
||||
来源:[`packages/core/tools/src/types.ts:12`](../packages/core/tools/src/types.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/types.ts:12`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
@@ -5187,7 +5187,7 @@ SHA-256: `43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8`
|
||||
|
||||
<a id="persistence-type-sha256-3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f"></a>
|
||||
|
||||
<a id="persistence-type-packagescoretoolssrcindextstoolrestriction"></a>
|
||||
<a id="persistence-type-packagescoretoolssrccontractststoolrestriction"></a>
|
||||
|
||||
<a id="persistence-type-toolrestriction"></a>
|
||||
|
||||
@@ -5195,7 +5195,7 @@ SHA-256: `43e311235aa537df1bacdd92d144df8a952337a76e9ac892cdf670f1a797bad8`
|
||||
|
||||
SHA-256: `3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f`
|
||||
|
||||
来源:[`packages/core/tools/src/index.ts:701`](../packages/core/tools/src/index.ts)
|
||||
来源:[`packages/core/tools/src/contracts.ts:326`](../packages/core/tools/src/contracts.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
@@ -5981,7 +5981,7 @@ SHA-256: `cbbe8377ee744964537dbafd83607219e58ba79a13f6db0d0645c7ad3d5e8a09`
|
||||
|
||||
SHA-256: `a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735`
|
||||
|
||||
来源:[`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts) · [`packages/core/tools/src/types.ts:27`](../packages/core/tools/src/types.ts)
|
||||
来源:[`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts) · [`packages/core/tool-executor-ptc/src/types.ts:27`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
@@ -6962,7 +6962,7 @@ SHA-256: `b81e9de81a481b24e1e1f9adf038bfc59e57b4f35ce62f8f1e45284186f4f812`
|
||||
|
||||
SHA-256: `dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd`
|
||||
|
||||
来源:[`packages/core/tools/src/ptc.ts:15`](../packages/core/tools/src/ptc.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/types.ts:68`](../packages/core/tool-executor-ptc/src/types.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
@@ -7544,7 +7544,7 @@ SHA-256: `c5228b7a55498d84f529591744a0ab26e0b93ade18a70a26db1377a1ecfa6b49`
|
||||
|
||||
SHA-256: `8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543`
|
||||
|
||||
来源:[`packages/core/tools/src/index.ts:35`](../packages/core/tools/src/index.ts)
|
||||
来源:[`packages/core/tools/src/index.ts:18`](../packages/core/tools/src/index.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
|
||||
Generated
+6
-6
@@ -190,7 +190,7 @@
|
||||
{"digest":"2eafefdc6f79a4922d68a787a09eaf4dd2b2369c3777fba4c05e800b5678ac8e","names":["packages/experimental/agent-team/src/types.ts#TeamMessageSnapshot"],"sources":["packages/experimental/agent-team/src/types.ts:129"]},
|
||||
{"digest":"2f1e6a7ebace43d727ae138ddcd352eb3813960009e5805b8c5ac84300c97716","names":["packages/attachment/attachment/src/types.ts#ImageMediaType"],"sources":["packages/attachment/attachment/src/types.ts:8"]},
|
||||
{"digest":"2f3f201c8846e19c20bb75c02280e3d4eb3c57509e4715f0c0a4d1d4f91a7a06","names":[],"sources":[]},
|
||||
{"digest":"2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f","names":["packages/core/tools/src/types.ts#PtcDispatchStartEventData"],"sources":["packages/core/tools/src/types.ts:12"]},
|
||||
{"digest":"2fe5026daf14bd4ff2b7bfb7cf9791c302d9cbba06802178b6dfec00b892698f","names":["packages/core/tool-executor-ptc/src/types.ts#PtcDispatchStartEventData"],"sources":["packages/core/tool-executor-ptc/src/types.ts:12"]},
|
||||
{"digest":"30d5a537b296685770b1241c4b4bbde19d5a31ff81aa23df73fab5e90b8fc65f","names":["packages/session/session-title/src/types.ts#SessionTitleSource"],"sources":["packages/session/session-title/src/types.ts:28"]},
|
||||
{"digest":"312aee2f0c42aabbae6cc60d92d596d8453c0aeb061c5868d1755a69ef49e69a","names":[],"sources":[]},
|
||||
{"digest":"31907de9563751822af6d9be02bafaf26faa098bbd1cb412524134d577cc1648","names":["packages/compaction/compaction/src/checkpoint.ts#CompactionCheckpointSource"],"sources":["packages/compaction/compaction/src/checkpoint.ts:22"]},
|
||||
@@ -220,7 +220,7 @@
|
||||
{"digest":"3bec87f9e6ab3da03346f49923d3c51621debc0159df68605e543c3b2a026f90","names":[],"sources":["packages/llm/llm/src/types.ts:471"]},
|
||||
{"digest":"3bfeb47b58606f4661904bc723da612782214c463d01e6d61cd6d6193d7374e1","names":[],"sources":[]},
|
||||
{"digest":"3c2535ca0a2062f172f15344f8040755002b5ac506cf94fc4ebaa822b15feb8c","names":[],"sources":[]},
|
||||
{"digest":"3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f","names":["packages/core/tools/src/index.ts#ToolRestriction"],"sources":["packages/core/tools/src/index.ts:701"]},
|
||||
{"digest":"3cfc3a56502da1f8c6153c2c56657bab4b749056968634dd0991d325ec1c919f","names":["packages/core/tools/src/contracts.ts#ToolRestriction"],"sources":["packages/core/tools/src/contracts.ts:326"]},
|
||||
{"digest":"3d7d07060a7be77984feb651ea2bf1925d3e0477911d9d3ed86330d1e8ca6182","names":["packages/feedback/message-feedback/src/types.ts#MessageFeedbackItem"],"sources":["packages/feedback/message-feedback/src/types.ts:20"]},
|
||||
{"digest":"3e0eff5946255ff05d88a10839c60305135801f97794ea48d409f8503303317e","names":[],"sources":[]},
|
||||
{"digest":"3e2ece4967cfebe95f450a93f45523dff99d6749f6269f2f60f84dfecfcf3693","names":[],"sources":[]},
|
||||
@@ -416,7 +416,7 @@
|
||||
{"digest":"8e8e91646a5cae3fc78f7532a0013ff2088ae47077642c2edd507a508209b8af","names":["packages/schedule/schedule/src/types.ts#OneShotScheduleDispatchChange"],"sources":["packages/schedule/schedule/src/types.ts:237"]},
|
||||
{"digest":"8f324cea3916c0517261e88167def8efb3a9994c1135e23d40ed9fd48f8c7bd4","names":[],"sources":[]},
|
||||
{"digest":"8f6d609794bf5afc01d7ccf3e03811d32f4b8047f58a2c9a98db0154c2ad7cb9","names":[],"sources":[]},
|
||||
{"digest":"8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543","names":[],"sources":["packages/core/tools/src/index.ts:35"]},
|
||||
{"digest":"8fcb0b44a575e998665c053643d1ab04c82f39253ebd190ac0c975b78e40b543","names":[],"sources":["packages/core/tools/src/index.ts:18"]},
|
||||
{"digest":"904bf499d98be4a3a5f836fcac533b6c4899569b018071e6604e1d32657d00fd","names":[],"sources":[]},
|
||||
{"digest":"930c1cd289def119d443e19dd90008916bf035f0a4d23e07241e7f050f2b89b7","names":["packages/interaction/user-approval/src/types.ts#ApprovalOutcome"],"sources":["packages/interaction/user-approval/src/types.ts:32"]},
|
||||
{"digest":"935c8d486292b13c87b57ca280eb8c58b5b2f5239be86fcd4334c33fdeb87682","names":[],"sources":[]},
|
||||
@@ -471,7 +471,7 @@
|
||||
{"digest":"a6da9ad5d42ae83a6833a8288b076688e8e0801633ea36cbdd8a30a6d9f3160c","names":["packages/workflow/tool-workflow/src/types.ts#ToolWorkflowRunStartData"],"sources":["packages/workflow/tool-workflow/src/types.ts:14"]},
|
||||
{"digest":"a720757f704a2512e9d2f20da4a093e582472176236a75ab8b8eb7aaff17d85a","names":[],"sources":[]},
|
||||
{"digest":"a7cf43ce7c2a4c038feed1885cd7a00d5c6ee2d90a7e0d56b46f78a3e1ca327f","names":[],"sources":[]},
|
||||
{"digest":"a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735","names":[],"sources":["packages/core/session/src/types.ts:384","packages/core/tools/src/types.ts:27"]},
|
||||
{"digest":"a81059ca06999da1e712414520c2c65e491d052fcf9640fae20aa38f0a5dc735","names":[],"sources":["packages/core/session/src/types.ts:384","packages/core/tool-executor-ptc/src/types.ts:27"]},
|
||||
{"digest":"a853902cfab417b8f08aa51ad6855fea46f34ed4588a74e47403035111d0fb86","names":[],"sources":["packages/interaction/commands/src/types.ts:105"]},
|
||||
{"digest":"a8a2b9011fc067862df7ce40748868467e5778283d7ac193c13f77684a914c57","names":[],"sources":[]},
|
||||
{"digest":"a9059a81430b320792bbb7c2ee1f8f6c77ff71e40ee44c18aec72e157c522694","names":[],"sources":[]},
|
||||
@@ -570,7 +570,7 @@
|
||||
{"digest":"cda2345a9be9d139df49ccbd16dcba716f3440178bf20ff8b801fda1f5eb77dc","names":[],"sources":[]},
|
||||
{"digest":"cdca80b8dad24d4e7b1d5a288a8475ba8d8d46be385bd2da85f122ee836f1670","names":[],"sources":[]},
|
||||
{"digest":"cdee10e87dbed8440d8b6935888624884878efc7af95402e94171b29f173dced","names":[],"sources":["packages/llm/llm-retry/src/types.ts:17"]},
|
||||
{"digest":"cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6","names":["packages/core/tools/src/types.ts#PtcDispatchEventData"],"sources":["packages/core/tools/src/types.ts:21"]},
|
||||
{"digest":"cef171adf021a1867d244618a3dbbaafc22beb17c7f3df3ee203393271c8c6f6","names":["packages/core/tool-executor-ptc/src/types.ts#PtcDispatchEventData"],"sources":["packages/core/tool-executor-ptc/src/types.ts:21"]},
|
||||
{"digest":"cffcdc19881ab61ec0a9ce18743996f7ac44ac8889f34dfac36ae745574aa22f","names":["packages/goal/goal/src/domain.ts#GoalClearChangeMeta"],"sources":["packages/goal/goal/src/domain.ts:35"]},
|
||||
{"digest":"d0fbb0ca1bbba059830826f33f801da1aced35a2504376d61e020bdfec8d50c0","names":[],"sources":[]},
|
||||
{"digest":"d28765f87d6b6ab408e0b2f3e7e297791b004b806d8e302c49903ebae815feb2","names":[],"sources":[]},
|
||||
@@ -590,7 +590,7 @@
|
||||
{"digest":"db06ef35b27a38425046b2228fa6bce9582abe140d781d363137eb2f4d233a1c","names":[],"sources":[]},
|
||||
{"digest":"db6c5246911d47a7969f6b4cb47c7d0dbbde75c402710b22ace3672fa97bebe0","names":[],"sources":[]},
|
||||
{"digest":"db874d463b0fdec77e9da1c4568f37cb70bd6596781eb93800db44fb8a116965","names":[],"sources":[]},
|
||||
{"digest":"dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd","names":[],"sources":["packages/core/tools/src/ptc.ts:15"]},
|
||||
{"digest":"dba54c09c6e7aafc9acbed7792ecc920d99f92d0784aeeed10af55f7fe0bc8cd","names":[],"sources":["packages/core/tool-executor-ptc/src/types.ts:68"]},
|
||||
{"digest":"dbdafceb9a900183cccc80596498d386f3bf7bddead2b8cfde68453aa4739edc","names":[],"sources":[]},
|
||||
{"digest":"dd2780e7e07684332f7a9ab047237798d260e7eaffb1321cb38eca695d184c3d","names":[],"sources":[]},
|
||||
{"digest":"dd5ee8762bd8a14b6c6bffedd1753e4e78505bb0f9ea1621018d03a54eef59d5","names":[],"sources":[]},
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
/tools/toolrestriction-one-scope-s-live-filter-over-what-it-inherits:
|
||||
en: 8c3fc4ca26f7e314
|
||||
zh: 2e27263cb25243b9
|
||||
/tools/executors-and-raw-call-batches:
|
||||
en: 14522295539ea2fb
|
||||
zh: 572c462f2c6b70ad
|
||||
/tools/execution-extensible-waterfalls-plus-monotonic-policy:
|
||||
en: dcac8fa88ef3e719
|
||||
zh: aae2f4ce8852d8d8
|
||||
en: 356bf8128685d0fe
|
||||
zh: a28541da29c3deed
|
||||
/tools/the-enforced-raw-json-schema-subset:
|
||||
en: 28e354bfa2f9cebb
|
||||
zh: be1f75abccf8afdf
|
||||
|
||||
+145
-79
@@ -30,7 +30,7 @@ interface ToolDefinition extends ToolSchema {
|
||||
/**
|
||||
* Run one accepted call and return only its canonical lossless-JSON value.
|
||||
* Async work must observe or forward `exec.signal` and settle only after its
|
||||
* owned work reaches quiescence. The registry preserves caller cancellation
|
||||
* owned work reaches quiescence. The executor preserves caller cancellation
|
||||
* through around-dispatch signal replacement and does not abandon this
|
||||
* promise, but it cannot hard-kill same-process code.
|
||||
* @param args - losslessly snapshotted, frozen model arguments.
|
||||
@@ -49,12 +49,12 @@ interface ToolDefinition extends ToolSchema {
|
||||
*/
|
||||
projectContent?(exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): ContentBlock[] | undefined
|
||||
/**
|
||||
* Synchronous last-mile transform for model-facing content. The registry
|
||||
* Synchronous last-mile transform for model-facing content. The executor
|
||||
* snapshots this callback when execution starts and invokes it exactly once
|
||||
* for every normalized outcome, including pipeline failures that bypass
|
||||
* `tools/post-execute`, immediately before lossless materialization.
|
||||
* Returning `undefined` preserves the content; every other result field
|
||||
* remains registry-owned. The callback must be total and must not throw.
|
||||
* remains executor-owned. The callback must be total and must not throw.
|
||||
* @param exec - immutable execution identity and arguments.
|
||||
* @param result - complete normalized outcome before materialization.
|
||||
* @returns replacement content, or `undefined` to preserve it.
|
||||
@@ -177,9 +177,91 @@ interface ToolRestriction {
|
||||
}
|
||||
```
|
||||
|
||||
## Executors and raw call batches
|
||||
|
||||
`ctx.tools.execute()` delegates a complete raw model-call batch to the nearest scoped executor. The service selects the current provider when each batch starts; prompt assembly returns only model input. `agent` is absent for standalone service calls; `log` is absent for programmatic calls outside a model step, such as initialization hooks. An Agent without `log` still scopes tool access but produces no root call/result events. Tool-owned events may still use its Session.
|
||||
|
||||
```ts type-equiv
|
||||
/** Model-call schemas produced by an executor. */
|
||||
type ToolModelInput = Pick<ToolProviderResult, 'schemas' | 'knownNames'>
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Raw model calls, with optional Agent ownership and model-step logging. */
|
||||
interface ToolBatchInput {
|
||||
readonly calls: readonly ToolCallBlock[]
|
||||
readonly signal: AbortSignal
|
||||
/**
|
||||
* Positive integer overriding the executor's concurrency limit for this batch.
|
||||
* Applies to concurrency-safe root calls; program subcall limits remain separate.
|
||||
* Undefined uses the executor's configured limit.
|
||||
*/
|
||||
readonly maxParallelToolCalls?: number
|
||||
/**
|
||||
* Owning Agent supplies scoped tools and execution context, including outside a turn.
|
||||
* Undefined for standalone calls outside an Agent, such as a service invocation.
|
||||
*/
|
||||
readonly agent?: Agent
|
||||
/**
|
||||
* Committed model step receiving root call/result events; requires `agent`.
|
||||
* Undefined when `agent` is absent or for calls outside a model response, such
|
||||
* as session initialization hooks. Without `log`, root call/result events are
|
||||
* omitted while `agent`, when provided, still supplies scope and execution context.
|
||||
*/
|
||||
readonly log?: {
|
||||
readonly turn: number
|
||||
readonly step: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** One settled result correlated with its original model call. */
|
||||
interface ToolCallResult {
|
||||
readonly callId: ToolCallId
|
||||
readonly result: ToolExecutionResult
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Model-ordered outcomes and context accepted for the next step. */
|
||||
interface ToolBatchResult {
|
||||
readonly results: readonly ToolCallResult[]
|
||||
readonly additionalContexts: readonly UserMessage[]
|
||||
readonly concluded: boolean
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** A plugin owns argument parsing, dispatch, scheduling, cancellation, and logging. */
|
||||
interface ToolExecutor {
|
||||
/** Guidance registered and disposed with this executor; absent means no executor-owned sections. */
|
||||
readonly sections?: readonly ToolPromptSection[]
|
||||
/**
|
||||
* Describe the model's callable tools.
|
||||
* @param tools - currently visible capability definitions, after scoped restrictions.
|
||||
* @returns schemas and names used to validate tool ordering.
|
||||
*/
|
||||
describe(tools: readonly ToolDefinition[]): ToolModelInput
|
||||
/**
|
||||
* Execute a complete batch. With log, commit root call/result events to the
|
||||
* Agent's Session; without log, omit those events. Tool-owned events may still
|
||||
* use the owning Agent's Session. Return
|
||||
* one outcome per input call in input order, including skipped calls on abort.
|
||||
* Never settle while started work is still running. Internal failures reject
|
||||
* with ToolBatchExecutionError after draining, preserving committed outcomes
|
||||
* and context; callers must stop dependent work and repair missing log results.
|
||||
* An explicit maxParallelToolCalls takes precedence over executor configuration.
|
||||
* @param input - original calls, cancellation, optional concurrency override, Agent and logging step.
|
||||
* @returns settled results, deferred context, and whether a success concludes the turn.
|
||||
*/
|
||||
execute(input: ToolBatchInput): Promise<ToolBatchResult>
|
||||
}
|
||||
```
|
||||
|
||||
## Execution: extensible waterfalls plus monotonic policy
|
||||
|
||||
`ctx.tools.execute()` accepts a caller-owned `ToolExecutionInput` with a required readonly `signal`, materializes its parsed JSON arguments once into a pipeline-owned `ToolExecution`, and runs that call through `tools/pre-execute` (the reorderable allow/deny/ask waterfall) → registered monotonic guards → `tools/execute` (around-dispatch wrappers) → `projectContent` → `tools/post-execute` (inspect/replace the result) → optional definition-owned `finalizeContent` → `tools/result` (the immutable authoritative outcome). Only the `tools/execute` view may replace the required signal. The outcome is a `ToolExecutionResult`.
|
||||
Built-in executors pass parsed `ToolExecutionInput` values to the shared `ToolExecutionPipeline`. The pipeline owns argument snapshots, execution identities, policy waterfalls, dispatch, and final-result notification, returning one `ToolExecutionResult` per invocation. Custom executors can implement their own execution; the public `ToolExecutor` requires only descriptions and batch execution.
|
||||
|
||||
```ts type-equiv
|
||||
/** Opaque call identity that permits correlation without exposing mutable execution state. */
|
||||
@@ -188,8 +270,8 @@ type ToolExecutionToken = symbol & { readonly [toolExecutionTokenBrand]: true }
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Caller-supplied description of one tool call. {@link ToolRuntime.execute}
|
||||
* adds the registry-owned token to form a pipeline {@link ToolExecution};
|
||||
* Parsed input to the shared invocation pipeline. The pipeline
|
||||
* adds its own token to form a {@link ToolExecution};
|
||||
* callers do not choose that token.
|
||||
*/
|
||||
interface ToolExecutionInput {
|
||||
@@ -211,9 +293,9 @@ interface ToolExecutionInput {
|
||||
* mode sets this on SDK sub-dispatches so commit-style observers can wait for
|
||||
* the outer `run_code` outcome without receiving its live mutable execution.
|
||||
* The token also marks the call as a transport sub-dispatch rather than a
|
||||
* model-direct call: under `mode: 'ptc'`, only calls WITH a parent may
|
||||
* model-direct call: with the PTC executor selected, only calls with a parent may
|
||||
* execute a native tool name — a model-direct call (no parent) is denied as
|
||||
* `UNKNOWN_TOOL` before the policy pipeline. See {@link ToolRuntime.execute}.
|
||||
* `UNKNOWN_TOOL` before the policy pipeline.
|
||||
*/
|
||||
readonly parent?: ToolExecutionToken
|
||||
/** Required caller-owned cancellation for this invocation. */
|
||||
@@ -225,7 +307,7 @@ A tool body receives the runtime extension. `deferContext()` attaches context to
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Runtime context handed to a tool implementation after the registry has
|
||||
* Runtime context handed to a tool implementation after the executor has
|
||||
* accepted a {@link ToolExecution}. {@link deferContext} attaches context to
|
||||
* this execution's own result — a composite tool ferries nested-dispatch
|
||||
* context back to the outer result, and a leaf tool may mint a fresh
|
||||
@@ -294,16 +376,16 @@ interface PtcDispatchLog {
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* One pending tool call inside the registry pipeline. Parsed arguments cross
|
||||
* One pending tool call inside the executor pipeline. Parsed arguments cross
|
||||
* one lossless-JSON materialization boundary before policy and are deep-frozen;
|
||||
* call identity, the caller signal, and the registry-assigned {@link token} are
|
||||
* readonly. The registry freezes the complete object before `tools/result`
|
||||
* call identity, the caller signal, and the executor-assigned {@link token} are
|
||||
* readonly. The executor freezes the complete object before `tools/result`
|
||||
* observers run.
|
||||
*/
|
||||
interface ToolExecution extends ToolExecutionInput {
|
||||
/** Root model-requested call, resolved for every root and nested execution. */
|
||||
readonly rootCallId: ToolCallId
|
||||
/** Registry-assigned identity shared with nested calls only as their opaque `parent` token. */
|
||||
/** Executor-assigned identity shared with nested calls only as their opaque `parent` token. */
|
||||
readonly token: ToolExecutionToken
|
||||
}
|
||||
```
|
||||
@@ -312,7 +394,7 @@ interface ToolExecution extends ToolExecutionInput {
|
||||
/**
|
||||
* Around-dispatch view of a {@link ToolExecution}. A `tools/execute` wrapper
|
||||
* may replace the signal for its delegated lifetime, but it cannot remove it.
|
||||
* The registry fuses every replacement with the captured caller signal.
|
||||
* The executor fuses every replacement with the captured caller signal.
|
||||
*/
|
||||
interface ToolDispatchExecution extends Omit<ToolExecution, 'signal'> {
|
||||
/** Cancellation signal visible to the next wrapper or tool body. */
|
||||
@@ -501,26 +583,13 @@ The full presentation field docs live in [`packages/core/tools/src/presentation.
|
||||
|
||||
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
||||
|
||||
<a id="ctxtools--toolruntime"></a>
|
||||
<a id="ctxtools--toolsservice"></a>
|
||||
|
||||
### `ctx.tools` — `ToolRuntime`
|
||||
### `ctx.tools` — `ToolsService`
|
||||
|
||||
Tool registry and execution pipeline. Scoped registrations shadow globals; one visibility resolver feeds presentation, lookup, and dispatch.
|
||||
Concrete tool registry and scoped executor dispatcher.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Present the calling scope's tools in `mode` instead of the deployment
|
||||
* default. Nearest scope on the chain wins, so a preset's standing
|
||||
* declaration covers every agent joined under it.
|
||||
*
|
||||
* Scoped only, and one declaration per scope: this is how an agent preset
|
||||
* composes PTC mode agents beside native ones in the same process, and a
|
||||
* process-global override would be the `mode` config field instead.
|
||||
* @param mode - the presentation the covered agents' models see.
|
||||
* @returns the exact disposer that restores the deployment default.
|
||||
*/
|
||||
presentAs(mode: ToolPresentationMode): () => void
|
||||
|
||||
/**
|
||||
* Register globally or in the calling agent scope. Scoped tools shadow
|
||||
* globals; duplicates within one layer and the reserved `run_code` name fail.
|
||||
@@ -538,18 +607,6 @@ register(definition: ToolDefinition): () => void
|
||||
*/
|
||||
restrict(filter: ToolRestriction): () => void
|
||||
|
||||
/**
|
||||
* Register a monotonic guard after the extensible `tools/pre-execute`
|
||||
* waterfall. A plain-context guard applies globally; one registered through
|
||||
* `agent.ctx` applies only to that agent. Any matching guard may deny by
|
||||
* returning a reason, while no guard can force-allow a call another guard
|
||||
* denied. The exact effect disposer is returned for ordered ownership and
|
||||
* HMR cleanup.
|
||||
* @param guard - synchronous check; a returned string denies the execution.
|
||||
* @returns the exact disposer that unregisters the guard.
|
||||
*/
|
||||
guard(guard: ToolGuard): () => void
|
||||
|
||||
/**
|
||||
* Look up a tool as one scope sees it (scoped
|
||||
* shadows global; a restricted-away global reads as absent). Presenters pass
|
||||
@@ -561,6 +618,13 @@ guard(guard: ToolGuard): () => void
|
||||
*/
|
||||
get(name: string, scope?: ScopeKey): ToolDefinition | undefined
|
||||
|
||||
/**
|
||||
* Read the visible capability definitions for descriptions and program bindings.
|
||||
* @param scope - viewing Agent or preset; omitted selects the global view.
|
||||
* @returns definitions after scoped shadowing and restrictions.
|
||||
*/
|
||||
definitions(scope?: ScopeKey): readonly ToolDefinition[]
|
||||
|
||||
/**
|
||||
* Project visible definitions onto the allowlisted model-facing schema fields,
|
||||
* excluding execution and presentation callbacks.
|
||||
@@ -570,29 +634,34 @@ get(name: string, scope?: ScopeKey): ToolDefinition | undefined
|
||||
schemas(scope?: ScopeKey): ToolSchema[]
|
||||
|
||||
/**
|
||||
* Classify a pending call through the caller's visible tool definition. Only
|
||||
* an exact `true` is parallel; unknown, hidden, undeclared, invalid, or
|
||||
* throwing classifiers are exclusive.
|
||||
* @param exec - call name, parsed arguments, and optional agent scope.
|
||||
* @returns the fail-closed scheduling mode.
|
||||
* Provide the executor for the calling scope; an unscoped contribution is the deployment default.
|
||||
* Rendering any executor-owned section requires the viewing scope's selection to remain available.
|
||||
* @param executor - initialized provider owned by the contributing plugin.
|
||||
* @returns the effect disposer. Unloading leaves the selection unavailable until it is replaced.
|
||||
*/
|
||||
executionMode(exec: ToolExecutionInput): ToolExecutionMode
|
||||
setExecutor(executor: ToolExecutor): () => void
|
||||
|
||||
/**
|
||||
* Execute through pre-policy, guards, around-dispatch, post-policy,
|
||||
* definition-owned content finalization, and final notification. Tool and
|
||||
* listener failures resolve as materialized error results; an invisible tool
|
||||
* reports `UNKNOWN_TOOL`. The returned outcome is the same lossless, frozen
|
||||
* snapshot final observers receive. Cancellation
|
||||
* arriving after entry and before final result materialization skips a
|
||||
* not-yet-started body with `ABORTED_BEFORE_DISPATCH` or replaces a
|
||||
* successful started outcome with `ABORTED`; already-started work is still
|
||||
* drained and may retain a tool-owned structured error.
|
||||
* @param exec - the typed same-process call input. The registry assigns its
|
||||
* correlation token before policy begins.
|
||||
* @returns the materialized final result.
|
||||
* Delegate a raw call batch to its Agent's provider or the deployment default.
|
||||
* Select at dispatch; accepted batches settle through that provider even if it unloads.
|
||||
* @param input - original calls, optional owning Agent, and optional logging step.
|
||||
* @returns the selected executor's settled batch; unavailable selections reject.
|
||||
*/
|
||||
async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
|
||||
async execute(input: ToolBatchInput): Promise<ToolBatchResult>
|
||||
|
||||
/**
|
||||
* Register a monotonic denial in the calling scope.
|
||||
* @param guard - evaluated after extensible pre-execute policy by the shared pipeline.
|
||||
* @returns the effect disposer that removes this guard.
|
||||
*/
|
||||
guard(guard: ToolGuard): () => void
|
||||
|
||||
/**
|
||||
* Check global and inherited guards after pre-execute policy and approval resolve.
|
||||
* @param exec - invocation whose guards are checked before dispatch.
|
||||
* @returns the first denial reason, or undefined when no guard denies.
|
||||
*/
|
||||
checkGuards(exec: ToolExecution): string | undefined
|
||||
```
|
||||
|
||||
Types: [ScopeKey](scope.md)
|
||||
@@ -607,22 +676,19 @@ Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index
|
||||
|
||||
#### `tools/change` — emit
|
||||
|
||||
A tool was registered or unregistered, or a scoped restriction changed (the available tool set changed — possibly for one scope only). An UNFILTERED registry-subject notification, deliberately not scope-filtered dispatch: a global change concerns every agent's next assembly, so a scoped listener subscribing here sees every change, not just its own scope's.
|
||||
A tool was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* A tool was registered or unregistered, or a scoped restriction changed
|
||||
* (the available tool set changed — possibly for one scope only). An
|
||||
* UNFILTERED registry-subject notification, deliberately not scope-filtered
|
||||
* dispatch: a global change concerns every agent's next assembly, so a
|
||||
* scoped listener subscribing here sees every change, not just its own
|
||||
* scope's.
|
||||
* A tool was registered or unregistered, or a scoped restriction changed.
|
||||
* Unfiltered registry notification: scoped listeners receive changes from every
|
||||
* scope because a global contribution can affect every agent's next assembly.
|
||||
* @mode emit
|
||||
*/
|
||||
'tools/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolsexecute--waterfall"></a>
|
||||
|
||||
@@ -641,12 +707,12 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor
|
||||
* @param exec - the allowed call about to dispatch (name, parsed arguments, caller agent, signal).
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/execute'(this: Scoped<ToolRuntime>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
'tools/execute'(this: Scoped<ToolsService>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolspost-execute--waterfall"></a>
|
||||
|
||||
@@ -666,12 +732,12 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
|
||||
* @param result - the dispatch outcome a listener may accept, replace, or block.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/post-execute'(this: Scoped<ToolRuntime>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>
|
||||
'tools/post-execute'(this: Scoped<ToolsService>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolspre-execute--waterfall"></a>
|
||||
|
||||
@@ -690,12 +756,12 @@ Allow, deny, cancel, or ask before dispatch. `next()` delegates to allow; `cance
|
||||
* @param exec - the pending call (name, parsed arguments, caller agent).
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/pre-execute'(this: Scoped<ToolRuntime>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
|
||||
'tools/pre-execute'(this: Scoped<ToolsService>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolsptc-dispatch-log--waterfall"></a>
|
||||
|
||||
@@ -717,12 +783,12 @@ Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` su
|
||||
* @param dispatch - the parent execution, sub-call identity, and the settled content to log.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/ptc-dispatch-log'(this: Scoped<ToolRuntime>, dispatch: PtcDispatchLog, next: () => Promise<ContentBlock[]>): Promise<ContentBlock[]>
|
||||
'tools/ptc-dispatch-log'(this: Scoped<ToolsService>, dispatch: PtcDispatchLog, next: () => Promise<ContentBlock[]>): Promise<ContentBlock[]>
|
||||
```
|
||||
|
||||
Types: [ContentBlock](llm-streaming.md) · [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tool-executor-ptc/src/runtime-types.ts`](../../packages/core/tool-executor-ptc/src/runtime-types.ts)
|
||||
|
||||
<a id="toolsresult--emit"></a>
|
||||
|
||||
@@ -738,10 +804,10 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
|
||||
* @param result - a deep-frozen snapshot of the final returned result.
|
||||
* @mode emit
|
||||
*/
|
||||
'tools/result'(this: Scoped<ToolRuntime>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
|
||||
'tools/result'(this: Scoped<ToolsService>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
<!-- END GENERATED cordis-surface -->
|
||||
+145
-79
@@ -30,7 +30,7 @@ interface ToolDefinition extends ToolSchema {
|
||||
/**
|
||||
* Run one accepted call and return only its canonical lossless-JSON value.
|
||||
* Async work must observe or forward `exec.signal` and settle only after its
|
||||
* owned work reaches quiescence. The registry preserves caller cancellation
|
||||
* owned work reaches quiescence. The executor preserves caller cancellation
|
||||
* through around-dispatch signal replacement and does not abandon this
|
||||
* promise, but it cannot hard-kill same-process code.
|
||||
* @param args - losslessly snapshotted, frozen model arguments.
|
||||
@@ -49,12 +49,12 @@ interface ToolDefinition extends ToolSchema {
|
||||
*/
|
||||
projectContent?(exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): ContentBlock[] | undefined
|
||||
/**
|
||||
* Synchronous last-mile transform for model-facing content. The registry
|
||||
* Synchronous last-mile transform for model-facing content. The executor
|
||||
* snapshots this callback when execution starts and invokes it exactly once
|
||||
* for every normalized outcome, including pipeline failures that bypass
|
||||
* `tools/post-execute`, immediately before lossless materialization.
|
||||
* Returning `undefined` preserves the content; every other result field
|
||||
* remains registry-owned. The callback must be total and must not throw.
|
||||
* remains executor-owned. The callback must be total and must not throw.
|
||||
* @param exec - immutable execution identity and arguments.
|
||||
* @param result - complete normalized outcome before materialization.
|
||||
* @returns replacement content, or `undefined` to preserve it.
|
||||
@@ -177,9 +177,91 @@ interface ToolRestriction {
|
||||
}
|
||||
```
|
||||
|
||||
## 执行器与原始调用批次
|
||||
|
||||
`ctx.tools.execute()` 把完整的原始模型调用批次委托给最近作用域的执行器。服务在每个批次开始时选择当前提供者;提示词组装仅返回模型输入。`agent` 在独立服务调用中不存在;`log` 在模型步骤之外的程序调用(例如初始化钩子)中不存在。有 Agent 而没有 `log` 时,调用仍受该 Agent 的工具作用域约束,但不记录根调用/结果事件。工具自身的事件仍可使用 Agent 的 Session。
|
||||
|
||||
```ts type-equiv
|
||||
/** Model-call schemas produced by an executor. */
|
||||
type ToolModelInput = Pick<ToolProviderResult, 'schemas' | 'knownNames'>
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Raw model calls, with optional Agent ownership and model-step logging. */
|
||||
interface ToolBatchInput {
|
||||
readonly calls: readonly ToolCallBlock[]
|
||||
readonly signal: AbortSignal
|
||||
/**
|
||||
* Positive integer overriding the executor's concurrency limit for this batch.
|
||||
* Applies to concurrency-safe root calls; program subcall limits remain separate.
|
||||
* Undefined uses the executor's configured limit.
|
||||
*/
|
||||
readonly maxParallelToolCalls?: number
|
||||
/**
|
||||
* Owning Agent supplies scoped tools and execution context, including outside a turn.
|
||||
* Undefined for standalone calls outside an Agent, such as a service invocation.
|
||||
*/
|
||||
readonly agent?: Agent
|
||||
/**
|
||||
* Committed model step receiving root call/result events; requires `agent`.
|
||||
* Undefined when `agent` is absent or for calls outside a model response, such
|
||||
* as session initialization hooks. Without `log`, root call/result events are
|
||||
* omitted while `agent`, when provided, still supplies scope and execution context.
|
||||
*/
|
||||
readonly log?: {
|
||||
readonly turn: number
|
||||
readonly step: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** One settled result correlated with its original model call. */
|
||||
interface ToolCallResult {
|
||||
readonly callId: ToolCallId
|
||||
readonly result: ToolExecutionResult
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Model-ordered outcomes and context accepted for the next step. */
|
||||
interface ToolBatchResult {
|
||||
readonly results: readonly ToolCallResult[]
|
||||
readonly additionalContexts: readonly UserMessage[]
|
||||
readonly concluded: boolean
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** A plugin owns argument parsing, dispatch, scheduling, cancellation, and logging. */
|
||||
interface ToolExecutor {
|
||||
/** Guidance registered and disposed with this executor; absent means no executor-owned sections. */
|
||||
readonly sections?: readonly ToolPromptSection[]
|
||||
/**
|
||||
* Describe the model's callable tools.
|
||||
* @param tools - currently visible capability definitions, after scoped restrictions.
|
||||
* @returns schemas and names used to validate tool ordering.
|
||||
*/
|
||||
describe(tools: readonly ToolDefinition[]): ToolModelInput
|
||||
/**
|
||||
* Execute a complete batch. With log, commit root call/result events to the
|
||||
* Agent's Session; without log, omit those events. Tool-owned events may still
|
||||
* use the owning Agent's Session. Return
|
||||
* one outcome per input call in input order, including skipped calls on abort.
|
||||
* Never settle while started work is still running. Internal failures reject
|
||||
* with ToolBatchExecutionError after draining, preserving committed outcomes
|
||||
* and context; callers must stop dependent work and repair missing log results.
|
||||
* An explicit maxParallelToolCalls takes precedence over executor configuration.
|
||||
* @param input - original calls, cancellation, optional concurrency override, Agent and logging step.
|
||||
* @returns settled results, deferred context, and whether a success concludes the turn.
|
||||
*/
|
||||
execute(input: ToolBatchInput): Promise<ToolBatchResult>
|
||||
}
|
||||
```
|
||||
|
||||
## 执行:可扩展的 waterfall(瀑布式事件)加单调策略
|
||||
|
||||
`ctx.tools.execute()` 接受由调用方拥有且包含必需 readonly `signal` 的 `ToolExecutionInput`,将其解析后的 JSON 参数一次性物化为流水线拥有的 `ToolExecution`,然后让调用依次经过 `tools/pre-execute`(可重排的 allow/deny/ask waterfall)→ 已注册的单调 guard → `tools/execute`(环绕分派包装层)→ `projectContent` → `tools/post-execute`(检查/替换结果)→ 可选且由定义拥有的 `finalizeContent` → `tools/result`(不可变的权威结果)。只有 `tools/execute` 视图可以替换必需的 signal。最终产出为 `ToolExecutionResult`。
|
||||
内置执行器把解析后的 `ToolExecutionInput` 交给共享 `ToolExecutionPipeline`。流水线负责参数快照、执行身份、策略瀑布、工具分发和最终结果通知,每次返回一个 `ToolExecutionResult`。自定义执行器可以独立实现这些行为;公开的 `ToolExecutor` 只要求工具描述和批次执行方法。
|
||||
|
||||
```ts type-equiv
|
||||
/** Opaque call identity that permits correlation without exposing mutable execution state. */
|
||||
@@ -188,8 +270,8 @@ type ToolExecutionToken = symbol & { readonly [toolExecutionTokenBrand]: true }
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Caller-supplied description of one tool call. {@link ToolRuntime.execute}
|
||||
* adds the registry-owned token to form a pipeline {@link ToolExecution};
|
||||
* Parsed input to the shared invocation pipeline. The pipeline
|
||||
* adds its own token to form a {@link ToolExecution};
|
||||
* callers do not choose that token.
|
||||
*/
|
||||
interface ToolExecutionInput {
|
||||
@@ -211,9 +293,9 @@ interface ToolExecutionInput {
|
||||
* mode sets this on SDK sub-dispatches so commit-style observers can wait for
|
||||
* the outer `run_code` outcome without receiving its live mutable execution.
|
||||
* The token also marks the call as a transport sub-dispatch rather than a
|
||||
* model-direct call: under `mode: 'ptc'`, only calls WITH a parent may
|
||||
* model-direct call: with the PTC executor selected, only calls with a parent may
|
||||
* execute a native tool name — a model-direct call (no parent) is denied as
|
||||
* `UNKNOWN_TOOL` before the policy pipeline. See {@link ToolRuntime.execute}.
|
||||
* `UNKNOWN_TOOL` before the policy pipeline.
|
||||
*/
|
||||
readonly parent?: ToolExecutionToken
|
||||
/** Required caller-owned cancellation for this invocation. */
|
||||
@@ -225,7 +307,7 @@ interface ToolExecutionInput {
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Runtime context handed to a tool implementation after the registry has
|
||||
* Runtime context handed to a tool implementation after the executor has
|
||||
* accepted a {@link ToolExecution}. {@link deferContext} attaches context to
|
||||
* this execution's own result — a composite tool ferries nested-dispatch
|
||||
* context back to the outer result, and a leaf tool may mint a fresh
|
||||
@@ -294,16 +376,16 @@ interface PtcDispatchLog {
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* One pending tool call inside the registry pipeline. Parsed arguments cross
|
||||
* One pending tool call inside the executor pipeline. Parsed arguments cross
|
||||
* one lossless-JSON materialization boundary before policy and are deep-frozen;
|
||||
* call identity, the caller signal, and the registry-assigned {@link token} are
|
||||
* readonly. The registry freezes the complete object before `tools/result`
|
||||
* call identity, the caller signal, and the executor-assigned {@link token} are
|
||||
* readonly. The executor freezes the complete object before `tools/result`
|
||||
* observers run.
|
||||
*/
|
||||
interface ToolExecution extends ToolExecutionInput {
|
||||
/** Root model-requested call, resolved for every root and nested execution. */
|
||||
readonly rootCallId: ToolCallId
|
||||
/** Registry-assigned identity shared with nested calls only as their opaque `parent` token. */
|
||||
/** Executor-assigned identity shared with nested calls only as their opaque `parent` token. */
|
||||
readonly token: ToolExecutionToken
|
||||
}
|
||||
```
|
||||
@@ -312,7 +394,7 @@ interface ToolExecution extends ToolExecutionInput {
|
||||
/**
|
||||
* Around-dispatch view of a {@link ToolExecution}. A `tools/execute` wrapper
|
||||
* may replace the signal for its delegated lifetime, but it cannot remove it.
|
||||
* The registry fuses every replacement with the captured caller signal.
|
||||
* The executor fuses every replacement with the captured caller signal.
|
||||
*/
|
||||
interface ToolDispatchExecution extends Omit<ToolExecution, 'signal'> {
|
||||
/** Cancellation signal visible to the next wrapper or tool body. */
|
||||
@@ -501,26 +583,13 @@ type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
|
||||
|
||||
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.zh.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
||||
|
||||
<a id="ctxtools--toolruntime"></a>
|
||||
<a id="ctxtools--toolsservice"></a>
|
||||
|
||||
### `ctx.tools` — `ToolRuntime`
|
||||
### `ctx.tools` — `ToolsService`
|
||||
|
||||
Tool registry and execution pipeline. Scoped registrations shadow globals; one visibility resolver feeds presentation, lookup, and dispatch.
|
||||
Concrete tool registry and scoped executor dispatcher.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Present the calling scope's tools in `mode` instead of the deployment
|
||||
* default. Nearest scope on the chain wins, so a preset's standing
|
||||
* declaration covers every agent joined under it.
|
||||
*
|
||||
* Scoped only, and one declaration per scope: this is how an agent preset
|
||||
* composes PTC mode agents beside native ones in the same process, and a
|
||||
* process-global override would be the `mode` config field instead.
|
||||
* @param mode - the presentation the covered agents' models see.
|
||||
* @returns the exact disposer that restores the deployment default.
|
||||
*/
|
||||
presentAs(mode: ToolPresentationMode): () => void
|
||||
|
||||
/**
|
||||
* Register globally or in the calling agent scope. Scoped tools shadow
|
||||
* globals; duplicates within one layer and the reserved `run_code` name fail.
|
||||
@@ -538,18 +607,6 @@ register(definition: ToolDefinition): () => void
|
||||
*/
|
||||
restrict(filter: ToolRestriction): () => void
|
||||
|
||||
/**
|
||||
* Register a monotonic guard after the extensible `tools/pre-execute`
|
||||
* waterfall. A plain-context guard applies globally; one registered through
|
||||
* `agent.ctx` applies only to that agent. Any matching guard may deny by
|
||||
* returning a reason, while no guard can force-allow a call another guard
|
||||
* denied. The exact effect disposer is returned for ordered ownership and
|
||||
* HMR cleanup.
|
||||
* @param guard - synchronous check; a returned string denies the execution.
|
||||
* @returns the exact disposer that unregisters the guard.
|
||||
*/
|
||||
guard(guard: ToolGuard): () => void
|
||||
|
||||
/**
|
||||
* Look up a tool as one scope sees it (scoped
|
||||
* shadows global; a restricted-away global reads as absent). Presenters pass
|
||||
@@ -561,6 +618,13 @@ guard(guard: ToolGuard): () => void
|
||||
*/
|
||||
get(name: string, scope?: ScopeKey): ToolDefinition | undefined
|
||||
|
||||
/**
|
||||
* Read the visible capability definitions for descriptions and program bindings.
|
||||
* @param scope - viewing Agent or preset; omitted selects the global view.
|
||||
* @returns definitions after scoped shadowing and restrictions.
|
||||
*/
|
||||
definitions(scope?: ScopeKey): readonly ToolDefinition[]
|
||||
|
||||
/**
|
||||
* Project visible definitions onto the allowlisted model-facing schema fields,
|
||||
* excluding execution and presentation callbacks.
|
||||
@@ -570,29 +634,34 @@ get(name: string, scope?: ScopeKey): ToolDefinition | undefined
|
||||
schemas(scope?: ScopeKey): ToolSchema[]
|
||||
|
||||
/**
|
||||
* Classify a pending call through the caller's visible tool definition. Only
|
||||
* an exact `true` is parallel; unknown, hidden, undeclared, invalid, or
|
||||
* throwing classifiers are exclusive.
|
||||
* @param exec - call name, parsed arguments, and optional agent scope.
|
||||
* @returns the fail-closed scheduling mode.
|
||||
* Provide the executor for the calling scope; an unscoped contribution is the deployment default.
|
||||
* Rendering any executor-owned section requires the viewing scope's selection to remain available.
|
||||
* @param executor - initialized provider owned by the contributing plugin.
|
||||
* @returns the effect disposer. Unloading leaves the selection unavailable until it is replaced.
|
||||
*/
|
||||
executionMode(exec: ToolExecutionInput): ToolExecutionMode
|
||||
setExecutor(executor: ToolExecutor): () => void
|
||||
|
||||
/**
|
||||
* Execute through pre-policy, guards, around-dispatch, post-policy,
|
||||
* definition-owned content finalization, and final notification. Tool and
|
||||
* listener failures resolve as materialized error results; an invisible tool
|
||||
* reports `UNKNOWN_TOOL`. The returned outcome is the same lossless, frozen
|
||||
* snapshot final observers receive. Cancellation
|
||||
* arriving after entry and before final result materialization skips a
|
||||
* not-yet-started body with `ABORTED_BEFORE_DISPATCH` or replaces a
|
||||
* successful started outcome with `ABORTED`; already-started work is still
|
||||
* drained and may retain a tool-owned structured error.
|
||||
* @param exec - the typed same-process call input. The registry assigns its
|
||||
* correlation token before policy begins.
|
||||
* @returns the materialized final result.
|
||||
* Delegate a raw call batch to its Agent's provider or the deployment default.
|
||||
* Select at dispatch; accepted batches settle through that provider even if it unloads.
|
||||
* @param input - original calls, optional owning Agent, and optional logging step.
|
||||
* @returns the selected executor's settled batch; unavailable selections reject.
|
||||
*/
|
||||
async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
|
||||
async execute(input: ToolBatchInput): Promise<ToolBatchResult>
|
||||
|
||||
/**
|
||||
* Register a monotonic denial in the calling scope.
|
||||
* @param guard - evaluated after extensible pre-execute policy by the shared pipeline.
|
||||
* @returns the effect disposer that removes this guard.
|
||||
*/
|
||||
guard(guard: ToolGuard): () => void
|
||||
|
||||
/**
|
||||
* Check global and inherited guards after pre-execute policy and approval resolve.
|
||||
* @param exec - invocation whose guards are checked before dispatch.
|
||||
* @returns the first denial reason, or undefined when no guard denies.
|
||||
*/
|
||||
checkGuards(exec: ToolExecution): string | undefined
|
||||
```
|
||||
|
||||
Types: [ScopeKey](scope.zh.md)
|
||||
@@ -607,22 +676,19 @@ Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index
|
||||
|
||||
#### `tools/change` — emit
|
||||
|
||||
A tool was registered or unregistered, or a scoped restriction changed (the available tool set changed — possibly for one scope only). An UNFILTERED registry-subject notification, deliberately not scope-filtered dispatch: a global change concerns every agent's next assembly, so a scoped listener subscribing here sees every change, not just its own scope's.
|
||||
A tool was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* A tool was registered or unregistered, or a scoped restriction changed
|
||||
* (the available tool set changed — possibly for one scope only). An
|
||||
* UNFILTERED registry-subject notification, deliberately not scope-filtered
|
||||
* dispatch: a global change concerns every agent's next assembly, so a
|
||||
* scoped listener subscribing here sees every change, not just its own
|
||||
* scope's.
|
||||
* A tool was registered or unregistered, or a scoped restriction changed.
|
||||
* Unfiltered registry notification: scoped listeners receive changes from every
|
||||
* scope because a global contribution can affect every agent's next assembly.
|
||||
* @mode emit
|
||||
*/
|
||||
'tools/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolsexecute--waterfall"></a>
|
||||
|
||||
@@ -641,12 +707,12 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor
|
||||
* @param exec - the allowed call about to dispatch (name, parsed arguments, caller agent, signal).
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/execute'(this: Scoped<ToolRuntime>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
'tools/execute'(this: Scoped<ToolsService>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.zh.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolspost-execute--waterfall"></a>
|
||||
|
||||
@@ -666,12 +732,12 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
|
||||
* @param result - the dispatch outcome a listener may accept, replace, or block.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/post-execute'(this: Scoped<ToolRuntime>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>
|
||||
'tools/post-execute'(this: Scoped<ToolsService>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.zh.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolspre-execute--waterfall"></a>
|
||||
|
||||
@@ -690,12 +756,12 @@ Allow, deny, cancel, or ask before dispatch. `next()` delegates to allow; `cance
|
||||
* @param exec - the pending call (name, parsed arguments, caller agent).
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/pre-execute'(this: Scoped<ToolRuntime>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
|
||||
'tools/pre-execute'(this: Scoped<ToolsService>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.zh.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
|
||||
<a id="toolsptc-dispatch-log--waterfall"></a>
|
||||
|
||||
@@ -717,12 +783,12 @@ Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` su
|
||||
* @param dispatch - the parent execution, sub-call identity, and the settled content to log.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/ptc-dispatch-log'(this: Scoped<ToolRuntime>, dispatch: PtcDispatchLog, next: () => Promise<ContentBlock[]>): Promise<ContentBlock[]>
|
||||
'tools/ptc-dispatch-log'(this: Scoped<ToolsService>, dispatch: PtcDispatchLog, next: () => Promise<ContentBlock[]>): Promise<ContentBlock[]>
|
||||
```
|
||||
|
||||
Types: [ContentBlock](llm-streaming.zh.md) · [Scoped](scope.zh.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tool-executor-ptc/src/runtime-types.ts`](../../packages/core/tool-executor-ptc/src/runtime-types.ts)
|
||||
|
||||
<a id="toolsresult--emit"></a>
|
||||
|
||||
@@ -738,10 +804,10 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
|
||||
* @param result - a deep-frozen snapshot of the final returned result.
|
||||
* @mode emit
|
||||
*/
|
||||
'tools/result'(this: Scoped<ToolRuntime>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
|
||||
'tools/result'(this: Scoped<ToolsService>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
|
||||
```
|
||||
|
||||
Types: [Scoped](scope.zh.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/events.ts`](../../packages/core/tools/src/events.ts)
|
||||
<!-- END GENERATED cordis-surface -->
|
||||
+10
-10
@@ -9,8 +9,8 @@
|
||||
en: 6cc2cd9ced70bb09
|
||||
zh: 1c0e6cb4ba2ed637
|
||||
/tool-schema-catalog/tool-package-map:
|
||||
en: 19883cdd5d6181cb
|
||||
zh: 7d0cac18206184ec
|
||||
en: 10fe940a3d17cde7
|
||||
zh: ef1e8863c28e3c05
|
||||
/tool-schema-catalog/deepseek-ai-dsh-plugin-manager:
|
||||
en: e0143916bb634762
|
||||
zh: e0143916bb634762
|
||||
@@ -60,14 +60,14 @@
|
||||
en: e713a4a11a15d13c
|
||||
zh: e713a4a11a15d13c
|
||||
/tool-schema-catalog/deepseek-ai-dsh-tool-ask-user/ask-user-question:
|
||||
en: 055268ba4dcd32f9
|
||||
zh: a1a3c4bfcbf698ed
|
||||
/tool-schema-catalog/deepseek-ai-dsh-tools:
|
||||
en: 76fbbf0fe38aef10
|
||||
zh: 76fbbf0fe38aef10
|
||||
/tool-schema-catalog/deepseek-ai-dsh-tools/run-code:
|
||||
en: a2368a9d8136276e
|
||||
zh: d1a4918fc45a7c87
|
||||
en: 2f86adf8ae823afb
|
||||
zh: a5dad3d821e75e55
|
||||
/tool-schema-catalog/deepseek-ai-dsh-tool-executor-ptc:
|
||||
en: 8c8643ef46fd075f
|
||||
zh: 8c8643ef46fd075f
|
||||
/tool-schema-catalog/deepseek-ai-dsh-tool-executor-ptc/run-code:
|
||||
en: a5d49232a604a2fb
|
||||
zh: 720040d11a3e31c2
|
||||
/tool-schema-catalog/deepseek-ai-dsh-plan-mode:
|
||||
en: b500b530845e26a9
|
||||
zh: b500b530845e26a9
|
||||
|
||||
@@ -20,7 +20,7 @@ This table connects model-visible tool names to the plugin package and service s
|
||||
| `@deepseek-ai/dsh-mcp-resources` | `list_mcp_resource_templates`, `list_mcp_resources`, `read_mcp_resource` | `ctx.tools`, `ctx.mcpResources` | `tool/call`, `tool/result` | - | - |
|
||||
| `@deepseek-ai/dsh-experimental-browser-use-stagehand-native` | `stagehand_act`, `stagehand_extract`, `stagehand_navigate`, `stagehand_observe`, `stagehand_screenshot`, `stagehand_tabs` | `ctx.browserUse`, `ctx.agents`, `ctx.tools`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | - |
|
||||
| `@deepseek-ai/dsh-tool-ask-user` | `ask_user_question` | `ctx.tools`, `ctx.userQuestions` | `tool/call`, `tool/result after an answer or timeout`, `late user/message` | - | ask_user_question keeps the original blocking behavior by default; set `mode: timed` to opt into a foreground timeout and pending result while the question remains answerable. In timed mode, `timeout: -1` keeps that call blocking indefinitely. |
|
||||
| `@deepseek-ai/dsh-tools` | `run_code` | `ctx.workingDirectory (Agent executions)`, `ctx.tools`, `ctx.ptcRuntime (execution time)`, `ctx.systemPrompt` | `tool/call`, `one tool/ptc-dispatch-start + tool/ptc-dispatch pair per bridged sub-call`, `tool/result` | - | Owned by the tool registry as a reserved transport outside filterable capability layers under `mode: ptc` (see the PTC mode Agent Note). Under `ptc` it is the registry's only wire contribution; the other visible capabilities are declared in a generated SDK section in the loaded runtime's language, and a program calls them through bindings scheduled under the native concurrency contract (submission-ordered starts and policy; concurrency-safe bodies overlap up to `maxParallelSubCalls`) that re-enter the complete guarded tool pipeline and link each nested execution to this outer result. |
|
||||
| `@deepseek-ai/dsh-tool-executor-ptc` | `run_code` | `ctx.workingDirectory (Agent executions)`, `ctx.tools`, `ctx.ptcRuntime`, `ctx.systemPrompt` | `tool/call`, `one tool/ptc-dispatch-start + tool/ptc-dispatch pair per bridged sub-call`, `tool/result` | - | The PTC executor exposes only run_code to the model and declares other visible capabilities in a generated SDK in the runtime’s language. Program bindings enter the shared guarded tool pipeline in submission order; concurrency-safe bodies overlap up to maxParallelSubCalls, and nested results remain linked to the outer program. |
|
||||
| `@deepseek-ai/dsh-plan-mode` | `exit_plan_mode` | `ctx.tools`, `ctx.systemPrompt`, `ctx.agents`, `ctx.userQuestions (execution time, opportunistic)` | `tool/call`, `plan/mode inactive on an approved review`, `tool/result` | - | exit_plan_mode stays in the model-facing schema while planning is inactive so transitions add no tool-catalog churn on top of the plan-policy change. Its execute path rejects calls outside plan mode; in plan mode it presents the plan over the user-questions seam (approve / keep planning with feedback), and approval logs plan mode inactive at the step boundary. |
|
||||
| `@deepseek-ai/dsh-tool-bash` | `bash` | `ctx.workingDirectory`, `ctx.tools`, `ctx.shell`, `ctx.systemPrompt`, `ctx.shellEnv`, `ctx.jobs for run_in_background and the job-backed foreground path` | `tool/call`, `tool/result` | - | The bash tool is the model-facing consumer of the bash executor seam. With a job registry composed every call registers with the generic `ctx.jobs` runtime as it starts, collected/stopped through the `job_*` tools from `@deepseek-ai/dsh-tool-jobs`; without one, or with `enableRunInBackground: false`, the tool registers a foreground-only schema without the `run_in_background` parameter. |
|
||||
| `@deepseek-ai/dsh-tool-present` | `present` | `ctx.workingDirectory`, `ctx.tools`, `ctx.fs`, `ctx.agents` | `tool/call`, `deliverables/presented after a successful final result`, `tool/result` | - | Deliveries belong to the calling Session; Web ui-deliverables supplies source-file opening and cards. |
|
||||
@@ -571,13 +571,13 @@ Source: [`packages/interaction/tool-ask-user/src/index.ts`](../packages/interact
|
||||
|
||||
ask_user_question keeps the original blocking behavior by default; set `mode: timed` to opt into a foreground timeout and pending result while the question remains answerable. In timed mode, `timeout: -1` keeps that call blocking indefinitely.
|
||||
|
||||
<a id="deepseek-aidsh-tools"></a>
|
||||
<a id="deepseek-aidsh-tool-executor-ptc"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tools`
|
||||
## `@deepseek-ai/dsh-tool-executor-ptc`
|
||||
|
||||
### `run_code`
|
||||
|
||||
Execute a TypeScript program against the available tools. Takes two required arguments: `code`, the program to execute, and `description`, a short summary of what the program does. Call tools as `await tools.name(args)` per the declarations in the system prompt. Curate the program output. Image-bearing subtool results are attached after the run.
|
||||
Execute a TypeScript program against the available tools. Takes two required arguments: `code`, the BODY of an async function (erasable syntax only; top-level `await` and `return` work), and `description`, a short summary of what the program does. Call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output — curate it. Image-bearing subtool results are attached after the run. The program is the body of an async TypeScript function; only erasable syntax is accepted, with no enum or namespaces. Type annotations are advisory. Top-level await and return are supported. Emit output with console.log(...) or return a lossless JSON value. Only printed values and the returned value become program output. Each call runs in a fresh Node process. Node APIs are available through await import(...). Relative paths use the supplied working directory; process.env starts empty. Direct filesystem access follows this execution's sandbox policy. Each program starts in the Session's current directory. Running programs keep their initial directory. A sandbox escalation approves this complete program for one execution only. Nested tools retain their own policies and approvals. Request wider access only after evidence of a denial. Earlier effects may already have completed: inspect them before explicitly retrying. Programs are never replayed automatically.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -585,7 +585,7 @@ Execute a TypeScript program against the available tools. Takes two required arg
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "The TypeScript program to execute, following this tool's execution instructions."
|
||||
"description": "The program: the body of an async TypeScript function."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
@@ -593,7 +593,7 @@ Execute a TypeScript program against the available tools. Takes two required arg
|
||||
},
|
||||
"timeoutMs": {
|
||||
"type": "number",
|
||||
"description": "Positive elapsed-time budget in milliseconds, capped by the deployment maximum."
|
||||
"description": "Positive elapsed-time budget in milliseconds, including nested tool and approval waits. Default 120000; capped at 600000. Zero does not disable the deadline."
|
||||
},
|
||||
"sandbox_permissions": {
|
||||
"type": "string",
|
||||
@@ -615,9 +615,9 @@ Execute a TypeScript program against the available tools. Takes two required arg
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/ptc.ts`](../packages/core/tools/src/ptc.ts)
|
||||
Source: [`packages/core/tool-executor-ptc/src/ptc.ts`](../packages/core/tool-executor-ptc/src/ptc.ts)
|
||||
|
||||
Owned by the tool registry as a reserved transport outside filterable capability layers under `mode: ptc` (see the PTC mode Agent Note). Under `ptc` it is the registry's only wire contribution; the other visible capabilities are declared in a generated SDK section in the loaded runtime's language, and a program calls them through bindings scheduled under the native concurrency contract (submission-ordered starts and policy; concurrency-safe bodies overlap up to `maxParallelSubCalls`) that re-enter the complete guarded tool pipeline and link each nested execution to this outer result.
|
||||
The PTC executor exposes only run_code to the model and declares other visible capabilities in a generated SDK in the runtime’s language. Program bindings enter the shared guarded tool pipeline in submission order; concurrency-safe bodies overlap up to maxParallelSubCalls, and nested results remain linked to the outer program.
|
||||
|
||||
<a id="deepseek-aidsh-plan-mode"></a>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
| `@deepseek-ai/dsh-mcp-resources` | `list_mcp_resource_templates`, `list_mcp_resources`, `read_mcp_resource` | `ctx.tools`, `ctx.mcpResources` | `tool/call`, `tool/result` | - | - |
|
||||
| `@deepseek-ai/dsh-experimental-browser-use-stagehand-native` | `stagehand_act`、`stagehand_extract`、`stagehand_navigate`、`stagehand_observe`、`stagehand_screenshot`、`stagehand_tabs` | `ctx.browserUse`、`ctx.agents`、`ctx.tools`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | - |
|
||||
| `@deepseek-ai/dsh-tool-ask-user` | `ask_user_question` | `ctx.tools`、`ctx.userQuestions` | `tool/call`、`tool/result after an answer or timeout`、`late user/message` | - | ask_user_question 默认保持原有阻塞行为;设置 `mode: timed` 后才启用前台超时与 pending 结果,同时问题仍可回答;timed 模式内 `timeout: -1` 让本次调用无限期阻塞。 |
|
||||
| `@deepseek-ai/dsh-tools` | `run_code` | `ctx.workingDirectory (Agent executions)`、`ctx.tools`、`ctx.ptcRuntime (execution time)`、`ctx.systemPrompt` | `tool/call`、`one tool/ptc-dispatch-start + tool/ptc-dispatch pair per bridged sub-call`、`tool/result` | - | 在 `mode: ptc` 下,它由工具注册表所有,作为可过滤能力层之外的保留传输机制(参见 PTC mode Agent Note)。在 `ptc` 下,它是注册表对协议格式(wire format)的唯一贡献;其他可见能力在使用已加载运行时语言生成的 SDK 章节中声明。程序通过 binding 调用这些能力,调用按照原生并发约定调度:启动顺序和策略遵循提交顺序,并发安全的函数体最多重叠执行 `maxParallelSubCalls` 个。调用会重新进入完整且受守卫保护的工具流水线,并将每个嵌套执行关联到此外层结果。 |
|
||||
| `@deepseek-ai/dsh-tool-executor-ptc` | `run_code` | `ctx.workingDirectory (Agent executions)`、`ctx.tools`、`ctx.ptcRuntime`、`ctx.systemPrompt` | `tool/call`、`one tool/ptc-dispatch-start + tool/ptc-dispatch pair per bridged sub-call`、`tool/result` | - | PTC 执行器只向模型公开 run_code,并在运行时语言生成的 SDK 中声明其他可见能力。程序绑定按提交顺序进入共享的受守卫工具流水线;并行安全的函数体最多重叠 maxParallelSubCalls 个,嵌套结果保持与外层程序关联。 |
|
||||
| `@deepseek-ai/dsh-plan-mode` | `exit_plan_mode` | `ctx.tools`、`ctx.systemPrompt`、`ctx.agents`、`ctx.userQuestions (execution time, opportunistic)` | `tool/call`、`plan/mode inactive on an approved review`、`tool/result` | - | 规划未激活时,exit_plan_mode 仍保留在面向模型的 schema 中,这样状态转换不会在规划策略变更之外额外造成工具目录变动。其执行路径会拒绝规划模式之外的调用;在规划模式下,它通过用户交互 seam 提交计划(批准/根据反馈继续规划),批准后会在步骤边界记录规划模式已停用。 |
|
||||
| `@deepseek-ai/dsh-tool-bash` | `bash` | `ctx.workingDirectory`、`ctx.tools`、`ctx.shell`、`ctx.systemPrompt`、`ctx.shellEnv`、`ctx.jobs for run_in_background and the job-backed foreground path` | `tool/call`、`tool/result` | - | bash 工具是 bash 执行器 seam 面向模型的消费方。组合中有 job 注册表时,每次调用一启动就注册到通用 `ctx.jobs` 运行时,并通过 `job_*` 工具(来自 `@deepseek-ai/dsh-tool-jobs`)收集/停止;没有注册表或 `enableRunInBackground: false` 时,工具注册不带 `run_in_background` 参数的纯前台 schema。 |
|
||||
| `@deepseek-ai/dsh-tool-present` | `present` | `ctx.workingDirectory`、`ctx.tools`, `ctx.fs`, `ctx.agents` | `tool/call`, `deliverables/presented 在成功的最终结果之后`, `tool/result` | - | 交付归调用方 Session 所有;Web ui-deliverables 提供源文件打开与卡片。 |
|
||||
@@ -41,7 +41,7 @@
|
||||
| `@deepseek-ai/dsh-tool-lsp` | `lsp` | `ctx.workingDirectory`、`ctx.tools`、`ctx.lsp`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,因此其模型可见 schema 在更换提供方时保持稳定。运行时要求已注册提供方,例如 `@deepseek-ai/dsh-lsp-stdio`;如果没有提供方,查询会返回结构化 `LSP_UNAVAILABLE` 错误,而不会改变 schema。 |
|
||||
| `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`、`ctx.workflowEngine`、`ctx.subagents`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents every fresh round)` | `tool/call`、`tool/result`、`workflow and child session events during execution` | - | 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 |
|
||||
| `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.workingDirectory`、`ctx.tools`、`ctx.agents`、`ctx.skills` | `tool/call`、`tool/result`、`user/message replacement catalogs via agent.inject()` | - | - |
|
||||
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`、`session_event_search`、`session_event_trace`、`session_search`、`session_trace` | `ctx.tools`、`ctx.systemPrompt`、`ctx.sessionQuery`、`ctx.agents`、`a calling Agent for workspace authority` | `tool/call`、`tool/result` | - | 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 |
|
||||
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`、`session_event_search`、`session_event_trace`、`session_search`、`session_trace` | `ctx.tools`、`ctx.systemPrompt`、`ctx.sessionQuery`、`a calling Agent for workspace authority` | `tool/call`、`tool/result` | - | 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 |
|
||||
| `@deepseek-ai/dsh-experimental-tool-subagent-oar` | `subagent_oar` | `ctx.tools`, `ctx.subagents` | `tool/call`, `tool/result`, `parent subagent catalog and completion notices` | - | subagent_oar 工具在为外部提供方配置的别名之间选择。本目录展示 Codex 和 Claude Code 别名;每个部署自行选择提供方。原生模型和权限设置由所选提供方的配置决定。 |
|
||||
| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`、`subagent` | `ctx.tools`、`ctx.subagents`、`ctx.systemPrompt`、`ctx.sessionProjections`、`用于模型发现和所选路由校验的 ctx.llm` | `tool/call`、`tool/result`、`child session events through the chosen provider` | `subagent`、`subagent_fork` | 加载时的 `toolName` 选择委派名称(默认为 `subagent`);`modelSelection` 增加可选路由字段。`modelDiscovery` 默认关闭,每个作用域由一个实例注册共享发现工具。Web 与 Desktop preset 启用 spawn 发现和路由字段,并为 `subagent_fork` 保持路由字段关闭。Host 设置服务为每个新顶层 Session 记录授权;子 Session 继承该授权。没有已记录策略时,发现和显式选择只允许当前父级路由。每次委派都会立即返回子代理 id;本地子代理接受后续消息,外部后端自动汇报单次执行结果。 |
|
||||
| `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`、`list_agents`、`send_message` | `ctx.tools`、`ctx.subagents`、`ctx.agents` | `tool/call`、`tool/result`、`child session events through ctx.subagents` | - | 这些是用于发现、中断托管 subagent 和向本地子代理发送消息的全局命名工具:绑定提供方的 `tool-subagent` 实例注册不同的委派工具;本包的一个实例注册 `send_message`、`interrupt_agent` 和 `list_agents`。 |
|
||||
@@ -575,13 +575,13 @@
|
||||
|
||||
ask_user_question 默认保持原有阻塞行为;设置 `mode: timed` 后才启用前台超时与 pending 结果,同时问题仍可回答;timed 模式内 `timeout: -1` 让本次调用无限期阻塞。
|
||||
|
||||
<a id="deepseek-aidsh-tools"></a>
|
||||
<a id="deepseek-aidsh-tool-executor-ptc"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-tools`
|
||||
## `@deepseek-ai/dsh-tool-executor-ptc`
|
||||
|
||||
### `run_code`
|
||||
|
||||
针对可用工具执行 TypeScript 程序。接受两个必填参数:`code`,要执行的程序;以及 `description`,简要说明该程序做什么。请根据系统提示词中的声明,以 `await tools.name(args)` 形式调用工具。请筛选程序输出。含图片的子工具结果会在运行结束后附加。
|
||||
针对可用工具执行 TypeScript 程序。接受两个必填参数:`code`,异步函数的函数体(仅限可擦除语法,支持顶层 `await` 和 `return`);以及 `description`,简要说明程序做什么。请按系统提示词中的声明,以 `await tools.name(args)` 调用工具。只有打印或返回的内容构成程序输出,请筛选这些内容。含图片的子工具结果会在运行结束后附加。程序是异步 TypeScript 函数的函数体,只接受可擦除语法,不支持 enum 或 namespace。类型标注只作提示。支持顶层 await 和 return。使用 console.log(...) 或返回无损 JSON 值来输出。只有打印值和返回值成为程序输出。每次调用在新的 Node 进程中运行,可通过 await import(...) 使用 Node API。相对路径以传入的工作目录为准;process.env 初始为空。直接文件系统访问遵循本次执行的沙箱策略。每个程序从 Session 的当前目录启动,运行中保留初始目录。沙箱提权只为本次完整程序执行授权。嵌套工具保留自身策略与审批。只有在获得拒绝证据后才请求更宽访问。先前效果可能已经发生,请在显式重试前检查。程序不会自动重放。
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -589,7 +589,7 @@ ask_user_question 默认保持原有阻塞行为;设置 `mode: timed` 后才
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "The TypeScript program to execute, following this tool's execution instructions."
|
||||
"description": "The program: the body of an async TypeScript function."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
@@ -597,7 +597,7 @@ ask_user_question 默认保持原有阻塞行为;设置 `mode: timed` 后才
|
||||
},
|
||||
"timeoutMs": {
|
||||
"type": "number",
|
||||
"description": "Positive elapsed-time budget in milliseconds, capped by the deployment maximum."
|
||||
"description": "Positive elapsed-time budget in milliseconds, including nested tool and approval waits. Default 120000; capped at 600000. Zero does not disable the deadline."
|
||||
},
|
||||
"sandbox_permissions": {
|
||||
"type": "string",
|
||||
@@ -619,9 +619,9 @@ ask_user_question 默认保持原有阻塞行为;设置 `mode: timed` 后才
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/core/tools/src/ptc.ts`](../packages/core/tools/src/ptc.ts)
|
||||
来源:[`packages/core/tool-executor-ptc/src/ptc.ts`](../packages/core/tool-executor-ptc/src/ptc.ts)
|
||||
|
||||
在 `mode: ptc` 下,它由工具注册表所有,作为可过滤能力层之外的保留传输机制(参见 PTC mode Agent Note)。在 `ptc` 下,它是注册表对协议格式的唯一贡献;其他可见能力在使用已加载运行时语言生成的 SDK 章节中声明。程序通过 binding 调用这些能力,调用按照原生并发约定调度:启动顺序和策略遵循提交顺序,并发安全的函数体最多重叠执行 `maxParallelSubCalls` 个。调用会重新进入完整且受守卫保护的工具流水线,并将每个嵌套执行关联到此外层结果。
|
||||
PTC 执行器只向模型公开 run_code,并在运行时语言生成的 SDK 中声明其他可见能力。程序绑定按提交顺序进入共享的受守卫工具流水线;并行安全的函数体最多重叠 maxParallelSubCalls 个,嵌套结果保持与外层程序关联。
|
||||
|
||||
<a id="deepseek-aidsh-plan-mode"></a>
|
||||
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
en: 41d772192075e133
|
||||
zh: 0eb190f00f396176
|
||||
/tool-execution-pipeline:
|
||||
en: f2811b12640c6f8e
|
||||
zh: 9e0323523dcbb04c
|
||||
en: a1103f6055f81a4b
|
||||
zh: 6eefe6bfa59b1692
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# Tool Execution Pipeline
|
||||
|
||||
This graph shows where policy, hooks, sandboxing, filesystem guards, result rewriting, final-outcome observation, and UI rendering run without changing the loop. The `tools/pre-execute` waterfall runs first, monotonic guards run next, and the `tools/execute` and `tools/post-execute` waterfalls follow; the three waterfalls may transform a call. Definition-owned `projectContent` installs prepared content before post-execute; `finalizeContent` and `tools/result` run afterward.
|
||||
Built-in executors own raw batch parsing, scheduling, cancellation, and Session call/result logging. This graph shows where their shared invocation pipeline applies policy, hooks, sandboxing, filesystem guards, result rewriting, final-outcome observation, and UI rendering without changing the loop. The `tools/pre-execute` waterfall runs first, monotonic guards run next, and the `tools/execute` and `tools/post-execute` waterfalls follow; the three waterfalls may transform a call. Definition-owned `projectContent` installs prepared content before post-execute; `finalizeContent` and `tools/result` run afterward.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -20,14 +20,15 @@ flowchart TD
|
||||
owned["Tool-owned session events<br/><code>todo/write</code>, <code>fs/observed</code>, <code>hook/invoked</code>, <code>hook/result</code>, <code>tool/ptc-dispatch</code>"]
|
||||
project["ToolDefinition.projectContent<br/>execution-prepared text and images"]
|
||||
post["<code>tools/post-execute</code> waterfall<br/>accept, block, replace, add context"]
|
||||
normalized["Registry outer normalization<br/>pipeline/result snapshot throws become isError"]
|
||||
normalized["Invocation pipeline normalization<br/>pipeline/result snapshot throws become isError"]
|
||||
finalize["ToolDefinition.finalizeContent<br/>last content-only invariant"]
|
||||
final["<code>tools/result</code> synchronous notification<br/>frozen authoritative outcome"]
|
||||
context["Active-batch additionalContexts FIFO<br/>injected user/message after recorded tool results"]
|
||||
toolResult["Session event: <code>tool/result</code><br/>single model-facing outcome"]
|
||||
allResults["Tool batch settled<br/>recorded tool/result events complete"]
|
||||
presentResult["UI completed card<br/>presentResult(args, result)"]
|
||||
model --> toolCall
|
||||
executor["Selected ToolExecutor.execute<br/>raw batch, Agent, optional logging step"]
|
||||
model --> executor --> toolCall
|
||||
toolCall --> presentCall
|
||||
toolCall --> pre
|
||||
pre -->|allow| guards
|
||||
@@ -60,6 +61,6 @@ flowchart TD
|
||||
allResults --> context
|
||||
```
|
||||
|
||||
Filesystem read-before-edit checks stay below `tool-fs` on `fs/*` events. Generic pre/post waterfalls host hooks and approval policy; `ctx.approval` resolves asks before monotonic guards, and owner policy that must not be reordered remains a registered guard. Around-dispatch concerns such as timeouts wrap `tools/execute`. The registry losslessly snapshots the candidate result and normalizes a snapshot failure before the visible definition's snapshotted `finalizeContent` callback enforces its synchronous content-only invariant. `tools/result` then observes the immutable, lossless-JSON outcome. This lets hooks span tool families without coupling the tools to one policy service. PTC mode sends both the reserved `run_code` transport and its serialized sub-calls through the pipeline; sub-calls carry the parent token, log `tool/ptc-dispatch`, return denials as binding rejections, and omit `additionalContexts` to preserve call/result adjacency.
|
||||
Filesystem read-before-edit checks stay below `tool-fs` on `fs/*` events. Generic pre/post waterfalls host hooks and approval policy; `ctx.approval` resolves asks before monotonic guards, and owner policy that must not be reordered remains a registered guard. Around-dispatch concerns such as timeouts wrap `tools/execute`. The pipeline losslessly snapshots the candidate result and normalizes a snapshot failure before the visible definition's snapshotted `finalizeContent` callback enforces its synchronous content-only invariant. `tools/result` then observes the immutable, lossless-JSON outcome. This lets hooks span tool families without coupling the tools to one policy service. PTC mode sends both the reserved `run_code` transport and its ordered sub-calls through the pipeline; sub-calls carry the parent token, log `tool/ptc-dispatch`, return denials as binding rejections, and omit `additionalContexts` to preserve call/result adjacency.
|
||||
|
||||
Maintenance mode: curated Mermaid flow; exact tool schemas and event signatures live in generated catalogs.
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
[English](tool-execution-pipeline.md) | 中文
|
||||
|
||||
此图展示策略、钩子、沙箱、文件系统守卫、结果重写、最终结果观察和 UI 渲染在不改变循环的情况下何时运行。`tools/pre-execute` waterfall(瀑布式事件)首先运行,随后是单调守卫,然后运行 `tools/execute` 和 `tools/post-execute` waterfall;这三个 waterfall 可以改写一次调用。由定义自身控制的 `projectContent` 在执行后策略之前安装已准备内容;`finalizeContent` 和 `tools/result` 在此之后运行。
|
||||
内置执行器负责原始批次解析、调度、取消和 Session 调用/结果日志。此图展示其共享调用流水线如何执行策略、钩子、沙箱、文件系统守卫、结果改写、最终结果观测和 UI 呈现,而无需改动循环。`tools/pre-execute` 瀑布先执行,然后是单调守卫,再是 `tools/execute` 和 `tools/post-execute` 瀑布;三个瀑布可以转换调用。定义拥有的 `projectContent` 在后置策略之前安装准备好的内容,`finalizeContent` 和 `tools/result` 在之后执行。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -22,14 +22,15 @@ flowchart TD
|
||||
owned["Tool-owned session events<br/><code>todo/write</code>, <code>fs/observed</code>, <code>hook/invoked</code>, <code>hook/result</code>, <code>tool/ptc-dispatch</code>"]
|
||||
project["ToolDefinition.projectContent<br/>execution-prepared text and images"]
|
||||
post["<code>tools/post-execute</code> waterfall<br/>accept, block, replace, add context"]
|
||||
normalized["Registry outer normalization<br/>pipeline/result snapshot throws become isError"]
|
||||
normalized["Invocation pipeline normalization<br/>pipeline/result snapshot throws become isError"]
|
||||
finalize["ToolDefinition.finalizeContent<br/>last content-only invariant"]
|
||||
final["<code>tools/result</code> synchronous notification<br/>frozen authoritative outcome"]
|
||||
context["Active-batch additionalContexts FIFO<br/>injected user/message after recorded tool results"]
|
||||
toolResult["Session event: <code>tool/result</code><br/>single model-facing outcome"]
|
||||
allResults["Tool batch settled<br/>recorded tool/result events complete"]
|
||||
presentResult["UI completed card<br/>presentResult(args, result)"]
|
||||
model --> toolCall
|
||||
executor["Selected ToolExecutor.execute<br/>raw batch, Agent, optional logging step"]
|
||||
model --> executor --> toolCall
|
||||
toolCall --> presentCall
|
||||
toolCall --> pre
|
||||
pre -->|allow| guards
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
en: d202616bf6e03fa4
|
||||
zh: cc276adda4b952be
|
||||
/sdk-desktop-tools-and-context/change:
|
||||
en: 85ac2825c52e2503
|
||||
zh: fd6fdbdca131c778
|
||||
en: ef89799953ecb457
|
||||
zh: 86fdb487b9a15a6f
|
||||
/sdk-desktop-tools-and-context/migration:
|
||||
en: 9caef4f8b153622a
|
||||
zh: 1b4901f5b18b72fd
|
||||
@@ -9,7 +9,7 @@ English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
The existing `sdk` profile now includes `present`, `ask_user_question`, schedule tools, file-reference guidance and time context. It does not start a Web server. Standard tool calling remains the default; `DSH_TOOLS_MODE=ptc` selects programmatic tool calling in the same profile. `sdk-minimal` is unchanged.
|
||||
The existing `sdk` profile now includes `present`, `ask_user_question`, schedule tools, file-reference guidance and time context. It does not start a Web server. Native tool execution remains the default; select PTC through an [executor overlay](../tool-executor-plugins/guide.md). `sdk-minimal` is unchanged.
|
||||
|
||||
## Migration
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ description: 现有 SDK profile 包含原生桌面工具和模型上下文。
|
||||
|
||||
## 变更
|
||||
|
||||
现有 `sdk` profile 现在包含 `present`、`ask_user_question`、定时任务工具、文件引用说明和时间上下文。它不启动 Web server。默认仍使用标准工具调用;`DSH_TOOLS_MODE=ptc` 在同一 profile 中选择程序化工具调用。`sdk-minimal` 保持不变。
|
||||
现有 `sdk` profile 现在包含 `present`、`ask_user_question`、定时任务工具、文件引用说明和时间上下文。它不启动 Web server。默认仍使用原生工具执行;通过[执行器 overlay](../tool-executor-plugins/guide.zh.md) 选择 PTC。`sdk-minimal` 保持不变。
|
||||
|
||||
## 迁移
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading
|
||||
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/tool-executor-plugins/guide.md
|
||||
/:
|
||||
en: 3b1ca9e0f78709e0
|
||||
zh: 13f23adcc722f319
|
||||
/mount-a-tool-executor:
|
||||
en: 73002a2963b9ea27
|
||||
zh: a67ea382d7c70c61
|
||||
/mount-a-tool-executor/change:
|
||||
en: fac0b27c9452c4f2
|
||||
zh: 2f53fd013ff460ba
|
||||
/mount-a-tool-executor/migration:
|
||||
en: 4d91c0177d06f4bd
|
||||
zh: e93047b58a5aef4c
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Tool execution modes move from dsh-tools configuration into explicit executor plugins."
|
||||
---
|
||||
|
||||
# Mount a tool executor
|
||||
|
||||
English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
`@deepseek-ai/dsh-tools` keeps tool registration and executor selection, but rejects the removed `mode` and `maxParallelSubCalls` configuration fields at load time. Native and PTC execution require `@deepseek-ai/dsh-tool-executor-native` or `@deepseek-ai/dsh-tool-executor-ptc`. Shipped profiles mount an executor; custom compositions must add one. The existing `dsh-agent-tool-presentation` selector remains supported but is deprecated. Enabled `tool-executor-native` and `tool-executor-ptc` rows are required at startup; invalid executor configuration now stops startup. Web, headless, and SDK no longer read `DSH_TOOLS_MODE`; all inherit native execution from base.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Keep the `dsh-tools` row and remove its execution configuration. Mount one native or PTC executor in the intended deployment or preset scope. For shipped profile patches, target the executor row instead of the `tools` row.
|
||||
2. Move `maxParallelSubCalls` to the PTC executor configuration and mount a compatible `ctx.ptcRuntime` provider. The executor declares this service as a required injection; a missing runtime stops startup, and unloading the runtime withdraws the executor. `agent-loop.maxParallelToolCalls` and saved overrides stay in place with default `10`. The loop forwards the current limit to each batch; live edits apply to the next batch instead of the next tool group.
|
||||
3. Custom executors implement `describe` and `execute`. Programmatic callers pass raw `calls` and `signal`, optional `agent`, and optional `log: { turn, step }`; read single-call outcomes from `results`. Omit `log` outside a committed model step.
|
||||
4. Import PTC SDK renderers and `CodeRunFailedError` from `@deepseek-ai/dsh-tool-executor-ptc`. Run a task with the selected interaction mode and confirm its tool results appear in the Session.
|
||||
5. Import `ToolExecutionPipeline` and `executeToolBatch` from `@deepseek-ai/dsh-tools/pipeline`. Complete calls, including single calls, use batches; custom schedulers call `prepare`, `dispatch`, and `complete` directly. Add `@deepseek-ai/dsh-tool-testkit` as a development dependency for tool fixtures and import them from that package. Neither is exported by the tool registry entry.
|
||||
6. Import shared dispatch events and the `ptc-mode` message-source declaration from `@deepseek-ai/dsh-tool-executor-ptc/types`; Client code uses its `/client` re-export. Host policy extensions use `import type` from `@deepseek-ai/dsh-tool-executor-ptc` for `PtcDispatchLog` and `tools/ptc-dispatch-log`.
|
||||
|
||||
7. Remove `DSH_TOOLS_MODE` from launch environments. For PTC, save the following as `ptc.yml` and pass it with `--patch`; native execution needs no overlay. The same patch works with `--profile web` and `--profile sdk`; TypeScript and Python SDK clients pass its path through `patches`. Confirm that the model receives only `run_code` in PTC mode.
|
||||
|
||||
```yaml
|
||||
- id: tool-executor-native
|
||||
disabled: true
|
||||
|
||||
- id: tool-executor-ptc
|
||||
disabled: false
|
||||
```
|
||||
|
||||
```bash
|
||||
dsh --profile headless --patch ./ptc.yml "task"
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "工具执行模式从 dsh-tools 配置移至显式执行器插件。"
|
||||
---
|
||||
|
||||
# 挂载工具执行器
|
||||
|
||||
[English](guide.md) | 中文
|
||||
|
||||
## 变更
|
||||
|
||||
`@deepseek-ai/dsh-tools` 保留工具注册和执行器选择,但加载时会拒绝已移除的 `mode` 和 `maxParallelSubCalls` 配置字段。原生和 PTC 执行分别要求 `@deepseek-ai/dsh-tool-executor-native` 或 `@deepseek-ai/dsh-tool-executor-ptc`。内置 profile 已挂载执行器,自定义组合必须添加一个。现有 `dsh-agent-tool-presentation` 选择器仍受支持,但已弃用。启用的 `tool-executor-native` 和 `tool-executor-ptc` 条目属于启动必需项;无效的执行器配置会终止启动。Web、headless 与 SDK 不再读取 `DSH_TOOLS_MODE`,均继承 base 的原生执行。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 保留 `dsh-tools` 条目并移除其执行配置。在目标部署或预设作用域挂载一个原生或 PTC 执行器。内置 profile 的补丁应修改执行器条目,而非 `tools` 条目。
|
||||
2. 把 `maxParallelSubCalls` 移到 PTC 执行器配置,并挂载兼容的 `ctx.ptcRuntime` 提供方。执行器将该服务声明为必需注入;缺少运行时会阻止启动,卸载运行时会撤回执行器。`agent-loop.maxParallelToolCalls` 和已保存的覆盖值保留原位,默认值为 `10`。循环向每个批次传入当前上限;实时修改从下一个批次生效,不再从下一个工具组生效。
|
||||
3. 自定义执行器实现 `describe` 和 `execute`。程序调用方传入原始 `calls` 和 `signal`,以及可选的 `agent` 和 `log: { turn, step }`;从 `results` 读取单次结果。不属于已提交模型步骤的调用应省略 `log`。
|
||||
4. 从 `@deepseek-ai/dsh-tool-executor-ptc` 导入 PTC SDK 渲染器和 `CodeRunFailedError`。用所选交互模式运行任务,确认工具结果出现在 Session 中。
|
||||
5. 从 `@deepseek-ai/dsh-tools/pipeline` 导入 `ToolExecutionPipeline` 和 `executeToolBatch`。完整执行(包括单次调用)使用批次;自定义调度器直接调用 `prepare`、`dispatch` 和 `complete`。把 `@deepseek-ai/dsh-tool-testkit` 添加为开发依赖,并从该包导入工具 fixture。工具注册表主入口不再导出这些成员。
|
||||
6. 从 `@deepseek-ai/dsh-tool-executor-ptc/types` 导入共享分派事件与 `ptc-mode` 消息来源声明;Client 代码使用其 `/client` 重导出。Host 策略扩展通过 `@deepseek-ai/dsh-tool-executor-ptc` 的 `import type` 获取 `PtcDispatchLog` 与 `tools/ptc-dispatch-log`。
|
||||
|
||||
7. 从启动环境中移除 `DSH_TOOLS_MODE`。需要 PTC 时,将以下内容保存为 `ptc.yml` 并通过 `--patch` 加载;原生执行无需 overlay。同一补丁也适用于 `--profile web` 和 `--profile sdk`;TypeScript 和 Python SDK 客户端通过 `patches` 传入其路径。确认 PTC 模式下模型只收到 `run_code`。
|
||||
|
||||
```yaml
|
||||
- id: tool-executor-native
|
||||
disabled: true
|
||||
|
||||
- id: tool-executor-ptc
|
||||
disabled: false
|
||||
```
|
||||
|
||||
```bash
|
||||
dsh --profile headless --patch ./ptc.yml "task"
|
||||
```
|
||||
Loaded 100 of 970 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user