@d3ara1n/pi-subagent 0.2.0 → 0.4.0

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 CHANGED
@@ -44,19 +44,17 @@ This means:
44
44
  ## TUI Display
45
45
 
46
46
  - **During execution**: Shows role, elapsed time, turn count, and live tool calls
47
- - **Collapsed result**: `✓ explorer · 找到了登录/注册/token三块逻辑` + recent tool calls + usage stats
47
+ - **Collapsed result**: `✓ explorer · Found login, registration, and token logic` + recent tool calls + usage stats
48
48
  - **Expanded result** (Ctrl+O): Full task text, all tool calls, final output as rendered Markdown, and usage details
49
49
 
50
- ## Requirements
50
+ ## Dependencies
51
51
 
52
- - **@d3ara1n/pi-model-roles** must be installed and configured
53
- - **@earendil-works/pi-tui** — bundled with pi, no separate install needed
54
- - Role definitions must exist in `modelRoles` settings
52
+ - [`@d3ara1n/pi-model-roles`](../pi-model-roles) model role resolution
55
53
 
56
54
  ## Installation
57
55
 
58
56
  ```bash
59
- pi extension add @d3ara1n/pi-subagent
57
+ pi install @d3ara1n/pi-subagent
60
58
  ```
61
59
 
62
60
  ## Configuration
@@ -66,11 +64,30 @@ Edit `~/.pi/agent/settings.json`:
66
64
  ```jsonc
67
65
  {
68
66
  "subagent": {
69
- // Default timeout per subagent (5 minutes)
70
- "timeoutMs": 300000,
67
+ // Default timeout per subagent (10 minutes)
68
+ "timeoutMs": 600000,
69
+
70
+ // Max subagents running at once; extras queue with a "queued" TUI hint
71
+ "maxConcurrency": 4,
72
+
73
+ // Max subagent nesting depth (the main session is depth 0).
74
+ // Default 3 covers worker → researcher → explorer chains.
75
+ "maxDepth": 3,
76
+
77
+ // Turn / cost budgets (0 = unlimited). A run is killed once either is hit;
78
+ // partial output is returned with stopReason "budget_exceeded".
79
+ "maxTurns": 0,
80
+ "maxCost": 0,
81
+
82
+ // Audit log: one JSON per delegate run under
83
+ // ~/.pi/subagent/history/{sessionId}/{toolCallId}.json
84
+ "history": {
85
+ "enabled": true
86
+ },
71
87
 
72
88
  // Summary generation — uses a lightweight model to create
73
- // a one-line Chinese summary for the TUI display
89
+ // a one-line summary for the TUI display.
90
+ // Outputs ≤ 150 chars skip the API call and reuse the text directly.
74
91
  "summary": {
75
92
  "role": "utility", // pi-model-roles role for summarization
76
93
  "enabled": true // set false to disable
@@ -79,7 +96,7 @@ Edit `~/.pi/agent/settings.json`:
79
96
  }
80
97
  ```
81
98
 
82
- All fields are optional. Defaults: `timeoutMs: 300000`, `summary.role: "utility"`, `summary.enabled: true`.
99
+ All fields are optional. Defaults: `timeoutMs: 600000` (10 min; roles that can `delegate` get 2× automatically when no per-role timeout is set), `maxConcurrency: 4`, `maxDepth: 3`, `maxTurns: 0` (unlimited), `maxCost: 0` (unlimited), `history.enabled: true`, `summary.role: "utility"`, `summary.enabled: true`.
83
100
 
84
101
  ### Agent Overrides
85
102
 
@@ -91,7 +108,10 @@ Override, disable, or add subagent roles via `agentOverrides`. Built-in and cust
91
108
  "agentOverrides": {
92
109
  // ── Override a built-in role (only specify changed fields) ──
93
110
  "worker": {
94
- "role": "heavy" // use a stronger model
111
+ "role": "heavy", // use a stronger model
112
+ "timeoutMs": 600000, // per-role timeout (overrides global)
113
+ "maxTurns": 50, // per-role turn budget (0 = unlimited)
114
+ "maxCost": 1.0 // per-role cost ceiling in USD (0 = unlimited)
95
115
  },
96
116
 
97
117
  // ── Disable a built-in role ──
@@ -118,7 +138,7 @@ Override, disable, or add subagent roles via `agentOverrides`. Built-in and cust
118
138
 
119
139
  **Required fields for custom roles:** `role`, `description`, `examples`, `decisionTrigger`, `tools`, `systemPrompt`.
120
140
 
121
- **Optional fields:** `subagentRoles` (roles this role can spawn via delegate), `fallbackRole` (backup pi-model-roles role on provider errors).
141
+ **Optional fields:** `subagentRoles` (roles this role can spawn via delegate), `timeoutMs` (per-role timeout override; when unset, delegate-capable roles get 2× the global default automatically), `maxTurns` / `maxCost` (per-role budget overrides; 0 = unlimited), `fallbackRole` (backup pi-model-roles role on provider errors).
122
142
 
123
143
  Invalid custom roles (missing required fields) are silently skipped with an error notification at session start.
124
144
 
@@ -151,6 +171,32 @@ Delegate tasks that would generate many tool calls or verbose output to keep you
151
171
  ]
