instar 1.3.399 → 1.3.400

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.
Files changed (34) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +73 -5
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/QuotaAwareScheduler.d.ts +96 -0
  5. package/dist/core/QuotaAwareScheduler.d.ts.map +1 -0
  6. package/dist/core/QuotaAwareScheduler.js +134 -0
  7. package/dist/core/QuotaAwareScheduler.js.map +1 -0
  8. package/dist/core/SessionManager.d.ts +6 -0
  9. package/dist/core/SessionManager.d.ts.map +1 -1
  10. package/dist/core/SessionManager.js +6 -0
  11. package/dist/core/SessionManager.js.map +1 -1
  12. package/dist/core/SessionRefresh.d.ts +18 -1
  13. package/dist/core/SessionRefresh.d.ts.map +1 -1
  14. package/dist/core/SessionRefresh.js +4 -1
  15. package/dist/core/SessionRefresh.js.map +1 -1
  16. package/dist/core/frameworkSessionLaunch.d.ts +10 -0
  17. package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
  18. package/dist/core/frameworkSessionLaunch.js +10 -6
  19. package/dist/core/frameworkSessionLaunch.js.map +1 -1
  20. package/dist/core/types.d.ts +18 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/server/AgentServer.d.ts +1 -0
  24. package/dist/server/AgentServer.d.ts.map +1 -1
  25. package/dist/server/AgentServer.js +1 -0
  26. package/dist/server/AgentServer.js.map +1 -1
  27. package/dist/server/routes.d.ts +2 -0
  28. package/dist/server/routes.d.ts.map +1 -1
  29. package/dist/server/routes.js +26 -0
  30. package/dist/server/routes.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/data/builtin-manifest.json +48 -48
  33. package/upgrades/1.3.400.md +55 -0
  34. package/upgrades/side-effects/subscription-auth-scheduler.md +90 -0
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA84BD,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,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAy5TtE;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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA05BD,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,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAk9TtE;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"}
@@ -378,7 +378,14 @@ let _slackAdapter = null;
378
378
  // Null until startServer constructs it; the Telegram /restart handler falls
379
379
  // back to the inline kill+respawn path when null (e.g. early in boot).
380
380
  let _sessionRefresh = null;
