@astralyn/pi 0.84.5 → 0.84.7

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.
Files changed (119) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +4 -0
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/extensions/index.d.ts +1 -1
  6. package/dist/core/extensions/index.d.ts.map +1 -1
  7. package/dist/core/extensions/index.js.map +1 -1
  8. package/dist/core/extensions/runner.d.ts +1 -0
  9. package/dist/core/extensions/runner.d.ts.map +1 -1
  10. package/dist/core/extensions/runner.js +6 -0
  11. package/dist/core/extensions/runner.js.map +1 -1
  12. package/dist/core/extensions/types.d.ts +11 -0
  13. package/dist/core/extensions/types.d.ts.map +1 -1
  14. package/dist/core/extensions/types.js.map +1 -1
  15. package/dist/core/tools/bash.d.ts +5 -0
  16. package/dist/core/tools/bash.d.ts.map +1 -1
  17. package/dist/core/tools/bash.js +1 -1
  18. package/dist/core/tools/bash.js.map +1 -1
  19. package/dist/extensions/background/index.d.ts +95 -20
  20. package/dist/extensions/background/index.d.ts.map +1 -1
  21. package/dist/extensions/background/index.js +470 -136
  22. package/dist/extensions/background/index.js.map +1 -1
  23. package/dist/extensions/background/manager.d.ts +14 -0
  24. package/dist/extensions/background/manager.d.ts.map +1 -1
  25. package/dist/extensions/background/manager.js +125 -24
  26. package/dist/extensions/background/manager.js.map +1 -1
  27. package/dist/extensions/background/registry.d.ts +82 -0
  28. package/dist/extensions/background/registry.d.ts.map +1 -1
  29. package/dist/extensions/background/registry.js +237 -6
  30. package/dist/extensions/background/registry.js.map +1 -1
  31. package/dist/extensions/background/render.d.ts +35 -11
  32. package/dist/extensions/background/render.d.ts.map +1 -1
  33. package/dist/extensions/background/render.js +180 -30
  34. package/dist/extensions/background/render.js.map +1 -1
  35. package/dist/extensions/router/dialog-host.d.ts +60 -0
  36. package/dist/extensions/router/dialog-host.d.ts.map +1 -0
  37. package/dist/extensions/router/dialog-host.js +196 -0
  38. package/dist/extensions/router/dialog-host.js.map +1 -0
  39. package/dist/extensions/router/probe.d.ts.map +1 -1
  40. package/dist/extensions/router/probe.js +2 -0
  41. package/dist/extensions/router/probe.js.map +1 -1
  42. package/dist/extensions/router/ui.d.ts.map +1 -1
  43. package/dist/extensions/router/ui.js +117 -67
  44. package/dist/extensions/router/ui.js.map +1 -1
  45. package/dist/extensions/subagent/activity.d.ts +3 -5
  46. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  47. package/dist/extensions/subagent/activity.js +8 -89
  48. package/dist/extensions/subagent/activity.js.map +1 -1
  49. package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
  50. package/dist/extensions/subagent/agents-command.js +391 -161
  51. package/dist/extensions/subagent/agents-command.js.map +1 -1
  52. package/dist/extensions/subagent/agents.d.ts +2 -0
  53. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  54. package/dist/extensions/subagent/agents.js +7 -1
  55. package/dist/extensions/subagent/agents.js.map +1 -1
  56. package/dist/extensions/subagent/budget.d.ts +15 -0
  57. package/dist/extensions/subagent/budget.d.ts.map +1 -0
  58. package/dist/extensions/subagent/budget.js +96 -0
  59. package/dist/extensions/subagent/budget.js.map +1 -0
  60. package/dist/extensions/subagent/cancellation.d.ts +29 -0
  61. package/dist/extensions/subagent/cancellation.d.ts.map +1 -0
  62. package/dist/extensions/subagent/cancellation.js +73 -0
  63. package/dist/extensions/subagent/cancellation.js.map +1 -0
  64. package/dist/extensions/subagent/index.d.ts.map +1 -1
  65. package/dist/extensions/subagent/index.js +5 -22
  66. package/dist/extensions/subagent/index.js.map +1 -1
  67. package/dist/extensions/subagent/model-selection.d.ts +16 -0
  68. package/dist/extensions/subagent/model-selection.d.ts.map +1 -0
  69. package/dist/extensions/subagent/model-selection.js +51 -0
  70. package/dist/extensions/subagent/model-selection.js.map +1 -0
  71. package/dist/extensions/subagent/render.d.ts +6 -1
  72. package/dist/extensions/subagent/render.d.ts.map +1 -1
  73. package/dist/extensions/subagent/render.js +23 -12
  74. package/dist/extensions/subagent/render.js.map +1 -1
  75. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  76. package/dist/extensions/subagent/resolve.js +2 -21
  77. package/dist/extensions/subagent/resolve.js.map +1 -1
  78. package/dist/extensions/subagent/runner.d.ts +4 -5
  79. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  80. package/dist/extensions/subagent/runner.js +71 -264
  81. package/dist/extensions/subagent/runner.js.map +1 -1
  82. package/dist/extensions/subagent/sdk-runner.d.ts +13 -11
  83. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  84. package/dist/extensions/subagent/sdk-runner.js +167 -148
  85. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  86. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  87. package/dist/extensions/subagent/settings.js +11 -4
  88. package/dist/extensions/subagent/settings.js.map +1 -1
  89. package/dist/extensions/subagent/state.d.ts +89 -0
  90. package/dist/extensions/subagent/state.d.ts.map +1 -0
  91. package/dist/extensions/subagent/state.js +294 -0
  92. package/dist/extensions/subagent/state.js.map +1 -0
  93. package/dist/extensions/subagent/text.d.ts +4 -0
  94. package/dist/extensions/subagent/text.d.ts.map +1 -1
  95. package/dist/extensions/subagent/text.js +75 -0
  96. package/dist/extensions/subagent/text.js.map +1 -1
  97. package/dist/extensions/subagent/types.d.ts +3 -8
  98. package/dist/extensions/subagent/types.d.ts.map +1 -1
  99. package/dist/extensions/subagent/types.js.map +1 -1
  100. package/dist/extensions/subagent/ui/choices.d.ts +36 -0
  101. package/dist/extensions/subagent/ui/choices.d.ts.map +1 -0
  102. package/dist/extensions/subagent/ui/choices.js +54 -0
  103. package/dist/extensions/subagent/ui/choices.js.map +1 -0
  104. package/dist/extensions/subagent/ui/model-list.d.ts +1 -0
  105. package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
  106. package/dist/extensions/subagent/ui/model-list.js +15 -18
  107. package/dist/extensions/subagent/ui/model-list.js.map +1 -1
  108. package/dist/index.d.ts +1 -1
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js.map +1 -1
  111. package/docs/bundled/README.md +1 -1
  112. package/docs/bundled/extensions/background.md +55 -20
  113. package/docs/extensions.md +13 -0
  114. package/npm-shrinkwrap.json +2 -2
  115. package/package.json +1 -1
  116. package/dist/extensions/subagent/retry.d.ts +0 -17
  117. package/dist/extensions/subagent/retry.d.ts.map +0 -1
  118. package/dist/extensions/subagent/retry.js +0 -41
  119. package/dist/extensions/subagent/retry.js.map +0 -1
