@animalabs/agent-framework 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/src/code-execution/index.d.ts +14 -0
  2. package/dist/src/code-execution/index.d.ts.map +1 -0
  3. package/dist/src/code-execution/index.js +13 -0
  4. package/dist/src/code-execution/index.js.map +1 -0
  5. package/dist/src/code-execution/py-runner.d.ts +91 -0
  6. package/dist/src/code-execution/py-runner.d.ts.map +1 -0
  7. package/dist/src/code-execution/py-runner.js +364 -0
  8. package/dist/src/code-execution/py-runner.js.map +1 -0
  9. package/dist/src/code-execution/runtime-py.d.ts +32 -0
  10. package/dist/src/code-execution/runtime-py.d.ts.map +1 -0
  11. package/dist/src/code-execution/runtime-py.js +265 -0
  12. package/dist/src/code-execution/runtime-py.js.map +1 -0
  13. package/dist/src/code-execution/tool-definition.d.ts +16 -0
  14. package/dist/src/code-execution/tool-definition.d.ts.map +1 -0
  15. package/dist/src/code-execution/tool-definition.js +45 -0
  16. package/dist/src/code-execution/tool-definition.js.map +1 -0
  17. package/dist/src/framework.d.ts +43 -1
  18. package/dist/src/framework.d.ts.map +1 -1
  19. package/dist/src/framework.js +274 -26
  20. package/dist/src/framework.js.map +1 -1
  21. package/dist/src/index.d.ts +2 -0
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/index.js +4 -0
  24. package/dist/src/index.js.map +1 -1
  25. package/dist/src/mcpl/channel-registry.d.ts +12 -0
  26. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  27. package/dist/src/mcpl/channel-registry.js +45 -0
  28. package/dist/src/mcpl/channel-registry.js.map +1 -1
  29. package/dist/src/mcpl/prose-grammar.d.ts +24 -0
  30. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -0
  31. package/dist/src/mcpl/prose-grammar.js +33 -0
  32. package/dist/src/mcpl/prose-grammar.js.map +1 -0
  33. package/dist/src/mcpl/prose-stream-router.d.ts +58 -0
  34. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -0
  35. package/dist/src/mcpl/prose-stream-router.js +168 -0
  36. package/dist/src/mcpl/prose-stream-router.js.map +1 -0
  37. package/dist/src/types/framework.d.ts +33 -0
  38. package/dist/src/types/framework.d.ts.map +1 -1
  39. package/dist/test/code-execution.test.d.ts +11 -0
  40. package/dist/test/code-execution.test.d.ts.map +1 -0
  41. package/dist/test/code-execution.test.js +412 -0
  42. package/dist/test/code-execution.test.js.map +1 -0
  43. package/dist/test/prose-stream-router.test.d.ts +2 -0
  44. package/dist/test/prose-stream-router.test.d.ts.map +1 -0
  45. package/dist/test/prose-stream-router.test.js +87 -0
  46. package/dist/test/prose-stream-router.test.js.map +1 -0
  47. package/dist/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +1 -1
  49. package/src/code-execution/index.ts +19 -0
  50. package/src/code-execution/py-runner.ts +433 -0
  51. package/src/code-execution/runtime-py.ts +265 -0
  52. package/src/code-execution/tool-definition.ts +52 -0
  53. package/src/framework.ts +307 -28
  54. package/src/index.ts +17 -0
  55. package/src/mcpl/channel-registry.ts +53 -0
  56. package/src/mcpl/prose-grammar.ts +40 -0
  57. package/src/mcpl/prose-stream-router.ts +161 -0
  58. package/src/types/framework.ts +35 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Client-side programmatic tool calling (PTC) for the connectome native stack.
