diff --git a/package.json b/package.json index 717d910..1be18da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agenthub", - "version": "0.9.0", + "version": "0.9.1", "description": "Local coordination layer for AI coding agents", "type": "module", "main": "./dist/index.js", diff --git a/src/cli/commands/agentSetup.ts b/src/cli/commands/agentSetup.ts index f407f6f..62f30eb 100644 --- a/src/cli/commands/agentSetup.ts +++ b/src/cli/commands/agentSetup.ts @@ -22,11 +22,14 @@ import { findProjectRoot } from '../../core/paths.js'; export function hookContext(opts: { agent: string; role: string }): void { const { agent, role } = opts; process.stdout.write( - `AgentHub auto-start — you are "${agent}" (${role}). Before anything else, run:\n` + + `AgentHub auto-start — you are "${agent}" (${role}). Before anything else, enter the work loop:\n` + ` agenthub work --agent ${agent} --role ${role}\n` + - `(or call the agenthub_work tool with { agent: "${agent}", role: "${role}" }), then LOOP: ` + - `work -> implement -> agenthub_task_review -> work. agenthub_work claims your tasks AND ` + - `surfaces your messages. Never run agenthub_task_done. Keep looping so you stay reachable.\n`, + `(or call the agenthub_work tool with { agent: "${agent}", role: "${role}" }). It BLOCKS until a ` + + `task or message addressed to you arrives, then returns it. Handle it, then IMMEDIATELY call ` + + `agenthub_work AGAIN — run it in the BACKGROUND so you're woken on the next event without ` + + `tying up your turn. The loop is: work -> handle -> agenthub_task_review -> work, forever. ` + + `agenthub_work claims your tasks AND delivers your messages. Never run agenthub_task_done. ` + + `Staying in this loop is what keeps you reachable — do not end a turn without relaunching agenthub_work.\n`, ); } diff --git a/src/cli/index.ts b/src/cli/index.ts index 3482e20..ba00c09 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -118,7 +118,7 @@ async function runRemote(serverUrl: string, fn: () => Promise): Promise', 'AgentHub server URL (env: AGENTHUB_SERVER)'); program diff --git a/src/mcp/server.ts b/src/mcp/server.ts index f36aea6..185cb5a 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -135,11 +135,18 @@ export async function startMcpServer(cwd: string): Promise { if (messages.length) return { claimed: null, messages, note: 'No task addressed to you, but you have messages — reply with agenthub_message.' }; return null; }; + // Self-perpetuating loop: every response reminds the agent to relaunch + // agenthub_work, so a finished task/message never leaves it dormant. + const LOOP = + 'STAY REACHABLE: the instant you finish handling this, call agenthub_work again — ' + + 'run it in the background so the next task or message reaches you in realtime. ' + + 'Never end your turn without relaunching agenthub_work.'; const immediate = await findWork(); - if (immediate) return asText(immediate); + if (immediate) return asText({ ...immediate, loop: LOOP }); if (!remote) return asText(`No open task addressed to ${agent}, and no hub server to wait on.`); const result = await waitForTask(serverUrl!, findWork, timeoutSec ?? 300); - return asText(result ?? `No task or message for ${agent} within ${timeoutSec ?? 300}s — call agenthub_work again.`); + if (result) return asText({ ...result, loop: LOOP }); + return asText(`No task or message for ${agent} within ${timeoutSec ?? 300}s. ${LOOP}`); }); server.tool('agenthub_task_list', 'List tasks, optionally filtered by status and/or role.',