feat(ptc-runtime): expose Script syntax and state retention

This commit is contained in:
_Kerman committed 2026-10-20 23:16:24 +08:00
1 parent 9e6692931c
commit 1f45e38279
17 files changed
+63 -49

No files matched your search

+2 -2
View File
@@ -6,8 +6,8 @@
en: 337a6580d7571274
zh: f4ae98899120d122
/ptc-runtime/the-run-request-in-result-out:
en: 0305ed1d4f8bc618
zh: fcfeb156574b5779
en: 6dfa7da8b13a4f17
zh: 09a3c8c4922239ef
/ptc-runtime/bindings-host-functions-as-program-globals:
en: 182147ddf388c600
zh: c0a7d77602c78bcd
+7 -5
View File
@@ -19,9 +19,11 @@ interface PtcRunRequest {
/**
* The program source, in the runtime's {@link ../index.ts | language}. It
* follows the provider's programFormat: an async function body supports
* top-level `await` and `return`; a REPL supports top-level declarations,
* `await`, and a final expression. The completion value becomes
* {@link PtcRunResult.value}.
* top-level `await` and `return`; REPL and Script programs support top-level
* declarations, `await`, and a final expression, but not top-level `return`.
* The Script provider lowers top-level await; its executionInstructions and
* documentation define retained-binding semantics. The completion value
* becomes {@link PtcRunResult.value}.
*/
program: string
/**
@@ -84,7 +86,7 @@ interface PtcRunResult {
/** Applied file policy and observed denial, when the provider enforces file policy. */
sandbox?: PtcRunSandbox
/**
* The program's completion value (a return or final REPL expression), when it ran to
* The program's completion value (a return or final REPL/Script expression), when it ran to
* completion and the value crossed the runtime's lossless-JSON boundary.
* Invalid or over-limit completions fail the run instead of substituting a
* rendered string; a failed or value-less run leaves this absent.
@@ -101,7 +103,7 @@ interface PtcRunResult {
}
```
`programFormat` distinguishes async function bodies from REPL statements. `stateOwner` is an in-process object identity for optional retained memory; distinct objects remain isolated. Consumers await `release(owner)` when that owner ends; cleanup failures reject that call. Omitted owners are one-shot, and stateless providers ignore ownership. The [persistent Node provider](../../packages/ptc-runtime/ptc-runtime-node/README.md#persistent-repl) defines reset and recovery behavior; no retained object enters the durable Session format.
`programFormat` distinguishes async function bodies, REPL statements, and scripts. REPL and Script programs accept top-level `await`, declarations, and a final expression; top-level `return` is not supported. The Node Script provider lowers top-level await and awaits the completion value; its [declaration limitations](../../packages/ptc-runtime/ptc-runtime-node/README.md#known-limitations-and-deferred-work) apply to transformed programs. `retainsState` reports memory retention independently of source syntax. `stateOwner` is an in-process object identity for optional retained memory; distinct objects remain isolated. Consumers await `release(owner)` when that owner ends; cleanup failures reject that call. Omitted owners are one-shot, and stateless providers ignore ownership. The [persistent Node provider](../../packages/ptc-runtime/ptc-runtime-node/README.md#persistent-repl) defines reset and recovery behavior; no retained object enters the durable Session format.
## Bindings: host functions as program globals
+7 -5
View File
@@ -19,9 +19,11 @@ interface PtcRunRequest {
/**
* The program source, in the runtime's {@link ../index.ts | language}. It
* follows the provider's programFormat: an async function body supports
* top-level `await` and `return`; a REPL supports top-level declarations,
* `await`, and a final expression. The completion value becomes
* {@link PtcRunResult.value}.
* top-level `await` and `return`; REPL and Script programs support top-level
* declarations, `await`, and a final expression, but not top-level `return`.
* The Script provider lowers top-level await; its executionInstructions and
* documentation define retained-binding semantics. The completion value
* becomes {@link PtcRunResult.value}.
*/
program: string
/**
@@ -84,7 +86,7 @@ interface PtcRunResult {
/** Applied file policy and observed denial, when the provider enforces file policy. */
sandbox?: PtcRunSandbox
/**
* The program's completion value (a return or final REPL expression), when it ran to
* The program's completion value (a return or final REPL/Script expression), when it ran to
* completion and the value crossed the runtime's lossless-JSON boundary.
* Invalid or over-limit completions fail the run instead of substituting a
* rendered string; a failed or value-less run leaves this absent.
@@ -101,7 +103,7 @@ interface PtcRunResult {
}
```
`programFormat` 区分异步函数体与 REPL 语句。`stateOwner` 是标识可选保留内存的进程内对象身份;不同对象相互隔离。消费者在所有者结束时等待 `release(owner)`;清理失败时该调用拒绝。省略所有者时仅执行一次,无状态提供方忽略所有权。[持久 Node 提供方](../../packages/ptc-runtime/ptc-runtime-node/README.zh.md#persistent-repl)定义重置和恢复行为;保留对象不会进入持久 Session 格式。
`programFormat` 区分异步函数体、REPL 语句与脚本。REPL 与 Script 程序接受顶层 `await`、声明和末尾表达式,不支持顶层 `return`。Node Script 提供方转换顶层 await 并等待完成值;其[声明限制](../../packages/ptc-runtime/ptc-runtime-node/README.zh.md#known-limitations-and-deferred-work)适用于转换后的程序。`retainsState` 独立于源码语法报告是否保留内存。`stateOwner` 是标识可选保留内存的进程内对象身份;不同对象相互隔离。消费者在所有者结束时等待 `release(owner)`;清理失败时该调用拒绝。省略所有者时仅执行一次,无状态提供方忽略所有权。[持久 Node 提供方](../../packages/ptc-runtime/ptc-runtime-node/README.zh.md#persistent-repl)定义重置和恢复行为;保留对象不会进入持久 Session 格式。
## 绑定:宿主函数作为程序全局变量
+6 -6
View File
@@ -45,8 +45,8 @@
en: dc44a88997777988
zh: 56454aeace1c8b77
/deepseek-ai-dsh-tools/understand-the-implementation/ptc-mode:
en: 387700aa396f7ca2
zh: d440b283027e4fbd
en: 1bac667d5e2dba60
zh: 766b31cd4e356e04
/deepseek-ai-dsh-tools/understand-the-implementation/extension-points:
en: c2a14d6f22bc9428
zh: 89c1414fca465931
@@ -72,8 +72,8 @@
en: eaefd7303f22977d
zh: 9c425f9501128224
/deepseek-ai-dsh-tools/model-experience/ptc-mode-schema-and-system-prompt/what-the-model-sees:
en: 3e170a222d746e98
zh: 1ea442fc59874cc5
en: 0c6441978f5d9bfc
zh: 87553f9bb87ce9b6
/deepseek-ai-dsh-tools/model-experience/ptc-mode-schema-and-system-prompt/what-the-model-sees/typescript-ptc-mode-sdk-instructions-with-bash:
en: 3a8df15e4ae32f9e
zh: fc4a800ba363e835
@@ -96,8 +96,8 @@
en: 2fbf2175168e8244
zh: ad59a120b54a0996
/deepseek-ai-dsh-tools/known-limitations-and-deferred-work:
en: 4a412f89b8a71b5a
zh: 803d995b036d5dbf
en: c42ac2124a619bdc
zh: ec142b05a3912a49
/deepseek-ai-dsh-tools/known-limitations-and-deferred-work/dev-note:
en: e67f633dc6fe7773
zh: 3bb0c20c93f16f98
+3 -3
View File
@@ -133,7 +133,7 @@ New sub-calls use `<parent>:ptc:<n>` ids. Consumers treat these ids as opaque an
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.
`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 both 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.
`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.
<a id="extension-points"></a>
### Extension points
@@ -179,7 +179,7 @@ Prefix-stable while visible definitions and their order are unchanged. Registrat
#### What the model sees
PTC mode exposes the generated [`run_code` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tools), 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. The TypeScript instructions use a return-value example for function-body runtimes and a printed-output example for REPL runtimes. They 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.
PTC mode exposes the generated [`run_code` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tools), 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.
##### TypeScript PTC mode SDK instructions with bash
@@ -235,7 +235,7 @@ These limits define when the registry needs special care. They are current packa
- **`timeoutMs` on a definition is declarative only** — the registry never enforces deadlines; enforcement requires the `@deepseek-ai/dsh-tool-call-timeout-policy` wrapper.
- **PTC mode's SDK language follows the one loaded runtime, and a presentation is per agent rather than per tool** — `mode: ptc` rejects prompt assembly unless `ctx.ptcRuntime.language` has 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_code` output has the worker's configurable hard cap.
- **State depends on the runtime**: the default backend starts fresh; a REPL backend retains 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.
- **State depends on the runtime**: the default backend starts fresh; the Node REPL and Script mode with `scriptPersistence: true` retain 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.
`defineTool()`, registry schema projection, and system-prompt assembly preserve `deferLoading: true`. The marker requests deferred definition loading and does not imply a `tool-addition` record; the [LLM package](../../../packages/llm/llm/README.md#known-limitations-and-deferred-work) documents provider enforcement limits.
+3 -3
View File
@@ -133,7 +133,7 @@ ctx.tools.register(defineTool({
成功且包含图片的子调用结果会成为延后的 user-message 上下文,其 `source.kind` 为 `ptc-mode`。其他 additional context 保留其生产工具的归属。
当已挂载运行时支持覆盖时,`run_code` 接受 `timeoutMs`;其 schema 报告配置的默认值和上限以及运行时使用说明。Node 默认值为 120,000 ms,上限为 600,000 ms,包含嵌套工具和审批等待。更宽的 `sandbox_permissions` 模式要求非空 `justification`,并在程序启动前获得审批。schema 提示模型使用当前用户的语言撰写理由。授权仅用于该次完整执行;常驻 Session 策略与嵌套工具保留各自权限。程序不会自动重放:显式重试被拒程序前,应检查先前已发生的效果。 保留状态的 PTC 环境遵循会话文件策略。PTC 观察已提交的 Session 模式变化,并立即取消两种 Node 模式下受影响的调用。后续 PTC 调用等待这些调用的嵌套工具清理后,再解析最新策略。运行时负责进程失效和清理,权限设置保持同步。单次提权省略状态所有者,在临时环境中执行;普通调用仍可访问原环境的变量。
当已挂载运行时支持覆盖时,`run_code` 接受 `timeoutMs`;其 schema 报告配置的默认值和上限以及运行时使用说明。Node 默认值为 120,000 ms,上限为 600,000 ms,包含嵌套工具和审批等待。更宽的 `sandbox_permissions` 模式要求非空 `justification`,并在程序启动前获得审批。schema 提示模型使用当前用户的语言撰写理由。授权仅用于该次完整执行;常驻 Session 策略与嵌套工具保留各自权限。程序不会自动重放:显式重试被拒程序前,应检查先前已发生的效果。 保留状态的 PTC 环境遵循会话文件策略。PTC 观察已提交的 Session 模式变化,并立即取消所有 Node 模式下受影响的调用。后续 PTC 调用等待这些调用的嵌套工具清理后,再解析最新策略。运行时负责进程失效和清理,权限设置保持同步。单次提权省略状态所有者,在临时环境中执行;普通调用仍可访问原环境的变量。
<a id="extension-points"></a>
### 扩展点
@@ -179,7 +179,7 @@ ctx.tools.register(defineTool({
#### 模型看到什么
PTC mode 会公开生成的 [`run_code` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tools)、下方 SDK 说明,以及按所加载运行时语言生成的精确 SDK 块。两种运行时语言都将 `code` 列在 `description` 前;这是呈现顺序,不强制 JSON 成员顺序。TypeScript 说明对函数体运行时使用返回值示例,对 REPL 运行时使用打印输出示例,并把生成声明明确标为只能在程序内使用的绑定。当当前 `bash` 参数 schema 接受示例参数时,说明还会给出以 `run_code` 包住 `tools.bash(...)` 的完整调用。`tools:sdk` 段使用 first-party 顺序 5000,并关闭提示词变量插值,使两种运行时语言都原样保留工具描述和 schema 中的 `{{…}}` 文本。在 `ptc` 下,提示词还会带上处于更早 first-party 顺序的 `tools:ptc-only` 规则,让模型先读到「可以调用哪些工具」再读「每个工具做什么」。
PTC mode 会公开生成的 [`run_code` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tools)、下方 SDK 说明,以及按所加载运行时语言生成的精确 SDK 块。两种运行时语言都将 `code` 列在 `description` 前;这是呈现顺序,不强制 JSON 成员顺序。REPL 与 Script 运行时共用通用工具描述和 SDK 说明;语法与状态规则由各自的 `executionInstructions` 提供。TypeScript bash 示例对函数体运行时返回值,对 REPL 和 Script 运行时打印输出。说明将生成声明明确标为只能在程序内使用的绑定。当当前 `bash` 参数 schema 接受示例参数时,说明还会给出以 `run_code` 包住 `tools.bash(...)` 的完整调用。`tools:sdk` 段使用 first-party 顺序 5000,并关闭提示词变量插值,使两种运行时语言都原样保留工具描述和 schema 中的 `{{…}}` 文本。在 `ptc` 下,提示词还会带上处于更早 first-party 顺序的 `tools:ptc-only` 规则,让模型先读到「可以调用哪些工具」再读「每个工具做什么」。
##### 带 bash 的 TypeScript PTC mode SDK 说明
@@ -235,7 +235,7 @@ Program-only SDK bindings:
- **定义中的 `timeoutMs` 仅作声明之用**:注册表绝不会强制执行截止时间;要强制执行,必须使用 `@deepseek-ai/dsh-tool-call-timeout-policy` 包装层。
- **PTC mode 的 SDK 语言由当前加载的运行时决定,且呈现方式按 agent 而非按工具**:`mode: ptc` 会拒绝组装提示词,除非 `ctx.ptcRuntime.language` 有已注册的 SDK 渲染器;同一个 agent 内不能让一个工具仅使用 Native,而另一个仅使用 PTC。
- **PTC mode 中间值只存在于执行局部,且没有字节上限**:它们无法从会话回放重建,并可能耗尽进程或 worker 内存;只有外层 `run_code` 输出受 worker 可配置的硬上限约束。
- **状态由运行时决定**:默认后端每次重新开始;REPL 后端按存活 Agent 保留内存。Agent 销毁时等待环境释放。重启与执行失败可能清除内存;模型说明会指导重新创建缺失变量。程序与结果仍写入 Session 日志,不序列化运行中的对象。
- **状态由运行时决定**:默认后端每次重新开始;Node REPL 和启用 `scriptPersistence: true` 的 Script 模式按存活 Agent 保留内存。Agent 销毁时等待环境释放。重启与执行失败可能清除内存;模型说明会指导重新创建缺失变量。程序与结果仍写入 Session 日志,不序列化运行中的对象。
`defineTool()`、注册表模式投影和系统提示组装会保留 `deferLoading: true`。该标记请求延迟加载工具定义,并不意味着存在 `tool-addition` 记录;提供方执行语义的限制见 [LLM 包](../../../packages/llm/llm/README.zh.md#known-limitations-and-deferred-work)。
+2 -2
View File
@@ -59,10 +59,10 @@ declare module '@deepseek-ai/dsh-llm' {
*/
const PTC_ONLY_INSTRUCTION = `\`${RUN_CODE_NAME}\` is the only tool you can call directly — a tool call naming any other tool fails. Reach every tool the SDK declares below from inside the program.`
const SDK_RENDERERS: Record<string, (schemas: ToolSdkSchema[], programFormat: 'function-body' | 'repl') => string> = {
const SDK_RENDERERS: Record<string, (schemas: ToolSdkSchema[], programFormat: PtcRuntime['programFormat']) => string> = {
typescript: renderToolsSdk,
python: renderToolsSdkPy,
} satisfies Record<PtcSdkLanguage, (schemas: ToolSdkSchema[], programFormat: 'function-body' | 'repl') => string>
} satisfies Record<PtcSdkLanguage, (schemas: ToolSdkSchema[], programFormat: PtcRuntime['programFormat']) => string>
export {
defineTool,
+6 -5
View File
@@ -7,6 +7,7 @@
*/
import type { ToolSchema } from '@deepseek-ai/dsh-llm'
import type { PtcRuntime } from '@deepseek-ai/dsh-ptc-runtime'
import { assertSupportedJsonSchema } from './json-schema.ts'
import type { JsonSchemaNode, JsonSchemaScalar } from './json-schema.ts'
/** Internal PTC mode projection: the model-facing schema plus the canonical output schema. */
@@ -247,7 +248,7 @@ export function jsonSchemaToTs(schema: unknown, indent = 0): string {
}
/** Render the argument and call instructions for the selected execution syntax. */
function renderSdkInstructions(programFormat: 'function-body' | 'repl'): string {
function renderSdkInstructions(programFormat: PtcRuntime['programFormat']): string {
const programDescription = programFormat === 'function-body'
? 'the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped)'
: 'the program to execute'
@@ -257,7 +258,7 @@ function renderSdkInstructions(programFormat: 'function-body' | 'repl'): string
}
/** Render tool execution and output instructions for the selected execution syntax. */
function renderSdkProgramInstructions(programFormat: 'function-body' | 'repl'): string {
function renderSdkProgramInstructions(programFormat: PtcRuntime['programFormat']): string {
const outputInstruction = programFormat === 'function-body'
? 'Emit results with `return` and/or `console.log(...)`. Only what you print or return is program output.'
: 'Only values emitted as program output enter the conversation.'
@@ -279,7 +280,7 @@ function acceptsExampleString(schema: JsonSchemaNode | undefined, value: string)
}
/** Render the bash example only when its literal arguments satisfy the current parameter schema. */
function renderBashExample(schemas: ToolSdkSchema[], programFormat: 'function-body' | 'repl'): string {
function renderBashExample(schemas: ToolSdkSchema[], programFormat: PtcRuntime['programFormat']): string {
const bash = schemas.find(schema => schema.name === 'bash')
if (bash === undefined) return ''
const parameters = bash.parameters as JsonSchemaNode
@@ -306,10 +307,10 @@ function renderBashExample(schemas: ToolSdkSchema[], programFormat: 'function-bo
* by name, so the input never carries a duplicate.
* @param schemas - the tool schemas to declare (the caller excludes
* `run_code` itself).
* @param programFormat - Runtime syntax; function bodies support returning a result, REPLs print it.
* @param programFormat - Runtime syntax selecting function-body, REPL, or Script instructions and examples.
* @returns the complete section text.
*/
export function renderToolsSdk(schemas: ToolSdkSchema[], programFormat: 'function-body' | 'repl' = 'function-body'): string {
export function renderToolsSdk(schemas: ToolSdkSchema[], programFormat: PtcRuntime['programFormat'] = 'function-body'): string {
const sorted = [...schemas].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
const argsMembers: string[] = []
const outputMembers: string[] = []
@@ -9,8 +9,8 @@
en: cced8c691b58657a
zh: 3da9cdf76a1a07ff
/deepseek-ai-dsh-ptc-runtime/summary:
en: b04917e62d63c7ff
zh: 12cb9f38cbf8ee3f
en: 6bf8184a933be9fa
zh: 19fe0bb198744a77
/deepseek-ai-dsh-ptc-runtime/table-of-contents:
en: d152484eb41ac6b4
zh: 09388d293f9be9cb
@@ -18,8 +18,8 @@
en: 7e5ebf7420c13af4
zh: 9ad1e056e794ca4a
/deepseek-ai-dsh-ptc-runtime/use-this-package/run-a-program:
en: c856760ebc15d59e
zh: dc093083b29794e0
en: ef030201a816ac84
zh: 2c3f6acfb57ad506
/deepseek-ai-dsh-ptc-runtime/use-this-package/choose-a-backend:
en: fc0d515f0c3664f3
zh: 0a1b646b5cf92232
+2 -2
View File
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
## Summary
Use `dsh-ptc-runtime` to execute model programs against host-provided asynchronous functions. Requests return lossless JSON, captured logs, or structured failures; rejected promises indicate caller misuse. Providers isolate distinct state owners and declare whether source is an async function body or REPL statements. A provider may retain memory for an explicit owner until release; it never restores that memory from a Session. Language and isolation descriptors identify syntax and execution substrate, not security guarantees.
Use `dsh-ptc-runtime` to execute model programs against host-provided asynchronous functions. Requests return lossless JSON, captured logs, or structured failures; rejected promises indicate caller misuse. Providers isolate distinct state owners and declare whether source is an async function body, REPL statements, or a script. `retainsState` reports whether a provider retains memory for an explicit owner until release; it never restores that memory from a Session. Language and isolation descriptors identify syntax and execution substrate, not security guarantees.
## Table of Contents
@@ -29,7 +29,7 @@ Choose this package when you compose a deployment that executes model-written pr
### Run a program
Call `resolve(request)` followed by `run(spec)` with a program and binding namespaces. Resolution validates cwd, timeout and sandbox choices and applies provider defaults. `programFormat` selects an async function body with top-level `await` and `return`, or REPL statements with top-level declarations, `await`, and a final expression. Lossless-JSON completion becomes `result.value`, text becomes `result.logs`, and failures become `result.error`.
Call `resolve(request)` followed by `run(spec)` with a program and binding namespaces. Resolution validates cwd, timeout and sandbox choices and applies provider defaults. `programFormat` selects an async function body with top-level `await` and `return`, or REPL/Script statements with top-level declarations, `await`, and a final expression. The Node Script provider lowers top-level await and awaits the completion value; its [declaration limitations](../ptc-runtime-node/README.md#known-limitations-and-deferred-work) apply to transformed programs. Lossless-JSON completion becomes `result.value`, text becomes `result.logs`, and failures become `result.error`.
```text
const spec = ctx.ptcRuntime.resolve({
@@ -9,7 +9,7 @@ kind: "package-reference"
## 概述
使用 `dsh-ptc-runtime` 执行调用宿主异步函数的模型程序。请求返回无损 JSON、捕获日志或结构化失败;Promise 拒绝表示调用方误用。提供方隔离不同状态所有者,并声明源码是异步函数体还是 REPL 语句。提供方可以为显式所有者保留内存,直到释放,但不会从 Session 恢复这些内存。语言与隔离描述符标识语法和执行基底,不提供安全保证。
使用 `dsh-ptc-runtime` 执行调用宿主异步函数的模型程序。请求返回无损 JSON、捕获日志或结构化失败;Promise 拒绝表示调用方误用。提供方隔离不同状态所有者,并声明源码是异步函数体、REPL 语句还是脚本。`retainsState` 报告提供方是否为显式所有者保留内存,直到释放,但不会从 Session 恢复这些内存。语言与隔离描述符标识语法和执行基底,不提供安全保证。
## 目录
@@ -29,7 +29,7 @@ kind: "package-reference"
### 运行一个程序
传入程序和绑定命名空间,依次调用 `resolve(request)` 和 `run(spec)`。解析阶段验证 cwd、超时与沙盒选项,并应用提供方默认值。`programFormat` 选择支持顶层 `await`、`return` 的异步函数体,或支持顶层声明、`await` 和末尾表达式的 REPL 语句。无损 JSON 完成值进入 `result.value`,文本进入 `result.logs`,失败进入 `result.error`。
传入程序和绑定命名空间,依次调用 `resolve(request)` 和 `run(spec)`。解析阶段验证 cwd、超时与沙盒选项,并应用提供方默认值。`programFormat` 选择支持顶层 `await`、`return` 的异步函数体,或支持顶层声明、`await` 和末尾表达式的 REPL/Script 语句。Node Script 提供方转换顶层 await 并等待完成值;其[声明限制](../ptc-runtime-node/README.zh.md#known-limitations-and-deferred-work)适用于转换后的程序。无损 JSON 完成值进入 `result.value`,文本进入 `result.logs`,失败进入 `result.error`。
```text
const spec = ctx.ptcRuntime.resolve({
@@ -122,7 +122,10 @@ export abstract class PtcRuntime extends Service {
abstract readonly isolation: string
/** Source evaluation form, independent of whether the provider retains state for an owner. */
get programFormat(): 'function-body' | 'repl' { return 'function-body' }
get programFormat(): 'function-body' | 'repl' | 'script' { return 'function-body' }
/** Whether this provider retains program memory across runs for the same stateOwner. */
get retainsState(): boolean { return false }
/**
* Release an owner's retained environment and await its execution resources.
@@ -74,9 +74,11 @@ export interface PtcRunRequest {
/**
* The program source, in the runtime's {@link ../index.ts | language}. It
* follows the provider's programFormat: an async function body supports
* top-level `await` and `return`; a REPL supports top-level declarations,
* `await`, and a final expression. The completion value becomes
* {@link PtcRunResult.value}.
* top-level `await` and `return`; REPL and Script programs support top-level
* declarations, `await`, and a final expression, but not top-level `return`.
* The Script provider lowers top-level await; its executionInstructions and
* documentation define retained-binding semantics. The completion value
* becomes {@link PtcRunResult.value}.
*/
program: string
/**
@@ -152,7 +154,7 @@ export interface PtcRunResult {
/** Applied file policy and observed denial, when the provider enforces file policy. */
sandbox?: PtcRunSandbox
/**
* The program's completion value (a return or final REPL expression), when it ran to
* The program's completion value (a return or final REPL/Script expression), when it ran to
* completion and the value crossed the runtime's lossless-JSON boundary.
* Invalid or over-limit completions fail the run instead of substituting a
* rendered string; a failed or value-less run leaves this absent.
@@ -24,8 +24,8 @@
en: 0626f232df315a7d
zh: 573e9a12bc69ac6d
/deepseek-ai-dsh-workflow-ptc/use-this-package/file-policy-and-cancellation:
en: 5a13be99e2c2ca39
zh: ff16dbe6bc83a75d
en: 7c0287dbaef61267
zh: 874c6efa4b39ed60
/deepseek-ai-dsh-workflow-ptc/understand-the-implementation:
en: ff9de0f5f3423c12
zh: 4c5ae9845d452cc1
+1 -1
View File
@@ -56,7 +56,7 @@ Invalid metadata, an unparseable body, an unavailable provider route or a per-ru
### File policy and cancellation
The engine captures the calling Session's effective working directory and standing file policy separately. The PTC process and every child started by that workflow retain the captured directory when the parent later moves. A runtime without confinement is accepted only for `danger-full-access`; `read-only` and `workspace-write` fail before execution. Node in-memory mode executes an async wrapper in a temporary environment, so workflow-local variables never join the Agent's retained REPL. The VM retains the documented helper API, but it is not a security boundary: code that reaches Node follows the selected runtime's file policy. The program-visible environment is empty. Network access is not restricted by the file policy.
The engine captures the calling Session's effective working directory and standing file policy separately. The PTC process and every child started by that workflow retain the captured directory when the parent later moves. A runtime without confinement is accepted only for `danger-full-access`; `read-only` and `workspace-write` fail before execution. Node in-memory mode executes an async wrapper in a temporary environment, so workflow-local variables never join the Agent's retained REPL. Script mode uses an async function expression whose Promise completion carries the workflow result. The VM retains the documented helper API, but it is not a security boundary: code that reaches Node follows the selected runtime's file policy. The program-visible environment is empty. Network access is not restricted by the file policy.
The workflow requests `timeoutMs: null` from PTC. Its initial VM slice still has `syncTimeoutMs`, and a caller's abort signal still applies, including an enclosing tool deadline. Cancellation immediately aborts the PTC process and pending or active subagents. The caller must dispose every run and await child cleanup; there is no separate workflow cleanup timer.
+1 -1
View File
@@ -56,7 +56,7 @@ Node PTC 提供方的 `maxPendingCalls` 也限制工作流并发:子 agent 启
### 文件策略与取消
引擎分别捕获调用 Session 的有效工作目录与常设文件策略。父级之后切换目录时,PTC 进程及该工作流随后启动的每个子级都保留捕获的目录。不支持文件约束的运行时只允许用于 `danger-full-access`;`read-only` 和 `workspace-write` 在执行前失败。Node 内存保留模式在临时环境中执行异步包装函数,因此工作流局部变量不会进入 Agent 保留的 REPL。VM 保留文档说明的辅助 API,但它不是安全边界:触达 Node 的代码遵循所选运行时的文件策略。程序可见的环境为空。文件策略不限制网络访问。
引擎分别捕获调用 Session 的有效工作目录与常设文件策略。父级之后切换目录时,PTC 进程及该工作流随后启动的每个子级都保留捕获的目录。不支持文件约束的运行时只允许用于 `danger-full-access`;`read-only` 和 `workspace-write` 在执行前失败。Node 内存保留模式在临时环境中执行异步包装函数,因此工作流局部变量不会进入 Agent 保留的 REPL。Script 模式使用 async 函数表达式,通过其 Promise 完成值返回工作流结果。VM 保留文档说明的辅助 API,但它不是安全边界:触达 Node 的代码遵循所选运行时的文件策略。程序可见的环境为空。文件策略不限制网络访问。
工作流向 PTC 请求 `timeoutMs: null`。最初的 VM 片段仍受 `syncTimeoutMs` 限制,调用方的中止信号仍然生效,包括外层工具的截止。取消立即中止 PTC 进程及待启动或活跃的 subagent。调用方必须释放每次运行并等待子 agent 清理;不另设工作流清理定时器。
+5 -1
View File
@@ -288,7 +288,11 @@ export class PtcWorkflowRun implements WorkflowRun {
throw new Error(`workflow runtime cannot enforce the ${this.policy.mode} file policy`)
}
const outcome = await this.runtime.run(this.runtime.resolve({
program: this.runtime.programFormat === 'repl' ? `await (async () => {\n${PROGRAM}\n})()` : PROGRAM,
program: {
'function-body': PROGRAM,
repl: `await (async () => {\n${PROGRAM}\n})()`,
script: `(async () => {\n${PROGRAM}\n})()`,
}[this.runtime.programFormat],
bindings: [{ global: 'workflowHost', functions: this.bindings() }],
cwd,
...this.runtime.sandboxMode === undefined ? {} : { sandboxPolicy: this.policy },