omnius 1.0.29 → 1.0.30
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 +252 -17
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -598971,6 +598971,182 @@ ${result.output}`,
|
|
|
598971
598971
|
}
|
|
598972
598972
|
});
|
|
598973
598973
|
|
|
598974
|
+
// packages/cli/src/tui/stimulation.ts
|
|
598975
|
+
function clamp016(value2) {
|
|
598976
|
+
return Math.max(0, Math.min(1, value2));
|
|
598977
|
+
}
|
|
598978
|
+
function cloneState(state) {
|
|
598979
|
+
return { ...state };
|
|
598980
|
+
}
|
|
598981
|
+
function normalizePhase(value2) {
|
|
598982
|
+
const raw = String(value2 ?? "").trim().toLowerCase();
|
|
598983
|
+
return raw === "idle" || raw === "observing" || raw === "engaged" || raw === "cooldown" ? raw : void 0;
|
|
598984
|
+
}
|
|
598985
|
+
function phaseFromAttention(attention) {
|
|
598986
|
+
if (attention >= 0.72) return "engaged";
|
|
598987
|
+
if (attention >= 0.38) return "observing";
|
|
598988
|
+
if (attention >= 0.14) return "cooldown";
|
|
598989
|
+
return "idle";
|
|
598990
|
+
}
|
|
598991
|
+
function parseStimulationPhase(value2) {
|
|
598992
|
+
return normalizePhase(value2);
|
|
598993
|
+
}
|
|
598994
|
+
var DEFAULT_STATE, PHASE_DEFAULTS, PHASE_FLOORS, StimulationController;
|
|
598995
|
+
var init_stimulation = __esm({
|
|
598996
|
+
"packages/cli/src/tui/stimulation.ts"() {
|
|
598997
|
+
"use strict";
|
|
598998
|
+
DEFAULT_STATE = {
|
|
598999
|
+
phase: "idle",
|
|
599000
|
+
attention: 0,
|
|
599001
|
+
lastStimulusAtMs: 0,
|
|
599002
|
+
messagesSinceAnalysis: 0,
|
|
599003
|
+
messagesSinceAgentOutput: 0,
|
|
599004
|
+
consecutiveNoReply: 0,
|
|
599005
|
+
updatedAtMs: 0
|
|
599006
|
+
};
|
|
599007
|
+
PHASE_DEFAULTS = {
|
|
599008
|
+
idle: { messages: 6, ms: 10 * 6e4 },
|
|
599009
|
+
cooldown: { messages: 4, ms: 5 * 6e4 },
|
|
599010
|
+
observing: { messages: 2, ms: 2 * 6e4 },
|
|
599011
|
+
engaged: { messages: 1, ms: 45e3 }
|
|
599012
|
+
};
|
|
599013
|
+
PHASE_FLOORS = {
|
|
599014
|
+
idle: 0,
|
|
599015
|
+
cooldown: 0.18,
|
|
599016
|
+
observing: 0.45,
|
|
599017
|
+
engaged: 0.78
|
|
599018
|
+
};
|
|
599019
|
+
StimulationController = class {
|
|
599020
|
+
states = /* @__PURE__ */ new Map();
|
|
599021
|
+
getState(channelId) {
|
|
599022
|
+
return cloneState(this.stateFor(channelId, Date.now()));
|
|
599023
|
+
}
|
|
599024
|
+
setState(channelId, state) {
|
|
599025
|
+
if (!state) return;
|
|
599026
|
+
const now = Date.now();
|
|
599027
|
+
this.states.set(channelId, {
|
|
599028
|
+
...DEFAULT_STATE,
|
|
599029
|
+
...state,
|
|
599030
|
+
phase: normalizePhase(state.phase) ?? DEFAULT_STATE.phase,
|
|
599031
|
+
attention: clamp016(Number.isFinite(state.attention) ? Number(state.attention) : DEFAULT_STATE.attention),
|
|
599032
|
+
updatedAtMs: Number.isFinite(state.updatedAtMs) ? Number(state.updatedAtMs) : now,
|
|
599033
|
+
lastStimulusAtMs: Number.isFinite(state.lastStimulusAtMs) ? Number(state.lastStimulusAtMs) : now,
|
|
599034
|
+
messagesSinceAnalysis: Math.max(0, Math.floor(Number(state.messagesSinceAnalysis ?? 0))),
|
|
599035
|
+
messagesSinceAgentOutput: Math.max(0, Math.floor(Number(state.messagesSinceAgentOutput ?? 0))),
|
|
599036
|
+
consecutiveNoReply: Math.max(0, Math.floor(Number(state.consecutiveNoReply ?? 0)))
|
|
599037
|
+
});
|
|
599038
|
+
}
|
|
599039
|
+
observe(input) {
|
|
599040
|
+
const now = input.nowMs ?? Date.now();
|
|
599041
|
+
const state = this.stateFor(input.channelId, now);
|
|
599042
|
+
this.applyTimeDecay(state, now);
|
|
599043
|
+
state.lastStimulusAtMs = now;
|
|
599044
|
+
state.updatedAtMs = now;
|
|
599045
|
+
state.messagesSinceAnalysis += 1;
|
|
599046
|
+
state.messagesSinceAgentOutput += 1;
|
|
599047
|
+
const metadataStimulus = input.privateChannel || input.directSignal || input.replyToAgent || input.activeAgent || input.forceAnalyze;
|
|
599048
|
+
if (input.privateChannel) state.attention = Math.max(state.attention, 0.82);
|
|
599049
|
+
if (input.directSignal) state.attention = Math.max(state.attention, 0.76);
|
|
599050
|
+
if (input.replyToAgent) state.attention = Math.max(state.attention, 0.84);
|
|
599051
|
+
if (input.activeAgent) state.attention = Math.max(state.attention, 0.68);
|
|
599052
|
+
state.phase = phaseFromAttention(state.attention);
|
|
599053
|
+
const cadence = PHASE_DEFAULTS[state.phase];
|
|
599054
|
+
const messageBudget = state.nextAnalysisAfterMessages ?? cadence.messages;
|
|
599055
|
+
const timeDue = state.nextAnalysisAtMs !== void 0 ? now >= state.nextAnalysisAtMs : state.lastAnalysisAtMs !== void 0 && now - state.lastAnalysisAtMs >= cadence.ms;
|
|
599056
|
+
const shouldAnalyze = !state.lastAnalysisAtMs || metadataStimulus || state.messagesSinceAnalysis >= messageBudget || timeDue;
|
|
599057
|
+
let reason = "cadence-hold";
|
|
599058
|
+
if (!state.lastAnalysisAtMs) reason = "initial-analysis";
|
|
599059
|
+
else if (input.privateChannel) reason = "private-channel";
|
|
599060
|
+
else if (input.replyToAgent) reason = "reply-to-agent";
|
|
599061
|
+
else if (input.directSignal) reason = "direct-platform-signal";
|
|
599062
|
+
else if (input.activeAgent) reason = "active-agent-thread";
|
|
599063
|
+
else if (state.messagesSinceAnalysis >= messageBudget) reason = "chronological-sample";
|
|
599064
|
+
else if (timeDue) reason = "time-sample";
|
|
599065
|
+
if (shouldAnalyze) {
|
|
599066
|
+
state.lastAnalysisAtMs = now;
|
|
599067
|
+
state.messagesSinceAnalysis = 0;
|
|
599068
|
+
}
|
|
599069
|
+
this.states.set(input.channelId, cloneState(state));
|
|
599070
|
+
return {
|
|
599071
|
+
shouldAnalyze,
|
|
599072
|
+
reason,
|
|
599073
|
+
state: cloneState(state),
|
|
599074
|
+
context: this.formatContext(input.channelId)
|
|
599075
|
+
};
|
|
599076
|
+
}
|
|
599077
|
+
applyAgentDecision(channelId, decision, nowMs = Date.now()) {
|
|
599078
|
+
const state = this.stateFor(channelId, nowMs);
|
|
599079
|
+
this.applyTimeDecay(state, nowMs);
|
|
599080
|
+
if (Number.isFinite(decision.attentionScore)) {
|
|
599081
|
+
state.attention = clamp016(Number(decision.attentionScore));
|
|
599082
|
+
} else if (Number.isFinite(decision.attentionDelta)) {
|
|
599083
|
+
state.attention = clamp016(state.attention + Number(decision.attentionDelta));
|
|
599084
|
+
} else {
|
|
599085
|
+
state.attention = clamp016(state.attention + (decision.shouldReply ? 0.22 : -0.1));
|
|
599086
|
+
}
|
|
599087
|
+
if (decision.phase) {
|
|
599088
|
+
state.attention = Math.max(state.attention, PHASE_FLOORS[decision.phase]);
|
|
599089
|
+
state.phase = decision.phase;
|
|
599090
|
+
} else {
|
|
599091
|
+
state.phase = phaseFromAttention(state.attention);
|
|
599092
|
+
}
|
|
599093
|
+
state.consecutiveNoReply = decision.shouldReply ? 0 : state.consecutiveNoReply + 1;
|
|
599094
|
+
state.nextAnalysisAfterMessages = Number.isFinite(decision.nextAnalysisAfterMessages) ? Math.max(1, Math.floor(Number(decision.nextAnalysisAfterMessages))) : void 0;
|
|
599095
|
+
state.nextAnalysisAtMs = Number.isFinite(decision.nextAnalysisAfterMs) ? nowMs + Math.max(0, Number(decision.nextAnalysisAfterMs)) : void 0;
|
|
599096
|
+
state.updatedAtMs = nowMs;
|
|
599097
|
+
this.states.set(channelId, cloneState(state));
|
|
599098
|
+
return cloneState(state);
|
|
599099
|
+
}
|
|
599100
|
+
recordAgentOutput(channelId, nowMs = Date.now()) {
|
|
599101
|
+
const state = this.stateFor(channelId, nowMs);
|
|
599102
|
+
this.applyTimeDecay(state, nowMs);
|
|
599103
|
+
state.phase = "engaged";
|
|
599104
|
+
state.attention = Math.max(state.attention, 0.78);
|
|
599105
|
+
state.lastAgentOutputAtMs = nowMs;
|
|
599106
|
+
state.messagesSinceAgentOutput = 0;
|
|
599107
|
+
state.consecutiveNoReply = 0;
|
|
599108
|
+
state.updatedAtMs = nowMs;
|
|
599109
|
+
this.states.set(channelId, cloneState(state));
|
|
599110
|
+
return cloneState(state);
|
|
599111
|
+
}
|
|
599112
|
+
formatContext(channelId) {
|
|
599113
|
+
const state = this.stateFor(channelId, Date.now());
|
|
599114
|
+
const sinceAnalysis = state.lastAnalysisAtMs ? `${Math.max(0, Math.round((Date.now() - state.lastAnalysisAtMs) / 1e3))}s` : "never";
|
|
599115
|
+
const sinceAgent = state.lastAgentOutputAtMs ? `${Math.max(0, Math.round((Date.now() - state.lastAgentOutputAtMs) / 1e3))}s` : "never";
|
|
599116
|
+
return [
|
|
599117
|
+
`Stimulation phase: ${state.phase}`,
|
|
599118
|
+
`Attention score: ${state.attention.toFixed(2)}`,
|
|
599119
|
+
`Messages since analysis: ${state.messagesSinceAnalysis}`,
|
|
599120
|
+
`Messages since agent output: ${state.messagesSinceAgentOutput}`,
|
|
599121
|
+
`Consecutive no-reply decisions: ${state.consecutiveNoReply}`,
|
|
599122
|
+
`Last analysis: ${sinceAnalysis}`,
|
|
599123
|
+
`Last agent output: ${sinceAgent}`,
|
|
599124
|
+
state.nextAnalysisAfterMessages ? `Agent-requested next check after messages: ${state.nextAnalysisAfterMessages}` : "",
|
|
599125
|
+
state.nextAnalysisAtMs ? `Agent-requested next check at: ${new Date(state.nextAnalysisAtMs).toISOString()}` : ""
|
|
599126
|
+
].filter(Boolean).join("\n");
|
|
599127
|
+
}
|
|
599128
|
+
stateFor(channelId, nowMs) {
|
|
599129
|
+
const existing = this.states.get(channelId);
|
|
599130
|
+
if (existing) return cloneState(existing);
|
|
599131
|
+
return {
|
|
599132
|
+
...DEFAULT_STATE,
|
|
599133
|
+
lastStimulusAtMs: nowMs,
|
|
599134
|
+
updatedAtMs: nowMs
|
|
599135
|
+
};
|
|
599136
|
+
}
|
|
599137
|
+
applyTimeDecay(state, nowMs) {
|
|
599138
|
+
const elapsedMs2 = Math.max(0, nowMs - (state.updatedAtMs || nowMs));
|
|
599139
|
+
if (elapsedMs2 <= 0) return;
|
|
599140
|
+
const halfLives = elapsedMs2 / (12 * 6e4);
|
|
599141
|
+
state.attention = clamp016(state.attention * Math.pow(0.5, halfLives));
|
|
599142
|
+
if (state.phase !== "engaged" || elapsedMs2 > 4 * 6e4) {
|
|
599143
|
+
state.phase = phaseFromAttention(state.attention);
|
|
599144
|
+
}
|
|
599145
|
+
}
|
|
599146
|
+
};
|
|
599147
|
+
}
|
|
599148
|
+
});
|
|
599149
|
+
|
|
598974
599150
|
// packages/cli/src/tui/vision-ingress.ts
|
|
598975
599151
|
var vision_ingress_exports = {};
|
|
598976
599152
|
__export(vision_ingress_exports, {
|
|
@@ -599143,13 +599319,22 @@ function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
|
599143
599319
|
const confidenceRaw = Number(parsed["confidence"]);
|
|
599144
599320
|
const confidence = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;
|
|
599145
599321
|
const reason = String(parsed["reason"] ?? "live inference decision").slice(0, 240);
|
|
599322
|
+
const attentionDeltaRaw = Number(parsed["attention_delta"] ?? parsed["attentionDelta"]);
|
|
599323
|
+
const attentionScoreRaw = Number(parsed["attention_score"] ?? parsed["attentionScore"]);
|
|
599324
|
+
const nextMessagesRaw = Number(parsed["next_check_after_messages"] ?? parsed["nextCheckAfterMessages"]);
|
|
599325
|
+
const nextMsRaw = Number(parsed["next_check_after_ms"] ?? parsed["nextCheckAfterMs"]);
|
|
599146
599326
|
return {
|
|
599147
599327
|
route,
|
|
599148
599328
|
shouldReply,
|
|
599149
599329
|
confidence,
|
|
599150
599330
|
reason,
|
|
599151
599331
|
source: forcedRoute ? "forced-mode" : "live-inference",
|
|
599152
|
-
raw: text
|
|
599332
|
+
raw: text,
|
|
599333
|
+
attentionState: parseStimulationPhase(parsed["attention_state"] ?? parsed["attentionState"]),
|
|
599334
|
+
attentionDelta: Number.isFinite(attentionDeltaRaw) ? Math.max(-1, Math.min(1, attentionDeltaRaw)) : void 0,
|
|
599335
|
+
attentionScore: Number.isFinite(attentionScoreRaw) ? Math.max(0, Math.min(1, attentionScoreRaw)) : void 0,
|
|
599336
|
+
nextCheckAfterMessages: Number.isFinite(nextMessagesRaw) ? Math.max(1, Math.floor(nextMessagesRaw)) : void 0,
|
|
599337
|
+
nextCheckAfterMs: Number.isFinite(nextMsRaw) ? Math.max(0, Math.floor(nextMsRaw)) : void 0
|
|
599153
599338
|
};
|
|
599154
599339
|
} catch {
|
|
599155
599340
|
return null;
|
|
@@ -599982,6 +600167,7 @@ var init_telegram_bridge = __esm({
|
|
|
599982
600167
|
init_scoped_personality();
|
|
599983
600168
|
init_telegram_creative_tools();
|
|
599984
600169
|
init_omnius_directory();
|
|
600170
|
+
init_stimulation();
|
|
599985
600171
|
TELEGRAM_SAFETY_PROMPT = `
|
|
599986
600172
|
CRITICAL SAFETY NOTICE — PUBLIC TELEGRAM CHANNEL
|
|
599987
600173
|
|
|
@@ -600206,6 +600392,8 @@ Telegram response contract:
|
|
|
600206
600392
|
chatParticipants = /* @__PURE__ */ new Map();
|
|
600207
600393
|
/** Lightweight Zettelkasten-style memory cards by chat/guest session key */
|
|
600208
600394
|
chatMemoryCards = /* @__PURE__ */ new Map();
|
|
600395
|
+
/** Generic chronological attention cadence shared by live surfaces. */
|
|
600396
|
+
stimulation = new StimulationController();
|
|
600209
600397
|
/** Throttles noisy "skipped group chatter" waterfall logs */
|
|
600210
600398
|
groupSkipLogAt = /* @__PURE__ */ new Map();
|
|
600211
600399
|
/** Telegram interaction routing profile */
|
|
@@ -600495,6 +600683,9 @@ Telegram response contract:
|
|
|
600495
600683
|
if (Array.isArray(parsed.memoryCards)) {
|
|
600496
600684
|
this.chatMemoryCards.set(sessionKey, parsed.memoryCards.slice(0, TELEGRAM_MEMORY_CARD_LIMIT));
|
|
600497
600685
|
}
|
|
600686
|
+
if (parsed.stimulation) {
|
|
600687
|
+
this.stimulation.setState(sessionKey, parsed.stimulation);
|
|
600688
|
+
}
|
|
600498
600689
|
} catch {
|
|
600499
600690
|
}
|
|
600500
600691
|
}
|
|
@@ -600528,7 +600719,8 @@ Telegram response contract:
|
|
|
600528
600719
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
600529
600720
|
history: this.chatHistory.get(sessionKey) ?? [],
|
|
600530
600721
|
participants,
|
|
600531
|
-
memoryCards: this.chatMemoryCards.get(sessionKey) ?? []
|
|
600722
|
+
memoryCards: this.chatMemoryCards.get(sessionKey) ?? [],
|
|
600723
|
+
stimulation: this.stimulation.getState(sessionKey)
|
|
600532
600724
|
};
|
|
600533
600725
|
writeFileSync57(this.telegramConversationPath(sessionKey), JSON.stringify(payload, null, 2) + "\n", "utf8");
|
|
600534
600726
|
} catch {
|
|
@@ -600593,6 +600785,7 @@ Telegram response contract:
|
|
|
600593
600785
|
chatTitle: msg.chatTitle
|
|
600594
600786
|
};
|
|
600595
600787
|
this.recordChatHistory(sessionKey, entry);
|
|
600788
|
+
this.stimulation.recordAgentOutput(sessionKey);
|
|
600596
600789
|
this.updateTelegramMemoryCards(sessionKey, entry);
|
|
600597
600790
|
try {
|
|
600598
600791
|
updateScopedPersonality(this.telegramPersonalityScope(sessionKey, msg), {
|
|
@@ -600952,21 +601145,53 @@ ${lines.join("\n")}`);
|
|
|
600952
601145
|
if (msg.replyToUsername && msg.replyToUsername.trim().replace(/^@/, "").toLowerCase() === bot) return true;
|
|
600953
601146
|
return false;
|
|
600954
601147
|
}
|
|
601148
|
+
telegramMessageRepliesToBot(msg) {
|
|
601149
|
+
const bot = this.state.botUsername.trim().replace(/^@/, "").toLowerCase();
|
|
601150
|
+
return !!bot && !!msg.replyToUsername && msg.replyToUsername.trim().replace(/^@/, "").toLowerCase() === bot;
|
|
601151
|
+
}
|
|
601152
|
+
applyTelegramStimulationDecision(sessionKey, decision) {
|
|
601153
|
+
this.stimulation.applyAgentDecision(sessionKey, {
|
|
601154
|
+
shouldReply: decision.shouldReply,
|
|
601155
|
+
phase: decision.attentionState,
|
|
601156
|
+
attentionDelta: decision.attentionDelta,
|
|
601157
|
+
attentionScore: decision.attentionScore,
|
|
601158
|
+
nextAnalysisAfterMessages: decision.nextCheckAfterMessages,
|
|
601159
|
+
nextAnalysisAfterMs: decision.nextCheckAfterMs
|
|
601160
|
+
});
|
|
601161
|
+
}
|
|
600955
601162
|
async inferTelegramInteractionDecision(msg, toolContext) {
|
|
600956
601163
|
const config = this.agentConfig;
|
|
600957
601164
|
const forcedRoute = this.interactionMode === "chat" || this.interactionMode === "action" ? this.interactionMode : null;
|
|
600958
601165
|
const isGroup = msg.chatType !== "private";
|
|
600959
601166
|
const addressesBot = this.telegramMessageAddressesBot(msg);
|
|
600960
|
-
|
|
601167
|
+
const sessionKey = this.sessionKeyForMessage(msg);
|
|
601168
|
+
const stimulationProbe = this.stimulation.observe({
|
|
601169
|
+
channelId: sessionKey,
|
|
601170
|
+
privateChannel: !isGroup,
|
|
601171
|
+
directSignal: addressesBot,
|
|
601172
|
+
replyToAgent: this.telegramMessageRepliesToBot(msg),
|
|
601173
|
+
activeAgent: this.subAgents.has(sessionKey)
|
|
601174
|
+
});
|
|
601175
|
+
if (isGroup && !stimulationProbe.shouldAnalyze) {
|
|
600961
601176
|
return {
|
|
601177
|
+
route: forcedRoute ?? "chat",
|
|
601178
|
+
shouldReply: false,
|
|
601179
|
+
confidence: 0.35,
|
|
601180
|
+
reason: `stimulation cadence held analysis (${stimulationProbe.reason}); context retained`,
|
|
601181
|
+
source: "attention-gated"
|
|
601182
|
+
};
|
|
601183
|
+
}
|
|
601184
|
+
if (!config) {
|
|
601185
|
+
const fallback2 = {
|
|
600962
601186
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
600963
601187
|
shouldReply: !isGroup || addressesBot,
|
|
600964
601188
|
confidence: 0,
|
|
600965
601189
|
reason: isGroup ? addressesBot ? "router inference unavailable; Telegram message directly addresses the bot" : "router inference unavailable; public group fails closed without keyword heuristics" : "router inference unavailable; private chat defaults to quick reply",
|
|
600966
601190
|
source: "inference-unavailable"
|
|
600967
601191
|
};
|
|
601192
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback2);
|
|
601193
|
+
return fallback2;
|
|
600968
601194
|
}
|
|
600969
|
-
const sessionKey = this.sessionKeyForMessage(msg);
|
|
600970
601195
|
const backend = new OllamaAgenticBackend(
|
|
600971
601196
|
config.backendUrl,
|
|
600972
601197
|
config.model,
|
|
@@ -600978,16 +601203,17 @@ ${lines.join("\n")}`);
|
|
|
600978
601203
|
`You are the Telegram live routing and reply-discretion model.`,
|
|
600979
601204
|
`Return JSON only, with no markdown and no explanation outside JSON.`,
|
|
600980
601205
|
``,
|
|
600981
|
-
`Schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason"}`,
|
|
601206
|
+
`Schema: {"route":"chat"|"action","should_reply":true|false,"confidence":0.0-1.0,"reason":"short reason","attention_state":"idle"|"observing"|"engaged"|"cooldown","attention_delta":-1.0..1.0,"next_check_after_messages":1..12}`,
|
|
600982
601207
|
``,
|
|
600983
601208
|
`Route meanings:`,
|
|
600984
601209
|
`- chat: a short conversational answer can be produced without tools.`,
|
|
600985
601210
|
`- action: tools, workspace context, media processing, web lookup, delegation, or a multi-step agent loop may be needed.`,
|
|
600986
601211
|
`Route discipline: greetings, acknowledgements, casual tone/style discussion, and simple conversational questions are chat. Use action only when the message asks you to inspect, create, change, send, remember, search, analyze media, or otherwise do tool-backed work.`,
|
|
600987
601212
|
``,
|
|
600988
|
-
`Reply discretion: infer from the live thread, speaker relationships, direct
|
|
601213
|
+
`Reply discretion: infer from the live thread, speaker relationships, direct platform signals, replies, tone, and current message. Do not use static keyword rules.`,
|
|
600989
601214
|
`Private chats: should_reply is normally true.`,
|
|
600990
601215
|
`Group/public chats: default should_reply to false unless the current message clearly addresses the bot, replies to the bot, continues an active bot-involved exchange, assigns the bot work, or asks for the bot's view. Ambient chatter, third-person discussion about the bot, commands meant for a human, or questions among other people are false. Do not set true just because the bot could help.`,
|
|
601216
|
+
`Stimulation discipline: also set attention_state, attention_delta, and optional next_check_after_messages/next_check_after_ms. These control future analysis cadence only; they do not force a reply. Use engaged for active back-and-forth, observing for likely relevant context, cooldown for recently irrelevant context, and idle for ambient chatter.`,
|
|
600991
601217
|
forcedLine,
|
|
600992
601218
|
``,
|
|
600993
601219
|
`Tool context: ${toolContext}`,
|
|
@@ -600999,6 +601225,9 @@ ${lines.join("\n")}`);
|
|
|
600999
601225
|
msg.replyToUsername ? `Current message replies to @${msg.replyToUsername}` : "",
|
|
601000
601226
|
(msg.mentionedUsernames ?? []).length > 0 ? `Current message mentions: ${(msg.mentionedUsernames ?? []).map((name10) => `@${name10}`).join(", ")}` : "",
|
|
601001
601227
|
msg.media ? `Current message has media: ${summarizeTelegramMessageAttachments(msg)}` : "",
|
|
601228
|
+
``,
|
|
601229
|
+
`Current stimulation state before semantic decision:
|
|
601230
|
+
${stimulationProbe.context}`,
|
|
601002
601231
|
``,
|
|
601003
601232
|
context2,
|
|
601004
601233
|
``,
|
|
@@ -601010,7 +601239,7 @@ ${msg.text}`
|
|
|
601010
601239
|
messages: [
|
|
601011
601240
|
{
|
|
601012
601241
|
role: "system",
|
|
601013
|
-
content: "You perform live Telegram route inference. Output strict JSON only."
|
|
601242
|
+
content: "You perform live Telegram route and stimulation inference. Output strict JSON only."
|
|
601014
601243
|
},
|
|
601015
601244
|
{ role: "user", content: userPrompt }
|
|
601016
601245
|
],
|
|
@@ -601024,16 +601253,21 @@ ${msg.text}`
|
|
|
601024
601253
|
const parsed = parseTelegramInteractionDecision(text, forcedRoute, {
|
|
601025
601254
|
defaultShouldReply: !isGroup
|
|
601026
601255
|
});
|
|
601027
|
-
if (parsed)
|
|
601256
|
+
if (parsed) {
|
|
601257
|
+
this.applyTelegramStimulationDecision(sessionKey, parsed);
|
|
601258
|
+
return parsed;
|
|
601259
|
+
}
|
|
601028
601260
|
} catch {
|
|
601029
601261
|
}
|
|
601030
|
-
|
|
601262
|
+
const fallback = {
|
|
601031
601263
|
route: forcedRoute ?? (isGroup ? "action" : "chat"),
|
|
601032
601264
|
shouldReply: !isGroup || addressesBot,
|
|
601033
601265
|
confidence: 0,
|
|
601034
601266
|
reason: isGroup ? addressesBot ? "router inference failed; Telegram message directly addresses the bot" : "router inference failed; public group fails closed without keyword heuristics" : "router inference failed; private chat defaults to quick reply",
|
|
601035
601267
|
source: "inference-unavailable"
|
|
601036
601268
|
};
|
|
601269
|
+
this.applyTelegramStimulationDecision(sessionKey, fallback);
|
|
601270
|
+
return fallback;
|
|
601037
601271
|
}
|
|
601038
601272
|
buildTelegramWorkspaceContext(modelTier, budget = 14e3) {
|
|
601039
601273
|
if (!this.repoRoot) return "";
|
|
@@ -605361,7 +605595,7 @@ __export(voicechat_exports, {
|
|
|
605361
605595
|
VoiceChatSession: () => VoiceChatSession
|
|
605362
605596
|
});
|
|
605363
605597
|
import { EventEmitter as EventEmitter11 } from "node:events";
|
|
605364
|
-
function
|
|
605598
|
+
function clamp017(x) {
|
|
605365
605599
|
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
605366
605600
|
}
|
|
605367
605601
|
function alnumRatio(s2) {
|
|
@@ -605400,9 +605634,9 @@ function computeSignalFromText(text, confidence) {
|
|
|
605400
605634
|
else score = 0.15;
|
|
605401
605635
|
score -= repeatingCharPenalty(t2) * 0.4;
|
|
605402
605636
|
if (typeof confidence === "number" && !Number.isNaN(confidence)) {
|
|
605403
|
-
score = 0.7 * score + 0.3 *
|
|
605637
|
+
score = 0.7 * score + 0.3 * clamp017(confidence);
|
|
605404
605638
|
}
|
|
605405
|
-
return
|
|
605639
|
+
return clamp017(score);
|
|
605406
605640
|
}
|
|
605407
605641
|
function truncateForLog(s2, n2) {
|
|
605408
605642
|
return s2.length <= n2 ? s2 : s2.slice(0, n2 - 1) + "…";
|
|
@@ -605672,7 +605906,7 @@ Rules:
|
|
|
605672
605906
|
}, MAX_SEGMENT_MS);
|
|
605673
605907
|
}
|
|
605674
605908
|
this.captureBuffer = text;
|
|
605675
|
-
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ?
|
|
605909
|
+
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp017(snr) : computeSignalFromText(text, confidence);
|
|
605676
605910
|
this.emit("snr", { score: this.lastSignalScore });
|
|
605677
605911
|
this.onPartialTranscript(text);
|
|
605678
605912
|
if (this.silenceTimer) clearTimeout(this.silenceTimer);
|
|
@@ -612629,7 +612863,7 @@ const $config = writable(null); // {endpoint, model, ...}
|
|
|
612629
612863
|
const $activeTab = writable('chat');
|
|
612630
612864
|
|
|
612631
612865
|
function parseInitialGuiRoute() {
|
|
612632
|
-
const path = (location.pathname || '/').replace(
|
|
612866
|
+
const path = (location.pathname || '/').replace(/\\/+$/, '') || '/';
|
|
612633
612867
|
const pathToTab = {
|
|
612634
612868
|
'/chat': 'chat',
|
|
612635
612869
|
'/agent': 'agent',
|
|
@@ -612644,7 +612878,7 @@ function parseInitialGuiRoute() {
|
|
|
612644
612878
|
const tab = pathToTab[path] || null;
|
|
612645
612879
|
let chatSession = null;
|
|
612646
612880
|
if (tab === 'chat') {
|
|
612647
|
-
const qs = location.search.replace(
|
|
612881
|
+
const qs = location.search.replace(/^\\?/, '').trim();
|
|
612648
612882
|
if (qs) {
|
|
612649
612883
|
try {
|
|
612650
612884
|
const params = new URLSearchParams(location.search);
|
|
@@ -614786,7 +615020,7 @@ function routePathForTab(tab) {
|
|
|
614786
615020
|
return map[tab] || '/chat';
|
|
614787
615021
|
}
|
|
614788
615022
|
function tabForRoutePath(pathname) {
|
|
614789
|
-
const path = (pathname || '/').replace(
|
|
615023
|
+
const path = (pathname || '/').replace(/\\/+$/, '') || '/';
|
|
614790
615024
|
const map = {
|
|
614791
615025
|
'/': 'chat',
|
|
614792
615026
|
'/chat': 'chat',
|
|
@@ -614802,7 +615036,7 @@ function tabForRoutePath(pathname) {
|
|
|
614802
615036
|
return map[path] || 'chat';
|
|
614803
615037
|
}
|
|
614804
615038
|
function chatSessionFromRouteSearch(search) {
|
|
614805
|
-
const qs = String(search || '').replace(
|
|
615039
|
+
const qs = String(search || '').replace(/^\\?/, '').trim();
|
|
614806
615040
|
if (!qs) return null;
|
|
614807
615041
|
try {
|
|
614808
615042
|
const params = new URLSearchParams(search);
|
|
@@ -614854,6 +615088,7 @@ function switchTab(tab, opts) {
|
|
|
614854
615088
|
try { loadVoiceTab(); } catch {}
|
|
614855
615089
|
}
|
|
614856
615090
|
}
|
|
615091
|
+
window.switchTab = switchTab;
|
|
614857
615092
|
window.addEventListener('popstate', () => {
|
|
614858
615093
|
const tab = tabForRoutePath(location.pathname);
|
|
614859
615094
|
if (tab === 'chat') {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
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.30",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED