instar 1.3.753 → 1.3.754
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/commands/server.d.ts +30 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +116 -16
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +20 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/componentCategories.d.ts.map +1 -1
- package/dist/core/componentCategories.js +6 -0
- package/dist/core/componentCategories.js.map +1 -1
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +6 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/data/llmBenchCoverage.d.ts.map +1 -1
- package/dist/data/llmBenchCoverage.js +6 -0
- package/dist/data/llmBenchCoverage.js.map +1 -1
- package/dist/threadline/HubIntentClassifier.d.ts +150 -0
- package/dist/threadline/HubIntentClassifier.d.ts.map +1 -0
- package/dist/threadline/HubIntentClassifier.js +322 -0
- package/dist/threadline/HubIntentClassifier.js.map +1 -0
- package/dist/threadline/hubCommands.d.ts +16 -12
- package/dist/threadline/hubCommands.d.ts.map +1 -1
- package/dist/threadline/hubCommands.js +16 -30
- package/dist/threadline/hubCommands.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/src/data/llmBenchCoverage.ts +7 -0
- package/upgrades/1.3.754.md +46 -0
- package/upgrades/side-effects/keyword-intent-conversion-3-hubcommands.md +170 -0
|
@@ -11,6 +11,7 @@ import { SessionManager } from '../core/SessionManager.js';
|
|
|
11
11
|
import { TelegramAdapter } from '../messaging/TelegramAdapter.js';
|
|
12
12
|
import { TopicMemory } from '../memory/TopicMemory.js';
|
|
13
13
|
import { QuotaTracker } from '../monitoring/QuotaTracker.js';
|
|
14
|
+
import type { IntelligenceProvider, InstarConfig } from '../core/types.js';
|
|
14
15
|
import { UserManager } from '../users/UserManager.js';
|
|
15
16
|
/**
|
|
16
17
|
* Pure: should the emergency "fix command" gate intercept this message?
|
|
@@ -38,7 +39,35 @@ interface StartOptions {
|
|
|
38
39
|
* Commander maps --no-telegram to telegram: false. */
|
|
39
40
|
telegram?: boolean;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the hub-intent classifier deps (Conversion #3,
|
|
44
|
+
* docs/specs/keyword-intent-conversions-1-and-3.md) from live config + the shared
|
|
45
|
+
* IntelligenceProvider. `enabled` is DEV-GATED (resolveDevAgentGate): DARK on the
|
|
46
|
+
* fleet, LIVE on a development agent. `dryRun` defaults true (the soak) so a
|
|
47
|
+
* dev-agent classifier RUNS but the message ALWAYS passes through until a
|
|
48
|
+
* deliberate `dryRun:false`. Passed as a late-bound getter so it re-reads config
|
|
49
|
+
* at message time.
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveHubClassifierDeps(config: InstarConfig, intelligence: IntelligenceProvider | null): {
|
|
52
|
+
intelligence: IntelligenceProvider | null;
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
dryRun: boolean;
|
|
55
|
+
minConfidence: number;
|
|
56
|
+
timeoutMs: number;
|
|
57
|
+
contextTurns: number;
|
|
58
|
+
modelTier: 'fast' | 'balanced' | 'capable';
|
|
59
|
+
stateDir: string;
|
|
60
|
+
};
|
|
61
|
+
export declare function wireTelegramRouting(telegram: TelegramAdapter, sessionManager: SessionManager, quotaTracker?: QuotaTracker, topicMemory?: TopicMemory, userManager?: UserManager, fixCommandHandler?: (topicId: number, text: string) => Promise<boolean>, getHubDeps?: () => import('../threadline/hubCommands.js').HubBindDeps | null, getTopicOperatorStore?: () => import('../users/TopicOperatorStore.js').TopicOperatorStore | null, getAttentionTopicId?: () => number | null | undefined, getHubClassifierDeps?: () => {
|
|
62
|
+
intelligence: import('../core/types.js').IntelligenceProvider | null;
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
dryRun: boolean;
|
|
65
|
+
minConfidence: number;
|
|
66
|
+
timeoutMs: number;
|
|
67
|
+
contextTurns: number;
|
|
68
|
+
modelTier: 'fast' | 'balanced' | 'capable';
|
|
69
|
+
stateDir: string;
|
|
70
|
+
} | null): void;
|
|
42
71
|
export declare function startServer(options: StartOptions): Promise<void>;
|
|
43
72
|
export declare function stopServer(options: {
|
|
44
73
|
dir?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiDH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAyBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiDH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAyBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA6H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2/CD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,oBAAoB,GAAG,IAAI,GACxC;IACD,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,EAQrD,oBAAoB,CAAC,EAAE,MAAM;IAC3B,YAAY,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,GACP,IAAI,CAonBN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ylBtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -1833,6 +1833,28 @@ async function handleProfileConfirm(telegram, surface, slots, topicId, principal
|
|
|
1833
1833
|
await send('That switch is no longer pending.');
|
|
1834
1834
|
return true;
|
|
1835
1835
|
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Resolve the hub-intent classifier deps (Conversion #3,
|
|
1838
|
+
* docs/specs/keyword-intent-conversions-1-and-3.md) from live config + the shared
|
|
1839
|
+
* IntelligenceProvider. `enabled` is DEV-GATED (resolveDevAgentGate): DARK on the
|
|
1840
|
+
* fleet, LIVE on a development agent. `dryRun` defaults true (the soak) so a
|
|
1841
|
+
* dev-agent classifier RUNS but the message ALWAYS passes through until a
|
|
1842
|
+
* deliberate `dryRun:false`. Passed as a late-bound getter so it re-reads config
|
|
1843
|
+
* at message time.
|
|
1844
|
+
*/
|
|
1845
|
+
export function resolveHubClassifierDeps(config, intelligence) {
|
|
1846
|
+
const cfg = config.threadline?.hubIntent;
|
|
1847
|
+
return {
|
|
1848
|
+
intelligence,
|
|
1849
|
+
enabled: resolveDevAgentGate(cfg?.enabled, config),
|
|
1850
|
+
dryRun: cfg?.dryRun ?? true,
|
|
1851
|
+
minConfidence: cfg?.minConfidence ?? 0.85,
|
|
1852
|
+
timeoutMs: cfg?.timeoutMs ?? 4000,
|
|
1853
|
+
contextTurns: cfg?.contextWindowTurns ?? 6,
|
|
1854
|
+
modelTier: cfg?.modelTier ?? 'fast',
|
|
1855
|
+
stateDir: config.stateDir,
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1836
1858
|
export function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager, fixCommandHandler,
|
|
1837
1859
|
// Late-bound: the threadline hub deps are constructed AFTER this is wired, so
|
|
1838
1860
|
// resolve them at message-time (CMT-529 deterministic "open this" intercept).
|
|
@@ -1846,7 +1868,15 @@ getTopicOperatorStore,
|
|
|
1846
1868
|
// fix-command gate (below) only fires in that topic; everywhere else a
|
|
1847
1869
|
// message starting with restart/fix/clean is normal conversation and must
|
|
1848
1870
|
// route to the session instead of being swallowed.
|
|
1849
|
-
getAttentionTopicId
|
|
1871
|
+
getAttentionTopicId,
|
|
1872
|
+
// Late-bound (same reason as getHubDeps): the hub-intent classifier deps —
|
|
1873
|
+
// the config-resolved dev-gate/settings + the shared IntelligenceProvider.
|
|
1874
|
+
// Conversion #3 (docs/specs/keyword-intent-conversions-1-and-3.md): the
|
|
1875
|
+
// "open this"/"tie this to <topic>" DECISION is inferred by an LLM over the
|
|
1876
|
+
// message + recent conversation (HubIntentClassifier), NOT a regex — the
|
|
1877
|
+
// regex SWALLOWED the message before the agent saw it, so a misread ATE it.
|
|
1878
|
+
// Resolved at the callsite where config + sharedIntelligence are in scope.
|
|
1879
|
+
getHubClassifierDeps) {
|
|
1850
1880
|
// Guard: tracks which topic IDs have a spawn in progress.
|
|
1851
1881
|
// Prevents duplicate concurrent spawns for the same topic when messages
|
|
1852
1882
|
// arrive faster than the async spawn completes.
|
|
@@ -1942,10 +1972,19 @@ getAttentionTopicId) {
|
|
|
1942
1972
|
return;
|
|
1943
1973
|
}
|
|
1944
1974
|
// ── Threadline hub commands: "open this" / "tie this to <topic>" (CMT-529) ──
|
|
1945
|
-
// When a message in the Threadline HUB topic is a
|
|
1946
|
-
//
|
|
1947
|
-
//
|
|
1975
|
+
// When a message in the Threadline HUB topic is a bind command, bind the
|
|
1976
|
+
// conversation to a topic STRUCTURALLY — before any agent interprets it. This
|
|
1977
|
+
// onTopicMessage seam is the convergence both inbound paths reach
|
|
1948
1978
|
// (lifeline-forward AND server-polling), so one intercept covers both modes.
|
|
1979
|
+
//
|
|
1980
|
+
// Conversion #3 (docs/specs/keyword-intent-conversions-1-and-3.md): the
|
|
1981
|
+
// "is this a bind command?" DECISION is inferred by an LLM over the message +
|
|
1982
|
+
// recent conversation (HubIntentClassifier), NOT a regex. The old regex
|
|
1983
|
+
// SWALLOWED the message before the agent saw it, so a misread silently ATE a
|
|
1984
|
+
// real message. Dev-gated dark (resolveDevAgentGate at the callsite) +
|
|
1985
|
+
// dry-run FIRST: while dark or dry-run the message ALWAYS passes through
|
|
1986
|
+
// (never swallowed); the classifier still runs on a dev agent and LOGS
|
|
1987
|
+
// would-swallow vs would-pass for the soak. Fail-OPEN on any uncertainty.
|
|
1949
1988
|
// FAIL-OPEN: any error falls through to normal routing.
|
|
1950
1989
|
const hubDeps = getHubDeps?.() ?? null;
|
|
1951
1990
|
if (hubDeps) {
|
|
@@ -1958,17 +1997,78 @@ getAttentionTopicId) {
|
|
|
1958
1997
|
hubTopicId = undefined;
|
|
1959
1998
|
}
|
|
1960
1999
|
if (hubTopicId !== undefined && Number(topicId) === Number(hubTopicId)) {
|
|
1961
|
-
const
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
2000
|
+
const clsDeps = getHubClassifierDeps?.() ?? null;
|
|
2001
|
+
// Dark gate: when the classifier isn't enabled (fleet default), never
|
|
2002
|
+
// swallow — pass the message through to the agent (no regex fallback).
|
|
2003
|
+
if (clsDeps?.enabled) {
|
|
2004
|
+
const { bindHubConversation } = await import('../threadline/hubCommands.js');
|
|
2005
|
+
const { classifyHubIntent, toHubCommand } = await import('../threadline/HubIntentClassifier.js');
|
|
2006
|
+
// The enum of bindable topics (real existing topics) — the model can
|
|
2007
|
+
// only tie to one of these (structured-output guardrail).
|
|
2008
|
+
let bindableTopics = [];
|
|
2009
|
+
try {
|
|
2010
|
+
bindableTopics = telegram.getAllTopicMappings()
|
|
2011
|
+
.map((m) => ({ topicId: m.topicId, topicName: m.topicName ?? `topic ${m.topicId}` }));
|
|
2012
|
+
}
|
|
2013
|
+
catch { /* best-effort — an empty enum simply means only "open" is possible */ }
|
|
2014
|
+
// Bounded window of recent turns so context-dependent commands ("yes,
|
|
2015
|
+
// tie it to that one") can resolve their target. Best-effort.
|
|
2016
|
+
let conversationContext = [];
|
|
2017
|
+
try {
|
|
2018
|
+
const hist = telegram.getTopicHistory(topicId, clsDeps.contextTurns) ?? [];
|
|
2019
|
+
conversationContext = hist.map((h) => ({ fromUser: !!h.fromUser, text: String(h.text ?? '') }));
|
|
2020
|
+
}
|
|
2021
|
+
catch { /* context is best-effort; classify on the message alone */ }
|
|
2022
|
+
const result = await classifyHubIntent({
|
|
2023
|
+
text,
|
|
2024
|
+
bindableTopics,
|
|
2025
|
+
conversationContext,
|
|
2026
|
+
intelligence: clsDeps.intelligence,
|
|
2027
|
+
minConfidence: clsDeps.minConfidence,
|
|
2028
|
+
timeoutMs: clsDeps.timeoutMs,
|
|
2029
|
+
maxContextTurns: clsDeps.contextTurns,
|
|
2030
|
+
modelTier: clsDeps.modelTier,
|
|
2031
|
+
});
|
|
2032
|
+
const willAct = result.isCommand && !clsDeps.dryRun;
|
|
2033
|
+
// Audit the soak: log LLM-engaged decisions (a prefilter-skip is the
|
|
2034
|
+
// bulk of traffic and always a would-pass — skipping it cuts volume
|
|
2035
|
+
// AND the message-preview privacy surface). Never gates the message.
|
|
2036
|
+
if (result.source !== 'prefilter-skip') {
|
|
2037
|
+
try {
|
|
2038
|
+
const logDir = path.join(clsDeps.stateDir, 'logs');
|
|
2039
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
2040
|
+
const decision = result.isCommand ? (willAct ? 'swallow' : 'would-swallow') : 'pass';
|
|
2041
|
+
fs.appendFileSync(path.join(logDir, 'hub-intent.jsonl'), JSON.stringify({
|
|
2042
|
+
ts: new Date().toISOString(),
|
|
2043
|
+
topicId,
|
|
2044
|
+
decision,
|
|
2045
|
+
dryRun: clsDeps.dryRun,
|
|
2046
|
+
source: result.source,
|
|
2047
|
+
intent: result.intent,
|
|
2048
|
+
targetTopicId: result.targetTopicId,
|
|
2049
|
+
confidence: result.confidence,
|
|
2050
|
+
reason: result.reason,
|
|
2051
|
+
textPreview: String(text).replace(/\s+/g, ' ').trim().slice(0, 80),
|
|
2052
|
+
}) + '\n');
|
|
2053
|
+
}
|
|
2054
|
+
catch { /* audit is observability — never gates the message path */ }
|
|
2055
|
+
}
|
|
2056
|
+
// Dry-run (the soak) OR not-a-command OR fail-open → pass the message
|
|
2057
|
+
// through untouched. Real swallowing needs a deliberate dryRun:false,
|
|
2058
|
+
// AND fail-open means uncertainty never swallows.
|
|
2059
|
+
if (willAct) {
|
|
2060
|
+
const cmd = toHubCommand(result);
|
|
2061
|
+
if (cmd) {
|
|
2062
|
+
const bindResult = await bindHubConversation(hubDeps, { ...cmd, autoPick: true }); // human "open this" → auto-pick most-recent, never 409
|
|
2063
|
+
if (!bindResult.ok) {
|
|
2064
|
+
await telegram.sendToTopic(topicId, bindResult.status === 404
|
|
2065
|
+
? 'Nothing waiting in the hub to open right now.'
|
|
2066
|
+
: `Couldn't open that — ${bindResult.error}`).catch(() => { });
|
|
2067
|
+
}
|
|
2068
|
+
// On success bindHubConversation already posted the hub confirmation.
|
|
2069
|
+
return; // structural: never inject the command into a session
|
|
2070
|
+
}
|
|
1969
2071
|
}
|
|
1970
|
-
// On success bindHubConversation already posted the hub confirmation.
|
|
1971
|
-
return; // structural: never inject the command into a session
|
|
1972
2072
|
}
|
|
1973
2073
|
}
|
|
1974
2074
|
}
|
|
@@ -6198,7 +6298,7 @@ export async function startServer(options) {
|
|
|
6198
6298
|
const userManagerSendOnly = new UserManager(config.stateDir, config.users);
|
|
6199
6299
|
attachUserReplication(userManagerSendOnly); // WS2.6 send-side (dark by default)
|
|
6200
6300
|
_fixDeps = { state, liveConfig, sessionManager, telegram, config };
|
|
6201
|
-
wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManagerSendOnly, (topicId, text) => handleFixCommand(topicId, text, _fixDeps), () => (collaborationSurfacer && conversationStore && telegram) ? { collaborationSurfacer, conversationStore, commitmentTracker, telegram, brief: briefDeps } : null, () => _agentServerRef?.getTopicOperatorStore() ?? null, () => state.get('agent-attention-topic'));
|
|
6301
|
+
wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManagerSendOnly, (topicId, text) => handleFixCommand(topicId, text, _fixDeps), () => (collaborationSurfacer && conversationStore && telegram) ? { collaborationSurfacer, conversationStore, commitmentTracker, telegram, brief: briefDeps } : null, () => _agentServerRef?.getTopicOperatorStore() ?? null, () => state.get('agent-attention-topic'), () => resolveHubClassifierDeps(config, _sharedIntelligence));
|
|
6202
6302
|
wireTelegramCallbacks(telegram, sessionManager, state, quotaTracker, undefined, config.sessions.claudePath, topicMemory);
|
|
6203
6303
|
console.log(pc.green(' Telegram routing + command callbacks wired (send-only)'));
|
|
6204
6304
|
}
|
|
@@ -6330,7 +6430,7 @@ export async function startServer(options) {
|
|
|
6330
6430
|
config,
|
|
6331
6431
|
};
|
|
6332
6432
|
// Wire up topic → session routing and session management callbacks
|
|
6333
|
-
wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager, (topicId, text) => handleFixCommand(topicId, text, _fixDeps), () => (collaborationSurfacer && conversationStore && telegram) ? { collaborationSurfacer, conversationStore, commitmentTracker, telegram, brief: briefDeps } : null, () => _agentServerRef?.getTopicOperatorStore() ?? null, () => state.get('agent-attention-topic'));
|
|
6433
|
+
wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager, (topicId, text) => handleFixCommand(topicId, text, _fixDeps), () => (collaborationSurfacer && conversationStore && telegram) ? { collaborationSurfacer, conversationStore, commitmentTracker, telegram, brief: briefDeps } : null, () => _agentServerRef?.getTopicOperatorStore() ?? null, () => state.get('agent-attention-topic'), () => resolveHubClassifierDeps(config, _sharedIntelligence));
|
|
6334
6434
|
wireTelegramCallbacks(telegram, sessionManager, state, quotaTracker, accountSwitcher, config.sessions.claudePath, topicMemory);
|
|
6335
6435
|
// Wire up unknown-user handling (Multi-User Setup Wizard Phase 4.5)
|
|
6336
6436
|
telegram.onGetRegistrationPolicy = () => ({
|