instar 1.3.245 → 1.3.247
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.map +1 -1
- package/dist/commands/server.js +147 -8
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +13 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +15 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/RelocationNicknameSet.d.ts +42 -0
- package/dist/core/RelocationNicknameSet.d.ts.map +1 -0
- package/dist/core/RelocationNicknameSet.js +47 -0
- package/dist/core/RelocationNicknameSet.js.map +1 -0
- package/dist/core/SessionManager.d.ts +3 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +3 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/TopicPlacementDescription.d.ts +46 -0
- package/dist/core/TopicPlacementDescription.d.ts.map +1 -0
- package/dist/core/TopicPlacementDescription.js +32 -0
- package/dist/core/TopicPlacementDescription.js.map +1 -0
- package/dist/core/frameworkInjectionProcesses.d.ts +41 -0
- package/dist/core/frameworkInjectionProcesses.d.ts.map +1 -0
- package/dist/core/frameworkInjectionProcesses.js +53 -0
- package/dist/core/frameworkInjectionProcesses.js.map +1 -0
- package/dist/core/frameworkSessionLaunch.d.ts +9 -0
- package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
- package/dist/core/frameworkSessionLaunch.js +7 -0
- package/dist/core/frameworkSessionLaunch.js.map +1 -1
- package/dist/core/types.d.ts +22 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/messaging/SpawnRequestManager.d.ts +13 -0
- package/dist/messaging/SpawnRequestManager.d.ts.map +1 -1
- package/dist/messaging/SpawnRequestManager.js +3 -0
- package/dist/messaging/SpawnRequestManager.js.map +1 -1
- package/dist/messaging/types.d.ts.map +1 -1
- package/dist/messaging/types.js +8 -1
- package/dist/messaging/types.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +3 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +6 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +3 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +11 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +163 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/ThreadlineRouter.d.ts +55 -1
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
- package/dist/threadline/ThreadlineRouter.js +246 -6
- package/dist/threadline/ThreadlineRouter.js.map +1 -1
- package/dist/threadline/WarmSessionPool.d.ts +22 -0
- package/dist/threadline/WarmSessionPool.d.ts.map +1 -1
- package/dist/threadline/WarmSessionPool.js +38 -0
- package/dist/threadline/WarmSessionPool.js.map +1 -1
- package/package.json +1 -1
- package/scripts/instar-dev-precommit.js +42 -0
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +3 -1
- package/upgrades/1.3.246.md +97 -0
- package/upgrades/1.3.247.md +48 -0
- package/upgrades/side-effects/mm-placement-transfer-robustness.md +45 -0
- package/upgrades/side-effects/threadline-warm-session-a2a.md +146 -0
- package/upgrades/threadline-warm-session-a2a.eli16.md +63 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAgxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmzQtE;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
|
@@ -122,7 +122,8 @@ import { pickupDroppedMessages } from '../messaging/DropPickup.js';
|
|
|
122
122
|
import { pickupGitSyncMessages } from '../messaging/GitSyncTransport.js';
|
|
123
123
|
import { DeliveryRetryManager } from '../messaging/DeliveryRetryManager.js';
|
|
124
124
|
import { SpawnRequestManager } from '../messaging/SpawnRequestManager.js';
|
|
125
|
-
import { ThreadlineRouter } from '../threadline/ThreadlineRouter.js';
|
|
125
|
+
import { ThreadlineRouter, trustMeetsFloor } from '../threadline/ThreadlineRouter.js';
|
|
126
|
+
import { WarmSessionPool } from '../threadline/WarmSessionPool.js';
|
|
126
127
|
import { resolveThreadlineMcpEntry } from '../threadline/mcpEntry.js';
|
|
127
128
|
import { ThreadResumeMap } from '../threadline/ThreadResumeMap.js';
|
|
128
129
|
import { ConversationStore } from '../threadline/ConversationStore.js';
|
|
@@ -7116,6 +7117,42 @@ export async function startServer(options) {
|
|
|
7116
7117
|
?? 5,
|
|
7117
7118
|
getActiveSessions: () => sessionManager.listRunningSessions(),
|
|
7118
7119
|
spawnSession: async (prompt, opts) => {
|
|
7120
|
+
// Warm-session A2A (Arch Y): when the SpawnRequest is flagged interactive,
|
|
7121
|
+
// launch a PERSISTENT (keep-alive) interactive worker instead of the
|
|
7122
|
+
// headless one-shot `claude -p`. The grounded prompt is delivered as the
|
|
7123
|
+
// worker's FIRST turn (after-ready inject), and the worker stays alive so
|
|
7124
|
+
// follow-ups inject into the same session. The MCP/permission flag set
|
|
7125
|
+
// matches the `-p` path: claude interactive keeps the PROJECT MCP (where
|
|
7126
|
+
// threadline_send lives) under --dangerously-skip-permissions, and codex
|
|
7127
|
+
// interactive launches with --dangerously-bypass-approvals-and-sandbox +
|
|
7128
|
+
// the per-agent threadline MCP (the bypass the `-p` codexAllowMcpTools
|
|
7129
|
+
// selects) — so threadline_send is available either way.
|
|
7130
|
+
if (opts?.interactive) {
|
|
7131
|
+
const warmName = `msg-warm-${Date.now()}`;
|
|
7132
|
+
// Framework-GENERAL: the warm worker runs in the LOCAL agent's
|
|
7133
|
+
// framework (claude-code / codex-cli / gemini-cli), NOT hardcoded
|
|
7134
|
+
// Claude. spawnInteractiveSession + frameworkSessionLaunch compose the
|
|
7135
|
+
// right argv + MCP/permission flags per framework (claude keeps PROJECT
|
|
7136
|
+
// MCP under --dangerously-skip-permissions; codex launches under
|
|
7137
|
+
// --dangerously-bypass-approvals-and-sandbox with its per-agent
|
|
7138
|
+
// threadline MCP) so threadline_send works regardless of framework.
|
|
7139
|
+
// A2A reply threads have no topic, so the agent default framework
|
|
7140
|
+
// applies (mirrors resolveTopicFramework's own fallback).
|
|
7141
|
+
const tmuxSession = await sessionManager.spawnInteractiveSession(prompt, warmName, {
|
|
7142
|
+
framework: _defaultFramework,
|
|
7143
|
+
// Deterministic conversation id for lossless eviction→resume (#746).
|
|
7144
|
+
// frameworkSessionLaunch maps this per framework: claude-code pins
|
|
7145
|
+
// `--session-id`; codex/gemini ignore it (they resume by their own
|
|
7146
|
+
// mechanism). NOT a Claude assumption — it's the abstraction's job.
|
|
7147
|
+
sessionId: opts?.sessionId,
|
|
7148
|
+
});
|
|
7149
|
+
// spawnInteractiveSession returns the tmux name; resolve the instar
|
|
7150
|
+
// session id from the running set so the warm callback returns the
|
|
7151
|
+
// slice-2 {sessionId, tmuxSession} shape spawnWarmThread expects.
|
|
7152
|
+
const running = sessionManager.listRunningSessions();
|
|
7153
|
+
const rec = running.find(s => s.tmuxSession === tmuxSession);
|
|
7154
|
+
return { sessionId: rec?.id ?? tmuxSession, tmuxSession };
|
|
7155
|
+
}
|
|
7119
7156
|
const session = await sessionManager.spawnSession({
|
|
7120
7157
|
name: `msg-spawn-${Date.now()}`,
|
|
7121
7158
|
prompt,
|
|
@@ -7222,9 +7259,66 @@ export async function startServer(options) {
|
|
|
7222
7259
|
else {
|
|
7223
7260
|
console.log('[spawn-manager] drain loop disabled by config.threadline.spawn.drainEnabled=false');
|
|
7224
7261
|
}
|
|
7262
|
+
// Warm-Session A2A (Arch Y, dark-ship) — keep each A2A reply thread's session
|
|
7263
|
+
// alive between messages so follow-ups inject into the live worker instead of
|
|
7264
|
+
// cold-spawning. Resolved via the developmentAgent gate: `enabled ?? !!dev` →
|
|
7265
|
+
// LIVE on Echo, DARK on the fleet. The pool is null when disabled, so the
|
|
7266
|
+
// ThreadlineRouter falls back to the proven cold-spawn path byte-for-byte.
|
|
7267
|
+
const warmCfg = config.threadline?.warmSessionA2A;
|
|
7268
|
+
const warmEnabled = warmCfg?.enabled ?? !!config.developmentAgent;
|
|
7269
|
+
const warmSessionPool = warmEnabled
|
|
7270
|
+
? new WarmSessionPool({
|
|
7271
|
+
globalCap: warmCfg?.globalCap ?? 3,
|
|
7272
|
+
perPeerCap: warmCfg?.perPeerCap ?? 1,
|
|
7273
|
+
ttlMs: warmCfg?.ttlMs ?? 600000,
|
|
7274
|
+
})
|
|
7275
|
+
: null;
|
|
7276
|
+
const warmTrustFloor = warmCfg?.trustFloor ?? 'verified';
|
|
7277
|
+
// Server-owned kill primitive: resolve the tmux NAME → instar session id →
|
|
7278
|
+
// killSession (sessions are filed by id, not tmux name). Used for cap-eviction
|
|
7279
|
+
// on admit and the periodic reap tick. Never throws to the caller.
|
|
7280
|
+
const killWarmSessionByName = (sessionName) => {
|
|
7281
|
+
try {
|
|
7282
|
+
const rec = sessionManager.listRunningSessions().find(s => s.tmuxSession === sessionName);
|
|
7283
|
+
if (rec)
|
|
7284
|
+
sessionManager.killSession(rec.id);
|
|
7285
|
+
else
|
|
7286
|
+
console.log(`[warm-session] kill requested for ${sessionName} but no running session matched (already gone?)`);
|
|
7287
|
+
}
|
|
7288
|
+
catch (err) {
|
|
7289
|
+
console.warn(`[warm-session] kill ${sessionName} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
7290
|
+
}
|
|
7291
|
+
};
|
|
7292
|
+
if (warmEnabled) {
|
|
7293
|
+
console.log(`[warm-session] A2A keep-alive ENABLED (globalCap=${warmCfg?.globalCap ?? 3}, perPeerCap=${warmCfg?.perPeerCap ?? 1}, ttlMs=${warmCfg?.ttlMs ?? 600000}, trustFloor=${warmTrustFloor})`);
|
|
7294
|
+
}
|
|
7225
7295
|
// Threadline Router — handles threaded cross-agent conversations via relay
|
|
7226
7296
|
const threadlineRouter = new ThreadlineRouter(messageRouter, spawnManager, threadResumeMap, messageStore, { localAgent: config.projectName, localMachine: os.hostname() }, null, // autonomyGate
|
|
7227
|
-
messageDelivery
|
|
7297
|
+
messageDelivery, // PR-4: live-session injection path
|
|
7298
|
+
undefined, // onLedgerEvent (wired below via registerLedgerEmitters if present)
|
|
7299
|
+
undefined, // nowFn
|
|
7300
|
+
warmSessionPool, // Warm-Session A2A (null when disabled)
|
|
7301
|
+
warmEnabled, warmTrustFloor, warmEnabled ? killWarmSessionByName : null);
|
|
7302
|
+
// Warm-Session A2A reap tick — kill warm sessions idle past their TTL so a
|
|
7303
|
+
// flood can't pin processes. Gated on warmEnabled; .unref() so it never holds
|
|
7304
|
+
// the process open; cleared on shutdown. Eviction is lossless (the next
|
|
7305
|
+
// message resumes via #746).
|
|
7306
|
+
let warmReapTimer = null;
|
|
7307
|
+
if (warmEnabled && warmSessionPool) {
|
|
7308
|
+
warmReapTimer = setInterval(() => {
|
|
7309
|
+
try {
|
|
7310
|
+
const expired = warmSessionPool.reapExpired();
|
|
7311
|
+
for (const rec of expired) {
|
|
7312
|
+
console.log(`[warm-session] reaping idle warm session ${rec.sessionName} (thread ${rec.threadId})`);
|
|
7313
|
+
killWarmSessionByName(rec.sessionName);
|
|
7314
|
+
}
|
|
7315
|
+
}
|
|
7316
|
+
catch (err) {
|
|
7317
|
+
console.warn(`[warm-session] reap tick failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
7318
|
+
}
|
|
7319
|
+
}, 60_000);
|
|
7320
|
+
warmReapTimer.unref();
|
|
7321
|
+
}
|
|
7228
7322
|
sessionManager.on('sessionComplete', (session) => {
|
|
7229
7323
|
const sessionName = session.tmuxSession || session.name;
|
|
7230
7324
|
if (!sessionName)
|
|
@@ -7784,11 +7878,19 @@ export async function startServer(options) {
|
|
|
7784
7878
|
transport: { protocol: 'relay', origin: { agent: senderFingerprint, machine: 'relay' }, nonce: `${crypto.randomUUID()}:${new Date().toISOString()}`, timestamp: new Date().toISOString() },
|
|
7785
7879
|
delivery: { status: 'delivered', attempts: 1, lastAttempt: new Date().toISOString() },
|
|
7786
7880
|
};
|
|
7881
|
+
// Warm-Session A2A (Arch Y, dark-ship): mark this inbound as eligible for
|
|
7882
|
+
// a keep-alive interactive worker when the feature is on, it's NOT a
|
|
7883
|
+
// topic-bound reply (those go to TopicLinkageHandler), and the peer meets
|
|
7884
|
+
// the trust floor. Trust compare via the explicit ordering array
|
|
7885
|
+
// (trustMeetsFloor), NEVER string `>=`. When false (or feature off), the
|
|
7886
|
+
// router takes the proven cold-spawn path byte-for-byte.
|
|
7887
|
+
const preferWarmSession = warmEnabled && !isTopicBoundReply && trustMeetsFloor(trustLevel, warmTrustFloor);
|
|
7787
7888
|
const relayContext = {
|
|
7788
7889
|
trust: { kind: 'plaintext-tofu', senderFingerprint },
|
|
7789
7890
|
senderFingerprint,
|
|
7790
7891
|
senderName,
|
|
7791
7892
|
trustLevel,
|
|
7893
|
+
preferWarmSession,
|
|
7792
7894
|
};
|
|
7793
7895
|
let result = await threadlineRouter.handleInboundMessage(envelope, relayContext);
|
|
7794
7896
|
// Fallback for threadId-less messages
|
|
@@ -9246,17 +9348,50 @@ export async function startServer(options) {
|
|
|
9246
9348
|
const nickMod = await import('../core/NicknameCommand.js');
|
|
9247
9349
|
const transferMod = await import('../core/TransferByNickname.js');
|
|
9248
9350
|
const pinMod = await import('../core/TopicPlacementPinStore.js');
|
|
9351
|
+
const relocSetMod = await import('../core/RelocationNicknameSet.js');
|
|
9352
|
+
const nickAssignMod = await import('../core/NicknameAssigner.js');
|
|
9249
9353
|
_topicPinStore = new pinMod.TopicPlacementPinStore({
|
|
9250
9354
|
filePath: path.join(config.stateDir, 'session-pool', 'topic-pins.json'),
|
|
9251
9355
|
});
|
|
9356
|
+
// Authoritative resolver for THIS machine's OWN nickname. Guarantees a topic
|
|
9357
|
+
// can always be moved BACK to the machine currently handling it, even when the
|
|
9358
|
+
// capacities view omits the self nickname (the back-transfer bug: the lifeline
|
|
9359
|
+
// forwards inbound to the holder, so the relocation check runs on the very
|
|
9360
|
+
// machine the user is moving back to). Priority: capacities self-entry →
|
|
9361
|
+
// identity registry self-entry → deterministic derive (reconstructs the
|
|
9362
|
+
// auto-assigned nickname; a manual rename is persisted on the identity entry).
|
|
9363
|
+
const resolveSelfNickname = (caps) => {
|
|
9364
|
+
const fromCaps = caps.find((c) => c.machineId === meshSelfId)?.nickname;
|
|
9365
|
+
if (fromCaps)
|
|
9366
|
+
return fromCaps;
|
|
9367
|
+
try {
|
|
9368
|
+
const selfEntry = meshIdMgr
|
|
9369
|
+
.getActiveMachines()
|
|
9370
|
+
.find((m) => m.machineId === meshSelfId)?.entry;
|
|
9371
|
+
if (selfEntry?.nickname)
|
|
9372
|
+
return selfEntry.nickname;
|
|
9373
|
+
const id = meshIdMgr.hasIdentity()
|
|
9374
|
+
? meshIdMgr.loadIdentity()
|
|
9375
|
+
: null;
|
|
9376
|
+
const derived = nickAssignMod.deriveBaseNickname(id?.name, selfEntry?.hardware?.platform);
|
|
9377
|
+
if (derived)
|
|
9378
|
+
return derived;
|
|
9379
|
+
}
|
|
9380
|
+
catch {
|
|
9381
|
+
/* @silent-fallback-ok — best-effort self-nickname resolution; on any failure we
|
|
9382
|
+
return undefined and the recognizer simply falls back to the capacities-derived
|
|
9383
|
+
set (the pre-existing behavior), so this can only ever ADD a nickname, never break. */
|
|
9384
|
+
}
|
|
9385
|
+
return undefined;
|
|
9386
|
+
};
|
|
9252
9387
|
_tryNicknameRelocation = async (topicId, text) => {
|
|
9253
9388
|
const sessionKey = String(topicId);
|
|
9254
9389
|
const caps = machinePoolRegistry?.getCapacities() ?? [];
|
|
9255
|
-
const nickToMachine =
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9390
|
+
const { knownNicknames, nickToMachine } = relocSetMod.buildRelocationNicknameSet({
|
|
9391
|
+
capacities: caps,
|
|
9392
|
+
selfMachineId: meshSelfId,
|
|
9393
|
+
selfNickname: resolveSelfNickname(caps),
|
|
9394
|
+
});
|
|
9260
9395
|
const cmd = nickMod.recognizeNicknameCommand(text, knownNicknames);
|
|
9261
9396
|
if (!cmd)
|
|
9262
9397
|
return { handled: false };
|
|
@@ -9372,7 +9507,7 @@ export async function startServer(options) {
|
|
|
9372
9507
|
catch (err) {
|
|
9373
9508
|
console.log(pc.dim(` [session-pool] rollout gate not wired: ${err instanceof Error ? err.message : String(err)}`));
|
|
9374
9509
|
}
|
|
9375
|
-
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, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, sessionOwnershipRegistry, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier });
|
|
9510
|
+
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, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier });
|
|
9376
9511
|
// Boot-recovery (tunnel-failure-resilience spec Part 6): if the agent
|
|
9377
9512
|
// died mid-relay-episode, the persisted tunnel.json carries
|
|
9378
9513
|
// rotationPending=true. Rotate the dashboard PIN + authToken BEFORE
|
|
@@ -9738,6 +9873,10 @@ export async function startServer(options) {
|
|
|
9738
9873
|
await notificationBatcher.flushAll(); // Drain pending notifications before exit
|
|
9739
9874
|
notificationBatcher.stop();
|
|
9740
9875
|
retryManager.stop();
|
|
9876
|
+
if (warmReapTimer) {
|
|
9877
|
+
clearInterval(warmReapTimer);
|
|
9878
|
+
warmReapTimer = null;
|
|
9879
|
+
} // Warm-Session A2A reap tick
|
|
9741
9880
|
spawnManager.dispose(); // §4.4: stop drain loop + clear DRR state
|
|
9742
9881
|
summarySentinel.stop();
|
|
9743
9882
|
memoryMonitor.stop();
|