omnius 1.0.182 → 1.0.183
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 +343 -59
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -550132,11 +550132,17 @@ function injectNoThinkDirective(messages2) {
|
|
|
550132
550132
|
const target = messages2[lastUserIdx];
|
|
550133
550133
|
if (!target || typeof target.content !== "string")
|
|
550134
550134
|
return messages2;
|
|
550135
|
-
|
|
550135
|
+
const hasOllamaNoThink = /\/nothink\b/i.test(target.content);
|
|
550136
|
+
const hasQwenNoThink = /\/no[_-]think\b/i.test(target.content);
|
|
550137
|
+
if (hasOllamaNoThink && hasQwenNoThink)
|
|
550136
550138
|
return messages2;
|
|
550139
|
+
const suffix = [
|
|
550140
|
+
hasOllamaNoThink ? null : "/nothink",
|
|
550141
|
+
hasQwenNoThink ? null : "/no_think"
|
|
550142
|
+
].filter(Boolean).join("\n");
|
|
550137
550143
|
const annotated = `${target.content}
|
|
550138
550144
|
|
|
550139
|
-
|
|
550145
|
+
${suffix}`;
|
|
550140
550146
|
return messages2.map((m2, i2) => i2 === lastUserIdx ? { ...m2, content: annotated } : m2);
|
|
550141
550147
|
}
|
|
550142
550148
|
function backendHttpErrorDetail(text) {
|
|
@@ -550154,6 +550160,8 @@ function isOllamaModelNotFoundResponse(status, text, model) {
|
|
|
550154
550160
|
function computeEffectiveThink(params) {
|
|
550155
550161
|
if (process.env["OMNIUS_FORCE_NO_THINK"] === "1")
|
|
550156
550162
|
return false;
|
|
550163
|
+
if (process.env["OMNIUS_ENABLE_THINKING"] !== "1")
|
|
550164
|
+
return false;
|
|
550157
550165
|
if (params.suppressed)
|
|
550158
550166
|
return false;
|
|
550159
550167
|
if (params.hasTools)
|
|
@@ -550172,18 +550180,9 @@ function computeEffectiveThink(params) {
|
|
|
550172
550180
|
return params.defaultThink;
|
|
550173
550181
|
}
|
|
550174
550182
|
function sanitizeHistoryThink(messages2) {
|
|
550175
|
-
|
|
550176
|
-
for (let i2 = messages2.length - 1; i2 >= 0; i2--) {
|
|
550177
|
-
if (messages2[i2]?.role === "assistant") {
|
|
550178
|
-
lastAsstIdx = i2;
|
|
550179
|
-
break;
|
|
550180
|
-
}
|
|
550181
|
-
}
|
|
550182
|
-
return messages2.map((m2, i2) => {
|
|
550183
|
+
return messages2.map((m2) => {
|
|
550183
550184
|
if (m2.role !== "assistant" || typeof m2.content !== "string")
|
|
550184
550185
|
return m2;
|
|
550185
|
-
if (i2 === lastAsstIdx)
|
|
550186
|
-
return m2;
|
|
550187
550186
|
return { ...m2, content: stripThinkBlocks(m2.content) };
|
|
550188
550187
|
});
|
|
550189
550188
|
}
|
|
@@ -563608,10 +563607,11 @@ ${description}`
|
|
|
563608
563607
|
if (effectiveThink === true && (effectiveMaxTokens ?? 0) < 4096) {
|
|
563609
563608
|
effectiveMaxTokens = 4096;
|
|
563610
563609
|
}
|
|
563610
|
+
const requestMessages = effectiveThink ? cleanedMessages : injectNoThinkDirective(cleanedMessages);
|
|
563611
563611
|
const responseFormat = request.responseFormat ?? request.response_format;
|
|
563612
563612
|
const body = {
|
|
563613
563613
|
model: this.model,
|
|
563614
|
-
messages:
|
|
563614
|
+
messages: requestMessages,
|
|
563615
563615
|
tools: request.tools,
|
|
563616
563616
|
temperature: request.temperature,
|
|
563617
563617
|
max_tokens: effectiveMaxTokens,
|
|
@@ -563620,7 +563620,7 @@ ${description}`
|
|
|
563620
563620
|
if (responseFormat !== void 0) {
|
|
563621
563621
|
body["response_format"] = responseFormat;
|
|
563622
563622
|
}
|
|
563623
|
-
const reqNumCtx = request.numCtx;
|
|
563623
|
+
const reqNumCtx = request.numCtx ?? request.num_ctx;
|
|
563624
563624
|
if (Number.isFinite(reqNumCtx) && (reqNumCtx ?? 0) > 0) {
|
|
563625
563625
|
const opts = body["options"] ?? {};
|
|
563626
563626
|
opts["num_ctx"] = reqNumCtx;
|
|
@@ -563705,7 +563705,7 @@ ${description}`
|
|
|
563705
563705
|
const justSuppressed = this._thinkSuppressed && this._thinkFailStreak === _OllamaAgenticBackend._thinkFailThreshold;
|
|
563706
563706
|
const shouldRetryThinkGuard = outcome !== null && effectiveThink === true && (justSuppressed || outcome === "empty_after_strip" || outcome === "unclosed_think");
|
|
563707
563707
|
if (shouldRetryThinkGuard || shouldRecoverFromEmpty) {
|
|
563708
|
-
const retryMessages = injectNoThinkDirective(
|
|
563708
|
+
const retryMessages = injectNoThinkDirective(requestMessages);
|
|
563709
563709
|
const retryBody = {
|
|
563710
563710
|
model: this.model,
|
|
563711
563711
|
messages: retryMessages,
|
|
@@ -563892,7 +563892,7 @@ ${description}`
|
|
|
563892
563892
|
* Ollama pool routing as non-stream completions.
|
|
563893
563893
|
*/
|
|
563894
563894
|
async *chatCompletionStream(request) {
|
|
563895
|
-
const cleanedMessages = normalizeMessagesForStrictOpenAI(request.messages
|
|
563895
|
+
const cleanedMessages = normalizeMessagesForStrictOpenAI(sanitizeHistoryThink(request.messages));
|
|
563896
563896
|
let effectiveThink = computeEffectiveThink({
|
|
563897
563897
|
requestThink: request.think,
|
|
563898
563898
|
defaultThink: this.thinking,
|
|
@@ -563907,10 +563907,11 @@ ${description}`
|
|
|
563907
563907
|
if (effectiveThink === true && (effectiveMaxTokens ?? 0) < 4096) {
|
|
563908
563908
|
effectiveMaxTokens = 4096;
|
|
563909
563909
|
}
|
|
563910
|
+
const requestMessages = effectiveThink ? cleanedMessages : injectNoThinkDirective(cleanedMessages);
|
|
563910
563911
|
const responseFormat = request.responseFormat ?? request.response_format;
|
|
563911
563912
|
const body = {
|
|
563912
563913
|
model: this.model,
|
|
563913
|
-
messages:
|
|
563914
|
+
messages: requestMessages,
|
|
563914
563915
|
tools: request.tools,
|
|
563915
563916
|
temperature: request.temperature,
|
|
563916
563917
|
max_tokens: effectiveMaxTokens,
|
|
@@ -563921,7 +563922,7 @@ ${description}`
|
|
|
563921
563922
|
if (responseFormat !== void 0) {
|
|
563922
563923
|
body["response_format"] = responseFormat;
|
|
563923
563924
|
}
|
|
563924
|
-
const reqNumCtx = request.numCtx;
|
|
563925
|
+
const reqNumCtx = request.numCtx ?? request.num_ctx;
|
|
563925
563926
|
if (Number.isFinite(reqNumCtx) && (reqNumCtx ?? 0) > 0) {
|
|
563926
563927
|
const opts = body["options"] ?? {};
|
|
563927
563928
|
opts["num_ctx"] = reqNumCtx;
|
|
@@ -564176,6 +564177,57 @@ var init_nexusBackend = __esm({
|
|
|
564176
564177
|
this.authKey = authKey || "";
|
|
564177
564178
|
this.thinking = thinking ?? false;
|
|
564178
564179
|
}
|
|
564180
|
+
effectiveThink(request) {
|
|
564181
|
+
if (process.env["OMNIUS_FORCE_NO_THINK"] === "1")
|
|
564182
|
+
return false;
|
|
564183
|
+
if (process.env["OMNIUS_ENABLE_THINKING"] !== "1")
|
|
564184
|
+
return false;
|
|
564185
|
+
if (Array.isArray(request.tools) && request.tools.length > 0)
|
|
564186
|
+
return false;
|
|
564187
|
+
if (request.think === true)
|
|
564188
|
+
return true;
|
|
564189
|
+
if (request.think === false)
|
|
564190
|
+
return false;
|
|
564191
|
+
return this.thinking === true;
|
|
564192
|
+
}
|
|
564193
|
+
noThinkMessages(messages2) {
|
|
564194
|
+
let lastUserIdx = -1;
|
|
564195
|
+
for (let i2 = messages2.length - 1; i2 >= 0; i2--) {
|
|
564196
|
+
if (messages2[i2]?.role === "user") {
|
|
564197
|
+
lastUserIdx = i2;
|
|
564198
|
+
break;
|
|
564199
|
+
}
|
|
564200
|
+
}
|
|
564201
|
+
if (lastUserIdx < 0)
|
|
564202
|
+
return messages2;
|
|
564203
|
+
const target = messages2[lastUserIdx];
|
|
564204
|
+
if (!target || typeof target.content !== "string")
|
|
564205
|
+
return messages2;
|
|
564206
|
+
const hasOllamaNoThink = /\/nothink\b/i.test(target.content);
|
|
564207
|
+
const hasQwenNoThink = /\/no[_-]think\b/i.test(target.content);
|
|
564208
|
+
if (hasOllamaNoThink && hasQwenNoThink)
|
|
564209
|
+
return messages2;
|
|
564210
|
+
const suffix = [
|
|
564211
|
+
hasOllamaNoThink ? null : "/nothink",
|
|
564212
|
+
hasQwenNoThink ? null : "/no_think"
|
|
564213
|
+
].filter(Boolean).join("\n");
|
|
564214
|
+
return messages2.map((m2, i2) => i2 === lastUserIdx ? { ...m2, content: `${target.content}
|
|
564215
|
+
|
|
564216
|
+
${suffix}` } : m2);
|
|
564217
|
+
}
|
|
564218
|
+
requestMessages(request, effectiveThink) {
|
|
564219
|
+
return effectiveThink ? request.messages : this.noThinkMessages(request.messages);
|
|
564220
|
+
}
|
|
564221
|
+
applyOptionalRequestFields(daemonArgs, request) {
|
|
564222
|
+
const responseFormat = request.responseFormat ?? request.response_format;
|
|
564223
|
+
if (responseFormat !== void 0) {
|
|
564224
|
+
daemonArgs.response_format = JSON.stringify(responseFormat);
|
|
564225
|
+
}
|
|
564226
|
+
const numCtx = request.numCtx ?? request.num_ctx;
|
|
564227
|
+
if (Number.isFinite(numCtx) && (numCtx ?? 0) > 0) {
|
|
564228
|
+
daemonArgs.num_ctx = String(numCtx);
|
|
564229
|
+
}
|
|
564230
|
+
}
|
|
564179
564231
|
/** Reset the consecutive failure counter (called on endpoint switch / reconnect) */
|
|
564180
564232
|
resetFailures() {
|
|
564181
564233
|
this.consecutiveFailures = 0;
|
|
@@ -564191,9 +564243,10 @@ var init_nexusBackend = __esm({
|
|
|
564191
564243
|
err.fatal = true;
|
|
564192
564244
|
throw err;
|
|
564193
564245
|
}
|
|
564246
|
+
const effectiveThink = this.effectiveThink(request);
|
|
564194
564247
|
const daemonArgs = {
|
|
564195
564248
|
model: this.model,
|
|
564196
|
-
messages: JSON.stringify(request
|
|
564249
|
+
messages: JSON.stringify(this.requestMessages(request, effectiveThink)),
|
|
564197
564250
|
tools: JSON.stringify(request.tools),
|
|
564198
564251
|
temperature: String(request.temperature),
|
|
564199
564252
|
max_tokens: String(request.maxTokens)
|
|
@@ -564204,7 +564257,8 @@ var init_nexusBackend = __esm({
|
|
|
564204
564257
|
if (this.authKey) {
|
|
564205
564258
|
daemonArgs.auth_key = this.authKey;
|
|
564206
564259
|
}
|
|
564207
|
-
daemonArgs.think = String(
|
|
564260
|
+
daemonArgs.think = String(effectiveThink);
|
|
564261
|
+
this.applyOptionalRequestFields(daemonArgs, request);
|
|
564208
564262
|
let rawResult;
|
|
564209
564263
|
try {
|
|
564210
564264
|
rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
|
|
@@ -564303,9 +564357,10 @@ var init_nexusBackend = __esm({
|
|
|
564303
564357
|
async *chatCompletionStream(request) {
|
|
564304
564358
|
const streamFile = join97(tmpdir18(), `nexus-stream-${randomBytes19(6).toString("hex")}.jsonl`);
|
|
564305
564359
|
writeFileSync38(streamFile, "", "utf8");
|
|
564360
|
+
const effectiveThink = this.effectiveThink(request);
|
|
564306
564361
|
const daemonArgs = {
|
|
564307
564362
|
model: this.model,
|
|
564308
|
-
messages: JSON.stringify(request
|
|
564363
|
+
messages: JSON.stringify(this.requestMessages(request, effectiveThink)),
|
|
564309
564364
|
tools: JSON.stringify(request.tools),
|
|
564310
564365
|
temperature: String(request.temperature),
|
|
564311
564366
|
max_tokens: String(request.maxTokens),
|
|
@@ -564315,7 +564370,8 @@ var init_nexusBackend = __esm({
|
|
|
564315
564370
|
daemonArgs.target_peer = this.targetPeer;
|
|
564316
564371
|
if (this.authKey)
|
|
564317
564372
|
daemonArgs.auth_key = this.authKey;
|
|
564318
|
-
daemonArgs.think = String(
|
|
564373
|
+
daemonArgs.think = String(effectiveThink);
|
|
564374
|
+
this.applyOptionalRequestFields(daemonArgs, request);
|
|
564319
564375
|
let rawResult;
|
|
564320
564376
|
try {
|
|
564321
564377
|
rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
|
|
@@ -629145,7 +629201,7 @@ function telegramRouterTimeoutMs(configTimeoutMs, minMs = 1e4, maxMs) {
|
|
|
629145
629201
|
10
|
|
629146
629202
|
);
|
|
629147
629203
|
const floor = Number.isFinite(minMs) && minMs > 0 ? minMs : 1e4;
|
|
629148
|
-
const configuredCap = Number.isFinite(envRaw) && envRaw >= floor ? envRaw :
|
|
629204
|
+
const configuredCap = Number.isFinite(envRaw) && envRaw >= floor ? envRaw : 3e4;
|
|
629149
629205
|
const callerCap = Number.isFinite(maxMs) && (maxMs ?? 0) >= floor ? maxMs : configuredCap;
|
|
629150
629206
|
const cap = Math.max(floor, Math.min(configuredCap, callerCap));
|
|
629151
629207
|
const requested = Number.isFinite(configTimeoutMs) && (configTimeoutMs ?? 0) > 0 ? configTimeoutMs : cap;
|
|
@@ -629172,6 +629228,9 @@ function telegramRouterDiagnosticAttemptLooksLikeTimeout(attempt) {
|
|
|
629172
629228
|
function telegramRouterDiagnosticAttemptLooksLikeBackendLiveness(attempt) {
|
|
629173
629229
|
return attempt.status === "threw" && telegramRouterErrorLooksLikeBackendLiveness(attempt.error ?? "");
|
|
629174
629230
|
}
|
|
629231
|
+
function telegramRouterDiagnosticIsDualEmptyVisible(diag) {
|
|
629232
|
+
return diag.jsonModeStatus === "empty-after-strip" && diag.plainStatus === "empty-after-strip";
|
|
629233
|
+
}
|
|
629175
629234
|
function telegramThinkSuppressedRequest(request) {
|
|
629176
629235
|
const messages2 = Array.isArray(request.messages) ? request.messages.slice() : [];
|
|
629177
629236
|
let appended = false;
|
|
@@ -629179,18 +629238,24 @@ function telegramThinkSuppressedRequest(request) {
|
|
|
629179
629238
|
const m2 = messages2[i2];
|
|
629180
629239
|
if (!m2 || m2.role !== "user") continue;
|
|
629181
629240
|
const content = typeof m2.content === "string" ? m2.content : "";
|
|
629182
|
-
|
|
629241
|
+
const hasOllamaNoThink = /\/nothink\b/i.test(content);
|
|
629242
|
+
const hasQwenNoThink = /\/no[_-]think\b/i.test(content);
|
|
629243
|
+
if (hasOllamaNoThink && hasQwenNoThink) {
|
|
629183
629244
|
appended = true;
|
|
629184
629245
|
break;
|
|
629185
629246
|
}
|
|
629186
|
-
|
|
629247
|
+
const suffix = [
|
|
629248
|
+
hasOllamaNoThink ? null : "/nothink",
|
|
629249
|
+
hasQwenNoThink ? null : "/no_think"
|
|
629250
|
+
].filter(Boolean).join("\n");
|
|
629251
|
+
messages2[i2] = { ...m2, content: content.endsWith("\n") ? `${content}${suffix}` : `${content}
|
|
629187
629252
|
|
|
629188
|
-
|
|
629253
|
+
${suffix}` };
|
|
629189
629254
|
appended = true;
|
|
629190
629255
|
break;
|
|
629191
629256
|
}
|
|
629192
629257
|
if (!appended) {
|
|
629193
|
-
messages2.push({ role: "user", content: "/no_think" });
|
|
629258
|
+
messages2.push({ role: "user", content: "/nothink\n/no_think" });
|
|
629194
629259
|
}
|
|
629195
629260
|
return { ...request, messages: messages2, think: false };
|
|
629196
629261
|
}
|
|
@@ -631288,10 +631353,14 @@ Telegram link integrity contract:
|
|
|
631288
631353
|
* capacity and flood the TUI.
|
|
631289
631354
|
*/
|
|
631290
631355
|
telegramActiveWorkSessions = /* @__PURE__ */ new Set();
|
|
631356
|
+
telegramActiveWorkGenerations = /* @__PURE__ */ new Map();
|
|
631357
|
+
telegramActiveWorkStartedAtMs = /* @__PURE__ */ new Map();
|
|
631291
631358
|
/** Queued Telegram sessions waiting for a global work slot. */
|
|
631292
631359
|
telegramQueuedSessionWork = /* @__PURE__ */ new Map();
|
|
631293
631360
|
telegramDispatchQueuedTimer = null;
|
|
631294
631361
|
telegramDispatchQueuedAtMs = 0;
|
|
631362
|
+
telegramQueueDiagnosticLastAtMs = 0;
|
|
631363
|
+
telegramPollWarningLastAtMs = 0;
|
|
631295
631364
|
/** Lightweight chat history by chat/guest session key */
|
|
631296
631365
|
chatHistory = /* @__PURE__ */ new Map();
|
|
631297
631366
|
/** Participant and tone state by chat/guest session key */
|
|
@@ -631927,6 +631996,63 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
|
|
|
631927
631996
|
if (!Number.isFinite(parsed)) return 350;
|
|
631928
631997
|
return Math.max(0, Math.min(2e3, Math.floor(parsed)));
|
|
631929
631998
|
}
|
|
631999
|
+
telegramQueueDiagnosticIntervalMs() {
|
|
632000
|
+
const raw = Number.parseInt(process.env["OMNIUS_TG_QUEUE_DIAGNOSTIC_MS"] ?? "", 10);
|
|
632001
|
+
if (Number.isFinite(raw) && raw >= 5e3 && raw <= 3e5) return raw;
|
|
632002
|
+
return 3e4;
|
|
632003
|
+
}
|
|
632004
|
+
maybeLogTelegramQueueDiagnostic(reason) {
|
|
632005
|
+
if (this.telegramQueuedSessionWork.size === 0) return;
|
|
632006
|
+
const now = Date.now();
|
|
632007
|
+
const interval = this.telegramQueueDiagnosticIntervalMs();
|
|
632008
|
+
if (now - this.telegramQueueDiagnosticLastAtMs < interval) return;
|
|
632009
|
+
this.telegramQueueDiagnosticLastAtMs = now;
|
|
632010
|
+
const queued = [...this.telegramQueuedSessionWork.values()].sort((a2, b) => a2.enqueuedAtMs - b.enqueuedAtMs).slice(0, 4).map((work) => {
|
|
632011
|
+
const age = formatTelegramPipelineDuration(now - work.enqueuedAtMs);
|
|
632012
|
+
const live = this.telegramSessionIsLive(work.sessionKey) ? "blocked:same-session-live" : "ready";
|
|
632013
|
+
return `${work.sessionKey} age=${age} bundled=${work.messageCount} ${live}`;
|
|
632014
|
+
});
|
|
632015
|
+
const active = [...this.activeTelegramInteractionSessionKeys()].slice(0, 6);
|
|
632016
|
+
const inferences = this.getTelegramActiveInferences().slice(0, 4).map((inf) => `${inf.id}/${inf.kind}/${inf.model} elapsed=${inf.elapsedSec.toFixed(1)}s ttfb=${inf.ttfbSec === void 0 ? "waiting" : `${inf.ttfbSec.toFixed(1)}s`}`);
|
|
632017
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
632018
|
+
"queue",
|
|
632019
|
+
`queue diagnostic (${reason}): active ${this.activeTelegramInteractionCount()}/${this.getSubAgentLimit()} [${active.join(", ") || "none"}]; queued ${this.telegramQueuedSessionWork.size} [${queued.join(" | ")}]; inferences [${inferences.join(" | ") || "none"}]`
|
|
632020
|
+
));
|
|
632021
|
+
}
|
|
632022
|
+
nextTelegramWorkGeneration(sessionKey) {
|
|
632023
|
+
const generation = (this.telegramActiveWorkGenerations.get(sessionKey) ?? 0) + 1;
|
|
632024
|
+
this.telegramActiveWorkGenerations.set(sessionKey, generation);
|
|
632025
|
+
return generation;
|
|
632026
|
+
}
|
|
632027
|
+
telegramWorkGenerationIsCurrent(sessionKey, generation) {
|
|
632028
|
+
return this.telegramActiveWorkGenerations.get(sessionKey) === generation;
|
|
632029
|
+
}
|
|
632030
|
+
telegramPreAgentWorkMaxIdleMs() {
|
|
632031
|
+
const routerMs = telegramRouterTimeoutMs(this.agentConfig?.timeoutMs);
|
|
632032
|
+
const raw = Number.parseInt(process.env["OMNIUS_TG_PRE_AGENT_MAX_IDLE_MS"] ?? "", 10);
|
|
632033
|
+
if (Number.isFinite(raw) && raw >= 3e4 && raw <= 9e5) return raw;
|
|
632034
|
+
return Math.max(12e4, routerMs + 3e4);
|
|
632035
|
+
}
|
|
632036
|
+
reapStaleTelegramPreAgentWork() {
|
|
632037
|
+
const now = Date.now();
|
|
632038
|
+
const maxIdleMs = this.telegramPreAgentWorkMaxIdleMs();
|
|
632039
|
+
for (const sessionKey of [...this.telegramActiveWorkSessions]) {
|
|
632040
|
+
if (this.subAgents.has(sessionKey) || this.activeChatSessions.has(sessionKey)) continue;
|
|
632041
|
+
const startedAt2 = this.telegramActiveWorkStartedAtMs.get(sessionKey);
|
|
632042
|
+
if (!startedAt2) continue;
|
|
632043
|
+
const idleMs = now - startedAt2;
|
|
632044
|
+
if (idleMs <= maxIdleMs) continue;
|
|
632045
|
+
const generation = this.telegramActiveWorkGenerations.get(sessionKey) ?? 0;
|
|
632046
|
+
this.telegramActiveWorkGenerations.set(sessionKey, generation + 1);
|
|
632047
|
+
this.telegramActiveWorkSessions.delete(sessionKey);
|
|
632048
|
+
this.telegramActiveWorkStartedAtMs.delete(sessionKey);
|
|
632049
|
+
this.refreshActiveTelegramInteractionCount();
|
|
632050
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
632051
|
+
"queue",
|
|
632052
|
+
`watchdog: released stale pre-agent Telegram work pin for ${sessionKey} after ${Math.round(idleMs / 1e3)}s; queued messages may dispatch now`
|
|
632053
|
+
));
|
|
632054
|
+
}
|
|
632055
|
+
}
|
|
631930
632056
|
dispatchQueuedTelegramSessionWorkSoon(delayMs = 0) {
|
|
631931
632057
|
const dueAt = Date.now() + Math.max(0, delayMs);
|
|
631932
632058
|
if (this.telegramDispatchQueuedTimer && this.telegramDispatchQueuedAtMs <= dueAt) return;
|
|
@@ -631956,6 +632082,9 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
|
|
|
631956
632082
|
this.dispatchQueuedTelegramSessionWorkSoon(Math.max(0, nextDue - Date.now()));
|
|
631957
632083
|
}
|
|
631958
632084
|
}
|
|
632085
|
+
if (this.telegramQueuedSessionWork.size > 0) {
|
|
632086
|
+
this.maybeLogTelegramQueueDiagnostic("dispatch");
|
|
632087
|
+
}
|
|
631959
632088
|
this.refreshActiveTelegramInteractionCount();
|
|
631960
632089
|
}
|
|
631961
632090
|
buildTelegramQueuedSessionWork(sessionKey, msg, toolContext, now) {
|
|
@@ -631999,11 +632128,16 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
|
|
|
631999
632128
|
return;
|
|
632000
632129
|
}
|
|
632001
632130
|
this.telegramActiveWorkSessions.add(work.sessionKey);
|
|
632131
|
+
this.telegramActiveWorkStartedAtMs.set(work.sessionKey, Date.now());
|
|
632132
|
+
const generation = this.nextTelegramWorkGeneration(work.sessionKey);
|
|
632002
632133
|
this.refreshActiveTelegramInteractionCount();
|
|
632003
|
-
void this.processTelegramMessageWork(work).catch((err) => {
|
|
632134
|
+
void this.processTelegramMessageWork(work, generation).catch((err) => {
|
|
632004
632135
|
this.tuiWrite(() => renderWarning(`Telegram sub-agent error: ${err instanceof Error ? err.message : String(err)}`));
|
|
632005
632136
|
}).finally(() => {
|
|
632006
|
-
this.
|
|
632137
|
+
if (this.telegramWorkGenerationIsCurrent(work.sessionKey, generation)) {
|
|
632138
|
+
this.telegramActiveWorkSessions.delete(work.sessionKey);
|
|
632139
|
+
this.telegramActiveWorkStartedAtMs.delete(work.sessionKey);
|
|
632140
|
+
}
|
|
632007
632141
|
this.refreshActiveTelegramInteractionCount();
|
|
632008
632142
|
this.dispatchQueuedTelegramSessionWorkSoon();
|
|
632009
632143
|
});
|
|
@@ -635238,7 +635372,7 @@ ${lines.join("\n")}`);
|
|
|
635238
635372
|
`Current Telegram message text (untrusted user data):
|
|
635239
635373
|
${this.quoteTelegramContextBlock(msg.text, 1200)}`,
|
|
635240
635374
|
"",
|
|
635241
|
-
"/no_think"
|
|
635375
|
+
"/nothink\n/no_think"
|
|
635242
635376
|
].filter(Boolean).join("\n");
|
|
635243
635377
|
try {
|
|
635244
635378
|
const result = await this.telegramRouterJsonCompletion(
|
|
@@ -635705,7 +635839,8 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`,
|
|
|
635705
635839
|
`Original router output:`,
|
|
635706
635840
|
rawPreview,
|
|
635707
635841
|
``,
|
|
635708
|
-
`/
|
|
635842
|
+
`/nothink
|
|
635843
|
+
/no_think`
|
|
635709
635844
|
].join("\n");
|
|
635710
635845
|
try {
|
|
635711
635846
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
@@ -635718,8 +635853,8 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`,
|
|
|
635718
635853
|
],
|
|
635719
635854
|
tools: [],
|
|
635720
635855
|
temperature: 0,
|
|
635721
|
-
maxTokens:
|
|
635722
|
-
timeoutMs: telegramRouterTimeoutMs(timeoutMs, 8e3,
|
|
635856
|
+
maxTokens: 500,
|
|
635857
|
+
timeoutMs: telegramRouterTimeoutMs(timeoutMs, 8e3, 15e3),
|
|
635723
635858
|
think: false
|
|
635724
635859
|
}, diagnostics, "router-repair", sessionKey);
|
|
635725
635860
|
const repairedText = result.choices[0]?.message?.content ?? "";
|
|
@@ -635772,7 +635907,8 @@ ${userPrompt.slice(-4e3)}` : userPrompt;
|
|
|
635772
635907
|
`Router context (trailing-window):`,
|
|
635773
635908
|
trimmedUserPrompt,
|
|
635774
635909
|
``,
|
|
635775
|
-
`/
|
|
635910
|
+
`/nothink
|
|
635911
|
+
/no_think`
|
|
635776
635912
|
].join("\n");
|
|
635777
635913
|
try {
|
|
635778
635914
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
@@ -635785,8 +635921,8 @@ ${userPrompt.slice(-4e3)}` : userPrompt;
|
|
|
635785
635921
|
],
|
|
635786
635922
|
tools: [],
|
|
635787
635923
|
temperature: 0,
|
|
635788
|
-
maxTokens:
|
|
635789
|
-
timeoutMs: telegramRouterTimeoutMs(timeoutMs,
|
|
635924
|
+
maxTokens: 500,
|
|
635925
|
+
timeoutMs: telegramRouterTimeoutMs(timeoutMs, 8e3, 15e3),
|
|
635790
635926
|
think: false
|
|
635791
635927
|
}, diagnostics, "router-strict-retry", sessionKey);
|
|
635792
635928
|
const retryText = result.choices[0]?.message?.content ?? "";
|
|
@@ -635980,6 +636116,7 @@ ${retryText}`,
|
|
|
635980
636116
|
* never fires.
|
|
635981
636117
|
*/
|
|
635982
636118
|
reapStaleTelegramSubAgents() {
|
|
636119
|
+
this.reapStaleTelegramPreAgentWork();
|
|
635983
636120
|
const maxIdleMs = this.telegramSubAgentMaxIdleMs();
|
|
635984
636121
|
const now = Date.now();
|
|
635985
636122
|
const stale = [];
|
|
@@ -636000,6 +636137,7 @@ ${retryText}`,
|
|
|
636000
636137
|
clearInterval(agent.typingInterval);
|
|
636001
636138
|
agent.typingInterval = null;
|
|
636002
636139
|
}
|
|
636140
|
+
this.stopTelegramPublicProgressMessage(agent);
|
|
636003
636141
|
try {
|
|
636004
636142
|
agent.runner?.abort?.();
|
|
636005
636143
|
} catch {
|
|
@@ -636019,6 +636157,10 @@ ${retryText}`,
|
|
|
636019
636157
|
this.subAgentViewCallbacks?.onStatus(agent.viewId, "failed");
|
|
636020
636158
|
this.subAgentViewCallbacks?.onComplete(agent.viewId);
|
|
636021
636159
|
}
|
|
636160
|
+
if (this.telegramQueuedSessionWork.size > 0) {
|
|
636161
|
+
this.maybeLogTelegramQueueDiagnostic("watchdog");
|
|
636162
|
+
this.dispatchQueuedTelegramSessionWorkSoon();
|
|
636163
|
+
}
|
|
636022
636164
|
}
|
|
636023
636165
|
async inferTelegramInteractionDecision(msg, toolContext) {
|
|
636024
636166
|
const config = this.agentConfig;
|
|
@@ -636205,10 +636347,10 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
636205
636347
|
],
|
|
636206
636348
|
tools: [],
|
|
636207
636349
|
temperature: 0,
|
|
636208
|
-
//
|
|
636209
|
-
//
|
|
636210
|
-
maxTokens:
|
|
636211
|
-
timeoutMs: telegramRouterTimeoutMs(config.timeoutMs),
|
|
636350
|
+
// Router JSON is tiny. Keep the answer budget tight so Qwen-class
|
|
636351
|
+
// models cannot spend a minute producing hidden <think>-only output.
|
|
636352
|
+
maxTokens: 360,
|
|
636353
|
+
timeoutMs: telegramRouterTimeoutMs(config.timeoutMs, 8e3, 3e4),
|
|
636212
636354
|
think: false
|
|
636213
636355
|
}, diagnostics, "router", sessionKey);
|
|
636214
636356
|
const text = result.choices[0]?.message?.content ?? "";
|
|
@@ -636263,8 +636405,8 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
636263
636405
|
],
|
|
636264
636406
|
tools: [],
|
|
636265
636407
|
temperature: 0,
|
|
636266
|
-
maxTokens:
|
|
636267
|
-
timeoutMs: telegramRouterTimeoutMs(config.timeoutMs),
|
|
636408
|
+
maxTokens: 700,
|
|
636409
|
+
timeoutMs: telegramRouterTimeoutMs(config.timeoutMs, 8e3, 3e4),
|
|
636268
636410
|
think: false
|
|
636269
636411
|
}, diagnostics, "router", sessionKey);
|
|
636270
636412
|
const reissuedText = reissued.choices[0]?.message?.content ?? "";
|
|
@@ -636277,7 +636419,14 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
636277
636419
|
} catch {
|
|
636278
636420
|
}
|
|
636279
636421
|
}
|
|
636280
|
-
const
|
|
636422
|
+
const dualEmptyVisible = telegramRouterDiagnosticIsDualEmptyVisible(diagnostics) && !telegramRouterRawPreview(text);
|
|
636423
|
+
if (dualEmptyVisible) {
|
|
636424
|
+
if (diagnostics.repairStatus === void 0) {
|
|
636425
|
+
diagnostics.repairStatus = "skipped";
|
|
636426
|
+
diagnostics.repairError = "router returned no visible text in json-mode or plain retry; repair/strict retry would only burn more inference";
|
|
636427
|
+
}
|
|
636428
|
+
}
|
|
636429
|
+
const repaired = dualEmptyVisible ? null : await this.repairTelegramInteractionDecision(
|
|
636281
636430
|
backend,
|
|
636282
636431
|
text,
|
|
636283
636432
|
forcedRoute,
|
|
@@ -636288,7 +636437,7 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
636288
636437
|
if (repaired) {
|
|
636289
636438
|
return withRouterTelemetry(this.applyTelegramSilentReflectionNotes(repaired, reflectionNotes));
|
|
636290
636439
|
}
|
|
636291
|
-
const strictRetry = await this.retryTelegramInteractionDecisionStrict(
|
|
636440
|
+
const strictRetry = dualEmptyVisible ? null : await this.retryTelegramInteractionDecisionStrict(
|
|
636292
636441
|
backend,
|
|
636293
636442
|
userPrompt,
|
|
636294
636443
|
text,
|
|
@@ -636304,12 +636453,12 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
636304
636453
|
const failureNarrative = this.summarizeTelegramRouterFailure(diagnostics);
|
|
636305
636454
|
const backendLivenessFailure = (diagnostics.attempts ?? []).some(telegramRouterDiagnosticAttemptLooksLikeBackendLiveness) || telegramRouterErrorLooksLikeBackendLiveness(diagnostics.repairError ?? "") || telegramRouterErrorLooksLikeBackendLiveness(diagnostics.strictRetryError ?? "");
|
|
636306
636455
|
const fallback = this.applyTelegramSilentReflectionNotes(this.buildTelegramRouterUnavailableDecision(msg, toolContext, {
|
|
636307
|
-
reason: backendLivenessFailure ? "router recovery hit a backend liveness failure; no model-derived reply decision" : "router output was not valid decision JSON after repair/retry; no model-derived reply decision",
|
|
636456
|
+
reason: backendLivenessFailure ? "router recovery hit a backend liveness failure; no model-derived reply decision" : dualEmptyVisible ? "router returned no visible decision content in JSON or plain mode; no model-derived reply decision" : "router output was not valid decision JSON after repair/retry; no model-derived reply decision",
|
|
636308
636457
|
silentDisposition: reflectionNotes.silentDisposition,
|
|
636309
636458
|
diagnosticNote: this.composeTelegramRouterDiagnosticNote(
|
|
636310
636459
|
invalidRouterPreview,
|
|
636311
636460
|
failureNarrative,
|
|
636312
|
-
backendLivenessFailure ? "router backend failed during attention-decision recovery; no usable router decision was available" : 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"
|
|
636461
|
+
backendLivenessFailure ? "router backend failed during attention-decision recovery; no usable router decision was available" : dualEmptyVisible ? "router returned no visible decision content in JSON or plain mode; repair/strict retry skipped" : 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"
|
|
636313
636462
|
),
|
|
636314
636463
|
raw: text
|
|
636315
636464
|
}), reflectionNotes);
|
|
@@ -636884,6 +637033,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
636884
637033
|
for (const [, agent] of this.subAgents) {
|
|
636885
637034
|
agent.aborted = true;
|
|
636886
637035
|
if (agent.typingInterval) clearInterval(agent.typingInterval);
|
|
637036
|
+
this.stopTelegramPublicProgressMessage(agent);
|
|
636887
637037
|
try {
|
|
636888
637038
|
agent.runner?.abort?.();
|
|
636889
637039
|
} catch {
|
|
@@ -636899,6 +637049,8 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
636899
637049
|
}
|
|
636900
637050
|
this.telegramQueuedSessionWork.clear();
|
|
636901
637051
|
this.telegramActiveWorkSessions.clear();
|
|
637052
|
+
this.telegramActiveWorkGenerations.clear();
|
|
637053
|
+
this.telegramActiveWorkStartedAtMs.clear();
|
|
636902
637054
|
this.telegramAdminLivePanels.clear();
|
|
636903
637055
|
this.flushTelegramViewWrites();
|
|
636904
637056
|
this.flushTelegramTuiWrites();
|
|
@@ -637085,6 +637237,62 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
637085
637237
|
}
|
|
637086
637238
|
}
|
|
637087
637239
|
}
|
|
637240
|
+
shouldUseTelegramPublicProgressMessage(msg, toolContext) {
|
|
637241
|
+
return toolContext === "telegram-public" && msg.chatType !== "private" && !msg.guestQueryId;
|
|
637242
|
+
}
|
|
637243
|
+
renderTelegramPublicProgressHTML(subAgent, msg, phase) {
|
|
637244
|
+
const elapsedSec = Math.max(0, Math.floor((Date.now() - subAgent.startedAtMs) / 1e3));
|
|
637245
|
+
const sessionKey = this.sessionKeyForMessage(msg);
|
|
637246
|
+
const activeInference = this.getTelegramActiveInferences().find((inf) => inf.sessionKey === sessionKey);
|
|
637247
|
+
const status = activeInference ? activeInference.ttfbSec === void 0 ? `model request active; waiting for first token (${activeInference.kind}, ${activeInference.elapsedSec.toFixed(1)}s)` : `streaming ${activeInference.kind}; content=${activeInference.contentTokens}t thinking=${activeInference.thinkingTokens}t` : phase;
|
|
637248
|
+
const width = 12;
|
|
637249
|
+
const filled = Math.min(width, Math.floor(elapsedSec % 60 / 60 * width));
|
|
637250
|
+
const bar = `[${"#".repeat(filled)}${"-".repeat(width - filled)}]`;
|
|
637251
|
+
return [
|
|
637252
|
+
`<b>Working</b>`,
|
|
637253
|
+
`<code>${bar}</code> ${elapsedSec}s`,
|
|
637254
|
+
`<i>${escapeTelegramHTML(status)}</i>`
|
|
637255
|
+
].join("\n");
|
|
637256
|
+
}
|
|
637257
|
+
startTelegramPublicProgressMessage(subAgent, msg, phase) {
|
|
637258
|
+
if (!this.shouldUseTelegramPublicProgressMessage(msg, subAgent.toolContext)) return;
|
|
637259
|
+
if (subAgent.publicProgressTimer) return;
|
|
637260
|
+
const update2 = () => {
|
|
637261
|
+
if (subAgent.aborted) return;
|
|
637262
|
+
if (!this.subAgents.has(this.sessionKeyForMessage(msg))) return;
|
|
637263
|
+
const html = this.renderTelegramPublicProgressHTML(subAgent, msg, phase);
|
|
637264
|
+
if (subAgent.liveMessageId) {
|
|
637265
|
+
const now = Date.now();
|
|
637266
|
+
if (now - subAgent.lastEditMs < 3e3) return;
|
|
637267
|
+
subAgent.lastEditMs = now;
|
|
637268
|
+
void this.editLiveMessage(msg.chatId, subAgent.liveMessageId, html).catch(() => {
|
|
637269
|
+
});
|
|
637270
|
+
return;
|
|
637271
|
+
}
|
|
637272
|
+
if (subAgent.liveMessagePromise) return;
|
|
637273
|
+
subAgent.liveMessagePromise = this.sendLiveMessage(
|
|
637274
|
+
msg.chatId,
|
|
637275
|
+
html,
|
|
637276
|
+
msg.chatType !== "private" ? msg.messageId : void 0
|
|
637277
|
+
).then((id) => {
|
|
637278
|
+
subAgent.liveMessageId = id;
|
|
637279
|
+
subAgent.lastEditMs = Date.now();
|
|
637280
|
+
}).catch(() => {
|
|
637281
|
+
}).finally(() => {
|
|
637282
|
+
subAgent.liveMessagePromise = null;
|
|
637283
|
+
});
|
|
637284
|
+
};
|
|
637285
|
+
update2();
|
|
637286
|
+
subAgent.publicProgressTimer = setInterval(update2, 5e3);
|
|
637287
|
+
if (typeof subAgent.publicProgressTimer.unref === "function") {
|
|
637288
|
+
subAgent.publicProgressTimer.unref();
|
|
637289
|
+
}
|
|
637290
|
+
}
|
|
637291
|
+
stopTelegramPublicProgressMessage(subAgent) {
|
|
637292
|
+
if (!subAgent.publicProgressTimer) return;
|
|
637293
|
+
clearInterval(subAgent.publicProgressTimer);
|
|
637294
|
+
subAgent.publicProgressTimer = null;
|
|
637295
|
+
}
|
|
637088
637296
|
ensureTelegramAdminLivePanel(subAgent, msg) {
|
|
637089
637297
|
const existing = subAgent.adminLivePanelNonce ? this.telegramAdminLivePanels.get(subAgent.adminLivePanelNonce) : void 0;
|
|
637090
637298
|
if (existing) return existing;
|
|
@@ -637343,11 +637551,12 @@ Join: ${newUrl}`);
|
|
|
637343
637551
|
}
|
|
637344
637552
|
this.scheduleTelegramSessionWork(msg, toolContext);
|
|
637345
637553
|
}
|
|
637346
|
-
async processTelegramMessageWork(work) {
|
|
637554
|
+
async processTelegramMessageWork(work, workGeneration) {
|
|
637347
637555
|
const msg = work.msg;
|
|
637348
637556
|
const toolContext = work.toolContext;
|
|
637349
637557
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
637350
637558
|
const isAdminDM = toolContext === "telegram-admin-dm";
|
|
637559
|
+
if (!this.telegramWorkGenerationIsCurrent(sessionKey, workGeneration)) return;
|
|
637351
637560
|
const existing = this.subAgents.get(sessionKey);
|
|
637352
637561
|
if (existing && !existing.aborted) {
|
|
637353
637562
|
await this.enqueueTelegramQueuedSessionWorkForExistingSubAgent(work, existing);
|
|
@@ -637365,6 +637574,13 @@ Join: ${newUrl}`);
|
|
|
637365
637574
|
} catch (err) {
|
|
637366
637575
|
decision2 = this.fallbackTelegramRouterDecision(msg, toolContext, err);
|
|
637367
637576
|
}
|
|
637577
|
+
if (!this.telegramWorkGenerationIsCurrent(sessionKey, workGeneration)) {
|
|
637578
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
637579
|
+
msg.username,
|
|
637580
|
+
`discarded stale Telegram work result after queue pin release for ${sessionKey}`
|
|
637581
|
+
));
|
|
637582
|
+
return;
|
|
637583
|
+
}
|
|
637368
637584
|
const storedPreference = this.applyTelegramReplyPreferenceUpdate(
|
|
637369
637585
|
sessionKey,
|
|
637370
637586
|
msg,
|
|
@@ -637482,6 +637698,7 @@ Join: ${newUrl}`);
|
|
|
637482
637698
|
if (replyEdge) {
|
|
637483
637699
|
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, replyEdge));
|
|
637484
637700
|
}
|
|
637701
|
+
this.startTelegramPublicProgressMessage(subAgent, msg, "taking notes and preparing tools");
|
|
637485
637702
|
try {
|
|
637486
637703
|
let mediaContext = "";
|
|
637487
637704
|
if (msg.media || msg.replyToMedia) {
|
|
@@ -637498,6 +637715,7 @@ Join: ${newUrl}`);
|
|
|
637498
637715
|
clearInterval(subAgent.typingInterval);
|
|
637499
637716
|
subAgent.typingInterval = null;
|
|
637500
637717
|
}
|
|
637718
|
+
this.stopTelegramPublicProgressMessage(subAgent);
|
|
637501
637719
|
const finalText = cleanTelegramVisibleReply(result || "");
|
|
637502
637720
|
if (isAdminDM && !this.telegramAdminRunCompleted(subAgent)) {
|
|
637503
637721
|
const incompleteText = this.telegramAdminIncompleteRunText(subAgent, finalText);
|
|
@@ -637566,6 +637784,7 @@ Join: ${newUrl}`);
|
|
|
637566
637784
|
clearInterval(subAgent.typingInterval);
|
|
637567
637785
|
subAgent.typingInterval = null;
|
|
637568
637786
|
}
|
|
637787
|
+
this.stopTelegramPublicProgressMessage(subAgent);
|
|
637569
637788
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
637570
637789
|
this.tuiWrite(() => renderTelegramSubAgentError(msg.username, errMsg));
|
|
637571
637790
|
this.subAgentViewCallbacks?.onWrite(subAgent.viewId, `error: ${errMsg}`);
|
|
@@ -637582,6 +637801,7 @@ Join: ${newUrl}`);
|
|
|
637582
637801
|
});
|
|
637583
637802
|
}
|
|
637584
637803
|
} finally {
|
|
637804
|
+
this.stopTelegramPublicProgressMessage(subAgent);
|
|
637585
637805
|
this.clearTelegramSubAgentContextBuffer(sessionKey);
|
|
637586
637806
|
this.subAgents.delete(sessionKey);
|
|
637587
637807
|
this.refreshActiveTelegramInteractionCount();
|
|
@@ -637755,6 +637975,24 @@ Join: ${newUrl}`);
|
|
|
637755
637975
|
typingInterval = this.startTypingIndicator(msg.chatId);
|
|
637756
637976
|
}
|
|
637757
637977
|
this.tuiWrite(() => renderTelegramSubAgentEvent(msg.username, `live inference: chat reply (${this.interactionMode})`));
|
|
637978
|
+
if (this.shouldUseTelegramPublicProgressMessage(msg, toolContext)) {
|
|
637979
|
+
const initialHtml = [
|
|
637980
|
+
`<b>Working</b>`,
|
|
637981
|
+
`<code>[------------]</code> 0s`,
|
|
637982
|
+
`<i>preparing a concise reply</i>`
|
|
637983
|
+
].join("\n");
|
|
637984
|
+
liveMessagePromise = this.sendLiveMessage(
|
|
637985
|
+
msg.chatId,
|
|
637986
|
+
initialHtml,
|
|
637987
|
+
msg.chatType !== "private" ? msg.messageId : void 0
|
|
637988
|
+
).then((id) => {
|
|
637989
|
+
liveMessageId = id;
|
|
637990
|
+
lastEditMs = Date.now();
|
|
637991
|
+
}).catch(() => {
|
|
637992
|
+
}).finally(() => {
|
|
637993
|
+
liveMessagePromise = null;
|
|
637994
|
+
});
|
|
637995
|
+
}
|
|
637758
637996
|
try {
|
|
637759
637997
|
const mediaContext = msg.media || msg.replyToMedia || msg.livePhoto ? await this.processMediaContextForMessage(msg) : "";
|
|
637760
637998
|
const contextualPayload = [mediaContext, additionalContext].filter(Boolean).join("\n\n");
|
|
@@ -641633,11 +641871,23 @@ ${caption}\r
|
|
|
641633
641871
|
}
|
|
641634
641872
|
} catch (err) {
|
|
641635
641873
|
if (this.polling) {
|
|
641874
|
+
const now = Date.now();
|
|
641875
|
+
if (now - this.telegramPollWarningLastAtMs > 3e4) {
|
|
641876
|
+
this.telegramPollWarningLastAtMs = now;
|
|
641877
|
+
this.tuiWrite(() => renderWarning(
|
|
641878
|
+
`Telegram polling warning: getUpdates failed (${err instanceof Error ? err.message : String(err)}); retrying`
|
|
641879
|
+
));
|
|
641880
|
+
}
|
|
641636
641881
|
await new Promise((r2) => setTimeout(r2, 5e3));
|
|
641637
641882
|
}
|
|
641638
641883
|
}
|
|
641639
641884
|
}
|
|
641640
641885
|
}
|
|
641886
|
+
telegramLongPollClientTimeoutMs() {
|
|
641887
|
+
const raw = Number.parseInt(process.env["OMNIUS_TG_LONG_POLL_CLIENT_TIMEOUT_MS"] ?? "", 10);
|
|
641888
|
+
if (Number.isFinite(raw) && raw >= 35e3 && raw <= 3e5) return raw;
|
|
641889
|
+
return 45e3;
|
|
641890
|
+
}
|
|
641641
641891
|
/** Make a Telegram Bot API call with rate-limit retry */
|
|
641642
641892
|
async apiCall(method, body, _retryDepth = 0) {
|
|
641643
641893
|
const url = `https://api.telegram.org/bot${this.botToken}/${method}`;
|
|
@@ -641650,7 +641900,13 @@ ${caption}\r
|
|
|
641650
641900
|
}
|
|
641651
641901
|
const isLongPoll = method === "getUpdates";
|
|
641652
641902
|
if (isLongPoll && this.abortController) {
|
|
641653
|
-
|
|
641903
|
+
const timeoutFn = AbortSignal.timeout;
|
|
641904
|
+
const anyFn = AbortSignal.any;
|
|
641905
|
+
const signals = [
|
|
641906
|
+
this.abortController.signal,
|
|
641907
|
+
typeof timeoutFn === "function" ? timeoutFn(this.telegramLongPollClientTimeoutMs()) : void 0
|
|
641908
|
+
].filter((signal) => signal instanceof AbortSignal);
|
|
641909
|
+
options2.signal = typeof anyFn === "function" && signals.length > 1 ? anyFn(signals) : signals[0];
|
|
641654
641910
|
} else if (!isLongPoll) {
|
|
641655
641911
|
options2.signal = AbortSignal.timeout(3e4);
|
|
641656
641912
|
}
|
|
@@ -659607,6 +659863,30 @@ function sanitizeChatContent(raw) {
|
|
|
659607
659863
|
}
|
|
659608
659864
|
return cleaned.join("\n").trim();
|
|
659609
659865
|
}
|
|
659866
|
+
function appendNoThinkDirectivesToMessages(messages2) {
|
|
659867
|
+
let lastUserIdx = -1;
|
|
659868
|
+
for (let i2 = messages2.length - 1; i2 >= 0; i2--) {
|
|
659869
|
+
if (messages2[i2]?.role === "user") {
|
|
659870
|
+
lastUserIdx = i2;
|
|
659871
|
+
break;
|
|
659872
|
+
}
|
|
659873
|
+
}
|
|
659874
|
+
if (lastUserIdx < 0) return messages2;
|
|
659875
|
+
const target = messages2[lastUserIdx];
|
|
659876
|
+
if (!target || typeof target.content !== "string") return messages2;
|
|
659877
|
+
const hasOllamaNoThink = /\/nothink\b/i.test(target.content);
|
|
659878
|
+
const hasQwenNoThink = /\/no[_-]think\b/i.test(target.content);
|
|
659879
|
+
if (hasOllamaNoThink && hasQwenNoThink) return messages2;
|
|
659880
|
+
const suffix = [
|
|
659881
|
+
hasOllamaNoThink ? null : "/nothink",
|
|
659882
|
+
hasQwenNoThink ? null : "/no_think"
|
|
659883
|
+
].filter(Boolean).join("\n");
|
|
659884
|
+
return messages2.map(
|
|
659885
|
+
(m2, i2) => i2 === lastUserIdx ? { ...m2, content: `${target.content}
|
|
659886
|
+
|
|
659887
|
+
${suffix}` } : m2
|
|
659888
|
+
);
|
|
659889
|
+
}
|
|
659610
659890
|
async function directChatBackend(opts) {
|
|
659611
659891
|
const { model, messages: messages2, stream, res, sessionId, ollamaUrl, extraFields } = opts;
|
|
659612
659892
|
const cfg = loadConfig();
|
|
@@ -659695,13 +659975,12 @@ async function directChatBackend(opts) {
|
|
|
659695
659975
|
if (Array.isArray(ef["stop"]) || typeof ef["stop"] === "string") ollamaOpts["stop"] = ef["stop"];
|
|
659696
659976
|
const hasTools = Array.isArray(ef["tools"]) && ef["tools"].length > 0;
|
|
659697
659977
|
const ollamaFormat = ollamaFormatFromOpenAIResponseFormat(ef["response_format"]);
|
|
659978
|
+
const ollamaMessages = appendNoThinkDirectivesToMessages(messages2);
|
|
659698
659979
|
const reqBody = JSON.stringify({
|
|
659699
659980
|
model: cleanModel,
|
|
659700
|
-
messages:
|
|
659981
|
+
messages: ollamaMessages,
|
|
659701
659982
|
stream,
|
|
659702
|
-
|
|
659703
|
-
// thinking models often need their reasoning chain to choose a tool.
|
|
659704
|
-
...hasTools ? {} : { think: false },
|
|
659983
|
+
think: false,
|
|
659705
659984
|
...hasTools ? { tools: ef["tools"] } : {},
|
|
659706
659985
|
...ef["tool_choice"] !== void 0 ? { tool_choice: ef["tool_choice"] } : {},
|
|
659707
659986
|
...ollamaFormat !== void 0 ? { format: ollamaFormat } : {},
|
|
@@ -659931,13 +660210,18 @@ async function completeRealtimeTextOnly(opts) {
|
|
|
659931
660210
|
if (!requestedModel) {
|
|
659932
660211
|
originalModel = realtimeOllamaFallbackCache.get(realtimeFallbackCacheKey(targetUrl, originalModel)) ?? originalModel;
|
|
659933
660212
|
}
|
|
659934
|
-
const makeOllamaChatBody = (modelName) =>
|
|
659935
|
-
|
|
659936
|
-
|
|
659937
|
-
|
|
659938
|
-
|
|
659939
|
-
|
|
659940
|
-
|
|
660213
|
+
const makeOllamaChatBody = (modelName) => {
|
|
660214
|
+
const rtMessages = Array.isArray(requestBody["messages"]) ? appendNoThinkDirectivesToMessages(
|
|
660215
|
+
requestBody["messages"]
|
|
660216
|
+
) : requestBody["messages"];
|
|
660217
|
+
return JSON.stringify({
|
|
660218
|
+
model: modelName,
|
|
660219
|
+
messages: rtMessages,
|
|
660220
|
+
stream: false,
|
|
660221
|
+
think: false,
|
|
660222
|
+
options: { temperature, num_predict: maxTokens }
|
|
660223
|
+
});
|
|
660224
|
+
};
|
|
659941
660225
|
let result = await ollamaRequest(targetUrl, "/api/chat", "POST", makeOllamaChatBody(originalModel), timeoutMs, route?.endpoint);
|
|
659942
660226
|
if (result.status >= 400 && !requestedModel && isOllamaMissingModelError(result.body)) {
|
|
659943
660227
|
const fallbackModel = await resolveRealtimeOllamaFallbackModel(targetUrl, timeoutMs, originalModel);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.183",
|
|
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.183",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED