titan-agent 2026.4.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.
Files changed (43) hide show
  1. package/.env.example +21 -0
  2. package/LICENSE +29 -0
  3. package/README.md +305 -0
  4. package/assets/titan-logo.png +0 -0
  5. package/dist/agent/agent.js +1458 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/generator.js +1078 -0
  8. package/dist/agent/generator.js.map +1 -0
  9. package/dist/cli/index.js +5064 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/gateway/server.js +4462 -0
  12. package/dist/gateway/server.js.map +1 -0
  13. package/dist/skills/builtin/apply_patch.js +368 -0
  14. package/dist/skills/builtin/apply_patch.js.map +1 -0
  15. package/dist/skills/builtin/auto_generate.js +1129 -0
  16. package/dist/skills/builtin/auto_generate.js.map +1 -0
  17. package/dist/skills/builtin/browser.js +357 -0
  18. package/dist/skills/builtin/browser.js.map +1 -0
  19. package/dist/skills/builtin/cron.js +410 -0
  20. package/dist/skills/builtin/cron.js.map +1 -0
  21. package/dist/skills/builtin/filesystem.js +386 -0
  22. package/dist/skills/builtin/filesystem.js.map +1 -0
  23. package/dist/skills/builtin/memory_skill.js +430 -0
  24. package/dist/skills/builtin/memory_skill.js.map +1 -0
  25. package/dist/skills/builtin/process.js +421 -0
  26. package/dist/skills/builtin/process.js.map +1 -0
  27. package/dist/skills/builtin/sessions.js +1729 -0
  28. package/dist/skills/builtin/sessions.js.map +1 -0
  29. package/dist/skills/builtin/shell.js +327 -0
  30. package/dist/skills/builtin/shell.js.map +1 -0
  31. package/dist/skills/builtin/vision.js +491 -0
  32. package/dist/skills/builtin/vision.js.map +1 -0
  33. package/dist/skills/builtin/voice.js +468 -0
  34. package/dist/skills/builtin/voice.js.map +1 -0
  35. package/dist/skills/builtin/web_fetch.js +331 -0
  36. package/dist/skills/builtin/web_fetch.js.map +1 -0
  37. package/dist/skills/builtin/web_search.js +317 -0
  38. package/dist/skills/builtin/web_search.js.map +1 -0
  39. package/dist/skills/builtin/webhook.js +323 -0
  40. package/dist/skills/builtin/webhook.js.map +1 -0
  41. package/dist/skills/registry.js +3369 -0
  42. package/dist/skills/registry.js.map +1 -0
  43. package/package.json +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/constants.ts","../../../src/utils/logger.ts","../../../src/utils/helpers.ts","../../../src/config/schema.ts","../../../src/config/config.ts","../../../src/agent/toolRunner.ts","../../../src/skills/registry.ts","../../../src/providers/base.ts","../../../src/providers/anthropic.ts","../../../src/providers/openai.ts","../../../src/providers/google.ts","../../../src/providers/ollama.ts","../../../src/providers/router.ts","../../../src/agent/generator.ts","../../../src/skills/builtin/auto_generate.ts"],"sourcesContent":["/**\n * TITAN Constants\n */\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport const TITAN_VERSION = '2026.4.0';\nexport const TITAN_NAME = 'TITAN';\nexport const TITAN_FULL_NAME = 'The Intelligent Task Automation Network';\nexport const TITAN_ASCII_LOGO = `\n╔════════════════════════════════════════════════════╗\n║ ║\n║ ████████╗██╗████████╗ █████╗ ███╗ ██╗ ║\n║ ╚══██╔══╝██║╚══██╔══╝██╔══██╗████╗ ██║ ║\n║ ██║ ██║ ██║ ███████║██╔██╗ ██║ ║\n║ ██║ ██║ ██║ ██╔══██║██║╚██╗██║ ║\n║ ██║ ██║ ██║ ██║ ██║██║ ╚████║ ║\n║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ║\n║ ║\n║ The Intelligent Task Automation Network ║\n║ v${TITAN_VERSION} ║\n╚════════════════════════════════════════════════════╝`;\n\n// Paths\nexport const TITAN_HOME = join(homedir(), '.titan');\nexport const TITAN_CONFIG_PATH = join(TITAN_HOME, 'titan.json');\nexport const TITAN_DB_PATH = join(TITAN_HOME, 'titan.db');\nexport const TITAN_WORKSPACE = join(TITAN_HOME, 'workspace');\nexport const TITAN_SKILLS_DIR = join(TITAN_WORKSPACE, 'skills');\nexport const TITAN_LOGS_DIR = join(TITAN_HOME, 'logs');\nexport const TITAN_MEMORY_DIR = join(TITAN_HOME, 'memory');\n\n// Workspace prompt files (injected into agent context)\nexport const AGENTS_MD = join(TITAN_WORKSPACE, 'AGENTS.md');\nexport const SOUL_MD = join(TITAN_WORKSPACE, 'SOUL.md');\nexport const TOOLS_MD = join(TITAN_WORKSPACE, 'TOOLS.md');\n\n// Gateway defaults\nexport const DEFAULT_GATEWAY_HOST = '127.0.0.1';\nexport const DEFAULT_GATEWAY_PORT = 18789;\nexport const DEFAULT_WEB_PORT = 18790;\n\n// Agent defaults\nexport const DEFAULT_MODEL = 'anthropic/claude-sonnet-4-20250514';\nexport const DEFAULT_MAX_TOKENS = 8192;\nexport const DEFAULT_TEMPERATURE = 0.7;\nexport const MAX_CONTEXT_MESSAGES = 50;\nexport const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\n// Security\nexport const DEFAULT_SANDBOX_MODE = 'host';\nexport const ALLOWED_TOOLS_DEFAULT = [\n 'shell', 'read_file', 'write_file', 'edit_file', 'list_dir',\n 'web_search', 'browser', 'cron', 'webhook', 'email', 'memory',\n];\nexport const DENIED_TOOLS_DEFAULT: string[] = [];\n","/**\n * TITAN Logger — Structured logging with levels and colors\n */\nimport chalk from 'chalk';\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n SILENT = 4,\n}\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: chalk.gray('DEBUG'),\n [LogLevel.INFO]: chalk.cyan('INFO '),\n [LogLevel.WARN]: chalk.yellow('WARN '),\n [LogLevel.ERROR]: chalk.red('ERROR'),\n [LogLevel.SILENT]: '',\n};\n\nlet currentLevel: LogLevel = LogLevel.INFO;\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nexport function getLogLevel(): LogLevel {\n return currentLevel;\n}\n\nfunction formatTimestamp(): string {\n return chalk.gray(new Date().toISOString().replace('T', ' ').slice(0, 19));\n}\n\nfunction log(level: LogLevel, component: string, message: string, ...args: unknown[]): void {\n if (level < currentLevel) return;\n const prefix = `${formatTimestamp()} ${LEVEL_LABELS[level]} ${chalk.blue(`[${component}]`)}`;\n console.log(`${prefix} ${message}`, ...args);\n}\n\nexport const logger = {\n debug: (component: string, msg: string, ...args: unknown[]) => log(LogLevel.DEBUG, component, msg, ...args),\n info: (component: string, msg: string, ...args: unknown[]) => log(LogLevel.INFO, component, msg, ...args),\n warn: (component: string, msg: string, ...args: unknown[]) => log(LogLevel.WARN, component, msg, ...args),\n error: (component: string, msg: string, ...args: unknown[]) => log(LogLevel.ERROR, component, msg, ...args),\n};\n\nexport default logger;\n","/**\n * TITAN Helper Utilities\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { dirname } from 'path';\n\n/** Ensure a directory exists, creating it recursively if needed */\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/** Safely read a JSON file, returning null on failure */\nexport function readJsonFile<T = unknown>(filePath: string): T | null {\n try {\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/** Safely write a JSON file, creating parent dirs if needed */\nexport function writeJsonFile(filePath: string, data: unknown): void {\n ensureDir(dirname(filePath));\n writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n/** Safe string truncation */\nexport function truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + '...';\n}\n\n/** Sleep for a given number of milliseconds */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Generate a short ID */\nexport function shortId(): string {\n return Math.random().toString(36).slice(2, 10);\n}\n\n/** Format bytes into human-readable string */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n}\n\n/** Format a duration in ms to human-readable */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3600000) return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n return `${Math.floor(ms / 3600000)}h ${Math.floor((ms % 3600000) / 60000)}m`;\n}\n\n/** Deep merge two objects */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n for (const key of Object.keys(source) as Array<keyof T>) {\n const sourceVal = source[key];\n const targetVal = result[key];\n if (\n sourceVal &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n targetVal &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(\n targetVal as Record<string, unknown>,\n sourceVal as Record<string, unknown>,\n ) as T[keyof T];\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal as T[keyof T];\n }\n }\n return result;\n}\n","/**\n * TITAN Configuration Schema — Zod-based validation with full type inference\n */\nimport { z } from 'zod';\nimport {\n DEFAULT_GATEWAY_HOST,\n DEFAULT_GATEWAY_PORT,\n DEFAULT_WEB_PORT,\n DEFAULT_MODEL,\n DEFAULT_MAX_TOKENS,\n DEFAULT_TEMPERATURE,\n DEFAULT_SANDBOX_MODE,\n ALLOWED_TOOLS_DEFAULT,\n} from '../utils/constants.js';\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n model: z.string().optional(),\n maxTokens: z.number().optional(),\n temperature: z.number().min(0).max(2).optional(),\n});\n\nexport const ChannelConfigSchema = z.object({\n enabled: z.boolean().default(false),\n token: z.string().optional(),\n apiKey: z.string().optional(),\n allowFrom: z.array(z.string()).default([]),\n dmPolicy: z.enum(['pairing', 'open', 'closed']).default('pairing'),\n});\n\nexport const SecurityConfigSchema = z.object({\n sandboxMode: z.enum(['host', 'docker', 'none']).default(DEFAULT_SANDBOX_MODE as 'host'),\n allowedTools: z.array(z.string()).default(ALLOWED_TOOLS_DEFAULT),\n deniedTools: z.array(z.string()).default([]),\n maxConcurrentTasks: z.number().default(5),\n commandTimeout: z.number().default(30000),\n fileSystemAllowlist: z.array(z.string()).default([]),\n networkAllowlist: z.array(z.string()).default(['*']),\n shield: z.object({\n enabled: z.boolean().default(true),\n mode: z.enum(['standard', 'strict']).default('strict'),\n }).default({}),\n});\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().default(DEFAULT_GATEWAY_HOST),\n port: z.number().default(DEFAULT_GATEWAY_PORT),\n webPort: z.number().default(DEFAULT_WEB_PORT),\n auth: z.object({\n mode: z.enum(['none', 'token', 'password']).default('token'),\n token: z.string().optional(),\n password: z.string().optional(),\n }).default({}),\n});\n\nexport const AgentConfigSchema = z.object({\n model: z.string().default(DEFAULT_MODEL),\n maxTokens: z.number().default(DEFAULT_MAX_TOKENS),\n temperature: z.number().default(DEFAULT_TEMPERATURE),\n systemPrompt: z.string().optional(),\n workspace: z.string().optional(),\n thinkingMode: z.enum(['off', 'low', 'medium', 'high']).default('medium'),\n});\n\nexport const TitanConfigSchema = z.object({\n agent: AgentConfigSchema.default({}),\n providers: z.object({\n anthropic: ProviderConfigSchema.default({}),\n openai: ProviderConfigSchema.default({}),\n google: ProviderConfigSchema.default({}),\n ollama: ProviderConfigSchema.default({}),\n }).default({}),\n channels: z.object({\n discord: ChannelConfigSchema.default({}),\n telegram: ChannelConfigSchema.default({}),\n slack: ChannelConfigSchema.default({}),\n whatsapp: ChannelConfigSchema.default({}),\n webchat: ChannelConfigSchema.default({}),\n googlechat: ChannelConfigSchema.default({}),\n matrix: ChannelConfigSchema.default({}),\n signal: ChannelConfigSchema.default({}),\n msteams: ChannelConfigSchema.default({}),\n bluebubbles: ChannelConfigSchema.default({}),\n }).default({}),\n gateway: GatewayConfigSchema.default({}),\n security: SecurityConfigSchema.default({}),\n memory: z.object({\n enabled: z.boolean().default(true),\n maxHistoryMessages: z.number().default(50),\n vectorSearchEnabled: z.boolean().default(false),\n }).default({}),\n skills: z.object({\n enabled: z.boolean().default(true),\n autoDiscover: z.boolean().default(true),\n marketplace: z.boolean().default(false),\n }).default({}),\n logging: z.object({\n level: z.enum(['debug', 'info', 'warn', 'error', 'silent']).default('info'),\n file: z.boolean().default(true),\n }).default({}),\n autonomy: z.object({\n /** autonomous = full auto, supervised = asks for dangerous ops, locked = asks for everything */\n mode: z.enum(['autonomous', 'supervised', 'locked']).default('supervised'),\n /** Auto-approve moderate-risk tools in main session (cli/webchat) */\n autoApproveMainSession: z.boolean().default(true),\n /** Timeout for HITL approval requests (ms). Auto-deny after timeout. */\n approvalTimeoutMs: z.number().default(60000),\n /** Notify user of auto-approved actions */\n notifyOnAutoApprove: z.boolean().default(true),\n }).default({}),\n});\n\nexport type TitanConfig = z.infer<typeof TitanConfigSchema>;\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\nexport type ChannelConfig = z.infer<typeof ChannelConfigSchema>;\nexport type SecurityConfig = z.infer<typeof SecurityConfigSchema>;\nexport type GatewayConfig = z.infer<typeof GatewayConfigSchema>;\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\n","/**\n * TITAN Configuration Manager\n * Loads, validates, and persists configuration from ~/.titan/titan.json\n */\nimport { existsSync } from 'fs';\nimport { TITAN_CONFIG_PATH, TITAN_HOME } from '../utils/constants.js';\nimport { readJsonFile, writeJsonFile, ensureDir, deepMerge } from '../utils/helpers.js';\nimport { TitanConfigSchema, type TitanConfig } from './schema.js';\nimport logger from '../utils/logger.js';\n\nconst COMPONENT = 'Config';\n\nlet cachedConfig: TitanConfig | null = null;\n\n/** Get the default configuration */\nexport function getDefaultConfig(): TitanConfig {\n return TitanConfigSchema.parse({});\n}\n\n/** Load configuration from disk, merging with defaults */\nexport function loadConfig(): TitanConfig {\n if (cachedConfig) return cachedConfig;\n\n ensureDir(TITAN_HOME);\n\n let rawConfig: Record<string, unknown> = {};\n\n if (existsSync(TITAN_CONFIG_PATH)) {\n const loaded = readJsonFile<Record<string, unknown>>(TITAN_CONFIG_PATH);\n if (loaded) {\n rawConfig = loaded;\n logger.debug(COMPONENT, `Loaded config from ${TITAN_CONFIG_PATH}`);\n } else {\n logger.warn(COMPONENT, `Failed to parse config at ${TITAN_CONFIG_PATH}, using defaults`);\n }\n } else {\n logger.info(COMPONENT, 'No config file found, using defaults');\n }\n\n // Apply environment variables\n applyEnvOverrides(rawConfig);\n\n // Validate and merge with defaults via Zod\n const result = TitanConfigSchema.safeParse(rawConfig);\n if (!result.success) {\n logger.warn(COMPONENT, 'Config validation issues, using defaults for invalid fields');\n logger.debug(COMPONENT, result.error.message);\n cachedConfig = getDefaultConfig();\n } else {\n cachedConfig = result.data;\n }\n\n return cachedConfig;\n}\n\n/** Save current configuration to disk */\nexport function saveConfig(config: TitanConfig): void {\n ensureDir(TITAN_HOME);\n writeJsonFile(TITAN_CONFIG_PATH, config);\n cachedConfig = config;\n logger.info(COMPONENT, `Config saved to ${TITAN_CONFIG_PATH}`);\n}\n\n/** Update specific fields in the config */\nexport function updateConfig(partial: Partial<TitanConfig>): TitanConfig {\n const current = loadConfig();\n const updated = deepMerge(current as Record<string, unknown>, partial as Record<string, unknown>) as TitanConfig;\n const validated = TitanConfigSchema.parse(updated);\n saveConfig(validated);\n return validated;\n}\n\n/** Reset config cache (useful for testing) */\nexport function resetConfigCache(): void {\n cachedConfig = null;\n}\n\n/** Check if the configuration file exists */\nexport function configExists(): boolean {\n return existsSync(TITAN_CONFIG_PATH);\n}\n\n/** Apply environment variable overrides to raw config */\nfunction applyEnvOverrides(config: Record<string, unknown>): void {\n const envMap: Record<string, (val: string) => void> = {\n TITAN_MODEL: (val) => setNested(config, 'agent.model', val),\n TITAN_GATEWAY_PORT: (val) => setNested(config, 'gateway.port', parseInt(val, 10)),\n TITAN_GATEWAY_HOST: (val) => setNested(config, 'gateway.host', val),\n TITAN_LOG_LEVEL: (val) => setNested(config, 'logging.level', val),\n ANTHROPIC_API_KEY: (val) => setNested(config, 'providers.anthropic.apiKey', val),\n OPENAI_API_KEY: (val) => setNested(config, 'providers.openai.apiKey', val),\n GOOGLE_API_KEY: (val) => setNested(config, 'providers.google.apiKey', val),\n OLLAMA_BASE_URL: (val) => setNested(config, 'providers.ollama.baseUrl', val),\n DISCORD_TOKEN: (val) => setNested(config, 'channels.discord.token', val),\n TELEGRAM_TOKEN: (val) => setNested(config, 'channels.telegram.token', val),\n SLACK_TOKEN: (val) => setNested(config, 'channels.slack.token', val),\n };\n\n for (const [envKey, setter] of Object.entries(envMap)) {\n const val = process.env[envKey];\n if (val) {\n setter(val);\n logger.debug(COMPONENT, `Applied env override: ${envKey}`);\n }\n }\n}\n\n/** Set a nested property by dot-notation path */\nfunction setNested(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.');\n let current: Record<string, unknown> = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]] || typeof current[parts[i]] !== 'object') {\n current[parts[i]] = {};\n }\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = value;\n}\n","/**\n * TITAN — Tool Runner\n * Executes tool calls from the LLM with sandboxing, timeouts, and result formatting.\n */\nimport type { ToolCall, ToolDefinition } from '../providers/base.js';\nimport logger from '../utils/logger.js';\nimport { loadConfig } from '../config/config.js';\n\nconst COMPONENT = 'ToolRunner';\n\n/** Tool execution result */\nexport interface ToolResult {\n toolCallId: string;\n name: string;\n content: string;\n success: boolean;\n durationMs: number;\n}\n\n/** A registered tool handler */\nexport interface ToolHandler {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n execute: (args: Record<string, unknown>) => Promise<string>;\n}\n\n/** Global tool registry */\nconst toolRegistry: Map<string, ToolHandler> = new Map();\n\n/** Register a tool */\nexport function registerTool(handler: ToolHandler): void {\n toolRegistry.set(handler.name, handler);\n logger.debug(COMPONENT, `Registered tool: ${handler.name}`);\n}\n\n/** Unregister a tool */\nexport function unregisterTool(name: string): void {\n toolRegistry.delete(name);\n}\n\n/** Get all registered tools */\nexport function getRegisteredTools(): ToolHandler[] {\n return Array.from(toolRegistry.values());\n}\n\n/** Convert registered tools to LLM tool definitions */\nexport function getToolDefinitions(): ToolDefinition[] {\n const config = loadConfig();\n const allowed = new Set(config.security.allowedTools);\n const denied = new Set(config.security.deniedTools);\n\n return Array.from(toolRegistry.values())\n .filter((tool) => {\n if (denied.has(tool.name)) return false;\n if (allowed.size > 0 && !allowed.has(tool.name)) return false;\n return true;\n })\n .map((tool) => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n }));\n}\n\n/** Execute a single tool call */\nexport async function executeTool(toolCall: ToolCall): Promise<ToolResult> {\n const config = loadConfig();\n const startTime = Date.now();\n const handler = toolRegistry.get(toolCall.function.name);\n\n if (!handler) {\n return {\n toolCallId: toolCall.id,\n name: toolCall.function.name,\n content: `Error: Unknown tool \"${toolCall.function.name}\"`,\n success: false,\n durationMs: Date.now() - startTime,\n };\n }\n\n // Check permissions\n if (config.security.deniedTools.includes(handler.name)) {\n return {\n toolCallId: toolCall.id,\n name: handler.name,\n content: `Error: Tool \"${handler.name}\" is denied by security policy`,\n success: false,\n durationMs: Date.now() - startTime,\n };\n }\n\n try {\n // Parse arguments\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(toolCall.function.arguments);\n } catch {\n args = {};\n }\n\n logger.info(COMPONENT, `Executing tool: ${handler.name}`);\n\n // Execute with timeout\n const timeout = config.security.commandTimeout || 30000;\n const result = await Promise.race([\n handler.execute(args),\n new Promise<string>((_, reject) =>\n setTimeout(() => reject(new Error(`Tool \"${handler.name}\" timed out after ${timeout}ms`)), timeout)\n ),\n ]);\n\n const durationMs = Date.now() - startTime;\n logger.info(COMPONENT, `Tool ${handler.name} completed in ${durationMs}ms`);\n\n return {\n toolCallId: toolCall.id,\n name: handler.name,\n content: result,\n success: true,\n durationMs,\n };\n } catch (error) {\n const durationMs = Date.now() - startTime;\n const errorMsg = (error as Error).message;\n logger.error(COMPONENT, `Tool ${handler.name} failed: ${errorMsg}`);\n\n return {\n toolCallId: toolCall.id,\n name: handler.name,\n content: `Error: ${errorMsg}`,\n success: false,\n durationMs,\n };\n }\n}\n\n/** Execute multiple tool calls (in parallel where possible) */\nexport async function executeTools(toolCalls: ToolCall[]): Promise<ToolResult[]> {\n const config = loadConfig();\n const maxConcurrent = config.security.maxConcurrentTasks || 5;\n\n // Execute in batches\n const results: ToolResult[] = [];\n for (let i = 0; i < toolCalls.length; i += maxConcurrent) {\n const batch = toolCalls.slice(i, i + maxConcurrent);\n const batchResults = await Promise.all(batch.map(executeTool));\n results.push(...batchResults);\n }\n\n return results;\n}\n","/**\n * TITAN — Skills Registry\n * Discovers, loads, and manages skills from bundled, workspace, and marketplace sources.\n */\nimport { existsSync, readdirSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { TITAN_HOME, TITAN_SKILLS_DIR } from '../utils/constants.js';\nimport { registerTool, type ToolHandler } from '../agent/toolRunner.js';\nimport { ensureDir } from '../utils/helpers.js';\nimport logger from '../utils/logger.js';\n\nconst COMPONENT = 'Skills';\n\nexport interface SkillMeta {\n name: string;\n description: string;\n version: string;\n author?: string;\n source: 'bundled' | 'workspace' | 'marketplace';\n enabled: boolean;\n}\n\nconst registeredSkills: Map<string, SkillMeta> = new Map();\n\n/** Register a built-in skill (tool handler + metadata) */\nexport function registerSkill(meta: SkillMeta, handler: ToolHandler): void {\n registeredSkills.set(meta.name, meta);\n registerTool(handler);\n logger.debug(COMPONENT, `Registered skill: ${meta.name} (${meta.source})`);\n}\n\n/** Get all registered skills */\nexport function getSkills(): SkillMeta[] {\n return Array.from(registeredSkills.values());\n}\n\n/** Get a skill by name */\nexport function getSkill(name: string): SkillMeta | undefined {\n return registeredSkills.get(name);\n}\n\n/** Discover workspace skills from ~/.titan/workspace/skills/ */\nexport function discoverWorkspaceSkills(): SkillMeta[] {\n ensureDir(TITAN_SKILLS_DIR);\n const discovered: SkillMeta[] = [];\n\n if (!existsSync(TITAN_SKILLS_DIR)) return discovered;\n\n const entries = readdirSync(TITAN_SKILLS_DIR, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillDir = join(TITAN_SKILLS_DIR, entry.name);\n const skillMdPath = join(skillDir, 'SKILL.md');\n\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const content = readFileSync(skillMdPath, 'utf-8');\n const meta = parseSkillMd(content, entry.name);\n if (meta) {\n discovered.push({ ...meta, source: 'workspace', enabled: true });\n }\n } catch (error) {\n logger.warn(COMPONENT, `Failed to load skill ${entry.name}: ${(error as Error).message}`);\n }\n }\n\n logger.info(COMPONENT, `Discovered ${discovered.length} workspace skills`);\n return discovered;\n}\n\n/** Parse SKILL.md frontmatter to extract metadata */\nfunction parseSkillMd(content: string, fallbackName: string): Omit<SkillMeta, 'source' | 'enabled'> | null {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) {\n return {\n name: fallbackName,\n description: content.split('\\n')[0] || 'No description',\n version: '1.0.0',\n };\n }\n\n const frontmatter = frontmatterMatch[1];\n const name = frontmatter.match(/name:\\s*(.+)/)?.[1]?.trim() || fallbackName;\n const description = frontmatter.match(/description:\\s*(.+)/)?.[1]?.trim() || 'No description';\n const version = frontmatter.match(/version:\\s*(.+)/)?.[1]?.trim() || '1.0.0';\n const author = frontmatter.match(/author:\\s*(.+)/)?.[1]?.trim();\n\n return { name, description, version, author };\n}\n\n/** Initialize all built-in skills */\nexport async function initBuiltinSkills(): Promise<void> {\n logger.info(COMPONENT, 'Loading built-in skills...');\n\n // Import and register built-in skills\n const { registerShellSkill } = await import('./builtin/shell.js');\n const { registerFilesystemSkill } = await import('./builtin/filesystem.js');\n const { registerWebSearchSkill } = await import('./builtin/web_search.js');\n const { registerCronSkill } = await import('./builtin/cron.js');\n const { registerWebhookSkill } = await import('./builtin/webhook.js');\n const { registerMemorySkill } = await import('./builtin/memory_skill.js');\n const { registerBrowserSkill } = await import('./builtin/browser.js');\n const { registerSessionsSkill } = await import('./builtin/sessions.js');\n const { registerProcessSkill } = await import('./builtin/process.js');\n const { registerWebFetchSkill } = await import('./builtin/web_fetch.js');\n const { registerApplyPatchSkill } = await import('./builtin/apply_patch.js');\n const { registerAutoGenerateSkill } = await import('./builtin/auto_generate.js');\n const { registerVisionSkill } = await import('./builtin/vision.js');\n const { registerVoiceSkills } = await import('./builtin/voice.js');\n\n registerShellSkill();\n registerFilesystemSkill();\n registerWebSearchSkill();\n registerCronSkill();\n registerWebhookSkill();\n registerMemorySkill();\n registerBrowserSkill();\n registerSessionsSkill();\n registerProcessSkill();\n registerWebFetchSkill();\n registerApplyPatchSkill();\n registerAutoGenerateSkill();\n registerVisionSkill();\n registerVoiceSkills();\n\n logger.info(COMPONENT, `Loaded ${registeredSkills.size} built-in skills`);\n}\n\n/** \n * Discover and load auto-generated skills from ~/.titan/skills/auto/\n */\nexport async function loadAutoSkills(): Promise<void> {\n const autoDir = join(TITAN_HOME, 'skills', 'auto');\n if (!existsSync(autoDir)) return;\n\n logger.info(COMPONENT, 'Checking for auto-generated skills...');\n const files = readdirSync(autoDir).filter(f => f.endsWith('.js'));\n\n let loadedCount = 0;\n for (const file of files) {\n try {\n const skillPath = join(autoDir, file);\n // Append cache buster to force hot-reload of ES modules\n const modulePath = `file://${skillPath}?t=${Date.now()}`;\n const mod = await import(modulePath);\n\n if (mod.default && mod.default.name && mod.default.execute) {\n const handler = mod.default as ToolHandler;\n\n // Add to our registry metadata\n const meta: SkillMeta = {\n name: handler.name,\n description: handler.description || 'Auto-generated skill',\n version: '1.0.0',\n source: 'workspace', // Consider it part of user workspace\n enabled: true,\n };\n\n registerSkill(meta, handler);\n loadedCount++;\n }\n } catch (e: any) {\n logger.error(COMPONENT, `Failed to load auto skill ${file}: ${e.message}`);\n }\n }\n\n if (loadedCount > 0) {\n logger.info(COMPONENT, `Successfully loaded ${loadedCount} auto-generated skills`);\n }\n}\n","/**\n * TITAN LLM Provider — Base Interface\n * All LLM providers implement this interface for a unified API.\n */\n\n/** A single message in a conversation */\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n name?: string;\n toolCallId?: string;\n toolCalls?: ToolCall[];\n}\n\n/** A tool call requested by the LLM */\nexport interface ToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/** A tool definition for the LLM */\nexport interface ToolDefinition {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n };\n}\n\n/** Options for a chat completion request */\nexport interface ChatOptions {\n model?: string;\n messages: ChatMessage[];\n tools?: ToolDefinition[];\n maxTokens?: number;\n temperature?: number;\n stream?: boolean;\n thinking?: boolean;\n}\n\n/** Response from a chat completion */\nexport interface ChatResponse {\n id: string;\n content: string;\n toolCalls?: ToolCall[];\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n finishReason: 'stop' | 'tool_calls' | 'length' | 'error';\n model: string;\n}\n\n/** Streaming chunk from a chat completion */\nexport interface ChatStreamChunk {\n type: 'text' | 'tool_call' | 'done' | 'error';\n content?: string;\n toolCall?: ToolCall;\n error?: string;\n}\n\n/** Abstract LLM Provider interface */\nexport abstract class LLMProvider {\n abstract readonly name: string;\n abstract readonly displayName: string;\n\n /** Send a chat completion request */\n abstract chat(options: ChatOptions): Promise<ChatResponse>;\n\n /** Send a streaming chat completion request */\n abstract chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk>;\n\n /** List available models */\n abstract listModels(): Promise<string[]>;\n\n /** Check if the provider is configured and reachable */\n abstract healthCheck(): Promise<boolean>;\n\n /** Get the provider identifier from a model string like \"anthropic/claude-3\" */\n static parseModelId(modelId: string): { provider: string; model: string } {\n const parts = modelId.split('/');\n if (parts.length >= 2) {\n return { provider: parts[0], model: parts.slice(1).join('/') };\n }\n return { provider: 'anthropic', model: modelId };\n }\n}\n","/**\n * TITAN — Anthropic/Claude Provider\n */\nimport {\n LLMProvider,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport logger from '../utils/logger.js';\nimport { v4 as uuid } from 'uuid';\n\nconst COMPONENT = 'Anthropic';\n\nexport class AnthropicProvider extends LLMProvider {\n readonly name = 'anthropic';\n readonly displayName = 'Anthropic (Claude)';\n\n private get apiKey(): string {\n const config = loadConfig();\n return config.providers.anthropic.apiKey || process.env.ANTHROPIC_API_KEY || '';\n }\n\n private get baseUrl(): string {\n const config = loadConfig();\n return config.providers.anthropic.baseUrl || 'https://api.anthropic.com';\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const model = options.model || 'claude-sonnet-4-20250514';\n const apiKey = this.apiKey;\n if (!apiKey) throw new Error('Anthropic API key not configured');\n\n logger.debug(COMPONENT, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const systemMessage = options.messages.find((m) => m.role === 'system');\n const nonSystemMessages = options.messages.filter((m) => m.role !== 'system');\n\n const body: Record<string, unknown> = {\n model: model.replace('anthropic/', ''),\n max_tokens: options.maxTokens || 8192,\n messages: nonSystemMessages.map((m) => ({\n role: m.role === 'tool' ? 'user' : m.role,\n content: m.role === 'tool'\n ? [{ type: 'tool_result', tool_use_id: m.toolCallId, content: m.content }]\n : m.content,\n })),\n };\n\n if (systemMessage) {\n body.system = systemMessage.content;\n }\n\n if (options.tools && options.tools.length > 0) {\n body.tools = options.tools.map((t) => ({\n name: t.function.name,\n description: t.function.description,\n input_schema: t.function.parameters,\n }));\n }\n\n if (options.temperature !== undefined) {\n body.temperature = options.temperature;\n }\n\n const response = await fetch(`${this.baseUrl}/v1/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Anthropic API error (${response.status}): ${errorText}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const content = data.content as Array<Record<string, unknown>>;\n\n let textContent = '';\n const toolCalls: ToolCall[] = [];\n\n for (const block of content) {\n if (block.type === 'text') {\n textContent += block.text as string;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id as string,\n type: 'function',\n function: {\n name: block.name as string,\n arguments: JSON.stringify(block.input),\n },\n });\n }\n }\n\n const usage = data.usage as { input_tokens: number; output_tokens: number } | undefined;\n\n return {\n id: (data.id as string) || uuid(),\n content: textContent,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: usage\n ? {\n promptTokens: usage.input_tokens,\n completionTokens: usage.output_tokens,\n totalTokens: usage.input_tokens + usage.output_tokens,\n }\n : undefined,\n finishReason: toolCalls.length > 0 ? 'tool_calls' : 'stop',\n model,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n // For streaming, we'll use the non-streaming endpoint and yield the full response\n // A full streaming implementation would use SSE, which we'd implement for production\n try {\n const response = await this.chat(options);\n if (response.content) {\n yield { type: 'text', content: response.content };\n }\n if (response.toolCalls) {\n for (const tc of response.toolCalls) {\n yield { type: 'tool_call', toolCall: tc };\n }\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n return [\n 'claude-opus-4-0',\n 'claude-sonnet-4-20250514',\n 'claude-haiku-4-20250414',\n 'claude-3-5-sonnet-20241022',\n 'claude-3-5-haiku-20241022',\n ];\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n if (!this.apiKey) return false;\n const response = await fetch(`${this.baseUrl}/v1/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({\n model: 'claude-haiku-4-20250414',\n max_tokens: 1,\n messages: [{ role: 'user', content: 'ping' }],\n }),\n });\n return response.ok || response.status === 400; // 400 = valid auth but bad request\n } catch {\n return false;\n }\n }\n}\n","/**\n * TITAN — OpenAI Provider (GPT-4, o-series)\n */\nimport {\n LLMProvider,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport logger from '../utils/logger.js';\nimport { v4 as uuid } from 'uuid';\n\nconst COMPONENT = 'OpenAI';\n\nexport class OpenAIProvider extends LLMProvider {\n readonly name = 'openai';\n readonly displayName = 'OpenAI (GPT)';\n\n private get apiKey(): string {\n const config = loadConfig();\n return config.providers.openai.apiKey || process.env.OPENAI_API_KEY || '';\n }\n\n private get baseUrl(): string {\n const config = loadConfig();\n return config.providers.openai.baseUrl || 'https://api.openai.com';\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const model = options.model || 'gpt-4o';\n const apiKey = this.apiKey;\n if (!apiKey) throw new Error('OpenAI API key not configured');\n\n logger.debug(COMPONENT, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const body: Record<string, unknown> = {\n model: model.replace('openai/', ''),\n messages: options.messages.map((m) => {\n if (m.role === 'tool') {\n return { role: 'tool', content: m.content, tool_call_id: m.toolCallId };\n }\n if (m.role === 'assistant' && m.toolCalls) {\n return {\n role: 'assistant',\n content: m.content || null,\n tool_calls: m.toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: { name: tc.function.name, arguments: tc.function.arguments },\n })),\n };\n }\n return { role: m.role, content: m.content };\n }),\n max_tokens: options.maxTokens || 8192,\n };\n\n if (options.tools && options.tools.length > 0) {\n body.tools = options.tools;\n }\n\n if (options.temperature !== undefined) {\n body.temperature = options.temperature;\n }\n\n const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`OpenAI API error (${response.status}): ${errorText}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const choices = data.choices as Array<Record<string, unknown>>;\n const choice = choices[0];\n const message = choice.message as Record<string, unknown>;\n\n const toolCalls: ToolCall[] = [];\n if (message.tool_calls) {\n for (const tc of message.tool_calls as Array<Record<string, unknown>>) {\n const fn = tc.function as Record<string, string>;\n toolCalls.push({\n id: tc.id as string,\n type: 'function',\n function: { name: fn.name, arguments: fn.arguments },\n });\n }\n }\n\n const usage = data.usage as { prompt_tokens: number; completion_tokens: number; total_tokens: number } | undefined;\n\n return {\n id: (data.id as string) || uuid(),\n content: (message.content as string) || '',\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: usage\n ? {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n }\n : undefined,\n finishReason: toolCalls.length > 0 ? 'tool_calls' : (choice.finish_reason as 'stop' | 'length') || 'stop',\n model,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n try {\n const response = await this.chat(options);\n if (response.content) {\n yield { type: 'text', content: response.content };\n }\n if (response.toolCalls) {\n for (const tc of response.toolCalls) {\n yield { type: 'tool_call', toolCall: tc };\n }\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n return ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1', 'o1-mini', 'o3-mini'];\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n if (!this.apiKey) return false;\n const response = await fetch(`${this.baseUrl}/v1/models`, {\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n","/**\n * TITAN — Google Gemini Provider\n */\nimport {\n LLMProvider,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport logger from '../utils/logger.js';\nimport { v4 as uuid } from 'uuid';\n\nconst COMPONENT = 'Google';\n\nexport class GoogleProvider extends LLMProvider {\n readonly name = 'google';\n readonly displayName = 'Google (Gemini)';\n\n private get apiKey(): string {\n const config = loadConfig();\n return config.providers.google.apiKey || process.env.GOOGLE_API_KEY || '';\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const model = (options.model || 'gemini-2.0-flash').replace('google/', '');\n const apiKey = this.apiKey;\n if (!apiKey) throw new Error('Google API key not configured');\n\n logger.debug(COMPONENT, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const systemInstruction = options.messages.find((m) => m.role === 'system')?.content;\n const contents = options.messages\n .filter((m) => m.role !== 'system')\n .map((m) => ({\n role: m.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: m.content }],\n }));\n\n const body: Record<string, unknown> = {\n contents,\n generationConfig: {\n maxOutputTokens: options.maxTokens || 8192,\n temperature: options.temperature ?? 0.7,\n },\n };\n\n if (systemInstruction) {\n body.systemInstruction = { parts: [{ text: systemInstruction }] };\n }\n\n if (options.tools && options.tools.length > 0) {\n body.tools = [{\n functionDeclarations: options.tools.map((t) => ({\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters,\n })),\n }];\n }\n\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Google API error (${response.status}): ${errorText}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const candidates = data.candidates as Array<Record<string, unknown>>;\n\n let textContent = '';\n const toolCalls: ToolCall[] = [];\n\n if (candidates && candidates.length > 0) {\n const parts = (candidates[0].content as Record<string, unknown>)?.parts as Array<Record<string, unknown>> || [];\n for (const part of parts) {\n if (part.text) {\n textContent += part.text as string;\n }\n if (part.functionCall) {\n const fc = part.functionCall as Record<string, unknown>;\n toolCalls.push({\n id: uuid(),\n type: 'function',\n function: {\n name: fc.name as string,\n arguments: JSON.stringify(fc.args),\n },\n });\n }\n }\n }\n\n const usageMeta = data.usageMetadata as { promptTokenCount?: number; candidatesTokenCount?: number; totalTokenCount?: number } | undefined;\n\n return {\n id: uuid(),\n content: textContent,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: usageMeta\n ? {\n promptTokens: usageMeta.promptTokenCount || 0,\n completionTokens: usageMeta.candidatesTokenCount || 0,\n totalTokens: usageMeta.totalTokenCount || 0,\n }\n : undefined,\n finishReason: toolCalls.length > 0 ? 'tool_calls' : 'stop',\n model: `google/${model}`,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n try {\n const response = await this.chat(options);\n if (response.content) yield { type: 'text', content: response.content };\n if (response.toolCalls) {\n for (const tc of response.toolCalls) yield { type: 'tool_call', toolCall: tc };\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n return ['gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.0-flash', 'gemini-1.5-pro'];\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n if (!this.apiKey) return false;\n const url = `https://generativelanguage.googleapis.com/v1beta/models?key=${this.apiKey}`;\n const response = await fetch(url);\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n","/**\n * TITAN — Ollama Provider (Local LLMs)\n */\nimport {\n LLMProvider,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport logger from '../utils/logger.js';\nimport { v4 as uuid } from 'uuid';\n\nconst COMPONENT = 'Ollama';\n\nexport class OllamaProvider extends LLMProvider {\n readonly name = 'ollama';\n readonly displayName = 'Ollama (Local)';\n\n private get baseUrl(): string {\n const config = loadConfig();\n return config.providers.ollama.baseUrl || process.env.OLLAMA_BASE_URL || 'http://localhost:11434';\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const model = (options.model || 'llama3.1').replace('ollama/', '');\n logger.debug(COMPONENT, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const body: Record<string, unknown> = {\n model,\n messages: options.messages.map((m) => ({\n role: m.role,\n content: m.content,\n })),\n stream: false,\n options: {\n num_predict: options.maxTokens || 8192,\n temperature: options.temperature ?? 0.7,\n },\n };\n\n if (options.tools && options.tools.length > 0) {\n body.tools = options.tools.map((t) => ({\n type: 'function',\n function: {\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters,\n },\n }));\n }\n\n const response = await fetch(`${this.baseUrl}/api/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Ollama error (${response.status}): ${errorText}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const message = data.message as Record<string, unknown>;\n const toolCalls: ToolCall[] = [];\n\n if (message.tool_calls) {\n for (const tc of message.tool_calls as Array<Record<string, unknown>>) {\n const fn = tc.function as Record<string, unknown>;\n toolCalls.push({\n id: uuid(),\n type: 'function',\n function: {\n name: fn.name as string,\n arguments: JSON.stringify(fn.arguments),\n },\n });\n }\n }\n\n return {\n id: uuid(),\n content: (message.content as string) || '',\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: {\n promptTokens: (data.prompt_eval_count as number) || 0,\n completionTokens: (data.eval_count as number) || 0,\n totalTokens: ((data.prompt_eval_count as number) || 0) + ((data.eval_count as number) || 0),\n },\n finishReason: toolCalls.length > 0 ? 'tool_calls' : 'stop',\n model: `ollama/${model}`,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n try {\n const response = await this.chat(options);\n if (response.content) yield { type: 'text', content: response.content };\n if (response.toolCalls) {\n for (const tc of response.toolCalls) yield { type: 'tool_call', toolCall: tc };\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n try {\n const response = await fetch(`${this.baseUrl}/api/tags`);\n if (!response.ok) return [];\n const data = await response.json() as { models?: Array<{ name: string }> };\n return (data.models || []).map((m) => m.name);\n } catch {\n return [];\n }\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/api/tags`);\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n","/**\n * TITAN — Provider Router\n * Routes model requests to the correct provider with failover support.\n */\nimport { LLMProvider, type ChatOptions, type ChatResponse, type ChatStreamChunk } from './base.js';\nimport { AnthropicProvider } from './anthropic.js';\nimport { OpenAIProvider } from './openai.js';\nimport { GoogleProvider } from './google.js';\nimport { OllamaProvider } from './ollama.js';\nimport logger from '../utils/logger.js';\n\nconst COMPONENT = 'Router';\n\n/** Provider registry */\nconst providers: Map<string, LLMProvider> = new Map();\nlet initialized = false;\n\nfunction initProviders(): void {\n if (initialized) return;\n providers.set('anthropic', new AnthropicProvider());\n providers.set('openai', new OpenAIProvider());\n providers.set('google', new GoogleProvider());\n providers.set('ollama', new OllamaProvider());\n initialized = true;\n}\n\n/** Get a provider by name */\nexport function getProvider(name: string): LLMProvider | undefined {\n initProviders();\n return providers.get(name);\n}\n\n/** Get all registered providers */\nexport function getAllProviders(): Map<string, LLMProvider> {\n initProviders();\n return providers;\n}\n\n/** Resolve the provider and model from a model ID like \"anthropic/claude-3\" */\nexport function resolveModel(modelId: string): { provider: LLMProvider; model: string } {\n initProviders();\n const { provider: providerName, model } = LLMProvider.parseModelId(modelId);\n const provider = providers.get(providerName);\n if (!provider) {\n throw new Error(`Unknown provider: ${providerName}. Available: ${Array.from(providers.keys()).join(', ')}`);\n }\n return { provider, model };\n}\n\n/** Send a chat request, automatically routing to the correct provider */\nexport async function chat(options: ChatOptions): Promise<ChatResponse> {\n const modelId = options.model || 'anthropic/claude-sonnet-4-20250514';\n const { provider, model } = resolveModel(modelId);\n\n logger.info(COMPONENT, `Routing to ${provider.displayName} (model: ${model})`);\n\n try {\n return await provider.chat({ ...options, model });\n } catch (error) {\n logger.error(COMPONENT, `Provider ${provider.name} failed: ${(error as Error).message}`);\n // Attempt failover to other providers\n const failoverOrder = ['anthropic', 'openai', 'google', 'ollama'];\n for (const fallbackName of failoverOrder) {\n if (fallbackName === provider.name) continue;\n const fallback = providers.get(fallbackName);\n if (!fallback) continue;\n\n try {\n const healthy = await fallback.healthCheck();\n if (!healthy) continue;\n\n const models = await fallback.listModels();\n if (models.length === 0) continue;\n\n logger.warn(COMPONENT, `Failing over to ${fallback.displayName} (model: ${models[0]})`);\n return await fallback.chat({ ...options, model: models[0] });\n } catch {\n continue;\n }\n }\n throw error;\n }\n}\n\n/** Send a streaming chat request */\nexport async function* chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n const modelId = options.model || 'anthropic/claude-sonnet-4-20250514';\n const { provider, model } = resolveModel(modelId);\n yield* provider.chatStream({ ...options, model });\n}\n\n/** Health check all providers */\nexport async function healthCheckAll(): Promise<Record<string, boolean>> {\n initProviders();\n const results: Record<string, boolean> = {};\n for (const [name, provider] of providers) {\n try {\n results[name] = await provider.healthCheck();\n } catch {\n results[name] = false;\n }\n }\n return results;\n}\n","/**\n * TITAN — Skill Auto-Generation Engine\n * Allows TITAN to dynamically write, validate, and install its own TypeScript tools\n * when it encounters a task it doesn't currently have a skill for.\n */\nimport path from 'path';\nimport { existsSync, writeFileSync, mkdirSync } from 'fs';\nimport { loadConfig } from '../config/config.js';\nimport { chat } from '../providers/router.js';\nimport type { ChatMessage } from '../providers/base.js';\nimport { TITAN_HOME } from '../utils/constants.js';\nimport { loadAutoSkills } from '../skills/registry.js';\nimport logger from '../utils/logger.js';\nimport { execSync } from 'child_process';\n\nconst COMPONENT = 'SkillGenerator';\nconst AUTO_SKILLS_DIR = path.join(TITAN_HOME, 'skills', 'auto');\n\nexport interface GenerationResult {\n success: boolean;\n skillName?: string;\n filePath?: string;\n error?: string;\n}\n\nconst GENERATOR_PROMPT = `You are the core intelligence of TITAN, an elite autonomous AI agent framework.\nYour task is to generate a new, fully functional TypeScript tool (skill) based on the user's request.\n\nCRITICAL REQUIREMENTS FOR THE CODE:\n1. It MUST export a \"default\" object that implements the \"ToolConfig\" interface.\n2. It MUST use ESM imports (e.g., \"import { ... } from '...'\").\n3. It CAN ONLY use built-in Node.js modules (fs, path, crypto, child_process, os, http, https, url) unless you are absolutely certain a specific npm package is guaranteed to be installed globally. Prefer built-ins.\n4. It MUST handle errors gracefully and return descriptive string messages.\n5. Do NOT wrap the output in markdown code blocks. Output ONLY the raw TypeScript code.\n\nHere is the exact ToolConfig interface you must implement:\nexport interface ToolConfig {\n name: string; // lowercase, alphanumeric, underscores only (e.g. 'my_custom_tool')\n description: string; // concise explanation of what the tool does\n parameters: any; // Zod schema converted to JSON schema format for LLM function calling\n execute: (args: any, config: any) => Promise<string>; // the async execution function\n}\n\nExample JSON schema for parameters (must follow this exact structure):\n{\n \"type\": \"object\",\n \"properties\": {\n \"filePath\": {\n \"type\": \"string\",\n \"description\": \"Absolute path to the file\"\n }\n },\n \"required\": [\"filePath\"]\n}\n\nExample implementation format:\nimport fs from 'fs';\n\nexport default {\n name: \"count_lines\",\n description: \"Counts the number of lines in a given text file.\",\n parameters: {\n type: \"object\",\n properties: {\n filePath: { type: \"string\" }\n },\n required: [\"filePath\"]\n },\n execute: async (args, config) => {\n try {\n const content = fs.readFileSync(args.filePath, 'utf-8');\n return \\`File has \\${content.split('\\\\n').length} lines.\\`;\n } catch (e) {\n return \\`Error: \\${e.message}\\`;\n }\n }\n};\n\nNow, generate the TypeScript code for the following requested tool capability:\n`;\n\n/**\n * Generate, validate, and install a new skill.\n */\nexport async function generateAndInstallSkill(\n description: string,\n requestedName: string\n): Promise<GenerationResult> {\n logger.info(COMPONENT, `Initiating auto-generation for skill: \"${requestedName}\"`);\n\n // Ensure auto directory exists\n if (!existsSync(AUTO_SKILLS_DIR)) {\n mkdirSync(AUTO_SKILLS_DIR, { recursive: true });\n }\n\n try {\n const config = loadConfig();\n const model = config.agent.model; // Use primary agent model to write code\n\n // 1. Generate the Code\n logger.debug(COMPONENT, `Prompting ${model} to generate code...`);\n const messages: ChatMessage[] = [\n { role: 'user', content: GENERATOR_PROMPT + `\\nRequested Capability: ${description}\\nRequested Name: ${requestedName}` }\n ];\n\n const response = await chat({ messages, model });\n let code = response.content;\n\n // Clean up markdown block if the LLM ignored instructions\n if (code.startsWith('\\`\\`\\`typescript')) {\n code = code.replace(/^\\`\\`\\`typescript\\n/, '').replace(/\\n\\`\\`\\`$/, '');\n } else if (code.startsWith('\\`\\`\\`')) {\n code = code.replace(/^\\`\\`\\`\\n/, '').replace(/\\n\\`\\`\\`$/, '');\n }\n\n // 2. Static Analysis / Safety Check (Basic)\n // Prevent obvious malicious generation (e.g., trying to modify TITAN itself)\n if (code.includes('process.exit') || code.includes('rm -rf /*') || code.includes('fs.rmSync(\\'/\\'')) {\n return { success: false, error: \"Generated code failed safety static analysis.\" };\n }\n\n // Extract the name from the generated code (fallback to requestedName)\n const nameMatch = code.match(/name:\\s*['\"]([a-z0-9_]+)['\"]/);\n const finalName = nameMatch ? nameMatch[1] : requestedName.replace(/[^a-z0-9_]/g, '_');\n\n const tsFilePath = path.join(AUTO_SKILLS_DIR, `${finalName}.ts`);\n const jsFilePath = path.join(AUTO_SKILLS_DIR, `${finalName}.js`);\n\n // 3. Write to disk\n writeFileSync(tsFilePath, code, 'utf-8');\n logger.info(COMPONENT, `Wrote generated source to ${tsFilePath}`);\n\n // 4. Compile it exactly like TITAN does (tsc)\n try {\n // Use tsx or tsc to compile it to JS so Node can load it dynamically\n // We'll write a tiny compiler script or use tsc directly if available globally\n execSync(`npx tsc ${tsFilePath} --module NodeNext --moduleResolution NodeNext --target ES2022`, { stdio: 'pipe' });\n logger.info(COMPONENT, `Compiled ${finalName}.ts successfully.`);\n } catch (compileError: any) {\n logger.error(COMPONENT, `Compilation failed for ${finalName}`);\n return { success: false, error: `Compilation failed: ${compileError.message || 'Unknown error'}` };\n }\n\n if (!existsSync(jsFilePath)) {\n return { success: false, error: \"Compilation did not produce a .js file.\" };\n }\n\n // 5. Reload Skills Registry\n // By calling loadAutoSkills, it will pick up the new .js file if we ensure it scans the auto dir\n await loadAutoSkills();\n\n logger.info(COMPONENT, `✨ Successfully generated and installed new skill: ${finalName}`);\n\n return {\n success: true,\n skillName: finalName,\n filePath: tsFilePath\n };\n\n } catch (e: any) {\n logger.error(COMPONENT, `Auto-generation failed: ${e.message}`);\n return { success: false, error: e.message };\n }\n}\n","import { registerSkill } from '../registry.js';\nimport type { ToolHandler } from '../../agent/toolRunner.js';\nimport { generateAndInstallSkill } from '../../agent/generator.js';\n\nconst meta = {\n name: 'auto_generate_skill',\n description: 'Auto-generates, compiles, and installs a new TypeScript tool/skill when TITAN lacks a necessary capability.',\n version: '1.0.0',\n source: 'bundled' as const,\n enabled: true,\n};\n\nconst handler: ToolHandler = {\n name: 'auto_generate_skill',\n description: 'Use this tool to write a NEW skill/tool when you realize you cannot complete the user request with your standard tools. Generates real TypeScript code, compiles it, and hot-reloads it into your capabilities.',\n parameters: {\n type: 'object',\n properties: {\n capability_description: {\n type: 'string',\n description: 'A detailed explanation of exactly what this new tool should do, what arguments it should take, and what it should return.',\n },\n suggested_name: {\n type: 'string',\n description: 'A short, lowercase name with underscores for the new tool (e.g., \"parse_csv\", \"resize_image\").',\n },\n },\n required: ['capability_description', 'suggested_name'],\n },\n execute: async (args: Record<string, unknown>) => {\n const capability = args.capability_description as string;\n const name = args.suggested_name as string;\n\n if (!capability || !name) {\n return \"Error: missing required arguments capability_description or suggested_name.\";\n }\n\n const result = await generateAndInstallSkill(capability, name);\n if (result.success) {\n return `✨ SUCCESS! New skill '${result.skillName}' has been generated, compiled, and hot-loaded into your tools. You can now use this tool natively!`;\n } else {\n return `Failed to generate skill: ${result.error}`;\n }\n },\n};\n\nexport function registerAutoGenerateSkill(): void {\n registerSkill(meta, handler);\n}\n"],"mappings":"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","names":["existsSync","path","handler","COMPONENT","existsSync","readFileSync","join","meta","handler","COMPONENT","COMPONENT","uuid","COMPONENT","uuid","COMPONENT","uuid","COMPONENT","COMPONENT","existsSync","writeFileSync","mkdirSync","COMPONENT"]}
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env node
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+
7
+ // src/utils/constants.ts
8
+ import { homedir } from "os";
9
+ import { join } from "path";
10
+ var TITAN_VERSION, TITAN_ASCII_LOGO, TITAN_HOME, TITAN_CONFIG_PATH, TITAN_DB_PATH, TITAN_WORKSPACE, TITAN_SKILLS_DIR, TITAN_LOGS_DIR, TITAN_MEMORY_DIR, AGENTS_MD, SOUL_MD, TOOLS_MD, DEFAULT_GATEWAY_HOST, DEFAULT_GATEWAY_PORT, DEFAULT_WEB_PORT, DEFAULT_MODEL, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE, SESSION_TIMEOUT_MS, DEFAULT_SANDBOX_MODE, ALLOWED_TOOLS_DEFAULT;
11
+ var init_constants = __esm({
12
+ "src/utils/constants.ts"() {
13
+ "use strict";
14
+ TITAN_VERSION = "2026.4.0";
15
+ TITAN_ASCII_LOGO = `
16
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
17
+ \u2551 \u2551
18
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
19
+ \u2551 \u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2551
20
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2551
21
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2551
22
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2551
23
+ \u2551 \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u2551
24
+ \u2551 \u2551
25
+ \u2551 The Intelligent Task Automation Network \u2551
26
+ \u2551 v${TITAN_VERSION} \u2551
27
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;
28
+ TITAN_HOME = join(homedir(), ".titan");
29
+ TITAN_CONFIG_PATH = join(TITAN_HOME, "titan.json");
30
+ TITAN_DB_PATH = join(TITAN_HOME, "titan.db");
31
+ TITAN_WORKSPACE = join(TITAN_HOME, "workspace");
32
+ TITAN_SKILLS_DIR = join(TITAN_WORKSPACE, "skills");
33
+ TITAN_LOGS_DIR = join(TITAN_HOME, "logs");
34
+ TITAN_MEMORY_DIR = join(TITAN_HOME, "memory");
35
+ AGENTS_MD = join(TITAN_WORKSPACE, "AGENTS.md");
36
+ SOUL_MD = join(TITAN_WORKSPACE, "SOUL.md");
37
+ TOOLS_MD = join(TITAN_WORKSPACE, "TOOLS.md");
38
+ DEFAULT_GATEWAY_HOST = "127.0.0.1";
39
+ DEFAULT_GATEWAY_PORT = 18789;
40
+ DEFAULT_WEB_PORT = 18790;
41
+ DEFAULT_MODEL = "anthropic/claude-sonnet-4-20250514";
42
+ DEFAULT_MAX_TOKENS = 8192;
43
+ DEFAULT_TEMPERATURE = 0.7;
44
+ SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
45
+ DEFAULT_SANDBOX_MODE = "host";
46
+ ALLOWED_TOOLS_DEFAULT = [
47
+ "shell",
48
+ "read_file",
49
+ "write_file",
50
+ "edit_file",
51
+ "list_dir",
52
+ "web_search",
53
+ "browser",
54
+ "cron",
55
+ "webhook",
56
+ "email",
57
+ "memory"
58
+ ];
59
+ }
60
+ });
61
+
62
+ // src/utils/logger.ts
63
+ import chalk from "chalk";
64
+ function formatTimestamp() {
65
+ return chalk.gray((/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19));
66
+ }
67
+ function log(level, component, message, ...args) {
68
+ if (level < currentLevel) return;
69
+ const prefix = `${formatTimestamp()} ${LEVEL_LABELS[level]} ${chalk.blue(`[${component}]`)}`;
70
+ console.log(`${prefix} ${message}`, ...args);
71
+ }
72
+ var LEVEL_LABELS, currentLevel, logger, logger_default;
73
+ var init_logger = __esm({
74
+ "src/utils/logger.ts"() {
75
+ "use strict";
76
+ LEVEL_LABELS = {
77
+ [0 /* DEBUG */]: chalk.gray("DEBUG"),
78
+ [1 /* INFO */]: chalk.cyan("INFO "),
79
+ [2 /* WARN */]: chalk.yellow("WARN "),
80
+ [3 /* ERROR */]: chalk.red("ERROR"),
81
+ [4 /* SILENT */]: ""
82
+ };
83
+ currentLevel = 1 /* INFO */;
84
+ logger = {
85
+ debug: (component, msg, ...args) => log(0 /* DEBUG */, component, msg, ...args),
86
+ info: (component, msg, ...args) => log(1 /* INFO */, component, msg, ...args),
87
+ warn: (component, msg, ...args) => log(2 /* WARN */, component, msg, ...args),
88
+ error: (component, msg, ...args) => log(3 /* ERROR */, component, msg, ...args)
89
+ };
90
+ logger_default = logger;
91
+ }
92
+ });
93
+
94
+ // src/utils/helpers.ts
95
+ var init_helpers = __esm({
96
+ "src/utils/helpers.ts"() {
97
+ "use strict";
98
+ }
99
+ });
100
+
101
+ // src/config/schema.ts
102
+ import { z } from "zod";
103
+ var ProviderConfigSchema, ChannelConfigSchema, SecurityConfigSchema, GatewayConfigSchema, AgentConfigSchema, TitanConfigSchema;
104
+ var init_schema = __esm({
105
+ "src/config/schema.ts"() {
106
+ "use strict";
107
+ init_constants();
108
+ ProviderConfigSchema = z.object({
109
+ apiKey: z.string().optional(),
110
+ baseUrl: z.string().optional(),
111
+ model: z.string().optional(),
112
+ maxTokens: z.number().optional(),
113
+ temperature: z.number().min(0).max(2).optional()
114
+ });
115
+ ChannelConfigSchema = z.object({
116
+ enabled: z.boolean().default(false),
117
+ token: z.string().optional(),
118
+ apiKey: z.string().optional(),
119
+ allowFrom: z.array(z.string()).default([]),
120
+ dmPolicy: z.enum(["pairing", "open", "closed"]).default("pairing")
121
+ });
122
+ SecurityConfigSchema = z.object({
123
+ sandboxMode: z.enum(["host", "docker", "none"]).default(DEFAULT_SANDBOX_MODE),
124
+ allowedTools: z.array(z.string()).default(ALLOWED_TOOLS_DEFAULT),
125
+ deniedTools: z.array(z.string()).default([]),
126
+ maxConcurrentTasks: z.number().default(5),
127
+ commandTimeout: z.number().default(3e4),
128
+ fileSystemAllowlist: z.array(z.string()).default([]),
129
+ networkAllowlist: z.array(z.string()).default(["*"]),
130
+ shield: z.object({
131
+ enabled: z.boolean().default(true),
132
+ mode: z.enum(["standard", "strict"]).default("strict")
133
+ }).default({})
134
+ });
135
+ GatewayConfigSchema = z.object({
136
+ host: z.string().default(DEFAULT_GATEWAY_HOST),
137
+ port: z.number().default(DEFAULT_GATEWAY_PORT),
138
+ webPort: z.number().default(DEFAULT_WEB_PORT),
139
+ auth: z.object({
140
+ mode: z.enum(["none", "token", "password"]).default("token"),
141
+ token: z.string().optional(),
142
+ password: z.string().optional()
143
+ }).default({})
144
+ });
145
+ AgentConfigSchema = z.object({
146
+ model: z.string().default(DEFAULT_MODEL),
147
+ maxTokens: z.number().default(DEFAULT_MAX_TOKENS),
148
+ temperature: z.number().default(DEFAULT_TEMPERATURE),
149
+ systemPrompt: z.string().optional(),
150
+ workspace: z.string().optional(),
151
+ thinkingMode: z.enum(["off", "low", "medium", "high"]).default("medium")
152
+ });
153
+ TitanConfigSchema = z.object({
154
+ agent: AgentConfigSchema.default({}),
155
+ providers: z.object({
156
+ anthropic: ProviderConfigSchema.default({}),
157
+ openai: ProviderConfigSchema.default({}),
158
+ google: ProviderConfigSchema.default({}),
159
+ ollama: ProviderConfigSchema.default({})
160
+ }).default({}),
161
+ channels: z.object({
162
+ discord: ChannelConfigSchema.default({}),
163
+ telegram: ChannelConfigSchema.default({}),
164
+ slack: ChannelConfigSchema.default({}),
165
+ whatsapp: ChannelConfigSchema.default({}),
166
+ webchat: ChannelConfigSchema.default({}),
167
+ googlechat: ChannelConfigSchema.default({}),
168
+ matrix: ChannelConfigSchema.default({}),
169
+ signal: ChannelConfigSchema.default({}),
170
+ msteams: ChannelConfigSchema.default({}),
171
+ bluebubbles: ChannelConfigSchema.default({})
172
+ }).default({}),
173
+ gateway: GatewayConfigSchema.default({}),
174
+ security: SecurityConfigSchema.default({}),
175
+ memory: z.object({
176
+ enabled: z.boolean().default(true),
177
+ maxHistoryMessages: z.number().default(50),
178
+ vectorSearchEnabled: z.boolean().default(false)
179
+ }).default({}),
180
+ skills: z.object({
181
+ enabled: z.boolean().default(true),
182
+ autoDiscover: z.boolean().default(true),
183
+ marketplace: z.boolean().default(false)
184
+ }).default({}),
185
+ logging: z.object({
186
+ level: z.enum(["debug", "info", "warn", "error", "silent"]).default("info"),
187
+ file: z.boolean().default(true)
188
+ }).default({}),
189
+ autonomy: z.object({
190
+ /** autonomous = full auto, supervised = asks for dangerous ops, locked = asks for everything */
191
+ mode: z.enum(["autonomous", "supervised", "locked"]).default("supervised"),
192
+ /** Auto-approve moderate-risk tools in main session (cli/webchat) */
193
+ autoApproveMainSession: z.boolean().default(true),
194
+ /** Timeout for HITL approval requests (ms). Auto-deny after timeout. */
195
+ approvalTimeoutMs: z.number().default(6e4),
196
+ /** Notify user of auto-approved actions */
197
+ notifyOnAutoApprove: z.boolean().default(true)
198
+ }).default({})
199
+ });
200
+ }
201
+ });
202
+
203
+ // src/config/config.ts
204
+ var init_config = __esm({
205
+ "src/config/config.ts"() {
206
+ "use strict";
207
+ init_constants();
208
+ init_helpers();
209
+ init_schema();
210
+ init_logger();
211
+ }
212
+ });
213
+
214
+ // src/agent/toolRunner.ts
215
+ function registerTool(handler) {
216
+ toolRegistry.set(handler.name, handler);
217
+ logger_default.debug(COMPONENT, `Registered tool: ${handler.name}`);
218
+ }
219
+ var COMPONENT, toolRegistry;
220
+ var init_toolRunner = __esm({
221
+ "src/agent/toolRunner.ts"() {
222
+ "use strict";
223
+ init_logger();
224
+ init_config();
225
+ COMPONENT = "ToolRunner";
226
+ toolRegistry = /* @__PURE__ */ new Map();
227
+ }
228
+ });
229
+
230
+ // src/skills/registry.ts
231
+ function registerSkill(meta, handler) {
232
+ registeredSkills.set(meta.name, meta);
233
+ registerTool(handler);
234
+ logger_default.debug(COMPONENT2, `Registered skill: ${meta.name} (${meta.source})`);
235
+ }
236
+ var COMPONENT2, registeredSkills;
237
+ var init_registry = __esm({
238
+ "src/skills/registry.ts"() {
239
+ "use strict";
240
+ init_constants();
241
+ init_toolRunner();
242
+ init_helpers();
243
+ init_logger();
244
+ COMPONENT2 = "Skills";
245
+ registeredSkills = /* @__PURE__ */ new Map();
246
+ }
247
+ });
248
+
249
+ // src/skills/builtin/browser.ts
250
+ import { exec } from "child_process";
251
+ function registerBrowserSkill() {
252
+ registerSkill(
253
+ { name: "browser", description: "Browser control and web automation", version: "1.0.0", source: "bundled", enabled: true },
254
+ {
255
+ name: "browser",
256
+ description: "Control a Chromium-based browser to navigate websites, take snapshots, click elements, type text, evaluate JavaScript, and extract page content. Uses Chrome DevTools Protocol (CDP).",
257
+ parameters: {
258
+ type: "object",
259
+ properties: {
260
+ action: {
261
+ type: "string",
262
+ enum: ["navigate", "snapshot", "click", "type", "evaluate", "extract", "screenshot"],
263
+ description: "Browser action to perform"
264
+ },
265
+ url: { type: "string", description: "URL to navigate to (for navigate action)" },
266
+ selector: { type: "string", description: "CSS selector for click/type actions" },
267
+ text: { type: "string", description: "Text to type (for type action)" },
268
+ script: { type: "string", description: "JavaScript code to evaluate (for evaluate action)" }
269
+ },
270
+ required: ["action"]
271
+ },
272
+ execute: async (args) => {
273
+ const action = args.action;
274
+ switch (action) {
275
+ case "navigate": {
276
+ const url = args.url;
277
+ if (!url) return "Error: url is required";
278
+ logger_default.info(COMPONENT3, `Navigating to: ${url}`);
279
+ return new Promise((resolve) => {
280
+ exec(`curl -sL --max-time 15 "${url}" | head -c 50000`, { timeout: 2e4 }, (err, stdout) => {
281
+ if (err) {
282
+ resolve(`Error fetching ${url}: ${err.message}`);
283
+ return;
284
+ }
285
+ const text = stdout.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
286
+ resolve(`Page content from ${url}:
287
+ ${text.slice(0, 2e4)}`);
288
+ });
289
+ });
290
+ }
291
+ case "snapshot":
292
+ case "extract": {
293
+ const url = args.url;
294
+ if (!url) return "Error: url is required for snapshot/extract";
295
+ return new Promise((resolve) => {
296
+ exec(`curl -sL --max-time 15 "${url}" | head -c 50000`, { timeout: 2e4 }, (err, stdout) => {
297
+ if (err) {
298
+ resolve(`Error: ${err.message}`);
299
+ return;
300
+ }
301
+ const title = stdout.match(/<title[^>]*>(.*?)<\/title>/i)?.[1] || "No title";
302
+ const desc = stdout.match(/<meta[^>]*name="description"[^>]*content="([^"]*)"[^>]*>/i)?.[1] || "";
303
+ const links = [];
304
+ const linkRegex = /<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi;
305
+ let m;
306
+ while ((m = linkRegex.exec(stdout)) !== null && links.length < 20) {
307
+ const text = m[2].replace(/<[^>]*>/g, "").trim();
308
+ if (text && m[1] && !m[1].startsWith("#")) links.push(` ${text}: ${m[1]}`);
309
+ }
310
+ resolve(`Page: ${title}
311
+ Description: ${desc}
312
+ Links:
313
+ ${links.join("\n")}`);
314
+ });
315
+ });
316
+ }
317
+ case "evaluate": {
318
+ const script = args.script;
319
+ if (!script) return "Error: script is required";
320
+ return `Note: Full CDP browser evaluation requires a running browser session. Script queued: ${script.slice(0, 200)}`;
321
+ }
322
+ case "screenshot": {
323
+ const url = args.url;
324
+ if (!url) return "Error: url is required";
325
+ return `Screenshot capture requires CDP connection to a running Chromium instance. Target: ${url}`;
326
+ }
327
+ case "click": {
328
+ const selector = args.selector;
329
+ if (!selector) return "Error: selector is required";
330
+ return `Click action requires CDP connection. Selector: ${selector}`;
331
+ }
332
+ case "type": {
333
+ const selector = args.selector;
334
+ const text = args.text;
335
+ if (!selector || !text) return "Error: selector and text are required";
336
+ return `Type action requires CDP connection. Selector: ${selector}, Text: ${text}`;
337
+ }
338
+ default:
339
+ return `Unknown browser action: ${action}`;
340
+ }
341
+ }
342
+ }
343
+ );
344
+ }
345
+ var COMPONENT3;
346
+ var init_browser = __esm({
347
+ "src/skills/builtin/browser.ts"() {
348
+ init_registry();
349
+ init_logger();
350
+ COMPONENT3 = "Browser";
351
+ }
352
+ });
353
+ init_browser();
354
+ export {
355
+ registerBrowserSkill
356
+ };
357
+ //# sourceMappingURL=browser.js.map