From b007ddffc8b8f9a162be3be888a1ef68489808d9 Mon Sep 17 00:00:00 2001 From: Jiayuan Zhang Date: Sun, 15 Feb 2026 18:06:51 +0800 Subject: [PATCH] feat(cli): initialize Hub in run mode for full agent capabilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always initialize Hub in CLI run mode to match the Desktop environment where Hub is always active. This enables sessions_spawn (sub-agent creation), cron tasks, channel plugins, and other Hub-dependent features during E2E testing. Hub constructor is non-blocking — gateway connection failures are handled gracefully with auto-reconnect. hub.shutdown() in finally block ensures clean teardown on exit. Co-Authored-By: Claude Opus 4.6 --- apps/cli/src/commands/run.ts | 66 +++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/apps/cli/src/commands/run.ts b/apps/cli/src/commands/run.ts index 1b915d0d06..c5fb6916f7 100644 --- a/apps/cli/src/commands/run.ts +++ b/apps/cli/src/commands/run.ts @@ -7,7 +7,7 @@ */ import { join } from "node:path"; -import { Agent } from "@multica/core"; +import { Agent, Hub } from "@multica/core"; import type { AgentOptions } from "@multica/core"; import type { ToolsConfig } from "@multica/core"; import { DATA_DIR } from "@multica/utils"; @@ -192,35 +192,45 @@ export async function runCommand(args: string[]): Promise { const enableRunLog = opts.runLog || !!process.env.MULTICA_RUN_LOG; - const agent = new Agent({ - profileId: opts.profile, - provider: opts.provider, - model: opts.model, - apiKey: opts.apiKey, - baseUrl: opts.baseUrl, - systemPrompt: opts.system, - thinkingLevel: opts.thinking as any, - reasoningMode: opts.reasoning as AgentOptions["reasoningMode"], - cwd: opts.cwd, - sessionId: opts.session, - debug: opts.debug, - enableRunLog, - tools: toolsConfig, - }); + // Initialize Hub to enable full agent capabilities (sub-agents, channels, cron). + // Matches Desktop environment where Hub is always active. + // Gateway connection failures are non-blocking (auto-reconnect with backoff). + const gatewayUrl = process.env.GATEWAY_URL || "http://localhost:3000"; + const hub = new Hub(gatewayUrl); - const sessionDir = join(DATA_DIR, "sessions", agent.sessionId); + try { + const agent = new Agent({ + profileId: opts.profile, + provider: opts.provider, + model: opts.model, + apiKey: opts.apiKey, + baseUrl: opts.baseUrl, + systemPrompt: opts.system, + thinkingLevel: opts.thinking as any, + reasoningMode: opts.reasoning as AgentOptions["reasoningMode"], + cwd: opts.cwd, + sessionId: opts.session, + debug: opts.debug, + enableRunLog, + tools: toolsConfig, + }); - // If it's a newly created session, notify user of sessionId - if (!opts.session) { - console.error(`[session: ${agent.sessionId}]`); - } - if (enableRunLog) { - console.error(`[session-dir: ${sessionDir}]`); - } + const sessionDir = join(DATA_DIR, "sessions", agent.sessionId); - const result = await agent.run(finalPrompt); - if (result.error) { - console.error(`Error: ${result.error}`); - process.exitCode = 1; + // If it's a newly created session, notify user of sessionId + if (!opts.session) { + console.error(`[session: ${agent.sessionId}]`); + } + if (enableRunLog) { + console.error(`[session-dir: ${sessionDir}]`); + } + + const result = await agent.run(finalPrompt); + if (result.error) { + console.error(`Error: ${result.error}`); + process.exitCode = 1; + } + } finally { + hub.shutdown(); } }