@@ -0,0 +1,89 @@
1
+ import type { Usage } from "@earendil-works/pi-ai";
2
+ import type { ResolvedSubagentTask, SubagentDetails, SubagentRunDetails, ToolActivity } from "./types.ts";
3
+ /**
4
+ * Mutable-run state plus an internal revision counter. All transitions go
5
+ * through {@link reduceRun}; the batch runner compares version sums instead
6
+ * of diffing rendered fields.
7
+ */
8
+ export interface SubagentRunState extends SubagentRunDetails {
9
+ /** Monotonic per-run revision; bumped by every applied event. */
10
+ version: number;
11
+ }
12
+ /** The adapter layer's only output and the reducer's only input. */
13
+ export type SubagentRunEvent = {
14
+ type: "slot_acquired";
15
+ startedAt: number;
16
+ } | {
17
+ type: "retry_scheduled";
18
+ attempt: number;
19
+ maxAttempts: number;
20
+ deadline: number;
21
+ error: string | undefined;
22
+ } | {
23
+ type: "retry_started";
24
+ } | {
25
+ type: "auto_retry_start";
26
+ attempt: number;
27
+ maxAttempts: number;
28
+ deadline: number;
29
+ error: string;
30
+ } | {
31
+ type: "auto_retry_end";
32
+ } | {
33
+ type: "turn_end";
34
+ } | {
35
+ type: "assistant_message_settled";
36
+ usage: Usage | undefined;
37
+ } | {
38
+ type: "tool_started";
39
+ toolCallId: string;
40
+ toolName: string;
41
+ args: unknown;
42
+ startedAt: number;
43
+ } | {
44
+ type: "tool_updated";
45
+ toolCallId: string;
46
+ toolName: string;
47
+ args: unknown;
48
+ } | {
49
+ type: "tool_ended";
50
+ toolCallId: string;
51
+ result: unknown;
52
+ isError: boolean;
53
+ endedAt: number;
54
+ } | {
55
+ type: "settle";
56
+ verdict: "completed" | "failed" | "aborted";
57
+ report: string;
58
+ error: string | undefined;
59
+ endedAt: number;
60
+ } | {
61
+ type: "abort_while_queued";
62
+ endedAt: number;
63
+ } | {
64
+ type: "abort_while_retrying";
65
+ endedAt: number;
66
+ };
67
+ export declare function createRunState(task: ResolvedSubagentTask, index: number, batchId: string | undefined, parentCwd: string): SubagentRunState;
68
+ /** Strips internal fields for projection into the public details shape. */
69
+ export declare function toRunDetails(state: SubagentRunState): SubagentRunDetails;
70
+ export declare function deriveCurrentActivity(state: SubagentRunState): string | undefined;
71
+ export declare function appendActivity(activities: ToolActivity[], activity: ToolActivity): void;
72
+ /**
73
+ * Pure transition function; timestamps and deadlines arrive in the event.
74
+ * Events applied after a terminal verdict are ignored (settle is idempotent)
75
+ * — except retry_scheduled, the one sanctioned reopening transition.
76
+ */
77
+ export declare function reduceRun(state: SubagentRunState, event: SubagentRunEvent): SubagentRunState;
78
+ export declare function versionSum(runs: readonly SubagentRunState[]): number;
79
+ export declare function statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails["status"];
80
+ export declare function isSubagentError(details: Pick<SubagentDetails, "status" | "runs">): boolean;
81
+ export declare function statusSummary(details: SubagentDetails): string;
82
+ export interface SubagentRetryView {
83
+ attempt: number;
84
+ maxAttempts: number;
85
+ remainingSeconds: number;
86
+ error: string;
87
+ }
88
+ export declare function getSubagentRetryView(run: SubagentRunDetails, now?: number): SubagentRetryView | undefined;
89
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,294 @@
1
+ import { relative } from "node:path";
2
+ import { activitySummary, addUsage, emptyUsage, resultSummary } from "./activity.js";
3
+ import { ACTIVITY_LIMIT, ACTIVITY_TEXT_LIMIT, ERROR_TEXT_LIMIT, RETRY_ERROR_TEXT_LIMIT, TASK_OUTPUT_LIMIT, } from "./constants.js";
4
+ import { modelId } from "./model-selection.js";
5
+ import { boundText } from "./text.js";
6
+ function runId(batchId, index) {
7
+ if (!batchId)
8
+ return `subagent-${index + 1}`;
9
+ // toolCallIds are provider-shaped ("call_ABC..."); keep the readable
10
+ // prefix, then disambiguate truncated collisions with a deterministic
11
+ // hash of the full id.
12
+ const sanitized = batchId.replace(/[^A-Za-z0-9-]+/gu, "-").replace(/^-+|-+$/gu, "");
13
+ const hash = hashRunId(batchId);
14
+ const prefix = sanitized.length > 24 ? `${sanitized.slice(0, 24)}-${hash}` : sanitized || `run-${hash}`;
15
+ return `${prefix}-${index + 1}`;
16
+ }
17
+ function hashRunId(value) {
18
+ let hash = 0x811c9dc5;
19
+ for (let index = 0; index < value.length; index++) {
20
+ hash ^= value.charCodeAt(index);
21
+ hash = Math.imul(hash, 0x01000193);
22
+ }
23
+ return (hash >>> 0).toString(36).padStart(6, "0").slice(0, 6);
24
+ }
25
+ export function createRunState(task, index, batchId, parentCwd) {
26
+ return {
27
+ id: runId(batchId, index),
28
+ agent: task.agent.name,
29
+ description: task.description,
30
+ // Display-only relative path; the worker session itself uses the
31
+ // resolved absolute task.cwd. Empty means "same as the parent".
32
+ cwd: relative(parentCwd, task.cwd),
33
+ model: modelId(task.model),
34
+ thinking: task.thinking,
35
+ status: "queued",
36
+ activities: [],
37
+ report: "",
38
+ usage: emptyUsage(),
39
+ version: 0,
40
+ };
41
+ }
42
+ /** Strips internal fields for projection into the public details shape. */
43
+ export function toRunDetails(state) {
44
+ const { version: _version, ...details } = state;
45
+ return details;
46
+ }
47
+ // The live "current activity" line is derived, never imperative: a pending
48
+ // retry wins, then the most recent still-running tool. This is what keeps a
49
+ // parallel batch's line correct when tools end out of order.
50
+ export function deriveCurrentActivity(state) {
51
+ if (state.status === "completed" || state.status === "failed" || state.status === "aborted")
52
+ return undefined;
53
+ if (state.retry)
54
+ return `Retrying (${state.retry.attempt}/${state.retry.maxAttempts})…`;
55
+ for (let index = state.activities.length - 1; index >= 0; index--) {
56
+ const activity = state.activities[index];
57
+ if (activity?.status === "running")
58
+ return activity.summary;
59
+ }
60
+ return undefined;
61
+ }
62
+ function positiveInteger(value, fallback) {
63
+ return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
64
+ }
65
+ function retryError(error) {
66
+ const normalized = error.replace(/\s+/gu, " ").trim();
67
+ return boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\s+/gu, " ").trim();
68
+ }
69
+ function makeRetry(attempt, maxAttempts, deadline, error) {
70
+ const normalizedAttempt = positiveInteger(attempt, 1);
71
+ return {
72
+ attempt: normalizedAttempt,
73
+ maxAttempts: Math.max(normalizedAttempt, positiveInteger(maxAttempts, normalizedAttempt)),
74
+ deadline,
75
+ error: retryError(error),
76
+ };
77
+ }
78
+ // The in-memory activity log keeps the newest entries within both the count
79
+ // and text budgets; a bounded O(ACTIVITY_LIMIT) rescan per event replaces
80
+ // incremental byte bookkeeping. Exported for direct budget tests: real
81
+ // events bound every summary, so the text-budget eviction is otherwise
82
+ // purely defensive.
83
+ export function appendActivity(activities, activity) {
84
+ activities.push(activity);
85
+ while (activities.length > ACTIVITY_LIMIT)
86
+ activities.shift();
87
+ while (activities.reduce((total, item) => total + item.summary.length + (item.resultSummary?.length ?? 0), 0) >
88
+ ACTIVITY_TEXT_LIMIT) {
89
+ if (activities.length <= 1)
90
+ break;
91
+ activities.shift();
92
+ }
93
+ }
94
+ function isTerminal(state) {
95
+ return state.status === "completed" || state.status === "failed" || state.status === "aborted";
96
+ }
97
+ function withRevision(state, mutate) {
98
+ const draft = {
99
+ ...state,
100
+ activities: state.activities.map((activity) => ({ ...activity })),
101
+ usage: { ...state.usage },
102
+ };
103
+ mutate(draft);
104
+ draft.version = state.version + 1;
105
+ return draft;
106
+ }
107
+ function clearRetry(draft) {
108
+ draft.retry = undefined;
109
+ }
110
+ /**
111
+ * Pure transition function; timestamps and deadlines arrive in the event.
112
+ * Events applied after a terminal verdict are ignored (settle is idempotent)
113
+ * — except retry_scheduled, the one sanctioned reopening transition.
114
+ */
115
+ export function reduceRun(state, event) {
116
+ if (isTerminal(state) && event.type !== "retry_scheduled")
117
+ return state;
118
+ switch (event.type) {
119
+ case "slot_acquired":
120
+ return withRevision(state, (draft) => {
121
+ clearRetry(draft);
122
+ draft.status = "running";
123
+ draft.startedAt = event.startedAt;
124
+ draft.currentActivity = deriveCurrentActivity(draft);
125
+ });
126
+ case "retry_scheduled":
127
+ // The full reset matrix from the historical resetRunForRetry: only
128
+ // runs that produced nothing are retried, so nothing of value is
129
+ // discarded. The retry view stays visible through the backoff.
130
+ return withRevision(state, (draft) => {
131
+ const error = draft.error ?? "Subagent failed before retry.";
132
+ draft.status = "queued";
133
+ draft.error = undefined;
134
+ draft.startedAt = undefined;
135
+ draft.endedAt = undefined;
136
+ draft.report = "";
137
+ draft.activities = [];
138
+ draft.usage = emptyUsage();
139
+ draft.retry = makeRetry(event.attempt, event.maxAttempts, event.deadline, error);
140
+ draft.currentActivity = deriveCurrentActivity(draft);
141
+ });
142
+ case "retry_started":
143
+ return withRevision(state, (draft) => {
144
+ clearRetry(draft);
145
+ draft.currentActivity = deriveCurrentActivity(draft);
146
+ });
147
+ case "auto_retry_start":
148
+ return withRevision(state, (draft) => {
149
+ draft.retry = makeRetry(event.attempt, event.maxAttempts, event.deadline, event.error);
150
+ draft.currentActivity = deriveCurrentActivity(draft);
151
+ });
152
+ case "auto_retry_end":
153
+ return withRevision(state, (draft) => {
154
+ clearRetry(draft);
155
+ draft.currentActivity = deriveCurrentActivity(draft);
156
+ });
157
+ case "turn_end":
158
+ return withRevision(state, (draft) => {
159
+ clearRetry(draft);
160
+ draft.usage.turns++;
161
+ draft.currentActivity = deriveCurrentActivity(draft);
162
+ });
163
+ case "assistant_message_settled":
164
+ return withRevision(state, (draft) => {
165
+ clearRetry(draft);
166
+ addUsage(draft.usage, event.usage);
167
+ draft.currentActivity = deriveCurrentActivity(draft);
168
+ });
169
+ case "tool_started":
170
+ return withRevision(state, (draft) => {
171
+ clearRetry(draft);
172
+ draft.usage.toolUses++;
173
+ appendActivity(draft.activities, {
174
+ id: event.toolCallId,
175
+ toolName: event.toolName,
176
+ summary: activitySummary(event.toolName, event.args),
177
+ status: "running",
178
+ startedAt: event.startedAt,
179
+ });
180
+ draft.currentActivity = deriveCurrentActivity(draft);
181
+ });
182
+ case "tool_updated": {
183
+ const summary = activitySummary(event.toolName, event.args);
184
+ return withRevision(state, (draft) => {
185
+ clearRetry(draft);
186
+ const activity = draft.activities.find((candidate) => candidate.id === event.toolCallId && candidate.status === "running") ?? [...draft.activities].reverse().find((candidate) => candidate.status === "running");
187
+ if (activity)
188
+ activity.summary = summary;
189
+ draft.currentActivity = deriveCurrentActivity(draft);
190
+ });
191
+ }
192
+ case "tool_ended":
193
+ return withRevision(state, (draft) => {
194
+ clearRetry(draft);
195
+ const activity = draft.activities.find((candidate) => candidate.id === event.toolCallId);
196
+ if (activity && activity.status === "running") {
197
+ activity.status = event.isError ? "failed" : "succeeded";
198
+ activity.endedAt = event.endedAt;
199
+ activity.resultSummary = resultSummary(event.result) || undefined;
200
+ }
201
+ draft.currentActivity = deriveCurrentActivity(draft);
202
+ });
203
+ case "settle":
204
+ return withRevision(state, (draft) => {
205
+ draft.status = event.verdict;
206
+ draft.report = boundText(event.report, TASK_OUTPUT_LIMIT);
207
+ draft.error = event.error ? boundText(event.error, ERROR_TEXT_LIMIT) : undefined;
208
+ draft.endedAt = event.endedAt;
209
+ draft.retry = undefined;
210
+ draft.currentActivity = deriveCurrentActivity({ ...draft, status: event.verdict });
211
+ });
212
+ case "abort_while_queued":
213
+ return withRevision(state, (draft) => {
214
+ draft.status = "aborted";
215
+ draft.error = "Subagent was aborted while queued.";
216
+ draft.endedAt = event.endedAt;
217
+ draft.retry = undefined;
218
+ draft.currentActivity = undefined;
219
+ });
220
+ case "abort_while_retrying":
221
+ return withRevision(state, (draft) => {
222
+ draft.status = "aborted";
223
+ draft.error = "Subagent was aborted while waiting to retry.";
224
+ draft.endedAt = event.endedAt;
225
+ draft.retry = undefined;
226
+ draft.currentActivity = undefined;
227
+ });
228
+ }
229
+ }
230
+ export function versionSum(runs) {
231
+ let total = 0;
232
+ for (const run of runs)
233
+ total += run.version;
234
+ return total;
235
+ }
236
+ export function statusOf(runs) {
237
+ if (runs.length === 0)
238
+ return "running";
239
+ // Active beats terminal: any queued or running run keeps the batch
240
+ // "running" regardless of what the others have settled to.
241
+ if (runs.some((run) => run.status === "queued" || run.status === "running"))
242
+ return "running";
243
+ if (runs.every((run) => run.status === "completed"))
244
+ return "completed";
245
+ if (runs.some((run) => run.status === "completed"))
246
+ return "partial";
247
+ if (runs.every((run) => run.status === "aborted"))
248
+ return "aborted";
249
+ return "failed";
250
+ }
251
+ export function isSubagentError(details) {
252
+ if (details.status !== "failed" && details.status !== "aborted")
253
+ return false;
254
+ // A batch with any successful run is a partial result, not an error:
255
+ // per-run status is already reported in the content sections.
256
+ return !details.runs.some((run) => run.status === "completed");
257
+ }
258
+ function statusText(details) {
259
+ if (details.runs.length === 0)
260
+ return "Initializing…";
261
+ const running = details.runs.filter((run) => run.status === "running").length;
262
+ const queued = details.runs.filter((run) => run.status === "queued").length;
263
+ const completed = details.runs.filter((run) => run.status === "completed").length;
264
+ const failed = details.runs.filter((run) => run.status === "failed").length;
265
+ const aborted = details.runs.filter((run) => run.status === "aborted").length;
266
+ const parts = [`${completed}/${details.runs.length} complete`];
267
+ if (running)
268
+ parts.push(`${running} running`);
269
+ if (queued)
270
+ parts.push(`${queued} queued`);
271
+ if (failed)
272
+ parts.push(`${failed} failed`);
273
+ if (aborted)
274
+ parts.push(`${aborted} aborted`);
275
+ return parts.join(" · ");
276
+ }
277
+ export function statusSummary(details) {
278
+ return statusText(details);
279
+ }
280
+ export function getSubagentRetryView(run, now = Date.now()) {
281
+ const retry = run.retry;
282
+ if (!retry || !Number.isFinite(retry.deadline))
283
+ return undefined;
284
+ const attempt = positiveInteger(retry.attempt, 1);
285
+ const maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));
286
+ const currentTime = Number.isFinite(now) ? now : retry.deadline;
287
+ return {
288
+ attempt,
289
+ maxAttempts,
290
+ remainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),
291
+ error: retryError(typeof retry.error === "string" ? retry.error : ""),
292
+ };
293
+ }
294
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/extensions/subagent/state.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from \"node:path\";\nimport type { Usage } from \"@earendil-works/pi-ai\";\nimport { activitySummary, addUsage, emptyUsage, resultSummary } from \"./activity.ts\";\nimport {\n\tACTIVITY_LIMIT,\n\tACTIVITY_TEXT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tTASK_OUTPUT_LIMIT,\n} from \"./constants.ts\";\nimport { modelId } from \"./model-selection.ts\";\nimport { boundText } from \"./text.ts\";\nimport type { ResolvedSubagentTask, SubagentDetails, SubagentRunDetails, ToolActivity } from \"./types.ts\";\n\n/**\n * Mutable-run state plus an internal revision counter. All transitions go\n * through {@link reduceRun}; the batch runner compares version sums instead\n * of diffing rendered fields.\n */\nexport interface SubagentRunState extends SubagentRunDetails {\n\t/** Monotonic per-run revision; bumped by every applied event. */\n\tversion: number;\n}\n\n/** The adapter layer's only output and the reducer's only input. */\nexport type SubagentRunEvent =\n\t| { type: \"slot_acquired\"; startedAt: number }\n\t| {\n\t\t\ttype: \"retry_scheduled\";\n\t\t\tattempt: number;\n\t\t\tmaxAttempts: number;\n\t\t\tdeadline: number;\n\t\t\terror: string | undefined;\n\t }\n\t| { type: \"retry_started\" }\n\t| { type: \"auto_retry_start\"; attempt: number; maxAttempts: number; deadline: number; error: string }\n\t| { type: \"auto_retry_end\" }\n\t| { type: \"turn_end\" }\n\t| { type: \"assistant_message_settled\"; usage: Usage | undefined }\n\t| { type: \"tool_started\"; toolCallId: string; toolName: string; args: unknown; startedAt: number }\n\t| { type: \"tool_updated\"; toolCallId: string; toolName: string; args: unknown }\n\t| { type: \"tool_ended\"; toolCallId: string; result: unknown; isError: boolean; endedAt: number }\n\t| {\n\t\t\ttype: \"settle\";\n\t\t\tverdict: \"completed\" | \"failed\" | \"aborted\";\n\t\t\treport: string;\n\t\t\terror: string | undefined;\n\t\t\tendedAt: number;\n\t }\n\t| { type: \"abort_while_queued\"; endedAt: number }\n\t| { type: \"abort_while_retrying\"; endedAt: number };\n\nfunction runId(batchId: string | undefined, index: number): string {\n\tif (!batchId) return `subagent-${index + 1}`;\n\t// toolCallIds are provider-shaped (\"call_ABC...\"); keep the readable\n\t// prefix, then disambiguate truncated collisions with a deterministic\n\t// hash of the full id.\n\tconst sanitized = batchId.replace(/[^A-Za-z0-9-]+/gu, \"-\").replace(/^-+|-+$/gu, \"\");\n\tconst hash = hashRunId(batchId);\n\tconst prefix = sanitized.length > 24 ? `${sanitized.slice(0, 24)}-${hash}` : sanitized || `run-${hash}`;\n\treturn `${prefix}-${index + 1}`;\n}\n\nfunction hashRunId(value: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < value.length; index++) {\n\t\thash ^= value.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36).padStart(6, \"0\").slice(0, 6);\n}\n\nexport function createRunState(\n\ttask: ResolvedSubagentTask,\n\tindex: number,\n\tbatchId: string | undefined,\n\tparentCwd: string,\n): SubagentRunState {\n\treturn {\n\t\tid: runId(batchId, index),\n\t\tagent: task.agent.name,\n\t\tdescription: task.description,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: modelId(task.model),\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\treport: \"\",\n\t\tusage: emptyUsage(),\n\t\tversion: 0,\n\t};\n}\n\n/** Strips internal fields for projection into the public details shape. */\nexport function toRunDetails(state: SubagentRunState): SubagentRunDetails {\n\tconst { version: _version, ...details } = state;\n\treturn details;\n}\n\n// The live \"current activity\" line is derived, never imperative: a pending\n// retry wins, then the most recent still-running tool. This is what keeps a\n// parallel batch's line correct when tools end out of order.\nexport function deriveCurrentActivity(state: SubagentRunState): string | undefined {\n\tif (state.status === \"completed\" || state.status === \"failed\" || state.status === \"aborted\") return undefined;\n\tif (state.retry) return `Retrying (${state.retry.attempt}/${state.retry.maxAttempts})…`;\n\tfor (let index = state.activities.length - 1; index >= 0; index--) {\n\t\tconst activity = state.activities[index];\n\t\tif (activity?.status === \"running\") return activity.summary;\n\t}\n\treturn undefined;\n}\n\nfunction positiveInteger(value: number, fallback: number): number {\n\treturn Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;\n}\n\nfunction retryError(error: string): string {\n\tconst normalized = error.replace(/\\s+/gu, \" \").trim();\n\treturn boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\\s+/gu, \" \").trim();\n}\n\nfunction makeRetry(attempt: number, maxAttempts: number, deadline: number, error: string): SubagentRunState[\"retry\"] {\n\tconst normalizedAttempt = positiveInteger(attempt, 1);\n\treturn {\n\t\tattempt: normalizedAttempt,\n\t\tmaxAttempts: Math.max(normalizedAttempt, positiveInteger(maxAttempts, normalizedAttempt)),\n\t\tdeadline,\n\t\terror: retryError(error),\n\t};\n}\n\n// The in-memory activity log keeps the newest entries within both the count\n// and text budgets; a bounded O(ACTIVITY_LIMIT) rescan per event replaces\n// incremental byte bookkeeping. Exported for direct budget tests: real\n// events bound every summary, so the text-budget eviction is otherwise\n// purely defensive.\nexport function appendActivity(activities: ToolActivity[], activity: ToolActivity): void {\n\tactivities.push(activity);\n\twhile (activities.length > ACTIVITY_LIMIT) activities.shift();\n\twhile (\n\t\tactivities.reduce((total, item) => total + item.summary.length + (item.resultSummary?.length ?? 0), 0) >\n\t\tACTIVITY_TEXT_LIMIT\n\t) {\n\t\tif (activities.length <= 1) break;\n\t\tactivities.shift();\n\t}\n}\n\nfunction isTerminal(state: SubagentRunState): boolean {\n\treturn state.status === \"completed\" || state.status === \"failed\" || state.status === \"aborted\";\n}\n\nfunction withRevision(state: SubagentRunState, mutate: (draft: SubagentRunState) => void): SubagentRunState {\n\tconst draft: SubagentRunState = {\n\t\t...state,\n\t\tactivities: state.activities.map((activity) => ({ ...activity })),\n\t\tusage: { ...state.usage },\n\t};\n\tmutate(draft);\n\tdraft.version = state.version + 1;\n\treturn draft;\n}\n\nfunction clearRetry(draft: SubagentRunState): void {\n\tdraft.retry = undefined;\n}\n\n/**\n * Pure transition function; timestamps and deadlines arrive in the event.\n * Events applied after a terminal verdict are ignored (settle is idempotent)\n * — except retry_scheduled, the one sanctioned reopening transition.\n */\nexport function reduceRun(state: SubagentRunState, event: SubagentRunEvent): SubagentRunState {\n\tif (isTerminal(state) && event.type !== \"retry_scheduled\") return state;\n\n\tswitch (event.type) {\n\t\tcase \"slot_acquired\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tdraft.status = \"running\";\n\t\t\t\tdraft.startedAt = event.startedAt;\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"retry_scheduled\":\n\t\t\t// The full reset matrix from the historical resetRunForRetry: only\n\t\t\t// runs that produced nothing are retried, so nothing of value is\n\t\t\t// discarded. The retry view stays visible through the backoff.\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tconst error = draft.error ?? \"Subagent failed before retry.\";\n\t\t\t\tdraft.status = \"queued\";\n\t\t\t\tdraft.error = undefined;\n\t\t\t\tdraft.startedAt = undefined;\n\t\t\t\tdraft.endedAt = undefined;\n\t\t\t\tdraft.report = \"\";\n\t\t\t\tdraft.activities = [];\n\t\t\t\tdraft.usage = emptyUsage();\n\t\t\t\tdraft.retry = makeRetry(event.attempt, event.maxAttempts, event.deadline, error);\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"retry_started\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"auto_retry_start\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tdraft.retry = makeRetry(event.attempt, event.maxAttempts, event.deadline, event.error);\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"auto_retry_end\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"turn_end\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tdraft.usage.turns++;\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"assistant_message_settled\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\taddUsage(draft.usage, event.usage);\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"tool_started\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tdraft.usage.toolUses++;\n\t\t\t\tappendActivity(draft.activities, {\n\t\t\t\t\tid: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\tsummary: activitySummary(event.toolName, event.args),\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt: event.startedAt,\n\t\t\t\t});\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"tool_updated\": {\n\t\t\tconst summary = activitySummary(event.toolName, event.args);\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tconst activity =\n\t\t\t\t\tdraft.activities.find(\n\t\t\t\t\t\t(candidate) => candidate.id === event.toolCallId && candidate.status === \"running\",\n\t\t\t\t\t) ?? [...draft.activities].reverse().find((candidate) => candidate.status === \"running\");\n\t\t\t\tif (activity) activity.summary = summary;\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\t}\n\t\tcase \"tool_ended\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tclearRetry(draft);\n\t\t\t\tconst activity = draft.activities.find((candidate) => candidate.id === event.toolCallId);\n\t\t\t\tif (activity && activity.status === \"running\") {\n\t\t\t\t\tactivity.status = event.isError ? \"failed\" : \"succeeded\";\n\t\t\t\t\tactivity.endedAt = event.endedAt;\n\t\t\t\t\tactivity.resultSummary = resultSummary(event.result) || undefined;\n\t\t\t\t}\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity(draft);\n\t\t\t});\n\t\tcase \"settle\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tdraft.status = event.verdict;\n\t\t\t\tdraft.report = boundText(event.report, TASK_OUTPUT_LIMIT);\n\t\t\t\tdraft.error = event.error ? boundText(event.error, ERROR_TEXT_LIMIT) : undefined;\n\t\t\t\tdraft.endedAt = event.endedAt;\n\t\t\t\tdraft.retry = undefined;\n\t\t\t\tdraft.currentActivity = deriveCurrentActivity({ ...draft, status: event.verdict });\n\t\t\t});\n\t\tcase \"abort_while_queued\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tdraft.status = \"aborted\";\n\t\t\t\tdraft.error = \"Subagent was aborted while queued.\";\n\t\t\t\tdraft.endedAt = event.endedAt;\n\t\t\t\tdraft.retry = undefined;\n\t\t\t\tdraft.currentActivity = undefined;\n\t\t\t});\n\t\tcase \"abort_while_retrying\":\n\t\t\treturn withRevision(state, (draft) => {\n\t\t\t\tdraft.status = \"aborted\";\n\t\t\t\tdraft.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\t\tdraft.endedAt = event.endedAt;\n\t\t\t\tdraft.retry = undefined;\n\t\t\t\tdraft.currentActivity = undefined;\n\t\t\t});\n\t}\n}\n\nexport function versionSum(runs: readonly SubagentRunState[]): number {\n\tlet total = 0;\n\tfor (const run of runs) total += run.version;\n\treturn total;\n}\n\nexport function statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.length === 0) return \"running\";\n\t// Active beats terminal: any queued or running run keeps the batch\n\t// \"running\" regardless of what the others have settled to.\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\tif (runs.every((run) => run.status === \"completed\")) return \"completed\";\n\tif (runs.some((run) => run.status === \"completed\")) return \"partial\";\n\tif (runs.every((run) => run.status === \"aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tif (details.runs.length === 0) return \"Initializing…\";\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n\nexport interface SubagentRetryView {\n\tattempt: number;\n\tmaxAttempts: number;\n\tremainingSeconds: number;\n\terror: string;\n}\n\nexport function getSubagentRetryView(run: SubagentRunDetails, now = Date.now()): SubagentRetryView | undefined {\n\tconst retry = run.retry;\n\tif (!retry || !Number.isFinite(retry.deadline)) return undefined;\n\tconst attempt = positiveInteger(retry.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));\n\tconst currentTime = Number.isFinite(now) ? now : retry.deadline;\n\treturn {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tremainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),\n\t\terror: retryError(typeof retry.error === \"string\" ? retry.error : \"\"),\n\t};\n}\n"]}
@@ -1,3 +1,7 @@
1
1
  export declare function plainLine(text: string): string;
