@ouro.bot/cli 0.1.0-alpha.492 → 0.1.0-alpha.494
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.json +12 -0
- package/dist/heart/core.js +23 -11
- package/dist/heart/session-events.js +12 -8
- package/dist/mailroom/blob-store.js +7 -1
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.494",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Bump default Azure Blob operation timeout from 20s to 60s. Slugger's HEY-corpus validation against the booking-aware ranking from #608 surfaced a real issue: ranking and metadata are clean, but body fetches for targeted retrieval (`mail_thread`-style 'open this specific message') were timing out on real-world mail bodies. HEY mail with HTML-heavy booking confirmations regularly exceed the 20s ceiling on cold reads from Azure Blob. 60s with 2 attempts gives 120s max wait, which matches Azure's actual cold-read SLA for few-MB blobs while still bounding total wait. Index reads still fit comfortably in this budget. Existing test fixture for the timeout error message updated."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"version": "0.1.0-alpha.493",
|
|
12
|
+
"changes": [
|
|
13
|
+
"Position-aware orphan-tool-result detection in `repairToolCallSequences`. Slugger's session was STILL hitting MiniMax error 2013 even after the alpha.492 inline-reasoning strip landed because the orphan check was global (a tool result was kept if its tool_call_id appeared in ANY assistant message in the conversation, regardless of order). After session pruning, a synthetic tool-result for a long-pruned tool_call ended up at sequence 86 referencing `call_function_utqogadgqp5h_1` while the assistant message that defined that id lived at sequence 88 — AFTER the tool result. MiniMax requires tool results to follow their matching assistant. The fix walks the conversation in order, tracking tool_call_ids only as they're encountered in assistant messages; tool results referencing ids that haven't been defined yet are removed. Regression test reproduces the exact misordered shape and asserts the misplaced tool result is dropped while the correctly-ordered one survives. This is the third and final layer of the empty-reply chain (#611 stripped the operator surface, #612 stripped the persisted content + load-time repair, #493 fixes orphan-detection ordering)."
|
|
14
|
+
]
|
|
15
|
+
},
|
|
4
16
|
{
|
|
5
17
|
"version": "0.1.0-alpha.492",
|
|
6
18
|
"changes": [
|
package/dist/heart/core.js
CHANGED
|
@@ -361,27 +361,39 @@ const TOOL_SCAN_BOUNDARY_ROLES = new Set(["assistant", "user"]);
|
|
|
361
361
|
// 1. If an assistant message has tool_calls but missing tool results, inject synthetic error results.
|
|
362
362
|
// 2. If a tool result's tool_call_id doesn't match any tool_calls in a preceding assistant message, remove it.
|
|
363
363
|
// This prevents 400 errors from the API after an aborted turn.
|
|
364
|
+
//
|
|
365
|
+
// Position-aware: a tool result is orphaned when its tool_call_id hasn't been
|
|
366
|
+
// defined by an assistant message AT THIS POSITION yet. MiniMax-M2.7 reuses
|
|
367
|
+
// canonical tool_call_ids across turns, so the global-set check that this
|
|
368
|
+
// function used previously kept misordered tool results that MiniMax then
|
|
369
|
+
// rejected with error 2013 ("tool result's tool id not found"). Walking
|
|
370
|
+
// in order matches what MiniMax actually enforces.
|
|
364
371
|
function repairOrphanedToolCalls(messages) {
|
|
365
|
-
// Pass 1:
|
|
366
|
-
|
|
367
|
-
|
|
372
|
+
// Pass 1: walk in order, accumulate seen tool_call_ids per-position, and
|
|
373
|
+
// mark tool results for removal if their id hasn't been defined yet.
|
|
374
|
+
const seenCallIds = new Set();
|
|
375
|
+
const removeIndices = [];
|
|
376
|
+
for (let i = 0; i < messages.length; i++) {
|
|
377
|
+
const msg = messages[i];
|
|
368
378
|
if (msg.role === "assistant") {
|
|
369
379
|
const asst = msg;
|
|
370
380
|
if (asst.tool_calls) {
|
|
371
381
|
for (const tc of asst.tool_calls)
|
|
372
|
-
|
|
382
|
+
seenCallIds.add(tc.id);
|
|
373
383
|
}
|
|
384
|
+
continue;
|
|
374
385
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const toolMsg = messages[i];
|
|
380
|
-
if (!validCallIds.has(toolMsg.tool_call_id)) {
|
|
381
|
-
messages.splice(i, 1);
|
|
386
|
+
if (msg.role === "tool") {
|
|
387
|
+
const toolMsg = msg;
|
|
388
|
+
if (!seenCallIds.has(toolMsg.tool_call_id)) {
|
|
389
|
+
removeIndices.push(i);
|
|
382
390
|
}
|
|
383
391
|
}
|
|
384
392
|
}
|
|
393
|
+
// Splice from the end so earlier indices stay valid.
|
|
394
|
+
for (let i = removeIndices.length - 1; i >= 0; i--) {
|
|
395
|
+
messages.splice(removeIndices[i], 1);
|
|
396
|
+
}
|
|
385
397
|
// Pass 3: inject synthetic results for tool_calls missing their tool results
|
|
386
398
|
for (let i = 0; i < messages.length; i++) {
|
|
387
399
|
const msg = messages[i];
|
|
@@ -336,18 +336,22 @@ function repairSessionMessages(messages) {
|
|
|
336
336
|
}
|
|
337
337
|
function repairToolCallSequences(messages, inlineReasoningStrippedCallIds = new Set()) {
|
|
338
338
|
const normalized = messages.map(normalizeMessage);
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
validCallIds.add(toolCall.id);
|
|
345
|
-
}
|
|
339
|
+
// Position-aware orphan detection. A tool result is orphaned if there is
|
|
340
|
+
// no preceding assistant message in the array whose tool_calls contain the
|
|
341
|
+
// matching id. (The previous logic checked all assistant messages
|
|
342
|
+
// globally, which kept tool results that appeared BEFORE their matching
|
|
343
|
+
// assistant — invalid order — and triggered MiniMax error 2013 on replay.)
|
|
346
344
|
let removed = 0;
|
|
345
|
+
const seenCallIds = new Set();
|
|
347
346
|
const repaired = normalized.filter((msg) => {
|
|
347
|
+
if (msg.role === "assistant") {
|
|
348
|
+
for (const tc of msg.toolCalls)
|
|
349
|
+
seenCallIds.add(tc.id);
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
348
352
|
if (msg.role !== "tool")
|
|
349
353
|
return true;
|
|
350
|
-
const keep = msg.toolCallId !== null &&
|
|
354
|
+
const keep = msg.toolCallId !== null && seenCallIds.has(msg.toolCallId);
|
|
351
355
|
if (!keep)
|
|
352
356
|
removed++;
|
|
353
357
|
return keep;
|
|
@@ -9,7 +9,13 @@ const MESSAGE_INDEX_PREFIX = "message-index";
|
|
|
9
9
|
const MESSAGE_INDEX_SORT_MAX_MS = 9_999_999_999_999;
|
|
10
10
|
const MESSAGE_INDEX_SORT_WIDTH = 13;
|
|
11
11
|
const MESSAGE_INDEX_NO_SOURCE = "~";
|
|
12
|
-
|
|
12
|
+
// Bumped from 20s after Slugger's HEY-corpus validation revealed that
|
|
13
|
+
// real-world mail bodies (HTML-heavy booking confirmations, MBOX-imported
|
|
14
|
+
// large messages) regularly exceed the original 20s ceiling. 60s with 2
|
|
15
|
+
// attempts = 120s max wait, which is closer to what Azure Blob actually
|
|
16
|
+
// needs for cold reads of a few-MB message body. Index reads still fit
|
|
17
|
+
// comfortably in this budget.
|
|
18
|
+
const DEFAULT_BLOB_OPERATION_TIMEOUT_MS = 60_000;
|
|
13
19
|
const DEFAULT_BLOB_DOWNLOAD_ATTEMPTS = 2;
|
|
14
20
|
const DEFAULT_MESSAGE_FETCH_CONCURRENCY = 20;
|
|
15
21
|
const DEFAULT_MESSAGE_INDEX_BACKFILL_CONCURRENCY = 8;
|