@link-assistant/hive-mind 2.13.5 → 2.15.0

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.
@@ -507,6 +507,17 @@ export const SOLVE_OPTION_DEFINITIONS = {
507
507
  description: '[EXPERIMENTAL] When --accept-incomming-comments-as-input is enabled, queue new PR/issue comments and only flush them once the AI signals it is idle (waiting for input). This is the default mode implied by --auto-input-until-mergeable so the AI completes the current step before being interrupted with new instructions. Mutually exclusive with --stream-comments-to-input; queue mode wins if both are set. Only supported for --tool claude and --tool agent.',
508
508
  default: false,
509
509
  },
510
+ // Issue #2164: route the task's model traffic through a `hive-mind-router`
511
+ // sidecar instead of bind-mounting the operator's vendor credentials into
512
+ // the task container. The task then holds a token scoped to itself alone,
513
+ // every request lands in that token's own audit log, and the subscription
514
+ // never leaves the sidecar. Experimental: GitHub traffic and `--model
515
+ // formal-ai` are not routed yet (see docs/ROUTER.md).
516
+ 'use-router': {
517
+ type: 'boolean',
518
+ description: '[EXPERIMENTAL] Route model traffic through the hive-mind-router sidecar instead of mounting Claude/Codex credentials into the task container. Each task receives its own scoped, short-lived token and its own request log, and the AI subscription stays in the router. Requires --isolation docker (or the Telegram bot in docker isolation mode).',
519
+ default: false,
520
+ },
510
521
  'prompt-explore-sub-agent': {
511
522
  type: 'boolean',
512
523
  description: 'Encourage AI to use Explore-style sub-agent workflow for codebase exploration. Supported for --tool claude and --tool codex.',
@@ -592,6 +603,11 @@ export const SOLVE_OPTION_DEFINITIONS = {
592
603
  description: 'Disable Claude Code built-in tools and MCP servers that have no value (and may be harmful) in autonomous headless runs: AskUserQuestion, CronCreate/Delete/List, EnterPlanMode/ExitPlanMode, EnterWorktree/ExitWorktree, Monitor, NotebookEdit, PushNotification, RemoteTrigger, ScheduleWakeup, and the claude.ai Gmail/Drive/Calendar OAuth connectors. Default: true. Use --no-useless-tools-disabled to keep them enabled. Supported for --tool claude (issue #1627).',
593
604
  default: true,
594
605
  },
606
+ 'agent-memory-disabled': {
607
+ type: 'boolean',
608
+ description: "Disable every AI tool's own cross-task memory and permission classifier, so the repository stays the only memory a task keeps. For --tool codex: -c features.memories=false and -c features.external_agent_memory_import=false. For --tool gemini and --tool qwen: tools.exclude=[save_memory] and experimental.autoMemory=false. --tool opencode and --tool agent have no cross-session memory feature. Default: true; --no-agent-memory-disabled lets those tools keep their own memory. For --tool claude the same switches (CLAUDE_CODE_DISABLE_AUTO_MEMORY, CLAUDE_CODE_DISABLE_ORG_MEMORY, autoMemoryEnabled=false, permissions.disableAutoMode=disable) are part of the quiet configuration baked into the Docker image, so they stay off regardless of this flag (issue #2178).",
609
+ default: true,
610
+ },
595
611
  'auto-gh-configuration-repair': {
596
612
  type: 'boolean',
597
613
  description: 'Automatically repair git configuration using gh-setup-git-identity --repair when git identity is not configured. Requires gh-setup-git-identity to be installed.',
@@ -63,6 +63,11 @@ export const createYargsConfig = yargsInstance =>
63
63
  choices: ['screen', 'none', 'docker'],
64
64
  default: 'docker',
65
65
  })
