@astralyn/pi 1.4.5 → 1.4.6

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 (169) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/bundle/chunks/{chunk-I5S7H7GA.js → chunk-EYKC6ESU.js} +1 -1
  3. package/dist/bundle/chunks/chunk-KDO6L76C.js +230 -0
  4. package/dist/bundle/chunks/chunk-RBTJBQWX.js +1500 -0
  5. package/dist/bundle/chunks/{execute-GMFGC27P.js → execute-5ZQUS52M.js} +1 -1
  6. package/dist/bundle/chunks/{virtual-modules-6FUV7ZDV.js → virtual-modules-KCQU7LOC.js} +1 -1
  7. package/dist/bundle/cli.js +1 -1
  8. package/dist/bundle/index.js +1 -1
  9. package/dist/bundle/rpc-entry.js +1 -1
  10. package/dist/core/extensions/index.d.ts +1 -1
  11. package/dist/core/extensions/index.d.ts.map +1 -1
  12. package/dist/core/extensions/index.js.map +1 -1
  13. package/dist/core/isolated-session.d.ts +23 -0
  14. package/dist/core/isolated-session.d.ts.map +1 -0
  15. package/dist/core/isolated-session.js +55 -0
  16. package/dist/core/isolated-session.js.map +1 -0
  17. package/dist/core/tasks/codec.d.ts +12 -0
  18. package/dist/core/tasks/codec.d.ts.map +1 -0
  19. package/dist/core/tasks/codec.js +139 -0
  20. package/dist/core/tasks/codec.js.map +1 -0
  21. package/dist/core/tasks/execution.d.ts +64 -0
  22. package/dist/core/tasks/execution.d.ts.map +1 -0
  23. package/dist/core/tasks/execution.js +272 -0
  24. package/dist/core/tasks/execution.js.map +1 -0
  25. package/dist/core/tasks/output.d.ts +12 -6
  26. package/dist/core/tasks/output.d.ts.map +1 -1
  27. package/dist/core/tasks/output.js +38 -38
  28. package/dist/core/tasks/output.js.map +1 -1
  29. package/dist/core/tasks/presentation.d.ts +14 -5
  30. package/dist/core/tasks/presentation.d.ts.map +1 -1
  31. package/dist/core/tasks/presentation.js +56 -185
  32. package/dist/core/tasks/presentation.js.map +1 -1
  33. package/dist/core/tasks/runtime.d.ts +9 -9
  34. package/dist/core/tasks/runtime.d.ts.map +1 -1
  35. package/dist/core/tasks/runtime.js +63 -254
  36. package/dist/core/tasks/runtime.js.map +1 -1
  37. package/dist/core/tasks/scheduler.d.ts +16 -0
  38. package/dist/core/tasks/scheduler.d.ts.map +1 -0
  39. package/dist/core/tasks/scheduler.js +42 -0
  40. package/dist/core/tasks/scheduler.js.map +1 -0
  41. package/dist/core/tasks/session.d.ts +1 -0
  42. package/dist/core/tasks/session.d.ts.map +1 -1
  43. package/dist/core/tasks/session.js +15 -27
  44. package/dist/core/tasks/session.js.map +1 -1
  45. package/dist/core/tasks/store.js +4 -4
  46. package/dist/core/tasks/store.js.map +1 -1
  47. package/dist/core/tasks/types.d.ts +63 -53
  48. package/dist/core/tasks/types.d.ts.map +1 -1
  49. package/dist/core/tasks/types.js +3 -9
  50. package/dist/core/tasks/types.js.map +1 -1
  51. package/dist/core/tools/shell-execution.js +4 -4
  52. package/dist/core/tools/shell-execution.js.map +1 -1
  53. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  54. package/dist/core/tools/shell-tool.js +23 -30
  55. package/dist/core/tools/shell-tool.js.map +1 -1
  56. package/dist/core/usage-totals.d.ts +1 -3
  57. package/dist/core/usage-totals.d.ts.map +1 -1
  58. package/dist/core/usage-totals.js +17 -8
  59. package/dist/core/usage-totals.js.map +1 -1
  60. package/dist/extensions/agent/activity.d.ts +4 -4
  61. package/dist/extensions/agent/activity.d.ts.map +1 -1
  62. package/dist/extensions/agent/activity.js +15 -24
  63. package/dist/extensions/agent/activity.js.map +1 -1
  64. package/dist/extensions/agent/index.d.ts +2 -11
  65. package/dist/extensions/agent/index.d.ts.map +1 -1
  66. package/dist/extensions/agent/index.js +3 -88
  67. package/dist/extensions/agent/index.js.map +1 -1
  68. package/dist/extensions/agent/progress.d.ts +31 -0
  69. package/dist/extensions/agent/progress.d.ts.map +1 -0
  70. package/dist/extensions/agent/progress.js +145 -0
  71. package/dist/extensions/agent/progress.js.map +1 -0
  72. package/dist/extensions/agent/render.d.ts.map +1 -1
  73. package/dist/extensions/agent/render.js +8 -17
  74. package/dist/extensions/agent/render.js.map +1 -1
  75. package/dist/extensions/agent/report.d.ts +9 -0
  76. package/dist/extensions/agent/report.d.ts.map +1 -0
  77. package/dist/extensions/agent/report.js +40 -0
  78. package/dist/extensions/agent/report.js.map +1 -0
  79. package/dist/extensions/agent/settings-panel.d.ts +43 -0
  80. package/dist/extensions/agent/settings-panel.d.ts.map +1 -0
  81. package/dist/extensions/agent/settings-panel.js +125 -0
  82. package/dist/extensions/agent/settings-panel.js.map +1 -0
  83. package/dist/extensions/agent/settings.d.ts +1 -1
  84. package/dist/extensions/agent/settings.d.ts.map +1 -1
  85. package/dist/extensions/agent/settings.js +101 -83
  86. package/dist/extensions/agent/settings.js.map +1 -1
  87. package/dist/extensions/agent/tool.d.ts +13 -0
  88. package/dist/extensions/agent/tool.d.ts.map +1 -0
  89. package/dist/extensions/agent/tool.js +84 -0
  90. package/dist/extensions/agent/tool.js.map +1 -0
  91. package/dist/extensions/agent/types.d.ts +19 -21
  92. package/dist/extensions/agent/types.d.ts.map +1 -1
  93. package/dist/extensions/agent/types.js +2 -10
  94. package/dist/extensions/agent/types.js.map +1 -1
  95. package/dist/extensions/agent/worker.d.ts +16 -0
  96. package/dist/extensions/agent/worker.d.ts.map +1 -0
  97. package/dist/extensions/agent/worker.js +68 -0
  98. package/dist/extensions/agent/worker.js.map +1 -0
  99. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  100. package/dist/extensions/tasks/tool/actions.js +1 -9
  101. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  102. package/dist/extensions/tasks/tool/schema.js +1 -1
  103. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  104. package/dist/extensions/tasks/tool/types.d.ts +2 -8
  105. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  106. package/dist/extensions/tasks/tool/types.js +0 -2
  107. package/dist/extensions/tasks/tool/types.js.map +1 -1
  108. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  109. package/dist/extensions/tasks/ui/completion-render.js +27 -26
  110. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  111. package/dist/extensions/tasks/ui/inspector.d.ts +5 -3
  112. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  113. package/dist/extensions/tasks/ui/inspector.js +18 -6
  114. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  115. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
  116. package/dist/extensions/tasks/ui/layout.js +111 -75
  117. package/dist/extensions/tasks/ui/layout.js.map +1 -1
  118. package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
  119. package/dist/extensions/tasks/ui/list.js +43 -28
  120. package/dist/extensions/tasks/ui/list.js.map +1 -1
  121. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  122. package/dist/extensions/tasks/ui/manager.js +8 -2
  123. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  124. package/dist/extensions/tasks/ui/model.d.ts +4 -0
  125. package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
  126. package/dist/extensions/tasks/ui/model.js +12 -1
  127. package/dist/extensions/tasks/ui/model.js.map +1 -1
  128. package/dist/extensions/tasks/ui/render.js +3 -4
  129. package/dist/extensions/tasks/ui/render.js.map +1 -1
  130. package/dist/extensions/tasks/ui/task-view.d.ts +0 -5
  131. package/dist/extensions/tasks/ui/task-view.d.ts.map +1 -1
  132. package/dist/extensions/tasks/ui/task-view.js +0 -7
  133. package/dist/extensions/tasks/ui/task-view.js.map +1 -1
  134. package/dist/extensions/tasks/ui/tree.js +1 -1
  135. package/dist/extensions/tasks/ui/tree.js.map +1 -1
  136. package/dist/extensions/tasks/ui/views.d.ts +10 -5
  137. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  138. package/dist/extensions/tasks/ui/views.js +61 -36
  139. package/dist/extensions/tasks/ui/views.js.map +1 -1
  140. package/dist/index.d.ts +2 -1
  141. package/dist/index.d.ts.map +1 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  144. package/dist/modes/interactive/components/keybinding-hints.js +2 -1
  145. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  146. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  147. package/dist/modes/interactive/components/model-selector.js +7 -4
  148. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  149. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  150. package/dist/modes/interactive/components/thinking-selector.js +10 -3
  151. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  152. package/docs/bundled/extensions/agent.md +12 -10
  153. package/docs/bundled/extensions/statusline.md +1 -1
  154. package/docs/bundled/tasks.md +15 -14
  155. package/docs/extensions.md +22 -6
  156. package/docs/sdk.md +2 -2
  157. package/docs/session-format.md +27 -23
  158. package/npm-shrinkwrap.json +2 -2
  159. package/package.json +1 -1
  160. package/dist/bundle/chunks/chunk-FSJ45CRP.js +0 -229
  161. package/dist/bundle/chunks/chunk-W3FIUMGM.js +0 -1501
  162. package/dist/core/tasks/history.d.ts +0 -4
  163. package/dist/core/tasks/history.d.ts.map +0 -1
  164. package/dist/core/tasks/history.js +0 -131
  165. package/dist/core/tasks/history.js.map +0 -1
  166. package/dist/extensions/agent/runner.d.ts +0 -24
  167. package/dist/extensions/agent/runner.d.ts.map +0 -1
  168. package/dist/extensions/agent/runner.js +0 -274
  169. package/dist/extensions/agent/runner.js.map +0 -1
