@trim21/personal-pi-extensions 0.0.161 → 0.0.165
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/package.json +2 -1
- package/src/spawn-agent.ts +31 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trim21/personal-pi-extensions",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.165",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
|
|
6
6
|
"keywords": [
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"src/opencode-write.ts",
|
|
63
63
|
"src/bash-default-timeout.ts",
|
|
64
64
|
"src/gh-readonly.ts",
|
|
65
|
+
"src/spawn-agent.ts",
|
|
65
66
|
"src/todo-pendant.ts"
|
|
66
67
|
]
|
|
67
68
|
},
|
package/src/spawn-agent.ts
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
* is blocking: the tool awaits the subagent process until it exits and
|
|
11
11
|
* returns its final output to the parent model. Progress is streamed through
|
|
12
12
|
* `onUpdate`, the same channel the built-in bash tool uses for live output.
|
|
13
|
+
* Progress is a rolling log: `tool: <name>` lines for tool calls and
|
|
14
|
+
* `text: <content>` lines for completed text blocks, keeping the last
|
|
15
|
+
* `MAX_PROGRESS_LINES` lines.
|
|
13
16
|
*
|
|
14
17
|
* Security default: without an explicit `tools:` in the frontmatter, the
|
|
15
18
|
* subagent only gets read-only tools (read/grep/find/ls) — no bash/write/edit.
|
|
@@ -40,6 +43,8 @@ import { type AgentConfig, discoverAgents, formatAgentList } from "./spawn-agent
|
|
|
40
43
|
const MAX_OUTPUT_BYTES = 50 * 1024;
|
|
41
44
|
/** Read-only toolset used when an agent does not declare `tools`. */
|
|
42
45
|
const DEFAULT_TOOLS = ["read", "grep", "find", "ls"];
|
|
46
|
+
/** Progress log keeps only the most recent lines (rolling window). */
|
|
47
|
+
const MAX_PROGRESS_LINES = 5;
|
|
43
48
|
|
|
44
49
|
// ── schema ───────────────────────────────────────────────────────────────────
|
|
45
50
|
|
|
@@ -205,9 +210,22 @@ export async function runAgent(
|
|
|
205
210
|
env: { ...process.env, PI_SUBAGENT_CHILD: "1" },
|
|
206
211
|
});
|
|
207
212
|
|
|
213
|
+
let logLines: string[] = [];
|
|
214
|
+
|
|
215
|
+
const pushLogLine = (line: string) => {
|
|
216
|
+
logLines.push(line);
|
|
217
|
+
if (logLines.length > MAX_PROGRESS_LINES) {
|
|
218
|
+
logLines = logLines.slice(-MAX_PROGRESS_LINES);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
208
222
|
const emitUpdate = () => {
|
|
223
|
+
// Usage line rides on the last row so the TUI always shows live token
|
|
224
|
+
// cost; it lives outside the rolling window so it is never trimmed.
|
|
225
|
+
const usageLine = formatUsageStats(result.usage, result.model);
|
|
226
|
+
const lines = usageLine ? [...logLines, usageLine] : logLines;
|
|
209
227
|
onUpdate?.({
|
|
210
|
-
content: [{ type: "text", text:
|
|
228
|
+
content: [{ type: "text", text: lines.join("\n") || "(running...)" }],
|
|
211
229
|
details: { ...result },
|
|
212
230
|
});
|
|
213
231
|
};
|
|
@@ -224,7 +242,18 @@ export async function runAgent(
|
|
|
224
242
|
}
|
|
225
243
|
if (!isRecord(event)) return;
|
|
226
244
|
|
|
227
|
-
if (event.type === "
|
|
245
|
+
if (event.type === "message_update" && isRecord(event.assistantMessageEvent)) {
|
|
246
|
+
// A completed text block (text_end carries the full content) becomes a
|
|
247
|
+
// `text:` log line. Deltas/thinking are intentionally not logged.
|
|
248
|
+
const delta = event.assistantMessageEvent;
|
|
249
|
+
if (delta.type === "text_end" && typeof delta.content === "string") {
|
|
250
|
+
pushLogLine(`text: ${delta.content}`);
|
|
251
|
+
emitUpdate();
|
|
252
|
+
}
|
|
253
|
+
} else if (event.type === "tool_execution_start" && typeof event.toolName === "string") {
|
|
254
|
+
pushLogLine(`tool: ${event.toolName}`);
|
|
255
|
+
emitUpdate();
|
|
256
|
+
} else if (event.type === "message_end" && isRecord(event.message)) {
|
|
228
257
|
const msg = event.message as unknown as Message;
|
|
229
258
|
result.messages.push(msg);
|
|
230
259
|
if (msg.role === "assistant") {
|
|
@@ -241,9 +270,6 @@ export async function runAgent(
|
|
|
241
270
|
if (typeof msg.errorMessage === "string") result.errorMessage = msg.errorMessage;
|
|
242
271
|
}
|
|
243
272
|
emitUpdate();
|
|
244
|
-
} else if (event.type === "tool_result_end" && isRecord(event.message)) {
|
|
245
|
-
result.messages.push(event.message as unknown as Message);
|
|
246
|
-
emitUpdate();
|
|
247
273
|
}
|
|
248
274
|
};
|
|
249
275
|
|