3
+ *
4
+ * Mirrors the surface Anthropic's server-side PTC was trained on
5
+ * (code_execution tool + tools exposed as async python functions), but runs
6
+ * the interpreter on the host and dispatches inner tool calls in-process
7
+ * through the framework's own tool routing — intermediate results never
8
+ * enter the model's context; the full trace stays on-box.
9
+ */
10
+ export { PyRunner, buildInjectedTools } from './py-runner.js';
11
+ export type { InjectedTool, ExecResult, PyRunnerOptions, ScriptToolCallHandler, } from './py-runner.js';
12
+ export { PYTHON_RUNTIME_SOURCE } from './runtime-py.js';
13
+ export { buildCodeExecutionToolDefinition, CODE_EXECUTION_TOOL_NAME } from './tool-definition.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code-execution/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EACV,YAAY,EACZ,UAAU,EACV,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Client-side programmatic tool calling (PTC) for the connectome native stack.
3
+ *
4
+ * Mirrors the surface Anthropic's server-side PTC was trained on
5
+ * (code_execution tool + tools exposed as async python functions), but runs
6
+ * the interpreter on the host and dispatches inner tool calls in-process
7
+ * through the framework's own tool routing — intermediate results never
8
+ * enter the model's context; the full trace stays on-box.
9
+ */
10
+ export { PyRunner, buildInjectedTools } from './py-runner.js';
11
+ export { PYTHON_RUNTIME_SOURCE } from './runtime-py.js';
12
+ export { buildCodeExecutionToolDefinition, CODE_EXECUTION_TOOL_NAME } from './tool-definition.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/code-execution/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAO9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * PyRunner — subprocess lifecycle + protocol driver for the client-side
3
+ * programmatic tool calling (`code_execution`) runtime.
4
+ *
5
+ * One runner per agent. The interpreter is spawned lazily on first exec,
6
+ * persists between execs (script globals survive — container-reuse
7
+ * semantics), and is reclaimed after an idle period, mirroring the managed
8
+ * runtime's ~5-minute container reclaim.
9
+ *
10
+ * This is a ROBUSTNESS boundary, not a security sandbox — same doctrine as
11
+ * GateScript: the agent already has broader host access through its tools.
12
+ * What this class guarantees is liveness: a wedged or runaway script cannot
13
+ * hang the agent turn (cancel -> grace -> SIGKILL -> respawn) and a crashed
14
+ * interpreter surfaces as a tool result, never as an unhandled rejection.
15
+ */
16
+ export interface InjectedTool {
17
+ /** Python identifier the tool is bound to (sanitized, `--` -> `__`). */
18
+ pyName: string;
19
+ /** Exact framework tool name, sent back on tool_call ops. */
20
+ toolName: string;
21
+ }
22
+ export interface ExecResult {
23
+ stdout: string;
24
+ stderr: string;
25
+ returnCode: number;
26
+ /** Set when the host killed the script (deadline / abort / crash). */
27
+ aborted?: boolean;
28
+ }
29
+ /** Resolves inner tool calls. Must never reject — map errors to strings. */
30
+ export type ScriptToolCallHandler = (toolName: string, args: Record<string, unknown>) => Promise<string>;
31
+ export interface PyRunnerOptions {
32
+ pythonPath?: string;
33
+ /** Per-tool-call timeout surfaced as TimeoutError inside the script. */
34
+ toolCallTimeoutMs?: number;
35
+ /** Whole-script deadline; exceeded -> cancel, grace, kill. */
36
+ scriptTimeoutMs?: number;
37
+ /** Idle interpreter reclaim (state lost), mirroring container reclaim. */
38
+ idleReclaimMs?: number;
39
+ onToolCall: ScriptToolCallHandler;
40
+ /** Log prefix, typically the agent name. */
41
+ label?: string;
42
+ }
43
+ export declare class PyRunner {
44
+ private readonly pythonPath;
45
+ private readonly toolCallTimeoutMs;
46
+ private readonly scriptTimeoutMs;
47
+ private readonly idleReclaimMs;
48
+ private readonly onToolCall;
49
+ private readonly label;
50
+ private child;
51
+ private childReady;
52
+ private reader;
53
+ private runtimeDir;
54
+ private pending;
55
+ private idleTimer;
56
+ private execCounter;
57
+ private disposed;
58
+ constructor(options: PyRunnerOptions);
59
+ get busy(): boolean;
60
+ /**
61
+ * Run one script. Tools are (re-)injected before every exec so the
62
+ * interpreter always reflects the current tool surface (list_changed etc.).
63
+ * Never rejects: every failure mode resolves to an ExecResult.
64
+ */
65
+ exec(code: string, tools: InjectedTool[]): Promise<ExecResult>;
66
+ /**
67
+ * Abort a running script (turn cancelled, agent reset/stopped). The
68
+ * interpreter is reclaimed: after an abort its state is suspect (a script
69
+ * died midway), and the next exec gets a fresh one.
70
+ */
71
+ abort(reason: string): void;
72
+ dispose(): void;
73
+ private ensureChild;
74
+ private readyResolver;
75
+ private handleLine;
76
+ private settlePending;
77
+ private send;
78
+ /** Kill interpreter + clean temp dir. State is lost (by design). */
79
+ private reclaim;
80
+ private teardownChild;
81
+ private armIdleTimer;
82
+ private clearIdleTimer;
83
+ }
84
+ /**
85
+ * Map framework tool names to python identifiers: `--` becomes `__`.
86
+ * Names that still aren't valid identifiers, or that collide after
87
+ * sanitization, are skipped loudly — a skipped tool is unreachable from
88
+ * scripts (the exact-name tools[...] dict is built from this same list).
89
+ */
90
+ export declare function buildInjectedTools(toolNames: string[], log?: (message: string) => void): InjectedTool[];
91
+ //# sourceMappingURL=py-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"py-runner.d.ts","sourceRoot":"","sources":["../../../src/code-execution/py-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,4EAA4E;AAC5E,MAAM,MAAM,qBAAqB,GAAG,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,qBAAqB,CAAC;IAClC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAeD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,eAAe;IASpC,IAAI,IAAI,IAAI,OAAO,CAElB;IAED;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAiEpE;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAY3B,OAAO,IAAI,IAAI;YAgBD,WAAW;IA2EzB,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,UAAU;IA8ClB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,IAAI;IAYZ,oEAAoE;IACpE,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,cAAc;CAMvB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EAAE,EACnB,GAAG,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAA8B,GACvD,YAAY,EAAE,CAkBhB"}
@@ -0,0 +1,364 @@
1
+ /**
2
+ * PyRunner — subprocess lifecycle + protocol driver for the client-side
3
+ * programmatic tool calling (`code_execution`) runtime.
4
+ *
5
+ * One runner per agent. The interpreter is spawned lazily on first exec,
6
+ * persists between execs (script globals survive — container-reuse
7
+ * semantics), and is reclaimed after an idle period, mirroring the managed
8
+ * runtime's ~5-minute container reclaim.
9
+ *
10
+ * This is a ROBUSTNESS boundary, not a security sandbox — same doctrine as
11
+ * GateScript: the agent already has broader host access through its tools.
12
+ * What this class guarantees is liveness: a wedged or runaway script cannot
13
+ * hang the agent turn (cancel -> grace -> SIGKILL -> respawn) and a crashed
14
+ * interpreter surfaces as a tool result, never as an unhandled rejection.
15
+ */
16
+ import { spawn } from 'node:child_process';
17
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { tmpdir } from 'node:os';
19
+ import { join } from 'node:path';
20
+ import { createInterface } from 'node:readline';
21
+ import { PYTHON_RUNTIME_SOURCE } from './runtime-py.js';
22
+ const DEFAULT_TOOL_CALL_TIMEOUT_MS = 270_000;
23
+ const DEFAULT_SCRIPT_TIMEOUT_MS = 600_000;
24
+ const DEFAULT_IDLE_RECLAIM_MS = 300_000;
25
+ const CANCEL_GRACE_MS = 10_000;
26
+ export class PyRunner {
27
+ pythonPath;
28
+ toolCallTimeoutMs;
29
+ scriptTimeoutMs;
30
+ idleReclaimMs;
31
+ onToolCall;
32
+ label;
33
+ child = null;
34
+ childReady = null;
35
+ reader = null;
36
+ runtimeDir = null;
37
+ pending = null;
38
+ idleTimer = null;
39
+ execCounter = 0;
40
+ disposed = false;
41
+ constructor(options) {
42
+ this.pythonPath = options.pythonPath ?? 'python3';
43
+ this.toolCallTimeoutMs = options.toolCallTimeoutMs ?? DEFAULT_TOOL_CALL_TIMEOUT_MS;
44
+ this.scriptTimeoutMs = options.scriptTimeoutMs ?? DEFAULT_SCRIPT_TIMEOUT_MS;
45
+ this.idleReclaimMs = options.idleReclaimMs ?? DEFAULT_IDLE_RECLAIM_MS;
46
+ this.onToolCall = options.onToolCall;
47
+ this.label = options.label ?? 'pytc';
48
+ }
49
+ get busy() {
50
+ return this.pending !== null;
51
+ }
52
+ /**
53
+ * Run one script. Tools are (re-)injected before every exec so the
54
+ * interpreter always reflects the current tool surface (list_changed etc.).
55
+ * Never rejects: every failure mode resolves to an ExecResult.
56
+ */
57
+ async exec(code, tools) {
58
+ if (this.disposed) {
59
+ return { stdout: '', stderr: 'code_execution runner disposed', returnCode: 1, aborted: true };
60
+ }
61
+ if (this.pending) {
62
+ return {
63
+ stdout: '',
64
+ stderr: 'RuntimeError: another code_execution script is already running for this agent',
65
+ returnCode: 1,
66
+ aborted: true,
67
+ };
68
+ }
69
+ this.clearIdleTimer();
70
+ try {
71
+ await this.ensureChild();
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : String(err);
75
+ this.reclaim('spawn-failed');
76
+ return {
77
+ stdout: '',
78
+ stderr: `Failed to start python runtime (${this.pythonPath}): ${message}`,
79
+ returnCode: 1,
80
+ aborted: true,
81
+ };
82
+ }
83
+ const execId = `e${++this.execCounter}`;
84
+ const result = await new Promise((resolve) => {
85
+ const pending = {
86
+ id: execId,
87
+ resolve,
88
+ deadlineTimer: null,
89
+ killTimer: null,
90
+ settled: false,
91
+ };
92
+ this.pending = pending;
93
+ pending.deadlineTimer = setTimeout(() => {
94
+ // Deadline: ask politely first (script sees CancelledError and its
95
+ // exec_result still flows back), then kill on unresponsiveness.
96
+ this.send({ op: 'cancel', id: execId, reason: 'deadline' });
97
+ pending.killTimer = setTimeout(() => {
98
+ this.settlePending({
99
+ stdout: '',
100
+ stderr: `script killed after exceeding ${Math.round(this.scriptTimeoutMs / 1000)}s deadline`,
101
+ returnCode: 1,
102
+ aborted: true,
103
+ });
104
+ this.reclaim('deadline-kill');
105
+ }, CANCEL_GRACE_MS);
106
+ }, this.scriptTimeoutMs);
107
+ this.send({
108
+ op: 'init',
109
+ tools: tools.map((t) => ({ py_name: t.pyName, tool_name: t.toolName })),
110
+ call_timeout_s: Math.round(this.toolCallTimeoutMs / 1000),
111
+ });
112
+ this.send({ op: 'exec', id: execId, code });
113
+ });
114
+ this.armIdleTimer();
115
+ return result;
116
+ }
117
+ /**
118
+ * Abort a running script (turn cancelled, agent reset/stopped). The
119
+ * interpreter is reclaimed: after an abort its state is suspect (a script
120
+ * died midway), and the next exec gets a fresh one.
121
+ */
122
+ abort(reason) {
123
+ if (!this.pending)
124
+ return;
125
+ this.send({ op: 'cancel', id: this.pending.id, reason });
126
+ this.settlePending({
127
+ stdout: '',
128
+ stderr: `script aborted by host: ${reason}`,
129
+ returnCode: 1,
130
+ aborted: true,
131
+ });
132
+ this.reclaim(`abort: ${reason}`);
133
+ }
134
+ dispose() {
135
+ if (this.disposed)
136
+ return;
137
+ this.disposed = true;
138
+ if (this.pending) {
139
+ this.settlePending({
140
+ stdout: '',
141
+ stderr: 'code_execution runner disposed',
142
+ returnCode: 1,
143
+ aborted: true,
144
+ });
145
+ }
146
+ this.reclaim('dispose');
147
+ }
148
+ // -------------------------------------------------------------------------
149
+ async ensureChild() {
150
+ if (this.child && this.child.exitCode === null && !this.child.killed) {
151
+ return this.childReady ?? Promise.resolve();
152
+ }
153
+ this.teardownChild();
154
+ this.runtimeDir = mkdtempSync(join(tmpdir(), 'af-pytc-'));
155
+ const runtimePath = join(this.runtimeDir, 'runtime.py');
156
+ writeFileSync(runtimePath, PYTHON_RUNTIME_SOURCE, 'utf8');
157
+ const child = spawn(this.pythonPath, [runtimePath], {
158
+ stdio: ['pipe', 'pipe', 'pipe'],
159
+ env: { ...process.env, PYTHONUNBUFFERED: '1' },
160
+ });
161
+ this.child = child;
162
+ child.stderr.setEncoding('utf8');
163
+ child.stderr.on('data', (chunk) => {
164
+ // Outside an exec, python stderr is runtime diagnostics (crash
165
+ // tracebacks etc.) — surface them in host logs.
166
+ console.error(`[pytc:${this.label}] ${chunk.trimEnd()}`);
167
+ });
168
+ child.on('error', (err) => {
169
+ // Spawn failure lands here (e.g. python3 missing); readiness rejects.
170
+ console.error(`[pytc:${this.label}] python process error: ${err.message}`);
171
+ });
172
+ child.on('exit', (exitCode, signal) => {
173
+ if (this.pending) {
174
+ this.settlePending({
175
+ stdout: '',
176
+ stderr: `python runtime exited unexpectedly (code=${exitCode}, signal=${signal ?? 'none'})`,
177
+ returnCode: 1,
178
+ aborted: true,
179
+ });
180
+ }
181
+ if (this.child === child) {
182
+ this.teardownChild();
183
+ }
184
+ });
185
+ this.reader = createInterface({ input: child.stdout });
186
+ this.reader.on('line', (line) => this.handleLine(line));
187
+ this.childReady = new Promise((resolve, reject) => {
188
+ const onReady = () => {
189
+ cleanup();
190
+ resolve();
191
+ };
192
+ const onExit = () => {
193
+ cleanup();
194
+ reject(new Error('python runtime exited before becoming ready'));
195
+ };
196
+ const onError = (err) => {
197
+ cleanup();
198
+ reject(err);
199
+ };
200
+ const timeout = setTimeout(() => {
201
+ cleanup();
202
+ reject(new Error('python runtime did not become ready within 15s'));
203
+ }, 15_000);
204
+ const cleanup = () => {
205
+ clearTimeout(timeout);
206
+ this.readyResolver = null;
207
+ child.off('exit', onExit);
208
+ child.off('error', onError);
209
+ };
210
+ this.readyResolver = onReady;
211
+ child.on('exit', onExit);
212
+ child.on('error', onError);
213
+ });
214
+ return this.childReady;
215
+ }
216
+ readyResolver = null;
217
+ handleLine(line) {
218
+ let msg;
219
+ try {
220
+ msg = JSON.parse(line);
221
+ }
222
+ catch {
223
+ console.error(`[pytc:${this.label}] non-protocol stdout line: ${line.slice(0, 200)}`);
224
+ return;
225
+ }
226
+ switch (msg.op) {
227
+ case 'ready':
228
+ this.readyResolver?.();
229
+ return;
230
+ case 'tool_call': {
231
+ const callId = msg.id;
232
+ const toolName = msg.name;
233
+ if (!callId || !toolName)
234
+ return;
235
+ const args = msg.args && typeof msg.args === 'object' && !Array.isArray(msg.args)
236
+ ? msg.args
237
+ : {};
238
+ this.onToolCall(toolName, args)
239
+ .catch((err) => `Error: ${err instanceof Error ? err.message : String(err)}`)
240
+ .then((result) => {
241
+ this.send({ op: 'tool_result', id: callId, result });
242
+ });
243
+ return;
244
+ }
245
+ case 'exec_result': {
246
+ if (this.pending && msg.id === this.pending.id) {
247
+ this.settlePending({
248
+ stdout: msg.stdout ?? '',
249
+ stderr: msg.stderr ?? '',
250
+ returnCode: typeof msg.return_code === 'number' ? msg.return_code : 1,
251
+ });
252
+ }
253
+ return;
254
+ }
255
+ default:
256
+ console.error(`[pytc:${this.label}] unknown protocol op: ${String(msg.op)}`);
257
+ }
258
+ }
259
+ settlePending(result) {
260
+ const pending = this.pending;
261
+ if (!pending || pending.settled)
262
+ return;
263
+ pending.settled = true;
264
+ if (pending.deadlineTimer)
265
+ clearTimeout(pending.deadlineTimer);
266
+ if (pending.killTimer)
267
+ clearTimeout(pending.killTimer);
268
+ this.pending = null;
269
+ pending.resolve(result);
270
+ }
271
+ send(obj) {
272
+ const child = this.child;
273
+ if (!child || child.exitCode !== null || child.killed)
274
+ return;
275
+ try {
276
+ child.stdin.write(JSON.stringify(obj) + '\n');
277
+ }
278
+ catch (err) {
279
+ console.error(`[pytc:${this.label}] protocol write failed: ${err instanceof Error ? err.message : String(err)}`);
280
+ }
281
+ }
282
+ /** Kill interpreter + clean temp dir. State is lost (by design). */
283
+ reclaim(reason) {
284
+ if (this.child) {
285
+ console.error(`[pytc:${this.label}] reclaiming python interpreter (${reason})`);
286
+ }
287
+ this.teardownChild();
288
+ this.clearIdleTimer();
289
+ }
290
+ teardownChild() {
291
+ if (this.reader) {
292
+ this.reader.close();
293
+ this.reader = null;
294
+ }
295
+ if (this.child) {
296
+ const child = this.child;
297
+ this.child = null;
298
+ this.childReady = null;
299
+ this.readyResolver = null;
300
+ child.removeAllListeners('exit');
301
+ try {
302
+ child.stdin.end();
303
+ }
304
+ catch {
305
+ // stream may already be destroyed
306
+ }
307
+ if (child.exitCode === null && !child.killed) {
308
+ child.kill('SIGKILL');
309
+ }
310
+ }
311
+ if (this.runtimeDir) {
312
+ try {
313
+ rmSync(this.runtimeDir, { recursive: true, force: true });
314
+ }
315
+ catch {
316
+ // temp cleanup is best-effort
317
+ }
318
+ this.runtimeDir = null;
319
+ }
320
+ }
321
+ armIdleTimer() {
322
+ this.clearIdleTimer();
323
+ if (this.idleReclaimMs <= 0 || !this.child)
324
+ return;
325
+ this.idleTimer = setTimeout(() => {
326
+ if (!this.pending)
327
+ this.reclaim('idle');
328
+ }, this.idleReclaimMs);
329
+ // Do not hold the process open just to reclaim an idle interpreter.
330
+ this.idleTimer.unref?.();
331
+ }
332
+ clearIdleTimer() {
333
+ if (this.idleTimer) {
334
+ clearTimeout(this.idleTimer);
335
+ this.idleTimer = null;
336
+ }
337
+ }
338
+ }
339
+ /**
340
+ * Map framework tool names to python identifiers: `--` becomes `__`.
341
+ * Names that still aren't valid identifiers, or that collide after
342
+ * sanitization, are skipped loudly — a skipped tool is unreachable from
343
+ * scripts (the exact-name tools[...] dict is built from this same list).
344
+ */
345
+ export function buildInjectedTools(toolNames, log = (m) => console.error(m)) {
346
+ const seen = new Map();
347
+ const injected = [];
348
+ for (const toolName of toolNames) {
349
+ const pyName = toolName.replace(/--/g, '__');
350
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(pyName)) {
351
+ log(`[pytc] tool '${toolName}' skipped: '${pyName}' is not a valid python identifier`);
352
+ continue;
353
+ }
354
+ const existing = seen.get(pyName);
355
+ if (existing) {
356
+ log(`[pytc] tool '${toolName}' skipped: python name '${pyName}' collides with '${existing}'`);
357
+ continue;
358
+ }
359
+ seen.set(pyName, toolName);
360
+ injected.push({ pyName, toolName });
361
+ }
362
+ return injected;
363
+ }
364
+ //# sourceMappingURL=py-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"py-runner.js","sourceRoot":"","sources":["../../../src/code-execution/py-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Python runtime for client-side programmatic tool calling (PTC).
3
+ *
4
+ * This is the interpreter-side half of the `code_execution` tool: a small
5
+ * asyncio REPL that mimics the environment Anthropic's server-side PTC was
6
+ * trained on (see docs/en/agents-and-tools/tool-use/programmatic-tool-calling):
7
+ *
8
+ * - scripts run with top-level `await` (PyCF_ALLOW_TOP_LEVEL_AWAIT)
9
+ * - host tools are injected as async functions taking a single dict and
10
+ * returning a string (the tool_result text)
11
+ * - a pending tool call that gets no response raises TimeoutError with the
12
+ * same message shape the managed runtime produces
13
+ * - interpreter globals persist across execs (container-reuse semantics)
14
+ *
15
+ * Embedded as a TS string because tsc does not copy non-TS assets to dist/;
16
+ * PyRunner materializes it to a temp file at spawn.
17
+ *
18
+ * Protocol (JSON lines):
19
+ * host -> py : {op:"init", tools:[{py_name,tool_name}], call_timeout_s}
20
+ * {op:"exec", id, code}
21
+ * {op:"tool_result", id, result}
22
+ * {op:"cancel", id, reason?}
23
+ * py -> host : {op:"ready"}
24
+ * {op:"tool_call", id, exec_id, name, args}
25
+ * {op:"exec_result", id, stdout, stderr, return_code}
26
+ *
27
+ * IMPORTANT: the python source below must not contain backticks or the
28
+ * sequence dollar+brace (TS template literal syntax). String.raw preserves
29
+ * backslashes, so \n inside python string literals is fine.
30
+ */
31
+ export declare const PYTHON_RUNTIME_SOURCE: string;
32
+ //# sourceMappingURL=runtime-py.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-py.d.ts","sourceRoot":"","sources":["../../../src/code-execution/runtime-py.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,eAAO,MAAM,qBAAqB,EAAE,MAyOnC,CAAC"}