66
+ .option('use-router', {
67
+ type: 'boolean',
68
+ description: '[EXPERIMENTAL] Route model traffic through the hive-mind-router sidecar instead of mounting AI credentials into the task container (issue #2164)',
69
+ default: false,
70
+ })
66
71
  .option('screen-name', {
67
72
  type: 'string',
68
73
  description: 'Screen session name when --isolation screen is used',
package/src/task.mjs CHANGED
@@ -42,6 +42,7 @@ if (earlyArgs.length === 0 || earlyArgs.includes('--help') || earlyArgs.includes
42
42
  console.log(' --tool AI tool for agent-commander read-only mode (claude, codex, opencode, agent, qwen, gemini) [default: claude]');
43
43
  console.log(' --model, -m Model to use');
44
44
  console.log(' --isolation agent-commander isolation mode [default: docker]');
45
+ console.log(' --use-router [EXPERIMENTAL] Route model traffic through the hive-mind-router sidecar (issue #2164)');
45
46
  console.log(' --dry-run Print split output without creating GitHub issues');
46
47
  console.log(' --verbose, -v Enable verbose logging');
47
48
  console.log(' --output-format Output format (text or json) [default: text]');
@@ -255,6 +255,7 @@ const { createHeartbeat, resumeSessionsOnLaunch, createShutdownHandler } = await
255
255
  const { formatExecutingWorkSessionMessage, formatStartingWorkSessionMessage } = await import('./work-session-formatting.lib.mjs');
256
256
  const { buildTelegramHelpMessage, buildTelegramInfoBlock, buildSolveQueuedMessage } = await import('./telegram-ui-messages.lib.mjs');
257
257
  const { startFormalAiMaintenance } = await import('./formal-ai-maintenance.lib.mjs');
258
+ const { startRouterMaintenance } = await import('./router-maintenance.lib.mjs');
258
259
  // Initialize Sentry for error tracking
259
260
  await initializeSentry({
260
261
  debug: VERBOSE,
@@ -1198,6 +1199,7 @@ if (VERBOSE) {
1198
1199
  const launchAbortController = new AbortController();
1199
1200
  let sessionMonitoringTimer = null;
1200
1201
  let formalAiMaintenance = null;
1202
+ let routerMaintenance = null;
1201
1203
  let launchAnnouncementShown = false;
1202
1204
 
1203
1205
  function startSessionMonitoringOnce() {
@@ -1220,6 +1222,20 @@ function startFormalAiMaintenanceOnce() {
1220
1222
  });
1221
1223
  }
1222
1224
 
1225
+ // Issue #2164 (R5): the router sidecar must only run while at least one task
1226
+ // uses it. A task that finishes releases its own lease, but a killed task or a
1227
+ // host reboot leaves one behind — this tick reconciles those against Docker and
1228
+ // stops an idle router. The audit data volume is never removed.
1229
+ function startRouterMaintenanceOnce() {
1230
+ if (routerMaintenance) return;
1231
+ routerMaintenance = startRouterMaintenance({
1232
+ verbose: VERBOSE,
1233
+ log: async message => {
1234
+ console.log(message);
1235
+ },
1236
+ });
1237
+ }
1238
+
1223
1239
  // Issue #1927 (requirements #3/#4): a periodic timestamped heartbeat so the "last
1224
1240
  // time the bot was alive" is always discoverable from the log. The heartbeat
1225
1241
  // logic lives in bot-lifecycle.lib.mjs so it can be unit tested.
@@ -1240,6 +1256,7 @@ async function onBotLaunched() {
1240
1256
 
1241
1257
  startSessionMonitoringOnce();
1242
1258
  startFormalAiMaintenanceOnce();
1259
+ startRouterMaintenanceOnce();
1243
1260
  heartbeat.start();
1244
1261
  if (VERBOSE) {
1245
1262
  console.log('[VERBOSE] Bot launched successfully');
@@ -1334,6 +1351,7 @@ const handleShutdownSignal = createShutdownHandler({
1334
1351
  launchAbortController.abort();
1335
1352
  if (sessionMonitoringTimer) clearInterval(sessionMonitoringTimer);
1336
1353
  formalAiMaintenance?.stop();
1354
+ routerMaintenance?.stop();
1337
1355
  heartbeat.stop();
1338
1356
  stopSolveQueue();
1339
1357
  },