# Conflicts: # packages/client/ui-agent-team/package.json # packages/client/ui-brand-official/package.json # packages/client/ui-open-in-app/package.json # packages/client/ui-settings-web-search/package.json # packages/experimental/agent-team-profile/package.json # packages/team/agent-team/package.json # packages/web/web-search-exa/package.json # packages/web/web-search-perplexity/package.json
description, kind
| description | kind |
|---|---|
| Program-based tool execution, generated SDKs, and nested-call limits. | package-reference |
@deepseek-ai/dsh-tool-executor-ptc
English | 中文
Summary
Use this executor when models should call tools through run_code programs. Mount a compatible PTC runtime and tool registry first. Scoped restrictions determine the generated SDK; only run_code is directly callable. Configure the total tool-call limit per program and concurrency for parallel-safe subcalls.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Add this row to a composition with dsh-tools mounted. The nearest scoped executor selects tool behavior; one scope permits only one executor.
- name: '@deepseek-ai/dsh-tool-executor-ptc'
config:
maxSubCallsPerMinute: 1024
maxParallelSubCalls: 10
Root run_code calls are exclusive and execute serially. maxParallelSubCalls limits parallel-safe nested calls within each program and defaults to 10; it must be a positive integer, with 1 selecting serial execution. Exclusive calls form barriers.
maxSubCallsPerMinute defaults to 1024 and must be a positive integer. Each run_code gets floor(resolved timeoutMs / 60000 × maxSubCallsPerMinute) tool-call attempts: the default Node timeout of two minutes allows 2048. Runtime defaults and timeout caps apply before this calculation; no deadline means no finite call allowance. This is a total allowance, not a rolling window, so calls may happen in a burst. All tool bindings share the count, including queued calls, invalid arguments, and failed tools. The next attempt terminates the entire program through the runtime abort path, cancels active subcalls, and abandons queued calls before returning CODE_RUN_FAILED. As with a timeout, catching a binding error cannot keep the program running; retained runtime state is discarded. Completed tool effects remain, and the next program starts a fresh count.
This package declares ctx.ptcRuntime and ctx.systemPrompt as required injections; Agent-owned programs need ctx.workingDirectory. The executor activates only after its runtime is available and withdraws when that runtime unloads. An enabled PTC executor without a runtime stops application startup. A withdrawn PTC selection never falls back to native execution.
Shared dispatch events and the ptc-mode message-source declaration live in @deepseek-ai/dsh-tool-executor-ptc/types; Client code imports the same declarations through @deepseek-ai/dsh-tool-executor-ptc/client. Both entries exclude Host service declarations. Host policy extensions use import type from the package entry for PtcDispatchLog and tools/ptc-dispatch-log without mounting the executor.
Understand the implementation
Implementation internals — click to expand
The executor receives the entire raw call batch and owns parsing, scheduling, cancellation, and optional model-step logging. It reuses the shared invocation pipeline for policy, tool bodies, and result notifications. After abort, it waits for started work and returns ordered error results for skipped calls. Unloading the executor aborts active Agent-owned programs whose runtime supports sandboxing or retains state, and waits for their nested calls to settle. Accepted batches still settle through that executor, potentially with cancellation errors.
PTC mode
The PTC executor exposes the reserved run_code transport and a deterministic SDK generated in the loaded runtime's language. Each SDK binding captures a frozen ToolSchema and passes it through the scheduler to its execution context. Before policy, a started call records only pairing ids, name, and normalized arguments; its settle event preserves the rendered result, optional presentation metadata, and structured error. Metadata is projected from that call’s canonical value and frozen; it changes neither the program value nor model content. Description and parameters remain transient and never enter Session events or SDK output. Calls are scheduled through a per-run pool that reuses the native concurrency contract. Under ptc alone, a model-direct call naming a program-only SDK tool resolves to UNKNOWN_TOOL before policy — the announced surface and the callable surface stay the same. Intermediate binding values are execution-local; only the outer run_code result has a hard size cap.
New sub-calls use <parent>:ptc:<n> ids. Consumers treat these ids as opaque and correlate events by exact equality; restored historical ids retain their original bytes. The PTC mode decision owns durable naming and restoration rules.
Successful image-bearing subcall results become deferred user-message context with source.kind set to ptc-mode. Other additional contexts retain their producing tool's attribution.
When the caller cancels and the runtime reports abort, run_code waits for cleanup and returns the native tool cancellation result: AbortError / ABORTED, with Error: tool call aborted as its content. Retained runtimes append their cancellation diagnostic, including whether variables were preserved or cleared. The Agent records the specific cancellation cause in turn/end, including a hook's reason. Other runtime failures retain CODE_RUN_FAILED and their diagnostics, even if the caller also cancels. Cancellation can discard retained runtime state and does not undo completed tool effects.
run_code accepts timeoutMs when the mounted runtime supports an override; its schema reports the configured default and maximum, and the runtime's usage instructions. The Node default is 120,000 ms with a 600,000 ms cap, including nested tool and approval waits. A wider sandbox_permissions mode requires a non-empty justification and approval before the program starts. The schema asks the model to write that reason in the current user's language. The grant applies to that complete execution; standing Session policy and nested tools retain their own authority. Programs are never replayed automatically: inspect earlier effects before explicitly retrying a denied program. Retained PTC environments follow the standing file policy. PTC observes committed Session mode changes and immediately cancels affected calls in all Node modes. Later PTC calls wait for their nested-tool cleanup before resolving the latest policy. The runtime owns process invalidation and cleanup; permission setters remain synchronous. One-time escalations omit the state owner and complete in a temporary environment; standing variables remain available to ordinary calls.
Custom host integrations retain their PtcExecutor instance and call reset(agent) to clear that Agent's environment; reset is not a model tool or SDK binding. It requires a state-retaining runtime, cancels active calls, invokes release(agent), and waits for process and started nested-tool cleanup without requiring the program to respond. Before admitting new programs, it queues Program environment reset; retained variables cleared. Completed tool effects remain. The notice is logged when consumed; cancellation or Agent disposal can discard it after state is cleared. Concurrent resets share cleanup. Missing or unsupported runtimes reject without blocking admission. Cleanup or notice-admission failure throws CodeResetFailedError; later programs report CodeRunFailedError with host-reset guidance until an explicit retry succeeds. Reset does not undo completed tool effects.
src/index.ts— Scoped registration, tool descriptions, batch execution and host environment reset.src/ptc-calls.ts— Call admission and cancellation; reset waits for runtime release and nested-tool cleanup before admitting new calls.
Further Exploration
Model Experience
PTC mode schema and system prompt
What the model sees
PTC mode exposes the generated run_code schema, the SDK instructions below, and the generated exact SDK block for the loaded runtime's language. Both runtime languages list code before description; this is presentation order, not an enforced JSON member order. REPL and Script runtimes share the generic tool description and SDK instructions; their executionInstructions supply syntax and state rules. The TypeScript bash example returns a value for function-body runtimes, and prints output for REPL and Script runtimes. The instructions identify generated declarations as program-only bindings. When the current bash parameter schema accepts the example arguments, they also show a complete run_code call around tools.bash(...). The tools:sdk section uses first-party order 5000 and disables prompt-variable interpolation, preserving literal {{…}} text in tool descriptions and schemas for both runtime languages. Under ptc, the prompt also carries the tools:ptc-only rule earlier in the first-party order, so the model reads which tools it may call before it reads what each one is for. Exhausting the tool-call allowance returns a failed run_code result with the limit, rejected call number, termination notice, and possible infinite-loop warning. Runtime cleanup diagnostics and captured output remain visible.
TypeScript PTC mode SDK instructions with bash
## Writing code for run_code
`run_code` takes two required arguments: `code`, the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped), and `description`, a short summary of what the program does. The declarations below are SDK bindings for this program. A declaration does not make its name a directly callable tool; only names supplied as separate tool schemas may be called directly. When no separate `bash` schema is supplied, invoke a declared `bash` binding inside `run_code`:
`run_code({ code: "return await tools.bash({ description: 'Show current directory', command: 'pwd' })", description: "Show current directory" })`
Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.
- Emit results with `return` and/or `console.log(...)`. Only what you print or return is program output. A successful tool result containing an image is attached after the run so you can inspect it on the next step; every other intermediate result stays out of the conversation, so extract just what you need.
Program-only SDK bindings:
Tool-call allowance exhausted
Error: code run failed (abort): run_code exceeded its limit of 2048 tool calls (1024 per minute of its timeout); call 2049 was not dispatched. The run_code program may contain an infinite loop. Check loop termination or split the work into smaller run_code calls.
Token effect
Fixed per-request cost proportional to the visible definitions. PTC mode trades end-tool schemas for generated SDK text plus one transport schema rather than promising a universal reduction. The allowance adds no SDK or schema text; its diagnostic contributes tokens through the failed run's result.
KV Cache effect
Prefix-stable while the PTC mode selection, generated SDK, transport schema, and visible tool set are unchanged. Mode or filter changes may invalidate reuse from the first changed prompt or schema token. Changing maxSubCallsPerMinute does not change prompt or schema tokens.
Known Limitations and Deferred Work
These constraints apply to the host integration and accepted calls.
- No built-in reset control — the shipped Loader plugin does not expose its executor instance through a service, GUI control or SDK endpoint. Hosts needing reset must mount and retain
PtcExecutorin their own composition; that integration owns retries after a failed reset. - PTC mode's SDK language follows the one loaded runtime, and a presentation is per agent rather than per tool — PTC execution rejects prompt assembly unless
ctx.ptcRuntime.languagehas a registered SDK renderer; within one agent no tool can be native-only while another is ptc-only. - PTC mode intermediate values are execution-local and unbounded by bytes — they cannot be reconstructed from session replay and may exhaust process or worker memory; only the outer
run_codeoutput has the worker's configurable hard cap. - State depends on the runtime: the default backend starts fresh; the Node REPL and Script mode with
scriptPersistence: trueretain memory per live Agent. Agent disposal awaits release. Restart and execution failures can clear memory; model-visible guidance explains how to recreate missing variables. Programs and results remain in the Session log, without serializing live objects.
Dev Note
Working context for maintainers — click to expand
None.