pi-agent-flow 1.8.1 → 1.8.3

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 (154) hide show
  1. package/README.md +4 -30
  2. package/agents/audit.md +1 -2
  3. package/agents/build.md +1 -0
  4. package/agents/craft.md +12 -8
  5. package/agents/debug.md +2 -2
  6. package/agents/ideas.md +1 -0
  7. package/agents/scout.md +1 -0
  8. package/dist/agents.d.ts +41 -0
  9. package/dist/agents.d.ts.map +1 -0
  10. package/dist/agents.js +283 -0
  11. package/dist/agents.js.map +1 -0
  12. package/dist/batch/batch-bash.d.ts +87 -0
  13. package/dist/batch/batch-bash.d.ts.map +1 -0
  14. package/dist/batch/batch-bash.js +369 -0
  15. package/dist/batch/batch-bash.js.map +1 -0
  16. package/dist/batch/constants.d.ts +100 -0
  17. package/dist/batch/constants.d.ts.map +1 -0
  18. package/dist/batch/constants.js +15 -0
  19. package/dist/batch/constants.js.map +1 -0
  20. package/dist/batch/execute.d.ts +21 -0
  21. package/dist/batch/execute.d.ts.map +1 -0
  22. package/dist/batch/execute.js +440 -0
  23. package/dist/batch/execute.js.map +1 -0
  24. package/dist/batch/fuzzy-edit.d.ts +29 -0
  25. package/dist/batch/fuzzy-edit.d.ts.map +1 -0
  26. package/dist/batch/fuzzy-edit.js +257 -0
  27. package/dist/batch/fuzzy-edit.js.map +1 -0
  28. package/dist/batch/index.d.ts +85 -0
  29. package/dist/batch/index.d.ts.map +1 -0
  30. package/dist/batch/index.js +422 -0
  31. package/dist/batch/index.js.map +1 -0
  32. package/dist/batch/render.d.ts +14 -0
  33. package/dist/batch/render.d.ts.map +1 -0
  34. package/dist/batch/render.js +74 -0
  35. package/dist/batch/render.js.map +1 -0
  36. package/dist/batch/symbols.d.ts +9 -0
  37. package/dist/batch/symbols.d.ts.map +1 -0
  38. package/dist/batch/symbols.js +310 -0
  39. package/dist/batch/symbols.js.map +1 -0
  40. package/dist/batch.d.ts +12 -0
  41. package/dist/batch.d.ts.map +1 -0
  42. package/dist/batch.js +11 -0
  43. package/dist/batch.js.map +1 -0
  44. package/dist/cli-args.d.ts +27 -0
  45. package/dist/cli-args.d.ts.map +1 -0
  46. package/dist/cli-args.js +265 -0
  47. package/dist/cli-args.js.map +1 -0
  48. package/dist/config.d.ts +58 -0
  49. package/dist/config.d.ts.map +1 -0
  50. package/dist/config.js +296 -0
  51. package/dist/config.js.map +1 -0
  52. package/dist/depth.d.ts +25 -0
  53. package/dist/depth.d.ts.map +1 -0
  54. package/dist/depth.js +160 -0
  55. package/dist/depth.js.map +1 -0
  56. package/dist/executor.d.ts +87 -0
  57. package/dist/executor.d.ts.map +1 -0
  58. package/dist/executor.js +295 -0
  59. package/dist/executor.js.map +1 -0
  60. package/dist/flow-prompt.d.ts +23 -0
  61. package/dist/flow-prompt.d.ts.map +1 -0
  62. package/dist/flow-prompt.js +99 -0
  63. package/dist/flow-prompt.js.map +1 -0
  64. package/dist/flow.d.ts +76 -0
  65. package/dist/flow.d.ts.map +1 -0
  66. package/dist/flow.js +704 -0
  67. package/dist/flow.js.map +1 -0
  68. package/dist/index.d.ts +10 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +327 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/reasoning-strip.d.ts +26 -0
  73. package/dist/reasoning-strip.d.ts.map +1 -0
  74. package/dist/reasoning-strip.js +58 -0
  75. package/dist/reasoning-strip.js.map +1 -0
  76. package/dist/render-utils.d.ts +42 -0
  77. package/dist/render-utils.d.ts.map +1 -0
  78. package/dist/render-utils.js +182 -0
  79. package/dist/render-utils.js.map +1 -0
  80. package/dist/render.d.ts +24 -0
  81. package/dist/render.d.ts.map +1 -0
  82. package/dist/render.js +409 -0
  83. package/dist/render.js.map +1 -0
  84. package/dist/runner-events.d.ts +59 -0
  85. package/dist/runner-events.d.ts.map +1 -0
  86. package/dist/runner-events.js +539 -0
  87. package/dist/runner-events.js.map +1 -0
  88. package/dist/session-mode.d.ts +10 -0
  89. package/dist/session-mode.d.ts.map +1 -0
  90. package/dist/session-mode.js +25 -0
  91. package/dist/session-mode.js.map +1 -0
  92. package/dist/settings-resolver.d.ts +28 -0
  93. package/dist/settings-resolver.d.ts.map +1 -0
  94. package/dist/settings-resolver.js +148 -0
  95. package/dist/settings-resolver.js.map +1 -0
  96. package/dist/sliding-prompt.d.ts +40 -0
  97. package/dist/sliding-prompt.d.ts.map +1 -0
  98. package/dist/sliding-prompt.js +121 -0
  99. package/dist/sliding-prompt.js.map +1 -0
  100. package/dist/snapshot.d.ts +29 -0
  101. package/dist/snapshot.d.ts.map +1 -0
  102. package/dist/snapshot.js +199 -0
  103. package/dist/snapshot.js.map +1 -0
  104. package/dist/structured-output.d.ts +36 -0
  105. package/dist/structured-output.d.ts.map +1 -0
  106. package/dist/structured-output.js +244 -0
  107. package/dist/structured-output.js.map +1 -0
  108. package/dist/timed-bash.d.ts +45 -0
  109. package/dist/timed-bash.d.ts.map +1 -0
  110. package/dist/timed-bash.js +219 -0
  111. package/dist/timed-bash.js.map +1 -0
  112. package/dist/tool-utils.d.ts +20 -0
  113. package/dist/tool-utils.d.ts.map +1 -0
  114. package/dist/tool-utils.js +38 -0
  115. package/dist/tool-utils.js.map +1 -0
  116. package/dist/transitions.d.ts +39 -0
  117. package/dist/transitions.d.ts.map +1 -0
  118. package/dist/transitions.js +59 -0
  119. package/dist/transitions.js.map +1 -0
  120. package/dist/types.d.ts +207 -0
  121. package/dist/types.d.ts.map +1 -0
  122. package/dist/types.js +143 -0
  123. package/dist/types.js.map +1 -0
  124. package/dist/web-tool.d.ts +35 -0
  125. package/dist/web-tool.d.ts.map +1 -0
  126. package/dist/web-tool.js +545 -0
  127. package/dist/web-tool.js.map +1 -0
  128. package/package.json +7 -5
  129. package/src/agents.ts +0 -299
  130. package/src/ambient.d.ts +0 -107
  131. package/src/batch/batch-bash.ts +0 -443
  132. package/src/batch/constants.ts +0 -128
  133. package/src/batch/execute.ts +0 -551
  134. package/src/batch/fuzzy-edit.ts +0 -323
  135. package/src/batch/index.ts +0 -494
  136. package/src/batch/render.ts +0 -81
  137. package/src/batch/symbols.ts +0 -341
  138. package/src/batch.ts +0 -28
  139. package/src/cli-args.ts +0 -315
  140. package/src/config.ts +0 -391
  141. package/src/executor.ts +0 -445
  142. package/src/flow.ts +0 -834
  143. package/src/hooks.ts +0 -294
  144. package/src/index.ts +0 -1132
  145. package/src/render-utils.ts +0 -205
  146. package/src/render.ts +0 -524
  147. package/src/runner-events.ts +0 -692
  148. package/src/session-mode.ts +0 -33
  149. package/src/sliding-prompt.ts +0 -144
  150. package/src/structured-output.ts +0 -195
  151. package/src/timed-bash.ts +0 -270
  152. package/src/transitions.ts +0 -86
  153. package/src/types.ts +0 -386
  154. package/src/web-tool.ts +0 -663
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Session snapshot building, sanitization, and flow result compression.
3
+ *
4
+ * Extracted from index.ts for single-responsibility and testability.
5
+ */
6
+ import { stripReasoningFromAssistantMessage } from "./reasoning-strip.js";
7
+ import { stripSlidingPromptFromContent, contentContainsSlidingTag, isJsonEqual, } from "./sliding-prompt.js";
8
+ // ---------------------------------------------------------------------------
9
+ // Session snapshot serialization
10
+ // ---------------------------------------------------------------------------
11
+ export function buildForkSessionSnapshotJsonl(sessionManager) {
12
+ const header = sessionManager.getHeader();
13
+ if (!header || typeof header !== "object")
14
+ return null;
15
+ const branchEntries = sessionManager.getBranch();
16
+ const lines = [JSON.stringify(header)];
17
+ for (const entry of branchEntries)
18
+ lines.push(JSON.stringify(entry));
19
+ return `${lines.join("\n")}\n`;
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // Flow result compression
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Render a compressed flow result as compact text for child context.
26
+ */
27
+ export function renderCompressedFlowResult(r) {
28
+ const parts = [`[Flow: ${r.type} ${r.status}]`];
29
+ if (r.files?.length) {
30
+ const fileLines = r.files.map((f) => {
31
+ const role = f.role ? ` (${f.role})` : "";
32
+ const desc = f.description ? ` — ${f.description}` : "";
33
+ return ` ${f.path}${role}${desc}`;
34
+ });
35
+ parts.push(`Files:\n${fileLines.join("\n")}`);
36
+ }
37
+ if (r.commands?.length) {
38
+ const cmdLines = r.commands.map((c) => ` ${c.tool ?? "cmd"}: ${c.command}`);
39
+ parts.push(`Commands:\n${cmdLines.join("\n")}`);
40
+ }
41
+ if (r.error)
42
+ parts.push(`Error: ${r.error}`);
43
+ return parts.join("\n");
44
+ }
45
+ /**
46
+ * Compress flow tool results in a sanitized session snapshot.
47
+ *
48
+ * Scans for tool result messages that correspond to flow invocations
49
+ * and replaces their content with compact compressed output.
50
+ */
51
+ export function compressFlowToolResults(snapshot, cache) {
52
+ if (cache.size === 0)
53
+ return snapshot;
54
+ const lines = snapshot.trimEnd().split("\n");
55
+ const result = [];
56
+ // First pass: map toolCallId → tool name from assistant messages
57
+ const toolCallIdToName = new Map();
58
+ for (const line of lines) {
59
+ let entry;
60
+ try {
61
+ entry = JSON.parse(line);
62
+ }
63
+ catch {
64
+ continue;
65
+ }
66
+ if (entry?.type !== "message" || entry.message?.role !== "assistant")
67
+ continue;
68
+ const content = entry.message.content;
69
+ if (!Array.isArray(content))
70
+ continue;
71
+ for (const part of content) {
72
+ if (part.type === "toolCall" && part.toolCallId && part.name) {
73
+ toolCallIdToName.set(part.toolCallId, part.name);
74
+ }
75
+ }
76
+ }
77
+ // Second pass: compress flow tool results
78
+ for (const line of lines) {
79
+ let entry;
80
+ try {
81
+ entry = JSON.parse(line);
82
+ }
83
+ catch {
84
+ result.push(line);
85
+ continue;
86
+ }
87
+ if (entry?.type !== "message" || entry.message?.role !== "tool") {
88
+ result.push(line);
89
+ continue;
90
+ }
91
+ // Extract toolCallId — either from message-level or content-level toolResult
92
+ let toolCallId;
93
+ if (typeof entry.message.toolCallId === "string") {
94
+ toolCallId = entry.message.toolCallId;
95
+ }
96
+ else if (Array.isArray(entry.message.content)) {
97
+ for (const part of entry.message.content) {
98
+ if (part.type === "toolResult" && part.toolCallId) {
99
+ toolCallId = part.toolCallId;
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ if (!toolCallId) {
105
+ result.push(line);
106
+ continue;
107
+ }
108
+ const toolName = toolCallIdToName.get(toolCallId);
109
+ if (toolName !== "flow") {
110
+ result.push(line);
111
+ continue;
112
+ }
113
+ const compressed = cache.get(toolCallId);
114
+ if (!compressed || compressed.length === 0) {
115
+ result.push(line);
116
+ continue;
117
+ }
118
+ const rendered = compressed.map(renderCompressedFlowResult).join("\n\n");
119
+ // Replace content in the tool result message
120
+ if (typeof entry.message.toolCallId === "string") {
121
+ // Format 1: toolCallId at message level, content is text array
122
+ entry = {
123
+ ...entry,
124
+ message: {
125
+ ...entry.message,
126
+ content: [{ type: "text", text: rendered }],
127
+ },
128
+ };
129
+ }
130
+ else {
131
+ // Format 2: toolCallId inside content array
132
+ entry = {
133
+ ...entry,
134
+ message: {
135
+ ...entry.message,
136
+ content: entry.message.content.map((part) => part.type === "toolResult" && part.toolCallId === toolCallId
137
+ ? { ...part, content: rendered }
138
+ : part),
139
+ },
140
+ };
141
+ }
142
+ result.push(JSON.stringify(entry));
143
+ }
144
+ return `${result.join("\n")}\n`;
145
+ }
146
+ /**
147
+ * Sanitize a fork session snapshot JSONL to remove only non-inheritable
148
+ * artifacts before passing full parent context to child flows: sliding system
149
+ * prompts, legacy reminders, and assistant reasoning/thinking.
150
+ */
151
+ export function sanitizeForkSnapshot(snapshot, cache = new Map()) {
152
+ if (!snapshot)
153
+ return snapshot;
154
+ const lines = snapshot.trimEnd().split("\n");
155
+ const sanitizedLines = [];
156
+ for (const line of lines) {
157
+ let entry;
158
+ try {
159
+ entry = JSON.parse(line);
160
+ }
161
+ catch {
162
+ sanitizedLines.push(line);
163
+ continue;
164
+ }
165
+ let changed = false;
166
+ // Drop sliding system prompt messages entirely.
167
+ if (entry?.type === "message" &&
168
+ entry.message?.role === "system" &&
169
+ contentContainsSlidingTag(entry.message?.content)) {
170
+ continue;
171
+ }
172
+ if (entry?.type === "message" && entry.message) {
173
+ let message = entry.message;
174
+ if (message.role === "assistant") {
175
+ const stripped = stripReasoningFromAssistantMessage(message);
176
+ message = stripped.message;
177
+ changed ||= stripped.changed;
178
+ }
179
+ if ("content" in message) {
180
+ const originalContent = message.content;
181
+ const strippedContent = stripSlidingPromptFromContent(originalContent);
182
+ if (!isJsonEqual(strippedContent, originalContent)) {
183
+ message = {
184
+ ...message,
185
+ content: strippedContent,
186
+ };
187
+ changed = true;
188
+ }
189
+ }
190
+ if (changed) {
191
+ entry = { ...entry, message };
192
+ }
193
+ }
194
+ sanitizedLines.push(changed ? JSON.stringify(entry) : line);
195
+ }
196
+ const sanitized = `${sanitizedLines.join("\n")}\n`;
197
+ return compressFlowToolResults(sanitized, cache);
198
+ }
199
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Structured JSON output extraction from flow responses.
3
+ *
4
+ * Parses a JSON code block from the end of the flow's final assistant text
5
+ * and validates it against the FlowStructuredOutput schema.
6
+ */
7
+ import type { Message } from "@mariozechner/pi-ai";
8
+ import type { CommandEntry, FlowStructuredOutput } from "./types.js";
9
+ /**
10
+ * Extract a structured JSON output block from the end of an assistant's text.
11
+ *
12
+ * Looks for a final ```json ... ``` code block, parses it, and validates
13
+ * against the FlowStructuredOutput schema. Returns undefined when the block
14
+ * is missing, malformed, or fails validation.
15
+ */
16
+ export declare function extractStructuredOutput(text: string): FlowStructuredOutput | undefined;
17
+ /**
18
+ * Walk the message history and mechanically generate a commands array
19
+ * from all bash tool calls (standalone, batch-nested, and batch_bash_poll).
20
+ *
21
+ * This replaces the old enrichStructuredOutputCommands approach which relied
22
+ * on the LLM generating a paraphrased commands array that was then replaced
23
+ * with verbatim versions. Now commands are generated purely from tool call
24
+ * history — no LLM involvement required.
25
+ *
26
+ * Deduplication strategy:
27
+ * - Batch-nested bash ops that completed within the batch call are emitted
28
+ * immediately with their timing.
29
+ * - Batch-nested bash ops that were still pending when the batch returned
30
+ * (no timing available) are deferred to batch_bash_poll.
31
+ * - batch_bash_poll only emits entries for IDs that were deferred AND have
32
+ * completed (with timing). Still-pending poll results are skipped.
33
+ * - Once an ID is emitted (from batch or poll), subsequent encounters skip it.
34
+ */
35
+ export declare function generateCommandsFromHistory(messages: Message[]): CommandEntry[];
36
+ //# sourceMappingURL=structured-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAU,YAAY,EAAa,oBAAoB,EAAe,MAAM,YAAY,CAAC;AA8CrG;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAoCtF;AAyCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAuH/E"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Structured JSON output extraction from flow responses.
3
+ *
4
+ * Parses a JSON code block from the end of the flow's final assistant text
5
+ * and validates it against the FlowStructuredOutput schema.
6
+ */
7
+ const VALID_STATUSES = ["complete", "partial", "blocked", "failed"];
8
+ function isRecord(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function isOptionalArray(record, key) {
12
+ return record[key] === undefined || Array.isArray(record[key]);
13
+ }
14
+ /** Minimum required fields to consider parsed JSON a valid structured output. */
15
+ function isValidStructuredOutput(obj) {
16
+ if (!isRecord(obj))
17
+ return false;
18
+ return (typeof obj.version === "string" &&
19
+ typeof obj.status === "string" &&
20
+ VALID_STATUSES.includes(obj.status) &&
21
+ typeof obj.summary === "string" &&
22
+ isOptionalArray(obj, "files") &&
23
+ isOptionalArray(obj, "actions") &&
24
+ isOptionalArray(obj, "commands") &&
25
+ isOptionalArray(obj, "notDone") &&
26
+ isOptionalArray(obj, "nextSteps") &&
27
+ isOptionalArray(obj, "reasoning") &&
28
+ isOptionalArray(obj, "notes"));
29
+ }
30
+ /**
31
+ * Extract a structured JSON output block from the end of an assistant's text.
32
+ *
33
+ * Looks for a final ```json ... ``` code block, parses it, and validates
34
+ * against the FlowStructuredOutput schema. Returns undefined when the block
35
+ * is missing, malformed, or fails validation.
36
+ */
37
+ export function extractStructuredOutput(text) {
38
+ if (!text)
39
+ return undefined;
40
+ // Find the last ```json ... ``` block in the text.
41
+ // Scan backward from the end to handle multiple blocks.
42
+ const allMatches = [...text.matchAll(/```json\s*([\s\S]*?)\s*```/g)];
43
+ const match = allMatches.length > 0 ? allMatches[allMatches.length - 1] : null;
44
+ if (!match || !match[1])
45
+ return undefined;
46
+ const jsonStr = match[1].trim();
47
+ if (!jsonStr)
48
+ return undefined;
49
+ let parsed;
50
+ try {
51
+ parsed = JSON.parse(jsonStr);
52
+ }
53
+ catch {
54
+ return undefined;
55
+ }
56
+ if (!isValidStructuredOutput(parsed))
57
+ return undefined;
58
+ // Sanitize: trim string fields and normalize omitted arrays to [] for
59
+ // backward compatibility with earlier structured-output prompts.
60
+ return {
61
+ version: parsed.version.trim(),
62
+ status: parsed.status,
63
+ summary: parsed.summary.trim(),
64
+ files: parsed.files ?? [],
65
+ actions: parsed.actions ?? [],
66
+ commands: parsed.commands ?? [],
67
+ notDone: parsed.notDone ?? [],
68
+ nextSteps: parsed.nextSteps ?? [],
69
+ reasoning: parsed.reasoning ?? [],
70
+ notes: parsed.notes ?? [],
71
+ ...(parsed.extensions !== undefined ? { extensions: parsed.extensions } : {}),
72
+ };
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Mechanical command generation from tool call history
76
+ // ---------------------------------------------------------------------------
77
+ /**
78
+ * Extract [Execution time: ...] markers keyed by bash-op-ID from batch
79
+ * result text. Uses the `--- bash [ID]` delimiter to split sections.
80
+ * Pending sections (no timing marker) are not included in the result.
81
+ */
82
+ function extractBatchTimingsById(text) {
83
+ const result = new Map();
84
+ const sections = text.split(/^--- bash \[([^\]]+)\]/m);
85
+ // sections: [preamble, id1, body1, id2, body2, ...]
86
+ for (let i = 1; i < sections.length - 1; i += 2) {
87
+ const id = sections[i].trim();
88
+ const body = sections[i + 1] || "";
89
+ const match = body.match(/\[Execution time: ([^\]]+)\]/);
90
+ if (match)
91
+ result.set(id, match[1]);
92
+ }
93
+ return result;
94
+ }
95
+ /**
96
+ * Extract [Execution time: ...] markers keyed by bash-op-ID from poll
97
+ * result text. Uses the `--- [ID]` delimiter to split sections.
98
+ */
99
+ function extractPollTimingsById(text) {
100
+ const result = new Map();
101
+ const sections = text.split(/^--- \[([^\]]+)\]/m);
102
+ // sections: [preamble, id1, body1, id2, body2, ...]
103
+ for (let i = 1; i < sections.length - 1; i += 2) {
104
+ const id = sections[i].trim();
105
+ const body = sections[i + 1] || "";
106
+ const match = body.match(/\[Execution time: ([^\]]+)\]/);
107
+ if (match)
108
+ result.set(id, match[1]);
109
+ }
110
+ return result;
111
+ }
112
+ /**
113
+ * Walk the message history and mechanically generate a commands array
114
+ * from all bash tool calls (standalone, batch-nested, and batch_bash_poll).
115
+ *
116
+ * This replaces the old enrichStructuredOutputCommands approach which relied
117
+ * on the LLM generating a paraphrased commands array that was then replaced
118
+ * with verbatim versions. Now commands are generated purely from tool call
119
+ * history — no LLM involvement required.
120
+ *
121
+ * Deduplication strategy:
122
+ * - Batch-nested bash ops that completed within the batch call are emitted
123
+ * immediately with their timing.
124
+ * - Batch-nested bash ops that were still pending when the batch returned
125
+ * (no timing available) are deferred to batch_bash_poll.
126
+ * - batch_bash_poll only emits entries for IDs that were deferred AND have
127
+ * completed (with timing). Still-pending poll results are skipped.
128
+ * - Once an ID is emitted (from batch or poll), subsequent encounters skip it.
129
+ */
130
+ export function generateCommandsFromHistory(messages) {
131
+ const commands = [];
132
+ // ── Phase 1: Build lookup maps ──
133
+ // Map toolCallId → concatenated text from tool result messages
134
+ const toolResultTexts = new Map();
135
+ for (const msg of messages) {
136
+ if (msg.role !== "tool" || !Array.isArray(msg.content))
137
+ continue;
138
+ const id = msg.toolCallId ||
139
+ msg.tool_call_id ||
140
+ "";
141
+ if (!id)
142
+ continue;
143
+ const text = msg.content
144
+ .filter((c) => c.type === "text" && typeof c.text === "string")
145
+ .map((c) => c.text)
146
+ .join("");
147
+ toolResultTexts.set(id, text);
148
+ }
149
+ // Map toolCallId → execution time (from [Execution time: ...] markers)
150
+ const timingMap = new Map();
151
+ for (const [id, text] of toolResultTexts) {
152
+ const match = text.match(/\[Execution time: ([^\]]+)\]/);
153
+ if (match)
154
+ timingMap.set(id, match[1]);
155
+ }
156
+ // Map bash-op-ID → command string (from all batch calls, for poll lookback)
157
+ const bashIdToCommand = new Map();
158
+ // Track which bash-op IDs have already been emitted (with timing).
159
+ // Prevents duplicates from poll calls.
160
+ const emittedBashIds = new Set();
161
+ // ── Phase 2: Walk tool calls ──
162
+ for (const msg of messages) {
163
+ if (msg.role !== "assistant" || !Array.isArray(msg.content))
164
+ continue;
165
+ for (const part of msg.content) {
166
+ if (part.type !== "toolCall")
167
+ continue;
168
+ const name = part.name || part.toolName || "";
169
+ const args = part.arguments || part.input || {};
170
+ const toolCallId = part.toolCallId || part.tool_call_id || "";
171
+ switch (name) {
172
+ case "bash": {
173
+ const cmd = args.command || "";
174
+ if (cmd) {
175
+ commands.push({
176
+ command: cmd,
177
+ tool: "bash",
178
+ ...(timingMap.has(toolCallId) ? { executionTime: timingMap.get(toolCallId) } : {}),
179
+ });
180
+ }
181
+ break;
182
+ }
183
+ case "batch": {
184
+ const ops = Array.isArray(args.o)
185
+ ? args.o
186
+ : Array.isArray(args.op)
187
+ ? args.op
188
+ : Array.isArray(args.operations)
189
+ ? args.operations
190
+ : [];
191
+ const resultText = toolResultTexts.get(toolCallId) || "";
192
+ const batchTimings = extractBatchTimingsById(resultText);
193
+ for (const op of ops) {
194
+ if (!op)
195
+ continue;
196
+ const opType = (op.o ?? op.op);
197
+ if (opType === "bash" && op.command) {
198
+ const id = (op.i ?? op.id);
199
+ if (id)
200
+ bashIdToCommand.set(id, op.command);
201
+ const timing = id ? batchTimings.get(id) : undefined;
202
+ if (timing) {
203
+ // Completed within batch — emit immediately with timing
204
+ commands.push({
205
+ command: op.command,
206
+ tool: "bash",
207
+ executionTime: timing,
208
+ });
209
+ if (id)
210
+ emittedBashIds.add(id);
211
+ }
212
+ // Pending ops (no timing) are deferred to batch_bash_poll
213
+ }
214
+ }
215
+ break;
216
+ }
217
+ case "batch_bash_poll": {
218
+ const ids = Array.isArray(args.i) ? args.i : [];
219
+ const resultText = toolResultTexts.get(toolCallId) || "";
220
+ const pollTimings = extractPollTimingsById(resultText);
221
+ for (const id of ids) {
222
+ if (emittedBashIds.has(id))
223
+ continue; // already emitted
224
+ const command = bashIdToCommand.get(id);
225
+ if (!command)
226
+ continue; // unknown ID — skip
227
+ const timing = pollTimings.get(id);
228
+ if (!timing)
229
+ continue; // still pending — skip, defer to next poll
230
+ commands.push({
231
+ command,
232
+ tool: "bash",
233
+ executionTime: timing,
234
+ });
235
+ emittedBashIds.add(id);
236
+ }
237
+ break;
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return commands;
243
+ }
244
+ //# sourceMappingURL=structured-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.js","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Timed Bash Tool Wrapper
3
+ *
4
+ * Wraps the built-in bash tool to append execution-time classification
5
+ * to every result. This gives the LLM concrete feedback to self-correct
6
+ * strategy (e.g. switch from bash grep to grep tool, batch commands, etc.).
7
+ *
8
+ * Child flows also receive a hard deadline from the parent runner. When a
9
+ * bash command is still running near that deadline, this wrapper aborts just
10
+ * the bash tool and returns an explicit instruction to stop using tools and
11
+ * summarize. That preserves the child agent process long enough to produce
12
+ * its final structured report instead of being killed while a shell command is
13
+ * still active.
14
+ */
15
+ export type TimingTier = "normal" | "avg" | "long" | "extreme_long" | "very_long";
16
+ export interface TimingReport {
17
+ tier: TimingTier;
18
+ seconds: number;
19
+ label: string;
20
+ }
21
+ /** Classify duration into user-defined tiers with actionable feedback. */
22
+ export declare function classifyDuration(ms: number): TimingReport;
23
+ /** Format the timing appendix that gets appended to bash output. */
24
+ export declare function formatTimingAppendix(report: TimingReport): string;
25
+ /**
26
+ * Read any pending reminder from the reminder file set by the parent runner.
27
+ * Returns the reminder text (without trailing newline), or null if no reminder exists.
28
+ * Clears the file after reading so the agent only sees each reminder once.
29
+ */
30
+ export declare function readAndClearReminderFile(): string | null;
31
+ /**
32
+ * Create a timed bash tool definition that wraps the built-in one.
33
+ * Extensions override built-in tools by name, so this replaces the
34
+ * default `bash` tool transparently.
35
+ *
36
+ * Returns `null` if the underlying `createBashToolDefinition` is not
37
+ * available (e.g. test environment or incompatible CLI version).
38
+ */
39
+ export declare function createTimedBashToolDefinition(cwd: string, options?: {
40
+ shellPath?: string;
41
+ commandPrefix?: string;
42
+ operations?: any;
43
+ spawnHook?: any;
44
+ }): any;
45
+ //# sourceMappingURL=timed-bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timed-bash.d.ts","sourceRoot":"","sources":["../src/timed-bash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,MAAM,MAAM,UAAU,GACnB,QAAQ,GACR,KAAK,GACL,MAAM,GACN,cAAc,GACd,WAAW,CAAC;AAEf,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAOD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CA2BzD;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEjE;AA2BD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAYxD;AA2DD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IACT,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,GAAG,CAAC;CAChB,GACC,GAAG,CA4EL"}