@ferris1225/pi-subagents 1.0.0 → 2.0.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/LICENSE +2 -0
- package/README.md +188 -95
- package/agents/cleaner.md +51 -0
- package/agents/explore.md +6 -4
- package/agents/reviewer.md +2 -0
- package/package.json +9 -7
- package/src/agents.ts +2 -7
- package/src/announcements.ts +12 -1
- package/src/completion.ts +7 -36
- package/src/config.ts +310 -364
- package/src/dispatch.ts +145 -275
- package/src/fixloop.ts +0 -16
- package/src/format.ts +28 -30
- package/src/index.ts +6 -3
- package/src/models.ts +89 -106
- package/src/monitor.ts +57 -101
- package/src/prompt.ts +13 -8
- package/src/rpc-run.ts +90 -21
- package/src/runtime.ts +3 -17
- package/src/session-fork.ts +0 -4
- package/src/setup.ts +437 -639
- package/src/spawn.ts +587 -557
- package/src/tools.ts +27 -35
- package/src/ui.ts +3 -7
- package/src/widget.ts +144 -0
- package/src/worktree.ts +1 -1
- package/src/trajectory.ts +0 -312
package/src/announcements.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
|
5
5
|
import { loadConfig, saveConfig } from "./config.ts";
|
|
6
6
|
import { announceRecoveryRecords } from "./recovery.ts";
|
|
7
7
|
import type { SubagentRuntime } from "./runtime.ts";
|
|
8
|
+
import { pruneResultArtifacts } from "./spawn.ts";
|
|
9
|
+
import { installActiveRunsWidget } from "./widget.ts";
|
|
8
10
|
|
|
9
11
|
const ANNOUNCEMENTS: Array<{
|
|
10
12
|
key: string;
|
|
@@ -17,6 +19,12 @@ const ANNOUNCEMENTS: Array<{
|
|
|
17
19
|
message:
|
|
18
20
|
"pi-subagents: new — a vision-capable model can now handle image tasks (screenshots, mockups, designs). Run /subagents-setup to configure it; until set, vision tasks use the main session's current model.",
|
|
19
21
|
},
|
|
22
|
+
{
|
|
23
|
+
key: "cleanerAgent",
|
|
24
|
+
condition: (config) => !config.enabledAgents.includes("cleaner"),
|
|
25
|
+
message:
|
|
26
|
+
"pi-subagents: new built-in cleaner agent is available for evidence-first code cleanup. Run /subagents-setup to enable it; your existing enabledAgents selection was left unchanged.",
|
|
27
|
+
},
|
|
20
28
|
];
|
|
21
29
|
|
|
22
30
|
async function announceNewFeatures(
|
|
@@ -53,7 +61,10 @@ async function announceNewFeatures(
|
|
|
53
61
|
|
|
54
62
|
export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime): void {
|
|
55
63
|
pi.on("session_start", async (_event, ctx) => {
|
|
64
|
+
pruneResultArtifacts();
|
|
56
65
|
await announceRecoveryRecords(runtime.configPath, ctx);
|
|
57
|
-
if (ctx.mode
|
|
66
|
+
if (ctx.mode !== "tui") return;
|
|
67
|
+
installActiveRunsWidget(ctx);
|
|
68
|
+
await announceNewFeatures(ctx, runtime);
|
|
58
69
|
});
|
|
59
70
|
}
|
package/src/completion.ts
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Smart batching for successful background completions.
|
|
3
3
|
*
|
|
4
4
|
* A short debounce coalesces sibling runs while a max-wait timer, measured from
|
|
5
|
-
* the first item in the open group, bounds delivery latency.
|
|
6
|
-
* shortly after an emitted group use a smaller straggler window. Failures are
|
|
5
|
+
* the first item in the open group, bounds delivery latency. Failures are
|
|
7
6
|
* intentionally handled by the caller: flush held successes, then emit the
|
|
8
7
|
* failure directly so it is never delayed.
|
|
9
8
|
*/
|
|
@@ -13,30 +12,14 @@ import { getResultOutput, isFailedResult, reviewVerdict, type SingleResult } fro
|
|
|
13
12
|
export interface CompletionBatchTimings {
|
|
14
13
|
debounceMs: number;
|
|
15
14
|
maxWaitMs: number;
|
|
16
|
-
stragglerDebounceMs: number;
|
|
17
|
-
stragglerMaxWaitMs: number;
|
|
18
|
-
stragglerWindowMs: number;
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
export const DEFAULT_COMPLETION_BATCH_TIMINGS: CompletionBatchTimings = {
|
|
22
18
|
debounceMs: 150,
|
|
23
19
|
maxWaitMs: 1_000,
|
|
24
|
-
stragglerDebounceMs: 75,
|
|
25
|
-
stragglerMaxWaitMs: 400,
|
|
26
|
-
stragglerWindowMs: 2_000,
|
|
27
20
|
};
|
|
28
21
|
|
|
29
|
-
type TimerHandle =
|
|
30
|
-
|
|
31
|
-
export interface TimerApi {
|
|
32
|
-
setTimeout(handler: () => void, delayMs: number): TimerHandle;
|
|
33
|
-
clearTimeout(handle: TimerHandle): void;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const defaultTimers: TimerApi = {
|
|
37
|
-
setTimeout: (handler, delayMs) => setTimeout(handler, delayMs),
|
|
38
|
-
clearTimeout: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),
|
|
39
|
-
};
|
|
22
|
+
type TimerHandle = ReturnType<typeof setTimeout>;
|
|
40
23
|
|
|
41
24
|
function unrefHandle(handle: TimerHandle): void {
|
|
42
25
|
if (
|
|
@@ -52,8 +35,6 @@ function unrefHandle(handle: TimerHandle): void {
|
|
|
52
35
|
export interface CompletionBatcherOptions<T> {
|
|
53
36
|
emit: (items: T[]) => void;
|
|
54
37
|
timings?: Partial<CompletionBatchTimings>;
|
|
55
|
-
timers?: TimerApi;
|
|
56
|
-
now?: () => number;
|
|
57
38
|
}
|
|
58
39
|
|
|
59
40
|
export interface CompletionBatcher<T> {
|
|
@@ -66,22 +47,18 @@ export interface CompletionBatcher<T> {
|
|
|
66
47
|
}
|
|
67
48
|
|
|
68
49
|
export function createCompletionBatcher<T>(options: CompletionBatcherOptions<T>): CompletionBatcher<T> {
|
|
69
|
-
const timers = options.timers ?? defaultTimers;
|
|
70
|
-
const now = options.now ?? Date.now;
|
|
71
50
|
const timings = { ...DEFAULT_COMPLETION_BATCH_TIMINGS, ...options.timings };
|
|
72
51
|
let pending: T[] = [];
|
|
73
52
|
let debounceTimer: TimerHandle | null = null;
|
|
74
53
|
let maxWaitTimer: TimerHandle | null = null;
|
|
75
|
-
let straggler = false;
|
|
76
|
-
let lastEmitAt: number | null = null;
|
|
77
54
|
|
|
78
55
|
const clearTimers = (): void => {
|
|
79
56
|
if (debounceTimer !== null) {
|
|
80
|
-
|
|
57
|
+
clearTimeout(debounceTimer);
|
|
81
58
|
debounceTimer = null;
|
|
82
59
|
}
|
|
83
60
|
if (maxWaitTimer !== null) {
|
|
84
|
-
|
|
61
|
+
clearTimeout(maxWaitTimer);
|
|
85
62
|
maxWaitTimer = null;
|
|
86
63
|
}
|
|
87
64
|
};
|
|
@@ -91,25 +68,19 @@ export function createCompletionBatcher<T>(options: CompletionBatcherOptions<T>)
|
|
|
91
68
|
if (pending.length === 0) return;
|
|
92
69
|
const items = pending;
|
|
93
70
|
pending = [];
|
|
94
|
-
lastEmitAt = now();
|
|
95
71
|
options.emit(items);
|
|
96
72
|
};
|
|
97
73
|
|
|
98
74
|
return {
|
|
99
75
|
push(item: T): void {
|
|
100
|
-
if (pending.length === 0) {
|
|
101
|
-
straggler = lastEmitAt !== null && now() - lastEmitAt < timings.stragglerWindowMs;
|
|
102
|
-
}
|
|
103
76
|
pending.push(item);
|
|
104
77
|
|
|
105
|
-
if (debounceTimer !== null)
|
|
106
|
-
|
|
107
|
-
debounceTimer = timers.setTimeout(emitGroup, debounceDelay);
|
|
78
|
+
if (debounceTimer !== null) clearTimeout(debounceTimer);
|
|
79
|
+
debounceTimer = setTimeout(emitGroup, timings.debounceMs);
|
|
108
80
|
unrefHandle(debounceTimer);
|
|
109
81
|
|
|
110
82
|
if (maxWaitTimer === null) {
|
|
111
|
-
|
|
112
|
-
maxWaitTimer = timers.setTimeout(emitGroup, maxWaitDelay);
|
|
83
|
+
maxWaitTimer = setTimeout(emitGroup, timings.maxWaitMs);
|
|
113
84
|
unrefHandle(maxWaitTimer);
|
|
114
85
|
}
|
|
115
86
|
},
|