maestro-agent-sdk 0.1.27 → 0.1.29

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 (49) hide show
  1. package/dist/core/agent.d.ts +28 -0
  2. package/dist/core/agent.d.ts.map +1 -1
  3. package/dist/core/agent.js +2 -0
  4. package/dist/core/agent.js.map +1 -1
  5. package/dist/core/is-abort-error.d.ts +18 -0
  6. package/dist/core/is-abort-error.d.ts.map +1 -1
  7. package/dist/core/is-abort-error.js +34 -0
  8. package/dist/core/is-abort-error.js.map +1 -1
  9. package/dist/core/loop.d.ts.map +1 -1
  10. package/dist/core/loop.js +69 -14
  11. package/dist/core/loop.js.map +1 -1
  12. package/dist/core/tool-result-truncation.d.ts +34 -0
  13. package/dist/core/tool-result-truncation.d.ts.map +1 -0
  14. package/dist/core/tool-result-truncation.js +162 -0
  15. package/dist/core/tool-result-truncation.js.map +1 -0
  16. package/dist/index.d.ts +6 -4
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +4 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/memory/active-task-template.d.ts +7 -4
  21. package/dist/memory/active-task-template.d.ts.map +1 -1
  22. package/dist/memory/active-task-template.js +19 -4
  23. package/dist/memory/active-task-template.js.map +1 -1
  24. package/dist/memory/aux-model-map.d.ts +49 -0
  25. package/dist/memory/aux-model-map.d.ts.map +1 -0
  26. package/dist/memory/aux-model-map.js +103 -0
  27. package/dist/memory/aux-model-map.js.map +1 -0
  28. package/dist/memory/compressor.d.ts +34 -59
  29. package/dist/memory/compressor.d.ts.map +1 -1
  30. package/dist/memory/compressor.js +289 -92
  31. package/dist/memory/compressor.js.map +1 -1
  32. package/dist/provider.d.ts +2 -2
  33. package/dist/provider.d.ts.map +1 -1
  34. package/dist/provider.js +32 -4
  35. package/dist/provider.js.map +1 -1
  36. package/dist/providers/codex-auth.d.ts.map +1 -1
  37. package/dist/providers/codex-auth.js +20 -0
  38. package/dist/providers/codex-auth.js.map +1 -1
  39. package/dist/providers/codex.d.ts +29 -1
  40. package/dist/providers/codex.d.ts.map +1 -1
  41. package/dist/providers/codex.js +94 -11
  42. package/dist/providers/codex.js.map +1 -1
  43. package/dist/session-store.d.ts.map +1 -1
  44. package/dist/session-store.js +14 -4
  45. package/dist/session-store.js.map +1 -1
  46. package/dist/types.d.ts +24 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js.map +1 -1
  49. package/package.json +1 -1
@@ -3,12 +3,28 @@ import { pruneMessages } from "../memory/prune.js";
3
3
  import { estimateTokens } from "../memory/token-estimate.js";
4
4
  import { logger } from "../platform/logger.js";
5
5
  const compactorAntiThrash = new WeakMap();
6
- /** A compaction that doesn't save at least this fraction of tokens is
7
- * considered ineffective and counts toward backoff. */
8
6
  const COMPACTOR_MIN_SAVINGS_RATIO = 0.1;
9
- /** Two consecutive ineffective calls on the same array → bail out and just
10
- * prune. */
11
7
  const COMPACTOR_ANTI_THRASH_LIMIT = 2;
