omnius 1.0.78 → 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 +295 -71
- 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,19 +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
|
-
|
|
615366
|
-
|
|
615423
|
+
const visible = jsonModeResult.choices.some(
|
|
615424
|
+
(choice) => stripTelegramHiddenThinking(choice.message.content ?? "").trim().length > 0
|
|
615425
|
+
);
|
|
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;
|
|
615367
615454
|
}
|
|
615368
615455
|
}
|
|
615369
|
-
async repairTelegramInteractionDecision(backend, rawOutput, forcedRoute, timeoutMs) {
|
|
615456
|
+
async repairTelegramInteractionDecision(backend, rawOutput, forcedRoute, timeoutMs, diagnostics) {
|
|
615370
615457
|
const rawPreview = telegramRouterRawPreview(rawOutput, 4e3);
|
|
615371
|
-
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
|
+
}
|
|
615372
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.`;
|
|
615373
615466
|
const prompt = [
|
|
615374
615467
|
`Repair this Telegram attention-router output into strict JSON.`,
|
|
@@ -615380,7 +615473,9 @@ ${lines.join("\n")}`);
|
|
|
615380
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"}`,
|
|
615381
615474
|
``,
|
|
615382
615475
|
`Original router output:`,
|
|
615383
|
-
rawPreview
|
|
615476
|
+
rawPreview,
|
|
615477
|
+
``,
|
|
615478
|
+
`/no_think`
|
|
615384
615479
|
].join("\n");
|
|
615385
615480
|
try {
|
|
615386
615481
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
@@ -615398,11 +615493,18 @@ ${lines.join("\n")}`);
|
|
|
615398
615493
|
think: false
|
|
615399
615494
|
});
|
|
615400
615495
|
const repairedText = result.choices[0]?.message?.content ?? "";
|
|
615401
|
-
if (telegramDecisionRecoverableFlag(repairedText) === false)
|
|
615496
|
+
if (telegramDecisionRecoverableFlag(repairedText) === false) {
|
|
615497
|
+
if (diagnostics) diagnostics.repairStatus = "no-recoverable-output";
|
|
615498
|
+
return null;
|
|
615499
|
+
}
|
|
615402
615500
|
const parsed = parseTelegramInteractionDecision(repairedText, forcedRoute, {
|
|
615403
615501
|
defaultShouldReply: false
|
|
615404
615502
|
});
|
|
615405
|
-
if (!parsed)
|
|
615503
|
+
if (!parsed) {
|
|
615504
|
+
if (diagnostics) diagnostics.repairStatus = "no-recoverable-output";
|
|
615505
|
+
return null;
|
|
615506
|
+
}
|
|
615507
|
+
if (diagnostics) diagnostics.repairStatus = "recovered";
|
|
615406
615508
|
return {
|
|
615407
615509
|
...parsed,
|
|
615408
615510
|
reason: `recovered router decision: ${parsed.reason}`.slice(0, 240),
|
|
@@ -615413,17 +615515,23 @@ ${repairedText}`,
|
|
|
615413
615515
|
mentalNote: parsed.mentalNote ?? "router decision recovered from non-JSON model output",
|
|
615414
615516
|
memoryNote: parsed.memoryNote ?? "router repair preserved the model-derived attention decision"
|
|
615415
615517
|
};
|
|
615416
|
-
} catch {
|
|
615518
|
+
} catch (err) {
|
|
615519
|
+
if (diagnostics) {
|
|
615520
|
+
diagnostics.repairStatus = "threw";
|
|
615521
|
+
diagnostics.repairError = err instanceof Error ? err.message : String(err);
|
|
615522
|
+
}
|
|
615417
615523
|
return null;
|
|
615418
615524
|
}
|
|
615419
615525
|
}
|
|
615420
|
-
async retryTelegramInteractionDecisionStrict(backend, userPrompt, rawOutput, forcedRoute, timeoutMs) {
|
|
615526
|
+
async retryTelegramInteractionDecisionStrict(backend, userPrompt, rawOutput, forcedRoute, timeoutMs, diagnostics) {
|
|
615421
615527
|
const invalidPreview = telegramRouterRawPreview(rawOutput, 1200) ?? "(empty assistant content)";
|
|
615422
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;
|
|
615423
615531
|
const retryPrompt = [
|
|
615424
615532
|
`The previous Telegram attention-router response was not usable JSON.`,
|
|
615425
|
-
`Make a fresh model-derived attention decision from the
|
|
615426
|
-
`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.`,
|
|
615427
615535
|
routeInstruction,
|
|
615428
615536
|
``,
|
|
615429
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"}`,
|
|
@@ -615431,15 +615539,17 @@ ${repairedText}`,
|
|
|
615431
615539
|
`Invalid previous output, for diagnostics only:`,
|
|
615432
615540
|
invalidPreview,
|
|
615433
615541
|
``,
|
|
615434
|
-
`
|
|
615435
|
-
|
|
615542
|
+
`Router context (trailing-window):`,
|
|
615543
|
+
trimmedUserPrompt,
|
|
615544
|
+
``,
|
|
615545
|
+
`/no_think`
|
|
615436
615546
|
].join("\n");
|
|
615437
615547
|
try {
|
|
615438
615548
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
615439
615549
|
messages: [
|
|
615440
615550
|
{
|
|
615441
615551
|
role: "system",
|
|
615442
|
-
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."
|
|
615443
615553
|
},
|
|
615444
615554
|
{ role: "user", content: retryPrompt }
|
|
615445
615555
|
],
|
|
@@ -615450,10 +615560,18 @@ ${repairedText}`,
|
|
|
615450
615560
|
think: false
|
|
615451
615561
|
});
|
|
615452
615562
|
const retryText = result.choices[0]?.message?.content ?? "";
|
|
615563
|
+
if (diagnostics) diagnostics.strictRetryPreview = telegramRouterRawPreview(retryText, 320);
|
|
615453
615564
|
const parsed = parseTelegramInteractionDecision(retryText, forcedRoute, {
|
|
615454
615565
|
defaultShouldReply: false
|
|
615455
615566
|
});
|
|
615456
|
-
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";
|
|
615457
615575
|
return {
|
|
615458
615576
|
...parsed,
|
|
615459
615577
|
reason: `strict router retry: ${parsed.reason}`.slice(0, 240),
|
|
@@ -615463,7 +615581,11 @@ ${repairedText}`,
|
|
|
615463
615581
|
${retryText}`,
|
|
615464
615582
|
mentalNote: parsed.mentalNote ?? "strict router retry produced a valid attention decision"
|
|
615465
615583
|
};
|
|
615466
|
-
} catch {
|
|
615584
|
+
} catch (err) {
|
|
615585
|
+
if (diagnostics) {
|
|
615586
|
+
diagnostics.strictRetryStatus = "threw";
|
|
615587
|
+
diagnostics.strictRetryError = err instanceof Error ? err.message : String(err);
|
|
615588
|
+
}
|
|
615467
615589
|
return null;
|
|
615468
615590
|
}
|
|
615469
615591
|
}
|
|
@@ -615484,7 +615606,7 @@ ${retryText}`,
|
|
|
615484
615606
|
forceAnalyze: daydreamForceCheck
|
|
615485
615607
|
});
|
|
615486
615608
|
if (!config) {
|
|
615487
|
-
const
|
|
615609
|
+
const fallback = {
|
|
615488
615610
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
615489
615611
|
shouldReply: false,
|
|
615490
615612
|
confidence: 0,
|
|
@@ -615493,8 +615615,8 @@ ${retryText}`,
|
|
|
615493
615615
|
silentDisposition: "retained as context without replying",
|
|
615494
615616
|
mentalNote: "router unavailable, so no model-derived attention note was produced"
|
|
615495
615617
|
};
|
|
615496
|
-
this.applyTelegramStimulationDecision(sessionKey,
|
|
615497
|
-
return
|
|
615618
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback);
|
|
615619
|
+
return fallback;
|
|
615498
615620
|
}
|
|
615499
615621
|
const backend = new OllamaAgenticBackend(
|
|
615500
615622
|
config.backendUrl,
|
|
@@ -615549,6 +615671,7 @@ ${stimulationProbe.context}`,
|
|
|
615549
615671
|
`Current Telegram message text (untrusted user data):
|
|
615550
615672
|
${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
615551
615673
|
].filter(Boolean).join("\n");
|
|
615674
|
+
const diagnostics = {};
|
|
615552
615675
|
try {
|
|
615553
615676
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
615554
615677
|
messages: [
|
|
@@ -615563,7 +615686,7 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615563
615686
|
maxTokens: 700,
|
|
615564
615687
|
timeoutMs: Math.min(Math.max(config.timeoutMs ?? 3e4, 5e3), 15e3),
|
|
615565
615688
|
think: false
|
|
615566
|
-
});
|
|
615689
|
+
}, diagnostics);
|
|
615567
615690
|
const text = result.choices[0]?.message?.content ?? "";
|
|
615568
615691
|
const parsed = parseTelegramInteractionDecision(text, forcedRoute, {
|
|
615569
615692
|
defaultShouldReply: false
|
|
@@ -615576,7 +615699,8 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615576
615699
|
backend,
|
|
615577
615700
|
text,
|
|
615578
615701
|
forcedRoute,
|
|
615579
|
-
config.timeoutMs ?? 3e4
|
|
615702
|
+
config.timeoutMs ?? 3e4,
|
|
615703
|
+
diagnostics
|
|
615580
615704
|
);
|
|
615581
615705
|
if (repaired) {
|
|
615582
615706
|
this.applyTelegramStimulationDecision(sessionKey, repaired);
|
|
@@ -615587,39 +615711,122 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
615587
615711
|
userPrompt,
|
|
615588
615712
|
text,
|
|
615589
615713
|
forcedRoute,
|
|
615590
|
-
config.timeoutMs ?? 3e4
|
|
615714
|
+
config.timeoutMs ?? 3e4,
|
|
615715
|
+
diagnostics
|
|
615591
615716
|
);
|
|
615592
615717
|
if (strictRetry) {
|
|
615593
615718
|
this.applyTelegramStimulationDecision(sessionKey, strictRetry);
|
|
615594
615719
|
return strictRetry;
|
|
615595
615720
|
}
|
|
615596
615721
|
const invalidRouterPreview = telegramRouterRawPreview(text);
|
|
615597
|
-
const
|
|
615722
|
+
const failureNarrative = this.summarizeTelegramRouterFailure(diagnostics);
|
|
615723
|
+
const fallback = {
|
|
615598
615724
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
615599
615725
|
shouldReply: false,
|
|
615600
615726
|
confidence: 0,
|
|
615601
615727
|
reason: "router output was not valid decision JSON after repair/retry; no model-derived reply decision",
|
|
615602
615728
|
source: "inference-unavailable",
|
|
615603
615729
|
silentDisposition: "retained as context without replying because the router decision could not be parsed",
|
|
615604
|
-
|
|
615605
|
-
|
|
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,
|
|
615606
615736
|
raw: text
|
|
615607
615737
|
};
|
|
615608
|
-
this.applyTelegramStimulationDecision(sessionKey,
|
|
615609
|
-
return
|
|
615610
|
-
} 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;
|
|
615756
|
+
}
|
|
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";
|
|
615611
615817
|
}
|
|
615612
|
-
|
|
615613
|
-
|
|
615614
|
-
|
|
615615
|
-
|
|
615616
|
-
reason: "router inference failed; no model-derived reply decision",
|
|
615617
|
-
source: "inference-unavailable",
|
|
615618
|
-
silentDisposition: "retained as context without replying",
|
|
615619
|
-
mentalNote: "router failed, so no model-derived attention note was produced"
|
|
615818
|
+
return {
|
|
615819
|
+
summary: parts.join("; "),
|
|
615820
|
+
detail: detailParts.join("; "),
|
|
615821
|
+
relationshipHint
|
|
615620
615822
|
};
|
|
615621
|
-
|
|
615622
|
-
|
|
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(" | ");
|
|
615623
615830
|
}
|
|
615624
615831
|
buildTelegramWorkspaceContext(modelTier, budget = 14e3) {
|
|
615625
615832
|
if (!this.repoRoot) return "";
|
|
@@ -637795,6 +638002,7 @@ async function directChatBackend(opts) {
|
|
|
637795
638002
|
if (typeof ef["presence_penalty"] === "number") ollamaOpts["presence_penalty"] = ef["presence_penalty"];
|
|
637796
638003
|
if (Array.isArray(ef["stop"]) || typeof ef["stop"] === "string") ollamaOpts["stop"] = ef["stop"];
|
|
637797
638004
|
const hasTools = Array.isArray(ef["tools"]) && ef["tools"].length > 0;
|
|
638005
|
+
const ollamaFormat = ollamaFormatFromOpenAIResponseFormat(ef["response_format"]);
|
|
637798
638006
|
const reqBody = JSON.stringify({
|
|
637799
638007
|
model: cleanModel,
|
|
637800
638008
|
messages: messages2,
|
|
@@ -637804,7 +638012,7 @@ async function directChatBackend(opts) {
|
|
|
637804
638012
|
...hasTools ? {} : { think: false },
|
|
637805
638013
|
...hasTools ? { tools: ef["tools"] } : {},
|
|
637806
638014
|
...ef["tool_choice"] !== void 0 ? { tool_choice: ef["tool_choice"] } : {},
|
|
637807
|
-
...
|
|
638015
|
+
...ollamaFormat !== void 0 ? { format: ollamaFormat } : {},
|
|
637808
638016
|
options: ollamaOpts
|
|
637809
638017
|
});
|
|
637810
638018
|
if (stream) {
|
|
@@ -637907,6 +638115,22 @@ async function directChatBackend(opts) {
|
|
|
637907
638115
|
}
|
|
637908
638116
|
}
|
|
637909
638117
|
}
|
|
638118
|
+
function ollamaFormatFromOpenAIResponseFormat(value2) {
|
|
638119
|
+
if (typeof value2 === "string") return value2;
|
|
638120
|
+
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return void 0;
|
|
638121
|
+
const record = value2;
|
|
638122
|
+
if (record["type"] === "json_object") return "json";
|
|
638123
|
+
if (record["type"] === "json_schema") {
|
|
638124
|
+
const jsonSchema = record["json_schema"];
|
|
638125
|
+
if (jsonSchema && typeof jsonSchema === "object" && !Array.isArray(jsonSchema)) {
|
|
638126
|
+
const schemaRecord = jsonSchema;
|
|
638127
|
+
return schemaRecord["schema"] ?? jsonSchema;
|
|
638128
|
+
}
|
|
638129
|
+
return "json";
|
|
638130
|
+
}
|
|
638131
|
+
if (record["type"] === "object" || record["properties"] !== void 0) return record;
|
|
638132
|
+
return void 0;
|
|
638133
|
+
}
|
|
637910
638134
|
function backendAuthHeaders(endpoint) {
|
|
637911
638135
|
const key = endpoint?.authKey ?? loadConfig().apiKey;
|
|
637912
638136
|
if (key) return { Authorization: `Bearer ${key}` };
|
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