omnius 1.0.79 → 1.0.80
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/dist/index.js +276 -73
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -538985,6 +538985,28 @@ function stripThinkBlocks(s2) {
|
|
|
538985
538985
|
return s2;
|
|
538986
538986
|
return s2.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
538987
538987
|
}
|
|
538988
|
+
function injectNoThinkDirective(messages2) {
|
|
538989
|
+
if (!Array.isArray(messages2) || messages2.length === 0)
|
|
538990
|
+
return messages2;
|
|
538991
|
+
let lastUserIdx = -1;
|
|
538992
|
+
for (let i2 = messages2.length - 1; i2 >= 0; i2--) {
|
|
538993
|
+
if (messages2[i2]?.role === "user") {
|
|
538994
|
+
lastUserIdx = i2;
|
|
538995
|
+
break;
|
|
538996
|
+
}
|
|
538997
|
+
}
|
|
538998
|
+
if (lastUserIdx === -1)
|
|
538999
|
+
return messages2;
|
|
539000
|
+
const target = messages2[lastUserIdx];
|
|
539001
|
+
if (!target || typeof target.content !== "string")
|
|
539002
|
+
return messages2;
|
|
539003
|
+
if (/\/no_think\b/i.test(target.content))
|
|
539004
|
+
return messages2;
|
|
539005
|
+
const annotated = `${target.content}
|
|
539006
|
+
|
|
539007
|
+
/no_think`;
|
|
539008
|
+
return messages2.map((m2, i2) => i2 === lastUserIdx ? { ...m2, content: annotated } : m2);
|
|
539009
|
+
}
|
|
538988
539010
|
function computeEffectiveThink(params) {
|
|
538989
539011
|
if (process.env["OMNIUS_FORCE_NO_THINK"] === "1")
|
|
538990
539012
|
return false;
|
|
@@ -551435,14 +551457,40 @@ ${description}`
|
|
|
551435
551457
|
}) : null;
|
|
551436
551458
|
const requestBaseUrl = poolSlot?.baseUrl ?? this.baseUrl;
|
|
551437
551459
|
let poolSuccess = false;
|
|
551460
|
+
const combineAbortSignals = (signals) => {
|
|
551461
|
+
const filtered = signals.filter((s2) => s2 instanceof AbortSignal);
|
|
551462
|
+
if (filtered.length === 0)
|
|
551463
|
+
return void 0;
|
|
551464
|
+
if (filtered.length === 1)
|
|
551465
|
+
return filtered[0];
|
|
551466
|
+
const anyFn = AbortSignal.any;
|
|
551467
|
+
if (typeof anyFn === "function")
|
|
551468
|
+
return anyFn(filtered);
|
|
551469
|
+
const controller = new AbortController();
|
|
551470
|
+
for (const sig of filtered) {
|
|
551471
|
+
if (sig.aborted) {
|
|
551472
|
+
controller.abort(sig.reason);
|
|
551473
|
+
break;
|
|
551474
|
+
}
|
|
551475
|
+
sig.addEventListener("abort", () => {
|
|
551476
|
+
if (!controller.signal.aborted) {
|
|
551477
|
+
controller.abort(sig.reason);
|
|
551478
|
+
}
|
|
551479
|
+
});
|
|
551480
|
+
}
|
|
551481
|
+
return controller.signal;
|
|
551482
|
+
};
|
|
551483
|
+
const effectiveTimeoutMs = Number.isFinite(request.timeoutMs) && request.timeoutMs > 0 ? request.timeoutMs : 0;
|
|
551484
|
+
const timeoutSignal = effectiveTimeoutMs > 0 && typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(effectiveTimeoutMs) : void 0;
|
|
551485
|
+
const combinedAbortSignal = combineAbortSignals([this._abortSignal, timeoutSignal]);
|
|
551438
551486
|
try {
|
|
551439
551487
|
const fetchOpts = {
|
|
551440
551488
|
method: "POST",
|
|
551441
551489
|
headers: this.authHeaders(),
|
|
551442
551490
|
body: JSON.stringify(body)
|
|
551443
551491
|
};
|
|
551444
|
-
if (
|
|
551445
|
-
fetchOpts.signal =
|
|
551492
|
+
if (combinedAbortSignal)
|
|
551493
|
+
fetchOpts.signal = combinedAbortSignal;
|
|
551446
551494
|
const resp = await fetch(`${requestBaseUrl}/v1/chat/completions`, fetchOpts);
|
|
551447
551495
|
if (!resp.ok) {
|
|
551448
551496
|
const text = await resp.text().catch(() => "");
|
|
@@ -551456,34 +551504,42 @@ ${description}`
|
|
|
551456
551504
|
const firstChoice = choices[0];
|
|
551457
551505
|
const responseText = firstChoice ? String(firstChoice.message?.content ?? "") : "";
|
|
551458
551506
|
const outcome = this.recordThinkOutcome(responseText, effectiveThink === true);
|
|
551459
|
-
|
|
551460
|
-
|
|
551461
|
-
|
|
551462
|
-
|
|
551463
|
-
|
|
551464
|
-
|
|
551465
|
-
|
|
551466
|
-
|
|
551467
|
-
|
|
551468
|
-
|
|
551507
|
+
const independentOutcome = effectiveThink !== true ? classifyThinkOutcome(responseText) : null;
|
|
551508
|
+
const shouldRecoverFromEmpty = responseFormat !== void 0 && independentOutcome !== null && (independentOutcome === "empty_after_strip" || independentOutcome === "unclosed_think");
|
|
551509
|
+
const justSuppressed = this._thinkSuppressed && this._thinkFailStreak === _OllamaAgenticBackend._thinkFailThreshold;
|
|
551510
|
+
const shouldRetryThinkGuard = outcome !== null && effectiveThink === true && (justSuppressed || outcome === "empty_after_strip" || outcome === "unclosed_think");
|
|
551511
|
+
if (shouldRetryThinkGuard || shouldRecoverFromEmpty) {
|
|
551512
|
+
const retryMessages = injectNoThinkDirective(cleanedMessages);
|
|
551513
|
+
const retryBody = {
|
|
551514
|
+
model: this.model,
|
|
551515
|
+
messages: retryMessages,
|
|
551516
|
+
tools: request.tools,
|
|
551517
|
+
temperature: request.temperature,
|
|
551518
|
+
max_tokens: request.maxTokens,
|
|
551519
|
+
think: false
|
|
551520
|
+
};
|
|
551521
|
+
if (responseFormat !== void 0 && shouldRetryThinkGuard && !shouldRecoverFromEmpty) {
|
|
551522
|
+
retryBody["response_format"] = responseFormat;
|
|
551523
|
+
}
|
|
551524
|
+
try {
|
|
551525
|
+
const retryOpts = {
|
|
551526
|
+
method: "POST",
|
|
551527
|
+
headers: this.authHeaders(),
|
|
551528
|
+
body: JSON.stringify(retryBody)
|
|
551469
551529
|
};
|
|
551470
|
-
if (
|
|
551471
|
-
|
|
551472
|
-
}
|
|
551473
|
-
|
|
551474
|
-
const
|
|
551475
|
-
|
|
551476
|
-
|
|
551477
|
-
|
|
551478
|
-
|
|
551479
|
-
|
|
551480
|
-
|
|
551481
|
-
|
|
551482
|
-
|
|
551483
|
-
const retryData = await retryResp.json();
|
|
551484
|
-
const retryChoices = retryData.choices ?? [];
|
|
551485
|
-
const retryUsage = retryData.usage;
|
|
551486
|
-
if (retryChoices.length > 0) {
|
|
551530
|
+
if (combinedAbortSignal)
|
|
551531
|
+
retryOpts.signal = combinedAbortSignal;
|
|
551532
|
+
const retryResp = await fetch(`${requestBaseUrl}/v1/chat/completions`, retryOpts);
|
|
551533
|
+
if (retryResp.ok) {
|
|
551534
|
+
const retryData = await retryResp.json();
|
|
551535
|
+
const retryChoices = retryData.choices ?? [];
|
|
551536
|
+
const retryUsage = retryData.usage;
|
|
551537
|
+
if (retryChoices.length > 0) {
|
|
551538
|
+
const retryFirst = retryChoices[0];
|
|
551539
|
+
const retryText = retryFirst ? String(retryFirst.message?.content ?? "") : "";
|
|
551540
|
+
const retryClass = classifyThinkOutcome(retryText);
|
|
551541
|
+
const retryUsable = retryClass !== "empty_after_strip" && retryClass !== "unclosed_think";
|
|
551542
|
+
if (retryUsable) {
|
|
551487
551543
|
poolSuccess = true;
|
|
551488
551544
|
return {
|
|
551489
551545
|
choices: retryChoices.map((c9) => {
|
|
@@ -551501,8 +551557,8 @@ ${description}`
|
|
|
551501
551557
|
};
|
|
551502
551558
|
}
|
|
551503
551559
|
}
|
|
551504
|
-
} catch {
|
|
551505
551560
|
}
|
|
551561
|
+
} catch {
|
|
551506
551562
|
}
|
|
551507
551563
|
}
|
|
551508
551564
|
poolSuccess = true;
|
|
@@ -615356,23 +615412,56 @@ ${lines.join("\n")}`);
|
|
|
615356
615412
|
nextAnalysisAfterMs: decision.nextCheckAfterMs
|
|
615357
615413
|
});
|
|
615358
615414
|
}
|
|
615359
|
-
async telegramRouterJsonCompletion(backend, request) {
|
|
615415
|
+
async telegramRouterJsonCompletion(backend, request, diagnostics) {
|
|
615416
|
+
let jsonModeResult;
|
|
615417
|
+
let jsonModeError;
|
|
615360
615418
|
try {
|
|
615361
|
-
|
|
615419
|
+
jsonModeResult = await backend.chatCompletion({
|
|
615362
615420
|
...request,
|
|
615363
615421
|
responseFormat: TELEGRAM_INTERACTION_DECISION_RESPONSE_FORMAT
|
|
615364
615422
|
});
|
|
615365
|
-
const visible =
|
|
615423
|
+
const visible = jsonModeResult.choices.some(
|
|
615366
615424
|
(choice) => stripTelegramHiddenThinking(choice.message.content ?? "").trim().length > 0
|
|
615367
615425
|
);
|
|
615368
|
-
if (visible)
|
|
615369
|
-
|
|
615426
|
+
if (visible) {
|
|
615427
|
+
if (diagnostics) diagnostics.jsonModeStatus = "visible";
|
|
615428
|
+
return jsonModeResult;
|
|
615429
|
+
}
|
|
615430
|
+
if (diagnostics) diagnostics.jsonModeStatus = "empty-after-strip";
|
|
615431
|
+
} catch (err) {
|
|
615432
|
+
jsonModeError = err;
|
|
615433
|
+
if (diagnostics) {
|
|
615434
|
+
diagnostics.jsonModeStatus = "threw";
|
|
615435
|
+
diagnostics.jsonModeError = err instanceof Error ? err.message : String(err);
|
|
615436
|
+
}
|
|
615437
|
+
}
|
|
615438
|
+
try {
|
|
615439
|
+
const plainResult = await backend.chatCompletion(request);
|
|
615440
|
+
if (diagnostics) {
|
|
615441
|
+
const plainVisible = plainResult.choices.some(
|
|
615442
|
+
(choice) => stripTelegramHiddenThinking(choice.message.content ?? "").trim().length > 0
|
|
615443
|
+
);
|
|
615444
|
+
diagnostics.plainStatus = plainVisible ? "visible" : "empty-after-strip";
|
|
615445
|
+
}
|
|
615446
|
+
return plainResult;
|
|
615447
|
+
} catch (err) {
|
|
615448
|
+
if (diagnostics) {
|
|
615449
|
+
diagnostics.plainStatus = "threw";
|
|
615450
|
+
diagnostics.plainError = err instanceof Error ? err.message : String(err);
|
|
615451
|
+
}
|
|
615452
|
+
if (jsonModeError instanceof Error && !(err instanceof Error)) throw jsonModeError;
|
|
615453
|
+
throw err;
|
|
615370
615454
|
}
|
|
615371
|
-
return backend.chatCompletion(request);
|
|
615372
615455
|
}
|
|
615373
|
-
async repairTelegramInteractionDecision(backend, rawOutput, forcedRoute, timeoutMs) {
|
|
615456
|
+
async repairTelegramInteractionDecision(backend, rawOutput, forcedRoute, timeoutMs, diagnostics) {
|
|
615374
615457
|
const rawPreview = telegramRouterRawPreview(rawOutput, 4e3);
|
|
615375
|
-
if (!rawPreview || telegramDecisionOutputHasDanglingJson(rawOutput))
|
|
615458
|
+
if (!rawPreview || telegramDecisionOutputHasDanglingJson(rawOutput)) {
|
|
615459
|
+
if (diagnostics) {
|
|
615460
|
+
diagnostics.repairStatus = "skipped";
|
|
615461
|
+
diagnostics.repairError = !rawPreview ? "no recoverable text in router output (empty after <think> strip)" : "router output was dangling JSON; repair would only re-produce a truncation";
|
|
615462
|
+
}
|
|
615463
|
+
return null;
|
|
615464
|
+
}
|
|
615376
615465
|
const routeInstruction = forcedRoute ? `The route is operator-forced and must be "${forcedRoute}".` : `Preserve the original route if present; otherwise choose chat or action only if the original output clearly implies one.`;
|
|
615377
615466
|
const prompt = [
|
|
615378
615467
|
`Repair this Telegram attention-router output into strict JSON.`,
|
|
@@ -615384,7 +615473,9 @@ ${lines.join("\n")}`);
|
|
|
615384
615473
|
`{"recoverable":true|false,"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note"}`,
|
|
615385
615474
|
``,
|
|
615386
615475
|
`Original router output:`,
|
|
615387
|
-
rawPreview
|
|
615476
|
+
rawPreview,
|
|
615477
|
+
``,
|
|
615478
|
+
`/no_think`
|
|
615388
615479
|
].join("\n");
|
|
615389
615480
|
try {
|
|
615390
615481
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
@@ -615402,11 +615493,18 @@ ${lines.join("\n")}`);
|
|
|
615402
615493
|
think: false
|
|
615403
615494
|
});
|
|
615404
615495
|
const repairedText = result.choices[0]?.message?.content ?? "";
|
|
615405
|
-
if (telegramDecisionRecoverableFlag(repairedText) === false)
|
|
615496
|
+
if (telegramDecisionRecoverableFlag(repairedText) === false) {
|
|
615497
|
+
if (diagnostics) diagnostics.repairStatus = "no-recoverable-output";
|
|
615498
|
+
return null;
|
|
615499
|
+
}
|
|
615406
615500
|
const parsed = parseTelegramInteractionDecision(repairedText, forcedRoute, {
|
|
615407
615501
|
defaultShouldReply: false
|
|
615408
615502
|
});
|
|
615409
|
-
if (!parsed)
|
|
615503
|
+
if (!parsed) {
|
|
615504
|
+
if (diagnostics) diagnostics.repairStatus = "no-recoverable-output";
|
|
615505
|
+
return null;
|
|
615506
|
+
}
|
|
615507
|
+
if (diagnostics) diagnostics.repairStatus = "recovered";
|
|
615410
615508
|
return {
|
|
615411
615509
|
...parsed,
|
|
615412
615510
|
reason: `recovered router decision: ${parsed.reason}`.slice(0, 240),
|
|
@@ -615417,17 +615515,23 @@ ${repairedText}`,
|
|
|
615417
615515
|
mentalNote: parsed.mentalNote ?? "router decision recovered from non-JSON model output",
|
|
615418
615516
|
memoryNote: parsed.memoryNote ?? "router repair preserved the model-derived attention decision"
|
|
615419
615517
|
};
|
|
615420
|
-
} catch {
|
|
615518
|
+
} catch (err) {
|
|
615519
|
+
if (diagnostics) {
|
|
615520
|
+
diagnostics.repairStatus = "threw";
|
|
615521
|
+
diagnostics.repairError = err instanceof Error ? err.message : String(err);
|
|
615522
|
+
}
|
|
615421
615523
|
return null;
|
|
615422
615524
|
}
|
|
615423
615525
|
}
|
|
615424
|
-
async retryTelegramInteractionDecisionStrict(backend, userPrompt, rawOutput, forcedRoute, timeoutMs) {
|
|
615526
|
+
async retryTelegramInteractionDecisionStrict(backend, userPrompt, rawOutput, forcedRoute, timeoutMs, diagnostics) {
|
|
615425
615527
|
const invalidPreview = telegramRouterRawPreview(rawOutput, 1200) ?? "(empty assistant content)";
|
|
615426
615528
|
const routeInstruction = forcedRoute ? `The operator selected Telegram mode "${forcedRoute}". The route field must be "${forcedRoute}", but should_reply must still be inferred from context.` : `Infer route live from context.`;
|
|
615529
|
+
const trimmedUserPrompt = userPrompt.length > 4e3 ? `…
|
|
615530
|
+
${userPrompt.slice(-4e3)}` : userPrompt;
|
|
615427
615531
|
const retryPrompt = [
|
|
615428
615532
|
`The previous Telegram attention-router response was not usable JSON.`,
|
|
615429
|
-
`Make a fresh model-derived attention decision from the
|
|
615430
|
-
`Return exactly one JSON object and no prose.`,
|
|
615533
|
+
`Make a fresh model-derived attention decision from the context below. Do not use hard-coded mention or keyword triggers.`,
|
|
615534
|
+
`Return exactly one JSON object and no prose. No <think> tags. No commentary.`,
|
|
615431
615535
|
routeInstruction,
|
|
615432
615536
|
``,
|
|
615433
615537
|
`Required schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12,"silent_disposition":"short outcome-level disposition","mental_note":"short outcome-level observation","memory_note":"short memory/summary update","relationship_note":"short relationship/thread note"}`,
|
|
@@ -615435,15 +615539,17 @@ ${repairedText}`,
|
|
|
615435
615539
|
`Invalid previous output, for diagnostics only:`,
|
|
615436
615540
|
invalidPreview,
|
|
615437
615541
|
``,
|
|
615438
|
-
`
|
|
615439
|
-
|
|
615542
|
+
`Router context (trailing-window):`,
|
|
615543
|
+
trimmedUserPrompt,
|
|
615544
|
+
``,
|
|
615545
|
+
`/no_think`
|
|
615440
615546
|
].join("\n");
|
|
615441
615547
|
try {
|
|
615442
615548
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
615443
615549
|
messages: [
|
|
615444
615550
|
{
|
|
615445
615551
|
role: "system",
|
|
615446
|
-
content: "You are a strict JSON Telegram attention router. Output one valid JSON object only."
|
|
615552
|
+
content: "You are a strict JSON Telegram attention router. Output one valid JSON object only. Never emit <think> tags."
|
|
615447
615553
|
},
|
|
615448
615554
|
{ role: "user", content: retryPrompt }
|
|
615449
615555
|
],
|
|
@@ -615454,10 +615560,18 @@ ${repairedText}`,
|
|
|
615454
615560
|
think: false
|
|
615455
615561
|
});
|
|
615456
615562
|
const retryText = result.choices[0]?.message?.content ?? "";
|
|
615563
|
+
if (diagnostics) diagnostics.strictRetryPreview = telegramRouterRawPreview(retryText, 320);
|
|
615457
615564
|
const parsed = parseTelegramInteractionDecision(retryText, forcedRoute, {
|
|
615458
615565
|
defaultShouldReply: false
|
|
615459
615566
|
});
|
|
615460
|
-
if (!parsed)
|
|
615567
|
+
if (!parsed) {
|
|
615568
|
+
if (diagnostics) {
|
|
615569
|
+
const cleaned = stripTelegramHiddenThinking(retryText).trim();
|
|
615570
|
+
diagnostics.strictRetryStatus = cleaned ? "unparseable" : "empty";
|
|
615571
|
+
}
|
|
615572
|
+
return null;
|
|
615573
|
+
}
|
|
615574
|
+
if (diagnostics) diagnostics.strictRetryStatus = "recovered";
|
|
615461
615575
|
return {
|
|
615462
615576
|
...parsed,
|
|
615463
615577
|
reason: `strict router retry: ${parsed.reason}`.slice(0, 240),
|
|
@@ -615467,7 +615581,11 @@ ${repairedText}`,
|
|
|
615467
615581
|
${retryText}`,
|
|
615468
615582
|
mentalNote: parsed.mentalNote ?? "strict router retry produced a valid attention decision"
|
|
615469
615583
|
};
|
|
615470
|
-
} catch {
|
|
615584
|
+
} catch (err) {
|
|
615585
|
+
if (diagnostics) {
|
|
615586
|
+
diagnostics.strictRetryStatus = "threw";
|
|
615587
|
+
diagnostics.strictRetryError = err instanceof Error ? err.message : String(err);
|
|
615588
|
+
}
|
|
615471
615589
|
return null;
|
|
615472
615590
|
}
|
|
615473
615591
|
}
|
|
@@ -615488,7 +615606,7 @@ ${retryText}`,
|
|
|
615488
615606
|
forceAnalyze: daydreamForceCheck
|
|
615489
615607
|
});
|
|
615490
615608
|
if (!config) {
|
|
615491
|
-
const
|
|
615609
|
+
const fallback = {
|
|
615492
615610
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
615493
615611
|
shouldReply: false,
|
|
615494
615612
|
confidence: 0,
|
|
@@ -615497,8 +615615,8 @@ ${retryText}`,
|
|
|
615497
615615
|
silentDisposition: "retained as context without replying",
|
|
615498
615616
|
mentalNote: "router unavailable, so no model-derived attention note was produced"
|
|
615499
615617
|
};
|
|
615500
|
-
this.applyTelegramStimulationDecision(sessionKey,
|
|
615501
|
-
return
|
|
615618
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback);
|
|
615619
|
+
return fallback;
|
|
615502
615620
|
}
|
|
615503
615621
|
const backend = new OllamaAgenticBackend(
|
|
615504
615622
|
config.backendUrl,
|
|
@@ -615553,6 +615671,7 @@ ${stimulationProbe.context}`,
|
|
|
615553
615671
|
`Current Telegram message text (untrusted user data):
|
|
615554
615672
|
${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
615555
615673
|
].filter(Boolean).join("\n");
|
|
615674
|
+
const diagnostics = {};
|
|
615556
615675
|
try {
|
|
615557
615676
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
615558
615677
|
messages: [
|
|
@@ -615567,7 +615686,7 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615567
615686
|
maxTokens: 700,
|
|
615568
615687
|
timeoutMs: Math.min(Math.max(config.timeoutMs ?? 3e4, 5e3), 15e3),
|
|
615569
615688
|
think: false
|
|
615570
|
-
});
|
|
615689
|
+
}, diagnostics);
|
|
615571
615690
|
const text = result.choices[0]?.message?.content ?? "";
|
|
615572
615691
|
const parsed = parseTelegramInteractionDecision(text, forcedRoute, {
|
|
615573
615692
|
defaultShouldReply: false
|
|
@@ -615580,7 +615699,8 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615580
615699
|
backend,
|
|
615581
615700
|
text,
|
|
615582
615701
|
forcedRoute,
|
|
615583
|
-
config.timeoutMs ?? 3e4
|
|
615702
|
+
config.timeoutMs ?? 3e4,
|
|
615703
|
+
diagnostics
|
|
615584
615704
|
);
|
|
615585
615705
|
if (repaired) {
|
|
615586
615706
|
this.applyTelegramStimulationDecision(sessionKey, repaired);
|
|
@@ -615591,39 +615711,122 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615591
615711
|
userPrompt,
|
|
615592
615712
|
text,
|
|
615593
615713
|
forcedRoute,
|
|
615594
|
-
config.timeoutMs ?? 3e4
|
|
615714
|
+
config.timeoutMs ?? 3e4,
|
|
615715
|
+
diagnostics
|
|
615595
615716
|
);
|
|
615596
615717
|
if (strictRetry) {
|
|
615597
615718
|
this.applyTelegramStimulationDecision(sessionKey, strictRetry);
|
|
615598
615719
|
return strictRetry;
|
|
615599
615720
|
}
|
|
615600
615721
|
const invalidRouterPreview = telegramRouterRawPreview(text);
|
|
615601
|
-
const
|
|
615722
|
+
const failureNarrative = this.summarizeTelegramRouterFailure(diagnostics);
|
|
615723
|
+
const fallback = {
|
|
615602
615724
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
615603
615725
|
shouldReply: false,
|
|
615604
615726
|
confidence: 0,
|
|
615605
615727
|
reason: "router output was not valid decision JSON after repair/retry; no model-derived reply decision",
|
|
615606
615728
|
source: "inference-unavailable",
|
|
615607
615729
|
silentDisposition: "retained as context without replying because the router decision could not be parsed",
|
|
615608
|
-
|
|
615609
|
-
|
|
615730
|
+
// Preserve the well-known mental-note strings (existing tests rely
|
|
615731
|
+
// on them) but append the per-step diagnostic so operators get a
|
|
615732
|
+
// real explanation of what actually failed.
|
|
615733
|
+
mentalNote: (invalidRouterPreview ? "router produced an invalid attention decision payload; repair and strict retry did not recover it" : "router produced an empty attention decision payload; strict retry did not recover it") + (failureNarrative.summary ? ` — ${failureNarrative.summary}` : ""),
|
|
615734
|
+
memoryNote: this.composeTelegramRouterMemoryNote(invalidRouterPreview, failureNarrative.detail),
|
|
615735
|
+
relationshipNote: failureNarrative.relationshipHint,
|
|
615610
615736
|
raw: text
|
|
615611
615737
|
};
|
|
615612
|
-
this.applyTelegramStimulationDecision(sessionKey,
|
|
615613
|
-
return
|
|
615614
|
-
} catch {
|
|
615738
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback);
|
|
615739
|
+
return fallback;
|
|
615740
|
+
} catch (err) {
|
|
615741
|
+
const failureNarrative = this.summarizeTelegramRouterFailure(diagnostics);
|
|
615742
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
615743
|
+
const fallback = {
|
|
615744
|
+
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
615745
|
+
shouldReply: false,
|
|
615746
|
+
confidence: 0,
|
|
615747
|
+
reason: `router inference failed; no model-derived reply decision (${errMsg.slice(0, 160)})`,
|
|
615748
|
+
source: "inference-unavailable",
|
|
615749
|
+
silentDisposition: "retained as context without replying",
|
|
615750
|
+
mentalNote: `router failed, so no model-derived attention note was produced` + (failureNarrative.summary ? ` — ${failureNarrative.summary}` : ` — ${errMsg.slice(0, 160)}`),
|
|
615751
|
+
memoryNote: failureNarrative.detail ? `router-failure trace: ${failureNarrative.detail}` : `router-failure trace: ${errMsg.slice(0, 240)}`,
|
|
615752
|
+
relationshipNote: failureNarrative.relationshipHint
|
|
615753
|
+
};
|
|
615754
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback);
|
|
615755
|
+
return fallback;
|
|
615615
615756
|
}
|
|
615616
|
-
|
|
615617
|
-
|
|
615618
|
-
|
|
615619
|
-
|
|
615620
|
-
|
|
615621
|
-
|
|
615622
|
-
|
|
615623
|
-
|
|
615624
|
-
|
|
615625
|
-
|
|
615626
|
-
|
|
615757
|
+
}
|
|
615758
|
+
/**
|
|
615759
|
+
* Reduce captured per-step diagnostics into:
|
|
615760
|
+
* - `summary`: a short outcome-level line for the mental note
|
|
615761
|
+
* - `detail`: a longer ordered trace for the memory note
|
|
615762
|
+
* - `relationshipHint`: an operational hint (e.g. "ollama backend appears to be injecting <think> tags despite think:false")
|
|
615763
|
+
*/
|
|
615764
|
+
summarizeTelegramRouterFailure(diag) {
|
|
615765
|
+
const parts = [];
|
|
615766
|
+
const detailParts = [];
|
|
615767
|
+
let thinkInjectionSuspected = false;
|
|
615768
|
+
let networkErrorSeen = false;
|
|
615769
|
+
if (diag.jsonModeStatus === "threw") {
|
|
615770
|
+
parts.push(`json-mode call threw`);
|
|
615771
|
+
detailParts.push(`json-mode: threw (${diag.jsonModeError ?? "no detail"})`);
|
|
615772
|
+
networkErrorSeen = true;
|
|
615773
|
+
} else if (diag.jsonModeStatus === "empty-after-strip") {
|
|
615774
|
+
parts.push(`json-mode returned empty content (likely <think>-only)`);
|
|
615775
|
+
detailParts.push(`json-mode: empty-after-strip`);
|
|
615776
|
+
thinkInjectionSuspected = true;
|
|
615777
|
+
} else if (diag.jsonModeStatus === "visible") {
|
|
615778
|
+
detailParts.push(`json-mode: visible`);
|
|
615779
|
+
}
|
|
615780
|
+
if (diag.plainStatus === "threw") {
|
|
615781
|
+
parts.push(`plain call threw`);
|
|
615782
|
+
detailParts.push(`plain: threw (${diag.plainError ?? "no detail"})`);
|
|
615783
|
+
networkErrorSeen = true;
|
|
615784
|
+
} else if (diag.plainStatus === "empty-after-strip") {
|
|
615785
|
+
parts.push(`plain call returned empty content`);
|
|
615786
|
+
detailParts.push(`plain: empty-after-strip`);
|
|
615787
|
+
thinkInjectionSuspected = true;
|
|
615788
|
+
} else if (diag.plainStatus === "visible") {
|
|
615789
|
+
detailParts.push(`plain: visible-but-unparseable`);
|
|
615790
|
+
}
|
|
615791
|
+
if (diag.repairStatus === "skipped") {
|
|
615792
|
+
detailParts.push(`repair: skipped (${diag.repairError ?? "no recoverable input"})`);
|
|
615793
|
+
} else if (diag.repairStatus === "no-recoverable-output") {
|
|
615794
|
+
detailParts.push(`repair: returned non-recoverable JSON`);
|
|
615795
|
+
} else if (diag.repairStatus === "threw") {
|
|
615796
|
+
detailParts.push(`repair: threw (${diag.repairError ?? "no detail"})`);
|
|
615797
|
+
networkErrorSeen = true;
|
|
615798
|
+
} else if (diag.repairStatus === "recovered") {
|
|
615799
|
+
detailParts.push(`repair: recovered`);
|
|
615800
|
+
}
|
|
615801
|
+
if (diag.strictRetryStatus === "empty") {
|
|
615802
|
+
detailParts.push(`strict-retry: empty`);
|
|
615803
|
+
thinkInjectionSuspected = true;
|
|
615804
|
+
} else if (diag.strictRetryStatus === "unparseable") {
|
|
615805
|
+
detailParts.push(`strict-retry: unparseable (preview="${diag.strictRetryPreview ?? ""}")`);
|
|
615806
|
+
} else if (diag.strictRetryStatus === "threw") {
|
|
615807
|
+
detailParts.push(`strict-retry: threw (${diag.strictRetryError ?? "no detail"})`);
|
|
615808
|
+
networkErrorSeen = true;
|
|
615809
|
+
} else if (diag.strictRetryStatus === "recovered") {
|
|
615810
|
+
detailParts.push(`strict-retry: recovered`);
|
|
615811
|
+
}
|
|
615812
|
+
let relationshipHint;
|
|
615813
|
+
if (networkErrorSeen) {
|
|
615814
|
+
relationshipHint = "router backend appears unreachable or rate-limited; continued conversation depends on recovery";
|
|
615815
|
+
} else if (thinkInjectionSuspected) {
|
|
615816
|
+
relationshipHint = "router model emitted <think>-only or unclosed-think output; conversation continuity preserved but inference is degraded";
|
|
615817
|
+
}
|
|
615818
|
+
return {
|
|
615819
|
+
summary: parts.join("; "),
|
|
615820
|
+
detail: detailParts.join("; "),
|
|
615821
|
+
relationshipHint
|
|
615822
|
+
};
|
|
615823
|
+
}
|
|
615824
|
+
composeTelegramRouterMemoryNote(invalidRouterPreview, detail) {
|
|
615825
|
+
const segments = [];
|
|
615826
|
+
if (invalidRouterPreview) segments.push(`invalid router output preview: ${invalidRouterPreview}`);
|
|
615827
|
+
if (detail) segments.push(`router-failure trace: ${detail}`);
|
|
615828
|
+
if (segments.length === 0) return void 0;
|
|
615829
|
+
return segments.join(" | ");
|
|
615627
615830
|
}
|
|
615628
615831
|
buildTelegramWorkspaceContext(modelTier, budget = 14e3) {
|
|
615629
615832
|
if (!this.repoRoot) return "";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.80",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.80",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED