instar 0.26.3 → 0.26.5
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/README.md +61 -7
- package/dashboard/index.html +55 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +188 -3
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/slack-cli.d.ts.map +1 -1
- package/dist/commands/slack-cli.js +6 -0
- package/dist/commands/slack-cli.js.map +1 -1
- package/dist/core/CapabilityMapper.d.ts.map +1 -1
- package/dist/core/CapabilityMapper.js +2 -0
- package/dist/core/CapabilityMapper.js.map +1 -1
- package/dist/core/EvolutionManager.d.ts +17 -0
- package/dist/core/EvolutionManager.d.ts.map +1 -1
- package/dist/core/EvolutionManager.js +64 -0
- package/dist/core/EvolutionManager.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +37 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +31 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +169 -16
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/messaging/imessage/IMessageAdapter.d.ts +128 -0
- package/dist/messaging/imessage/IMessageAdapter.d.ts.map +1 -0
- package/dist/messaging/imessage/IMessageAdapter.js +541 -0
- package/dist/messaging/imessage/IMessageAdapter.js.map +1 -0
- package/dist/messaging/imessage/NativeBackend.d.ts +82 -0
- package/dist/messaging/imessage/NativeBackend.d.ts.map +1 -0
- package/dist/messaging/imessage/NativeBackend.js +353 -0
- package/dist/messaging/imessage/NativeBackend.js.map +1 -0
- package/dist/messaging/imessage/OutboundAuditLog.d.ts +49 -0
- package/dist/messaging/imessage/OutboundAuditLog.d.ts.map +1 -0
- package/dist/messaging/imessage/OutboundAuditLog.js +58 -0
- package/dist/messaging/imessage/OutboundAuditLog.js.map +1 -0
- package/dist/messaging/imessage/OutboundRateLimiter.d.ts +54 -0
- package/dist/messaging/imessage/OutboundRateLimiter.d.ts.map +1 -0
- package/dist/messaging/imessage/OutboundRateLimiter.js +111 -0
- package/dist/messaging/imessage/OutboundRateLimiter.js.map +1 -0
- package/dist/messaging/imessage/index.d.ts +10 -0
- package/dist/messaging/imessage/index.d.ts.map +1 -0
- package/dist/messaging/imessage/index.js +13 -0
- package/dist/messaging/imessage/index.js.map +1 -0
- package/dist/messaging/imessage/normalize-phone.d.ts +26 -0
- package/dist/messaging/imessage/normalize-phone.d.ts.map +1 -0
- package/dist/messaging/imessage/normalize-phone.js +55 -0
- package/dist/messaging/imessage/normalize-phone.js.map +1 -0
- package/dist/messaging/imessage/types.d.ts +95 -0
- package/dist/messaging/imessage/types.d.ts.map +1 -0
- package/dist/messaging/imessage/types.js +5 -0
- package/dist/messaging/imessage/types.js.map +1 -0
- package/dist/messaging/shared/MessagingEventBus.d.ts +5 -0
- package/dist/messaging/shared/MessagingEventBus.d.ts.map +1 -1
- package/dist/messaging/shared/MessagingEventBus.js.map +1 -1
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
- package/dist/messaging/slack/SlackAdapter.js +65 -1
- package/dist/messaging/slack/SlackAdapter.js.map +1 -1
- package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -1
- package/dist/messaging/slack/SocketModeClient.js +6 -0
- package/dist/messaging/slack/SocketModeClient.js.map +1 -1
- package/dist/monitoring/PresenceProxy.d.ts +6 -0
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
- package/dist/monitoring/PresenceProxy.js +46 -0
- package/dist/monitoring/PresenceProxy.js.map +1 -1
- package/dist/monitoring/QuotaExhaustionDetector.d.ts +15 -0
- package/dist/monitoring/QuotaExhaustionDetector.d.ts.map +1 -1
- package/dist/monitoring/QuotaExhaustionDetector.js +26 -3
- package/dist/monitoring/QuotaExhaustionDetector.js.map +1 -1
- package/dist/monitoring/SessionMonitor.d.ts.map +1 -1
- package/dist/monitoring/SessionMonitor.js +5 -2
- package/dist/monitoring/SessionMonitor.js.map +1 -1
- package/dist/monitoring/SessionRecovery.d.ts +16 -1
- package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
- package/dist/monitoring/SessionRecovery.js +71 -8
- package/dist/monitoring/SessionRecovery.js.map +1 -1
- package/dist/scaffold/templates.d.ts +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +32 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/scheduler/JobScheduler.js +1 -1
- package/dist/scheduler/JobScheduler.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +169 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +83 -67
- package/src/templates/hooks/intercept-imsg-send.js +68 -0
- package/src/templates/hooks/settings-template.json +11 -0
- package/src/templates/scripts/imessage-reply.sh +130 -0
- package/upgrades/0.26.4.md +17 -0
- package/upgrades/0.26.5.md +15 -0
package/dist/commands/server.js
CHANGED
|
@@ -865,8 +865,9 @@ function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory
|
|
|
865
865
|
telegram.trackMessageInjection(topicId, targetSession, text);
|
|
866
866
|
}
|
|
867
867
|
else {
|
|
868
|
-
// Session died —
|
|
868
|
+
// Session died — classify death cause before deciding how to respawn
|
|
869
869
|
let isQuotaDeath = false;
|
|
870
|
+
let isContextExhausted = false;
|
|
870
871
|
try {
|
|
871
872
|
const output = sessionManager.captureOutput(targetSession, 100);
|
|
872
873
|
if (output) {
|
|
@@ -877,10 +878,36 @@ function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory
|
|
|
877
878
|
telegram.sendToTopic(topicId, `🔴 Session died — quota limit reached.\n${classification.detail}\n\n` +
|
|
878
879
|
`Use /switch-account to switch, /login to add an account, or reply again to force restart.`).catch(() => { });
|
|
879
880
|
}
|
|
881
|
+
else if (classification.cause === 'context_exhausted') {
|
|
882
|
+
isContextExhausted = true;
|
|
883
|
+
telegram.sendToTopic(topicId, `🔄 Conversation got too long — starting a fresh session with your recent history.`).catch(() => { });
|
|
884
|
+
}
|
|
880
885
|
}
|
|
881
886
|
}
|
|
882
887
|
catch { /* classification failed — fall through to respawn */ }
|
|
883
|
-
if (
|
|
888
|
+
if (isContextExhausted) {
|
|
889
|
+
// Context exhaustion: respawn FRESH (no --resume) — the old conversation
|
|
890
|
+
// is too large to continue. The respawn path will load telegram thread
|
|
891
|
+
// history as context, giving the new session continuity.
|
|
892
|
+
if (spawningTopics.has(topicId)) {
|
|
893
|
+
console.log(`[telegram→session] Spawn already in progress for topic ${topicId} — skipping duplicate respawn`);
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
spawningTopics.add(topicId);
|
|
897
|
+
// Remove the resume UUID so respawnSessionForTopic doesn't try --resume
|
|
898
|
+
if (_topicResumeMap) {
|
|
899
|
+
_topicResumeMap.remove(topicId);
|
|
900
|
+
}
|
|
901
|
+
respawnSessionForTopic(sessionManager, telegram, targetSession, topicId, text, topicMemory, resolvedUser ?? undefined)
|
|
902
|
+
.catch(err => {
|
|
903
|
+
console.error(`[telegram→session] Context exhaustion respawn failed:`, err);
|
|
904
|
+
telegram.sendToTopic(topicId, `❌ Fresh session restart failed. Try sending your message again.`).catch(() => { });
|
|
905
|
+
})
|
|
906
|
+
.finally(() => {
|
|
907
|
+
spawningTopics.delete(topicId);
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
else if (!isQuotaDeath) {
|
|
884
911
|
// Guard: skip respawn if one is already in progress for this topic.
|
|
885
912
|
// Prevents the infinite respawn loop: dead session + rapid messages → each
|
|
886
913
|
// message triggers a new respawn → multiple concurrent spawns → chaos.
|
|
@@ -990,6 +1017,115 @@ function wireWhatsAppRouting(whatsapp, sessionManager) {
|
|
|
990
1017
|
}
|
|
991
1018
|
});
|
|
992
1019
|
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Wire iMessage message routing — mirrors Telegram's session patterns exactly.
|
|
1022
|
+
*
|
|
1023
|
+
* Routes incoming iMessages to Claude Code sessions using the same flow as Telegram:
|
|
1024
|
+
* 1. Existing alive session → injectIMessageMessage (with pendingInjections tracking)
|
|
1025
|
+
* 2. Existing dead session → respawn via spawnInteractiveSession(bootstrapMessage)
|
|
1026
|
+
* 3. No session → auto-spawn via spawnInteractiveSession(bootstrapMessage)
|
|
1027
|
+
*
|
|
1028
|
+
* Key design: the bootstrap message (with inline context) is passed as the
|
|
1029
|
+
* initialMessage to spawnInteractiveSession, which handles wait-for-ready and
|
|
1030
|
+
* injection internally — the same code path that Telegram uses successfully.
|
|
1031
|
+
*/
|
|
1032
|
+
function wireIMessageRouting(imessage, sessionManager) {
|
|
1033
|
+
const spawningSenders = new Set();
|
|
1034
|
+
// Wire session alive check for stall detection
|
|
1035
|
+
imessage.setIsSessionAlive((sessionName) => sessionManager.isSessionAlive(sessionName));
|
|
1036
|
+
const replyScript = '.claude/scripts/imessage-reply.sh';
|
|
1037
|
+
/**
|
|
1038
|
+
* Build a bootstrap message for spawning an iMessage session.
|
|
1039
|
+
* Follows Telegram's spawnSessionForTopic pattern: context is INLINE in the
|
|
1040
|
+
* bootstrap message, not a file reference. For long messages, writes to a temp
|
|
1041
|
+
* file with a strong read instruction (matching Telegram's BOOTSTRAP_FILE_THRESHOLD).
|
|
1042
|
+
*/
|
|
1043
|
+
function buildBootstrapMessage(sender, text, senderName) {
|
|
1044
|
+
// Get conversation history from chat.db (includes both user AND agent messages)
|
|
1045
|
+
const conversationContext = imessage.getConversationContext(sender, 30);
|
|
1046
|
+
const parts = [];
|
|
1047
|
+
if (conversationContext) {
|
|
1048
|
+
parts.push(`CONTINUATION — You are resuming an EXISTING conversation via iMessage.`, `Read the context below before responding.`, ``, conversationContext, ``, `IMPORTANT: Your response MUST acknowledge and continue the conversation above. Do NOT introduce yourself or ask "how can I help" — the user has been talking to you. Pick up where the conversation left off.`, ``);
|
|
1049
|
+
}
|
|
1050
|
+
// Sanitize sender name to prevent injection via chat.db display_name
|
|
1051
|
+
const safeSenderName = senderName ? senderName.replace(/[\[\]`$\\]/g, '') : undefined;
|
|
1052
|
+
// iMessage relay instructions
|
|
1053
|
+
parts.push(`--- iMessage SESSION (${sender}) ---`, `This is a PERSISTENT conversational session via iMessage.`, `MANDATORY: After EVERY response, relay your message back to the user:`, ` cat <<'EOF' | ${replyScript} "${sender}"`, ` Your response text here`, ` EOF`, ``, `CRITICAL: After replying, STAY AT THE PROMPT and wait for follow-up messages.`, `Do NOT exit. More messages will be injected as [imessage:${sender}] prefixed text.`, `Strip the [imessage:...] prefix before interpreting messages.`, `Only relay conversational text — not tool output or internal reasoning.`, `--- END iMessage SESSION ---`, ``, `The user's latest message:`, `[imessage:${sender}${safeSenderName ? ` from ${safeSenderName}` : ''}] ${text}`);
|
|
1054
|
+
let bootstrapMessage = parts.join('\n');
|
|
1055
|
+
// Large bootstrap messages: write to temp file with strong read instruction
|
|
1056
|
+
// (matches Telegram's BOOTSTRAP_FILE_THRESHOLD pattern)
|
|
1057
|
+
const BOOTSTRAP_FILE_THRESHOLD = 500;
|
|
1058
|
+
if (bootstrapMessage.length > BOOTSTRAP_FILE_THRESHOLD) {
|
|
1059
|
+
const tmpDir = '/tmp/instar-imessage';
|
|
1060
|
+
fs.mkdirSync(tmpDir, { recursive: true, mode: 0o700 });
|
|
1061
|
+
// Clean up old temp files (>1 hour) to prevent unbounded accumulation
|
|
1062
|
+
try {
|
|
1063
|
+
const cutoff = Date.now() - 3_600_000;
|
|
1064
|
+
for (const f of fs.readdirSync(tmpDir)) {
|
|
1065
|
+
const fp = path.join(tmpDir, f);
|
|
1066
|
+
try {
|
|
1067
|
+
if (fs.statSync(fp).mtimeMs < cutoff)
|
|
1068
|
+
fs.unlinkSync(fp);
|
|
1069
|
+
}
|
|
1070
|
+
catch { /* ignore */ }
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
catch { /* non-critical */ }
|
|
1074
|
+
const senderSlug = sender.replace(/[^a-zA-Z0-9]/g, '').slice(-8);
|
|
1075
|
+
const filepath = path.join(tmpDir, `bootstrap-${senderSlug}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.txt`);
|
|
1076
|
+
fs.writeFileSync(filepath, bootstrapMessage, { mode: 0o600 });
|
|
1077
|
+
console.log(`[imessage→session] Bootstrap too large (${bootstrapMessage.length} chars), wrote to ${filepath}`);
|
|
1078
|
+
bootstrapMessage = `[IMPORTANT: Read ${filepath} — it contains your full session context, conversation history, and the user's latest message. You MUST read this file before responding.]`;
|
|
1079
|
+
}
|
|
1080
|
+
return bootstrapMessage;
|
|
1081
|
+
}
|
|
1082
|
+
imessage.onMessage(async (msg) => {
|
|
1083
|
+
const sender = msg.channel?.identifier;
|
|
1084
|
+
if (!sender)
|
|
1085
|
+
return;
|
|
1086
|
+
const text = msg.content;
|
|
1087
|
+
const senderName = msg.metadata?.senderName ?? undefined;
|
|
1088
|
+
const senderNorm = sender.toLowerCase();
|
|
1089
|
+
// Skip empty messages (reactions, read receipts, lookback artifacts)
|
|
1090
|
+
if (!text || !text.trim())
|
|
1091
|
+
return;
|
|
1092
|
+
// Check for existing session
|
|
1093
|
+
const targetSession = imessage.getSessionForSender(sender);
|
|
1094
|
+
// Guard: skip if spawn already in progress for this sender
|
|
1095
|
+
if (spawningSenders.has(senderNorm)) {
|
|
1096
|
+
console.log(`[imessage→session] Spawn already in progress for ${senderNorm} — skipping`);
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
if (targetSession && sessionManager.isSessionAlive(targetSession)) {
|
|
1100
|
+
// Session alive — inject directly (same as Telegram's injectTelegramMessage path)
|
|
1101
|
+
console.log(`[imessage→session] Injecting into ${targetSession}: "${text.slice(0, 80)}"`);
|
|
1102
|
+
sessionManager.injectIMessageMessage(targetSession, sender, text, senderName);
|
|
1103
|
+
imessage.trackMessageInjection(sender, targetSession, text);
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
// Session dead or missing — spawn with full context (same as Telegram's spawnSessionForTopic)
|
|
1107
|
+
spawningSenders.add(senderNorm);
|
|
1108
|
+
// Use a hash of the full sender to avoid collisions (slice(-6) collides easily)
|
|
1109
|
+
const crypto = await import('node:crypto');
|
|
1110
|
+
const senderHash = crypto.createHash('sha1').update(sender.toLowerCase()).digest('hex').slice(0, 8);
|
|
1111
|
+
const sessionName = `im-${senderHash}`;
|
|
1112
|
+
const bootstrapMessage = buildBootstrapMessage(sender, text, senderName);
|
|
1113
|
+
// Pass bootstrap as initialMessage — spawnInteractiveSession handles
|
|
1114
|
+
// wait-for-ready and injection internally (same code path as Telegram)
|
|
1115
|
+
sessionManager.spawnInteractiveSession(bootstrapMessage, sessionName)
|
|
1116
|
+
.then((newSession) => {
|
|
1117
|
+
imessage.registerSession(sender, newSession);
|
|
1118
|
+
console.log(`[imessage→session] Spawned "${newSession}" for ${imessage.constructor.maskIdentifier?.(sender) || sender}`);
|
|
1119
|
+
})
|
|
1120
|
+
.catch((err) => {
|
|
1121
|
+
console.error(`[imessage→session] Spawn failed:`, err);
|
|
1122
|
+
})
|
|
1123
|
+
.finally(() => {
|
|
1124
|
+
spawningSenders.delete(senderNorm);
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
993
1129
|
/**
|
|
994
1130
|
* Ensure the Agent Attention topic exists — the agent's direct line to the user.
|
|
995
1131
|
* Created once on first server start, persisted in state.
|
|
@@ -2590,6 +2726,39 @@ export async function startServer(options) {
|
|
|
2590
2726
|
});
|
|
2591
2727
|
}
|
|
2592
2728
|
}
|
|
2729
|
+
// ── iMessage adapter initialization ────────────────────────────────
|
|
2730
|
+
let imessageAdapter;
|
|
2731
|
+
const imessageConfig = config.messaging?.find(m => m.type === 'imessage' && m.enabled);
|
|
2732
|
+
if (imessageConfig) {
|
|
2733
|
+
try {
|
|
2734
|
+
const { IMessageAdapter } = await import('../messaging/imessage/index.js');
|
|
2735
|
+
imessageAdapter = new IMessageAdapter(imessageConfig.config, config.stateDir);
|
|
2736
|
+
// Wire session routing (following Telegram/WhatsApp pattern)
|
|
2737
|
+
wireIMessageRouting(imessageAdapter, sessionManager);
|
|
2738
|
+
// Set agent name for mention-based triggering
|
|
2739
|
+
const imAgentName = imessageConfig.config?.agentName || config.projectName;
|
|
2740
|
+
if (imAgentName)
|
|
2741
|
+
imessageAdapter.setAgentName(imAgentName);
|
|
2742
|
+
await imessageAdapter.start();
|
|
2743
|
+
const triggerInfo = imessageAdapter.getTriggerMode() === 'mention'
|
|
2744
|
+
? `trigger: @${imAgentName}`
|
|
2745
|
+
: 'trigger: all messages';
|
|
2746
|
+
console.log(pc.green(` iMessage adapter: connected (${triggerInfo})`));
|
|
2747
|
+
console.log(pc.green(' iMessage message routing: wired'));
|
|
2748
|
+
}
|
|
2749
|
+
catch (err) {
|
|
2750
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
2751
|
+
console.error(pc.red(` iMessage init failed: ${reason}`));
|
|
2752
|
+
imessageAdapter = undefined;
|
|
2753
|
+
degradationReporter.report({
|
|
2754
|
+
feature: 'iMessage',
|
|
2755
|
+
primary: 'iMessage messaging adapter',
|
|
2756
|
+
fallback: 'Other messaging channels',
|
|
2757
|
+
reason: `iMessage init failed: ${reason}`,
|
|
2758
|
+
impact: 'iMessage messaging unavailable.',
|
|
2759
|
+
});
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2593
2762
|
// Initialize SemanticMemory — the knowledge graph that unifies all memory systems.
|
|
2594
2763
|
// Uses the same better-sqlite3 as TopicMemory; shares the rebuild path.
|
|
2595
2764
|
let semanticMemory;
|
|
@@ -3122,6 +3291,22 @@ export async function startServer(options) {
|
|
|
3122
3291
|
if (telegram)
|
|
3123
3292
|
await telegram.sendToTopic(topicId, message);
|
|
3124
3293
|
},
|
|
3294
|
+
captureSessionOutput: (name, lines) => {
|
|
3295
|
+
return sessionManager.captureOutput(name, lines);
|
|
3296
|
+
},
|
|
3297
|
+
respawnSessionFresh: async (topicId, _sessionName, recoveryPrompt) => {
|
|
3298
|
+
// Fresh respawn for context exhaustion — explicitly clear resume UUID
|
|
3299
|
+
// so the new session starts clean with telegram history, not --resume.
|
|
3300
|
+
if (_topicResumeMap) {
|
|
3301
|
+
_topicResumeMap.remove(topicId);
|
|
3302
|
+
}
|
|
3303
|
+
if (telegram) {
|
|
3304
|
+
const targetSession = telegram.getSessionForTopic(topicId);
|
|
3305
|
+
if (!targetSession)
|
|
3306
|
+
return;
|
|
3307
|
+
await respawnSessionForTopic(sessionManager, telegram, targetSession, topicId, undefined, topicMemory, undefined, recoveryPrompt, { silent: true });
|
|
3308
|
+
}
|
|
3309
|
+
},
|
|
3125
3310
|
});
|
|
3126
3311
|
console.log(pc.green(' Session Recovery enabled (mechanical fast-path)'));
|
|
3127
3312
|
}
|
|
@@ -4408,7 +4593,7 @@ export async function startServer(options) {
|
|
|
4408
4593
|
return { content: lines.join('\n'), truncated: false, elapsedMs: Date.now() - start };
|
|
4409
4594
|
}, { description: 'Feature discovery state and behavioral contract summary' });
|
|
4410
4595
|
}
|
|
4411
|
-
const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, whatsapp: whatsappAdapter, slack: slackAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, threadlineRelayClient, listenerManager: listenerManager ?? undefined, responseReviewGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, liveConfig });
|
|
4596
|
+
const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, threadlineRelayClient, listenerManager: listenerManager ?? undefined, responseReviewGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, liveConfig });
|
|
4412
4597
|
await server.start();
|
|
4413
4598
|
// Connect DegradationReporter downstream systems now that everything is initialized.
|
|
4414
4599
|
// Any degradation events queued during startup will drain to feedback + telegram.
|