返回源码地图

packages/ptc-runtime/ptc-runtime/src/types.ts

main snapshot · da00f7f5358f · 正文引用章节 11;完整原文可核对,不声称全文件人工逐行审计

完整原文供逐行核对;页面收录不代表每行都经过人工语义审核。MIT 许可见 许可证。

1/**
2 * Vocabulary types for the PTC execution seam: what a caller hands a
3 * {@link ../index.ts | PtcRuntime} and what it gets back. Pure types — no
4 * runtime code lives here.
5 *
6 * @module @deepseek-ai/dsh-ptc-runtime/src/types
7 */
8
9import type { SandboxEnforcement, SandboxExecutionPolicy, SandboxMode } from '@deepseek-ai/dsh-sandbox'
10
11/**
12 * One host-side function exposed to the program as an async callable. The
13 * runtime bridges calls to it (possibly across a serialization boundary), so
14 * `args` and the resolution value MUST be lossless JSON. A runtime rejects a
15 * lossy or non-cloneable value with a descriptive error rather than corrupting
16 * the run. No seam-level byte cap applies to a binding resolution. A rejection
17 * of this function surfaces inside the program as a rejection of the
18 * corresponding call.
19 */
20export type PtcBindingFunction = (args: unknown) => Promise<PtcJsonValue>
21
22/** A lossless JSON value transferable through the dependency-light Service Definition. */
23export type PtcJsonValue = null | boolean | number | string | PtcJsonValue[] | { [key: string]: PtcJsonValue }
24
25/**
26 * Program-visible typed rejection for one binding namespace. The runtime
27 * injects a real error constructor under `name`; rejected member calls become
28 * its instances and expose the exact member name through
29 * `memberNameProperty`. Both strings are runtime data rather than knowledge
30 * of a particular consumer such as PTC mode.
31 */
32export interface PtcBindingErrorClass {
33 /** Constructor global and resulting `Error.name`; same portable identifier rule as {@link PtcBindingNamespace.global}. */
34 name: string
35 /**
36 * Non-empty own property for the member name. The portable exclusion set is
37 * `RESERVED_ERROR_MEMBERS` plus dunder-form names (`__x__`, non-empty
38 * middle), enforced identically by every backend; any other name —
39 * identifiers or not — is accepted everywhere.
40 */
41 memberNameProperty: string
42}
43
44/**
45 * A named group of {@link PtcBindingFunction}s the runtime exposes to the
46 * program as one global object (e.g. `tools`). Function names are arbitrary
47 * strings — a runtime must treat names like `__proto__` or `constructor` as
48 * ordinary own properties (null-prototype construction), never as prototype
49 * collisions.
50 */
51export interface PtcBindingNamespace {
52 /**
53 * The global identifier the program sees. Must match the LANGUAGE-PORTABLE
54 * identifier subset `[A-Za-z_][A-Za-z0-9_]*` and no language's reserved
55 * words, so the same namespace list works against every backend regardless
56 * of `language` — a JS-only spelling like `$tools` is rejected by design,
57 * not just by the Python backend. Names that satisfy the identifier rule but
58 * name a backend-owned slot (`RESERVED_BINDING_GLOBALS`, e.g. `console`,
59 * `__dsh_main__`) are also refused everywhere; see its declaration for the
60 * exact set and why each entry is reserved.
61 */
62 global: string
63 /** The callable members, keyed by the exact name the program calls. */
64 functions: Record<string, PtcBindingFunction>
65 /** Optional program-visible typed rejection contract for this namespace. */
66 errorClass?: PtcBindingErrorClass
67}
68
69/**
70 * Caller inputs for one program. The provider's resolve method validates supported
71 * options and supplies directory, deadline, and authority before execution.
72 */
73export interface PtcRunRequest {
74 /**
75 * The program source, in the runtime's {@link ../index.ts | language}. It
76 * runs as the body of an async function: top-level `await` and `return`
77 * are available, and the completion value becomes
78 * {@link PtcRunResult.value}.
79 */
80 program: string
81 /** Host functions exposed to the program, one global object per namespace. */
82 bindings: PtcBindingNamespace[]
83 /** Working directory in the mounted filesystem and subprocess execution world. */
84 cwd?: string
85 /**
86 * Elapsed execution budget in milliseconds. Omission uses provider defaults;
87 * null requests no deadline. Providers validate and cap numeric budgets or reject unsupported choices.
88 */
89 timeoutMs?: number | null
90 /** Resolved authority for this execution. Providers without confinement reject an explicit policy. */
91 sandboxPolicy?: SandboxExecutionPolicy
92 /**
93 * Abort the run: the runtime stops the program (hard, even mid-loop) and
94 * resolves with a {@link PtcRunFailure} of kind `'abort'`. In-flight
95 * binding calls are the CALLER's to settle — the runtime only stops asking.
96 */
97 signal?: AbortSignal
98}
99
100/** Fully resolved execution inputs; run never supplies a missing directory or deadline choice. */
101export interface PtcRunSpec extends PtcRunRequest {
102 /** Absolute directory in the provider's execution world. */
103 cwd: string
104 /** Positive finite elapsed budget in milliseconds after provider capping, or null for no deadline. */
105 timeoutMs: number | null
106}
107
108/** File confinement applied to a program, independently of its terminal outcome. */
109export interface PtcRunSandbox {
110 /** File-effect mode used for this execution. */
111 mode: SandboxMode
112 /** Program failure text matched backend diagnostics; not enforcement proof or an exhaustive denial record. */
113 denied: boolean
114 /** Completeness reported by the selected confining backend; absent for full access. */
115 enforcement?: SandboxEnforcement
116}
117
118/**
119 * Why a run failed. The kinds are orthogonal outcomes reported independently
120 * (per docs/defensive-patterns.md): a budget expiry is not an exception, an
121 * abort is not a timeout, and a substrate death is neither.
122 *
123 * - `'exception'` — the program threw or failed to parse/transform.
124 * - `'timeout'` — an implementation-owned budget expired; the message says which.
125 * - `'abort'` — {@link PtcRunRequest.signal} fired.
126 * - `'worker-exit'` — the execution substrate died without settling (e.g. OOM).
127 * - `'invalid-output'` — the completion value was not lossless JSON.
128 * - `'output-limit'` — the serialized outer logs/value/diagnostic exceeded the configured cap.
129 * - `'protocol'` — the program sent invalid or over-budget control traffic.
130 * - `'sandbox-unavailable'` — required confinement could not be established.
131 */
132export interface PtcRunFailure {
133 /** The failure class (see the interface doc for each kind's meaning). */
134 kind: 'exception' | 'timeout' | 'abort' | 'worker-exit' | 'invalid-output' | 'output-limit' | 'protocol' | 'sandbox-unavailable'
135 /** Human-readable detail, suitable for feeding back to a model to self-correct. */
136 message: string
137}
138
139/**
140 * The outcome of one run. An error is a FIELD on a resolved result, never a
141 * rejection of `run()` — reporting a failed program is the caller's job, not
142 * an exception path.
143 */
144export interface PtcRunResult {
145 /** Applied file policy and observed denial, when the provider enforces file policy. */
146 sandbox?: PtcRunSandbox
147 /**
148 * The program's completion value (its top-level `return`), when it ran to
149 * completion and the value crossed the runtime's lossless-JSON boundary.
150 * Invalid or over-limit completions fail the run instead of substituting a
151 * rendered string; a failed or value-less run leaves this absent.
152 */
153 value?: PtcJsonValue
154 /**
155 * Captured text. Each source channel preserves emission order; interleaving
156 * across independent channels is backend-dependent. Bounded only as part of
157 * the outer result.
158 */
159 logs: string[]
160 /** Present iff the run failed; see {@link PtcRunFailure} for the taxonomy. */
161 error?: PtcRunFailure
162}