8
+ /** Sentinel user message that marks a compaction block pair.
9
+ * Uses NUL-bytes to make accidental user-content collision extremely unlikely. */
10
+ const COMPACTION_MARKER = "\x00maestro-compaction\x00";
11
+ /** Incremental summary update prompt. Restates the schema contract
12
+ * (same sections as ACTIVE_TASK_TEMPLATE) so aux output never drifts. */
13
+ function incrementalPrompt(previousSummary) {
14
+ return [
15
+ ACTIVE_TASK_TEMPLATE,
16
+ "",
17
+ "---",
18
+ "The conversation above has been partially summarized before.",
19
+ "Update the previous summary below by preserving still-true details,",
20
+ "removing stale details, and merging in new facts from the recent",
21
+ "conversation history above.",
22
+ "",
23
+ "<previous-summary>",
24
+ previousSummary,
25
+ "</previous-summary>",
26
+ ].join("\n");
27
+ }
12
28
  function defaultContextWindow() {
13
29
  const env = process.env.MAESTRO_CONTEXT_WINDOW;
14
30
  if (env) {
@@ -18,109 +34,164 @@ function defaultContextWindow() {
18
34
  }
19
35
  return 200_000;
20
36
  }
37
+ function extractText(blocks) {
38
+ if (typeof blocks === "string")
39
+ return blocks;
40
+ if (Array.isArray(blocks)) {
41
+ return blocks
42
+ .filter((b) => b.type === "text")
43
+ .map((b) => b.text ?? "")
44
+ .join("\n");
45
+ }
46
+ return "";
47
+ }
48
+ /**
49
+ * Returns true when a ProviderMessage's blocks contain at least one
50
+ * tool_result. Used by snap-helper to avoid cutting the wire at a
51
+ * tool_result user message that would orphan the preceding tool_use.
52
+ */
53
+ function hasToolResultBlocks(msg) {
54
+ const content = msg.content;
55
+ if (typeof content === "string")
56
+ return false;
57
+ if (!Array.isArray(content))
58
+ return false;
59
+ return content.some((b) => b.type === "tool_result");
60
+ }
61
+ /**
62
+ * Find the most recent compaction block pair in messages.
63
+ * Returns indices and the summary text, or undefined.
64
+ */
65
+ function findLastCompaction(messages) {
66
+ for (let i = messages.length - 1; i >= 1; i--) {
67
+ const assistant = messages[i];
68
+ const user = messages[i - 1];
69
+ if (user.role === "user" &&
70
+ typeof user.content === "string" &&
71
+ user.content === COMPACTION_MARKER &&
72
+ assistant.role === "assistant" &&
73
+ typeof assistant.content === "string" &&
74
+ assistant.content.length > 0) {
75
+ return { userIdx: i - 1, assistantIdx: i, summary: assistant.content };
76
+ }
77
+ }
78
+ return undefined;
79
+ }
80
+ /**
81
+ * Collect indices of all compaction block pairs in messages.
82
+ */
83
+ function compactionBlockIndices(messages) {
84
+ const indices = new Set();
85
+ for (let i = 0; i < messages.length - 1; i++) {
86
+ const user = messages[i];
87
+ const next = messages[i + 1];
88
+ if (user.role === "user" &&
89
+ typeof user.content === "string" &&
90
+ user.content === COMPACTION_MARKER &&
91
+ next.role === "assistant") {
92
+ indices.add(i);
93
+ indices.add(i + 1);
94
+ }
95
+ }
96
+ return indices;
97
+ }
98
+ // ─── public API ───────────────────────────────────────────────────────────
21
99
  /**
22
100
  * Run the auto-compaction pipeline.
23
101
  *
24
102
  * Steps:
25
- * 1. Apply `pruneMessages` first pass 1+2 are cheap and frequently
26
- * bring the wire size below the trigger ratio on their own.
27
- * 2. Re-estimate tokens. If below threshold, return the pruned array.
28
- * 3. Otherwise slice head + tail and dispatch the aux LLM to summarize
29
- * the middle. Reconstruct as [head, summary user message, tail].
30
- * 4. Anti-thrash: if two consecutive compactions on this array saved
31
- * <10%, drop back to prune-only and stop calling the aux LLM until
32
- * the caller hands us a different array reference.
103
+ * 1. Prune (cheap: dedup, age-summary, truncate tool output).
104
+ * 2. Re-estimate tokens. If below threshold, return pruned.
105
+ * 3. Snap head/tail boundaries. If no middle, return pruned.
106
+ * 4. Find previous compaction blocks extract last summary for
107
+ * incremental aux-LLM prompt.
108
+ * 5. Call aux LLM to summarize the middle. When a previous summary
109
+ * exists, only the *delta* after the last compaction
110
+ * (messages[assistantIdx+1 .. tailStart]) is sent to the aux LLM.
111
+ * 6. After the degenerate-savings guard, persist compaction user +
112
+ * summary assistant pair in the canonical `messages` array.
113
+ * 7. Return wire array: [head, wrapped-summary, tail].
33
114
  *
34
- * Returns a new array caller is responsible for using the returned slice
35
- * on the wire and keeping the unmodified canonical history for persistence.
115
+ * All wire head/tail boundaries are built from a compaction-stripped
116
+ * view of messages so the wire never leaks internal sentinels.
36
117
  */
37
118
  export async function compressIfNeeded(messages, opts = {}) {
38
119
  const contextWindow = opts.contextWindow ?? defaultContextWindow();
39
- const triggerRatio = opts.triggerRatio ?? 0.8;
120
+ const triggerRatio = opts.triggerRatio ?? 0.6;
40
121
  const headProtect = opts.headProtect ?? 2;
41
122
  const tailProtect = opts.tailProtect ?? 6;
42
123
  const auxModel = opts.auxModel;
43
- // v0.1.19+ fast-path: short conversations can never trigger compaction (we
44
- // need at least `headProtect + 1 + tailProtect` messages to even slice a
45
- // middle), AND at this size dedup/age-summary saves nothing (age threshold
46
- // is 10 user-turns). Skipping the whole prune pipeline saves ~6 O(n) walks
47
- // per turn during the first several iterations of every session — the
48
- // exact window where the loop spends most of its short-conversation life.
49
- // Trade-off: we forgo the cheap "string-content gets deduped immediately"
50
- // win on duplicate tool results in the first few turns, but the model
51
- // rarely re-issues an identical tool call inside a 9-message window.
124
+ // Fast-path: short conversations can't trigger compaction.
52
125
  const minSize = headProtect + 1 + tailProtect;
53
126
  if (messages.length < minSize) {
54
127
  return messages;
55
128
  }
56
- // v0.1.19+ cheap pre-gate: estimate raw tokens BEFORE running prune. If
57
- // we're well under the trigger (≤ 50% of threshold) the conversation has
58
- // nowhere near enough payload to need compaction, and prune's three passes
59
- // wouldn't do anything an anti-thrash latch wouldn't catch on iteration 2.
60
- // We skip prune entirely and return the input — same as the anti-thrash
61
- // short-circuit, just gated on actual size rather than past behavior.
62
- //
63
- // 0.5 ratio picked empirically: at 200K window × 0.8 trigger × 0.5 gate =
64
- // 80K tokens, which lands between "still actively gathering context" and
65
- // "approaching compaction zone". Above the gate we run the full pipeline
66
- // so an anti-thrash latch from earlier doesn't strand the loop without
67
- // any pruning when the conversation actually grows large.
129
+ // Cheap pre-gate: skip prune when well under threshold.
68
130
  const threshold = contextWindow * triggerRatio;
69
131
  const rawTokens = estimateTokens(messages);
70
132
  if (rawTokens < threshold * 0.5) {
71
133
  return messages;
72
134
  }
73
- // Step 1: prune first. Cheap and often enough.
135
+ // Step 1: prune.
74
136
  const pruned = pruneMessages(messages);
75
137
  const prunedTokens = estimateTokens(pruned);
76
138
  if (prunedTokens < threshold) {
77
139
  return pruned;
78
140
  }
79
- // Anti-thrash check — bail if we already tried twice and it didn't help.
141
+ // Anti-thrash check.
80
142
  const state = compactorAntiThrash.get(messages);
81
143
  if (state && state.failedCompactions >= COMPACTOR_ANTI_THRASH_LIMIT) {
82
144
  return pruned;
83
145
  }
84
- // (Step 2 short-conversation guard moved to the fast-path at the top of
85
- // this function — pruneMessages preserves array length, so checking
86
- // `messages.length < minSize` up there is equivalent and lets us skip
87
- // the whole prune pipeline when the conversation is too small to ever
88
- // need compaction.)
89
- // Snap head/tail boundaries to safe split points. Anthropic rejects a
90
- // request whose first message after the head isn't a user turn, and
91
- // requires every tool_use to be answered by a tool_result on the next
92
- // user turn. We never split a user→assistant or assistant→user(tool_result)
93
- // pairing.
94
- const headEnd = snapHeadEnd(pruned, headProtect);
95
- const tailStart = snapTailStart(pruned, pruned.length - tailProtect);
96
- if (tailStart <= headEnd) {
97
- // Snapping collapsed the middle — nothing left to compress.
146
+ // Step 4: find previous compaction for incremental prompt.
147
+ const prevCompaction = findLastCompaction(messages);
148
+ const previousSummary = prevCompaction?.summary;
149
+ // Build a compaction-free view of canonical messages for all wire
150
+ // boundary calculations (FIX #1: head/tail must never contain
151
+ // sentinel markers).
152
+ const skipIndices = compactionBlockIndices(messages);
153
+ const cleanMessages = messages.filter((_, i) => !skipIndices.has(i));
154
+ // Snap wire boundaries on the clean view.
155
+ const cleanHeadEnd = snapHeadEnd(cleanMessages, Math.min(headProtect, cleanMessages.length));
156
+ const cleanTailStart = snapTailStart(cleanMessages, Math.max(cleanMessages.length - tailProtect, 0));
157
+ if (cleanTailStart <= cleanHeadEnd) {
98
158
  return pruned;
99
159
  }
100
- const head = pruned.slice(0, headEnd);
101
- const middle = pruned.slice(headEnd, tailStart);
102
- const tail = pruned.slice(tailStart);
103
- // Step 3: aux LLM call.
160
+ // Build middle for aux LLM.
161
+ // FIX #2: when a previous summary exists, limit the aux input to
162
+ // the *delta* after the last compaction (messages *including* the
163
+ // sentinel pair are canonical; the delta starts right after the
164
+ // summary assistant). Otherwise use the full clean middle.
165
+ let auxMiddle;
166
+ if (prevCompaction) {
167
+ // Delta: everything after the summary assistant up to (but not including) the tail.
168
+ const deltaStart = prevCompaction.assistantIdx + 1;
169
+ const deltaEnd = messages.length - tailProtect;
170
+ auxMiddle = messages.slice(deltaStart, Math.max(deltaStart, deltaEnd));
171
+ }
172
+ else {
173
+ auxMiddle = cleanMessages.slice(cleanHeadEnd, cleanTailStart);
174
+ }
175
+ // Step 5: aux LLM call.
104
176
  if (!opts.auxProvider) {
105
- // No provider supplied AND no factory available in production callers
106
- // (the agent loop passes its own provider). Without one we can't
107
- // summarize — drop to pruned and log so the operator sees why.
108
- logger.warn({ prunedTokens, threshold }, "compressIfNeeded: over threshold but no auxProvider supplied — falling back to prune-only");
177
+ logger.warn({ prunedTokens, threshold }, "compressIfNeeded: no auxProvider prune-only");
109
178
  return pruned;
110
179
  }
111
180
  if (!auxModel) {
112
- // No model id supplied. The agent loop wires `auxModel: agent.config.model`
113
- // by default, so this branch only fires if a host calls compressIfNeeded
114
- // directly without one. Same fallback as missing provider.
115
- logger.warn({ prunedTokens, threshold }, "compressIfNeeded: over threshold but no auxModel supplied — falling back to prune-only");
181
+ logger.warn({ prunedTokens, threshold }, "compressIfNeeded: no auxModel prune-only");
116
182
  return pruned;
117
183
  }
184
+ // FIX #4: incremental prompt now includes the full ACTIVE_TASK_TEMPLATE
185
+ // so the schema contract is restated every time.
186
+ const systemPrompt = previousSummary
187
+ ? incrementalPrompt(previousSummary)
188
+ : ACTIVE_TASK_TEMPLATE;
118
189
  let summaryText;
119
190
  try {
120
191
  const auxResponse = await opts.auxProvider.complete({
121
192
  model: auxModel,
122
- messages: middle,
123
- system: ACTIVE_TASK_TEMPLATE,
193
+ messages: auxMiddle,
194
+ system: systemPrompt,
124
195
  maxTokens: 2048,
125
196
  ...(opts.abortSignal ? { abortSignal: opts.abortSignal } : {}),
126
197
  });
@@ -130,67 +201,193 @@ export async function compressIfNeeded(messages, opts = {}) {
130
201
  }
131
202
  }
132
203
  catch (err) {
133
- logger.warn({ err, prunedTokens, threshold }, "compressIfNeeded: aux LLM call failed — returning prune-only fallback");
204
+ logger.warn({ err, prunedTokens, threshold }, "compressIfNeeded: aux LLM failed");
134
205
  if (opts.disablePruneFallback)
135
206
  return messages;
136
- return pruned;
207
+ const target = opts.emergencyTargetTokens;
208
+ const effectiveTarget = target !== undefined && Number.isFinite(target) && target > 0 ? target : 50_000;
209
+ if (target === 0)
210
+ return pruned;
211
+ const notice = "[메모리 압축 실패로 이전 대화 일부가 잘렸습니다. 최근 대화만 모델에 전달됨.]";
212
+ if (opts.onEmergencyTrim) {
213
+ try {
214
+ opts.onEmergencyTrim(notice);
215
+ }
216
+ catch (cbErr) {
217
+ logger.warn({ err: cbErr }, "onEmergencyTrim threw — swallowed");
218
+ }
219
+ }
220
+ return emergencyTail(pruned, effectiveTarget, notice);
137
221
  }
222
+ // Build wire from clean messages (FIX #1).
223
+ const head = cleanMessages.slice(0, cleanHeadEnd);
224
+ const tail = cleanMessages.slice(cleanTailStart);
225
+ // H2 defense (2026-05-24): if head ends with a user message and the
226
+ // summary user is prepended directly after it, we create a user-user
227
+ // consecutive pattern that some providers reject. Insert a dummy
228
+ // assistant to restore the alternating-role invariant.
229
+ const headEndsUser = head.length > 0 && head[head.length - 1].role === "user";
138
230
  const compacted = [
139
231
  ...head,
232
+ ...(headEndsUser
233
+ ? [{ role: "assistant", content: [{ type: "text", text: "" }] }]
234
+ : []),
140
235
  { role: "user", content: wrapCompactedSummary(summaryText) },
141
236
  ...tail,
142
237
  ];
143
238
  const compactedTokens = estimateTokens(compacted);
144
- // Degenerate aux output: compaction made things bigger or barely smaller.
145
- // Discard and fall back to prune-only.
239
+ // Degenerate check MUST run before persisting compaction blocks (FIX #3).
146
240
  const savings = prunedTokens - compactedTokens;
147
241
  const ratio = savings / prunedTokens;
148
242
  if (ratio < COMPACTOR_MIN_SAVINGS_RATIO) {
149
243
  const next = state ?? { failedCompactions: 0 };
150
244
  next.failedCompactions++;
151
245
  compactorAntiThrash.set(messages, next);
152
- logger.info({ prunedTokens, compactedTokens, ratio, failedCompactions: next.failedCompactions }, "compressIfNeeded: low-savings compaction discarded — anti-thrash counter incremented");
246
+ logger.info({
247
+ prunedTokens,
248
+ compactedTokens,
249
+ ratio,
250
+ failedCompactions: next.failedCompactions,
251
+ }, "compressIfNeeded: low savings — anti-thrash incremented");
153
252
  return pruned;
154
253
  }
155
- // Successful compaction resets the anti-thrash counter.
254
+ // Step 6: persist compaction blocks AFTER savings gate (FIX #3).
255
+ if (prevCompaction) {
256
+ messages[prevCompaction.userIdx] = { role: "user", content: COMPACTION_MARKER };
257
+ messages[prevCompaction.assistantIdx] = { role: "assistant", content: summaryText };
258
+ }
259
+ else {
260
+ messages.push({ role: "user", content: COMPACTION_MARKER });
261
+ messages.push({ role: "assistant", content: summaryText });
262
+ }
156
263
  if (state)
157
264
  compactorAntiThrash.delete(messages);
158
- logger.info({ prunedTokens, compactedTokens, ratio, headProtect, tailProtect, middleSize: middle.length }, "compressIfNeeded: applied aux-LLM compaction");
265
+ logger.info({
266
+ prunedTokens,
267
+ compactedTokens,
268
+ ratio,
269
+ incremental: !!previousSummary,
270
+ auxMiddleSize: auxMiddle.length,
271
+ }, "compressIfNeeded: applied compaction");
159
272
  return compacted;
160
273
  }
274
+ // ─── helpers ──────────────────────────────────────────────────────────────
161
275
  /**
162
- * Walk forward from `idealEnd` to land on the first boundary where the next
163
- * message is `role:"user"` (so the post-head slice starts cleanly with a
164
- * user turn Anthropic's pairing rules require it). Caps at `idealEnd + 4`
165
- * so a pathological "all assistant" run can't push the head past the tail.
276
+ * Walk forward from `idealEnd` to land on a user message boundary.
277
+ * Skips user messages that are tool_result carriers (to avoid
278
+ * orphaning a preceding tool_use).
279
+ *
280
+ * H1 fix (2026-05-24): the old cap of `idealEnd + 4` could leave an
281
+ * orphan tool_use when the first user prompt triggered 3+ tool_use /
282
+ * tool_result pairs — the final tool_result sat at index > cap and
283
+ * the head ended with an unpaired assistant tool_use, causing both
284
+ * Codex and Anthropic to reject the request (400). The fix tracks
285
+ * open tool_use IDs and only stops at a plain user when every
286
+ * tool_use in the head region has a matching tool_result.
166
287
  */
167
288
  function snapHeadEnd(messages, idealEnd) {
168
- const cap = Math.min(messages.length, idealEnd + 4);
169
- let i = Math.min(idealEnd, messages.length);
170
- while (i < cap && messages[i] && messages[i].role !== "user")
289
+ // Pre-populate open tool_uses from the prefix we're keeping (0..idealEnd-1).
290
+ const open = new Set();
291
+ const limit = Math.min(idealEnd, messages.length);
292
+ for (let j = 0; j < limit; j++) {
293
+ const msg = messages[j];
294
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
295
+ for (const b of msg.content) {
296
+ if (b.type === "tool_use" && b.id) {
297
+ open.add(b.id);
298
+ }
299
+ }
300
+ }
301
+ if (msg.role === "user" && Array.isArray(msg.content)) {
302
+ for (const b of msg.content) {
303
+ if (b.type === "tool_result" &&
304
+ b.tool_use_id) {
305
+ open.delete(b.tool_use_id);
306
+ }
307
+ }
308
+ }
309
+ }
310
+ const safetyCap = Math.min(messages.length, idealEnd + 20);
311
+ let i = limit;
312
+ while (i < safetyCap && messages[i]) {
313
+ const msg = messages[i];
314
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
315
+ for (const b of msg.content) {
316
+ if (b.type === "tool_use" && b.id) {
317
+ open.add(b.id);
318
+ }
319
+ }
320
+ }
321
+ if (msg.role === "user" && Array.isArray(msg.content)) {
322
+ for (const b of msg.content) {
323
+ if (b.type === "tool_result" &&
324
+ b.tool_use_id) {
325
+ open.delete(b.tool_use_id);
326
+ }
327
+ }
328
+ }
329
+ const isPlainUser = msg.role === "user" && !hasToolResultBlocks(msg);
330
+ if (isPlainUser && open.size === 0) {
331
+ return i;
332
+ }
171
333
  i++;
172
- return i;
334
+ }
335
+ // Safety fallback: find the last plain user anywhere in the array.
336
+ // Better to overshoot the budget than ship an orphan tool_use.
337
+ for (i = messages.length - 1; i >= 0; i--) {
338
+ const msg = messages[i];
339
+ if (msg.role === "user" && !hasToolResultBlocks(msg))
340
+ return i;
341
+ }
342
+ return idealEnd;
173
343
  }