381
- async function spawnSessionForTopic(sessionManager, telegram, sessionName, topicId, latestMessage, topicMemory, userProfile, precomputedContext) {
381
+ // Subscription & Auth Standard P1.3 quota-aware account-swap scheduler. Null
382
+ // until wired (requires SessionRefresh + the subscription pool).
383
+ let _quotaAwareScheduler = null;
384
+ async function spawnSessionForTopic(sessionManager, telegram, sessionName, topicId, latestMessage, topicMemory, userProfile, precomputedContext,
385
+ /** Subscription & Auth Standard P1.3 (additive): launch under this account's
386
+ * config home + record its id (the quota-aware account-swap mechanism).
387
+ * Omitted = unchanged behaviour. */
388
+ accountSwap) {
382
389
  const msg = latestMessage || 'Session started — send a message to continue.';
383
390
  // If memory is elevated/critical and we have the reaper, try to free memory
384
391
  // by cleaning orphans before spawning. Interactive sessions are NEVER blocked
@@ -619,6 +626,10 @@ async function spawnSessionForTopic(sessionManager, telegram, sessionName, topic
619
626
  framework,
620
627
  ...(codexLocalProvider ? { codexLocalProvider } : {}),
621
628
  ...(codexLocalModelOverride ? { defaultModel: codexLocalModelOverride } : {}),
629
+ // Subscription & Auth Standard P1.3 (additive): account-swap — launch under
630
+ // this account's config home + record its id. Unset = unchanged.
631
+ ...(accountSwap?.configHome ? { configHome: accountSwap.configHome } : {}),
632
+ ...(accountSwap?.accountId ? { subscriptionAccountId: accountSwap.accountId } : {}),
622
633
  });
623
634
  // Clear the resume entry after successful spawn to prevent stale reuse
624
635
  if (resumeSessionId) {
@@ -696,7 +707,7 @@ async function respawnSessionForTopic(sessionManager, telegram, targetSession, t
696
707
  const effectiveMessage = recoveryPrompt
697
708
  ? `${recoveryPrompt}\n\n${latestMessage || 'Session recovered — continue where you left off.'}`
698
709
  : latestMessage;
699
- const newSessionName = await spawnSessionForTopic(sessionManager, telegram, topicName, topicId, effectiveMessage, topicMemory, userProfile);
710
+ const newSessionName = await spawnSessionForTopic(sessionManager, telegram, topicName, topicId, effectiveMessage, topicMemory, userProfile, undefined, (options?.configHome || options?.accountId) ? { configHome: options?.configHome, accountId: options?.accountId } : undefined);
700
711
  telegram.registerTopicSession(topicId, newSessionName, topicName);
701
712
  if (!options?.silent) {
702
713
  await telegram.sendToTopic(topicId, `Session respawned.`);
@@ -9261,15 +9272,72 @@ export async function startServer(options) {
9261
9272
  state,
9262
9273
  telegram: telegramRef,
9263
9274
  topicResumeMap: _topicResumeMap,
9264
- respawner: async (sessionName, topicId, followUpPrompt) => {
9275
+ respawner: async (sessionName, topicId, followUpPrompt, accountSwap) => {
9265
9276
  // killSession (called inside SessionRefresh) has already fired
9266
9277
  // beforeSessionKill (UUID persisted) and destroyed the tmux
9267
9278
  // session. respawnSessionForTopic spawns the new tmux running
9268
9279
  // `claude --resume <uuid>` and registers the topic mapping.
9269
- await respawnSessionForTopic(sessionManager, telegramRef, sessionName, topicId, followUpPrompt, topicMemory);
9280
+ // P1.3: accountSwap (when present) re-launches the resume under a
9281
+ // different account's config home — the --resume uuid is account-
9282
+ // agnostic, so the conversation is preserved across the swap.
9283
+ await respawnSessionForTopic(sessionManager, telegramRef, sessionName, topicId, followUpPrompt, topicMemory, undefined, undefined, accountSwap ? { configHome: accountSwap.configHome, accountId: accountSwap.accountId } : undefined);
9270
9284
  return telegramRef.getSessionForTopic(topicId) ?? sessionName;
9271
9285
  },
9272
9286
  });
9287
+ // ── QuotaAwareScheduler (Subscription & Auth Standard P1.3) ──
9288
+ // Selects the optimal account + enforces the continuity guarantee: on
9289
+ // quota pressure it resumes the session under another account (via the
9290
+ // SessionRefresh account-swap path), never letting it die. Auto-trigger
9291
+ // off RateLimitSentinel ships DARK behind a config flag (default off);
9292
+ // the manual route + selection logic are always available.
9293
+ const { QuotaAwareScheduler } = await import('../core/QuotaAwareScheduler.js');
9294
+ _quotaAwareScheduler = new QuotaAwareScheduler({
9295
+ listAccounts: () => subscriptionPool.list(),
9296
+ softThresholdPct: config.subscriptionPool?.swapSoftThresholdPct,
9297
+ refreshFn: async (o) => {
9298
+ if (!_sessionRefresh)
9299
+ return false;
9300
+ const r = await _sessionRefresh.refreshSession({
9301
+ sessionName: o.sessionName,
9302
+ reason: o.reason,
9303
+ configHome: o.configHome,
9304
+ accountId: o.accountId,
9305
+ });
9306
+ return r.ok;
9307
+ },
9308
+ onNoAlternate: (sessionName, exhaustedAccountId) => {
9309
+ void telegramRef.createAttentionItem({
9310
+ id: `subpool-no-alternate-${exhaustedAccountId}`,
9311
+ title: 'Subscription pool — no alternate account to swap to',
9312
+ summary: `Session "${sessionName}" hit account "${exhaustedAccountId}"'s quota and there's no other eligible account in the pool. The session falls back to the existing rate-limit back-off; consider enrolling another account.`,
9313
+ category: 'subscription-pool',
9314
+ priority: 'HIGH',
9315
+ sourceContext: 'subscription-pool:no-alternate',
9316
+ }).catch(() => { });
9317
+ },
9318
+ logger: { log: (m) => console.log(m), warn: (m) => console.warn(m) },
9319
+ });
9320
+ // DARK auto-trigger: only when explicitly enabled does a rate-limit
9321
+ // escalation drive an account swap. Default off — opt-in per Justin's
9322
+ // tier-2 sign-off (auto-swapping live sessions is real authority).
9323
+ if (config.subscriptionPool?.autoSwapOnRateLimit) {
9324
+ rateLimitSentinel.on('rate-limit:escalated', (rlState) => {
9325
+ const sessionName = rlState?.sessionName;
9326
+ if (!sessionName)
9327
+ return;
9328
+ // Resolve which account this session is running under; only pool-managed
9329
+ // sessions are swap-eligible (others fall back to the existing back-off).
9330
+ const accountId = state.listSessions({ status: 'running' })
9331
+ .find(s => s.tmuxSession === sessionName)?.subscriptionAccountId;
9332
+ if (!accountId)
9333
+ return;
9334
+ void _quotaAwareScheduler?.onQuotaPressure({
9335
+ sessionName,
9336
+ exhaustedAccountId: accountId,
9337
+ nowMs: Date.now(),
9338
+ });
9339
+ });
9340
+ }
9273
9341
  }
9274
9342
  // ── SessionReaper (SESSION-REAPER-SPEC) ──────────────────────────────
9275
9343
  // Pressure-aware reaper of idle-but-alive sessions. Ships OFF + dry-run by
@@ -11214,7 +11282,7 @@ export async function startServer(options) {
11214
11282
  catch (err) {
11215
11283
  console.log(pc.dim(` [session-pool] rollout gate not wired: ${err instanceof Error ? err.message : String(err)}`));
11216
11284
  }
11217
- 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, subscriptionPool, quotaPoller, 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, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, forwardCommitmentMutate, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? 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 });
11285
+ 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, subscriptionPool, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, 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, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, forwardCommitmentMutate, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? 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 });
11218
11286
  // Resolve the late-bound topic-operator getter (increment 2e): routing was
11219
11287
  // wired before the server existed; from here on inbound binds use the
11220
11288
  // server's own store instance.