@@ -1,181 +1,28 @@
1
1
  import { truncateHead, truncateTail } from "../tools/truncate.js";
2
- import { boundTail, boundText, TASK_DETAILS_BYTES, TASK_RESULT_BYTES, TASK_TITLE_BYTES } from "./output.js";
3
- const OUTPUT_BYTES = 40 * 1024;
4
- /** Replay keeps the larger snapshot; automatic model turns get only a small readable tail. */
5
- const MODEL_OUTPUT_BYTES = 8 * 1024;
2
+ import { TASK_SNAPSHOT_VERSION } from "./codec.js";
3
+ import { boundTail, boundText, TASK_DETAILS_BYTES, TASK_RESULT_BYTES } from "./output.js";
4
+ /** Automatic model turns get only a small readable log tail; reports arrive whole. */
5
+ const MODEL_LOG_BYTES = 8 * 1024;
6
6
  const MODEL_LINES = 2000;
7
- /** Read data properties only, including at the persisted-message boundary. */
8
- function object(value) {
9
- if (!value || typeof value !== "object" || Array.isArray(value))
10
- throw new Error("Expected snapshot object");
11
- const prototype = Object.getPrototypeOf(value);
12
- if (prototype !== Object.prototype && prototype !== null)
13
- throw new Error("Expected plain snapshot");
14
- return value;
15
- }
16
- function field(value, key) {
17
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
18
- if (descriptor && !("value" in descriptor))
19
- throw new Error("Unexpected snapshot accessor");
20
- return descriptor?.value;
21
- }
22
- /** Bound escaped JSON as well as UTF-8, without serializing an unbounded source. */
23
- function string(value, bytes) {
24
- if (typeof value !== "string")
25
- throw new Error("Expected snapshot text");
26
- const prefix = boundText(value, bytes - 2);
27
- if (Buffer.byteLength(JSON.stringify(prefix)) <= bytes)
28
- return prefix;
29
- let low = 0;
30
- let high = Buffer.byteLength(prefix);
31
- while (low < high) {
32
- const middle = Math.ceil((low + high) / 2);
33
- if (Buffer.byteLength(JSON.stringify(boundText(prefix, middle))) <= bytes)
34
- low = middle;
35
- else
36
- high = middle - 1;
37
- }
38
- return boundText(prefix, low);
39
- }
40
- /** The end of a text whose escaped JSON fits `bytes`: a command's outcome is at its end. */
41
- function tail(value, bytes) {
42
- const fits = (size) => Buffer.byteLength(JSON.stringify(boundTail(value, size).text)) <= bytes;
43
- let low = 0;
44
- let high = Buffer.byteLength(value);
45
- if (fits(high))
46
- return { text: value, truncated: false };
47
- while (low < high) {
48
- const middle = Math.ceil((low + high) / 2);
49
- if (fits(middle))
50
- low = middle;
51
- else
52
- high = middle - 1;
53
- }
54
- return boundTail(value, low);
55
- }
56
- function optionalString(source, key, bytes) {
57
- const value = field(source, key);
58
- return value === undefined ? undefined : string(value, bytes);
59
- }
60
- function text(value, bytes) {
61
- const source = object(value);
62
- const original = field(source, "text");
63
- const truncated = field(source, "truncated");
64
- if (typeof truncated !== "boolean")
65
- throw new Error("Expected truncation flag");
66
- const bounded = string(original, bytes);
67
- return { text: bounded, truncated: truncated || bounded !== original };
68
- }
69
- function terminalStatus(value) {
70
- if (value === "completed" ||
71
- value === "partial" ||
72
- value === "failed" ||
73
- value === "cancelled" ||
74
- value === "timeout")
75
- return value;
76
- throw new Error("Expected terminal status");
77
- }
78
- /** Only this format is understood. Invalid/older details receive the renderer's bounded plain-text fallback. */
79
- export function readTaskCompletion(value) {
80
- try {
81
- const source = object(value);
82
- if (field(source, "version") !== 2)
83
- return undefined;
84
- const taskId = field(source, "taskId");
85
- const kind = field(source, "kind");
86
- if (typeof kind !== "string" || !/^[a-z][a-z0-9-]{0,63}$/.test(kind))
87
- return undefined;
88
- if (typeof taskId !== "string" ||
89
- !taskId.startsWith(`${kind}-`) ||
90
- taskId.length <= kind.length + 1 ||
91
- taskId.length > 512 ||
92
- Buffer.byteLength(taskId) > 512 ||
93
- taskId.includes("\0"))
94
- return undefined;
95
- const startedAt = field(source, "startedAt");
96
- const endedAt = field(source, "endedAt");
97
- if (typeof startedAt !== "number" ||
98
- !Number.isSafeInteger(startedAt) ||
99
- startedAt < 0 ||
100
- typeof endedAt !== "number" ||
101
- !Number.isSafeInteger(endedAt) ||
102
- endedAt < startedAt)
103
- return undefined;
104
- const command = field(source, "command");
105
- const outputPath = field(source, "outputPath");
106
- const exitCode = field(source, "exitCode");
107
- if (exitCode !== undefined &&
108
- exitCode !== null &&
109
- (typeof exitCode !== "number" || !Number.isSafeInteger(exitCode)))
110
- return undefined;
111
- // A clipped path would name a different file. Omit oversized paths intact.
112
- if (outputPath !== undefined && typeof outputPath !== "string")
113
- return undefined;
114
- const snapshot = {
115
- version: 2,
116
- kind,
117
- taskId,
118
- title: string(field(source, "title"), TASK_TITLE_BYTES),
119
- status: terminalStatus(field(source, "status")),
120
- startedAt,
121
- endedAt,
122
- error: optionalString(source, "error", 4096),
123
- command: command === undefined ? undefined : text(command, 8192),
124
- cwd: optionalString(source, "cwd", 4096),
125
- outputPath: outputPath &&
126
- !outputPath.includes("\0") &&
127
- outputPath.length <= 8192 &&
128
- Buffer.byteLength(JSON.stringify(outputPath)) <= 8192
129
- ? outputPath
130
- : undefined,
131
- ...(exitCode !== undefined ? { exitCode } : {}),
132
- output: text(field(source, "output"), OUTPUT_BYTES),
133
- };
134
- return Buffer.byteLength(JSON.stringify(snapshot)) <= TASK_DETAILS_BYTES ? snapshot : undefined;
135
- }
136
- catch {
137
- return undefined;
138
- }
139
- }
140
- export function taskCompletionSnapshot(task) {
141
- const result = task.result?.content
142
- .filter((block) => block.type === "text")
143
- .map((block) => block.text)
144
- .join("\n") ?? "";
145
- const output = tail(result, OUTPUT_BYTES);
146
- const snapshot = readTaskCompletion({
147
- version: 2,
148
- kind: task.kind,
149
- taskId: task.id,
150
- title: task.title,
151
- status: task.status,
152
- startedAt: task.startedAt,
153
- endedAt: task.endedAt,
154
- error: task.error,
155
- command: task.command === undefined ? undefined : { text: task.command, truncated: task.commandTruncated ?? false },
156
- cwd: task.cwd,
157
- outputPath: task.outputPath,
158
- ...(task.exitCode !== undefined ? { exitCode: task.exitCode } : {}),
159
- output: { text: output.text, truncated: output.truncated || (task.resultTruncated ?? false) },
160
- });
161
- if (!snapshot)
162
- throw new Error("Invalid task completion snapshot");
163
- return snapshot;
164
- }
7
+ /** Replay copies of the output and input inside completion details. */
8
+ const REPLAY_OUTPUT_BYTES = [40 * 1024, 16 * 1024, 4 * 1024, 0];
9
+ const REPLAY_INPUT_BYTES = 8 * 1024;
165
10
  const singleLine = (value) => value.replace(/\s+/gu, " ").trim();