174
344
  /**
175
- * Walk backward from `idealStart` until we land on a user turn — so the
176
- * tail slice begins with a user turn (mirror of `snapHeadEnd`). Caps at
177
- * `idealStart - 4` so the tail never grows unboundedly.
345
+ * Walk backward from `idealStart` until we land on a user message boundary.
346
+ * Skips user messages that are tool_result carriers (FIX #6).
178
347
  */
179
348
  function snapTailStart(messages, idealStart) {
180
349
  const floor = Math.max(0, idealStart - 4);
181
350
  let i = Math.max(idealStart, 0);
182
- while (i > floor && messages[i] && messages[i].role !== "user")
351
+ while (i > floor &&
352
+ messages[i] &&
353
+ (messages[i].role !== "user" || hasToolResultBlocks(messages[i]))) {
183
354
  i--;
355
+ }
184
356
  return i;
185
357
  }
186
- /** Pull the concatenated text out of an aux LLM ProviderResponse. */
187
- function extractText(blocks) {
188
- return blocks
189
- .filter((b) => b.type === "text")
190
- .map((b) => b.text)
191
- .join("\n");
358
+ /**
359
+ * Emergency tail-only trim — FIX #5: does NOT over-trim when the whole
360
+ * history fits inside targetTokens.
361
+ */
362
+ function emergencyTail(messages, targetTokens, notice) {
363
+ if (messages.length === 0)
364
+ return messages;
365
+ let acc = 0;
366
+ let cut = messages.length; // marker: threshold never reached
367
+ let reachedThreshold = false;
368
+ for (let i = messages.length - 1; i >= 0; i--) {
369
+ acc += estimateTokens([messages[i]]);
370
+ if (acc >= targetTokens) {
371
+ cut = i;
372
+ reachedThreshold = true;
373
+ break;
374
+ }
375
+ }
376
+ // FIX #5: if history fits entirely within target, return full history.
377
+ if (!reachedThreshold) {
378
+ return [{ role: "user", content: `<emergency-truncation>\n${notice}\n</emergency-truncation>` }, ...messages];
379
+ }
380
+ // Snap cut to a safe user message boundary.
381
+ while (cut < messages.length && messages[cut]?.role !== "user")
382
+ cut++;
383
+ if (cut >= messages.length)
384
+ cut = messages.length - 1;
385
+ while (cut > 0 && messages[cut]?.role !== "user")
386
+ cut--;
387
+ const tail = messages.slice(cut);
388
+ return [{ role: "user", content: `<emergency-truncation>\n${notice}\n</emergency-truncation>` }, ...tail];
192
389
  }
193
- // Test-only: reset the WeakMap state for deterministic single-test runs.
390
+ /** Test-only: reset the compactor anti-thrash WeakMap entry for an array. */
194
391
  export function __resetCompactorState(messages) {
195
392
  compactorAntiThrash.delete(messages);
196
393
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compressor.js","sourceRoot":"","sources":["../../src/memory/compressor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compressor.js","sourceRoot":"","sources":["../../src/memory/compressor.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { isAbortError } from "./core/is-abort-error.js";
1
+ import { isAbortError, isTimeoutError } from "./core/is-abort-error.js";
2
2
  import type { Provider } from "./providers/base.js";
3
3
  import type { AgentQueryOptions, UnifiedEvent } from "./types.js";
4
4
  /**
@@ -239,5 +239,5 @@ export declare function pickHigherBudget(a: number | undefined, b: number | unde
239
239
  * Exported for unit coverage — used internally by `maestroProvider`'s catch
240
240
  * branch to distinguish a user-initiated abort from a real provider crash.
241
241
  */
242
- export { isAbortError };
242
+ export { isAbortError, isTimeoutError };
243
243
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAsBrD,OAAO,KAAK,EAAE,QAAQ,EAAyC,MAAM,kBAAkB,CAAC;AA0CxF,OAAO,KAAK,EAAE,iBAAiB,EAAc,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,sBAAsB,QAA2B,CAAC;AAE/D,wBAAuB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,cAAc,CAAC,YAAY,CAAC,CA0jB5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAa1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/E;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAG,SAAkB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC5D,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,CAAC,EAAE,CAGL;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAQhE;AAwBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIjG;AAED;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAsBrE,OAAO,KAAK,EAAE,QAAQ,EAAyC,MAAM,kBAAkB,CAAC;AA0CxF,OAAO,KAAK,EAAE,iBAAiB,EAAc,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,sBAAsB,QAA2B,CAAC;AAE/D,wBAAuB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,cAAc,CAAC,YAAY,CAAC,CAylB5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAa1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/E;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAG,SAAkB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC5D,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,CAAC,EAAE,CAGL;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAQhE;AAwBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIjG;AAED;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC"}
package/dist/provider.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { join } from "node:path";
3
3
  import { AIAgent } from "./core/agent.js";
4
- import { isAbortError } from "./core/is-abort-error.js";
4
+ import { isAbortError, isTimeoutError } from "./core/is-abort-error.js";
5
5
  import { runConversation } from "./core/loop.js";
6
6
  import { registerMcpTools, startMcpPool } from "./mcp/pool.js";
7
7
  import { buildSystemReminder } from "./memory/reminder.js";
@@ -25,6 +25,7 @@ import { buildSkillsIndex } from "./skills/index-builder.js";
25
25
  import { loadSkillsCached } from "./skills/loader.js";
26
26
  import { getTaskStore } from "./state/tasks.js";
27
27
  import { createAgentTool } from "./tools/builtin/agent.js";
28
+ import { askUserQuestionTool } from "./tools/builtin/ask_user_question.js";
28
29
  import { bashTool, createBashTool } from "./tools/builtin/bash.js";
29
30
  import { createBackgroundBashRegistry, createBashOutputTool, createKillBashTool, } from "./tools/builtin/bash_background.js";
30
31
  import { createEditTool } from "./tools/builtin/edit.js";
@@ -33,10 +34,9 @@ import { grepTool } from "./tools/builtin/grep.js";
33
34
  import { createReadTool } from "./tools/builtin/read.js";
34
35
  import { createSkillViewTool } from "./tools/builtin/skill_view.js";
35
36
  import { createSkillWriteTool } from "./tools/builtin/skill_write.js";
36
- import { createTaskOutputTool, createTaskStopTool, createTaskCreateTool, createTaskGetTool, createTaskListTool, createTaskUpdateTool, } from "./tools/builtin/tasks.js";
37
+ import { createTaskCreateTool, createTaskGetTool, createTaskListTool, createTaskOutputTool, createTaskStopTool, createTaskUpdateTool, } from "./tools/builtin/tasks.js";
37
38
  import { createToolSearchTool } from "./tools/builtin/tool_search.js";
38
39
  import { webFetchTool } from "./tools/builtin/web_fetch.js";
39
- import { askUserQuestionTool } from "./tools/builtin/ask_user_question.js";
40
40
  import { createWriteTool } from "./tools/builtin/write.js";
41
41
  import { getFileStateTracker } from "./tools/file-state.js";
42
42
  import { ToolRegistry } from "./tools/registry.js";
@@ -502,6 +502,12 @@ export async function* maestroProvider(opts) {
502
502
  ...(thinkingBudget ? { thinkingBudget } : {}),
503
503
  ...(resolvedEffort ? { effort: resolvedEffort } : {}),
504
504
  ...(opts.abortController?.signal ? { abortSignal: opts.abortController.signal } : {}),
505
+ // v0.1.28+: forward the caller's aux-model override into AIAgent so the
506
+ // loop's compressIfNeeded call honors it. When omitted the loop falls
507
+ // back to `resolveAuxModel(resolvedModel)`, which routes heavy tiers
508
+ // (gpt-5.5, opus, deepseek-v4-pro) to their cheapest sibling.
509
+ ...(opts.auxModel ? { auxModel: opts.auxModel } : {}),
510
+ ...(opts.toolResultTruncation ? { toolResultTruncation: opts.toolResultTruncation } : {}),
505
511
  });
506
512
  // Wire abort → close MCP pool early. Without this, an aborted turn could
507
513
  // leave Playwright / OCR subprocesses spinning until the finally block,
@@ -549,6 +555,28 @@ export async function* maestroProvider(opts) {
549
555
  aborted = true;
550
556
  }
551
557
  else {
558
+ // v0.1.28: dump the full error shape (name/code/cause/stack) so we can
559
+ // tell the difference between a codex OAuth refresh timeout, the
560
+ // `/responses` HTTP fetch timing out mid-roundtrip, an SSE stream
561
+ // abort during chunk parse, and a plain Anthropic/Deepseek crash —
562
+ // all of which previously surfaced as the same opaque "maestroProvider
563
+ // crashed: <message>" event. The lower-level codex hops also log on
564
+ // throw (see `codex.ts`/`codex-auth.ts` v0.1.28 instrumentation), so
565
+ // the combined log trail tells us which leg actually died.
566
+ const errIsTimeout = isTimeoutError(e);
567
+ logger.error({
568
+ sessionId,
569
+ model: resolvedModel,
570
+ effort: resolvedEffort,
571
+ isTimeoutError: errIsTimeout,
572
+ errName: e instanceof Error ? e.name : typeof e,
573
+ errCode: e?.code,
574
+ errMessage: e instanceof Error ? e.message : String(e),
575
+ errCause: e?.cause,
576
+ stack: e instanceof Error ? e.stack : undefined,
577
+ }, errIsTimeout
578
+ ? "maestroProvider: upstream timeout caught in provider.ts catch"
579
+ : "maestroProvider: unhandled error caught in provider.ts catch");
552
580
  yield {
553
581
  type: "error",
554
582
  content: `maestroProvider crashed: ${e instanceof Error ? e.message : String(e)}`,
@@ -866,5 +894,5 @@ export function pickHigherBudget(a, b) {
866
894
  * Exported for unit coverage — used internally by `maestroProvider`'s catch
867
895
  * branch to distinguish a user-initiated abort from a real provider crash.
868
896
  */
869
- export { isAbortError };
897
+ export { isAbortError, isTimeoutError };
870
898
  //# sourceMappingURL=provider.js.map