@tshu-w/pi-agents 0.1.1 → 0.2.1
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.
- package/README.md +27 -20
- package/bin/daemon.mjs +32 -14
- package/bin/host.mjs +9 -1
- package/bin/pd.mjs +87 -42
- package/docs/HOSTS.md +111 -0
- package/docs/PROGRAM.md +39 -114
- package/docs/SPEC.md +109 -161
- package/package.json +7 -5
- package/src/agents/agents.ts +129 -55
- package/src/agents/registry.ts +62 -10
- package/src/agents/search.ts +21 -4
- package/src/agents/tool.ts +41 -13
- package/src/daemon/client.mjs +4 -1
- package/src/host/client.mjs +30 -5
- package/src/host/extension.ts +38 -14
- package/src/host/rpc-client.mjs +380 -0
- package/src/index.ts +44 -16
- package/src/output.ts +5 -1
- package/src/programs/codemode.ts +2 -2
- package/src/programs/execute.ts +150 -34
- package/src/programs/host-patches.ts +56 -27
- package/src/programs/loadout.ts +18 -3
- package/src/programs/programs.ts +128 -20
- package/src/programs/run-output.mjs +11 -0
- package/src/programs/sandbox.ts +17 -4
- package/src/programs/scope.ts +15 -7
- package/src/programs/tool.ts +172 -16
- package/src/render-call.ts +113 -15
- package/src/roots/guard.mjs +8 -2
- package/src/roots/paths.mjs +4 -4
- package/src/roots/queue.ts +52 -0
- package/src/roots/report.ts +12 -6
- package/src/roots/rpc.ts +618 -0
- package/src/roots/runtime.ts +17 -2
- package/src/roots/transport.mjs +41 -23
- package/src/ui/message.ts +24 -0
- package/src/ui/panel.ts +39 -7
- package/src/ui/queue.ts +47 -0
- package/src/ui/viewer.ts +182 -38
- package/src/workbench.mjs +91 -51
- package/docs/WORKBENCH.md +0 -167
package/docs/PROGRAM.md
CHANGED
|
@@ -1,34 +1,18 @@
|
|
|
1
1
|
# Pi Agents Program Specification
|
|
2
2
|
|
|
3
|
-
A Program is JavaScript that calls tools and Agents. Agents are defined in
|
|
4
|
-
SPEC.md.
|
|
3
|
+
A Program is JavaScript that calls tools and Agents. Agents are defined in SPEC.md.
|
|
5
4
|
|
|
6
|
-
The `program` tool replaces Pi's `codemode` tool and keeps its script API,
|
|
7
|
-
tool list, result format, and truncation. This document describes what
|
|
8
|
-
Programs add.
|
|
5
|
+
The `program` tool replaces Pi's `codemode` tool and keeps its script API, tool list, result format, and truncation. This document describes what Programs add.
|
|
9
6
|
|
|
10
7
|
## 1. Semantic model
|
|
11
8
|
|
|
12
|
-
An Agent runs a **Program** with the `program` tool. That Agent is the
|
|
13
|
-
Program's **caller**. The Program can call the caller's tools and create
|
|
14
|
-
Agents.
|
|
9
|
+
An Agent runs a **Program** with the `program` tool. That Agent is the Program's **caller**. The Program can call the caller's tools and create Agents.
|
|
15
10
|
|
|
16
|
-
A Program runs in the **foreground** or the **background**. In the
|
|
17
|
-
foreground, the tool call returns the Program's result. In the background,
|
|
18
|
-
the tool call returns the Program's ID, and the caller gets the result with
|
|
19
|
-
`wait`.
|
|
11
|
+
A Program runs in the **foreground** or the **background**. In the foreground, the tool call returns the Program's result. In the background, the tool call returns the Program's ID, and the caller gets the result with `wait`.
|
|
20
12
|
|
|
21
|
-
A Program is shown by its short ID: the shortest prefix of its ID, at least
|
|
22
|
-
8 characters, that none of the caller's other Programs' IDs starts with. A
|
|
23
|
-
target is an ID or a unique ID prefix.
|
|
13
|
+
A Program is shown by its short ID: the shortest prefix of its ID, at least 8 characters, that none of the caller's other Programs' IDs starts with. A target is an ID or a unique ID prefix.
|
|
24
14
|
|
|
25
|
-
Agents created with `agent()` belong to the Program: it gets their results
|
|
26
|
-
from `send()`, without `wait` or notifications, and only it can abort
|
|
27
|
-
them. Each of these Agents and the Agents under it see only one another,
|
|
28
|
-
and no other Agent sees them. The user sees them in `/tasks` and `/agents`,
|
|
29
|
-
and can talk to them or interrupt them in the viewer; an interrupted input
|
|
30
|
-
makes its `send()` throw. When the Program ends, their unfinished inputs end
|
|
31
|
-
as `aborted`, and the Agents go offline for good, from the bottom up.
|
|
15
|
+
Agents created with `agent()` belong to the Program: it gets their results from `send()`, without `wait` or notifications, and only it can abort them. Each of these Agents and the Agents under it see only one another, and no other Agent sees them. The user sees them in the task panel and `/tasks`, and can talk to them or interrupt them in the viewer; an interrupted input makes its `send()` throw. When the Program ends, their unfinished inputs end as `aborted`, and the Agents go offline for good, from the bottom up.
|
|
32
16
|
|
|
33
17
|
A Program is `running` until it ends in one of three ways:
|
|
34
18
|
|
|
@@ -38,76 +22,38 @@ A Program is `running` until it ends in one of three ways:
|
|
|
38
22
|
|
|
39
23
|
## 2. Operations
|
|
40
24
|
|
|
41
|
-
- `run` runs a Program in the foreground or background, with an optional
|
|
42
|
-
timeout.
|
|
25
|
+
- `run` runs a Program in the foreground or background, with an optional timeout.
|
|
43
26
|
- `wait` waits for background Programs and returns their results.
|
|
44
27
|
- `list` lists the caller's background Programs.
|
|
45
28
|
- `stop` stops a running Program.
|
|
46
29
|
|
|
47
|
-
When a background Program ends and its caller is not waiting for it, the
|
|
48
|
-
caller gets a notification, as in SPEC §5.
|
|
30
|
+
When a background Program ends and its caller is not waiting for it, the caller gets a notification, as in SPEC §5. A steer input ends `wait` early, as in SPEC §5.
|
|
49
31
|
|
|
50
32
|
## 3. Program API
|
|
51
33
|
|
|
52
|
-
`tools` holds the caller's tools, except `program`; which tools the caller
|
|
53
|
-
can use is checked at each call. If a Program fails or is stopped, the
|
|
54
|
-
error or stop reason follows its output. Its `store()` writes are kept
|
|
55
|
-
only if it completes.
|
|
34
|
+
`tools` holds the caller's tools, except `program`; which tools the caller can use is checked at each call. If a Program fails or is stopped, the error or stop reason follows its output. Its `store()` writes are kept only if it completes.
|
|
56
35
|
|
|
57
|
-
A Program also creates Agents with `agent()
|
|
36
|
+
A Program also creates idle Agents with `agent()`, typed in the Agent API (§6). Options work like `agent` `spawn`; an omitted name is generated, unique within the Program. `send()` sends a message and returns its result. `abort()` works like `agent` `abort`. The Agent gets its tools as if the caller had spawned it.
|
|
58
37
|
|
|
59
|
-
|
|
60
|
-
agent(options?: {
|
|
61
|
-
name?: string;
|
|
62
|
-
cwd?: string;
|
|
63
|
-
context?: "fresh" | "fork";
|
|
64
|
-
model?: string;
|
|
65
|
-
thinkingLevel?: string;
|
|
66
|
-
}): AgentHandle
|
|
38
|
+
A result is the Agent's answer. If the input fails or is aborted, the result throws an Error. A write returns `undefined` once accepted.
|
|
67
39
|
|
|
68
|
-
|
|
69
|
-
readonly id: string;
|
|
70
|
-
readonly name: string;
|
|
71
|
-
send(message: string, options?: {
|
|
72
|
-
deliverAs?: "followUp" | "steer" | "write";
|
|
73
|
-
schema?: JsonSchema;
|
|
74
|
-
}): Promise<unknown>;
|
|
75
|
-
abort(): Promise<void>;
|
|
76
|
-
}
|
|
77
|
-
```
|
|
40
|
+
With `schema`, the Agent must call `submit_result` with a value that matches the schema, and the result is that value. If it does not, the input fails.
|
|
78
41
|
|
|
79
|
-
`
|
|
80
|
-
omitted name is generated, unique within the Program. `send()` sends a
|
|
81
|
-
message and returns its result. `abort()` works like `agent` `abort`.
|
|
82
|
-
It gets its tools as if the caller had spawned it.
|
|
42
|
+
With `timeout`, an input that has not ended within that many seconds of `send()`, including time queued for a slot, is aborted; the Agent's queued inputs are unaffected. The result throws a timeout Error.
|
|
83
43
|
|
|
84
|
-
|
|
85
|
-
result throws an Error. A write returns `undefined` once accepted.
|
|
86
|
-
|
|
87
|
-
With `schema`, the Agent must call `submit_result` with a value that
|
|
88
|
-
matches the schema, and the result is that value. If it does not, the
|
|
89
|
-
input fails. `send()` throws if `schema` is used without `followUp`.
|
|
44
|
+
`send()` throws if `schema` or `timeout` is used without `followUp`.
|
|
90
45
|
|
|
91
46
|
## 4. Lifecycle
|
|
92
47
|
|
|
93
|
-
When a Program ends, it cancels its unfinished tool calls and aborts its
|
|
94
|
-
Agents' unfinished inputs, and waits for its Agents to go offline. It
|
|
95
|
-
returns its result after cleanup. Work not stopped within the cleanup
|
|
96
|
-
timeout is abandoned and may keep running; the Program's result and `stop`
|
|
97
|
-
report it as an error.
|
|
98
|
-
Stopping a Program does not undo completed tool calls.
|
|
48
|
+
When a Program ends, it cancels its unfinished tool calls and aborts its Agents' unfinished inputs, and waits for its Agents to go offline. It returns its result after cleanup. Work not stopped within the cleanup timeout is abandoned and may keep running; the Program's result and `stop` report it as an error, and the Program's state is unchanged.
|
|
99
49
|
|
|
100
|
-
When the caller goes offline, its running Programs stop. Their results
|
|
101
|
-
remain available when the caller is loaded again.
|
|
50
|
+
When the caller goes offline, its running Programs stop. Their results remain available when the caller is loaded again.
|
|
102
51
|
|
|
103
52
|
## 5. Limits
|
|
104
53
|
|
|
105
|
-
A Program's Agents and the Agents under them count toward the caller's
|
|
106
|
-
tree: they share its slots and `maxOutstanding` limit, as in SPEC §4. At
|
|
107
|
-
`maxOutstanding`, `send()` throws.
|
|
54
|
+
A Program's Agents and the Agents under them count toward the caller's tree: they share its slots and `maxOutstanding` limit, as in SPEC §4. At `maxOutstanding`, `send()` throws.
|
|
108
55
|
|
|
109
|
-
An owned caller gives up its slot while a foreground Program runs or while
|
|
110
|
-
it waits for background Programs, and takes one again before continuing.
|
|
56
|
+
An owned caller gives up its slot while a foreground Program runs or while it waits for background Programs, and takes one again before continuing.
|
|
111
57
|
|
|
112
58
|
## 6. Model-facing tool
|
|
113
59
|
|
|
@@ -115,21 +61,11 @@ it waits for background Programs, and takes one again before continuing.
|
|
|
115
61
|
|
|
116
62
|
description:
|
|
117
63
|
|
|
118
|
-
Run JavaScript that composes tool calls and Agents; only its output and
|
|
119
|
-
return value reach the caller. `run` runs a Program in the foreground, or
|
|
120
|
-
in the background with `background`; `wait` waits for background Programs
|
|
121
|
-
and returns their results; `list` lists background Programs; `stop` stops
|
|
122
|
-
a running Program. When a background Program ends while its caller is not
|
|
123
|
-
waiting for it, the caller receives a notification; `wait` returns the
|
|
124
|
-
result.
|
|
64
|
+
Run JavaScript that composes tool calls and Agents; only its output and return value reach the caller. `run` runs a Program in the foreground, or in the background with `background`; `wait` waits for background Programs and returns their results; `list` lists background Programs; `stop` stops a running Program. When a background Program ends while its caller is not waiting for it, the caller receives a notification; `wait` returns the result.
|
|
125
65
|
|
|
126
|
-
Program code is the body of an async function. It calls the caller's tools
|
|
127
|
-
through `tools.*`, which excludes `program`, and creates Agents through
|
|
128
|
-
`agent()`. These Agents belong to the Program, are isolated from other
|
|
129
|
-
Agents, and go offline when it ends.
|
|
66
|
+
Program code is the body of an async function. It calls the caller's tools through `tools.*`, which excludes `program`, and creates Agents through `agent()`. These Agents belong to the Program, are isolated from other Agents, and go offline when it ends.
|
|
130
67
|
|
|
131
|
-
`program` replaces the `codemode` tool; wherever `codemode` is mentioned,
|
|
132
|
-
use `program`.
|
|
68
|
+
`program` replaces the `codemode` tool; wherever `codemode` is mentioned, use `program`.
|
|
133
69
|
|
|
134
70
|
[the script API of `codemode`, without its Model API]
|
|
135
71
|
|
|
@@ -153,11 +89,13 @@ interface SendOptions {
|
|
|
153
89
|
deliverAs?: "followUp" | "steer" | "write";
|
|
154
90
|
/** `followUp` only. The Agent must submit a value matching it. */
|
|
155
91
|
schema?: JsonSchema;
|
|
92
|
+
/** `followUp` only. Seconds before the input is aborted. Default: none. */
|
|
93
|
+
timeout?: number;
|
|
156
94
|
}
|
|
157
95
|
interface AgentHandle {
|
|
158
96
|
readonly id: string;
|
|
159
97
|
readonly name: string;
|
|
160
|
-
/** Resolves with the answer, or with the submitted value when `schema` is set; a write resolves with undefined once accepted. Throws if the input fails or
|
|
98
|
+
/** Resolves with the answer, or with the submitted value when `schema` is set; a write resolves with undefined once accepted. Throws if the input fails, is aborted, or times out. */
|
|
161
99
|
send(message: string, options?: SendOptions): Promise<unknown>;
|
|
162
100
|
/** Aborts the Agent's current turn and queued inputs; the Agent stays usable. */
|
|
163
101
|
abort(): Promise<void>;
|
|
@@ -177,14 +115,9 @@ Run JavaScript that composes tool calls and Agents
|
|
|
177
115
|
|
|
178
116
|
promptGuidelines:
|
|
179
117
|
|
|
180
|
-
- Use `program(action='run', code=...)` to call tools or Agents several
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
condition holds.
|
|
184
|
-
- Use `Promise.allSettled` for independent calls. Return only what the
|
|
185
|
-
caller needs; use `text()` for progress worth reading.
|
|
186
|
-
- Use `background=true` for long Programs, and `program(action='wait', ...)`
|
|
187
|
-
when the next step depends on their results.
|
|
118
|
+
- Use `program(action='run', code=...)` to call tools or Agents several times without a model turn between the calls, for example to read many files, filter large tool output, fan out Agents, or loop until a condition holds.
|
|
119
|
+
- Use `Promise.allSettled` for independent calls. Return only what the caller needs; use `text()` for progress worth reading.
|
|
120
|
+
- Use `background=true` for long Programs, and `program(action='wait', ...)` when the next step depends on their results.
|
|
188
121
|
|
|
189
122
|
parameters:
|
|
190
123
|
|
|
@@ -200,8 +133,7 @@ results:
|
|
|
200
133
|
|
|
201
134
|
In these formats, `<id>` is the Program's short ID.
|
|
202
135
|
|
|
203
|
-
`run` in the foreground returns the Program result, as an error if the
|
|
204
|
-
Program failed or was stopped.
|
|
136
|
+
`run` in the foreground returns the Program result, as an error if the Program failed or was stopped. A Program result lists its `send()` calls with its tool calls, and names the calls still running when the script returned, which were cancelled.
|
|
205
137
|
|
|
206
138
|
`run` in the background:
|
|
207
139
|
|
|
@@ -209,8 +141,7 @@ Program failed or was stopped.
|
|
|
209
141
|
Program <id> started.
|
|
210
142
|
```
|
|
211
143
|
|
|
212
|
-
`wait` returns one block per result, followed by running Programs on
|
|
213
|
-
timeout:
|
|
144
|
+
`wait` returns one block per result, followed by running Programs on timeout:
|
|
214
145
|
|
|
215
146
|
```text
|
|
216
147
|
<program-result id="<id>" status="<outcome>">
|
|
@@ -220,8 +151,9 @@ timeout:
|
|
|
220
151
|
Still running: <id>, ...
|
|
221
152
|
```
|
|
222
153
|
|
|
223
|
-
|
|
224
|
-
|
|
154
|
+
When a steer input ended the wait, the line of SPEC §6 follows.
|
|
155
|
+
|
|
156
|
+
A single completed result, with nothing running, is returned alone. When there are no results or running Programs:
|
|
225
157
|
|
|
226
158
|
```text
|
|
227
159
|
No results.
|
|
@@ -252,8 +184,7 @@ Program <id> stopped.
|
|
|
252
184
|
Program <id> has already ended.
|
|
253
185
|
```
|
|
254
186
|
|
|
255
|
-
When some of the Program's work does not stop within the timeout, `stop`
|
|
256
|
-
fails with:
|
|
187
|
+
When some of the Program's work does not stop within the timeout, `stop` fails with the following; only restarting Pi stops it.
|
|
257
188
|
|
|
258
189
|
```text
|
|
259
190
|
Program <id> did not stop within the timeout and may still be running.
|
|
@@ -267,8 +198,7 @@ Cleanup error: some of the Program's work did not stop within the timeout and ma
|
|
|
267
198
|
|
|
268
199
|
errors:
|
|
269
200
|
|
|
270
|
-
Invalid calls fail with an error. Errors that need a follow-up say what to
|
|
271
|
-
do:
|
|
201
|
+
Invalid calls fail with an error. Errors that need a follow-up say what to do:
|
|
272
202
|
|
|
273
203
|
```text
|
|
274
204
|
No Program matches "<target>". Use list to find Programs.
|
|
@@ -280,10 +210,7 @@ No Program matches "<target>". Use list to find Programs.
|
|
|
280
210
|
|
|
281
211
|
truncation:
|
|
282
212
|
|
|
283
|
-
`wait` text beyond Pi's output limits is truncated as in SPEC §6. `wait`
|
|
284
|
-
adds results in order; the result that crosses the limit is truncated but keeps
|
|
285
|
-
its closing tag, and later results are omitted. A truncated result counts
|
|
286
|
-
as returned. Omitted results stay unreturned, and the text ends with:
|
|
213
|
+
`wait` text beyond Pi's output limits is truncated as in SPEC §6. `wait` adds results in order; the result that crosses the limit is truncated but keeps its closing tag, and later results are omitted. A truncated result counts as returned. Omitted results stay unreturned, and the text ends with:
|
|
287
214
|
|
|
288
215
|
```text
|
|
289
216
|
[Results omitted: <id>, ... Use wait with fewer targets.]
|
|
@@ -299,12 +226,10 @@ Program <id> <outcome>.
|
|
|
299
226
|
|
|
300
227
|
## 7. Human interface
|
|
301
228
|
|
|
302
|
-
The task panel (SPEC §7) lists running background Programs.
|
|
229
|
+
The task panel (SPEC §7) lists running background Programs. `/tasks` opens a background Program in the task viewer (SPEC §7).
|
|
230
|
+
|
|
231
|
+
`/program <path> [args]` runs the script in a file as a foreground Program of the current Agent, with the text after the path as the global `args`. Like a `!` command, it and its result join the context without starting a turn. With `pi -p`, the result is printed, and Pi exits with status 1 if the run fails.
|
|
303
232
|
|
|
304
233
|
## 8. Configuration
|
|
305
234
|
|
|
306
|
-
`program` is inactive by default, like `codemode`; enable it with `"defaultTools": ["+program"]` or `--tools`.
|
|
307
|
-
MCP treats `program` as `codemode`: it activates `program` when its servers need a script tool and neither is active, unless `autoEnableCodemode` is false, and a Program waits for the MCP servers its code names.
|
|
308
|
-
When both `program` and `codemode` are active, Pi warns once per Session, since they do a similar job.
|
|
309
|
-
`codemode.mode` decides how the tool list is presented, as for `codemode`.
|
|
310
|
-
`--program-only` activates `program` and uses `only` for the process, including its owned Agents.
|
|
235
|
+
`program` is inactive by default, like `codemode`; enable it with `"defaultTools": ["+program"]` or `--tools`. `/program` does not need it. MCP treats `program` as `codemode`: it activates `program` when its servers need a script tool and neither is active, unless `autoEnableCodemode` is false, and a Program waits for the MCP servers its code names. When both `program` and `codemode` are active, Pi warns once per Session, since they do a similar job. `codemode.mode` decides how the tool list is presented, as for `codemode`. `--program-only` activates `program` and uses `only` for the process, including its owned Agents.
|