152
172
  ```
153
173
 
174
+ ### Passing extra context
175
+
176
+ The optional `context` field lets you hand a subagent precise context — selected code, a prior delegate's result, a file list, a git diff — without inflating the `task` string. It's prepended before the task:
177
+
178
+ ```json
179
+ {
180
+ "role": "worker",
181
+ "task": "Add input validation to the login function",
182
+ "context": "Current implementation (src/auth.ts:42-70):\n```ts\nasync function login(email, pw) { ... }\n```\nValidation must reject empty/invalid emails and enforce a min 8-char password."
183
+ }
184
+ ```
185
+
186
+ The stored/displayed task stays as the original `task`; the `context` is merged into the prompt the subagent receives.
187
+
188
+ ### Budget enforcement
189
+
190
+ `maxTurns` / `maxCost` cap a run. When exceeded, the child is killed and the last completed output is returned with `stopReason: "budget_exceeded"` (shown in the expanded TUI). Defaults are unlimited (0); set global defaults in config or per-role via `agentOverrides`.
191
+
192
+ ### Oversized outputs
193
+
194
+ When a run's output exceeds the size limit (50,000 chars), pi-subagent first tries to **compress** it with the summary model (same role configured under `summary.role`) into a compact form that preserves conclusions, code, file paths, and errors. If compression fails or doesn't shrink enough, it falls back to mechanical head+tail truncation. The prepared text is what the main model receives and what the expanded TUI renders; a hint line notes which method was used. The **full raw output is always kept in the history file** for auditing.
195
+
196
+ ### Run history
197
+
198
+ Every completed delegate run is written (best-effort) to `~/.pi/subagent/history/{sessionId}/{toolCallId}.json`, recording role, task, usage, activity log, and the **full raw output** (even when the main model saw a compressed/truncated version). Useful for auditing what subagents did and how much they cost. Disable with `history.enabled: false`.
199
+
154
200
  ## License
155
201
 
156
202
  MIT
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@d3ara1n/pi-subagent",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
+ "type": "module",
4
5
  "description": "Role-based subagent orchestration for pi — delegates tasks to specialized pi child processes with configurable model roles",
5
6
  "main": "src/index.ts",
6
7
  "keywords": [
package/src/config.ts CHANGED
@@ -21,8 +21,7 @@ function readSettingsFile(filePath: string): any {
21
21
  try {
22
22
  if (!fs.existsSync(filePath)) return {};
23
23
  const content = fs.readFileSync(filePath, "utf-8");
24
- const stripped = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
25
- return JSON.parse(stripped);
24
+ return JSON.parse(content);
26
25
  } catch {
27
26
  return {};
28
27
  }
@@ -53,8 +52,16 @@ export function loadSubagentConfig(cwd?: string): SubagentConfig {
53
52
  if (!raw) return DEFAULT_CONFIG;
54
53
 
55
54
  const rawSummary = raw?.summary;
55
+ const rawHistory = raw?.history;
56
56
  return {
57
57
  timeoutMs: raw.timeoutMs ?? DEFAULT_CONFIG.timeoutMs,
58
+ maxConcurrency: raw.maxConcurrency ?? DEFAULT_CONFIG.maxConcurrency,
59
+ maxDepth: raw.maxDepth ?? DEFAULT_CONFIG.maxDepth,
60
+ maxTurns: raw.maxTurns ?? DEFAULT_CONFIG.maxTurns,
61
+ maxCost: raw.maxCost ?? DEFAULT_CONFIG.maxCost,
62
+ history: {
63
+ enabled: rawHistory?.enabled ?? DEFAULT_CONFIG.history.enabled,
64
+ },
58
65
  summary: {
59
66
  role: rawSummary?.role ?? DEFAULT_CONFIG.summary.role,
60
67
  enabled: rawSummary?.enabled ?? DEFAULT_CONFIG.summary.enabled,