feat(01-02): extract agent config and sandbox setup into src/daemon/agents.ts
- Create initAgents() function encapsulating AgentConfigRegistry, AgentRouter, SandboxManager init - Replace ~26 lines in startDaemon() with single initAgents() call - Lifecycle shutdown handler for sandbox cleanup included in agents.ts - Zero type errors, routing tests pass
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import type { Config } from '../config/index.js';
|
||||
import { AgentConfigRegistry, AgentRouter } from '../agents/index.js';
|
||||
import { DockerSandbox, SandboxManager } from '../sandbox/index.js';
|
||||
import type { Lifecycle } from './lifecycle.js';
|
||||
|
||||
export interface AgentsDeps {
|
||||
config: Config;
|
||||
lifecycle: Lifecycle;
|
||||
}
|
||||
|
||||
export interface AgentsResult {
|
||||
agentConfigRegistry: AgentConfigRegistry;
|
||||
agentRouter: AgentRouter;
|
||||
sandboxManager?: SandboxManager;
|
||||
}
|
||||
|
||||
export async function initAgents(deps: AgentsDeps): Promise<AgentsResult> {
|
||||
const { config, lifecycle } = deps;
|
||||
|
||||
// Initialize agent config registry and router
|
||||
const agentConfigRegistry = new AgentConfigRegistry();
|
||||
if (config.agent_configs && Object.keys(config.agent_configs).length > 0) {
|
||||
agentConfigRegistry.loadFromConfig(config.agent_configs);
|
||||
console.log(`Loaded ${Object.keys(config.agent_configs).length} agent config(s)`);
|
||||
}
|
||||
const agentRouter = new AgentRouter(config.routing);
|
||||
|
||||
// Initialize sandbox manager if Docker is available
|
||||
let sandboxManager: SandboxManager | undefined;
|
||||
if (config.sandbox.enabled) {
|
||||
const dockerAvailable = await DockerSandbox.isAvailable();
|
||||
if (dockerAvailable) {
|
||||
sandboxManager = new SandboxManager(config.sandbox);
|
||||
console.log(`Docker sandbox enabled (image=${config.sandbox.image}, network=${config.sandbox.network})`);
|
||||
} else {
|
||||
console.warn('Docker sandbox enabled but Docker not available — falling back to host execution');
|
||||
}
|
||||
}
|
||||
|
||||
if (sandboxManager) {
|
||||
lifecycle.onShutdown(async () => {
|
||||
await sandboxManager!.destroyAll();
|
||||
console.log('Docker sandboxes destroyed');
|
||||
});
|
||||
}
|
||||
|
||||
return { agentConfigRegistry, agentRouter, sandboxManager };
|
||||
}
|
||||
+7
-94
@@ -2,6 +2,7 @@ import { Lifecycle } from './lifecycle.js';
|
||||
import { createModelRouter } from './models.js';
|
||||
import { initMemory } from './memory.js';
|
||||
import { createMessageRouter } from './routing.js';
|
||||
import { initAgents } from './agents.js';
|
||||
import type { Config } from '../config/index.js';
|
||||
import type { AudioTranscriptionConfig } from '../models/media.js';
|
||||
import { ModelRouter } from '../models/index.js';
|
||||
@@ -16,8 +17,8 @@ import { CronScheduler, WebhookHandler, HeartbeatMonitor, GmailWatcher } from '.
|
||||
import { McpManager } from '../mcp/index.js';
|
||||
import { SkillRegistry, SkillInstaller, loadAllSkills } from '../skills/index.js';
|
||||
import { assembleSystemPrompt } from '../prompt/index.js';
|
||||
import { AgentConfigRegistry, AgentRouter } from '../agents/index.js';
|
||||
import { DockerSandbox, SandboxManager } from '../sandbox/index.js';
|
||||
import type { AgentConfigRegistry, AgentRouter } from '../agents/index.js';
|
||||
import type { SandboxManager } from '../sandbox/index.js';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { mkdirSync } from 'fs';
|
||||
@@ -97,76 +98,12 @@ export async function startDaemon(config: Config): Promise<DaemonContext> {
|
||||
// Initialize hook engine
|
||||
const hookEngine = new HookEngine(config.hooks);
|
||||
|
||||
// Initialize tool registry and executor
|
||||
const toolRegistry = new ToolRegistry();
|
||||
for (const tool of allBuiltinTools) {
|
||||
toolRegistry.register(tool);
|
||||
}
|
||||
// Initialize tool registry, executor, web search, process tools, browser tools, and tool policy
|
||||
const { toolRegistry, toolExecutor, browserManager } = initTools({ config, lifecycle, hookEngine });
|
||||
|
||||
// Initialize memory store, vector search, and memory tools
|
||||
const { memoryStore, hybridSearch, memoryDir } = await initMemory({ config, dataDir, lifecycle, toolRegistry });
|
||||
|
||||
// Register web search tool if configured with credentials
|
||||
if (config.web_search.api_key || config.web_search.endpoint) {
|
||||
for (const tool of createWebSearchTools({
|
||||
provider: config.web_search.provider,
|
||||
apiKey: config.web_search.api_key,
|
||||
endpoint: config.web_search.endpoint,
|
||||
maxResults: config.web_search.max_results,
|
||||
})) {
|
||||
toolRegistry.register(tool);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize process manager and register process tools
|
||||
const processManager = new ProcessManager({
|
||||
maxConcurrent: config.process.max_concurrent,
|
||||
maxRuntimeMinutes: config.process.max_runtime_minutes,
|
||||
bufferSize: config.process.buffer_size,
|
||||
});
|
||||
|
||||
for (const tool of createProcessTools(processManager)) {
|
||||
toolRegistry.register(tool);
|
||||
}
|
||||
|
||||
lifecycle.onShutdown(async () => {
|
||||
await processManager.shutdown();
|
||||
console.log('Process manager stopped');
|
||||
});
|
||||
|
||||
// Initialize browser manager and register browser tools (if enabled)
|
||||
let browserManager: BrowserManager | undefined;
|
||||
if (config.browser?.enabled) {
|
||||
browserManager = new BrowserManager({
|
||||
executablePath: config.browser.executable_path,
|
||||
wsEndpoint: config.browser.ws_endpoint,
|
||||
headless: config.browser.headless,
|
||||
maxPages: config.browser.max_pages,
|
||||
defaultTimeout: config.browser.default_timeout,
|
||||
});
|
||||
|
||||
for (const tool of createBrowserTools(browserManager)) {
|
||||
toolRegistry.register(tool);
|
||||
}
|
||||
console.log(`Browser tools enabled (headless=${config.browser.headless})`);
|
||||
|
||||
lifecycle.onShutdown(async () => {
|
||||
await browserManager!.shutdown();
|
||||
console.log('Browser manager stopped');
|
||||
});
|
||||
}
|
||||
|
||||
const toolExecutor = new ToolExecutor(toolRegistry, hookEngine);
|
||||
|
||||
// Initialize tool policy from config
|
||||
const toolPolicy = new ToolPolicy(config.tools);
|
||||
toolRegistry.setPolicy(toolPolicy);
|
||||
|
||||
const effectiveProfile = toolPolicy.getEffectiveProfile();
|
||||
if (effectiveProfile !== 'full') {
|
||||
console.log(`Tool policy: profile=${effectiveProfile}, deny=[${config.tools.deny.join(', ')}]`);
|
||||
}
|
||||
|
||||
// Initialize MCP manager and start configured servers
|
||||
const mcpManager = new McpManager(toolRegistry);
|
||||
|
||||
@@ -200,32 +137,8 @@ export async function startDaemon(config: Config): Promise<DaemonContext> {
|
||||
console.log(`Loaded ${skills.length} skill(s) (${available} available)`);
|
||||
}
|
||||
|
||||
// Initialize agent config registry and router
|
||||
const agentConfigRegistry = new AgentConfigRegistry();
|
||||
if (config.agent_configs && Object.keys(config.agent_configs).length > 0) {
|
||||
agentConfigRegistry.loadFromConfig(config.agent_configs);
|
||||
console.log(`Loaded ${Object.keys(config.agent_configs).length} agent config(s)`);
|
||||
}
|
||||
const agentRouter = new AgentRouter(config.routing);
|
||||
|
||||
// Initialize sandbox manager if Docker is available
|
||||
let sandboxManager: SandboxManager | undefined;
|
||||
if (config.sandbox.enabled) {
|
||||
const dockerAvailable = await DockerSandbox.isAvailable();
|
||||
if (dockerAvailable) {
|
||||
sandboxManager = new SandboxManager(config.sandbox);
|
||||
console.log(`Docker sandbox enabled (image=${config.sandbox.image}, network=${config.sandbox.network})`);
|
||||
} else {
|
||||
console.warn('Docker sandbox enabled but Docker not available — falling back to host execution');
|
||||
}
|
||||
}
|
||||
|
||||
if (sandboxManager) {
|
||||
lifecycle.onShutdown(async () => {
|
||||
await sandboxManager!.destroyAll();
|
||||
console.log('Docker sandboxes destroyed');
|
||||
});
|
||||
}
|
||||
// Initialize agent config registry, router, and sandbox manager
|
||||
const { agentConfigRegistry, agentRouter, sandboxManager } = await initAgents({ config, lifecycle });
|
||||
|
||||
// Initialize audio transcription config
|
||||
const audioConfig: AudioTranscriptionConfig = {
|
||||
|
||||
Reference in New Issue
Block a user