@d3ara1n/pi-subagent 0.5.0 → 0.6.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 +3 -3
- package/package.json +1 -1
- package/src/index.ts +30 -20
- package/src/types.ts +6 -6
- package/src/utils.ts +10 -6
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Edit `~/.pi/agent/settings.json`:
|
|
|
64
64
|
```json
|
|
65
65
|
{
|
|
66
66
|
"subagent": {
|
|
67
|
-
"timeout":
|
|
67
|
+
"timeout": 1500,
|
|
68
68
|
"maxConcurrency": 4,
|
|
69
69
|
"maxDepth": 3,
|
|
70
70
|
"maxTurns": 0,
|
|
@@ -80,7 +80,7 @@ Edit `~/.pi/agent/settings.json`:
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
All fields are optional. Defaults: `timeout:
|
|
83
|
+
All fields are optional. Defaults: `timeout: 1500` (seconds; 25 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`.
|
|
84
84
|
|
|
85
85
|
### Agent Overrides
|
|
86
86
|
|
|
@@ -92,7 +92,7 @@ Override, disable, or add subagent roles via `agentOverrides`. Built-in and cust
|
|
|
92
92
|
"agentOverrides": {
|
|
93
93
|
"worker": {
|
|
94
94
|
"role": "heavy",
|
|
95
|
-
"timeout":
|
|
95
|
+
"timeout": 1500,
|
|
96
96
|
"maxTurns": 50,
|
|
97
97
|
"maxCost": 1.0
|
|
98
98
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d3ara1n/pi-subagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Role-based subagent orchestration for pi — delegates tasks to specialized pi child processes with configurable model roles",
|
|
6
6
|
"main": "src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -686,27 +686,32 @@ export default function subagentExtension(pi: ExtensionAPI) {
|
|
|
686
686
|
const stats = formatUsageStats(r.usage, r.model);
|
|
687
687
|
const usageLine = [secs != null ? `${secs}s` : null, stats].filter(Boolean).join(" \u00b7 ");
|
|
688
688
|
|
|
689
|
-
//
|
|
690
|
-
|
|
691
|
-
|
|
689
|
+
// resultline: fixed line on terminal frames — `<icon> <content>` colored by outcome.
|
|
690
|
+
// success → AI summary, else first line of output (truncated), else a placeholder — never blank.
|
|
691
|
+
// error/timeout/budget → errorMessage (or a default label).
|
|
692
|
+
let resultline: string | undefined;
|
|
692
693
|
if (!isRunning) {
|
|
693
694
|
if (isFailedState) {
|
|
694
|
-
|
|
695
|
-
|
|
695
|
+
const content = r.errorMessage || (isTimeout ? "Timed out" : isBudget ? "Budget exceeded" : "failed");
|
|
696
|
+
const col: ThemeColor = isTimeout || isBudget ? "warning" : "error";
|
|
697
|
+
resultline = `${icon} ${theme.fg(col, content)}`;
|
|
696
698
|
} else {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
+
// success fallback chain: summary → output first line → placeholder.
|
|
700
|
+
const firstLine = r.output.trim().split("\n")[0] ?? "";
|
|
701
|
+
const preview = firstLine.length > 70 ? `${firstLine.slice(0, 70)}...` : firstLine;
|
|
702
|
+
const content = r.summary || preview;
|
|
703
|
+
const col: ThemeColor = content ? "text" : "muted";
|
|
704
|
+
resultline = `${icon} ${theme.fg(col, content || "(no output)")}`;
|
|
699
705
|
}
|
|
700
706
|
}
|
|
701
707
|
|
|
702
708
|
if (expanded) {
|
|
703
709
|
const container = new Container();
|
|
704
710
|
|
|
705
|
-
// Header: taskline
|
|
706
|
-
// — full output below makes it redundant).
|
|
711
|
+
// Header: taskline + resultline (summary on success, error message on failure).
|
|
707
712
|
container.addChild(new Text(taskline, 0, 0));
|
|
708
|
-
if (
|
|
709
|
-
container.addChild(new Text(
|
|
713
|
+
if (resultline) {
|
|
714
|
+
container.addChild(new Text(resultline, 0, 0));
|
|
710
715
|
}
|
|
711
716
|
|
|
712
717
|
// Input block: reference files + context char count + task full text,
|
|
@@ -745,14 +750,19 @@ export default function subagentExtension(pi: ExtensionAPI) {
|
|
|
745
750
|
}
|
|
746
751
|
}
|
|
747
752
|
|
|
748
|
-
// Full output (terminal runs only).
|
|
749
|
-
|
|
753
|
+
// Full output (terminal runs only). Always render the slot — show a
|
|
754
|
+
// placeholder when empty so the user never thinks output was lost.
|
|
755
|
+
if (!isRunning) {
|
|
750
756
|
container.addChild(new Spacer(1));
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
757
|
+
if (r.output.trim()) {
|
|
758
|
+
container.addChild(new Markdown(r.output.trim(), 0, 0, mdTheme));
|
|
759
|
+
if (r.outputMethod === "compressed") {
|
|
760
|
+
container.addChild(new Text(theme.fg("muted", "(output compressed by summary model \u2014 full text in history)"), 0, 0));
|
|
761
|
+
} else if (r.outputMethod === "truncated") {
|
|
762
|
+
container.addChild(new Text(theme.fg("muted", "(output truncated \u2014 full text in history)"), 0, 0));
|
|
763
|
+
}
|
|
764
|
+
} else {
|
|
765
|
+
container.addChild(new Text(theme.fg("muted", "(no output \u2014 the run produced no text)"), 0, 0));
|
|
756
766
|
}
|
|
757
767
|
}
|
|
758
768
|
|
|
@@ -768,8 +778,8 @@ export default function subagentExtension(pi: ExtensionAPI) {
|
|
|
768
778
|
// Collapsed view.
|
|
769
779
|
let text = taskline;
|
|
770
780
|
if (!isRunning) {
|
|
771
|
-
//
|
|
772
|
-
if (
|
|
781
|
+
// resultline (shared computation above).
|
|
782
|
+
if (resultline) text += `\n${resultline}`;
|
|
773
783
|
} else if (!r.queued) {
|
|
774
784
|
// Running (not queued): show recent activity only.
|
|
775
785
|
const activity = displayItems.filter((item) => item.type === "toolCall" || item.type === "thinking");
|
package/src/types.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface SubagentSummaryConfig {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export const DEFAULT_CONFIG: SubagentConfig = {
|
|
38
|
-
timeout:
|
|
38
|
+
timeout: 1500,
|
|
39
39
|
maxConcurrency: 4,
|
|
40
40
|
maxDepth: 3,
|
|
41
41
|
maxTurns: 0,
|
|
@@ -151,14 +151,14 @@ export interface SubagentResult {
|
|
|
151
151
|
/** Real-time activity log: thinking blocks and tool calls in arrival order. */
|
|
152
152
|
activityLog: ActivityEntry[];
|
|
153
153
|
|
|
154
|
-
// ── TUI
|
|
155
|
-
/**
|
|
154
|
+
// ── TUI rendering helpers (not produced by the child; filled in by the execute layer) ──
|
|
155
|
+
/** Wall-clock start time; present only on queued/running frames so the TUI can compute live elapsed time. Absent on terminal frames. */
|
|
156
156
|
startTime?: number;
|
|
157
|
-
/**
|
|
157
|
+
/** Total elapsed time (ms) for terminal frames, written by execute when the run ends; spans the whole delegate interval (incl. fallback retries). */
|
|
158
158
|
elapsedMs?: number;
|
|
159
|
-
/** delegate
|
|
159
|
+
/** Reference file paths passed to delegate (params.files); used by the expanded view. */
|
|
160
160
|
files?: string[];
|
|
161
|
-
/** delegate
|
|
161
|
+
/** Extra context passed to delegate (params.context); used by the expanded view. */
|
|
162
162
|
context?: string;
|
|
163
163
|
}
|
|
164
164
|
|
package/src/utils.ts
CHANGED
|
@@ -32,12 +32,13 @@ export function formatUsageStats(usage: SubagentResult["usage"], model?: string)
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
* -
|
|
37
|
-
* -
|
|
38
|
-
* -
|
|
35
|
+
* Display elapsed time in seconds.
|
|
36
|
+
* - Running (exitCode === -1 with startTime): live wall-clock value.
|
|
37
|
+
* - Terminal (exitCode !== -1 with elapsedMs): frozen value.
|
|
38
|
+
* - Queued or fields missing: undefined (caller should skip the elapsed display).
|
|
39
39
|
*
|
|
40
|
-
*
|
|
40
|
+
* Takes a structural subset rather than the full SubagentResult so it can be reused
|
|
41
|
+
* and tested in pure-helper contexts without importing the full type.
|
|
41
42
|
*/
|
|
42
43
|
export function elapsedSeconds(r: {
|
|
43
44
|
exitCode: number;
|
|
@@ -193,7 +194,10 @@ export function isProviderError(result: SubagentResult): boolean {
|
|
|
193
194
|
return /429|quota|rate.?limit|auth|timeout|exhausted|unavailable|503|server error|temporary|declined|overloaded|econnreset|socket hang up|epipe|network|connection/i.test(haystack);
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Shape-based preview for tools we don't have a dedicated formatter for.
|
|
199
|
+
* @internal — exported for testing; used internally by {@link formatToolCall}.
|
|
200
|
+
*/
|
|
197
201
|
export function previewArgs(args: Record<string, unknown>): string {
|
|
198
202
|
const command = args.command as string | undefined;
|
|
199
203
|
if (command) return `$ ${command.length > 60 ? command.slice(0, 60) + "..." : command}`;
|