11
+ const bytes = (value) => Buffer.byteLength(value);
166
12
  const OMISSION = "\n[Saved output truncated; use tasks read for retained task details.]";
167
- function modelText(value, bytes, lines) {
13
+ const EARLIER_OMISSION = "[Earlier output truncated; use tasks read for retained task details.]\n";
14
+ /** A report keeps its beginning, where its summary is. */
15
+ function modelHead(value, maxBytes, lines) {
168
16
  const result = truncateHead(value.text, {
169
- maxBytes: Math.max(0, bytes - Buffer.byteLength(OMISSION)),
17
+ maxBytes: Math.max(0, maxBytes - bytes(OMISSION)),
170
18
  maxLines: Math.max(1, lines - 1),
171
19
  });
172
20
  return result.content + (value.truncated || result.truncated ? OMISSION : "");
173
21
  }
174
- const EARLIER_OMISSION = "[Earlier output truncated; use tasks read for retained task details.]\n";
175
- /** Output keeps its end, where the outcome is. */
176
- function modelTail(value, bytes, lines) {
22
+ /** A log keeps its end, where the outcome is. */
23
+ function modelTail(value, maxBytes, lines) {
177
24
  const result = truncateTail(value.text, {
178
- maxBytes: Math.max(0, bytes - Buffer.byteLength(EARLIER_OMISSION)),
25
+ maxBytes: Math.max(0, maxBytes - bytes(EARLIER_OMISSION)),
179
26
  maxLines: Math.max(1, lines - 1),
180
27
  });
181
28
  return (value.truncated || result.truncated ? EARLIER_OMISSION : "") + result.content;
@@ -194,34 +41,58 @@ function nextStepLine(status) {
194
41
  return "";
195
42
  }
196
43
  }
197
- /** The context and the card share facts; only the context receives this prose projection. */
198
- function notificationText(snapshot) {
44
+ /**
45
+ * The model-facing text of a settled background task. A report reaches the model as its
46
+ * foreground result would have; a log contributes only its tail to the automatic turn.
47
+ */
48
+ export function projectForModel(task) {
199
49
  const header = [
200
- `Background ${snapshot.kind} ${snapshot.taskId}: ${snapshot.status}${snapshot.command ? "" : ` — ${singleLine(snapshot.title)}`}`,
201
- snapshot.error ? `Error: ${singleLine(snapshot.error)}` : "",
50
+ boundText(`Background ${task.kind} ${task.id}: ${task.status} — ${singleLine(task.title)}`, 2048),
51
+ task.error ? `Error: ${singleLine(task.error)}` : "",
52
+ ...(task.facts ?? []).map(([label, value]) => `${label}: ${singleLine(value)}`),
53
+ task.outputPath ? `Output: ${singleLine(task.outputPath)}` : "",
202
54
  ].filter(Boolean);
203
- if (snapshot.command)
204
- header.push(`Command:\n${modelText(snapshot.command, 8192, 128)}`);
205
- if (snapshot.cwd)
206
- header.push(`cwd: ${singleLine(snapshot.cwd)}`);
207
- if (snapshot.outputPath)
208
- header.push(`Output: ${singleLine(snapshot.outputPath)}`);
209
55
  const prefix = `${header.join("\n")}\n\n`;
210
- const guidance = nextStepLine(snapshot.status);
56
+ const guidance = nextStepLine(task.status);
211
57
  const suffix = guidance ? `\n\n${guidance}` : "";
212
- const remaining = Math.min(MODEL_OUTPUT_BYTES, TASK_RESULT_BYTES - Buffer.byteLength(prefix) - Buffer.byteLength(suffix));
58
+ const budget = TASK_RESULT_BYTES - bytes(prefix) - bytes(suffix);
213
59
  const lines = MODEL_LINES - prefix.split("\n").length - (guidance ? 3 : 0);
214
- const output = snapshot.output.text ? snapshot.output : { text: "No text result.", truncated: false };
215
- return prefix + modelTail(output, remaining, lines) + suffix;
60
+ const output = task.result?.text ? task.result : { text: "No text result.", truncated: false };
61
+ const body = task.output === "report"
62
+ ? modelHead(output, budget, lines)
63
+ : modelTail(output, Math.min(MODEL_LOG_BYTES, budget), lines);
64
+ return prefix + body + suffix;
65
+ }
66
+ function clipped(value, maxBytes, keep) {
67
+ const text = keep === "head" ? boundText(value.text, maxBytes) : boundTail(value.text, maxBytes).text;
68
+ return { text, truncated: value.truncated || text !== value.text };
69
+ }
70
+ /** A self-contained replay snapshot within the details budget; human-only display stays in the session record. */
71
+ export function taskCompletionDetails(task) {
72
+ const { display: _display, result, input, ...rest } = task;
73
+ const keep = task.output === "report" ? "head" : "tail";
74
+ const replayInput = input && { ...input, ...clipped(input, REPLAY_INPUT_BYTES, "head") };
75
+ for (const outputBytes of REPLAY_OUTPUT_BYTES) {
76
+ const details = {
77
+ version: TASK_SNAPSHOT_VERSION,
78
+ task: {
79
+ ...rest,
80
+ ...(replayInput ? { input: replayInput } : {}),
81
+ ...(result && outputBytes > 0 ? { result: clipped(result, outputBytes, keep) } : {}),
82
+ },
83
+ };
84
+ if (bytes(JSON.stringify(details)) <= TASK_DETAILS_BYTES)
85
+ return details;
86
+ }
87
+ return { version: TASK_SNAPSHOT_VERSION, task: rest };
216
88
  }
217
89
  export function taskCompletionMessage(task) {
218
- const details = taskCompletionSnapshot(task);
219
90
  return {
220
91
  role: "custom",
221
92
  customType: "task-completion",
222
93
  display: true,
223
- content: notificationText(details),
224
- details,
94
+ content: projectForModel(task),
95
+ details: taskCompletionDetails(task),
225
96
  timestamp: Date.now(),
226
97
  };
227
98
  }
@@ -1 +1 @@
1
- {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../../../src/core/tasks/presentation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CustomMessage } from \"../messages.ts\";\nimport { truncateHead, truncateTail } from \"../tools/truncate.ts\";\nimport { boundTail, boundText, TASK_DETAILS_BYTES, TASK_RESULT_BYTES, TASK_TITLE_BYTES } from \"./output.ts\";\nimport type { TaskCompletionSnapshot, TaskSnapshot, TaskTerminalStatus, TaskText } from \"./types.ts\";\n\nconst OUTPUT_BYTES = 40 * 1024;\n/** Replay keeps the larger snapshot; automatic model turns get only a small readable tail. */\nconst MODEL_OUTPUT_BYTES = 8 * 1024;\nconst MODEL_LINES = 2000;\n\n/** Read data properties only, including at the persisted-message boundary. */\nfunction object(value: unknown): object {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"Expected snapshot object\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (prototype !== Object.prototype && prototype !== null) throw new Error(\"Expected plain snapshot\");\n\treturn value;\n}\n\nfunction field(value: object, key: string): unknown {\n\tconst descriptor = Object.getOwnPropertyDescriptor(value, key);\n\tif (descriptor && !(\"value\" in descriptor)) throw new Error(\"Unexpected snapshot accessor\");\n\treturn descriptor?.value;\n}\n\n/** Bound escaped JSON as well as UTF-8, without serializing an unbounded source. */\nfunction string(value: unknown, bytes: number): string {\n\tif (typeof value !== \"string\") throw new Error(\"Expected snapshot text\");\n\tconst prefix = boundText(value, bytes - 2);\n\tif (Buffer.byteLength(JSON.stringify(prefix)) <= bytes) return prefix;\n\tlet low = 0;\n\tlet high = Buffer.byteLength(prefix);\n\twhile (low < high) {\n\t\tconst middle = Math.ceil((low + high) / 2);\n\t\tif (Buffer.byteLength(JSON.stringify(boundText(prefix, middle))) <= bytes) low = middle;\n\t\telse high = middle - 1;\n\t}\n\treturn boundText(prefix, low);\n}\n\n/** The end of a text whose escaped JSON fits `bytes`: a command's outcome is at its end. */\nfunction tail(value: string, bytes: number): TaskText {\n\tconst fits = (size: number) => Buffer.byteLength(JSON.stringify(boundTail(value, size).text)) <= bytes;\n\tlet low = 0;\n\tlet high = Buffer.byteLength(value);\n\tif (fits(high)) return { text: value, truncated: false };\n\twhile (low < high) {\n\t\tconst middle = Math.ceil((low + high) / 2);\n\t\tif (fits(middle)) low = middle;\n\t\telse high = middle - 1;\n\t}\n\treturn boundTail(value, low);\n}\n\nfunction optionalString(source: object, key: string, bytes: number): string | undefined {\n\tconst value = field(source, key);\n\treturn value === undefined ? undefined : string(value, bytes);\n}\n\nfunction text(value: unknown, bytes: number): TaskText {\n\tconst source = object(value);\n\tconst original = field(source, \"text\");\n\tconst truncated = field(source, \"truncated\");\n\tif (typeof truncated !== \"boolean\") throw new Error(\"Expected truncation flag\");\n\tconst bounded = string(original, bytes);\n\treturn { text: bounded, truncated: truncated || bounded !== original };\n}\n\nfunction terminalStatus(value: unknown): TaskTerminalStatus {\n\tif (\n\t\tvalue === \"completed\" ||\n\t\tvalue === \"partial\" ||\n\t\tvalue === \"failed\" ||\n\t\tvalue === \"cancelled\" ||\n\t\tvalue === \"timeout\"\n\t)\n\t\treturn value;\n\tthrow new Error(\"Expected terminal status\");\n}\n\n/** Only this format is understood. Invalid/older details receive the renderer's bounded plain-text fallback. */\nexport function readTaskCompletion(value: unknown): TaskCompletionSnapshot | undefined {\n\ttry {\n\t\tconst source = object(value);\n\t\tif (field(source, \"version\") !== 2) return undefined;\n\t\tconst taskId = field(source, \"taskId\");\n\t\tconst kind = field(source, \"kind\");\n\t\tif (typeof kind !== \"string\" || !/^[a-z][a-z0-9-]{0,63}$/.test(kind)) return undefined;\n\t\tif (\n\t\t\ttypeof taskId !== \"string\" ||\n\t\t\t!taskId.startsWith(`${kind}-`) ||\n\t\t\ttaskId.length <= kind.length + 1 ||\n\t\t\ttaskId.length > 512 ||\n\t\t\tBuffer.byteLength(taskId) > 512 ||\n\t\t\ttaskId.includes(\"\\0\")\n\t\t)\n\t\t\treturn undefined;\n\t\tconst startedAt = field(source, \"startedAt\");\n\t\tconst endedAt = field(source, \"endedAt\");\n\t\tif (\n\t\t\ttypeof startedAt !== \"number\" ||\n\t\t\t!Number.isSafeInteger(startedAt) ||\n\t\t\tstartedAt < 0 ||\n\t\t\ttypeof endedAt !== \"number\" ||\n\t\t\t!Number.isSafeInteger(endedAt) ||\n\t\t\tendedAt < startedAt\n\t\t)\n\t\t\treturn undefined;\n\t\tconst command = field(source, \"command\");\n\t\tconst outputPath = field(source, \"outputPath\");\n\t\tconst exitCode = field(source, \"exitCode\");\n\t\tif (\n\t\t\texitCode !== undefined &&\n\t\t\texitCode !== null &&\n\t\t\t(typeof exitCode !== \"number\" || !Number.isSafeInteger(exitCode))\n\t\t)\n\t\t\treturn undefined;\n\t\t// A clipped path would name a different file. Omit oversized paths intact.\n\t\tif (outputPath !== undefined && typeof outputPath !== \"string\") return undefined;\n\t\tconst snapshot: TaskCompletionSnapshot = {\n\t\t\tversion: 2,\n\t\t\tkind,\n\t\t\ttaskId,\n\t\t\ttitle: string(field(source, \"title\"), TASK_TITLE_BYTES),\n\t\t\tstatus: terminalStatus(field(source, \"status\")),\n\t\t\tstartedAt,\n\t\t\tendedAt,\n\t\t\terror: optionalString(source, \"error\", 4096),\n\t\t\tcommand: command === undefined ? undefined : text(command, 8192),\n\t\t\tcwd: optionalString(source, \"cwd\", 4096),\n\t\t\toutputPath:\n\t\t\t\toutputPath &&\n\t\t\t\t!outputPath.includes(\"\\0\") &&\n\t\t\t\toutputPath.length <= 8192 &&\n\t\t\t\tBuffer.byteLength(JSON.stringify(outputPath)) <= 8192\n\t\t\t\t\t? outputPath\n\t\t\t\t\t: undefined,\n\t\t\t...(exitCode !== undefined ? { exitCode } : {}),\n\t\t\toutput: text(field(source, \"output\"), OUTPUT_BYTES),\n\t\t};\n\t\treturn Buffer.byteLength(JSON.stringify(snapshot)) <= TASK_DETAILS_BYTES ? snapshot : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function taskCompletionSnapshot(task: TaskSnapshot): TaskCompletionSnapshot {\n\tconst result =\n\t\ttask.result?.content\n\t\t\t.filter((block) => block.type === \"text\")\n\t\t\t.map((block) => block.text)\n\t\t\t.join(\"\\n\") ?? \"\";\n\tconst output = tail(result, OUTPUT_BYTES);\n\tconst snapshot = readTaskCompletion({\n\t\tversion: 2,\n\t\tkind: task.kind,\n\t\ttaskId: task.id,\n\t\ttitle: task.title,\n\t\tstatus: task.status,\n\t\tstartedAt: task.startedAt,\n\t\tendedAt: task.endedAt,\n\t\terror: task.error,\n\t\tcommand:\n\t\t\ttask.command === undefined ? undefined : { text: task.command, truncated: task.commandTruncated ?? false },\n\t\tcwd: task.cwd,\n\t\toutputPath: task.outputPath,\n\t\t...(task.exitCode !== undefined ? { exitCode: task.exitCode } : {}),\n\t\toutput: { text: output.text, truncated: output.truncated || (task.resultTruncated ?? false) },\n\t});\n\tif (!snapshot) throw new Error(\"Invalid task completion snapshot\");\n\treturn snapshot;\n}\n\nconst singleLine = (value: string) => value.replace(/\\s+/gu, \" \").trim();\nconst OMISSION = \"\\n[Saved output truncated; use tasks read for retained task details.]\";\n\nfunction modelText(value: TaskText, bytes: number, lines: number): string {\n\tconst result = truncateHead(value.text, {\n\t\tmaxBytes: Math.max(0, bytes - Buffer.byteLength(OMISSION)),\n\t\tmaxLines: Math.max(1, lines - 1),\n\t});\n\treturn result.content + (value.truncated || result.truncated ? OMISSION : \"\");\n}\n\nconst EARLIER_OMISSION = \"[Earlier output truncated; use tasks read for retained task details.]\\n\";\n\n/** Output keeps its end, where the outcome is. */\nfunction modelTail(value: TaskText, bytes: number, lines: number): string {\n\tconst result = truncateTail(value.text, {\n\t\tmaxBytes: Math.max(0, bytes - Buffer.byteLength(EARLIER_OMISSION)),\n\t\tmaxLines: Math.max(1, lines - 1),\n\t});\n\treturn (value.truncated || result.truncated ? EARLIER_OMISSION : \"\") + result.content;\n}\n\n/** One bounded action hint per terminal outcome; completed work needs none. */\nfunction nextStepLine(status: TaskTerminalStatus): string {\n\tswitch (status) {\n\t\tcase \"cancelled\":\n\t\t\treturn \"Next step: the task was cancelled — do not restart it unless the user asks.\";\n\t\tcase \"timeout\":\n\t\t\treturn \"Next step: the task hit its timeout; inspect the partial output above, then rerun with a longer timeout or in smaller pieces if still needed.\";\n\t\tcase \"failed\":\n\t\tcase \"partial\":\n\t\t\treturn \"Next step: diagnose from the output above before retrying; rerun only what is still needed.\";\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\n/** The context and the card share facts; only the context receives this prose projection. */\nfunction notificationText(snapshot: TaskCompletionSnapshot): string {\n\tconst header = [\n\t\t`Background ${snapshot.kind} ${snapshot.taskId}: ${snapshot.status}${snapshot.command ? \"\" : ` — ${singleLine(snapshot.title)}`}`,\n\t\tsnapshot.error ? `Error: ${singleLine(snapshot.error)}` : \"\",\n\t].filter(Boolean);\n\tif (snapshot.command) header.push(`Command:\\n${modelText(snapshot.command, 8192, 128)}`);\n\tif (snapshot.cwd) header.push(`cwd: ${singleLine(snapshot.cwd)}`);\n\tif (snapshot.outputPath) header.push(`Output: ${singleLine(snapshot.outputPath)}`);\n\tconst prefix = `${header.join(\"\\n\")}\\n\\n`;\n\tconst guidance = nextStepLine(snapshot.status);\n\tconst suffix = guidance ? `\\n\\n${guidance}` : \"\";\n\tconst remaining = Math.min(\n\t\tMODEL_OUTPUT_BYTES,\n\t\tTASK_RESULT_BYTES - Buffer.byteLength(prefix) - Buffer.byteLength(suffix),\n\t);\n\tconst lines = MODEL_LINES - prefix.split(\"\\n\").length - (guidance ? 3 : 0);\n\tconst output = snapshot.output.text ? snapshot.output : { text: \"No text result.\", truncated: false };\n\treturn prefix + modelTail(output, remaining, lines) + suffix;\n}\n\nexport function taskCompletionMessage(task: TaskSnapshot): CustomMessage<TaskCompletionSnapshot> {\n\tconst details = taskCompletionSnapshot(task);\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: \"task-completion\",\n\t\tdisplay: true,\n\t\tcontent: notificationText(details),\n\t\tdetails,\n\t\ttimestamp: Date.now(),\n\t};\n}\n"]}
1
+ {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../../../src/core/tasks/presentation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CustomMessage } from \"../messages.ts\";\nimport { truncateHead, truncateTail } from \"../tools/truncate.ts\";\nimport { TASK_SNAPSHOT_VERSION } from \"./codec.ts\";\nimport { boundTail, boundText, TASK_DETAILS_BYTES, TASK_RESULT_BYTES } from \"./output.ts\";\nimport type { TaskSnapshot, TaskStatus, TaskText } from \"./types.ts\";\n\n/** Automatic model turns get only a small readable log tail; reports arrive whole. */\nconst MODEL_LOG_BYTES = 8 * 1024;\nconst MODEL_LINES = 2000;\n/** Replay copies of the output and input inside completion details. */\nconst REPLAY_OUTPUT_BYTES = [40 * 1024, 16 * 1024, 4 * 1024, 0] as const;\nconst REPLAY_INPUT_BYTES = 8 * 1024;\n\nexport interface TaskCompletionDetails {\n\tversion: typeof TASK_SNAPSHOT_VERSION;\n\ttask: TaskSnapshot;\n}\n\nconst singleLine = (value: string) => value.replace(/\\s+/gu, \" \").trim();\nconst bytes = (value: string) => Buffer.byteLength(value);\n\nconst OMISSION = \"\\n[Saved output truncated; use tasks read for retained task details.]\";\nconst EARLIER_OMISSION = \"[Earlier output truncated; use tasks read for retained task details.]\\n\";\n\n/** A report keeps its beginning, where its summary is. */\nfunction modelHead(value: TaskText, maxBytes: number, lines: number): string {\n\tconst result = truncateHead(value.text, {\n\t\tmaxBytes: Math.max(0, maxBytes - bytes(OMISSION)),\n\t\tmaxLines: Math.max(1, lines - 1),\n\t});\n\treturn result.content + (value.truncated || result.truncated ? OMISSION : \"\");\n}\n\n/** A log keeps its end, where the outcome is. */\nfunction modelTail(value: TaskText, maxBytes: number, lines: number): string {\n\tconst result = truncateTail(value.text, {\n\t\tmaxBytes: Math.max(0, maxBytes - bytes(EARLIER_OMISSION)),\n\t\tmaxLines: Math.max(1, lines - 1),\n\t});\n\treturn (value.truncated || result.truncated ? EARLIER_OMISSION : \"\") + result.content;\n}\n\n/** One bounded action hint per terminal outcome; completed work needs none. */\nfunction nextStepLine(status: TaskStatus): string {\n\tswitch (status) {\n\t\tcase \"cancelled\":\n\t\t\treturn \"Next step: the task was cancelled — do not restart it unless the user asks.\";\n\t\tcase \"timeout\":\n\t\t\treturn \"Next step: the task hit its timeout; inspect the partial output above, then rerun with a longer timeout or in smaller pieces if still needed.\";\n\t\tcase \"failed\":\n\t\tcase \"partial\":\n\t\t\treturn \"Next step: diagnose from the output above before retrying; rerun only what is still needed.\";\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\n/**\n * The model-facing text of a settled background task. A report reaches the model as its\n * foreground result would have; a log contributes only its tail to the automatic turn.\n */\nexport function projectForModel(task: TaskSnapshot): string {\n\tconst header = [\n\t\tboundText(`Background ${task.kind} ${task.id}: ${task.status} — ${singleLine(task.title)}`, 2048),\n\t\ttask.error ? `Error: ${singleLine(task.error)}` : \"\",\n\t\t...(task.facts ?? []).map(([label, value]) => `${label}: ${singleLine(value)}`),\n\t\ttask.outputPath ? `Output: ${singleLine(task.outputPath)}` : \"\",\n\t].filter(Boolean);\n\tconst prefix = `${header.join(\"\\n\")}\\n\\n`;\n\tconst guidance = nextStepLine(task.status);\n\tconst suffix = guidance ? `\\n\\n${guidance}` : \"\";\n\tconst budget = TASK_RESULT_BYTES - bytes(prefix) - bytes(suffix);\n\tconst lines = MODEL_LINES - prefix.split(\"\\n\").length - (guidance ? 3 : 0);\n\tconst output = task.result?.text ? task.result : { text: \"No text result.\", truncated: false };\n\tconst body =\n\t\ttask.output === \"report\"\n\t\t\t? modelHead(output, budget, lines)\n\t\t\t: modelTail(output, Math.min(MODEL_LOG_BYTES, budget), lines);\n\treturn prefix + body + suffix;\n}\n\nfunction clipped(value: TaskText, maxBytes: number, keep: \"head\" | \"tail\"): TaskText {\n\tconst text = keep === \"head\" ? boundText(value.text, maxBytes) : boundTail(value.text, maxBytes).text;\n\treturn { text, truncated: value.truncated || text !== value.text };\n}\n\n/** A self-contained replay snapshot within the details budget; human-only display stays in the session record. */\nexport function taskCompletionDetails(task: TaskSnapshot): TaskCompletionDetails {\n\tconst { display: _display, result, input, ...rest } = task;\n\tconst keep = task.output === \"report\" ? \"head\" : \"tail\";\n\tconst replayInput = input && { ...input, ...clipped(input, REPLAY_INPUT_BYTES, \"head\") };\n\tfor (const outputBytes of REPLAY_OUTPUT_BYTES) {\n\t\tconst details: TaskCompletionDetails = {\n\t\t\tversion: TASK_SNAPSHOT_VERSION,\n\t\t\ttask: {\n\t\t\t\t...rest,\n\t\t\t\t...(replayInput ? { input: replayInput } : {}),\n\t\t\t\t...(result && outputBytes > 0 ? { result: clipped(result, outputBytes, keep) } : {}),\n\t\t\t},\n\t\t};\n\t\tif (bytes(JSON.stringify(details)) <= TASK_DETAILS_BYTES) return details;\n\t}\n\treturn { version: TASK_SNAPSHOT_VERSION, task: rest };\n}\n\nexport function taskCompletionMessage(task: TaskSnapshot): CustomMessage<TaskCompletionDetails> {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType: \"task-completion\",\n\t\tdisplay: true,\n\t\tcontent: projectForModel(task),\n\t\tdetails: taskCompletionDetails(task),\n\t\ttimestamp: Date.now(),\n\t};\n}\n"]}
@@ -4,20 +4,22 @@ import { type TaskExecution, type TaskRead, type TaskRuntimeOptions, type TaskSn
4
4
  export declare class TaskRuntime implements TasksContext {
5
5
  private readonly store;
6
6
  private readonly executions;
7
+ private readonly scheduler;
7
8
  private readonly listeners;
8
- private readonly maxActive;
9
+ private readonly host;
10
+ private readonly maxBackground;
9
11
  private readonly maxHistory;
10
12
  private readonly maxRetained;
13
+ private readonly options;
11
14
  private configuredEnabled;
12
15
  private _closed;
13
- get closed(): boolean;
14
- get session(): TaskRuntimeOptions["session"];
15
16
  private pauses;
16
- private readonly options;
17
17
  constructor(options?: TaskRuntimeOptions);
18
+ get closed(): boolean;
19
+ get session(): TaskRuntimeOptions["session"];
18
20
  /**
19
- * Rehydrate terminal version-2 custom data only, newest endedAt in each history
20
- * (later input wins ties). Existing runtime records win ID collisions. No execution, accounting,
21
+ * Rehydrate terminal snapshots only, newest endedAt in each history (later input wins
22
+ * ties). Existing runtime records win ID collisions. No execution, accounting,
21
23
  * notification, or deletion ownership is restored. Foreground records take their output
22
24
  * from the branch's tool results. The host supplies the current branch; closed services
23
25
  * ignore restoration.
@@ -25,7 +27,7 @@ export declare class TaskRuntime implements TasksContext {
25
27
  restoreHistory(records: readonly unknown[], toolResults?: ReadonlyMap<string, AgentToolResult<unknown>["content"]>): void;
26
28
  get enabled(): boolean;
27
29
  setEnabled(enabled: boolean): void;
28
- /** Foreground work is bounded by its caller; only background work holds a slot. */
30
+ /** Foreground work is bounded by its caller; only background work, queued or running, holds a slot. */
29
31
  private backgroundActive;
30
32
  private limitError;
31
33
  execute<T>(execution: TaskExecution<T>): Promise<TaskToolOutcome<T>>;
@@ -33,8 +35,6 @@ export declare class TaskRuntime implements TasksContext {
33
35
  detachForeground(): number;
34
36
  canDetach(id: string): boolean;
35
37
  detach(id: string): boolean;
36
- private prepareDetach;
37
- private finishDetach;
38
38
  list(): TaskSnapshot[];
39
39
  private lookup;
40
40
  get(id: string): TaskSnapshot;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"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"}