2
2
  export declare function firstPlainLine(text: string): string;
3
+ export declare function truncate(text: string, limit: number): string;
4
+ export declare function utf8Prefix(text: string, maxBytes: number): string;
5
+ export declare function boundText(text: string, maxBytes: number): string;
6
+ export declare function tailText(text: string, maxBytes: number): string;
3
7
  //# sourceMappingURL=text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/text.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/text.ts"],"names":[],"mappings":"AAGA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD;AAID,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5D;AAGD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYjE;AAgBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBhE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAS/D"}
@@ -1,3 +1,5 @@
1
+ // Text utilities shared across the subagent extension: plain-text
2
+ // projection, UTF-8 byte bounding, and code-point truncation.
1
3
  export function plainLine(text) {
2
4
  return text
3
5
  .replace(/^\s*#{1,6}\s+/u, "")
@@ -13,4 +15,77 @@ export function firstPlainLine(text) {
13
15
  .map((line) => plainLine(line))
14
16
  .find(Boolean) ?? "");
15
17
  }
18
+ // Truncates by code points (never splitting a surrogate pair) and appends an
19
+ // ellipsis; for UTF-8 byte budgets use boundText/tailText instead.
20
+ export function truncate(text, limit) {
21
+ const characters = [...text];
22
+ return characters.length <= limit ? text : `${characters.slice(0, Math.max(0, limit - 1)).join("")}…`;
23
+ }
24
+ // Iterates code points so a surrogate pair is never split in half.
25
+ export function utf8Prefix(text, maxBytes) {
26
+ if (maxBytes <= 0)
27
+ return "";
28
+ if (Buffer.byteLength(text, "utf8") <= maxBytes)
29
+ return text;
30
+ let output = "";
31
+ let bytes = 0;
32
+ for (const character of text) {
33
+ const characterBytes = Buffer.byteLength(character, "utf8");
34
+ if (bytes + characterBytes > maxBytes)
35
+ break;
36
+ output += character;
37
+ bytes += characterBytes;
38
+ }
39
+ return output;
40
+ }
41
+ function utf8Suffix(text, maxBytes) {
42
+ if (maxBytes <= 0)
43
+ return "";
44
+ if (Buffer.byteLength(text, "utf8") <= maxBytes)
45
+ return text;
46
+ const characters = [];
47
+ let bytes = 0;
48
+ for (const character of Array.from(text).reverse()) {
49
+ const characterBytes = Buffer.byteLength(character, "utf8");
50
+ if (bytes + characterBytes > maxBytes)
51
+ break;
52
+ characters.push(character);
53
+ bytes += characterBytes;
54
+ }
55
+ return characters.reverse().join("");
56
+ }
57
+ export function boundText(text, maxBytes) {
58
+ if (maxBytes <= 0)
59
+ return "";
60
+ if (Buffer.byteLength(text, "utf8") <= maxBytes)
61
+ return text;
62
+ let output = utf8Prefix(text, maxBytes);
63
+ for (let attempt = 0; attempt < 8; attempt++) {
64
+ const omitted = Buffer.byteLength(text, "utf8") - Buffer.byteLength(output, "utf8");
65
+ const notice = `\n\n[Output truncated: ${omitted} bytes omitted.]`;
66
+ const available = maxBytes - Buffer.byteLength(notice, "utf8");
67
+ if (available <= 0)
68
+ return utf8Prefix("[Output truncated.]", maxBytes);
69
+ const next = utf8Prefix(text, available);
70
+ if (next === output)
71
+ return `${output}${notice}`;
72
+ output = next;
73
+ }
74
+ const omitted = Buffer.byteLength(text, "utf8") - Buffer.byteLength(output, "utf8");
75
+ const notice = `\n\n[Output truncated: ${omitted} bytes omitted.]`;
76
+ return `${utf8Prefix(output, Math.max(0, maxBytes - Buffer.byteLength(notice, "utf8")))}${notice}`;
77
+ }
78
+ export function tailText(text, maxBytes) {
79
+ if (maxBytes <= 0)
80
+ return "";
81
+ if (Buffer.byteLength(text, "utf8") <= maxBytes)
82
+ return text;
83
+ const noticeText = "[Earlier output omitted.]";
84
+ const notice = `${noticeText}\n`;
85
+ const available = maxBytes - Buffer.byteLength(notice, "utf8");
86
+ if (available <= 0)
87
+ return utf8Prefix(noticeText, maxBytes);
88
+ const output = utf8Suffix(text, available);
89
+ return output ? `${notice}${output}` : utf8Prefix(noticeText, maxBytes);
90
+ }
16
91
  //# sourceMappingURL=text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/extensions/subagent/text.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;IACrC,OAAO,IAAI;SACT,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC;SAC7B,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;SAC5B,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC;SAClC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC;SACxC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,IAAI,EAAE,CAAC;AACV,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,CACN,IAAI;SACF,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CACrB,CAAC;AACH,CAAC","sourcesContent":["export function plainLine(text: string): string {\n\treturn text\n\t\t.replace(/^\\s*#{1,6}\\s+/u, \"\")\n\t\t.replace(/`([^`]*)`/gu, \"$1\")\n\t\t.replace(/\\*\\*([^*]+)\\*\\*/gu, \"$1\")\n\t\t.replace(/\\[([^\\]]+)\\]\\([^)]*\\)/gu, \"$1\")\n\t\t.replace(/\\s+/gu, \" \")\n\t\t.trim();\n}\n\nexport function firstPlainLine(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => plainLine(line))\n\t\t\t.find(Boolean) ?? \"\"\n\t);\n}\n"]}
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/extensions/subagent/text.ts"],"names":[],"mappings":"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","sourcesContent":["// Text utilities shared across the subagent extension: plain-text\n// projection, UTF-8 byte bounding, and code-point truncation.\n\nexport function plainLine(text: string): string {\n\treturn text\n\t\t.replace(/^\\s*#{1,6}\\s+/u, \"\")\n\t\t.replace(/`([^`]*)`/gu, \"$1\")\n\t\t.replace(/\\*\\*([^*]+)\\*\\*/gu, \"$1\")\n\t\t.replace(/\\[([^\\]]+)\\]\\([^)]*\\)/gu, \"$1\")\n\t\t.replace(/\\s+/gu, \" \")\n\t\t.trim();\n}\n\nexport function firstPlainLine(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => plainLine(line))\n\t\t\t.find(Boolean) ?? \"\"\n\t);\n}\n\n// Truncates by code points (never splitting a surrogate pair) and appends an\n// ellipsis; for UTF-8 byte budgets use boundText/tailText instead.\nexport function truncate(text: string, limit: number): string {\n\tconst characters = [...text];\n\treturn characters.length <= limit ? text : `${characters.slice(0, Math.max(0, limit - 1)).join(\"\")}…`;\n}\n\n// Iterates code points so a surrogate pair is never split in half.\nexport function utf8Prefix(text: string, maxBytes: number): string {\n\tif (maxBytes <= 0) return \"\";\n\tif (Buffer.byteLength(text, \"utf8\") <= maxBytes) return text;\n\tlet output = \"\";\n\tlet bytes = 0;\n\tfor (const character of text) {\n\t\tconst characterBytes = Buffer.byteLength(character, \"utf8\");\n\t\tif (bytes + characterBytes > maxBytes) break;\n\t\toutput += character;\n\t\tbytes += characterBytes;\n\t}\n\treturn output;\n}\n\nfunction utf8Suffix(text: string, maxBytes: number): string {\n\tif (maxBytes <= 0) return \"\";\n\tif (Buffer.byteLength(text, \"utf8\") <= maxBytes) return text;\n\tconst characters: string[] = [];\n\tlet bytes = 0;\n\tfor (const character of Array.from(text).reverse()) {\n\t\tconst characterBytes = Buffer.byteLength(character, \"utf8\");\n\t\tif (bytes + characterBytes > maxBytes) break;\n\t\tcharacters.push(character);\n\t\tbytes += characterBytes;\n\t}\n\treturn characters.reverse().join(\"\");\n}\n\nexport function boundText(text: string, maxBytes: number): string {\n\tif (maxBytes <= 0) return \"\";\n\tif (Buffer.byteLength(text, \"utf8\") <= maxBytes) return text;\n\tlet output = utf8Prefix(text, maxBytes);\n\tfor (let attempt = 0; attempt < 8; attempt++) {\n\t\tconst omitted = Buffer.byteLength(text, \"utf8\") - Buffer.byteLength(output, \"utf8\");\n\t\tconst notice = `\\n\\n[Output truncated: ${omitted} bytes omitted.]`;\n\t\tconst available = maxBytes - Buffer.byteLength(notice, \"utf8\");\n\t\tif (available <= 0) return utf8Prefix(\"[Output truncated.]\", maxBytes);\n\t\tconst next = utf8Prefix(text, available);\n\t\tif (next === output) return `${output}${notice}`;\n\t\toutput = next;\n\t}\n\tconst omitted = Buffer.byteLength(text, \"utf8\") - Buffer.byteLength(output, \"utf8\");\n\tconst notice = `\\n\\n[Output truncated: ${omitted} bytes omitted.]`;\n\treturn `${utf8Prefix(output, Math.max(0, maxBytes - Buffer.byteLength(notice, \"utf8\")))}${notice}`;\n}\n\nexport function tailText(text: string, maxBytes: number): string {\n\tif (maxBytes <= 0) return \"\";\n\tif (Buffer.byteLength(text, \"utf8\") <= maxBytes) return text;\n\tconst noticeText = \"[Earlier output omitted.]\";\n\tconst notice = `${noticeText}\\n`;\n\tconst available = maxBytes - Buffer.byteLength(notice, \"utf8\");\n\tif (available <= 0) return utf8Prefix(noticeText, maxBytes);\n\tconst output = utf8Suffix(text, available);\n\treturn output ? `${notice}${output}` : utf8Prefix(noticeText, maxBytes);\n}\n"]}
@@ -42,18 +42,13 @@ export interface ToolActivity {
42
42
  endedAt?: number;
43
43
  resultSummary?: string;
44
44
  }
45
- export interface SubagentUsage {
45
+ export type SubagentUsage = Omit<Usage, "cost"> & {
46
+ cost: number;
46
47
  turns: number;
47
48
  toolUses: number;
48
- input: number;
49
- output: number;
50
- cacheRead: number;
51
- cacheWrite: number;
52
- totalTokens: number;
53
- cost: number;
54
49
  /** Context watermark: total tokens of the latest request, not a running sum. */
55
50
  contextTokens?: number;
56
- }
51
+ };
57
52
  export interface SubagentRetryDetails {
58
53
  attempt: number;
59
54
  maxAttempts: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/extensions/subagent/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model, Usage } from \"@earendil-works/pi-ai\";\nimport type { SubagentAgentName } from \"./constants.ts\";\n\n// Static built-in subagent profile; the only agents a task can select.\nexport interface AgentProfile {\n\tname: SubagentAgentName;\n\tdescription: string;\n\ttools: string[];\n\tsystemPrompt: string;\n\t/**\n\t * Skip loading AGENTS.md/CLAUDE.md into the worker's system prompt.\n\t * Read-only exploration doesn't need commit/PR/style rules; the parent\n\t * has full context to interpret results.\n\t */\n\tomitContextFiles?: boolean;\n}\n\nexport interface SubagentProfileOverride {\n\tmodel?: string;\n\tthinking?: ThinkingLevel;\n}\n\nexport interface SubagentConfigFile {\n\tversion: 1;\n\t// Absence means \"inherit the parent session\"; only the two built-in\n\t// profiles exist, so unknown keys are rejected by settings.ts.\n\tprofiles: Partial<Record<SubagentAgentName, SubagentProfileOverride>>;\n}\n\nexport interface ResolvedSubagentTask {\n\tagent: AgentProfile;\n\tdescription: string;\n\tprompt: string;\n\tcwd: string;\n\tmodel: Model<Api>;\n\tthinking: ThinkingLevel;\n}\n\nexport type SubagentRunStatus = \"queued\" | \"running\" | \"completed\" | \"failed\" | \"aborted\";\n/** Aggregate batch status; active runs beat every terminal verdict. */\nexport type SubagentBatchStatus = \"running\" | \"completed\" | \"partial\" | \"failed\" | \"aborted\";\nexport type ToolActivityStatus = \"running\" | \"succeeded\" | \"failed\";\n\nexport interface ToolActivity {\n\tid: string;\n\ttoolName: string;\n\tsummary: string;\n\tstatus: ToolActivityStatus;\n\tstartedAt: number;\n\tendedAt?: number;\n\tresultSummary?: string;\n}\n\nexport interface SubagentUsage {\n\tturns: number;\n\ttoolUses: number;\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: number;\n\t/** Context watermark: total tokens of the latest request, not a running sum. */\n\tcontextTokens?: number;\n}\n\nexport interface SubagentRetryDetails {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdeadline: number;\n\terror: string;\n}\n\nexport interface SubagentRunDetails {\n\tid: string;\n\tagent: string;\n\tdescription: string;\n\tcwd: string;\n\tmodel: string;\n\tthinking: ThinkingLevel;\n\tstatus: SubagentRunStatus;\n\tstartedAt?: number;\n\tendedAt?: number;\n\tcurrentActivity?: string;\n\tretry?: SubagentRetryDetails;\n\tactivities: ToolActivity[];\n\t/** Final assistant report; empty until the worker settles. */\n\treport: string;\n\terror?: string;\n\tusage: SubagentUsage;\n}\n\nexport interface SubagentDetails {\n\tstatus: SubagentBatchStatus;\n\truns: SubagentRunDetails[];\n\tstartedAt: number;\n\tendedAt?: number;\n\tusage: SubagentUsage;\n}\n\nexport interface SubagentExecutionResult {\n\tcontent: string;\n\tdetails: SubagentDetails;\n\tusage?: Usage;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/extensions/subagent/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model, Usage } from \"@earendil-works/pi-ai\";\nimport type { SubagentAgentName } from \"./constants.ts\";\n\n// Static built-in subagent profile; the only agents a task can select.\nexport interface AgentProfile {\n\tname: SubagentAgentName;\n\tdescription: string;\n\ttools: string[];\n\tsystemPrompt: string;\n\t/**\n\t * Skip loading AGENTS.md/CLAUDE.md into the worker's system prompt.\n\t * Read-only exploration doesn't need commit/PR/style rules; the parent\n\t * has full context to interpret results.\n\t */\n\tomitContextFiles?: boolean;\n}\n\nexport interface SubagentProfileOverride {\n\tmodel?: string;\n\tthinking?: ThinkingLevel;\n}\n\nexport interface SubagentConfigFile {\n\tversion: 1;\n\t// Absence means \"inherit the parent session\"; only the two built-in\n\t// profiles exist, so unknown keys are rejected by settings.ts.\n\tprofiles: Partial<Record<SubagentAgentName, SubagentProfileOverride>>;\n}\n\nexport interface ResolvedSubagentTask {\n\tagent: AgentProfile;\n\tdescription: string;\n\tprompt: string;\n\tcwd: string;\n\tmodel: Model<Api>;\n\tthinking: ThinkingLevel;\n}\n\nexport type SubagentRunStatus = \"queued\" | \"running\" | \"completed\" | \"failed\" | \"aborted\";\n/** Aggregate batch status; active runs beat every terminal verdict. */\nexport type SubagentBatchStatus = \"running\" | \"completed\" | \"partial\" | \"failed\" | \"aborted\";\nexport type ToolActivityStatus = \"running\" | \"succeeded\" | \"failed\";\n\nexport interface ToolActivity {\n\tid: string;\n\ttoolName: string;\n\tsummary: string;\n\tstatus: ToolActivityStatus;\n\tstartedAt: number;\n\tendedAt?: number;\n\tresultSummary?: string;\n}\n\n// Flat projection of pi-ai's Usage: the cost breakdown collapses to a\n// scalar total (renderers need one number; toNestedUsage rebuilds the nested\n// shape for the parent transcript), and turns/toolUses/contextTokens track\n// worker progress. The optional pi-ai fields (reasoning, cacheWrite1h) stay\n// optional here and are not aggregated.\nexport type SubagentUsage = Omit<Usage, \"cost\"> & {\n\tcost: number;\n\tturns: number;\n\ttoolUses: number;\n\t/** Context watermark: total tokens of the latest request, not a running sum. */\n\tcontextTokens?: number;\n};\n\nexport interface SubagentRetryDetails {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdeadline: number;\n\terror: string;\n}\n\nexport interface SubagentRunDetails {\n\tid: string;\n\tagent: string;\n\tdescription: string;\n\tcwd: string;\n\tmodel: string;\n\tthinking: ThinkingLevel;\n\tstatus: SubagentRunStatus;\n\tstartedAt?: number;\n\tendedAt?: number;\n\tcurrentActivity?: string;\n\tretry?: SubagentRetryDetails;\n\tactivities: ToolActivity[];\n\t/** Final assistant report; empty until the worker settles. */\n\treport: string;\n\terror?: string;\n\tusage: SubagentUsage;\n}\n\nexport interface SubagentDetails {\n\tstatus: SubagentBatchStatus;\n\truns: SubagentRunDetails[];\n\tstartedAt: number;\n\tendedAt?: number;\n\tusage: SubagentUsage;\n}\n\nexport interface SubagentExecutionResult {\n\tcontent: string;\n\tdetails: SubagentDetails;\n\tusage?: Usage;\n}\n"]}