omnius 1.0.134 → 1.0.135
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 +886 -113
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1365,7 +1365,7 @@ async function vramSnapshotMB() {
|
|
|
1365
1365
|
function getModelBroker() {
|
|
1366
1366
|
return ModelBroker.getInstance();
|
|
1367
1367
|
}
|
|
1368
|
-
var DEFAULT_RAM_HEADROOM_MB, DEFAULT_VRAM_HEADROOM_MB, DEFAULT_IDLE_EVICT_MS, DEFAULT_POLL_MS, DEFAULT_INFLIGHT_WAIT_MS, ModelBroker, _nvSmiAvailable;
|
|
1368
|
+
var DEFAULT_RAM_HEADROOM_MB, DEFAULT_VRAM_HEADROOM_MB, DEFAULT_IDLE_EVICT_MS, DEFAULT_POLL_MS, DEFAULT_INFLIGHT_WAIT_MS, DEFAULT_SLOT_CAPACITY, DEFAULT_QUEUE_CAPACITY, THROUGHPUT_EMA_ALPHA, THROUGHPUT_INITIAL_TPS, STUCK_INFLIGHT_DIAGNOSTIC_MS, ModelBroker, _nvSmiAvailable;
|
|
1369
1369
|
var init_model_broker = __esm({
|
|
1370
1370
|
"packages/execution/dist/model-broker.js"() {
|
|
1371
1371
|
"use strict";
|
|
@@ -1374,6 +1374,11 @@ var init_model_broker = __esm({
|
|
|
1374
1374
|
DEFAULT_IDLE_EVICT_MS = 5 * 60 * 1e3;
|
|
1375
1375
|
DEFAULT_POLL_MS = 4e3;
|
|
1376
1376
|
DEFAULT_INFLIGHT_WAIT_MS = 6e4;
|
|
1377
|
+
DEFAULT_SLOT_CAPACITY = 4;
|
|
1378
|
+
DEFAULT_QUEUE_CAPACITY = 50;
|
|
1379
|
+
THROUGHPUT_EMA_ALPHA = 0.2;
|
|
1380
|
+
THROUGHPUT_INITIAL_TPS = 25;
|
|
1381
|
+
STUCK_INFLIGHT_DIAGNOSTIC_MS = 5 * 60 * 1e3;
|
|
1377
1382
|
ModelBroker = class _ModelBroker {
|
|
1378
1383
|
static _instance = null;
|
|
1379
1384
|
/** Loaded model registry keyed by `${host}:${name}`. */
|
|
@@ -1398,6 +1403,22 @@ var init_model_broker = __esm({
|
|
|
1398
1403
|
ramHeadroomMB = DEFAULT_RAM_HEADROOM_MB;
|
|
1399
1404
|
vramHeadroomMB = DEFAULT_VRAM_HEADROOM_MB;
|
|
1400
1405
|
idleEvictMs = DEFAULT_IDLE_EVICT_MS;
|
|
1406
|
+
/** Inference slot capacity (auto-tunes from Ollama pool size when known). */
|
|
1407
|
+
slotCapacity = DEFAULT_SLOT_CAPACITY;
|
|
1408
|
+
/** Maximum queue depth before queue pressure is emitted. */
|
|
1409
|
+
queueCapacity = DEFAULT_QUEUE_CAPACITY;
|
|
1410
|
+
// ── Inference slot tracking ─────────────────────────────────────────
|
|
1411
|
+
/** Active slots keyed by slot id. */
|
|
1412
|
+
_activeSlots = /* @__PURE__ */ new Map();
|
|
1413
|
+
/** Reserved slots per sessionKey (1 reserved slot per active chat). */
|
|
1414
|
+
_reservedBySession = /* @__PURE__ */ new Map();
|
|
1415
|
+
// sessionKey -> slot id
|
|
1416
|
+
/** Shared (non-reserved) queue. FIFO with priority insertion. */
|
|
1417
|
+
_slotQueue = [];
|
|
1418
|
+
/** Per-model throughput tracking. */
|
|
1419
|
+
_throughput = /* @__PURE__ */ new Map();
|
|
1420
|
+
/** Monotonic counter for slot ids. */
|
|
1421
|
+
_slotIdSeq = 0;
|
|
1401
1422
|
static getInstance() {
|
|
1402
1423
|
if (!_ModelBroker._instance)
|
|
1403
1424
|
_ModelBroker._instance = new _ModelBroker();
|
|
@@ -1876,7 +1897,30 @@ var init_model_broker = __esm({
|
|
|
1876
1897
|
inflight: [...this._inflight.entries()].map(([key, v]) => ({ key, owner: v.owner, startedMs: v.startedMs })),
|
|
1877
1898
|
ramMB: ram,
|
|
1878
1899
|
vramMB: vram,
|
|
1879
|
-
lastPollAt: Date.now()
|
|
1900
|
+
lastPollAt: Date.now(),
|
|
1901
|
+
slots: this.buildSlotsSnapshot()
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
buildSlotsSnapshot() {
|
|
1905
|
+
const byModel = {};
|
|
1906
|
+
for (const slot of this._activeSlots.values()) {
|
|
1907
|
+
const k = slot.model;
|
|
1908
|
+
if (!byModel[k])
|
|
1909
|
+
byModel[k] = { inUse: 0, tokensPerSec: 0, samples: 0 };
|
|
1910
|
+
byModel[k].inUse += 1;
|
|
1911
|
+
}
|
|
1912
|
+
for (const [model, tp] of this._throughput) {
|
|
1913
|
+
if (!byModel[model])
|
|
1914
|
+
byModel[model] = { inUse: 0, tokensPerSec: 0, samples: 0 };
|
|
1915
|
+
byModel[model].tokensPerSec = tp.tokensPerSec;
|
|
1916
|
+
byModel[model].samples = tp.samples;
|
|
1917
|
+
}
|
|
1918
|
+
return {
|
|
1919
|
+
inUse: this._activeSlots.size,
|
|
1920
|
+
capacity: this.slotCapacity,
|
|
1921
|
+
queueDepth: this._slotQueue.length,
|
|
1922
|
+
queueCapacity: this.queueCapacity,
|
|
1923
|
+
byModel
|
|
1880
1924
|
};
|
|
1881
1925
|
}
|
|
1882
1926
|
async checkPressure(snap) {
|
|
@@ -1890,6 +1934,169 @@ var init_model_broker = __esm({
|
|
|
1890
1934
|
this.emit("pressure", "vram", v.free, this.vramHeadroomMB);
|
|
1891
1935
|
}
|
|
1892
1936
|
}
|
|
1937
|
+
const queueThreshold = Math.floor(this.queueCapacity * 0.8);
|
|
1938
|
+
if (this._slotQueue.length >= queueThreshold) {
|
|
1939
|
+
this.emit("pressure", "queue", this._slotQueue.length, queueThreshold);
|
|
1940
|
+
}
|
|
1941
|
+
const now = Date.now();
|
|
1942
|
+
for (const slot of this._activeSlots.values()) {
|
|
1943
|
+
if (now - slot.acquiredAt > STUCK_INFLIGHT_DIAGNOSTIC_MS) {
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
// ------------------------------------------------------------------
|
|
1948
|
+
// Inference slot admission control (replaces timeouts)
|
|
1949
|
+
// ------------------------------------------------------------------
|
|
1950
|
+
/**
|
|
1951
|
+
* Acquire an inference slot. Blocks (queues with backpressure) until a slot
|
|
1952
|
+
* is available. Never times out — work either completes or is cancelled
|
|
1953
|
+
* via the caller-provided AbortSignal before admission.
|
|
1954
|
+
*
|
|
1955
|
+
* Two-tier admission:
|
|
1956
|
+
* 1. Reserved: 1 slot per sessionKey kept warm even when shared pool full
|
|
1957
|
+
* 2. Shared: queue with FIFO+priority ordering; size-bounded by queueCapacity
|
|
1958
|
+
*
|
|
1959
|
+
* Backpressure: when queue exceeds 80% capacity, emit `pressure: "queue"` —
|
|
1960
|
+
* upstream callers (e.g. Telegram poll loop) should slow ingress.
|
|
1961
|
+
*/
|
|
1962
|
+
acquireInferenceSlot(spec) {
|
|
1963
|
+
if (this._activeSlots.size < this.slotCapacity) {
|
|
1964
|
+
return Promise.resolve(this.admitSlot(
|
|
1965
|
+
spec,
|
|
1966
|
+
/*reserved*/
|
|
1967
|
+
false
|
|
1968
|
+
));
|
|
1969
|
+
}
|
|
1970
|
+
if (spec.sessionKey && !this._reservedBySession.has(spec.sessionKey) && this._activeSlots.size < this.slotCapacity + 1) {
|
|
1971
|
+
const slot = this.admitSlot(
|
|
1972
|
+
spec,
|
|
1973
|
+
/*reserved*/
|
|
1974
|
+
true
|
|
1975
|
+
);
|
|
1976
|
+
this._reservedBySession.set(spec.sessionKey, slot.info.id);
|
|
1977
|
+
return Promise.resolve(slot);
|
|
1978
|
+
}
|
|
1979
|
+
return new Promise((resolve55, reject) => {
|
|
1980
|
+
const entry = { spec, resolve: resolve55, reject, enqueuedAt: Date.now() };
|
|
1981
|
+
if (spec.signal) {
|
|
1982
|
+
const onAbort = () => {
|
|
1983
|
+
const idx = this._slotQueue.indexOf(entry);
|
|
1984
|
+
if (idx >= 0)
|
|
1985
|
+
this._slotQueue.splice(idx, 1);
|
|
1986
|
+
reject(new Error("inference slot acquisition aborted by caller signal"));
|
|
1987
|
+
};
|
|
1988
|
+
if (spec.signal.aborted) {
|
|
1989
|
+
onAbort();
|
|
1990
|
+
return;
|
|
1991
|
+
}
|
|
1992
|
+
spec.signal.addEventListener("abort", onAbort, { once: true });
|
|
1993
|
+
entry.onSignalAbort = onAbort;
|
|
1994
|
+
}
|
|
1995
|
+
const prio = spec.priority ?? 0;
|
|
1996
|
+
let insertAt = this._slotQueue.length;
|
|
1997
|
+
for (let i2 = this._slotQueue.length - 1; i2 >= 0; i2--) {
|
|
1998
|
+
const p2 = this._slotQueue[i2].spec.priority ?? 0;
|
|
1999
|
+
if (p2 >= prio) {
|
|
2000
|
+
insertAt = i2 + 1;
|
|
2001
|
+
break;
|
|
2002
|
+
}
|
|
2003
|
+
if (i2 === 0)
|
|
2004
|
+
insertAt = 0;
|
|
2005
|
+
}
|
|
2006
|
+
this._slotQueue.splice(insertAt, 0, entry);
|
|
2007
|
+
const threshold = Math.floor(this.queueCapacity * 0.8);
|
|
2008
|
+
if (this._slotQueue.length === threshold) {
|
|
2009
|
+
this.emit("pressure", "queue", this._slotQueue.length, threshold);
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
}
|
|
2013
|
+
/** Admit a slot — internal, called from acquire fast path and from drainQueue. */
|
|
2014
|
+
admitSlot(spec, reserved) {
|
|
2015
|
+
const id = `slot-${++this._slotIdSeq}-${Date.now().toString(36)}`;
|
|
2016
|
+
const info = {
|
|
2017
|
+
id,
|
|
2018
|
+
model: spec.model,
|
|
2019
|
+
domain: spec.domain,
|
|
2020
|
+
owner: spec.owner,
|
|
2021
|
+
sessionKey: spec.sessionKey,
|
|
2022
|
+
acquiredAt: Date.now(),
|
|
2023
|
+
promptTokens: spec.promptTokens ?? 0,
|
|
2024
|
+
reserved
|
|
2025
|
+
};
|
|
2026
|
+
this._activeSlots.set(id, info);
|
|
2027
|
+
this.emit("slotAcquired", info);
|
|
2028
|
+
let released = false;
|
|
2029
|
+
const broker = this;
|
|
2030
|
+
return {
|
|
2031
|
+
info,
|
|
2032
|
+
release(outcome) {
|
|
2033
|
+
if (released)
|
|
2034
|
+
return;
|
|
2035
|
+
released = true;
|
|
2036
|
+
broker.releaseSlot(info, outcome);
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
releaseSlot(info, outcome) {
|
|
2041
|
+
this._activeSlots.delete(info.id);
|
|
2042
|
+
if (info.sessionKey && this._reservedBySession.get(info.sessionKey) === info.id) {
|
|
2043
|
+
this._reservedBySession.delete(info.sessionKey);
|
|
2044
|
+
}
|
|
2045
|
+
if (outcome.ok && (outcome.completionTokens ?? 0) > 0) {
|
|
2046
|
+
const wallMs = Date.now() - info.acquiredAt;
|
|
2047
|
+
if (wallMs > 100) {
|
|
2048
|
+
const tps = outcome.completionTokens * 1e3 / wallMs;
|
|
2049
|
+
const cur = this._throughput.get(info.model) ?? {
|
|
2050
|
+
tokensPerSec: THROUGHPUT_INITIAL_TPS,
|
|
2051
|
+
samples: 0,
|
|
2052
|
+
lastReleaseAt: 0
|
|
2053
|
+
};
|
|
2054
|
+
cur.tokensPerSec = cur.samples === 0 ? tps : cur.tokensPerSec * (1 - THROUGHPUT_EMA_ALPHA) + tps * THROUGHPUT_EMA_ALPHA;
|
|
2055
|
+
cur.samples += 1;
|
|
2056
|
+
cur.lastReleaseAt = Date.now();
|
|
2057
|
+
this._throughput.set(info.model, cur);
|
|
2058
|
+
this.emit("throughputUpdated", info.model, cur.tokensPerSec);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
this.emit("slotReleased", info, outcome);
|
|
2062
|
+
this.drainSlotQueue();
|
|
2063
|
+
}
|
|
2064
|
+
drainSlotQueue() {
|
|
2065
|
+
while (this._slotQueue.length > 0 && this._activeSlots.size < this.slotCapacity) {
|
|
2066
|
+
const entry = this._slotQueue.shift();
|
|
2067
|
+
if (entry.onSignalAbort && entry.spec.signal) {
|
|
2068
|
+
entry.spec.signal.removeEventListener("abort", entry.onSignalAbort);
|
|
2069
|
+
}
|
|
2070
|
+
if (entry.spec.signal?.aborted) {
|
|
2071
|
+
try {
|
|
2072
|
+
entry.reject(new Error("aborted before admission"));
|
|
2073
|
+
} catch {
|
|
2074
|
+
}
|
|
2075
|
+
continue;
|
|
2076
|
+
}
|
|
2077
|
+
const slot = this.admitSlot(
|
|
2078
|
+
entry.spec,
|
|
2079
|
+
/*reserved*/
|
|
2080
|
+
false
|
|
2081
|
+
);
|
|
2082
|
+
try {
|
|
2083
|
+
entry.resolve(slot);
|
|
2084
|
+
} catch {
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
/** Snapshot of throughput EMAs (for /broker and debugging). */
|
|
2089
|
+
throughputByModel() {
|
|
2090
|
+
const out = {};
|
|
2091
|
+
for (const [model, tp] of this._throughput) {
|
|
2092
|
+
out[model] = { tokensPerSec: tp.tokensPerSec, samples: tp.samples };
|
|
2093
|
+
}
|
|
2094
|
+
return out;
|
|
2095
|
+
}
|
|
2096
|
+
/** Tune the shared slot capacity at runtime (e.g. when Ollama pool resizes). */
|
|
2097
|
+
setSlotCapacity(n2) {
|
|
2098
|
+
this.slotCapacity = Math.max(1, Math.floor(n2));
|
|
2099
|
+
this.drainSlotQueue();
|
|
1893
2100
|
}
|
|
1894
2101
|
keyOf(spec) {
|
|
1895
2102
|
return `${spec.host}:${spec.name}`;
|
|
@@ -1899,6 +2106,115 @@ var init_model_broker = __esm({
|
|
|
1899
2106
|
}
|
|
1900
2107
|
});
|
|
1901
2108
|
|
|
2109
|
+
// packages/execution/dist/broker-mediated-backend.js
|
|
2110
|
+
function wrapWithBroker(backend, options2) {
|
|
2111
|
+
const broker = getModelBroker();
|
|
2112
|
+
const clamp7 = options2.clampNumCtx !== false;
|
|
2113
|
+
const wrapped = Object.create(backend);
|
|
2114
|
+
wrapped.chatCompletion = async (request) => {
|
|
2115
|
+
const model = backend.model || request.model || "unknown";
|
|
2116
|
+
let effectiveRequest = request;
|
|
2117
|
+
if (clamp7) {
|
|
2118
|
+
const trainCtx = await broker.getNctxTrain(model).catch(() => null);
|
|
2119
|
+
const requestedNumCtx = request.numCtx;
|
|
2120
|
+
if (trainCtx && trainCtx > 0) {
|
|
2121
|
+
const target = requestedNumCtx ? Math.min(requestedNumCtx, trainCtx) : Math.min(trainCtx, estimateContextNeed(request));
|
|
2122
|
+
if (target > 0) {
|
|
2123
|
+
effectiveRequest = { ...request, numCtx: target };
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
const promptTokens = estimatePromptTokens(request);
|
|
2128
|
+
const slot = await broker.acquireInferenceSlot({
|
|
2129
|
+
model,
|
|
2130
|
+
domain: options2.domain,
|
|
2131
|
+
owner: options2.owner,
|
|
2132
|
+
sessionKey: options2.sessionKey,
|
|
2133
|
+
promptTokens,
|
|
2134
|
+
priority: options2.priority ?? 0
|
|
2135
|
+
});
|
|
2136
|
+
try {
|
|
2137
|
+
const result = await backend.chatCompletion(effectiveRequest);
|
|
2138
|
+
const usage = result.usage;
|
|
2139
|
+
slot.release({ ok: true, completionTokens: usage?.completion_tokens ?? 0 });
|
|
2140
|
+
return result;
|
|
2141
|
+
} catch (err) {
|
|
2142
|
+
slot.release({ ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
2143
|
+
throw err;
|
|
2144
|
+
}
|
|
2145
|
+
};
|
|
2146
|
+
if (typeof backend.chatCompletionStream === "function") {
|
|
2147
|
+
const streamFn = backend.chatCompletionStream.bind(backend);
|
|
2148
|
+
wrapped.chatCompletionStream = async function* (request) {
|
|
2149
|
+
const model = backend.model || request.model || "unknown";
|
|
2150
|
+
let effectiveRequest = request;
|
|
2151
|
+
if (clamp7) {
|
|
2152
|
+
const trainCtx = await broker.getNctxTrain(model).catch(() => null);
|
|
2153
|
+
const requestedNumCtx = request.numCtx;
|
|
2154
|
+
if (trainCtx && trainCtx > 0) {
|
|
2155
|
+
const target = requestedNumCtx ? Math.min(requestedNumCtx, trainCtx) : Math.min(trainCtx, estimateContextNeed(request));
|
|
2156
|
+
if (target > 0)
|
|
2157
|
+
effectiveRequest = { ...request, numCtx: target };
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
const promptTokens = estimatePromptTokens(request);
|
|
2161
|
+
const slot = await broker.acquireInferenceSlot({
|
|
2162
|
+
model,
|
|
2163
|
+
domain: options2.domain,
|
|
2164
|
+
owner: options2.owner,
|
|
2165
|
+
sessionKey: options2.sessionKey,
|
|
2166
|
+
promptTokens,
|
|
2167
|
+
priority: options2.priority ?? 0
|
|
2168
|
+
});
|
|
2169
|
+
let completionTokens = 0;
|
|
2170
|
+
try {
|
|
2171
|
+
for await (const chunk of streamFn(effectiveRequest)) {
|
|
2172
|
+
const usage = chunk.usage;
|
|
2173
|
+
if (usage?.completion_tokens)
|
|
2174
|
+
completionTokens = usage.completion_tokens;
|
|
2175
|
+
yield chunk;
|
|
2176
|
+
}
|
|
2177
|
+
slot.release({ ok: true, completionTokens });
|
|
2178
|
+
} catch (err) {
|
|
2179
|
+
slot.release({ ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
2180
|
+
throw err;
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
return wrapped;
|
|
2185
|
+
}
|
|
2186
|
+
function estimatePromptTokens(request) {
|
|
2187
|
+
let chars = 0;
|
|
2188
|
+
if (Array.isArray(request?.messages)) {
|
|
2189
|
+
for (const m2 of request.messages) {
|
|
2190
|
+
if (typeof m2.content === "string")
|
|
2191
|
+
chars += m2.content.length;
|
|
2192
|
+
else if (Array.isArray(m2.content)) {
|
|
2193
|
+
for (const part of m2.content) {
|
|
2194
|
+
if (typeof part?.text === "string")
|
|
2195
|
+
chars += part.text.length;
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
chars += 8;
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
if (Array.isArray(request?.tools) && request.tools.length > 0) {
|
|
2202
|
+
chars += request.tools.length * 600;
|
|
2203
|
+
}
|
|
2204
|
+
return Math.ceil(chars / 4);
|
|
2205
|
+
}
|
|
2206
|
+
function estimateContextNeed(request) {
|
|
2207
|
+
const promptTokens = estimatePromptTokens(request);
|
|
2208
|
+
const maxTokens = request?.maxTokens ?? 1024;
|
|
2209
|
+
return Math.max(2048, promptTokens + maxTokens + 512);
|
|
2210
|
+
}
|
|
2211
|
+
var init_broker_mediated_backend = __esm({
|
|
2212
|
+
"packages/execution/dist/broker-mediated-backend.js"() {
|
|
2213
|
+
"use strict";
|
|
2214
|
+
init_model_broker();
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
|
|
1902
2218
|
// packages/execution/dist/tools/security-classifier.js
|
|
1903
2219
|
function classifyTool(name10) {
|
|
1904
2220
|
for (const rule of RULES) {
|
|
@@ -525416,6 +525732,7 @@ __export(dist_exports, {
|
|
|
525416
525732
|
videoGenerationQualityLadder: () => videoGenerationQualityLadder,
|
|
525417
525733
|
videoGenerationSetupPlan: () => videoGenerationSetupPlan,
|
|
525418
525734
|
worktreeHasChanges: () => worktreeHasChanges,
|
|
525735
|
+
wrapWithBroker: () => wrapWithBroker,
|
|
525419
525736
|
writeProvenanceFile: () => writeProvenanceFile,
|
|
525420
525737
|
writeTodos: () => writeTodos
|
|
525421
525738
|
});
|
|
@@ -525424,6 +525741,7 @@ var init_dist5 = __esm({
|
|
|
525424
525741
|
"use strict";
|
|
525425
525742
|
init_tool_executor();
|
|
525426
525743
|
init_model_broker();
|
|
525744
|
+
init_broker_mediated_backend();
|
|
525427
525745
|
init_security_classifier();
|
|
525428
525746
|
init_tool_manifest();
|
|
525429
525747
|
init_provenance();
|
|
@@ -555275,6 +555593,13 @@ ${description}`
|
|
|
555275
555593
|
if (responseFormat !== void 0) {
|
|
555276
555594
|
body["response_format"] = responseFormat;
|
|
555277
555595
|
}
|
|
555596
|
+
const reqNumCtx = request.numCtx;
|
|
555597
|
+
if (Number.isFinite(reqNumCtx) && (reqNumCtx ?? 0) > 0) {
|
|
555598
|
+
const opts = body["options"] ?? {};
|
|
555599
|
+
opts["num_ctx"] = reqNumCtx;
|
|
555600
|
+
body["options"] = opts;
|
|
555601
|
+
body["num_ctx"] = reqNumCtx;
|
|
555602
|
+
}
|
|
555278
555603
|
let poolSlot = shouldUseOllamaPoolForBaseUrl(this.baseUrl) ? await getOllamaPool({ baseInstanceUrl: this.baseUrl }).acquire({
|
|
555279
555604
|
model: this.model
|
|
555280
555605
|
}) : null;
|
|
@@ -615178,6 +615503,300 @@ var init_stimulation = __esm({
|
|
|
615178
615503
|
}
|
|
615179
615504
|
});
|
|
615180
615505
|
|
|
615506
|
+
// packages/cli/src/tui/pid-controller.ts
|
|
615507
|
+
function clamp018(x) {
|
|
615508
|
+
if (!Number.isFinite(x)) return 0;
|
|
615509
|
+
if (x < 0) return 0;
|
|
615510
|
+
if (x > 1) return 1;
|
|
615511
|
+
return x;
|
|
615512
|
+
}
|
|
615513
|
+
function getPidRegistry() {
|
|
615514
|
+
if (!_registry2) _registry2 = new PidRegistry();
|
|
615515
|
+
return _registry2;
|
|
615516
|
+
}
|
|
615517
|
+
var DEFAULT_PID_CONFIG, PidRegistry, _registry2;
|
|
615518
|
+
var init_pid_controller = __esm({
|
|
615519
|
+
"packages/cli/src/tui/pid-controller.ts"() {
|
|
615520
|
+
"use strict";
|
|
615521
|
+
DEFAULT_PID_CONFIG = {
|
|
615522
|
+
kp: 1e-4,
|
|
615523
|
+
ki: 1e-5,
|
|
615524
|
+
kd: 0,
|
|
615525
|
+
setpointMs: 8e3,
|
|
615526
|
+
initialOutput: 1,
|
|
615527
|
+
pvEmaAlpha: 0.3,
|
|
615528
|
+
integralClamp: 5e3
|
|
615529
|
+
// ms*s — bounds integral term contribution
|
|
615530
|
+
};
|
|
615531
|
+
PidRegistry = class {
|
|
615532
|
+
_controllers = /* @__PURE__ */ new Map();
|
|
615533
|
+
/** Get or create a controller. */
|
|
615534
|
+
get(key, configOverride) {
|
|
615535
|
+
let st = this._controllers.get(key);
|
|
615536
|
+
if (!st) {
|
|
615537
|
+
const config = { ...DEFAULT_PID_CONFIG, ...configOverride ?? {} };
|
|
615538
|
+
st = {
|
|
615539
|
+
output: config.initialOutput,
|
|
615540
|
+
pv: config.setpointMs,
|
|
615541
|
+
// assume on-target at startup
|
|
615542
|
+
integral: 0,
|
|
615543
|
+
lastError: 0,
|
|
615544
|
+
lastSampleAt: 0,
|
|
615545
|
+
samples: 0,
|
|
615546
|
+
config
|
|
615547
|
+
};
|
|
615548
|
+
this._controllers.set(key, st);
|
|
615549
|
+
}
|
|
615550
|
+
return st;
|
|
615551
|
+
}
|
|
615552
|
+
/** Read-only current output (inclusion ratio in [0,1]). */
|
|
615553
|
+
output(key) {
|
|
615554
|
+
return this._controllers.get(key)?.output ?? DEFAULT_PID_CONFIG.initialOutput;
|
|
615555
|
+
}
|
|
615556
|
+
/**
|
|
615557
|
+
* Record a new latency sample (in ms) and update the controller.
|
|
615558
|
+
* Returns the new output value.
|
|
615559
|
+
*/
|
|
615560
|
+
sample(key, latencyMs, configOverride) {
|
|
615561
|
+
const st = this.get(key, configOverride);
|
|
615562
|
+
const now = Date.now();
|
|
615563
|
+
st.pv = st.samples === 0 ? latencyMs : st.pv * (1 - st.config.pvEmaAlpha) + latencyMs * st.config.pvEmaAlpha;
|
|
615564
|
+
const error = st.config.setpointMs - st.pv;
|
|
615565
|
+
st.integral += error;
|
|
615566
|
+
if (st.integral > st.config.integralClamp) st.integral = st.config.integralClamp;
|
|
615567
|
+
if (st.integral < -st.config.integralClamp) st.integral = -st.config.integralClamp;
|
|
615568
|
+
const dt = st.lastSampleAt > 0 ? now - st.lastSampleAt : 1e3;
|
|
615569
|
+
const derivative = dt > 0 ? (error - st.lastError) / dt : 0;
|
|
615570
|
+
const u = st.config.kp * error + st.config.ki * st.integral + st.config.kd * derivative;
|
|
615571
|
+
st.output = clamp018(st.output + u);
|
|
615572
|
+
st.lastError = error;
|
|
615573
|
+
st.lastSampleAt = now;
|
|
615574
|
+
st.samples += 1;
|
|
615575
|
+
return st.output;
|
|
615576
|
+
}
|
|
615577
|
+
/** All controller snapshots — for /broker debug surface. */
|
|
615578
|
+
snapshot() {
|
|
615579
|
+
return [...this._controllers.entries()].map(([key, st]) => ({
|
|
615580
|
+
key,
|
|
615581
|
+
output: st.output,
|
|
615582
|
+
pv: st.pv,
|
|
615583
|
+
setpoint: st.config.setpointMs,
|
|
615584
|
+
samples: st.samples
|
|
615585
|
+
}));
|
|
615586
|
+
}
|
|
615587
|
+
/** Reset (test-only). */
|
|
615588
|
+
reset() {
|
|
615589
|
+
this._controllers.clear();
|
|
615590
|
+
}
|
|
615591
|
+
};
|
|
615592
|
+
_registry2 = null;
|
|
615593
|
+
}
|
|
615594
|
+
});
|
|
615595
|
+
|
|
615596
|
+
// packages/cli/src/tui/component-benefit.ts
|
|
615597
|
+
function getComponentBenefitRegistry() {
|
|
615598
|
+
if (!_registry3) _registry3 = new ComponentBenefitRegistry();
|
|
615599
|
+
return _registry3;
|
|
615600
|
+
}
|
|
615601
|
+
var EMA_ALPHA, MIN_SAMPLES_TO_TRUST, ComponentBenefitRegistry, _registry3;
|
|
615602
|
+
var init_component_benefit = __esm({
|
|
615603
|
+
"packages/cli/src/tui/component-benefit.ts"() {
|
|
615604
|
+
"use strict";
|
|
615605
|
+
EMA_ALPHA = 0.2;
|
|
615606
|
+
MIN_SAMPLES_TO_TRUST = 3;
|
|
615607
|
+
ComponentBenefitRegistry = class {
|
|
615608
|
+
/** Two-tier map: chatKey → componentKey → state. */
|
|
615609
|
+
_byChat = /* @__PURE__ */ new Map();
|
|
615610
|
+
/** Score for a component in a chat. Returns 0.5 (neutral) when not enough samples. */
|
|
615611
|
+
score(chatKey, componentKey) {
|
|
615612
|
+
const st = this._byChat.get(chatKey)?.get(componentKey);
|
|
615613
|
+
if (!st || st.samples < MIN_SAMPLES_TO_TRUST) return 0.5;
|
|
615614
|
+
return st.score;
|
|
615615
|
+
}
|
|
615616
|
+
/** Record one batch — for each sampled component, did the decision text reference its needle? */
|
|
615617
|
+
recordOutcome(chatKey, samples, decisionText) {
|
|
615618
|
+
const haystack = decisionText.toLowerCase();
|
|
615619
|
+
let map2 = this._byChat.get(chatKey);
|
|
615620
|
+
if (!map2) {
|
|
615621
|
+
map2 = /* @__PURE__ */ new Map();
|
|
615622
|
+
this._byChat.set(chatKey, map2);
|
|
615623
|
+
}
|
|
615624
|
+
const now = Date.now();
|
|
615625
|
+
for (const sample of samples) {
|
|
615626
|
+
const needle = sample.needle.toLowerCase();
|
|
615627
|
+
const hit = needle.length >= 3 && haystack.includes(needle);
|
|
615628
|
+
let st = map2.get(sample.key);
|
|
615629
|
+
if (!st) {
|
|
615630
|
+
st = { score: 0.5, samples: 0, hits: 0, lastSeenAt: now };
|
|
615631
|
+
map2.set(sample.key, st);
|
|
615632
|
+
}
|
|
615633
|
+
const newScore = hit ? 1 : 0;
|
|
615634
|
+
st.score = st.samples === 0 ? newScore : st.score * (1 - EMA_ALPHA) + newScore * EMA_ALPHA;
|
|
615635
|
+
st.samples += 1;
|
|
615636
|
+
st.hits += hit ? 1 : 0;
|
|
615637
|
+
st.lastSeenAt = now;
|
|
615638
|
+
}
|
|
615639
|
+
}
|
|
615640
|
+
/** Snapshot for /broker debug surface. */
|
|
615641
|
+
snapshot(chatKey) {
|
|
615642
|
+
const out = [];
|
|
615643
|
+
const iterate = chatKey ? [[chatKey, this._byChat.get(chatKey)]].filter((e2) => !!e2[1]) : [...this._byChat.entries()];
|
|
615644
|
+
for (const [cKey, map2] of iterate) {
|
|
615645
|
+
for (const [comp, st] of map2) {
|
|
615646
|
+
out.push({ chatKey: cKey, componentKey: comp, score: st.score, samples: st.samples, hits: st.hits });
|
|
615647
|
+
}
|
|
615648
|
+
}
|
|
615649
|
+
return out;
|
|
615650
|
+
}
|
|
615651
|
+
reset() {
|
|
615652
|
+
this._byChat.clear();
|
|
615653
|
+
}
|
|
615654
|
+
};
|
|
615655
|
+
_registry3 = null;
|
|
615656
|
+
}
|
|
615657
|
+
});
|
|
615658
|
+
|
|
615659
|
+
// packages/cli/src/tui/soul-observations.ts
|
|
615660
|
+
function getSoulObservationStream() {
|
|
615661
|
+
if (!_stream) {
|
|
615662
|
+
_stream = new SoulObservationStream();
|
|
615663
|
+
subscribeBrokerEvents(_stream);
|
|
615664
|
+
}
|
|
615665
|
+
return _stream;
|
|
615666
|
+
}
|
|
615667
|
+
function subscribeBrokerEvents(stream) {
|
|
615668
|
+
if (_brokerSubscribed) return;
|
|
615669
|
+
_brokerSubscribed = true;
|
|
615670
|
+
const broker = getModelBroker();
|
|
615671
|
+
broker.on("slotReleased", (info, outcome) => {
|
|
615672
|
+
if (outcome.ok) {
|
|
615673
|
+
stream.emit({
|
|
615674
|
+
kind: "inference.completed",
|
|
615675
|
+
model: info.model,
|
|
615676
|
+
sessionKey: info.sessionKey,
|
|
615677
|
+
latencyMs: Date.now() - info.acquiredAt,
|
|
615678
|
+
promptTokens: info.promptTokens,
|
|
615679
|
+
completionTokens: outcome.completionTokens ?? 0,
|
|
615680
|
+
ts: Date.now()
|
|
615681
|
+
});
|
|
615682
|
+
} else {
|
|
615683
|
+
stream.emit({
|
|
615684
|
+
kind: "inference.degraded",
|
|
615685
|
+
model: info.model,
|
|
615686
|
+
sessionKey: info.sessionKey,
|
|
615687
|
+
reason: outcome.error ?? "unknown",
|
|
615688
|
+
ts: Date.now()
|
|
615689
|
+
});
|
|
615690
|
+
}
|
|
615691
|
+
});
|
|
615692
|
+
broker.on("pressure", (kind, value2, threshold) => {
|
|
615693
|
+
stream.emit({ kind: "broker.pressure", pressure: kind, value: value2, threshold, ts: Date.now() });
|
|
615694
|
+
});
|
|
615695
|
+
broker.on("evicted", (m2, reason) => {
|
|
615696
|
+
stream.emit({ kind: "model.evicted", host: m2.host, name: m2.name, reason, ts: Date.now() });
|
|
615697
|
+
});
|
|
615698
|
+
}
|
|
615699
|
+
function formatSystemObservations(sessionKey) {
|
|
615700
|
+
const stream = getSoulObservationStream();
|
|
615701
|
+
const broker = getModelBroker();
|
|
615702
|
+
const snap = broker.snapshot();
|
|
615703
|
+
const pidSnap = getPidRegistry().snapshot();
|
|
615704
|
+
const lines = [];
|
|
615705
|
+
const slots = snap.slots;
|
|
615706
|
+
const utilPct = slots.capacity > 0 ? Math.round(slots.inUse / slots.capacity * 100) : 0;
|
|
615707
|
+
const tpsByModel = Object.entries(slots.byModel).filter(([, m2]) => m2.samples > 0).map(([model, m2]) => `${model}=${m2.tokensPerSec.toFixed(1)}t/s (${m2.samples}s)`).join(", ");
|
|
615708
|
+
if (slots.inUse > 0 || slots.queueDepth > 0 || tpsByModel) {
|
|
615709
|
+
lines.push(`Capacity: ${slots.inUse}/${slots.capacity} slots in use (${utilPct}%), queue=${slots.queueDepth}/${slots.queueCapacity}${tpsByModel ? `; throughput: ${tpsByModel}` : ""}.`);
|
|
615710
|
+
}
|
|
615711
|
+
if (snap.ramMB.free < (broker.ramHeadroomMB ?? 0)) {
|
|
615712
|
+
lines.push(`RAM pressure: ${snap.ramMB.free}MB free (below ${broker.ramHeadroomMB}MB headroom).`);
|
|
615713
|
+
}
|
|
615714
|
+
if (snap.vramMB && snap.vramMB.free < (broker.vramHeadroomMB ?? 0)) {
|
|
615715
|
+
lines.push(`VRAM pressure: ${snap.vramMB.free}MB free (below ${broker.vramHeadroomMB}MB headroom).`);
|
|
615716
|
+
}
|
|
615717
|
+
const queueThreshold = Math.floor(snap.slots.queueCapacity * 0.8);
|
|
615718
|
+
if (snap.slots.queueDepth >= queueThreshold) {
|
|
615719
|
+
lines.push(`Queue pressure: ${snap.slots.queueDepth}/${snap.slots.queueCapacity} entries — prefer brief replies or single-emoji reactions to keep the queue draining.`);
|
|
615720
|
+
}
|
|
615721
|
+
const interesting = pidSnap.filter((p2) => p2.samples >= 3 && (p2.output < 0.95 || p2.output > 1.05));
|
|
615722
|
+
if (interesting.length > 0) {
|
|
615723
|
+
const pidLines = interesting.slice(0, 4).map((p2) => `${p2.key}: u=${p2.output.toFixed(2)} (pv=${Math.round(p2.pv)}ms, sp=${p2.setpoint}ms)`).join(", ");
|
|
615724
|
+
lines.push(`Context tier PID state: ${pidLines}.`);
|
|
615725
|
+
}
|
|
615726
|
+
if (sessionKey) {
|
|
615727
|
+
const recent = stream.recentForSession(sessionKey, 15);
|
|
615728
|
+
if (recent.length > 0) {
|
|
615729
|
+
const sends = recent.filter((e2) => e2.kind.startsWith("telegram.send."));
|
|
615730
|
+
const reactions = recent.filter((e2) => e2.kind.startsWith("emoji."));
|
|
615731
|
+
const forbidden = sends.filter((e2) => e2.kind === "telegram.send.forbidden").length;
|
|
615732
|
+
const rateLimited = sends.filter((e2) => e2.kind === "telegram.send.rate_limited").length;
|
|
615733
|
+
if (forbidden > 0) lines.push(`This chat has refused ${forbidden} recent send attempt(s) (e.g. no rights to post). Treat as a strong silence signal.`);
|
|
615734
|
+
if (rateLimited > 0) lines.push(`This chat rate-limited ${rateLimited} recent send(s). Slow cadence.`);
|
|
615735
|
+
if (reactions.length > 0) {
|
|
615736
|
+
const reactSummary = reactions.filter((e2) => e2.kind === "emoji.reaction.received").map((e2) => e2.emoji).join("");
|
|
615737
|
+
if (reactSummary) lines.push(`Recent inbound reactions in this chat: ${reactSummary}`);
|
|
615738
|
+
}
|
|
615739
|
+
}
|
|
615740
|
+
}
|
|
615741
|
+
if (lines.length === 0) return "";
|
|
615742
|
+
return ["## System Observations (broker, PID, capacity, send outcomes)", ...lines].join("\n");
|
|
615743
|
+
}
|
|
615744
|
+
var PER_SESSION_BUFFER, GLOBAL_BUFFER, SoulObservationStream, _stream, _brokerSubscribed;
|
|
615745
|
+
var init_soul_observations = __esm({
|
|
615746
|
+
"packages/cli/src/tui/soul-observations.ts"() {
|
|
615747
|
+
"use strict";
|
|
615748
|
+
init_dist5();
|
|
615749
|
+
init_pid_controller();
|
|
615750
|
+
PER_SESSION_BUFFER = 60;
|
|
615751
|
+
GLOBAL_BUFFER = 200;
|
|
615752
|
+
SoulObservationStream = class {
|
|
615753
|
+
_bySession = /* @__PURE__ */ new Map();
|
|
615754
|
+
_global = [];
|
|
615755
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
615756
|
+
/** Record an event. */
|
|
615757
|
+
emit(event) {
|
|
615758
|
+
if ("sessionKey" in event && event.sessionKey) {
|
|
615759
|
+
let buf = this._bySession.get(event.sessionKey);
|
|
615760
|
+
if (!buf) {
|
|
615761
|
+
buf = [];
|
|
615762
|
+
this._bySession.set(event.sessionKey, buf);
|
|
615763
|
+
}
|
|
615764
|
+
buf.push(event);
|
|
615765
|
+
if (buf.length > PER_SESSION_BUFFER) buf.shift();
|
|
615766
|
+
}
|
|
615767
|
+
this._global.push(event);
|
|
615768
|
+
if (this._global.length > GLOBAL_BUFFER) this._global.shift();
|
|
615769
|
+
for (const listener of this._listeners) {
|
|
615770
|
+
try {
|
|
615771
|
+
listener(event);
|
|
615772
|
+
} catch {
|
|
615773
|
+
}
|
|
615774
|
+
}
|
|
615775
|
+
}
|
|
615776
|
+
/** Subscribe to all events (live tail). */
|
|
615777
|
+
subscribe(listener) {
|
|
615778
|
+
this._listeners.add(listener);
|
|
615779
|
+
return () => this._listeners.delete(listener);
|
|
615780
|
+
}
|
|
615781
|
+
/** Read recent events for a session (most recent last). */
|
|
615782
|
+
recentForSession(sessionKey, limit = 20) {
|
|
615783
|
+
const buf = this._bySession.get(sessionKey) ?? [];
|
|
615784
|
+
return buf.slice(-limit);
|
|
615785
|
+
}
|
|
615786
|
+
/** Read recent global events. */
|
|
615787
|
+
recentGlobal(limit = 30) {
|
|
615788
|
+
return this._global.slice(-limit);
|
|
615789
|
+
}
|
|
615790
|
+
reset() {
|
|
615791
|
+
this._bySession.clear();
|
|
615792
|
+
this._global.length = 0;
|
|
615793
|
+
}
|
|
615794
|
+
};
|
|
615795
|
+
_stream = null;
|
|
615796
|
+
_brokerSubscribed = false;
|
|
615797
|
+
}
|
|
615798
|
+
});
|
|
615799
|
+
|
|
615181
615800
|
// packages/cli/src/tui/telegram-channel-dmn.ts
|
|
615182
615801
|
import { existsSync as existsSync115, mkdirSync as mkdirSync65, readdirSync as readdirSync40, readFileSync as readFileSync94, writeFileSync as writeFileSync59 } from "node:fs";
|
|
615183
615802
|
import { join as join129 } from "node:path";
|
|
@@ -615276,7 +615895,7 @@ function buildReplyOpportunities(input, openQuestions) {
|
|
|
615276
615895
|
function daydreamOpportunityId(input, trigger) {
|
|
615277
615896
|
return createHash23("sha1").update(`${input.sessionKey}:${input.generatedAtMs}:${trigger}`).digest("hex").slice(0, 16);
|
|
615278
615897
|
}
|
|
615279
|
-
function
|
|
615898
|
+
function clamp019(value2) {
|
|
615280
615899
|
if (!Number.isFinite(value2)) return 0;
|
|
615281
615900
|
return Math.max(0, Math.min(1, value2));
|
|
615282
615901
|
}
|
|
@@ -615287,7 +615906,7 @@ function pushStimulationSignal(signals, signal, source, weight) {
|
|
|
615287
615906
|
const cleanSignal = compactLine2(signal, 120);
|
|
615288
615907
|
const cleanSource = compactLine2(source, 180);
|
|
615289
615908
|
if (!cleanSignal || signals.some((entry) => entry.signal === cleanSignal && entry.source === cleanSource)) return;
|
|
615290
|
-
signals.push({ signal: cleanSignal, source: cleanSource, weight:
|
|
615909
|
+
signals.push({ signal: cleanSignal, source: cleanSource, weight: clamp019(weight) });
|
|
615291
615910
|
}
|
|
615292
615911
|
function buildMetaAnalysisSignals(input) {
|
|
615293
615912
|
const chatLabel = input.chatTitle || input.chatId;
|
|
@@ -615362,7 +615981,7 @@ function buildCuriosityThreads(input, openQuestions, stimulationSignals) {
|
|
|
615362
615981
|
question: text.endsWith("?") || text.endsWith("?") ? text : `What should be learned or clarified from: ${text || entry.mediaSummary || "recent media"}?`,
|
|
615363
615982
|
rationale: "Human curiosity, uncertainty, or multimodal content makes this a useful idle exploration target.",
|
|
615364
615983
|
sourceMessages: messageId,
|
|
615365
|
-
intensity:
|
|
615984
|
+
intensity: clamp019(0.5 + replyBoost + mediaBoost + questionBoost)
|
|
615366
615985
|
});
|
|
615367
615986
|
}
|
|
615368
615987
|
for (const question of openQuestions.slice(-4)) {
|
|
@@ -615382,7 +616001,7 @@ function buildCuriosityThreads(input, openQuestions, stimulationSignals) {
|
|
|
615382
616001
|
question: `Is there a useful clarification or memory consolidation around ${strongest.source}?`,
|
|
615383
616002
|
rationale: "Strongest stimulation signal can seed a low-intrusion reflection target.",
|
|
615384
616003
|
sourceMessages: [],
|
|
615385
|
-
intensity:
|
|
616004
|
+
intensity: clamp019(strongest.weight * 0.72)
|
|
615386
616005
|
});
|
|
615387
616006
|
}
|
|
615388
616007
|
return threads.sort((a2, b) => b.intensity - a2.intensity).slice(0, 8);
|
|
@@ -615456,7 +616075,7 @@ function buildOutreachPlans(input, curiosityThreads) {
|
|
|
615456
616075
|
purpose: "Continue the public thread only when the live model judges that the group would benefit from a concise follow-up.",
|
|
615457
616076
|
draftIntent: "Ask one concrete clarification, offer one useful synthesis, or stay silent if the room has moved on.",
|
|
615458
616077
|
gate: "model_decision",
|
|
615459
|
-
confidence:
|
|
616078
|
+
confidence: clamp019(thread.intensity * 0.86)
|
|
615460
616079
|
});
|
|
615461
616080
|
const participant = participantForThread(input, thread);
|
|
615462
616081
|
if (!participant) continue;
|
|
@@ -615468,7 +616087,7 @@ function buildOutreachPlans(input, curiosityThreads) {
|
|
|
615468
616087
|
purpose: "Offer a one-to-one follow-up only if private contact is allowed and the issue is personal, unresolved, or better handled outside the group.",
|
|
615469
616088
|
draftIntent: "Reference the public thread briefly, ask permission to continue privately, and do not reveal hidden meta-analysis.",
|
|
615470
616089
|
gate: "admin_review",
|
|
615471
|
-
confidence:
|
|
616090
|
+
confidence: clamp019(thread.intensity * 0.58)
|
|
615472
616091
|
});
|
|
615473
616092
|
}
|
|
615474
616093
|
return plans.slice(0, 8);
|
|
@@ -616571,7 +617190,7 @@ function numberOr(value2, fallback) {
|
|
|
616571
617190
|
function isNumber(value2) {
|
|
616572
617191
|
return typeof value2 === "number" && Number.isFinite(value2);
|
|
616573
617192
|
}
|
|
616574
|
-
function
|
|
617193
|
+
function clamp0110(value2) {
|
|
616575
617194
|
return Math.max(0, Math.min(1, Number.isFinite(value2) ? value2 : 0));
|
|
616576
617195
|
}
|
|
616577
617196
|
function iso(ts) {
|
|
@@ -616718,8 +617337,8 @@ function normalizeRelationship(raw) {
|
|
|
616718
617337
|
kind: value2.kind,
|
|
616719
617338
|
fromKey: String(value2.fromKey),
|
|
616720
617339
|
toKey: String(value2.toKey),
|
|
616721
|
-
confidence:
|
|
616722
|
-
weight:
|
|
617340
|
+
confidence: clamp0110(numberOr(value2.confidence, 0)),
|
|
617341
|
+
weight: clamp0110(numberOr(value2.weight, 0)),
|
|
616723
617342
|
firstSeenAt: numberOr(value2.firstSeenAt, Date.now()),
|
|
616724
617343
|
lastSeenAt: numberOr(value2.lastSeenAt, Date.now()),
|
|
616725
617344
|
evidenceMessageIds: Array.isArray(value2.evidenceMessageIds) ? value2.evidenceMessageIds.filter(isNumber).slice(-40) : [],
|
|
@@ -616738,7 +617357,7 @@ function normalizePreferences(raw) {
|
|
|
616738
617357
|
if (!evidence || typeof evidence !== "object") continue;
|
|
616739
617358
|
out[actorKey][key] = {
|
|
616740
617359
|
value: Math.max(-1, Math.min(1, numberOr(evidence.value, 0))),
|
|
616741
|
-
confidence:
|
|
617360
|
+
confidence: clamp0110(numberOr(evidence.confidence, 0)),
|
|
616742
617361
|
updatedAt: numberOr(evidence.updatedAt, Date.now()),
|
|
616743
617362
|
evidenceMessageIds: Array.isArray(evidence.evidenceMessageIds) ? evidence.evidenceMessageIds.filter(isNumber).slice(-12) : [],
|
|
616744
617363
|
note: compactOptional(evidence.note, 220)
|
|
@@ -616796,7 +617415,7 @@ function normalizeOutcome(raw) {
|
|
|
616796
617415
|
replyToMessageId: typeof value2.replyToMessageId === "number" ? value2.replyToMessageId : void 0,
|
|
616797
617416
|
route: value2.route === "action" ? "action" : "chat",
|
|
616798
617417
|
shouldReply: value2.shouldReply === true,
|
|
616799
|
-
confidence:
|
|
617418
|
+
confidence: clamp0110(numberOr(value2.confidence, 0)),
|
|
616800
617419
|
reason: compact2(value2.reason || "", 280),
|
|
616801
617420
|
source: compact2(value2.source || "unknown", 80),
|
|
616802
617421
|
silentDisposition: compactOptional(value2.silentDisposition, 280),
|
|
@@ -616808,7 +617427,7 @@ function normalizeOutcome(raw) {
|
|
|
616808
617427
|
scenarioNote: compactOptional(value2.scenarioNote, 360),
|
|
616809
617428
|
scenarioId: compactOptional(value2.scenarioId, 160),
|
|
616810
617429
|
scenarioLabel: compactOptional(value2.scenarioLabel, 160),
|
|
616811
|
-
scenarioConfidence: typeof value2.scenarioConfidence === "number" && Number.isFinite(value2.scenarioConfidence) ?
|
|
617430
|
+
scenarioConfidence: typeof value2.scenarioConfidence === "number" && Number.isFinite(value2.scenarioConfidence) ? clamp0110(value2.scenarioConfidence) : void 0,
|
|
616812
617431
|
scenarioObjective: compactOptional(value2.scenarioObjective, 360),
|
|
616813
617432
|
scenarioStateLoop: compactOptional(value2.scenarioStateLoop, 360),
|
|
616814
617433
|
salienceSignals: Array.isArray(value2.salienceSignals) ? value2.salienceSignals.map(String).slice(0, 16) : [],
|
|
@@ -616826,7 +617445,7 @@ function normalizeDaydreamOpportunity(raw) {
|
|
|
616826
617445
|
artifactId: String(value2.artifactId || "unknown"),
|
|
616827
617446
|
generatedAt: String(value2.generatedAt || (/* @__PURE__ */ new Date()).toISOString()),
|
|
616828
617447
|
trigger: compact2(value2.trigger || "", 240),
|
|
616829
|
-
confidence:
|
|
617448
|
+
confidence: clamp0110(numberOr(value2.confidence, 0)),
|
|
616830
617449
|
lifecycle,
|
|
616831
617450
|
firstSeenAt: numberOr(value2.firstSeenAt, Date.now()),
|
|
616832
617451
|
updatedAt: numberOr(value2.updatedAt, Date.now()),
|
|
@@ -616883,7 +617502,7 @@ function commitTelegramSocialDecision(state, input) {
|
|
|
616883
617502
|
replyToMessageId: input.replyToMessageId,
|
|
616884
617503
|
route: input.route,
|
|
616885
617504
|
shouldReply: input.shouldReply,
|
|
616886
|
-
confidence:
|
|
617505
|
+
confidence: clamp0110(input.confidence),
|
|
616887
617506
|
reason: compact2(input.reason, 280),
|
|
616888
617507
|
source: compact2(input.source, 80),
|
|
616889
617508
|
silentDisposition: compactOptional(input.silentDisposition, 280),
|
|
@@ -616895,7 +617514,7 @@ function commitTelegramSocialDecision(state, input) {
|
|
|
616895
617514
|
scenarioNote: compactOptional(input.scenarioNote, 360),
|
|
616896
617515
|
scenarioId: compactOptional(input.scenarioId, 160),
|
|
616897
617516
|
scenarioLabel: compactOptional(input.scenarioLabel, 160),
|
|
616898
|
-
scenarioConfidence: input.scenarioConfidence === void 0 ? void 0 :
|
|
617517
|
+
scenarioConfidence: input.scenarioConfidence === void 0 ? void 0 : clamp0110(input.scenarioConfidence),
|
|
616899
617518
|
scenarioObjective: compactOptional(input.scenarioObjective, 360),
|
|
616900
617519
|
scenarioStateLoop: compactOptional(input.scenarioStateLoop, 360),
|
|
616901
617520
|
salienceSignals: [...new Set((input.salienceSignals ?? []).map(String))].slice(0, 16),
|
|
@@ -616919,7 +617538,7 @@ function registerDaydreamOpportunities(state, opportunities, now = Date.now()) {
|
|
|
616919
617538
|
artifactId: opportunity.artifactId || "unknown",
|
|
616920
617539
|
generatedAt: opportunity.generatedAt || new Date(now).toISOString(),
|
|
616921
617540
|
trigger: compact2(opportunity.trigger, 240),
|
|
616922
|
-
confidence:
|
|
617541
|
+
confidence: clamp0110(opportunity.confidence),
|
|
616923
617542
|
lifecycle: "proposed",
|
|
616924
617543
|
firstSeenAt: now,
|
|
616925
617544
|
updatedAt: now,
|
|
@@ -616929,7 +617548,7 @@ function registerDaydreamOpportunities(state, opportunities, now = Date.now()) {
|
|
|
616929
617548
|
};
|
|
616930
617549
|
if (existing) {
|
|
616931
617550
|
item.trigger = compact2(opportunity.trigger, 240) || item.trigger;
|
|
616932
|
-
item.confidence =
|
|
617551
|
+
item.confidence = clamp0110(opportunity.confidence);
|
|
616933
617552
|
item.updatedAt = now;
|
|
616934
617553
|
}
|
|
616935
617554
|
state.daydreamOpportunities[id] = item;
|
|
@@ -617069,8 +617688,8 @@ function upsertRelationship(state, kind, fromKey, toKey, messageId, confidence2,
|
|
|
617069
617688
|
evidenceMessageIds: [],
|
|
617070
617689
|
source
|
|
617071
617690
|
};
|
|
617072
|
-
edge.confidence = Math.max(edge.confidence,
|
|
617073
|
-
edge.weight = Math.min(1, edge.weight + 0.12 +
|
|
617691
|
+
edge.confidence = Math.max(edge.confidence, clamp0110(confidence2));
|
|
617692
|
+
edge.weight = Math.min(1, edge.weight + 0.12 + clamp0110(confidence2) * 0.2);
|
|
617074
617693
|
edge.lastSeenAt = now;
|
|
617075
617694
|
edge.evidenceMessageIds = appendUnique(edge.evidenceMessageIds, messageId, 40);
|
|
617076
617695
|
edge.note = compactOptional(note, 260) || edge.note;
|
|
@@ -617112,7 +617731,7 @@ function setPreference(vector, key, value2, confidence2, messageId, now, note) {
|
|
|
617112
617731
|
const existing = vector[key];
|
|
617113
617732
|
vector[key] = {
|
|
617114
617733
|
value: existing ? existing.value * 0.7 + value2 * 0.3 : value2,
|
|
617115
|
-
confidence: Math.max(existing?.confidence ?? 0,
|
|
617734
|
+
confidence: Math.max(existing?.confidence ?? 0, clamp0110(confidence2)),
|
|
617116
617735
|
updatedAt: now,
|
|
617117
617736
|
evidenceMessageIds: appendUnique(existing?.evidenceMessageIds ?? [], messageId, 12),
|
|
617118
617737
|
note
|
|
@@ -617503,9 +618122,31 @@ function parseTelegramSilentReflectionNotes(text) {
|
|
|
617503
618122
|
}
|
|
617504
618123
|
return null;
|
|
617505
618124
|
}
|
|
617506
|
-
function
|
|
617507
|
-
|
|
617508
|
-
|
|
618125
|
+
function estimatePromptTokensFromRequest(request) {
|
|
618126
|
+
let chars = 0;
|
|
618127
|
+
for (const m2 of request.messages ?? []) {
|
|
618128
|
+
if (typeof m2.content === "string") chars += m2.content.length;
|
|
618129
|
+
else if (Array.isArray(m2.content)) {
|
|
618130
|
+
for (const part of m2.content) {
|
|
618131
|
+
if (typeof part?.text === "string") chars += part.text.length;
|
|
618132
|
+
}
|
|
618133
|
+
}
|
|
618134
|
+
chars += 8;
|
|
618135
|
+
}
|
|
618136
|
+
if (Array.isArray(request.tools) && request.tools.length > 0) {
|
|
618137
|
+
chars += request.tools.length * 600;
|
|
618138
|
+
}
|
|
618139
|
+
return Math.ceil(chars / 4);
|
|
618140
|
+
}
|
|
618141
|
+
function telegramRouterTimeoutMs(configTimeoutMs, _minMs, _legacyMaxMs) {
|
|
618142
|
+
void _minMs;
|
|
618143
|
+
void _legacyMaxMs;
|
|
618144
|
+
const envRaw = Number.parseInt(process.env["OMNIUS_TG_INFERENCE_LIVENESS_MS"] ?? "", 10);
|
|
618145
|
+
const livenessMs = Number.isFinite(envRaw) && envRaw >= 1e4 ? envRaw : 6e5;
|
|
618146
|
+
if (Number.isFinite(configTimeoutMs) && (configTimeoutMs ?? 0) >= livenessMs) {
|
|
618147
|
+
return configTimeoutMs;
|
|
618148
|
+
}
|
|
618149
|
+
return livenessMs;
|
|
617509
618150
|
}
|
|
617510
618151
|
function telegramThinkSuppressedRequest(request) {
|
|
617511
618152
|
const messages2 = Array.isArray(request.messages) ? request.messages.slice() : [];
|
|
@@ -618960,6 +619601,9 @@ var init_telegram_bridge = __esm({
|
|
|
618960
619601
|
init_telegram_creative_tools();
|
|
618961
619602
|
init_omnius_directory();
|
|
618962
619603
|
init_stimulation();
|
|
619604
|
+
init_pid_controller();
|
|
619605
|
+
init_component_benefit();
|
|
619606
|
+
init_soul_observations();
|
|
618963
619607
|
init_identity_memory_tool();
|
|
618964
619608
|
init_visual_identity_association();
|
|
618965
619609
|
init_telegram_channel_dmn();
|
|
@@ -622925,6 +623569,12 @@ ${lines.join("\n")}`);
|
|
|
622925
623569
|
this.ensureTelegramConversationLoaded(sessionKey);
|
|
622926
623570
|
const history = this.chatHistory.get(sessionKey) ?? [];
|
|
622927
623571
|
const participants = [...this.chatParticipants.get(sessionKey)?.values() ?? []].sort((a2, b) => b.lastSeenTs - a2.lastSeenTs);
|
|
623572
|
+
const modelKey = this.agentConfig?.model ?? "?";
|
|
623573
|
+
const pidReg = getPidRegistry();
|
|
623574
|
+
const tier1Ratio = pidReg.output(`tier1.${modelKey}`);
|
|
623575
|
+
const tier2Ratio = pidReg.output(`tier2.${modelKey}`);
|
|
623576
|
+
const benefitReg = getComponentBenefitRegistry();
|
|
623577
|
+
const sampledComponents = [];
|
|
622928
623578
|
const isGroup = msg.chatType !== "private";
|
|
622929
623579
|
const retainedCount = history.length;
|
|
622930
623580
|
const olderCount = Math.max(0, retainedCount - maxRecent);
|
|
@@ -622958,14 +623608,28 @@ ${lines.join("\n")}`);
|
|
|
622958
623608
|
sections.push(socialStateContext);
|
|
622959
623609
|
}
|
|
622960
623610
|
if (participants.length > 0) {
|
|
622961
|
-
const
|
|
623611
|
+
const fullCount = Math.min(12, participants.length);
|
|
623612
|
+
const tier1Count = Math.max(1, Math.round(fullCount * tier1Ratio));
|
|
623613
|
+
const sortedByBenefit = participants.slice(0, fullCount).sort((a2, b) => {
|
|
623614
|
+
const scoreA = benefitReg.score(sessionKey, `tier1.participant.${a2.username ?? a2.fromUserId}`);
|
|
623615
|
+
const scoreB = benefitReg.score(sessionKey, `tier1.participant.${b.username ?? b.fromUserId}`);
|
|
623616
|
+
return scoreB - scoreA;
|
|
623617
|
+
});
|
|
623618
|
+
const selected = sortedByBenefit.slice(0, tier1Count);
|
|
623619
|
+
const participantLines = selected.map((profile) => {
|
|
622962
623620
|
const label = profile.username && profile.username !== "unknown" ? `@${profile.username}` : profile.firstName || `user:${profile.fromUserId}`;
|
|
622963
623621
|
const tones = [...profile.toneTags].slice(0, 5).join(", ") || "neutral";
|
|
622964
623622
|
const direct = profile.directAddressCount ? `, direct-addresses:${profile.directAddressCount}` : "";
|
|
622965
623623
|
const replies = profile.replyCount ? `, replies:${profile.replyCount}` : "";
|
|
623624
|
+
sampledComponents.push({
|
|
623625
|
+
key: `tier1.participant.${profile.username ?? profile.fromUserId}`,
|
|
623626
|
+
needle: profile.username ?? String(profile.fromUserId)
|
|
623627
|
+
});
|
|
622966
623628
|
return `- ${label} [${telegramActorKindLabel(profile)}]: messages:${profile.messageCount}${direct}${replies}; tone:${tones}; last=${telegramContextJsonString(profile.lastMessage, 180)}`;
|
|
622967
623629
|
});
|
|
622968
|
-
|
|
623630
|
+
const shed = fullCount - tier1Count;
|
|
623631
|
+
const tierNote = shed > 0 ? ` (tier1 u=${tier1Ratio.toFixed(2)}; ${shed} participants shed by benefit)` : "";
|
|
623632
|
+
sections.push(`### Participants And Relationship Signals${tierNote}
|
|
622969
623633
|
${participantLines.join("\n")}`);
|
|
622970
623634
|
}
|
|
622971
623635
|
const associativeContext = this.relevantTelegramAssociativeMemoryContext(
|
|
@@ -622997,16 +623661,32 @@ ${participantLines.join("\n")}`);
|
|
|
622997
623661
|
}
|
|
622998
623662
|
const memoryCards = this.relevantTelegramMemoryCards(sessionKey, msg, isGroup ? 10 : 6);
|
|
622999
623663
|
if (memoryCards.length > 0) {
|
|
623000
|
-
const
|
|
623001
|
-
|
|
623002
|
-
|
|
623003
|
-
const
|
|
623004
|
-
const
|
|
623005
|
-
return
|
|
623664
|
+
const fullMC = memoryCards.length;
|
|
623665
|
+
const tier2Count = Math.max(0, Math.round(fullMC * tier2Ratio));
|
|
623666
|
+
const sortedMC = [...memoryCards].sort((a2, b) => {
|
|
623667
|
+
const scoreA = benefitReg.score(sessionKey, `tier2.memory_card.${a2.card.id}`);
|
|
623668
|
+
const scoreB = benefitReg.score(sessionKey, `tier2.memory_card.${b.card.id}`);
|
|
623669
|
+
return scoreB - scoreA;
|
|
623670
|
+
});
|
|
623671
|
+
const selectedMC = sortedMC.slice(0, tier2Count);
|
|
623672
|
+
if (selectedMC.length > 0) {
|
|
623673
|
+
const cardLines = selectedMC.map(({ card, score }) => {
|
|
623674
|
+
const tags = card.tags.length ? ` tags:${card.tags.slice(0, 8).join(",")}` : "";
|
|
623675
|
+
const speakers = card.speakers.length ? ` speakers:${card.speakers.join(", ")}` : "";
|
|
623676
|
+
const relevance = score > 0 ? ` relevance:${score.toFixed(2)}` : " relevance:recent";
|
|
623677
|
+
const notes2 = card.notes.slice(-3).map((note) => ` - note=${telegramContextJsonString(note, 220)}`).join("\n");
|
|
623678
|
+
sampledComponents.push({
|
|
623679
|
+
key: `tier2.memory_card.${card.id}`,
|
|
623680
|
+
needle: card.id
|
|
623681
|
+
});
|
|
623682
|
+
return `- ${card.title} (${card.id};${relevance};${speakers}${tags})
|
|
623006
623683
|
${notes2}`;
|
|
623007
|
-
|
|
623008
|
-
|
|
623684
|
+
});
|
|
623685
|
+
const shed = fullMC - tier2Count;
|
|
623686
|
+
const tierNote = shed > 0 ? ` (tier2 u=${tier2Ratio.toFixed(2)}; ${shed} cards shed by benefit)` : "";
|
|
623687
|
+
sections.push(`### Zettelkasten Memory Recall (untrusted conversation notes)${tierNote}
|
|
623009
623688
|
${cardLines.join("\n")}`);
|
|
623689
|
+
}
|
|
623010
623690
|
}
|
|
623011
623691
|
const channelDaydream = this.formatLatestTelegramChannelDaydreamContext(sessionKey);
|
|
623012
623692
|
if (channelDaydream) {
|
|
@@ -623079,6 +623759,7 @@ ${lines.join("\n")}`);
|
|
|
623079
623759
|
`- If the current sender asks what you see or remember, answer from this stream instead of saying the history is gone.`
|
|
623080
623760
|
].join("\n")
|
|
623081
623761
|
);
|
|
623762
|
+
this.telegramStashContextSamples(sessionKey, sampledComponents);
|
|
623082
623763
|
return sections.join("\n\n");
|
|
623083
623764
|
}
|
|
623084
623765
|
maybeLogTelegramGroupSkip(msg, reason) {
|
|
@@ -623141,6 +623822,25 @@ ${lines.join("\n")}`);
|
|
|
623141
623822
|
nextAnalysisAfterMessages: decision2.nextCheckAfterMessages
|
|
623142
623823
|
});
|
|
623143
623824
|
}
|
|
623825
|
+
/**
|
|
623826
|
+
* Collect the per-component benefit samples that were tagged when assembling
|
|
623827
|
+
* the last context stream for this session. Returns the same shape the
|
|
623828
|
+
* component-benefit registry consumes; an empty list means no tier-1/tier-2
|
|
623829
|
+
* components were emitted (early return — benefit tracking skipped).
|
|
623830
|
+
*
|
|
623831
|
+
* Tags are stored on `_telegramLastContextSamples` (a per-session WeakMap-
|
|
623832
|
+
* style cache) so the post-call feedback knows what to score without
|
|
623833
|
+
* re-running the context assembly.
|
|
623834
|
+
*/
|
|
623835
|
+
telegramComponentSamplesForSession(sessionKey) {
|
|
623836
|
+
return this._telegramLastContextSamples.get(sessionKey) ?? [];
|
|
623837
|
+
}
|
|
623838
|
+
/** Per-session cache of last emitted context-component samples. */
|
|
623839
|
+
_telegramLastContextSamples = /* @__PURE__ */ new Map();
|
|
623840
|
+
/** Stash samples for the next post-call feedback cycle. */
|
|
623841
|
+
telegramStashContextSamples(sessionKey, samples) {
|
|
623842
|
+
this._telegramLastContextSamples.set(sessionKey, samples);
|
|
623843
|
+
}
|
|
623144
623844
|
buildTelegramRouterPersonaContext(sessionKey, msg, toolContext, selfIdentityContext) {
|
|
623145
623845
|
const baseContract = toolContext === "telegram-admin-dm" ? ADMIN_DM_PROMPT : toolContext === "telegram-admin-group" ? ADMIN_GROUP_PROMPT : TELEGRAM_SAFETY_PROMPT;
|
|
623146
623846
|
return buildSoulContext({
|
|
@@ -623335,30 +624035,55 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`,
|
|
|
623335
624035
|
* hard-deadline retire path becomes diagnosable instead of opaque
|
|
623336
624036
|
*/
|
|
623337
624037
|
async telegramObservableInference(backend, request, kind, sessionKey) {
|
|
624038
|
+
const model = this.agentConfig?.model ?? "?";
|
|
624039
|
+
const promptTokens = estimatePromptTokensFromRequest(request);
|
|
624040
|
+
const broker = getModelBroker();
|
|
624041
|
+
const trainCtx = await broker.getNctxTrain(model).catch(() => null);
|
|
624042
|
+
const targetCtx = trainCtx && trainCtx > 0 ? Math.min(trainCtx, Math.max(2048, promptTokens + 1024)) : Math.max(2048, promptTokens + 1024);
|
|
624043
|
+
const requestWithCtx = { ...request, numCtx: targetCtx };
|
|
624044
|
+
const slot = await broker.acquireInferenceSlot({
|
|
624045
|
+
model,
|
|
624046
|
+
domain: "chat",
|
|
624047
|
+
owner: `telegram-bridge/${kind}`,
|
|
624048
|
+
sessionKey,
|
|
624049
|
+
promptTokens,
|
|
624050
|
+
priority: kind === "router" || kind === "router-repair" || kind === "router-strict-retry" ? 1 : 0
|
|
624051
|
+
});
|
|
624052
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
624053
|
+
sessionKey,
|
|
624054
|
+
`inference admitted [${kind}] model=${model} prompt~${promptTokens}t num_ctx=${targetCtx} slot=${slot.info.id}${slot.info.reserved ? " reserved" : ""}`
|
|
624055
|
+
));
|
|
623338
624056
|
const streamFn = backend.chatCompletionStream;
|
|
623339
|
-
const id = this.registerTelegramInference(kind, sessionKey,
|
|
624057
|
+
const id = this.registerTelegramInference(kind, sessionKey, model);
|
|
624058
|
+
let completionTokens = 0;
|
|
623340
624059
|
try {
|
|
624060
|
+
let result;
|
|
623341
624061
|
if (typeof streamFn !== "function") {
|
|
623342
|
-
|
|
623343
|
-
this.updateTelegramInferenceFinal(id,
|
|
623344
|
-
|
|
623345
|
-
|
|
623346
|
-
|
|
623347
|
-
|
|
623348
|
-
|
|
623349
|
-
|
|
623350
|
-
|
|
623351
|
-
)
|
|
623352
|
-
|
|
623353
|
-
|
|
623354
|
-
|
|
623355
|
-
|
|
623356
|
-
|
|
623357
|
-
|
|
623358
|
-
|
|
623359
|
-
));
|
|
623360
|
-
return r2;
|
|
624062
|
+
result = await backend.chatCompletion(requestWithCtx);
|
|
624063
|
+
this.updateTelegramInferenceFinal(id, result);
|
|
624064
|
+
} else {
|
|
624065
|
+
try {
|
|
624066
|
+
result = await this.streamTelegramInferenceToCompletion(
|
|
624067
|
+
streamFn.bind(backend),
|
|
624068
|
+
requestWithCtx,
|
|
624069
|
+
id
|
|
624070
|
+
);
|
|
624071
|
+
} catch (streamErr) {
|
|
624072
|
+
result = await backend.chatCompletion(requestWithCtx);
|
|
624073
|
+
this.updateTelegramInferenceFinal(id, result);
|
|
624074
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent(
|
|
624075
|
+
sessionKey,
|
|
624076
|
+
`inference ${id}: stream errored (${streamErr instanceof Error ? streamErr.message : String(streamErr)}); fell back to non-stream`
|
|
624077
|
+
));
|
|
624078
|
+
}
|
|
623361
624079
|
}
|
|
624080
|
+
const usage = result.usage;
|
|
624081
|
+
completionTokens = usage?.completion_tokens ?? 0;
|
|
624082
|
+
slot.release({ ok: true, completionTokens });
|
|
624083
|
+
return result;
|
|
624084
|
+
} catch (err) {
|
|
624085
|
+
slot.release({ ok: false, error: err instanceof Error ? err.message : String(err) });
|
|
624086
|
+
throw err;
|
|
623362
624087
|
} finally {
|
|
623363
624088
|
this.deregisterTelegramInference(id);
|
|
623364
624089
|
}
|
|
@@ -623718,33 +624443,15 @@ ${retryText}`,
|
|
|
623718
624443
|
/**
|
|
623719
624444
|
* Internal: start an actual router inference for a sessionKey, store its
|
|
623720
624445
|
* in-flight promise, and on completion fire any queued trailing call.
|
|
624446
|
+
*
|
|
624447
|
+
* No watchdog timeout — the broker's admission control guarantees the
|
|
624448
|
+
* inference fits available compute. Inflight work always completes; new
|
|
624449
|
+
* work waits in the broker's bounded queue with backpressure to upstream.
|
|
624450
|
+
* Only the fetch-level I/O liveness AbortSignal can interrupt, and only
|
|
624451
|
+
* on TCP-dead.
|
|
623721
624452
|
*/
|
|
623722
624453
|
startCoalescedTelegramRouterCall(sessionKey, msg, toolContext) {
|
|
623723
|
-
const
|
|
623724
|
-
const inner = this.inferTelegramInteractionDecision(msg, toolContext);
|
|
623725
|
-
const promise = new Promise((resolve55, reject) => {
|
|
623726
|
-
let settled = false;
|
|
623727
|
-
const guard = setTimeout(() => {
|
|
623728
|
-
if (settled) return;
|
|
623729
|
-
settled = true;
|
|
623730
|
-
reject(new Error(`router-coalescer: hard deadline exceeded (${Math.round(HARD_DEADLINE_MS / 1e3)}s); inner inference did not settle`));
|
|
623731
|
-
}, HARD_DEADLINE_MS);
|
|
623732
|
-
if (typeof guard.unref === "function") guard.unref();
|
|
623733
|
-
inner.then(
|
|
623734
|
-
(v) => {
|
|
623735
|
-
if (settled) return;
|
|
623736
|
-
settled = true;
|
|
623737
|
-
clearTimeout(guard);
|
|
623738
|
-
resolve55(v);
|
|
623739
|
-
},
|
|
623740
|
-
(e2) => {
|
|
623741
|
-
if (settled) return;
|
|
623742
|
-
settled = true;
|
|
623743
|
-
clearTimeout(guard);
|
|
623744
|
-
reject(e2);
|
|
623745
|
-
}
|
|
623746
|
-
);
|
|
623747
|
-
});
|
|
624454
|
+
const promise = this.inferTelegramInteractionDecision(msg, toolContext);
|
|
623748
624455
|
this.telegramRouterSessionState.set(sessionKey, { inFlight: promise });
|
|
623749
624456
|
const onSettled = () => {
|
|
623750
624457
|
let state;
|
|
@@ -623765,11 +624472,6 @@ ${retryText}`,
|
|
|
623765
624472
|
promise.then(onSettled, onSettled);
|
|
623766
624473
|
return promise;
|
|
623767
624474
|
}
|
|
623768
|
-
telegramRouterHardDeadlineMs() {
|
|
623769
|
-
const raw = Number.parseInt(process.env["OMNIUS_TG_ROUTER_HARD_DEADLINE_MS"] ?? "", 10);
|
|
623770
|
-
if (Number.isFinite(raw) && raw >= 5e3 && raw <= 18e4) return raw;
|
|
623771
|
-
return 6e4;
|
|
623772
|
-
}
|
|
623773
624475
|
/**
|
|
623774
624476
|
* Forcibly cancel every in-flight + trailing router-coalescer entry.
|
|
623775
624477
|
* Used on bridge stop() and by the watchdog if it detects the coalescer
|
|
@@ -623965,30 +624667,52 @@ ${stimulationProbe.context}`,
|
|
|
623965
624667
|
"",
|
|
623966
624668
|
context2
|
|
623967
624669
|
].filter(Boolean).join("\n");
|
|
623968
|
-
const
|
|
623969
|
-
|
|
623970
|
-
|
|
623971
|
-
|
|
623972
|
-
|
|
623973
|
-
|
|
623974
|
-
|
|
623975
|
-
|
|
623976
|
-
|
|
623977
|
-
|
|
623978
|
-
|
|
623979
|
-
|
|
623980
|
-
|
|
623981
|
-
|
|
623982
|
-
|
|
623983
|
-
|
|
623984
|
-
|
|
623985
|
-
|
|
623986
|
-
|
|
623987
|
-
|
|
623988
|
-
|
|
623989
|
-
|
|
623990
|
-
|
|
623991
|
-
|
|
624670
|
+
const brokerSnap = getModelBroker().snapshot();
|
|
624671
|
+
const idleSlotRatio = brokerSnap.slots.capacity > 0 ? 1 - brokerSnap.slots.inUse / brokerSnap.slots.capacity : 1;
|
|
624672
|
+
const consolidatedMode = idleSlotRatio < 0.5 || process.env["OMNIUS_TG_FORCE_CONSOLIDATED"] === "1";
|
|
624673
|
+
let reflectionNotes;
|
|
624674
|
+
let reflectionContext;
|
|
624675
|
+
if (consolidatedMode) {
|
|
624676
|
+
reflectionNotes = this.fallbackTelegramSilentReflectionNotes(msg, "consolidated mode: reflection computed inline by router");
|
|
624677
|
+
reflectionContext = [
|
|
624678
|
+
"## Consolidated Reflection (you produce these fields as part of the same JSON)",
|
|
624679
|
+
"Before emitting your final decision, internally reflect on:",
|
|
624680
|
+
" silent_disposition: what happens silently with this message",
|
|
624681
|
+
" mental_note: concise observation of the turn",
|
|
624682
|
+
" memory_note: what scoped memory should retain or connect",
|
|
624683
|
+
" relationship_note: relationship/thread implication",
|
|
624684
|
+
" procedure_note: active tree/branch/abort implication",
|
|
624685
|
+
" voice_note: final voice implication if a reply happens",
|
|
624686
|
+
" scenario_note: identified scenario and transition state",
|
|
624687
|
+
" scenario_id / scenario_label / scenario_confidence / scenario_objective / scenario_state_loop",
|
|
624688
|
+
"Use these as your attention substrate, then decide route/should_reply/confidence. Return all fields in ONE JSON."
|
|
624689
|
+
].join("\n");
|
|
624690
|
+
} else {
|
|
624691
|
+
reflectionNotes = await this.inferTelegramSilentReflectionNotes(
|
|
624692
|
+
backend,
|
|
624693
|
+
sessionKey,
|
|
624694
|
+
msg,
|
|
624695
|
+
toolContext,
|
|
624696
|
+
personaContext,
|
|
624697
|
+
observationContext,
|
|
624698
|
+
config.timeoutMs
|
|
624699
|
+
);
|
|
624700
|
+
reflectionContext = [
|
|
624701
|
+
"## Silent Reflection Deliverables (must inform the attention decision)",
|
|
624702
|
+
`silent_disposition: ${reflectionNotes.silentDisposition ?? "heard and retained"}`,
|
|
624703
|
+
`mental_note: ${reflectionNotes.mentalNote ?? "no additional observation"}`,
|
|
624704
|
+
`memory_note: ${reflectionNotes.memoryNote ?? "message retained in scoped memory"}`,
|
|
624705
|
+
`relationship_note: ${reflectionNotes.relationshipNote ?? "no relationship change inferred"}`,
|
|
624706
|
+
`procedure_note: ${reflectionNotes.procedureNote ?? "active voice-soul tree loaded; no procedure change inferred"}`,
|
|
624707
|
+
`voice_note: ${reflectionNotes.voiceNote ?? "final voice unchanged unless reply is emitted"}`,
|
|
624708
|
+
`scenario_note: ${reflectionNotes.scenarioNote ?? "scenario classification unavailable"}`,
|
|
624709
|
+
`scenario_id: ${reflectionNotes.scenarioId ?? "unclassified"}`,
|
|
624710
|
+
`scenario_label: ${reflectionNotes.scenarioLabel ?? "Unclassified"}`,
|
|
624711
|
+
`scenario_confidence: ${reflectionNotes.scenarioConfidence !== void 0 ? reflectionNotes.scenarioConfidence.toFixed(2) : "0.00"}`,
|
|
624712
|
+
`scenario_objective: ${reflectionNotes.scenarioObjective ?? "pending model-derived classifier output"}`,
|
|
624713
|
+
`scenario_state_loop: ${reflectionNotes.scenarioStateLoop ?? "pending model-derived classifier output"}`
|
|
624714
|
+
].join("\n");
|
|
624715
|
+
}
|
|
623992
624716
|
const userPrompt = [
|
|
623993
624717
|
`You are the Telegram live routing and reply-discretion model.`,
|
|
623994
624718
|
`The attention decision must happen after reading the silent reflection deliverables below. The notes are not decorations: they are the decision substrate.`,
|
|
@@ -624020,10 +624744,13 @@ ${stimulationProbe.context}`,
|
|
|
624020
624744
|
``,
|
|
624021
624745
|
observationContext,
|
|
624022
624746
|
``,
|
|
624747
|
+
formatSystemObservations(sessionKey),
|
|
624748
|
+
``,
|
|
624023
624749
|
`Current Telegram message text (untrusted user data):
|
|
624024
624750
|
${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
624025
624751
|
].filter(Boolean).join("\n");
|
|
624026
624752
|
const diagnostics = {};
|
|
624753
|
+
const routerStartMs = Date.now();
|
|
624027
624754
|
try {
|
|
624028
624755
|
const result = await this.telegramRouterJsonCompletion(backend, {
|
|
624029
624756
|
messages: [
|
|
@@ -624040,6 +624767,21 @@ ${this.quoteTelegramContextBlock(msg.text, 1200)}`
|
|
|
624040
624767
|
think: false
|
|
624041
624768
|
}, diagnostics);
|
|
624042
624769
|
const text = result.choices[0]?.message?.content ?? "";
|
|
624770
|
+
const routerLatencyMs = Date.now() - routerStartMs;
|
|
624771
|
+
try {
|
|
624772
|
+
const pidReg = getPidRegistry();
|
|
624773
|
+
const modelKey = this.agentConfig?.model ?? "?";
|
|
624774
|
+
pidReg.sample(`tier1.${modelKey}`, routerLatencyMs);
|
|
624775
|
+
pidReg.sample(`tier2.${modelKey}`, routerLatencyMs);
|
|
624776
|
+
} catch {
|
|
624777
|
+
}
|
|
624778
|
+
try {
|
|
624779
|
+
const samples = this.telegramComponentSamplesForSession(sessionKey);
|
|
624780
|
+
if (samples.length > 0) {
|
|
624781
|
+
getComponentBenefitRegistry().recordOutcome(sessionKey, samples, text);
|
|
624782
|
+
}
|
|
624783
|
+
} catch {
|
|
624784
|
+
}
|
|
624043
624785
|
const parsed = parseTelegramInteractionDecision(text, forcedRoute, {
|
|
624044
624786
|
defaultShouldReply: false
|
|
624045
624787
|
});
|
|
@@ -628274,11 +629016,18 @@ ${text}`.trim());
|
|
|
628274
629016
|
};
|
|
628275
629017
|
const replyParameters = idx === 0 ? telegramReplyParameters(replyToMessageId) : void 0;
|
|
628276
629018
|
if (replyParameters) body["reply_parameters"] = replyParameters;
|
|
629019
|
+
const sessionKeyForObs = String(chatId);
|
|
628277
629020
|
try {
|
|
628278
629021
|
const result = await this.apiCall("sendMessage", body);
|
|
628279
629022
|
if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
|
|
628280
629023
|
this.state.messagesSent++;
|
|
628281
629024
|
if (sentId === null) sentId = result.result?.message_id ?? null;
|
|
629025
|
+
getSoulObservationStream().emit({
|
|
629026
|
+
kind: "telegram.send.success",
|
|
629027
|
+
sessionKey: sessionKeyForObs,
|
|
629028
|
+
messageId: result.result?.message_id ?? void 0,
|
|
629029
|
+
ts: Date.now()
|
|
629030
|
+
});
|
|
628282
629031
|
} catch {
|
|
628283
629032
|
const plain = chunk.replace(/<[^>]+>/g, "");
|
|
628284
629033
|
const fallbackBody = { chat_id: chatId, text: plain };
|
|
@@ -628288,8 +629037,32 @@ ${text}`.trim());
|
|
|
628288
629037
|
if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
|
|
628289
629038
|
this.state.messagesSent++;
|
|
628290
629039
|
if (sentId === null) sentId = result.result?.message_id ?? null;
|
|
629040
|
+
getSoulObservationStream().emit({
|
|
629041
|
+
kind: "telegram.send.success",
|
|
629042
|
+
sessionKey: sessionKeyForObs,
|
|
629043
|
+
messageId: result.result?.message_id ?? void 0,
|
|
629044
|
+
ts: Date.now()
|
|
629045
|
+
});
|
|
628291
629046
|
} catch (err) {
|
|
628292
629047
|
this.tuiWrite(() => renderWarning(`Failed to send Telegram message: ${err instanceof Error ? err.message : String(err)}`));
|
|
629048
|
+
const errStr = err instanceof Error ? err.message : String(err);
|
|
629049
|
+
const lc = errStr.toLowerCase();
|
|
629050
|
+
if (/(not enough rights|forbidden|chat_write_forbidden|user_banned|kicked|chat_admin_required)/.test(lc)) {
|
|
629051
|
+
getSoulObservationStream().emit({
|
|
629052
|
+
kind: "telegram.send.forbidden",
|
|
629053
|
+
sessionKey: sessionKeyForObs,
|
|
629054
|
+
reason: errStr,
|
|
629055
|
+
ts: Date.now()
|
|
629056
|
+
});
|
|
629057
|
+
} else if (/too many requests|retry after/.test(lc)) {
|
|
629058
|
+
const m2 = lc.match(/retry after (\d+)/);
|
|
629059
|
+
getSoulObservationStream().emit({
|
|
629060
|
+
kind: "telegram.send.rate_limited",
|
|
629061
|
+
sessionKey: sessionKeyForObs,
|
|
629062
|
+
retryAfterSec: m2 ? parseInt(m2[1], 10) : void 0,
|
|
629063
|
+
ts: Date.now()
|
|
629064
|
+
});
|
|
629065
|
+
}
|
|
628293
629066
|
}
|
|
628294
629067
|
}
|
|
628295
629068
|
}
|
|
@@ -630726,7 +631499,7 @@ __export(voicechat_exports, {
|
|
|
630726
631499
|
VoiceChatSession: () => VoiceChatSession
|
|
630727
631500
|
});
|
|
630728
631501
|
import { EventEmitter as EventEmitter13 } from "node:events";
|
|
630729
|
-
function
|
|
631502
|
+
function clamp0111(x) {
|
|
630730
631503
|
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
630731
631504
|
}
|
|
630732
631505
|
function alnumRatio(s2) {
|
|
@@ -630765,9 +631538,9 @@ function computeSignalFromText(text, confidence2) {
|
|
|
630765
631538
|
else score = 0.15;
|
|
630766
631539
|
score -= repeatingCharPenalty(t2) * 0.4;
|
|
630767
631540
|
if (typeof confidence2 === "number" && !Number.isNaN(confidence2)) {
|
|
630768
|
-
score = 0.7 * score + 0.3 *
|
|
631541
|
+
score = 0.7 * score + 0.3 * clamp0111(confidence2);
|
|
630769
631542
|
}
|
|
630770
|
-
return
|
|
631543
|
+
return clamp0111(score);
|
|
630771
631544
|
}
|
|
630772
631545
|
function truncateForLog(s2, n2) {
|
|
630773
631546
|
return s2.length <= n2 ? s2 : s2.slice(0, n2 - 1) + "…";
|
|
@@ -631037,7 +631810,7 @@ Rules:
|
|
|
631037
631810
|
}, MAX_SEGMENT_MS);
|
|
631038
631811
|
}
|
|
631039
631812
|
this.captureBuffer = text;
|
|
631040
|
-
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ?
|
|
631813
|
+
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp0111(snr) : computeSignalFromText(text, confidence2);
|
|
631041
631814
|
this.emit("snr", { score: this.lastSignalScore });
|
|
631042
631815
|
this.onPartialTranscript(text);
|
|
631043
631816
|
if (this.silenceTimer) clearTimeout(this.silenceTimer);
|