@gotgenes/pi-subagents 6.13.1 → 6.14.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/CHANGELOG.md +24 -0
- package/docs/plans/0152-add-prompt-snippet.md +91 -0
- package/docs/retro/0152-add-prompt-snippet.md +34 -0
- package/package.json +2 -3
- package/src/agent-manager.ts +3 -0
- package/src/handlers/index.ts +2 -6
- package/src/tools/agent-tool.ts +1 -0
- package/src/tools/get-result-tool.ts +1 -0
- package/src/tools/steer-tool.ts +1 -0
- package/src/types.ts +0 -1
- package/src/ui/agent-widget.ts +5 -0
- package/src/ui/conversation-viewer.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [6.14.1](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v6.14.0...pi-subagents-v6.14.1) (2026-05-23)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* resolve fallow dead-code warnings ([2113f6b](https://github.com/gotgenes/pi-packages/commit/2113f6bc49812ce32ac68d0e2dd88e0a60b4474a))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
* **retro:** add retro notes for issue [#152](https://github.com/gotgenes/pi-packages/issues/152) ([7337bc1](https://github.com/gotgenes/pi-packages/commit/7337bc175528b4fb99dbc765eb06f0bcf2accec1))
|
|
19
|
+
|
|
20
|
+
## [6.14.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v6.13.1...pi-subagents-v6.14.0) (2026-05-23)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* add promptSnippet to Agent, get_subagent_result, and steer_subagent ([#152](https://github.com/gotgenes/pi-packages/issues/152)) ([3ccbe14](https://github.com/gotgenes/pi-packages/commit/3ccbe140b05ab038c3c50ff1fdbe314d721c7b60))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Documentation
|
|
29
|
+
|
|
30
|
+
* plan add promptSnippet to subagent tools ([#152](https://github.com/gotgenes/pi-packages/issues/152)) ([f8fd56d](https://github.com/gotgenes/pi-packages/commit/f8fd56dff3d6a824f36c198d9a9d1b50a0bf740a))
|
|
31
|
+
|
|
8
32
|
## [6.13.1](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v6.13.0...pi-subagents-v6.13.1) (2026-05-23)
|
|
9
33
|
|
|
10
34
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 152
|
|
3
|
+
issue_title: "Add promptSnippet to pi-subagents tools"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add `promptSnippet` to pi-subagents tools
|
|
7
|
+
|
|
8
|
+
## Problem Statement
|
|
9
|
+
|
|
10
|
+
The `Agent`, `get_subagent_result`, and `steer_subagent` tools are the only tools across the monorepo that lack `promptSnippet`.
|
|
11
|
+
Pi's `buildSystemPrompt` uses `promptSnippet` to build a concise tool summary in the system prompt.
|
|
12
|
+
Without it, these tools rely entirely on their `description` field for model guidance.
|
|
13
|
+
The `Agent` tool's description is especially long (embeds full usage guidelines), so a short snippet would give the model a better quick-reference view.
|
|
14
|
+
|
|
15
|
+
## Goals
|
|
16
|
+
|
|
17
|
+
- Add `promptSnippet` to each of the three tool registrations in pi-subagents.
|
|
18
|
+
- Match the established `"<toolName>: <one-liner>"` format used by pi-github-tools and pi-colgrep.
|
|
19
|
+
|
|
20
|
+
## Non-Goals
|
|
21
|
+
|
|
22
|
+
- Changing `description`, `promptGuidelines`, or any other tool registration field.
|
|
23
|
+
- Adding `promptSnippet` to tools in other packages (already done).
|
|
24
|
+
|
|
25
|
+
## Background
|
|
26
|
+
|
|
27
|
+
Sibling packages pi-github-tools and pi-colgrep already provide `promptSnippet` on every tool.
|
|
28
|
+
The convention is a single string in the form `"tool_name: Short imperative description."`.
|
|
29
|
+
For example: `"ci_list: List recent CI runs for a workflow."`.
|
|
30
|
+
|
|
31
|
+
The three tool factories live in:
|
|
32
|
+
|
|
33
|
+
| Factory | File |
|
|
34
|
+
| --------------------- | ------------------------------ |
|
|
35
|
+
| `createAgentTool` | `src/tools/agent-tool.ts` |
|
|
36
|
+
| `createGetResultTool` | `src/tools/get-result-tool.ts` |
|
|
37
|
+
| `createSteerTool` | `src/tools/steer-tool.ts` |
|
|
38
|
+
|
|
39
|
+
Each factory returns a plain object with `name`, `label`, `description`, `parameters`, and `execute`.
|
|
40
|
+
Adding `promptSnippet` is a single property addition per factory.
|
|
41
|
+
|
|
42
|
+
## Design Overview
|
|
43
|
+
|
|
44
|
+
No structural change — this is a property addition to three existing object literals.
|
|
45
|
+
|
|
46
|
+
Proposed snippets:
|
|
47
|
+
|
|
48
|
+
- **Agent** — `"Agent: Launch a specialized agent for complex, multi-step tasks."`
|
|
49
|
+
- **get_subagent_result** — `"get_subagent_result: Check status and retrieve results from a background agent."`
|
|
50
|
+
- **steer_subagent** — `"steer_subagent: Send a mid-run message to redirect a running background agent."`
|
|
51
|
+
|
|
52
|
+
These are the exact phrasings from the issue.
|
|
53
|
+
Exact wording may be refined during implementation.
|
|
54
|
+
|
|
55
|
+
## Module-Level Changes
|
|
56
|
+
|
|
57
|
+
### `src/tools/agent-tool.ts`
|
|
58
|
+
|
|
59
|
+
Add `promptSnippet` property to the object returned by `createAgentTool`, after `label`.
|
|
60
|
+
|
|
61
|
+
### `src/tools/get-result-tool.ts`
|
|
62
|
+
|
|
63
|
+
Add `promptSnippet` property to the object returned by `createGetResultTool`, after `label`.
|
|
64
|
+
|
|
65
|
+
### `src/tools/steer-tool.ts`
|
|
66
|
+
|
|
67
|
+
Add `promptSnippet` property to the object returned by `createSteerTool`, after `label`.
|
|
68
|
+
|
|
69
|
+
## Test Impact Analysis
|
|
70
|
+
|
|
71
|
+
Existing tool-definition tests (`test/tools/agent-tool.test.ts`, `get-result-tool.test.ts`, `steer-tool.test.ts`) assert `name`, `label`, and `description` but not `promptSnippet`.
|
|
72
|
+
New assertions will verify the property exists with the expected value.
|
|
73
|
+
No existing tests need modification — the new property is additive.
|
|
74
|
+
|
|
75
|
+
## TDD Order
|
|
76
|
+
|
|
77
|
+
1. **Red → Green:** Add `promptSnippet` assertions to the tool-definition tests for all three tools, then add the `promptSnippet` property to each factory.
|
|
78
|
+
Commit: `feat: add promptSnippet to Agent, get_subagent_result, and steer_subagent (#152)`
|
|
79
|
+
|
|
80
|
+
This is a single-cycle change — one test step, one implementation step, one commit.
|
|
81
|
+
|
|
82
|
+
## Risks and Mitigations
|
|
83
|
+
|
|
84
|
+
| Risk | Mitigation |
|
|
85
|
+
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| Snippet wording doesn't match what Pi displays well | The snippets mirror the first sentence of each tool's `description`; can be tweaked in a follow-up without breaking anything. |
|
|
87
|
+
| SDK `defineTool` doesn't pass through `promptSnippet` | Sibling packages already use it successfully, confirming SDK support. |
|
|
88
|
+
|
|
89
|
+
## Open Questions
|
|
90
|
+
|
|
91
|
+
None.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 152
|
|
3
|
+
issue_title: "Add promptSnippet to pi-subagents tools"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #152 — Add `promptSnippet` to pi-subagents tools
|
|
7
|
+
|
|
8
|
+
## Final Retrospective (2026-05-22)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Added `promptSnippet` to the `Agent`, `get_subagent_result`, and `steer_subagent` tool registrations in pi-subagents, matching the convention used by pi-github-tools and pi-colgrep.
|
|
13
|
+
The full plan→TDD→ship pipeline completed in one session with zero rework.
|
|
14
|
+
Released as `pi-subagents-v6.14.0`.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
#### What went well
|
|
19
|
+
|
|
20
|
+
- Clean single-cycle execution: the issue was unambiguous, the plan correctly scoped it as one TDD step, and the implementation matched the plan exactly.
|
|
21
|
+
- Cross-package convention check (grepping sibling packages for `promptSnippet` usage) confirmed the `"tool_name: One-liner."` format before writing the plan, avoiding any wording rework.
|
|
22
|
+
|
|
23
|
+
#### What caused friction (agent side)
|
|
24
|
+
|
|
25
|
+
No friction points identified.
|
|
26
|
+
The issue was a straightforward property addition with no design decisions, no interface changes, and no downstream breakage.
|
|
27
|
+
|
|
28
|
+
#### What caused friction (user side)
|
|
29
|
+
|
|
30
|
+
No friction points identified.
|
|
31
|
+
|
|
32
|
+
### Changes made
|
|
33
|
+
|
|
34
|
+
1. Created `packages/pi-subagents/docs/retro/0152-add-prompt-snippet.md` (this file).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gotgenes/pi-subagents",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.14.1",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": "./src/service.ts"
|
|
6
6
|
},
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"@earendil-works/pi-tui": ">=0.75.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@sinclair/typebox": "^0.34.49"
|
|
39
|
-
"nanoid": "^5.0.0"
|
|
38
|
+
"@sinclair/typebox": "^0.34.49"
|
|
40
39
|
},
|
|
41
40
|
"engines": {
|
|
42
41
|
"node": ">=22"
|
package/src/agent-manager.ts
CHANGED
|
@@ -430,6 +430,7 @@ export class AgentManager {
|
|
|
430
430
|
}
|
|
431
431
|
|
|
432
432
|
/** Whether any agents are still running or queued. */
|
|
433
|
+
// fallow-ignore-next-line unused-class-member
|
|
433
434
|
hasRunning(): boolean {
|
|
434
435
|
return [...this.agents.values()].some(
|
|
435
436
|
r => r.status === "running" || r.status === "queued",
|
|
@@ -437,6 +438,7 @@ export class AgentManager {
|
|
|
437
438
|
}
|
|
438
439
|
|
|
439
440
|
/** Abort all running and queued agents immediately. */
|
|
441
|
+
// fallow-ignore-next-line unused-class-member
|
|
440
442
|
abortAll(): number {
|
|
441
443
|
let count = 0;
|
|
442
444
|
// Clear queued agents first
|
|
@@ -460,6 +462,7 @@ export class AgentManager {
|
|
|
460
462
|
}
|
|
461
463
|
|
|
462
464
|
/** Wait for all running and queued agents to complete (including queued ones). */
|
|
465
|
+
// fallow-ignore-next-line unused-class-member
|
|
463
466
|
async waitForAll(): Promise<void> {
|
|
464
467
|
// Loop because drainQueue respects the concurrency limit — as running
|
|
465
468
|
// agents finish they start queued ones, which need awaiting too.
|
package/src/handlers/index.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
type LifecycleRuntime,
|
|
4
|
-
SessionLifecycleHandler,
|
|
5
|
-
} from "./lifecycle.js";
|
|
6
|
-
export { ToolStartHandler, type ToolStartRuntime } from "./tool-start.js";
|
|
1
|
+
export { SessionLifecycleHandler } from "./lifecycle.js";
|
|
2
|
+
export { ToolStartHandler } from "./tool-start.js";
|
package/src/tools/agent-tool.ts
CHANGED
|
@@ -71,6 +71,7 @@ export function createAgentTool(deps: AgentToolDeps) {
|
|
|
71
71
|
return {
|
|
72
72
|
name: "Agent" as const,
|
|
73
73
|
label: "Agent",
|
|
74
|
+
promptSnippet: "Agent: Launch a specialized agent for complex, multi-step tasks.",
|
|
74
75
|
description: `Launch a new agent to handle complex, multi-step tasks autonomously.
|
|
75
76
|
|
|
76
77
|
The Agent tool launches specialized agents that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
|
|
@@ -19,6 +19,7 @@ export function createGetResultTool(deps: GetResultDeps) {
|
|
|
19
19
|
return {
|
|
20
20
|
name: "get_subagent_result" as const,
|
|
21
21
|
label: "Get Agent Result",
|
|
22
|
+
promptSnippet: "get_subagent_result: Check status and retrieve results from a background agent.",
|
|
22
23
|
description:
|
|
23
24
|
"Check status and retrieve results from a background agent. Use the agent ID returned by Agent with run_in_background.",
|
|
24
25
|
parameters: Type.Object({
|
package/src/tools/steer-tool.ts
CHANGED
|
@@ -18,6 +18,7 @@ export function createSteerTool(deps: SteerToolDeps) {
|
|
|
18
18
|
return {
|
|
19
19
|
name: "steer_subagent" as const,
|
|
20
20
|
label: "Steer Agent",
|
|
21
|
+
promptSnippet: "steer_subagent: Send a mid-run message to redirect a running background agent.",
|
|
21
22
|
description:
|
|
22
23
|
"Send a steering message to a running agent. The message will interrupt the agent after its current tool execution " +
|
|
23
24
|
"and be injected into its conversation, allowing you to redirect its work mid-run. Only works on running agents.",
|
package/src/types.ts
CHANGED
package/src/ui/agent-widget.ts
CHANGED
|
@@ -64,6 +64,7 @@ export class AgentWidget {
|
|
|
64
64
|
) {}
|
|
65
65
|
|
|
66
66
|
/** Set the UI context (grabbed from first tool execution). */
|
|
67
|
+
// fallow-ignore-next-line unused-class-member
|
|
67
68
|
setUICtx(ctx: UICtx) {
|
|
68
69
|
if (ctx !== this.uiCtx) {
|
|
69
70
|
// UICtx changed — the widget registered on the old context is gone.
|
|
@@ -79,6 +80,7 @@ export class AgentWidget {
|
|
|
79
80
|
* Called on each new turn (tool_execution_start).
|
|
80
81
|
* Ages finished agents and clears those that have lingered long enough.
|
|
81
82
|
*/
|
|
83
|
+
// fallow-ignore-next-line unused-class-member
|
|
82
84
|
onTurnStart() {
|
|
83
85
|
// Age all finished agents
|
|
84
86
|
for (const [id, age] of this.finishedTurnAge) {
|
|
@@ -89,6 +91,7 @@ export class AgentWidget {
|
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/** Ensure the widget update timer is running. */
|
|
94
|
+
// fallow-ignore-next-line unused-class-member
|
|
92
95
|
ensureTimer() {
|
|
93
96
|
if (!this.widgetInterval) {
|
|
94
97
|
this.widgetInterval = setInterval(() => this.update(), 80);
|
|
@@ -103,6 +106,7 @@ export class AgentWidget {
|
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
/** Record an agent as finished (call when agent completes). */
|
|
109
|
+
// fallow-ignore-next-line unused-class-member
|
|
106
110
|
markFinished(agentId: string) {
|
|
107
111
|
if (!this.finishedTurnAge.has(agentId)) {
|
|
108
112
|
this.finishedTurnAge.set(agentId, 0);
|
|
@@ -354,6 +358,7 @@ export class AgentWidget {
|
|
|
354
358
|
}
|
|
355
359
|
}
|
|
356
360
|
|
|
361
|
+
// fallow-ignore-next-line unused-class-member
|
|
357
362
|
dispose() {
|
|
358
363
|
if (this.widgetInterval) {
|
|
359
364
|
clearInterval(this.widgetInterval);
|
|
@@ -90,6 +90,7 @@ export class ConversationViewer implements Component {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
// fallow-ignore-next-line unused-class-member
|
|
93
94
|
handleInput(data: string): void {
|
|
94
95
|
if (matchesKey(data, "escape") || matchesKey(data, "q")) {
|
|
95
96
|
this.closed = true;
|
|
@@ -199,8 +200,10 @@ export class ConversationViewer implements Component {
|
|
|
199
200
|
return lines;
|
|
200
201
|
}
|
|
201
202
|
|
|
203
|
+
// fallow-ignore-next-line unused-class-member
|
|
202
204
|
invalidate(): void { /* no cached state to clear */ }
|
|
203
205
|
|
|
206
|
+
// fallow-ignore-next-line unused-class-member
|
|
204
207
|
dispose(): void {
|
|
205
208
|
this.closed = true;
|
|
206
209
|
if (this.unsubscribe) {
|