@axiom-lattice/gateway 2.1.63 → 2.1.64

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/controllers/assistant.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/agent_task.ts","../src/controllers/threads.ts","../src/controllers/schedules.ts","../src/config.ts","../src/services/queue_service.ts","../src/controllers/config.ts","../src/controllers/models.ts","../src/controllers/health.ts","../src/services/skill_service.ts","../src/controllers/skills.ts","../src/controllers/tools.ts","../src/controllers/data-query.ts","../src/schemas/data-query.ts","../src/schemas/index.ts","../src/controllers/thread_status.ts","../src/services/sandbox_service.ts","../src/controllers/sandbox.ts","../src/controllers/workspace.ts","../src/controllers/database-configs.ts","../src/controllers/metrics-configs.ts","../src/controllers/mcp-configs.ts","../src/controllers/users.ts","../src/controllers/tenants.ts","../src/controllers/auth.ts","../src/channels/lark/routes.ts","../src/channels/lark/parser.ts","../src/channels/lark/controller.ts","../src/channels/lark/config.ts","../src/channels/lark/mapping-service.ts","../src/channels/lark/runner.ts","../src/channels/lark/aggregator.ts","../src/channels/lark/sender.ts","../src/channels/lark/verification.ts","../src/channels/routes.ts","../src/controllers/channel-installations.ts","../src/routes/channel-installations.ts","../src/routes/index.ts","../src/swagger.ts","../src/services/agent_task_consumer.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport websocket from \"@fastify/websocket\";\nimport staticPlugin from \"@fastify/static\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { registerLatticeRoutes } from \"./routes\";\nimport { configureSwagger } from \"./swagger\";\nimport {\n setQueueServiceType,\n QueueServiceType,\n} from \"./services/queue_service\";\nimport { AgentTaskConsumer } from \"./services/agent_task_consumer\";\nimport {\n registerLoggerLattice,\n getLoggerLattice,\n loggerLatticeManager,\n sandboxLatticeManager,\n sqlDatabaseManager,\n getStoreLattice,\n agentInstanceManager,\n createSandboxProvider,\n type CreateSandboxProviderConfig,\n} from \"@axiom-lattice/core\";\nimport type { DatabaseConfigStore } from \"@axiom-lattice/protocols\";\nimport {\n LoggerType,\n LoggerConfig,\n PinoFileOptions,\n} from \"@axiom-lattice/protocols\";\n\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// Default logger configuration\nconst DEFAULT_LOGGER_CONFIG: LoggerConfig = {\n name: \"default\",\n description: \"Default logger for lattice-gateway service\",\n type: LoggerType.PINO,\n serviceName: \"lattice/gateway\",\n loggerName: \"lattice/gateway\",\n};\n\n// Initialize logger with default config (can be overridden in start function)\nlet loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);\nlet logger = loggerLattice.client;\n\n/**\n * Initialize logger lattice with given configuration\n */\nfunction initializeLogger(config: LoggerConfig) {\n // Remove existing logger if it exists\n if (loggerLatticeManager.hasLattice(\"default\")) {\n loggerLatticeManager.removeLattice(\"default\");\n }\n\n // Register logger with provided config\n registerLoggerLattice(\"default\", config);\n\n // Get and return logger lattice instance\n return getLoggerLattice(\"default\");\n}\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n bodyLimit: Number(process.env.BODY_LIMIT) || 50 * 1024 * 1024, // Default 50MB, configurable via BODY_LIMIT env var\n});\n\n// Custom content type parser to handle DELETE requests with Content-Type but no body\n// This prevents \"Body cannot be empty when content-type is set to 'application/json'\" error\napp.addContentTypeParser('application/json', { parseAs: 'string' }, function (request, body, done) {\n // For DELETE requests or empty body, return empty object\n if (request.method === 'DELETE' || !body || body.length === 0) {\n done(null, {});\n return;\n }\n try {\n const json = JSON.parse(body as string);\n done(null, json);\n } catch (err) {\n done(err as Error, undefined);\n }\n});\n\n\n// Add custom logging hooks\napp.addHook(\"onRequest\", (request, reply, done) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n // Update logger context for this request\n if (loggerLattice.updateContext) {\n loggerLattice.updateContext(context);\n }\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n //loggerLattice.info(`${request.method} ${request.url} - ${reply.statusCode}`);\n done();\n});\n\n// cors\napp.register(cors, {\n origin: true,\n methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\", \"PATCH\"],\n allowedHeaders: \"*\",\n exposedHeaders: [\"Content-Type\"],\n credentials: true,\n});\napp.register(sensible);\napp.register(multipart, {\n limits: {\n fileSize: Number(process.env.BODY_LIMIT) || 50 * 1024 * 1024,\n },\n});\napp.register(websocket);\n\n// Register static file serving for SDK\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\napp.register(staticPlugin, {\n root: path.join(__dirname, \"../public\"),\n prefix: \"/\",\n});\n\n// Error handler\napp.setErrorHandler((error, request, reply) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n logger.error(\n `请求错误: ${request.method} ${request.url} error:${error.message}`,\n {\n ...context,\n error: error.message,\n stack: error.stack,\n statusCode: error.statusCode || 500,\n }\n );\n reply.status(error.statusCode || 500).send({\n success: false,\n error: error.message || \"服务器内部错误\",\n });\n});\n\n// Logger lattice will be decorated in start() function\n\n/**\n * Logger configuration for gateway\n */\nexport interface GatewayLoggerConfig {\n name?: string;\n description?: string;\n type?: LoggerType;\n serviceName?: string;\n loggerName?: string;\n file?: string | PinoFileOptions;\n context?: Record<string, any>;\n}\n\n// Gateway configuration interface\nexport interface LatticeGatewayConfig {\n port?: number;\n queueServiceConfig?: {\n type: QueueServiceType;\n defaultStartPollingQueue: boolean;\n };\n loggerConfig?: Partial<GatewayLoggerConfig>; // Optional logger configuration to override defaults\n}\n\nfunction getConfiguredSandboxProvider(): ReturnType<typeof createSandboxProvider> {\n const sandboxProviderType =\n (process.env.SANDBOX_PROVIDER_TYPE as CreateSandboxProviderConfig[\"type\"] | undefined) ||\n \"microsandbox-remote\";\n\n return createSandboxProvider({\n type: sandboxProviderType,\n remoteBaseURL: process.env.SANDBOX_BASE_URL,\n microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,\n e2bApiKey: process.env.E2B_API_KEY,\n e2bTemplate: process.env.E2B_TEMPLATE,\n e2bTimeoutMs: process.env.E2B_TIMEOUT_MS\n ? parseInt(process.env.E2B_TIMEOUT_MS, 10)\n : undefined,\n daytonaApiKey: process.env.DAYTONA_API_KEY,\n daytonaApiUrl: process.env.DAYTONA_API_URL,\n daytonaTarget: process.env.DAYTONA_TARGET,\n daytonaTimeout: process.env.DAYTONA_TIMEOUT\n ? parseInt(process.env.DAYTONA_TIMEOUT, 10)\n : undefined,\n daytonaVolumeName: process.env.DAYTONA_VOLUME_NAME,\n });\n}\n\n// Start server\nconst start = async (config?: LatticeGatewayConfig) => {\n try {\n // Initialize or update logger configuration if provided\n if (config?.loggerConfig) {\n const loggerConfig: LoggerConfig = {\n ...DEFAULT_LOGGER_CONFIG,\n ...config.loggerConfig,\n // Merge file config if provided\n file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file,\n };\n loggerLattice = initializeLogger(loggerConfig);\n logger = loggerLattice.client;\n }\n\n // Decorate app with logger lattice (only once, in start function)\n // Access via: request.server.loggerLattice or app.loggerLattice\n app.decorate(\"loggerLattice\", loggerLattice);\n\n // Register all routes\n registerLatticeRoutes(app);\n\n // Set up database config store for on-demand loading\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n sqlDatabaseManager.setConfigStore(store);\n logger.info(\"Database config store set for SqlDatabaseManager\");\n } catch (error) {\n logger.warn(\"Failed to set database config store: \" + (error instanceof Error ? error.message : String(error)));\n }\n\n // Register sandbox manager if not already registered\n if (!sandboxLatticeManager.hasLattice(\"default\")) {\n sandboxLatticeManager.registerLattice(\"default\", getConfiguredSandboxProvider());\n logger.info(\"Registered sandbox manager from env configuration\");\n }\n\n const target_port = config?.port || Number(process.env.PORT) || 4001;\n\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${target_port}`);\n\n // Initialize AgentLifecycleManager\n try {\n logger.info(\"AgentLifecycleManager initialized\");\n } catch (error) {\n logger.warn(\"Failed to initialize AgentLifecycleManager\", { error });\n }\n\n // Configure queue service\n const queueServiceConfig = config?.queueServiceConfig;\n if (queueServiceConfig) {\n setQueueServiceType(queueServiceConfig.type);\n if (queueServiceConfig.defaultStartPollingQueue) {\n const agentTaskConsumer = new AgentTaskConsumer(target_port);\n agentTaskConsumer.startPollingQueue();\n }\n }\n\n // Restore agent instances with pending messages\n try {\n logger.info(\"Starting agent instance recovery...\");\n const restoreStats = await agentInstanceManager.restore();\n logger.info(`Agent recovery complete: ${restoreStats.restored} threads restored, ${restoreStats.errors} errors`);\n } catch (error) {\n logger.error(\"Agent recovery failed\", { error });\n // Don't exit - server can still function even if recovery fails\n }\n } catch (err) {\n logger.error(\"Server start failed\", { error: err });\n process.exit(1);\n }\n};\n\nconst LatticeGateway = {\n startAsHttpEndpoint: start,\n configureSwagger,\n registerLatticeRoutes,\n app,\n AgentTaskConsumer,\n};\n\nexport { LatticeGateway };\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager, getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\nimport type { AgentConfig } from \"@axiom-lattice/core\";\nimport { agentLatticeManager, eventBus } from \"@axiom-lattice/core\";\n\n/**\n * Assistant Controller\n * Handles assistant-related CRUD operations\n * Merges code-configured agents (from @axiom-lattice/core) with in-memory stored assistants\n * GET operations return both code-configured and stored assistants\n * CUD operations only work on stored assistants\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Convert AgentConfig to Assistant format\n */\nfunction convertAgentConfigToAssistant(config: AgentConfig): Assistant {\n return {\n id: config.key,\n tenantId: \"default\", // Code-configured agents belong to default tenant\n name: config.name,\n description: config.description,\n graphDefinition: config, // Store the full config as graphDefinition\n createdAt: new Date(0), // Code-configured agents have no creation date\n updatedAt: new Date(0), // Code-configured agents have no update date\n };\n}\n\n/**\n * Assistant list response interface\n */\ninterface AssistantListResponse {\n success: boolean;\n message: string;\n data: {\n records: Assistant[];\n total: number;\n };\n}\n\n/**\n * Assistant response interface\n */\ninterface AssistantResponse {\n success: boolean;\n message: string;\n data?: Assistant;\n}\n\n/**\n * Assistant update request body interface\n */\ninterface AssistantUpdateBody {\n name?: string;\n description?: string;\n graphDefinition?: any;\n}\n\n/**\n * Get list of all assistants\n * Merges code-configured agents with stored assistants\n */\nexport async function getAssistantList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<AssistantListResponse> {\n const tenantId = getTenantId(request);\n\n // Get code-configured agents for the tenant\n const agentConfigs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId);\n const codeConfiguredAssistants = agentConfigs.map(\n convertAgentConfigToAssistant\n );\n\n // Get stored assistants for the tenant\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const storedAssistants = await assistantStore.getAllAssistants(tenantId);\n\n // Merge both sources, stored assistants take precedence if ID conflicts\n const assistantMap = new Map<string, Assistant>();\n\n // First add code-configured agents\n codeConfiguredAssistants.forEach((assistant) => {\n assistantMap.set(assistant.id, assistant);\n });\n\n // Then add stored assistants (overwrite if ID exists)\n storedAssistants.forEach((assistant) => {\n assistantMap.set(assistant.id, assistant);\n });\n\n const allAssistants = Array.from(assistantMap.values());\n\n return {\n success: true,\n message: \"Successfully retrieved assistant list\",\n data: {\n records: allAssistants,\n total: allAssistants.length,\n },\n };\n}\n\n/**\n * Get a single assistant by ID\n * Checks both code-configured agents and stored assistants\n */\nexport async function getAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const { id } = request.params;\n const tenantId = getTenantId(request);\n\n // First check stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n let assistant = await assistantStore.getAssistantById(tenantId, id);\n\n // If not found in store, check code-configured agents for the tenant\n if (!assistant) {\n const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);\n if (agentConfig) {\n assistant = convertAgentConfigToAssistant(agentConfig);\n }\n }\n\n if (!assistant) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved assistant\",\n data: assistant,\n };\n}\n\n/**\n * Upsert assistant - create if not exists in store, update if exists\n */\nasync function upsertAssistant(\n tenantId: string,\n id: string,\n data: CreateAssistantRequest | AssistantUpdateBody,\n reply: FastifyReply,\n requireFields: boolean = false\n): Promise<AssistantResponse> {\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n const exists = await assistantStore.hasAssistant(tenantId, id);\n\n let assistant: Assistant | null;\n if (exists) {\n assistant = await assistantStore.updateAssistant(tenantId, id, data);\n if (!assistant) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update assistant\",\n });\n }\n eventBus.publish(\"assistant:updated\", { id: assistant.id, name: assistant.name, tenantId });\n return {\n success: true,\n message: \"Updated assistant\",\n data: assistant,\n };\n }\n\n if (requireFields) {\n const createData = data as CreateAssistantRequest;\n if (!createData.name || !createData.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"name and graphDefinition are required\",\n });\n }\n }\n\n assistant = await assistantStore.createAssistant(tenantId, id, data as CreateAssistantRequest);\n eventBus.publish(\"assistant:created\", { id: assistant.id, name: assistant.name, tenantId });\n return reply.status(201).send({\n success: true,\n message: \"Created assistant\",\n data: assistant,\n });\n}\n\n/**\n * Create a new assistant\n */\nexport async function createAssistant(\n request: FastifyRequest<{ Body: CreateAssistantRequest & { id?: string } }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const tenantId = getTenantId(request);\n const data = request.body;\n\n if (!data.name || !data.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"name and graphDefinition are required\",\n });\n }\n\n const id = data.id ?? randomUUID();\n return upsertAssistant(tenantId, id, data, reply, true);\n}\n\n/**\n * Update an existing assistant by ID\n */\nexport async function updateAssistant(\n request: FastifyRequest<{\n Params: { id: string };\n Body: AssistantUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const tenantId = getTenantId(request);\n const { id } = request.params;\n const updates = request.body;\n\n return upsertAssistant(tenantId, id, updates, reply, false);\n}\n\n/**\n * Delete an assistant by ID\n * For stored assistants: deletes from store\n * For code-configured assistants: only deletes from store if exists (code registration remains)\n */\nexport async function deleteAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { id } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);\n const isCodeConfigured = !!agentConfig;\n\n if (isCodeConfigured) {\n const exists = await assistantStore.hasAssistant(tenantId, id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found (code-configured assistants cannot be deleted from code, only from store)\",\n });\n }\n await assistantStore.deleteAssistant(tenantId, id);\n eventBus.publish(\"assistant:deleted\", { id, tenantId });\n return {\n success: true,\n message: \"Deleted assistant from store (code-configured registration remains)\",\n };\n }\n\n const exists = await assistantStore.hasAssistant(tenantId, id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n const deleted = await assistantStore.deleteAssistant(tenantId, id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete assistant\",\n });\n }\n\n eventBus.publish(\"assistant:deleted\", { id, tenantId });\n\n return {\n success: true,\n message: \"Successfully deleted assistant\",\n };\n}\n\n/**\n * Get agent graph visualization\n */\nexport const getAgentGraph = async (\n request: FastifyRequest<{\n Params: { assistantId: string };\n }>,\n reply: FastifyReply\n) => {\n try {\n const { assistantId } = request.params;\n const tenant_id = getTenantId(request);\n\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: '' })\n\n // Call drawing service to get image data\n const imageData = await agent.get_draw_graph()\n\n // Set response header and return image data\n reply.header(\"Content-Type\", \"application/json\").send({\n image: imageData,\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get agent graph\",\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { CreateRunRequest } from \"../types\";\nimport { v4 } from \"uuid\";\nimport {\n Agent,\n ThreadStatus,\n agentLatticeManager,\n agentInstanceManager,\n QueueMode,\n} from \"@axiom-lattice/core\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\n\ninterface ResumeStreamRequest {\n thread_id: string;\n assistant_id: string\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}\n\n// Create run\nexport const createRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const {\n assistant_id,\n thread_id,\n message_id,\n command,\n streaming,\n background,\n custom_run_config,\n mode,\n ...input\n } = request.body as CreateRunRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n const x_request_id = (request.headers[\"x-request-id\"] as string) || v4();\n\n // Validate request\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n // Get or create Agent instance (ensures single instance per thread)\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n custom_run_config,\n });\n\n\n // Handle streaming requests\n if (streaming) {\n // Setup SSE\n reply.hijack();\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n\n // Execute agent with streaming\n // Only pass id if message_id is provided (for backward compatibility)\n const messageInput = message_id \n ? { ...input, id: message_id }\n : input;\n \n const result = await agent.addMessage({\n input: messageInput,\n command,\n custom_run_config,\n }, mode as QueueMode);\n\n // const agentStatus = await agent.getRunStatus()\n // console.log(agentStatus)\n // if (agentStatus === \"busy\") {\n // reply.status(200).send({\n // success: true,\n\n // });\n // return\n // }\n\n const stream = agent.chunkStream((result).messageId, [MessageChunkTypes.MESSAGE_COMPLETED])\n\n // Forward all chunks to SSE\n for await (const chunk of stream) {\n const success = reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n if (!success) {\n await new Promise(resolve => reply.raw.once('drain', resolve));\n }\n }\n } catch (error: any) {\n // Send error as SSE event\n const errorEvent = {\n type: 'error',\n data: {\n id: v4(),\n content: error.message || 'Stream processing error',\n },\n };\n reply.raw.write(`data: ${JSON.stringify(errorEvent)}\\n\\n`);\n } finally {\n reply.raw.end();\n }\n } else {\n // Non-streaming: use agentExecutor\n const { message: msg, ...restInputNonStream } = input;\n const result = await agent.invoke({\n input: { message: msg, ...restInputNonStream },\n command,\n custom_run_config,\n });\n reply.status(200).send({\n success: true,\n ...result,\n });\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `创建运行时发生错误: ${error.message}`,\n });\n }\n};\n\n// Resume stream from known position\nexport const resumeStream = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n\n\n\n\n const { thread_id, message_id, assistant_id, known_content, poll_interval } =\n request.body as ResumeStreamRequest;\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n\n // Validate request data\n if (!thread_id || !message_id || !assistant_id || known_content === undefined) {\n reply.status(400).send({\n success: false,\n error: \"thread_id, message_id, assistant_id, and known_content are required\",\n });\n return;\n }\n\n // Notify Fastify that we will manually handle the response\n reply.hijack();\n\n // Set SSE response headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n // Create Agent instance for accessing chunk buffer\n // Get or create Agent instance (ensures single instance per thread)\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n // Get the stream from agent's chunk buffer\n const stream = agent.chunkStream(message_id, [MessageChunkTypes.THREAD_IDLE]);\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\n // console.log(chunk);\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error: any) {\n // Send error as SSE event before closing (following MessageChunk format)\n const errorEvent = {\n type: 'error',\n data: {\n id: v4(),\n content: error.message || 'Resume stream processing error'\n }\n };\n reply.raw.write(`data: ${JSON.stringify(errorEvent)}\\n\\n`);\n } finally {\n reply.raw.end();\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Error resuming stream: ${error.message}`,\n });\n }\n};\n\n// Abort agent execution for a thread\nexport const abortRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, threadId } = request.params as {\n assistantId: string;\n threadId: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = (request.headers[\"x-workspace-id\"] as string) || \"default\";\n const project_id = (request.headers[\"x-project-id\"] as string) || \"default\";\n\n const agent = agentInstanceManager.getAgent({\n assistant_id: assistantId,\n thread_id: threadId,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n await agent.abort();\n\n reply.status(200).send({\n success: true,\n message: \"Agent aborted\",\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Abort failed: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager } from \"@axiom-lattice/core\";\n\n// 设置内存项\nexport const setMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n const value = request.body;\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n if (value === undefined) {\n reply.status(400).send({\n success: false,\n error: \"值是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.setMemoryItem(assistantId, key, value);\n\n // if (!result.success) {\n reply.status(500).send();\n return;\n // }\n\n //reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `设置内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取内存项\nexport const getMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.getMemoryItem(assistantId, key);\n\n // if (!result.success) {\n reply.status(404).send();\n return;\n // }\n\n //reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取所有内存项\nexport const getAllMemoryItems = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, thread_id } = request.params as {\n assistantId: string;\n thread_id: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"线程ID是必需的\",\n });\n return;\n }\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: thread_id })\n\n const result = await agent.getCurrentMessages();\n\n if (!result) {\n reply.status(500).send(result);\n return;\n }\n\n reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取所有内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取助手状态\nexport const getAgentState = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, thread_id } = request.params as {\n assistantId: string;\n thread_id: string;\n };\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"线程ID是必需的\",\n });\n return;\n }\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: thread_id })\n\n // 1. 获取 LangGraph 状态(现有逻辑)\n const result = await agent.getCurrentState();\n const pendingMessages = await agent.getPendingMessages();\n\n\n if (!result) {\n reply.status(500).send(result);\n return;\n }\n\n // 3. 合并返回\n // Normalize pendingMessages content to string for consistent frontend format\n const normalizedPendingMessages = pendingMessages.map(msg => ({\n ...msg,\n content: typeof msg.content === 'object' && msg.content !== null\n ? ('message' in msg.content ? msg.content.message : JSON.stringify(msg.content))\n : String(msg.content || '')\n }));\n\n const mergedResult = {\n ...result,\n pendingMessages: normalizedPendingMessages\n };\n\n reply.send(mergedResult);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取助手状态时发生错误: ${error.message}`,\n });\n }\n};\n\n// 删除内存项\nexport const deleteMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.deleteMemoryItem(assistantId, key);\n\n // if (!result.success) {\n reply.status(500).send();\n return;\n // }\n\n reply.status(204).send();\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `删除内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 清除内存\nexport const clearMemory = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId } = request.params as { assistantId: string };\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n let result: any; //= await memoryModel.clearMemory(assistantId);\n\n if (!result.success) {\n reply.status(500).send(result);\n return;\n }\n\n reply.status(204).send();\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `清除内存时发生错误: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { AgentManager } from \"@axiom-lattice/core\";\n\n/**\n * Request body interface for triggering agent task\n */\ninterface TriggerAgentTaskRequest {\n assistant_id: string;\n thread_id: string;\n input: any;\n command?: any;\n}\n\n/**\n * Trigger an agent task\n * This endpoint triggers an agent task through the AgentManager,\n * which publishes the task to the event bus for processing\n */\nexport const triggerAgentTask = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistant_id, thread_id, input, command } =\n request.body as TriggerAgentTaskRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n\n // Validate required fields\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"assistant_id is required\",\n });\n return;\n }\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"thread_id is required\",\n });\n return;\n }\n\n // Get AgentManager instance and trigger the task\n const agentManager = AgentManager.getInstance();\n const result = await agentManager.callAgentInQueue({\n assistant_id,\n thread_id,\n input,\n command,\n \"x-tenant-id\": tenant_id,\n });\n\n reply.status(200).send({\n success: true,\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Failed to trigger agent task: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { Thread, CreateThreadRequest } from \"../types\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Thread Controller\n * Handles thread-related CRUD operations for a specific assistant\n * All operations are scoped to a tenant ID and assistant ID\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Thread list response interface\n */\ninterface ThreadListResponse {\n success: boolean;\n message: string;\n data: {\n records: Thread[];\n total: number;\n };\n}\n\n/**\n * Thread response interface\n */\ninterface ThreadResponse {\n success: boolean;\n message: string;\n data?: Thread;\n}\n\n/**\n * Thread update request body interface\n */\ninterface ThreadUpdateBody {\n metadata?: Record<string, any>;\n}\n\n/**\n * Get list of all threads for a specific assistant\n */\nexport async function getThreadList(\n request: FastifyRequest<{\n Params: { assistantId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadListResponse> {\n const tenantId = getTenantId(request);\n const { assistantId } = request.params;\n\n // Build metadata filter from headers (workspace/project isolation)\n const metadataFilter: Record<string, string> = {};\n const workspaceId = request.headers[\"x-workspace-id\"] as string | undefined;\n const projectId = request.headers[\"x-project-id\"] as string | undefined;\n \n if (workspaceId) {\n metadataFilter.workspaceId = workspaceId;\n }\n if (projectId) {\n metadataFilter.projectId = projectId;\n }\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const threads = await threadStore.getThreadsByAssistantId(\n tenantId,\n assistantId,\n Object.keys(metadataFilter).length > 0 ? metadataFilter : undefined\n );\n\n return {\n success: true,\n message: \"Successfully retrieved thread list\",\n data: {\n records: threads,\n total: threads.length,\n },\n };\n}\n\n/**\n * Get a single thread by ID for a specific tenant\n */\nexport async function getThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const thread = await threadStore.getThreadById(tenantId, threadId);\n\n if (!thread) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved thread\",\n data: thread,\n };\n}\n\n/**\n * Create a new thread for an assistant\n */\nexport async function createThread(\n request: FastifyRequest<{\n Params: { assistantId: string };\n Body: CreateThreadRequest;\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { assistantId } = request.params;\n const data = request.body;\n\n // Generate thread ID if not provided\n const threadId = randomUUID();\n\n // Extract workspace and project from headers\n const workspaceId = request.headers[\"x-workspace-id\"] as string | undefined;\n const projectId = request.headers[\"x-project-id\"] as string | undefined;\n\n // Enrich metadata with tenant/workspace/project\n const enrichedMetadata: Record<string, any> = {\n ...data.metadata,\n tenantId,\n };\n\n if (workspaceId) {\n enrichedMetadata.workspaceId = workspaceId;\n }\n if (projectId) {\n enrichedMetadata.projectId = projectId;\n }\n\n // Create thread with enriched metadata\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const newThread = await threadStore.createThread(tenantId, assistantId, threadId, {\n metadata: enrichedMetadata,\n });\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created thread\",\n data: newThread,\n });\n}\n\n/**\n * Update an existing thread by ID\n */\nexport async function updateThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n Body: ThreadUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n const updates = request.body;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n\n // Check if thread exists\n const exists = await threadStore.hasThread(tenantId, threadId);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n // Update thread\n const updatedThread = await threadStore.updateThread(\n tenantId,\n threadId,\n updates\n );\n\n if (!updatedThread) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update thread\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated thread\",\n data: updatedThread,\n };\n}\n\n/**\n * Delete a thread by ID\n */\nexport async function deleteThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n\n // Check if thread exists\n const exists = await threadStore.hasThread(tenantId, threadId);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n // Delete the thread\n const deleted = await threadStore.deleteThread(tenantId, threadId);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete thread\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully deleted thread\",\n };\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { scheduleLatticeManager } from \"@axiom-lattice/core\";\nimport {\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Schedule Controller\n * Handles schedule-related operations for viewing and managing scheduled tasks\n * All operations are scoped to a tenant ID\n */\n\n/**\n * Get tenant ID from request headers or user context\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Scheduled tasks list response interface\n */\ninterface ScheduledTasksListResponse {\n success: boolean;\n message: string;\n data: {\n records: ScheduledTaskDefinition[];\n total: number;\n };\n}\n\n/**\n * Scheduled task response interface\n */\ninterface ScheduledTaskResponse {\n success: boolean;\n message: string;\n data?: ScheduledTaskDefinition | null;\n}\n\n/**\n * Helper function to get the schedule lattice safely\n * Returns null if no schedule lattice is registered\n */\nfunction getScheduleLattice() {\n // Try to get the first available schedule lattice\n const keys = scheduleLatticeManager.getLatticeKeys();\n if (keys.length === 0) {\n return null;\n }\n // Use \"default\" if available, otherwise use the first one\n if (scheduleLatticeManager.hasLattice(\"default\")) {\n return scheduleLatticeManager.getScheduleLattice(\"default\");\n }\n return scheduleLatticeManager.getScheduleLattice(keys[0]);\n}\n\n/**\n * Get scheduled tasks for a specific thread\n */\nexport async function getThreadSchedules(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n Querystring: {\n status?: ScheduledTaskStatus;\n limit?: string;\n offset?: string;\n };\n }>,\n reply: FastifyReply\n): Promise<ScheduledTasksListResponse> {\n const { assistantId, threadId } = request.params;\n const { status, limit, offset } = request.query;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n // If no schedule lattice is registered, return empty result\n if (!scheduleLattice) {\n return {\n success: true,\n message: \"No schedule lattice configured\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n\n const storage = scheduleLattice.client.getStorage();\n\n if (!storage) {\n return {\n success: true,\n message: \"No schedule storage configured\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n\n const tenantId = getTenantId(request);\n\n const filters: {\n tenantId: string;\n threadId: string;\n assistantId?: string;\n status?: ScheduledTaskStatus;\n limit?: number;\n offset?: number;\n } = {\n tenantId,\n threadId,\n assistantId,\n };\n\n if (status) {\n filters.status = status;\n }\n if (limit) {\n filters.limit = parseInt(limit, 10);\n }\n if (offset) {\n filters.offset = parseInt(offset, 10);\n }\n\n const tasks = await storage.getAllTasks(filters);\n const total = await storage.countTasks({\n tenantId,\n threadId,\n assistantId,\n status,\n });\n\n return {\n success: true,\n message: \"Successfully retrieved scheduled tasks\",\n data: {\n records: tasks,\n total,\n },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get thread schedules\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to retrieve scheduled tasks\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single scheduled task by ID\n */\nexport async function getScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<ScheduledTaskResponse> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const task = await scheduleLattice.client.getTask(taskId);\n\n if (!task) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved scheduled task\",\n data: task,\n };\n } catch (error) {\n request.log.error(error, \"Failed to get scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to retrieve scheduled task\",\n });\n }\n}\n\n/**\n * Cancel a scheduled task\n */\nexport async function cancelScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.cancel(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or already cancelled\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully cancelled scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to cancel scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to cancel scheduled task\",\n });\n }\n}\n\n/**\n * Pause a scheduled cron task\n */\nexport async function pauseScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.pause(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or cannot be paused\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully paused scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to pause scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to pause scheduled task\",\n });\n }\n}\n\n/**\n * Resume a paused cron task\n */\nexport async function resumeScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.resume(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or cannot be resumed\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully resumed scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to resume scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to resume scheduled task\",\n });\n }\n}\n","/**\n * Configuration service\n * Manages environment variables and supports dynamic updates\n */\n\nexport interface GatewayConfig {\n port?: number;\n queueServiceType?: string;\n redisUrl?: string;\n redisPassword?: string;\n queueName?: string;\n [key: string]: any; // Allow additional config keys\n}\n\n/**\n * Get configuration from environment variables\n * Supports dynamic updates via updateConfig method\n */\nclass ConfigService {\n private config: GatewayConfig;\n\n constructor() {\n this.config = this.loadFromEnv();\n }\n\n /**\n * Load configuration from environment variables\n */\n private loadFromEnv(): GatewayConfig {\n return {\n port: process.env.PORT ? Number(process.env.PORT) : undefined,\n queueServiceType: process.env.QUEUE_SERVICE_TYPE,\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n queueName: process.env.QUEUE_NAME,\n };\n }\n\n /**\n * Update configuration from JSON object\n * This will update both the internal config and process.env\n */\n updateConfig(jsonConfig: Record<string, any>): void {\n // Update process.env for all provided keys\n for (const [key, value] of Object.entries(jsonConfig)) {\n if (value !== null && value !== undefined) {\n // Convert nested objects to environment variable format\n if (typeof value === \"object\" && !Array.isArray(value)) {\n // Handle nested objects like supabase: { url: \"...\", key: \"...\" }\n for (const [nestedKey, nestedValue] of Object.entries(value)) {\n const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;\n process.env[envKey] = String(nestedValue);\n }\n } else {\n // Handle flat keys\n process.env[key.toUpperCase()] = String(value);\n }\n }\n }\n\n // Reload config from updated environment variables\n this.config = this.loadFromEnv();\n\n // Deep merge the JSON config into our config object\n this.config = this.deepMerge(this.config, jsonConfig);\n }\n\n /**\n * Deep merge two objects\n */\n private deepMerge(target: any, source: any): any {\n const output = { ...target };\n if (this.isObject(target) && this.isObject(source)) {\n Object.keys(source).forEach((key) => {\n if (this.isObject(source[key])) {\n if (!(key in target)) {\n Object.assign(output, { [key]: source[key] });\n } else {\n output[key] = this.deepMerge(target[key], source[key]);\n }\n } else {\n Object.assign(output, { [key]: source[key] });\n }\n });\n }\n return output;\n }\n\n /**\n * Check if value is a plain object\n */\n private isObject(item: any): boolean {\n return item && typeof item === \"object\" && !Array.isArray(item);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): GatewayConfig {\n return { ...this.config };\n }\n}\n\n// Export singleton instance\nexport const configService = new ConfigService();\n\n// Export config getter for backward compatibility\nexport const config = {\n get port() {\n return configService.getConfig().port;\n },\n get queueServiceType() {\n return configService.getConfig().queueServiceType;\n },\n get redisUrl() {\n return configService.getConfig().redisUrl;\n },\n get redisPassword() {\n return configService.getConfig().redisPassword;\n },\n get queueName() {\n return configService.getConfig().queueName;\n },\n};\n","// Queue service adapter that uses QueueLatticeManager from core package\n// Provides backward-compatible API for gateway services\n\nimport {\n queueLatticeManager,\n registerQueueLattice,\n getQueueLattice,\n} from \"@axiom-lattice/core\";\nimport { QueueType } from \"@axiom-lattice/protocols\";\nimport type { QueueConfig, QueueClient } from \"@axiom-lattice/protocols\";\nimport { RedisQueueClient } from \"@axiom-lattice/queue-redis\";\n\nexport type QueueServiceType = \"memory\" | \"redis\";\n\n// Default queue key\nconst DEFAULT_QUEUE_KEY = \"default\";\n\n// Global configuration for queue service type\n// Can be set via environment variable QUEUE_SERVICE_TYPE or via LatticeGateway configuration\nlet queueServiceType: QueueServiceType =\n (process.env.QUEUE_SERVICE_TYPE as QueueServiceType) || \"memory\";\n\n/**\n * Configure the queue service type\n * This will register or update the default queue service\n * @param type - \"memory\" or \"redis\"\n */\nexport const setQueueServiceType = (type: QueueServiceType): void => {\n queueServiceType = type;\n console.log(`Queue service type set to: ${type}`);\n\n // Register or update the queue service\n const queueName = process.env.QUEUE_NAME || \"tasks\";\n const config: QueueConfig = {\n name: \"Default Queue Service\",\n description: `Default ${type} queue service`,\n type: type === \"redis\" ? QueueType.REDIS : QueueType.MEMORY,\n queueName,\n options:\n type === \"redis\"\n ? {\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n }\n : undefined,\n };\n\n // Remove existing queue if it exists\n if (queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {\n queueLatticeManager.removeLattice(DEFAULT_QUEUE_KEY);\n }\n\n // Create client for Redis type\n let client: QueueClient | undefined;\n if (type === \"redis\") {\n client = new RedisQueueClient(queueName, {\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n });\n }\n\n // Register the new queue service\n registerQueueLattice(DEFAULT_QUEUE_KEY, config, client);\n};\n\n/**\n * Get the current queue service type\n */\nexport const getQueueServiceType = (): QueueServiceType => {\n return queueServiceType;\n};\n\n/**\n * Get the default queue service\n * If not registered, register it with the current configuration\n */\nconst getQueueService = () => {\n // Check if queue is already registered\n if (!queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {\n // Auto-register with current configuration\n setQueueServiceType(queueServiceType);\n }\n\n return getQueueLattice(DEFAULT_QUEUE_KEY);\n};\n\n/**\n * Push agent task to queue\n * @param agentTask - Agent task to push\n */\nexport const pushAgentTaskToQueue = async (agentTask: any) => {\n const queue = getQueueService();\n const result = await queue.push(agentTask);\n return result;\n};\n\n/**\n * Pop agent task from queue\n */\nexport const popAgentTaskFromQueue = async () => {\n const queue = getQueueService();\n const result = await queue.pop();\n return result;\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { configService } from \"../config\";\nimport {\n setQueueServiceType,\n QueueServiceType,\n} from \"../services/queue_service\";\n\n/**\n * Configuration Controller\n * Handles configuration updates from frontend\n */\n\ninterface UpdateConfigRequest {\n Body: {\n config: Record<string, any>;\n };\n}\n\n/**\n * Update gateway configuration\n * Accepts JSON config and loads it into environment variables\n */\nexport async function updateConfig(\n request: FastifyRequest<UpdateConfigRequest>,\n reply: FastifyReply\n) {\n try {\n const { config: jsonConfig } = request.body;\n\n if (!jsonConfig || typeof jsonConfig !== \"object\") {\n return reply.status(400).send({\n success: false,\n error: \"Invalid configuration: config must be an object\",\n });\n }\n\n // Update configuration service\n configService.updateConfig(jsonConfig);\n\n const warnings: string[] = [];\n const requiresRestart: string[] = [];\n\n // Check if port is being changed (requires restart)\n if (jsonConfig.port !== undefined) {\n requiresRestart.push(\"PORT\");\n warnings.push(\"Port change requires server restart to take effect\");\n }\n\n // If queue service type is being updated, reconfigure the queue service\n if (jsonConfig.queueServiceType) {\n setQueueServiceType(jsonConfig.queueServiceType as QueueServiceType);\n }\n\n // If Redis configuration is being updated and queue service is Redis, reconfigure\n if (\n (jsonConfig.redisUrl || jsonConfig.redisPassword) &&\n (process.env.QUEUE_SERVICE_TYPE === \"redis\" ||\n jsonConfig.queueServiceType === \"redis\")\n ) {\n // Reconfigure queue service to pick up new Redis settings\n const currentType =\n (jsonConfig.queueServiceType as QueueServiceType) ||\n (process.env.QUEUE_SERVICE_TYPE as QueueServiceType) ||\n \"memory\";\n if (currentType === \"redis\") {\n setQueueServiceType(\"redis\");\n }\n }\n\n // Get updated config (without sensitive data)\n const updatedConfig = configService.getConfig();\n const safeConfig = {\n ...updatedConfig,\n redisPassword: updatedConfig.redisPassword\n ? \"***\"\n : updatedConfig.redisPassword,\n };\n\n return reply.send({\n success: true,\n message: \"Configuration updated successfully\",\n data: safeConfig,\n warnings: warnings.length > 0 ? warnings : undefined,\n requiresRestart: requiresRestart.length > 0 ? requiresRestart : undefined,\n });\n } catch (error: any) {\n console.error(\"Failed to update configuration\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to update configuration\",\n });\n }\n}\n\n/**\n * Get current gateway configuration\n * Returns current configuration (with sensitive data masked)\n */\nexport async function getConfig(request: FastifyRequest, reply: FastifyReply) {\n try {\n const currentConfig = configService.getConfig();\n const safeConfig = {\n ...currentConfig,\n redisPassword: currentConfig.redisPassword\n ? \"***\"\n : currentConfig.redisPassword,\n };\n\n return reply.send({\n success: true,\n data: safeConfig,\n });\n } catch (error: any) {\n console.error(\"Failed to get configuration\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get configuration\",\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { registerModelLattice, modelLatticeManager } from \"@axiom-lattice/core\";\nimport type { LLMConfig } from \"@axiom-lattice/protocols\";\n\n/**\n * Models Controller\n * Handles model lattice registration and management\n * Models are tenant-isolated using key prefix: {tenantId}:{modelKey}\n */\n\n/**\n * Get tenant ID from request headers or user context\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Get tenant-scoped model key\n */\nfunction getTenantModelKey(tenantId: string, modelKey: string): string {\n return `${tenantId}:${modelKey}`;\n}\n\n/**\n * Extract model key from tenant-scoped key\n */\nfunction extractModelKey(tenantId: string, tenantModelKey: string): string {\n const prefix = `${tenantId}:`;\n if (tenantModelKey.startsWith(prefix)) {\n return tenantModelKey.substring(prefix.length);\n }\n return tenantModelKey;\n}\n\ninterface ModelConfig {\n key: string;\n model: string;\n displayName?: string;\n provider: \"azure\" | \"openai\" | \"deepseek\" | \"siliconcloud\" | \"volcengine\";\n streaming?: boolean;\n apiKey?: string;\n baseURL?: string;\n maxTokens?: number;\n temperature?: number;\n timeout?: number;\n maxRetries?: number;\n}\n\ninterface UpdateModelsRequest {\n Body: {\n models: ModelConfig[];\n };\n}\n\ninterface UpdateModelsRequest {\n Body: {\n models: ModelConfig[];\n };\n}\n\n/**\n * Get all registered models\n */\nexport async function getModels(request: FastifyRequest, reply: FastifyReply) {\n try {\n const allLattices = modelLatticeManager.getAllLattices();\n const models = allLattices.map((lattice) => {\n // Extract config from the lattice client\n // Note: This is a simplified approach - you may need to adjust based on actual implementation\n const config = (lattice.client as any).config || {};\n // Use provided displayName or auto-generate from key\n const displayName = config.displayName || lattice.key\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n return {\n key: lattice.key,\n model: config.model || \"\",\n provider: config.provider || \"openai\",\n displayName: displayName,\n streaming: config.streaming || false,\n apiKey: config.apiKey || \"\",\n baseURL: config.baseURL || \"\",\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n timeout: config.timeout,\n maxRetries: config.maxRetries,\n };\n });\n\n return reply.send({\n success: true,\n data: models,\n });\n } catch (error: any) {\n console.error(\"Failed to get models\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get models\",\n });\n }\n}\n\n/**\n * Update models configuration\n * Registers or updates model lattices\n */\nexport async function updateModels(\n request: FastifyRequest<UpdateModelsRequest>,\n reply: FastifyReply\n) {\n try {\n const { models } = request.body;\n\n if (!models || !Array.isArray(models)) {\n return reply.status(400).send({\n success: false,\n error: \"Invalid request: models must be an array\",\n });\n }\n\n const registeredModels: string[] = [];\n const errors: string[] = [];\n\n for (const modelConfig of models) {\n if (!modelConfig.key || !modelConfig.model || !modelConfig.provider) {\n errors.push(\n `Model configuration is incomplete: key, model, and provider are required`\n );\n continue;\n }\n\n try {\n // Remove existing model with the same key if it exists\n if (modelLatticeManager.hasLattice(modelConfig.key)) {\n modelLatticeManager.removeLattice(modelConfig.key);\n }\n\n // Convert to LLMConfig format\n const llmConfig: LLMConfig = {\n provider: modelConfig.provider,\n model: modelConfig.model,\n displayName: modelConfig.displayName,\n streaming: modelConfig.streaming ?? false,\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n maxTokens: modelConfig.maxTokens,\n temperature: modelConfig.temperature,\n timeout: modelConfig.timeout,\n maxRetries: modelConfig.maxRetries,\n };\n\n // Register the new model lattice\n registerModelLattice(modelConfig.key, llmConfig);\n registeredModels.push(modelConfig.key);\n } catch (error: any) {\n errors.push(\n `Failed to register model ${modelConfig.key}: ${error.message}`\n );\n }\n }\n\n if (errors.length > 0 && registeredModels.length === 0) {\n return reply.status(400).send({\n success: false,\n error: errors.join(\"; \"),\n });\n }\n\n return reply.send({\n success: true,\n message: `Successfully registered ${registeredModels.length} model(s)`,\n data: {\n registered: registeredModels,\n errors: errors.length > 0 ? errors : undefined,\n },\n });\n } catch (error: any) {\n console.error(\"Failed to update models\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to update models\",\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\n\n/**\n * Health Controller\n * Handles health check endpoints for monitoring and load balancer checks\n */\n\n/**\n * Health check endpoint\n * Returns service status and basic information\n */\nexport async function getHealth(\n request: FastifyRequest,\n reply: FastifyReply\n) {\n try {\n const healthStatus = {\n status: \"healthy\",\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n service: \"lattice-gateway\",\n version: process.env.npm_package_version || \"1.0.0\",\n };\n\n return reply.send({\n success: true,\n data: healthStatus,\n });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n status: \"unhealthy\",\n error: error.message || \"Health check failed\",\n });\n }\n}\n","/**\n * SkillService\n *\n * Business logic layer for skill management.\n * Wraps SandboxSkillStore from @axiom-lattice/core.\n * Controllers should consume this service, not directly manipulate storage.\n */\n\nimport { SandboxSkillStore } from \"@axiom-lattice/core\";\nimport type {\n Skill,\n SkillStoreContext,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\nimport { FastifyRequest } from \"fastify\";\n\nfunction getTenantId(request: FastifyRequest): string {\n return (request as any).user?.tenantId || (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\nfunction getWorkspaceId(request: FastifyRequest): string | undefined {\n return request.headers[\"x-workspace-id\"] as string | undefined;\n}\n\nfunction getProjectId(request: FastifyRequest): string | undefined {\n return request.headers[\"x-project-id\"] as string | undefined;\n}\n\nfunction buildContext(request: FastifyRequest): SkillStoreContext {\n return {\n workspaceId: getWorkspaceId(request),\n projectId: getProjectId(request),\n };\n}\n\nexport class SkillService {\n private store: SandboxSkillStore;\n\n constructor() {\n this.store = new SandboxSkillStore();\n }\n\n async getAllSkills(request: FastifyRequest): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.getAllSkills(tenantId, buildContext(request));\n }\n\n async getSkillById(request: FastifyRequest, id: string): Promise<Skill | null> {\n const tenantId = getTenantId(request);\n return this.store.getSkillById(tenantId, id, buildContext(request));\n }\n\n async createSkill(\n request: FastifyRequest,\n id: string,\n data: CreateSkillRequest\n ): Promise<Skill> {\n const tenantId = getTenantId(request);\n return this.store.createSkill(tenantId, id, data, buildContext(request));\n }\n\n async updateSkill(\n request: FastifyRequest,\n id: string,\n updates: Partial<CreateSkillRequest>\n ): Promise<Skill | null> {\n const tenantId = getTenantId(request);\n return this.store.updateSkill(tenantId, id, updates, buildContext(request));\n }\n\n async deleteSkill(request: FastifyRequest, id: string): Promise<boolean> {\n const tenantId = getTenantId(request);\n return this.store.deleteSkill(tenantId, id, buildContext(request));\n }\n\n async searchByMetadata(\n request: FastifyRequest,\n key: string,\n value: string\n ): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.searchByMetadata(tenantId, key, value, buildContext(request));\n }\n\n async filterByCompatibility(\n request: FastifyRequest,\n compatibility: string\n ): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.filterByCompatibility(tenantId, compatibility, buildContext(request));\n }\n\n async filterByLicense(request: FastifyRequest, license: string): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.filterByLicense(tenantId, license, buildContext(request));\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { SkillService } from \"../services/skill_service\";\nimport type { Skill, CreateSkillRequest } from \"@axiom-lattice/protocols\";\n\nconst skillService = new SkillService();\n\nfunction serializeSkill(skill: Skill): any {\n const serialized: any = {\n id: skill.id,\n name: skill.name,\n description: skill.description,\n license: skill.license,\n compatibility: skill.compatibility,\n metadata: skill.metadata || {},\n content: skill.content,\n subSkills: skill.subSkills,\n createdAt: skill.createdAt instanceof Date ? skill.createdAt.toISOString() : new Date().toISOString(),\n updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : new Date().toISOString(),\n };\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) delete serialized[key];\n });\n return serialized;\n}\n\ninterface SkillListResponse {\n success: boolean;\n message: string;\n data: { records: any[]; total: number };\n}\n\ninterface SkillResponse {\n success: boolean;\n message: string;\n data?: any;\n}\n\ninterface SkillUpdateBody {\n name?: string;\n description?: string;\n license?: string;\n compatibility?: string;\n metadata?: Record<string, string>;\n content?: string;\n subSkills?: string[];\n}\n\nexport async function getSkillList(request: FastifyRequest, reply: FastifyReply): Promise<SkillListResponse> {\n try {\n const skills = await skillService.getAllSkills(request);\n return {\n success: true,\n message: \"Successfully retrieved skill list\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function getSkill(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const skill = await skillService.getSkillById(request, id);\n\n if (!skill) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully retrieved skill\", data: serializeSkill(skill) };\n } catch (error: any) {\n return reply.status(500).send({ success: false, message: `Failed to retrieve skill: ${error.message}` });\n }\n}\n\nexport async function createSkill(\n request: FastifyRequest<{ Body: CreateSkillRequest }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const data = request.body;\n if (!data.name) {\n return reply.status(400).send({ success: false, message: \"name is required\" });\n }\n if (!data.description) {\n return reply.status(400).send({ success: false, message: \"description is required\" });\n }\n\n const id = (request.body as any).id || data.name;\n if (id !== data.name) {\n return reply.status(400).send({\n success: false,\n message: `id \"${id}\" must equal name \"${data.name}\"`,\n });\n }\n\n const skill = await skillService.createSkill(request, id, data);\n return reply.status(201).send({\n success: true,\n message: \"Successfully created skill\",\n data: serializeSkill(skill),\n });\n } catch (error: any) {\n if (error.message?.includes(\"already exists\")) {\n return reply.status(409).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"must equal name\") || error.message?.includes(\"Invalid skill name\")) {\n return reply.status(400).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to create skill: ${error.message}` });\n }\n}\n\nexport async function updateSkill(\n request: FastifyRequest<{ Params: { id: string }; Body: SkillUpdateBody }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const updates = request.body;\n\n const skill = await skillService.updateSkill(request, id, updates);\n\n if (!skill) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully updated skill\", data: serializeSkill(skill) };\n } catch (error: any) {\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"Invalid skill name\")) {\n return reply.status(400).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to update skill: ${error.message}` });\n }\n}\n\nexport async function deleteSkill(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n try {\n const { id } = request.params;\n const result = await skillService.deleteSkill(request, id);\n\n if (!result) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully deleted skill\" };\n } catch (error: any) {\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to delete skill: ${error.message}` });\n }\n}\n\nexport async function searchSkillsByMetadata(\n request: FastifyRequest<{ Querystring: { key: string; value: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { key, value } = request.query;\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.searchByMetadata(request, key, value);\n return {\n success: true,\n message: \"Successfully searched skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function filterSkillsByCompatibility(\n request: FastifyRequest<{ Querystring: { compatibility: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { compatibility } = request.query;\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.filterByCompatibility(request, compatibility);\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function filterSkillsByLicense(\n request: FastifyRequest<{ Querystring: { license: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { license } = request.query;\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.filterByLicense(request, license);\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { toolLatticeManager } from \"@axiom-lattice/core\";\nimport type {\n ToolConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Tools Controller\n * Handles tool-related operations\n */\n\n/**\n * Tool config meta response interface\n */\ninterface ToolConfigMetaResponse {\n success: boolean;\n message: string;\n data: {\n records: Array<{\n id: string;\n name: string;\n description: string;\n schema?: any; // Serialized schema\n returnDirect?: boolean;\n needUserApprove?: boolean;\n }>;\n total: number;\n };\n}\n\n/**\n * Serialize ZodSchema to JSON-serializable format\n * Attempts to extract schema information for API response\n */\nfunction serializeSchema(schema: any): any {\n if (!schema) {\n return undefined;\n }\n\n try {\n // Try to get JSON schema if available (zod-to-json-schema or similar)\n if (schema._def) {\n // For Zod schemas, try to extract basic info\n const def = schema._def;\n if (def.typeName === \"ZodObject\") {\n // Extract shape information\n const shape = def.shape();\n const properties: Record<string, any> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n const fieldDef = (value as any)._def;\n if (fieldDef) {\n properties[key] = {\n type: fieldDef.typeName === \"ZodString\" ? \"string\" :\n fieldDef.typeName === \"ZodNumber\" ? \"number\" :\n fieldDef.typeName === \"ZodBoolean\" ? \"boolean\" :\n fieldDef.typeName === \"ZodArray\" ? \"array\" :\n fieldDef.typeName === \"ZodObject\" ? \"object\" : \"unknown\",\n description: fieldDef.description,\n };\n if (!(value as any).isOptional()) {\n required.push(key);\n }\n }\n }\n\n return {\n type: \"object\",\n properties,\n required: required.length > 0 ? required : undefined,\n };\n }\n }\n\n // Fallback: return schema description or type name\n return {\n type: \"object\",\n description: schema.description || \"Schema definition\",\n };\n } catch (error) {\n // If serialization fails, return a safe fallback\n return {\n type: \"object\",\n description: \"Schema definition\",\n };\n }\n}\n\n/**\n * Get tool config meta from ToolLatticeManager\n * Exposes tool configuration metadata via /api/tools endpoint\n */\nexport async function getToolConfigs(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ToolConfigMetaResponse> {\n try {\n const allLattices = toolLatticeManager.getAllLattices();\n \n const toolConfigs = allLattices.map((lattice) => {\n const config = { ...lattice.config };\n \n // Serialize schema if present\n const serializedSchema = config.schema ? serializeSchema(config.schema) : undefined;\n\n return {\n id: lattice.key,\n name: config.name,\n description: config.description,\n schema: serializedSchema,\n returnDirect: config.returnDirect,\n needUserApprove: config.needUserApprove,\n };\n });\n\n return reply.send({\n success: true,\n message: \"Successfully retrieved tool configs\",\n data: {\n records: toolConfigs,\n total: toolConfigs.length,\n },\n });\n } catch (error: any) {\n console.error(\"Failed to get tool configs\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tool configs: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n metricsServerManager,\n SemanticMetricsClient,\n} from \"@axiom-lattice/core\";\nimport type {\n MetricsServerConfigStore,\n SemanticMetricsServerConfig,\n SemanticMetricsFilter,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Get tenant ID from request headers\n */\nfunction getTenantId(request: FastifyRequest): string {\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Data query request body\n */\ninterface DataQueryRequest {\n serverKey?: string;\n datasourceId?: string;\n metrics?: string[];\n groupBy?: string[];\n filters?: Array<{\n dimension: string;\n operator: string;\n values: (string | number | boolean)[];\n }>;\n customSql?: string;\n params?: Record<string, string | number | boolean>;\n limit?: number;\n}\n\n/**\n * Data query response - 只返回原始数据\n */\ninterface DataQueryResponse {\n success: boolean;\n message: string;\n data?: {\n // 语义查询结果\n semanticModel?: string;\n columns: Array<{ name: string; type: string }>;\n rows?: Array<Array<unknown>>;\n rowsObject?: Array<Record<string, unknown>>;\n // SQL 查询结果\n tableName?: string;\n executedSql?: string;\n // 通用元数据\n metadata: {\n rowCount: number;\n executionTimeMs?: number;\n };\n };\n}\n\n/**\n * Execute data query (semantic or SQL)\n */\nexport async function executeDataQuery(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as DataQueryRequest;\n\n try {\n // Validate request\n if (!body.serverKey && !body.datasourceId) {\n reply.code(400);\n return {\n success: false,\n message: \"Either serverKey or datasourceId must be provided\",\n };\n }\n\n // Determine query type\n const isSemanticQuery = body.metrics && body.metrics.length > 0;\n const isSqlQuery = body.customSql && body.customSql.trim().length > 0;\n\n if (!isSemanticQuery && !isSqlQuery) {\n reply.code(400);\n return {\n success: false,\n message: \"Either metrics (for semantic query) or customSql (for SQL query) must be provided\",\n };\n }\n\n if (isSemanticQuery && isSqlQuery) {\n reply.code(400);\n return {\n success: false,\n message: \"Cannot provide both metrics and customSql. Use one query type only.\",\n };\n }\n\n // Get server config\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n if (!body.serverKey) {\n reply.code(400);\n return {\n success: false,\n message: \"serverKey is required\",\n };\n }\n\n const config = await store.getConfigByKey(tenantId, body.serverKey);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: `Metrics server configuration not found: ${body.serverKey}`,\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint only supports semantic metrics servers\",\n };\n }\n\n if (!body.datasourceId) {\n reply.code(400);\n return {\n success: false,\n message: \"datasourceId is required\",\n };\n }\n\n // Check if server is registered\n if (!metricsServerManager.hasServer(tenantId, body.serverKey)) {\n reply.code(400);\n return {\n success: false,\n message: `Metrics server not registered: ${body.serverKey}. Please register the server first.`,\n };\n }\n\n // Get client from manager (read-only, no registration)\n const client = metricsServerManager.getClient(tenantId, body.serverKey) as SemanticMetricsClient;\n\n // Execute query based on type\n if (isSemanticQuery) {\n return await executeSemanticQuery(client, body, reply);\n } else {\n return await executeSqlQuery(client, body, reply);\n }\n } catch (error) {\n console.error(\"Failed to execute data query:\", error);\n reply.code(500);\n return {\n success: false,\n message: `Failed to execute data query: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Execute semantic query\n */\nasync function executeSemanticQuery(\n client: SemanticMetricsClient,\n body: DataQueryRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const semanticFilters: SemanticMetricsFilter[] = (body.filters || []).map(f => ({\n dimension: f.dimension,\n operator: f.operator,\n values: f.values,\n }));\n\n const result = await client.semanticQuery({\n datasourceId: body.datasourceId!,\n metrics: body.metrics!,\n groupBy: body.groupBy,\n filters: semanticFilters,\n limit: body.limit || 1000,\n });\n\n // 直接返回原始数据,不做 ECharts 转换\n return {\n success: true,\n message: \"Semantic query executed successfully\",\n data: {\n semanticModel: result.semanticModel,\n columns: result.columns,\n rows: result.rows,\n rowsObject: result.rowsObject,\n metadata: {\n rowCount: result.rowCount,\n executionTimeMs: result.executionTimeMs,\n },\n },\n };\n}\n\n/**\n * Execute SQL query\n */\nasync function executeSqlQuery(\n client: SemanticMetricsClient,\n body: DataQueryRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const result = await client.executeSqlQuery({\n datasourceId: body.datasourceId!,\n customSql: body.customSql!,\n params: body.params,\n limit: body.limit || 100,\n });\n\n // 直接返回原始数据,不做 ECharts 转换\n return {\n success: true,\n message: \"SQL query executed successfully\",\n data: {\n tableName: result.tableName,\n columns: result.columns.map(name => ({ name, type: 'unknown' })),\n rows: result.rows,\n rowsObject: result.rowsObject,\n executedSql: result.executedSql,\n metadata: {\n rowCount: result.rowCount,\n executionTimeMs: result.executionTimeMs,\n },\n },\n };\n}\n","import { FastifySchema } from \"fastify\";\n\nexport const dataQuerySchema: FastifySchema = {\n description: \"Execute data query (semantic or SQL)\",\n tags: [\"Data Query\"],\n summary: \"Query Data\",\n body: {\n type: \"object\",\n properties: {\n serverKey: { \n type: \"string\", \n description: \"Target semantic metrics server key (optional if configured in runConfig)\" \n },\n datasourceId: { \n type: \"string\", \n description: \"Data source ID (optional if configured in runConfig)\" \n },\n // Semantic query parameters\n metrics: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of metric names for semantic query\"\n },\n groupBy: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional array of dimensions to group by\"\n },\n filters: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n dimension: { type: \"string\" },\n operator: { type: \"string\" },\n values: {\n type: \"array\",\n items: { type: [\"string\", \"number\", \"boolean\"] }\n }\n },\n required: [\"dimension\", \"operator\", \"values\"]\n },\n description: \"Optional array of filters\"\n },\n // SQL query parameters\n customSql: {\n type: \"string\",\n description: \"Custom SQL query string with named parameters\"\n },\n params: {\n type: \"object\",\n additionalProperties: { type: [\"string\", \"number\", \"boolean\"] },\n description: \"Optional parameters for SQL query\"\n },\n // Common parameters\n limit: {\n type: \"number\",\n description: \"Maximum number of results (default: 1000)\"\n },\n format: {\n type: \"string\",\n enum: [\"echarts\", \"raw\"],\n description: \"Response format (default: echarts)\"\n }\n }\n },\n // Response schema temporarily removed - format not yet finalized\n // TODO: Add proper response schema once data format is confirmed\n};\n","import { FastifySchema } from \"fastify\";\n\n// Create Run Schemas\nexport const createRunSchema: FastifySchema = {\n description: \"Create a new agent run\",\n tags: [\"Runs\"],\n summary: \"Create Agent Run\",\n body: {\n type: \"object\",\n properties: {\n thread_id: { type: \"string\", description: \"Thread ID\" },\n assistant_id: { type: \"string\", description: \"Assistant ID\" },\n message: { type: \"string\", description: \"Message data for the run\" },\n command: {\n type: \"object\",\n description: \"Command data for the run\",\n nullable: true,\n },\n streaming: {\n type: \"boolean\",\n description: \"Whether to stream the response\",\n nullable: true,\n },\n background: {\n type: \"boolean\",\n description: \"Whether to run in background\",\n nullable: true,\n },\n },\n required: [\"thread_id\", \"assistant_id\", \"message\"],\n },\n response: {\n 200: {},\n 400: {},\n },\n};\n\n// Memory Schemas\nexport const getAllMemoryItemsSchema: FastifySchema = {\n description: \"Get all memory items for an assistant thread\",\n tags: [\"Memory\"],\n summary: \"Get All Memory Items\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n thread_id: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"thread_id\"],\n },\n response: {\n 200: {},\n 400: {},\n 500: {},\n },\n};\n\nexport const getAgentStateSchema: FastifySchema = {\n description: \"Get agent state for an assistant thread\",\n tags: [\"Memory\"],\n summary: \"Get Agent State\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n thread_id: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"thread_id\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const getMemoryItemSchema: FastifySchema = {\n description: \"Get a specific memory item by key\",\n tags: [\"Memory\"],\n summary: \"Get Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const setMemoryItemSchema: FastifySchema = {\n description: \"Set or update a memory item\",\n tags: [\"Memory\"],\n summary: \"Set Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n body: {\n type: \"object\",\n description: \"Memory item data\",\n },\n response: {\n 200: {},\n },\n};\n\nexport const deleteMemoryItemSchema: FastifySchema = {\n description: \"Delete a specific memory item\",\n tags: [\"Memory\"],\n summary: \"Delete Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const clearMemorySchema: FastifySchema = {\n description: \"Clear all memory items for an assistant\",\n tags: [\"Memory\"],\n summary: \"Clear Memory\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n },\n required: [\"assistantId\"],\n },\n response: {\n 200: {},\n },\n};\n\n// Graph Schema\nexport const getAgentGraphSchema: FastifySchema = {\n description: \"Get agent graph visualization\",\n tags: [\"Graph\"],\n summary: \"Get Agent Graph\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n },\n required: [\"assistantId\"],\n },\n response: {\n 200: {},\n },\n};\n\n// Resume Stream Schema\nexport const resumeStreamSchema: FastifySchema = {\n description: \"Resume streaming from a known position\",\n tags: [\"Streaming\"],\n summary: \"Resume Stream\",\n body: {\n type: \"object\",\n properties: {\n thread_id: { type: \"string\", description: \"Thread ID\" },\n message_id: {\n type: \"string\",\n description: \"Message ID (usually run_id)\",\n },\n known_content: {\n type: \"string\",\n description: \"Content already received\",\n },\n poll_interval: {\n type: \"number\",\n description: \"Polling interval in milliseconds\",\n nullable: true,\n default: 100,\n },\n },\n required: [\"thread_id\", \"message_id\"],\n },\n response: {\n 200: {},\n 400: {},\n 500: {},\n },\n};\n\n// Trigger Agent Task Schema\nexport const triggerAgentTaskSchema: FastifySchema = {\n description: \"Trigger an agent task\",\n tags: [\"Agent Tasks\"],\n summary: \"Trigger Agent Task\",\n body: {\n type: \"object\",\n properties: {\n assistant_id: {\n type: \"string\",\n description: \"Assistant ID\",\n },\n thread_id: {\n type: \"string\",\n description: \"Thread ID\",\n },\n input: {\n type: \"object\",\n description: \"Task input data\",\n },\n command: {\n type: \"object\",\n description: \"Command data for the task\",\n nullable: true,\n },\n },\n required: [\"assistant_id\", \"thread_id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n result: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Configuration Schemas\nexport const updateConfigSchema: FastifySchema = {\n description: \"Update gateway configuration\",\n tags: [\"Configuration\"],\n summary: \"Update Configuration\",\n body: {\n type: \"object\",\n properties: {\n config: {\n type: \"object\",\n description: \"Configuration object to update\",\n properties: {\n port: { type: \"number\", description: \"Server port\" },\n queueServiceType: {\n type: \"string\",\n enum: [\"memory\", \"redis\"],\n description: \"Queue service type\",\n },\n redisUrl: { type: \"string\", description: \"Redis URL\" },\n redisPassword: { type: \"string\", description: \"Redis password\" },\n queueName: { type: \"string\", description: \"Queue name\" },\n },\n },\n },\n required: [\"config\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\nexport const getConfigSchema: FastifySchema = {\n description: \"Get current gateway configuration\",\n tags: [\"Configuration\"],\n summary: \"Get Configuration\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n data: { type: \"object\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Health Check Schema\nexport const getHealthSchema: FastifySchema = {\n description: \"Health check endpoint for monitoring and load balancer checks\",\n tags: [\"Health\"],\n summary: \"Health Check\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n data: {\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"healthy\", \"unhealthy\"] },\n timestamp: { type: \"string\" },\n uptime: { type: \"number\" },\n service: { type: \"string\" },\n version: { type: \"string\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n status: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Skills Schemas\nexport const getSkillListSchema: FastifySchema = {\n description: \"Get list of all skills\",\n tags: [\"Skills\"],\n summary: \"Get Skill List\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const getSkillSchema: FastifySchema = {\n description: \"Get a single skill by ID\",\n tags: [\"Skills\"],\n summary: \"Get Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const createSkillSchema: FastifySchema = {\n description: \"Create a new skill\",\n tags: [\"Skills\"],\n summary: \"Create Skill\",\n body: {\n type: \"object\",\n properties: {\n id: { \n type: \"string\", \n description: \"Skill ID (optional, defaults to name if not provided; must equal name, name is used for path addressing)\" \n },\n name: { \n type: \"string\", \n description: \"Skill name (1-64 chars, lowercase alphanumeric with single hyphens, pattern: ^[a-z0-9]+(-[a-z0-9]+)*$)\",\n pattern: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n minLength: 1,\n maxLength: 64\n },\n description: { type: \"string\", description: \"Skill description\" },\n license: { type: \"string\", description: \"License information\" },\n compatibility: { type: \"string\", description: \"Compatibility information\" },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Additional metadata\",\n },\n content: { type: \"string\", description: \"Skill detailed content (markdown)\" },\n subSkills: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of sub-skill names (hierarchical structure)\",\n },\n },\n required: [\"name\", \"description\"],\n },\n response: {\n 201: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 409: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const updateSkillSchema: FastifySchema = {\n description: \"Update an existing skill\",\n tags: [\"Skills\"],\n summary: \"Update Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n body: {\n type: \"object\",\n properties: {\n name: { \n type: \"string\", \n description: \"Skill name (1-64 chars, lowercase alphanumeric with single hyphens, pattern: ^[a-z0-9]+(-[a-z0-9]+)*$)\",\n pattern: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n minLength: 1,\n maxLength: 64\n },\n description: { type: \"string\", description: \"Skill description\" },\n license: { type: \"string\", description: \"License information\" },\n compatibility: { type: \"string\", description: \"Compatibility information\" },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Additional metadata\",\n },\n content: { type: \"string\", description: \"Skill detailed content (markdown)\" },\n subSkills: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of sub-skill names (hierarchical structure)\",\n },\n },\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const deleteSkillSchema: FastifySchema = {\n description: \"Delete a skill by ID\",\n tags: [\"Skills\"],\n summary: \"Delete Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const searchSkillsByMetadataSchema: FastifySchema = {\n description: \"Search skills by metadata\",\n tags: [\"Skills\"],\n summary: \"Search Skills by Metadata\",\n querystring: {\n type: \"object\",\n properties: {\n key: { type: \"string\", description: \"Metadata key\" },\n value: { type: \"string\", description: \"Metadata value\" },\n },\n required: [\"key\", \"value\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const filterSkillsByCompatibilitySchema: FastifySchema = {\n description: \"Filter skills by compatibility\",\n tags: [\"Skills\"],\n summary: \"Filter Skills by Compatibility\",\n querystring: {\n type: \"object\",\n properties: {\n compatibility: { type: \"string\", description: \"Compatibility string\" },\n },\n required: [\"compatibility\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const filterSkillsByLicenseSchema: FastifySchema = {\n description: \"Filter skills by license\",\n tags: [\"Skills\"],\n summary: \"Filter Skills by License\",\n querystring: {\n type: \"object\",\n properties: {\n license: { type: \"string\", description: \"License string\" },\n },\n required: [\"license\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const getSandboxUrlSchema: FastifySchema = {\n description: \"Get sandbox URL based on assistant and thread configuration\",\n tags: [\"Sandbox\"],\n summary: \"Get Sandbox URL\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n threadId: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"threadId\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n sandboxUrl: { type: \"string\", description: \"Sandbox URL\" },\n sandboxName: { type: \"string\", description: \"Sandbox name\" },\n vmIsolation: {\n type: \"string\",\n enum: [\"agent\", \"project\", \"global\"],\n description: \"Sandbox isolation level\",\n },\n },\n },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\n// Data Query Schema\nexport { dataQuerySchema } from \"./data-query\";\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager } from \"@axiom-lattice/core\";\n\n/**\n * DELETE /api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id\n * Remove pending message from queue\n */\nexport async function removePendingMessageHandler(\n request: FastifyRequest,\n reply: FastifyReply\n) {\n try {\n const { assistant_id, thread_id, message_id } = request.params as {\n assistant_id: string;\n thread_id: string;\n message_id: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n\n if (!tenant_id) {\n return reply.code(400).send({ error: \"Missing x-tenant-id header\" });\n }\n\n if (!assistant_id) {\n return reply.code(400).send({ error: \"Missing assistant_id parameter\" });\n }\n\n // Get agent instance\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n if (!agent) {\n return reply.code(404).send({\n error: \"Thread not found\",\n threadId: thread_id,\n });\n }\n\n const success = await agent.removePendingMessage(message_id);\n\n if (!success) {\n return reply.code(404).send({\n error: \"Message not found\",\n messageId: message_id,\n });\n }\n\n return reply.send({\n success: true,\n messageId: message_id,\n });\n } catch (error) {\n console.error(\"Error removing pending message:\", error);\n return reply.code(500).send({\n error: \"Internal server error\",\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\n","import { agentLatticeManager, getSandBoxManager, normalizeSandboxName, sandboxLatticeManager } from \"@axiom-lattice/core\";\nimport { SandboxMiddlewareConfig } from \"@axiom-lattice/protocols\";\n\n\nconst ERROR_HTML = `<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Sandbox 连接错误</title>\n <style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n .container {\n background: white;\n border-radius: 16px;\n padding: 40px;\n max-width: 500px;\n width: 100%;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n }\n .error-icon {\n width: 80px;\n height: 80px;\n background: #fee2e2;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .error-icon svg {\n width: 40px;\n height: 40px;\n color: #dc2626;\n }\n h1 { color: #1f2937; margin-bottom: 16px; text-align: center; }\n p { color: #6b7280; margin-bottom: 12px; line-height: 1.6; }\n .info {\n background: #f3f4f6;\n border-radius: 8px;\n padding: 16px;\n margin: 20px 0;\n }\n .info-item {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid #e5e7eb;\n }\n .info-item:last-child { border-bottom: none; }\n .label { color: #6b7280; font-size: 14px; }\n .value { color: #1f2937; font-weight: 500; font-family: monospace; }\n .retry-btn {\n width: 100%;\n padding: 14px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n cursor: pointer;\n transition: transform 0.2s;\n }\n .retry-btn:hover { transform: translateY(-2px); }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"/>\n </svg>\n </div>\n <h1>无法连接到 Sandbox</h1>\n <p>无法连接到沙箱环境,请检查配置后重试。</p>\n <div class=\"info\">\n <div class=\"info-item\">\n <span class=\"label\">Assistant ID</span>\n <span class=\"value\" id=\"assistantId\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">Thread ID</span>\n <span class=\"value\" id=\"threadId\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">隔离级别</span>\n <span class=\"value\" id=\"vmIsolation\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">错误信息</span>\n <span class=\"value\" id=\"errorMsg\">-</span>\n </div>\n </div>\n <button class=\"retry-btn\" onclick=\"window.location.reload()\">重新连接</button>\n </div>\n <script>\n const params = new URLSearchParams(window.location.search);\n document.getElementById('assistantId').textContent = params.get('assistantId') || '-';\n document.getElementById('threadId').textContent = params.get('threadId') || '-';\n document.getElementById('vmIsolation').textContent = params.get('vmIsolation') || '-';\n document.getElementById('errorMsg').textContent = params.get('error') || '未知错误';\n </script>\n</body>\n</html>`;\n\nexport class SandboxService {\n\n getFilesystemVmIsolation(tenantId: string, assistantId: string): \"agent\" | \"project\" | \"global\" | null {\n const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);\n if (!agentLattice) {\n return null;\n }\n\n const filesystemConfig = agentLattice?.config?.middleware?.find((m: any) => m.type === \"filesystem\");\n if (!filesystemConfig) {\n return null;\n }\n\n const config = filesystemConfig.config as SandboxMiddlewareConfig;\n return config?.vmIsolation || null;\n }\n\n computeSandboxName(\n assistantId: string,\n threadId: string,\n vmIsolation: string,\n tenantId?: string,\n workspaceId?: string,\n projectId?: string,\n ): string {\n switch (vmIsolation) {\n case \"agent\":\n return normalizeSandboxName(`${tenantId ?? \"default\"}-${assistantId}`);\n case \"project\":\n return normalizeSandboxName(\n `${tenantId ?? \"default\"}-${workspaceId ?? \"default\"}-${projectId ?? \"default\"}`\n );\n case \"global\":\n default:\n return \"global\";\n }\n }\n\n private getBrowserSandboxBaseURL(): string {\n return process.env.AGENT_INFRA_SANDBOX_BASE_URL || \"http://localhost:8080\";\n }\n\n getTargetUrl(sandboxName: string): string {\n return `${this.getBrowserSandboxBaseURL()}/sandbox/${sandboxName}`;\n }\n\n async getVncHtml(sandboxName: string): Promise<string> {\n const response = await fetch(`${this.getTargetUrl(sandboxName)}/vnc/index.html`);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch VNC HTML: ${response.statusText}`);\n }\n\n return response.text();\n }\n\n rewriteHtml(\n html: string,\n assistantId: string,\n threadId: string\n ): string {\n const prefix = `/api/assistants/${assistantId}/threads/${threadId}/sandbox/vnc`;\n\n let rewritten = html;\n\n rewritten = rewritten.replace(\n /(src|href)=[\"']([^\"']*)[\"']/g,\n (match, attr, url) => {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\") || url.startsWith(\"//\")) {\n return match;\n }\n const rewrittenUrl = url.startsWith(\"/\") ? `${prefix}${url}` : `${prefix}/${url}`;\n return `${attr}=\"${rewrittenUrl}\"`;\n }\n );\n\n rewritten = rewritten.replace(\n /path=sandbox\\/[^&\"']+/g,\n (match) => {\n return `path=${prefix}/websockify`;\n }\n );\n\n rewritten = rewritten.replace(\n /new WebSocket\\([^)]*\\?path=sandbox[^)]*\\)/g,\n (match) => {\n return match.replace(/path=sandbox[^)]+/, `path=${prefix}/websockify`);\n }\n );\n\n return rewritten;\n }\n\n generateErrorHtml(\n assistantId: string,\n threadId: string,\n vmIsolation: string,\n errorMessage: string\n ): string {\n const encodedError = encodeURIComponent(errorMessage);\n return ERROR_HTML\n .replace(\"{assistantId}\", assistantId)\n .replace(\"{threadId}\", threadId)\n .replace(\"{vmIsolation}\", vmIsolation)\n .replace(\"{errorMessage}\", errorMessage);\n }\n}\n\nexport const sandboxService = new SandboxService();\n","import { FastifyInstance } from \"fastify\";\nimport { sandboxService } from \"../services/sandbox_service\";\nimport { getSandBoxManager } from \"@axiom-lattice/core\";\n\n/** Get filename from path (e.g. /home/gem/uploads/foo.pdf -> foo.pdf) */\nfunction getFilenameFromPath(path: string): string {\n const segments = path.replace(/\\/+$/, \"\").split(\"/\");\n return segments[segments.length - 1] || \"download\";\n}\n\n/** Common extension -> MIME type for download response */\nconst EXT_TO_MIME: Record<string, string> = {\n \".txt\": \"text/plain\",\n \".html\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n \".json\": \"application/json\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".zip\": \"application/zip\",\n \".csv\": \"text/csv\",\n \".xml\": \"application/xml\",\n};\n\nfunction getContentTypeFromFilename(filename: string): string {\n const ext = filename.includes(\".\") ? filename.slice(filename.lastIndexOf(\".\")).toLowerCase() : \"\";\n return EXT_TO_MIME[ext] ?? \"application/octet-stream\";\n}\n\ninterface SandboxParams {\n assistantId: string;\n threadId: string;\n}\n\ninterface ProxyParams extends SandboxParams {\n \"*\": string;\n}\n\ninterface ResourceParams extends SandboxParams {\n resourcePath: string;\n}\n\nexport function registerSandboxProxyRoutes(app: FastifyInstance): void {\n // Register uploadfile route FIRST before wildcard routes to ensure it matches\n app.post<{ Params: SandboxParams }>(\n \"/api/assistants/:assistantId/threads/:threadId/sandbox/uploadfile\",\n async (request, reply) => {\n console.log(\"[Sandbox Upload] Route matched:\", request.url);\n const { assistantId, threadId } = request.params;\n const tenantId = (request.headers[\"x-tenant-id\"] as string) || \"default\";\n\n const vmIsolation = sandboxService.getFilesystemVmIsolation(tenantId, assistantId);\n if (!vmIsolation) {\n return reply.status(500).send({ error: \"Assistant sandbox config not found\" });\n }\n\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n vmIsolation\n );\n\n const sandboxManager = getSandBoxManager()\n const sandbox = await sandboxManager.createSandbox(sandboxName)\n\n try {\n const data = await request.file();\n if (!data) {\n return reply.status(400).send({ error: \"No file in request\" });\n }\n\n const buffer = await data.toBuffer();\n const pathEntry = data.fields?.path;\n const pathValue =\n pathEntry && typeof pathEntry === \"object\" && \"value\" in pathEntry\n ? String((pathEntry as { value: unknown }).value)\n : typeof pathEntry === \"string\"\n ? pathEntry\n : undefined;\n\n const filePath = `/uploads/${pathValue ? pathValue : \"\"}${data.filename}`;\n try {\n await sandbox.file.uploadFile({ file: filePath, data: buffer });\n } catch (err) {\n reply.status(500).send({ error: String(err) });\n return;\n }\n\n const relativePath = filePath.replace(`~/`, \"\");\n const result = { id: relativePath, name: data.filename, size: buffer.length };\n\n return reply.status(200).send({ message: \"File uploaded successfully\", ...result });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ error: `Upload proxy error: ${message}` });\n }\n }\n );\n\n // Download file from sandbox: GET with query param path (file path in sandbox, e.g. /home/gem/uploads/foo.txt)\n app.get<{\n Params: SandboxParams;\n Querystring: { path: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId/sandbox/downloadfile\",\n async (request, reply) => {\n const { assistantId, threadId } = request.params;\n const { path: filePath } = request.query;\n const tenantId = (request.headers[\"x-tenant-id\"] as string) || \"default\";\n\n if (!filePath || typeof filePath !== \"string\") {\n return reply.status(400).send({ error: \"Query parameter 'path' is required\" });\n }\n\n const vmIsolation = sandboxService.getFilesystemVmIsolation(tenantId, assistantId);\n if (!vmIsolation) {\n return reply.status(500).send({ error: \"Assistant filesystem vmIsolation not found\" });\n }\n\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n vmIsolation\n );\n\n const sandboxManager = getSandBoxManager();\n const sandbox = await sandboxManager.createSandbox(sandboxName);\n\n try {\n // Normalize path to /-prefixed absolute path\n const resolvedPath = filePath.startsWith(\"/\") ? filePath : `/${filePath}`;\n const filename = getFilenameFromPath(resolvedPath);\n const inferredContentType = getContentTypeFromFilename(filename);\n\n try {\n const buf = await sandbox.file.downloadFile({ file: resolvedPath });\n const contentDisposition = `inline; filename=\"${filename.replace(/\"/g, '\\\\\"')}\"; filename*=UTF-8''${encodeURIComponent(filename)}`;\n reply = reply.status(200).type(inferredContentType).header(\"Content-Disposition\", contentDisposition).send(buf);\n return reply;\n } catch (err) {\n reply.status(500).send({ error: String(err) });\n return;\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ error: `Download proxy error: ${message}` });\n }\n }\n );\n\n // app.get<{ Params: SandboxParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/browser\",\n // async (request, reply) => {\n // const { assistantId, threadId } = request.params;\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // const errorHtml = sandboxService.generateErrorHtml(\n // assistantId,\n // threadId,\n // \"unknown\",\n // `Assistant ${assistantId} not found`\n // );\n // return reply.status(404).type(\"text/html\").send(errorHtml);\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // try {\n // const html = await sandboxService.getVncHtml(sandboxName);\n // const rewrittenHtml = sandboxService.rewriteHtml(html, assistantId, threadId);\n // return reply.type(\"text/html\").send(rewrittenHtml);\n // } catch (error: any) {\n // const errorHtml = sandboxService.generateErrorHtml(\n // assistantId,\n // threadId,\n // vmIsolation,\n // error.message || \"Failed to connect to sandbox\"\n // );\n // return reply.status(502).type(\"text/html\").send(errorHtml);\n // }\n // }\n // );\n\n\n // app.get<{ Params: SandboxParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/websockify\",\n // { websocket: true },\n\n // (connection, request) => {\n\n // const url = (connection?.url) as string;\n // console.log(`[WebSocket] Received connection from URL: ${url}`);\n\n // const urlMatch = url.match(/\\/api\\/assistants\\/([^/]+)\\/threads\\/([^/]+)\\/sandbox\\/websockify/);\n // if (!urlMatch) {\n // console.error(`[WebSocket] Failed to parse params from URL: ${url}`);\n // connection.close(1008, \"Invalid URL format\");\n // return;\n // }\n\n // const assistantId = urlMatch[1];\n // const threadId = urlMatch[2];\n // console.log(`[WebSocket] Parsed params - assistantId: ${assistantId}, threadId: ${threadId}`);\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // console.error(`[WebSocket] Assistant ${assistantId} not found`);\n // connection.close(1008, \"Assistant not found\");\n // return;\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // const targetUrl = sandboxService.getTargetUrl(sandboxName);\n // const targetWsUrl = targetUrl.replace(/^http/, \"ws\").replace(/^https/, \"wss\") + \"/websockify\";\n\n // console.log(`[WebSocket] Connecting to target: ${targetWsUrl}`);\n\n // const targetSocket = new WebSocket(targetWsUrl);\n // const clientStream = createWebSocketStream(connection, { encoding: \"utf8\" });\n\n // const targetStream = createWebSocketStream(targetSocket, { encoding: \"utf8\" });\n\n // const forward = pipeline(clientStream, targetStream);\n // const backward = pipeline(targetStream, clientStream);\n\n // Promise.all([forward, backward]).catch((err) => {\n // console.error(`[WebSocket] Proxy pipeline failed:`, err.message);\n // targetSocket.terminate();\n // connection.terminate();\n // });\n // }\n // );\n\n // app.get<{ Params: ProxyParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/browser/vnc/*\",\n // async (request, reply) => {\n // const { assistantId, threadId, \"*\": restPath } = request.params;\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // return reply.status(404).send(\"Assistant not found\");\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // const targetPath = restPath ? `/vnc/${restPath}` : \"/vnc/\";\n // const targetUrl = `${sandboxService.getTargetUrl(sandboxName)}${targetPath}`;\n\n // try {\n // const response = await fetch(targetUrl);\n // const contentType = response.headers.get(\"content-type\") || \"application/octet-stream\";\n\n // const body = await response.arrayBuffer();\n // reply.status(response.status).type(contentType).send(Buffer.from(body));\n // } catch (error: any) {\n // reply.status(502).send(`Proxy error: ${error.message}`);\n // }\n // }\n // );\n\n\n}\n","/**\n * WorkspaceController\n *\n * Controller for workspace and project management\n * Handles CRUD operations, file browsing, and file uploads\n */\n\nimport { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { SandboxFilesystem, FilesystemBackend } from \"@axiom-lattice/core\";\nimport { getSandBoxManager } from \"@axiom-lattice/core\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type {\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n CreateProjectRequest,\n UpdateProjectRequest,\n Workspace,\n Project,\n} from \"@axiom-lattice/protocols\";\n\ninterface WorkspaceParams {\n workspaceId: string;\n}\n\ninterface ProjectParams {\n workspaceId: string;\n projectId: string;\n}\n\ninterface ListPathQuery {\n path?: string;\n assistantId?: string;\n}\n\ninterface ReadFileQuery {\n path: string;\n offset?: number;\n limit?: number;\n assistantId?: string;\n}\n\nexport class WorkspaceController {\n private workspaceStore;\n private projectStore;\n\n constructor() {\n this.workspaceStore = getStoreLattice(\"default\", \"workspace\").store;\n this.projectStore = getStoreLattice(\"default\", \"project\").store;\n }\n\n private getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Try to get from query parameters (for direct URL access like file downloads)\n const queryTenantId = (request.query as any)?.tenantId;\n if (queryTenantId) {\n return String(queryTenantId);\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n }\n\n // ==================== Workspace CRUD ====================\n\n async listWorkspaces(request: FastifyRequest, reply: FastifyReply) {\n const tenantId = this.getTenantId(request);\n const workspaces = await this.workspaceStore.getAllWorkspaces(tenantId);\n return { success: true, data: workspaces };\n }\n\n async createWorkspace(\n request: FastifyRequest<{ Body: CreateWorkspaceRequest }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const data = request.body;\n const id = uuidv4();\n\n const workspace = await this.workspaceStore.createWorkspace(\n tenantId,\n id,\n data\n );\n\n return reply.status(201).send({ success: true, data: workspace });\n }\n\n async getWorkspace(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true, data: workspace };\n }\n\n async updateWorkspace(\n request: FastifyRequest<{\n Params: WorkspaceParams;\n Body: UpdateWorkspaceRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n const updates = request.body;\n\n const workspace = await this.workspaceStore.updateWorkspace(\n tenantId,\n workspaceId,\n updates\n );\n\n if (!workspace) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true, data: workspace };\n }\n\n async deleteWorkspace(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const deleted = await this.workspaceStore.deleteWorkspace(\n tenantId,\n workspaceId\n );\n\n if (!deleted) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true };\n }\n\n // ==================== Project CRUD ====================\n\n async listProjects(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const projects = await this.projectStore.getProjectsByWorkspace(\n tenantId,\n workspaceId\n );\n\n return { success: true, data: projects };\n }\n\n async createProject(\n request: FastifyRequest<{\n Params: WorkspaceParams;\n Body: CreateProjectRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n const data = request.body;\n const id = uuidv4();\n\n const project = await this.projectStore.createProject(\n tenantId,\n workspaceId,\n id,\n data\n );\n\n return reply.status(201).send({ success: true, data: project });\n }\n\n async getProject(\n request: FastifyRequest<{ Params: ProjectParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n\n const project = await this.projectStore.getProjectById(tenantId, projectId);\n\n if (!project) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true, data: project };\n }\n\n async updateProject(\n request: FastifyRequest<{\n Params: ProjectParams;\n Body: UpdateProjectRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n const updates = request.body;\n\n const project = await this.projectStore.updateProject(\n tenantId,\n projectId,\n updates\n );\n\n if (!project) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true, data: project };\n }\n\n async deleteProject(\n request: FastifyRequest<{ Params: ProjectParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n\n const deleted = await this.projectStore.deleteProject(tenantId, projectId);\n\n if (!deleted) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true };\n }\n\n // ==================== File Operations ====================\n\n private async getBackend(tenantId: string, workspaceId: string, projectId: string, assistantId?: string, filePath?: string) {\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n throw new Error(\"Workspace not found\");\n }\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, filePath || \"/project\");\n if (volumeBackend) {\n return { backend: volumeBackend, workspace };\n }\n\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n return {\n backend: new SandboxFilesystem({\n sandboxInstance: sandbox,\n }), workspace\n };\n } else {\n return {\n backend: new FilesystemBackend({\n rootDir: `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`,\n virtualMode: true,\n }), workspace\n };\n }\n }\n\n private getFilenameFromPath(filePath: string): string {\n const segments = filePath.split(\"/\");\n return segments[segments.length - 1] || \"download\";\n }\n\n private getMimeType(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase() || \"\";\n const mimeTypes: Record<string, string> = {\n pdf: \"application/pdf\",\n csv: \"text/csv\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n xls: \"application/vnd.ms-excel\",\n txt: \"text/plain\",\n json: \"application/json\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n html: \"text/html\",\n htm: \"text/html\",\n mp3: \"audio/mpeg\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n };\n return mimeTypes[ext] || \"application/octet-stream\";\n }\n\n private isBinaryContentType(filename: string): boolean {\n const ext = filename.split(\".\").pop()?.toLowerCase() || \"\";\n const binaryExtensions = new Set([\n \"pdf\", \"xlsx\", \"xls\", \"docx\", \"doc\", \"pptx\", \"ppt\",\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"bmp\", \"ico\", \"webp\",\n \"mp3\", \"mp4\", \"webm\", \"ogg\", \"wav\", \"avi\", \"mov\",\n \"zip\", \"tar\", \"gz\", \"rar\", \"7z\",\n ]);\n return binaryExtensions.has(ext);\n }\n\n async downloadFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { path: string; assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const filePath = request.query.path;\n const assistantId = request.query.assistantId;\n\n if (!filePath) {\n return reply.status(400).send({ success: false, error: \"Path is required\" });\n }\n\n try {\n const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);\n const resolvedPath = filePath;\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const filename = this.getFilenameFromPath(resolvedPath);\n const isBinary = this.isBinaryContentType(filename);\n\n // Try volume backend for text files; binary files must use sandbox\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);\n\n let buf: Buffer;\n if (volumeBackend && !isBinary) {\n const fileData = await volumeBackend.readRaw(resolvedPath);\n buf = Buffer.from(fileData.content.join(\"\\n\"), \"utf-8\");\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n buf = await sandbox.file.downloadFile({ file: resolvedPath });\n }\n\n const inferredContentType = this.getMimeType(filename);\n\n const contentDisposition = `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`;\n return reply.status(200).type(inferredContentType).header(\"Content-Disposition\", contentDisposition).send(buf);\n }\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);\n const content = await backend.read(resolvedPath, 0, Infinity);\n const filename = this.getFilenameFromPath(resolvedPath);\n const mimeType = this.getMimeType(filename);\n const buffer = Buffer.from(content, \"utf-8\");\n\n return reply\n .status(200)\n .type(mimeType)\n .header(\"Content-Disposition\", `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`)\n .send(buffer);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ success: false, error: `Download proxy error: ${message}` });\n }\n }\n\n /**\n * View a file inline in the browser (not download).\n * Returns file content with inline Content-Disposition for preview.\n */\n async viewFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { path: string; assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const filePath = request.query.path;\n const assistantId = request.query.assistantId;\n\n if (!filePath) {\n return reply.status(400).send({ success: false, error: \"Path is required\" });\n }\n\n try {\n const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);\n const resolvedPath = filePath;\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const filename = this.getFilenameFromPath(resolvedPath);\n const isBinary = this.isBinaryContentType(filename);\n\n // Try volume backend for text files; binary files must use sandbox\n // (volume backend's readRaw API is text-based and corrupts binary data)\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);\n\n let buf: Buffer;\n if (volumeBackend && !isBinary) {\n const fileData = await volumeBackend.readRaw(resolvedPath);\n buf = Buffer.from(fileData.content.join(\"\\n\"), \"utf-8\");\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n buf = await sandbox.file.downloadFile({ file: resolvedPath });\n }\n\n const inferredContentType = this.getMimeType(filename);\n\n try {\n let contentType = inferredContentType;\n\n // Inject AI2APP context script for HTML files (sandbox storage)\n const isHtml = contentType?.toLowerCase().includes(\"text/html\") || \n filename.toLowerCase().endsWith(\".html\") || \n filename.toLowerCase().endsWith(\".htm\");\n let outputBuf = buf;\n if (isHtml) {\n console.log(`[viewFile] Injecting AI2APP context for sandbox HTML file: ${filename}, tenantId: ${tenantId}, contentType: ${contentType}`);\n let content = buf.toString(\"utf-8\");\n const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({\n tenantId,\n workspaceId,\n projectId,\n timestamp: Date.now()\n })};</script>`;\n \n if (content.toLowerCase().includes(\"</head>\")) {\n content = content.replace(/<\\/head>/i, `${contextScript}</head>`);\n console.log(`[viewFile] Context script injected before </head>`);\n } else if (content.toLowerCase().includes(\"<html>\")) {\n content = content.replace(/<html>/i, `<html>${contextScript}`);\n console.log(`[viewFile] Context script injected after <html>`);\n } else {\n content = contextScript + content;\n console.log(`[viewFile] Context script prepended to content`);\n }\n outputBuf = Buffer.from(content, \"utf-8\");\n }\n\n return reply\n .status(200)\n .type(contentType)\n .header(\"Content-Disposition\", \"inline\")\n .send(outputBuf);\n } catch (err) {\n return reply.status(502).send({ success: false, error: String(err) });\n }\n }\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);\n const content = await backend.read(resolvedPath, 0, Infinity);\n const filename = this.getFilenameFromPath(resolvedPath);\n const mimeType = this.getMimeType(filename);\n\n // Inject AI2APP context script for HTML files\n let finalContent = content;\n const isHtmlFs = mimeType?.toLowerCase().includes(\"text/html\") || \n filename.toLowerCase().endsWith(\".html\") || \n filename.toLowerCase().endsWith(\".htm\");\n if (isHtmlFs) {\n console.log(`[viewFile] Injecting AI2APP context for filesystem HTML file: ${filename}, tenantId: ${tenantId}, mimeType: ${mimeType}`);\n const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({\n tenantId,\n workspaceId,\n projectId,\n timestamp: Date.now()\n })};</script>`;\n // Insert before </head> or </html>\n if (content.toLowerCase().includes(\"</head>\")) {\n finalContent = content.replace(/<\\/head>/i, `${contextScript}</head>`);\n console.log(`[viewFile] Context script injected before </head>`);\n } else if (content.toLowerCase().includes(\"</html>\")) {\n finalContent = content.replace(/<\\/html>/i, `${contextScript}</html>`);\n console.log(`[viewFile] Context script injected before </html>`);\n } else {\n finalContent = content + contextScript;\n console.log(`[viewFile] Context script appended to content`);\n }\n }\n\n const buffer = Buffer.from(finalContent, \"utf-8\");\n\n return reply\n .status(200)\n .type(mimeType)\n .header(\"Content-Disposition\", \"inline\")\n .send(buffer);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ success: false, error: `View proxy error: ${message}` });\n }\n }\n\n async listPath(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: ListPathQuery;\n }>\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const path = (request.query.path as string) || \"/\";\n const assistantId = request.query.assistantId;\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path);\n const files = await backend.lsInfo(path);\n\n return { success: true, data: files };\n }\n\n async readFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: ReadFileQuery;\n }>\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const { path, offset = 0, limit = 1000, assistantId } = request.query;\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path);\n const content = await backend.read(path, Number(offset), Number(limit));\n\n return { success: true, data: { content, offset, limit } };\n }\n\n /**\n * Upload a file to the workspace project storage.\n *\n * Route: POST /api/workspaces/:workspaceId/projects/:projectId/uploadfile\n * Accepts multipart/form-data with:\n * - `file`: the file to upload (required)\n * - `path`: optional directory path relative to project root (e.g., \"docs\", \"src/utils\")\n * - `assistantId`: optional query parameter for sandbox identity matching\n * For sandbox storage, delegates to the sandbox upload API.\n * For filesystem storage, writes directly under /lattice_store/workspaces/{workspaceId}/{projectId}.\n */\n async uploadFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const assistantId = (request.query as any).assistantId;\n\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n return reply\n .status(404)\n .send({ success: false, error: \"Workspace not found\" });\n }\n\n try {\n const data = await (request as any).file();\n if (!data) {\n return reply\n .status(400)\n .send({ success: false, error: \"No file in request\" });\n }\n\n const buffer: Buffer = await data.toBuffer();\n const filename: string = data.filename || \"file\";\n\n const pathEntry = data.fields?.path;\n const pathValue =\n pathEntry && typeof pathEntry === \"object\" && \"value\" in pathEntry\n ? String((pathEntry as { value: unknown }).value)\n : typeof pathEntry === \"string\"\n ? pathEntry\n : undefined;\n\n if (pathValue && !/^[a-zA-Z0-9_./~\\-]+$/.test(pathValue)) {\n return reply\n .status(400)\n .send({ success: false, error: \"Invalid path parameter\" });\n }\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const realPath = pathValue\n ? path.posix.join(pathValue, filename)\n : path.posix.join(\"/project/uploads\", filename);\n\n // Try volume backend for text files; binary files must use sandbox\n // (volume backend's write API is text-based and corrupts binary data)\n const isBinary = this.isBinaryContentType(filename);\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, realPath);\n if (volumeBackend && !isBinary) {\n await volumeBackend.write(realPath, buffer.toString(\"utf-8\"));\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n await sandbox.file.uploadFile({ file: realPath, data: buffer });\n }\n\n const relativePath = pathValue\n ? path.posix.join(pathValue, filename)\n : path.posix.join(\"/project/uploads\", filename);\n\n const result = {\n path: relativePath,\n name: filename,\n is_dir: false,\n size: buffer.length,\n modified_at: new Date().toISOString(),\n };\n\n return reply.status(200).send({ success: true, data: result });\n }\n\n // Filesystem storage: write under /lattice_store/tenants/{tenantId}/workspaces/{workspaceId}/{projectId} and expose as virtual path \"/<filename>\"\n const rootDir = `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;\n const targetDir = pathValue ? path.join(rootDir, pathValue) : rootDir;\n const targetPath = path.join(targetDir, filename);\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.writeFile(targetPath, buffer);\n const stat = await fs.stat(targetPath);\n\n const result = {\n path: pathValue ? `/${pathValue}/${filename}` : `/${filename}`,\n name: filename,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n };\n\n return reply.status(200).send({ success: true, data: result });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n error: `Upload handler error: ${error?.message || String(error)}`,\n });\n }\n }\n}\n\nexport function registerWorkspaceRoutes(app: FastifyInstance) {\n const controller = new WorkspaceController();\n\n // Workspace routes\n app.get(\"/api/workspaces\", controller.listWorkspaces.bind(controller));\n app.post(\"/api/workspaces\", controller.createWorkspace.bind(controller));\n app.get(\n \"/api/workspaces/:workspaceId\",\n controller.getWorkspace.bind(controller)\n );\n app.patch(\n \"/api/workspaces/:workspaceId\",\n controller.updateWorkspace.bind(controller)\n );\n app.delete(\n \"/api/workspaces/:workspaceId\",\n controller.deleteWorkspace.bind(controller)\n );\n\n // Project routes\n app.get(\n \"/api/workspaces/:workspaceId/projects\",\n controller.listProjects.bind(controller)\n );\n app.post(\n \"/api/workspaces/:workspaceId/projects\",\n controller.createProject.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.getProject.bind(controller)\n );\n app.patch(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.updateProject.bind(controller)\n );\n app.delete(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.deleteProject.bind(controller)\n );\n\n // File operations\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/listpath\",\n controller.listPath.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/readfile\",\n controller.readFile.bind(controller)\n );\n app.post(\n \"/api/workspaces/:workspaceId/projects/:projectId/uploadfile\",\n controller.uploadFile.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/downloadfile\",\n controller.downloadFile.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/viewfile\",\n controller.viewFile.bind(controller)\n );\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n sqlDatabaseManager,\n} from \"@axiom-lattice/core\";\nimport type {\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Database Config Controller\n * Handles database configuration CRUD operations\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Database config list response\n */\ninterface DatabaseConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: DatabaseConfigEntry[];\n total: number;\n };\n}\n\n/**\n * Database config response\n */\ninterface DatabaseConfigResponse {\n success: boolean;\n message: string;\n data?: DatabaseConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * Get all database configs for a tenant\n */\nexport async function getDatabaseConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n \n console.log('Backend: getAllConfigs returned:', configs);\n if (configs.length > 0) {\n console.log('Backend: First config key:', configs[0].key);\n }\n\n return {\n success: true,\n message: \"Database configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get database configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve database configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get database config by key\n */\nexport async function getDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"Database configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get database config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve database configuration\",\n };\n }\n}\n\n/**\n * Create new database config\n */\nexport async function createDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateDatabaseConfigRequest & { id?: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"Database configuration with this key already exists\",\n };\n }\n\n const id = body.id || randomUUID();\n const config = await store.createConfig(tenantId, id, body);\n\n // Auto-register to SqlDatabaseManager\n try {\n sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);\n } catch (error) {\n console.warn(\"Failed to auto-register database:\", error);\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"Database configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create database config:\", error);\n return {\n success: false,\n message: \"Failed to create database configuration\",\n };\n }\n}\n\n/**\n * Update database config\n */\nexport async function updateDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateDatabaseConfigRequest>;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update database configuration\",\n };\n }\n\n // Re-register to SqlDatabaseManager if config changed\n if (updates.config) {\n try {\n sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);\n } catch (error) {\n console.warn(\"Failed to re-register database:\", error);\n }\n }\n\n return {\n success: true,\n message: \"Database configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update database config:\", error);\n return {\n success: false,\n message: \"Failed to update database configuration\",\n };\n }\n}\n\n/**\n * Delete database config by key or id\n */\nexport async function deleteDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n console.log('Delete request - keyOrId:', keyOrId);\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n console.log('Found config to delete:', { id: config.id, key: config.key });\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete database configuration\",\n };\n }\n\n // Remove from SqlDatabaseManager\n try {\n if (sqlDatabaseManager.hasDatabase(tenantId, configKey)) {\n await sqlDatabaseManager.removeDatabase(tenantId, configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from SqlDatabaseManager:\", error);\n }\n\n return {\n success: true,\n message: \"Database configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete database config:\", error);\n return {\n success: false,\n message: \"Failed to delete database configuration\",\n };\n }\n}\n\n/**\n * Test database connection\n */\nexport async function testDatabaseConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n // Register temporarily for testing\n const testKey = `__test_${key}_${Date.now()}`;\n sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);\n\n const startTime = Date.now();\n const db = await sqlDatabaseManager.getDatabase(tenantId, testKey);\n\n try {\n // Try to connect and list tables\n await db.connect();\n await db.listTables();\n const latency = Date.now() - startTime;\n\n // Disconnect gracefully with delay to ensure all operations complete\n await new Promise(resolve => setTimeout(resolve, 100));\n await db.disconnect();\n \n // Cleanup\n await sqlDatabaseManager.removeDatabase(tenantId, testKey);\n\n return {\n success: true,\n message: \"Connection test successful\",\n data: {\n connected: true,\n latency,\n },\n };\n } catch (error) {\n // Cleanup on error\n try {\n await db.disconnect();\n await sqlDatabaseManager.removeDatabase(tenantId, testKey);\n } catch {}\n\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test database connection:\", error);\n return {\n success: false,\n message: \"Failed to test database connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * Register database config routes\n */\nexport function registerDatabaseConfigRoutes(app: any): void {\n // Get all configs\n app.get(\n \"/api/database-configs\",\n getDatabaseConfigList\n );\n\n // Get config by key\n app.get(\n \"/api/database-configs/:key\",\n getDatabaseConfig\n );\n\n // Create config\n app.post(\n \"/api/database-configs\",\n createDatabaseConfig\n );\n\n // Update config\n app.put(\n \"/api/database-configs/:key\",\n updateDatabaseConfig\n );\n\n // Delete config by key or id\n app.delete(\n \"/api/database-configs/:keyOrId\",\n deleteDatabaseConfig\n );\n\n // Test connection\n app.post(\n \"/api/database-configs/:key/test\",\n testDatabaseConnection\n );\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n metricsServerManager,\n SemanticMetricsClient,\n} from \"@axiom-lattice/core\";\nimport type {\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n DataSource,\n SemanticMetricsQueryRequest,\n SemanticMetricsServerConfig,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Metrics Server Config Controller\n * Handles metrics server configuration CRUD operations\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Metrics server config list response\n */\ninterface MetricsServerConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: MetricsServerConfigEntry[];\n total: number;\n };\n}\n\n/**\n * Metrics server config response\n */\ninterface MetricsServerConfigResponse {\n success: boolean;\n message: string;\n data?: MetricsServerConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * List available metrics response\n */\ninterface ListMetricsResponse {\n success: boolean;\n message: string;\n data?: {\n metrics: Array<{\n name: string;\n type?: string;\n description?: string;\n }>;\n };\n}\n\n/**\n * Query metric data response\n */\ninterface QueryMetricDataResponse {\n success: boolean;\n message: string;\n data?: {\n metricName: string;\n dataPoints: Array<{\n timestamp: number;\n value: number;\n labels?: Record<string, string>;\n }>;\n };\n}\n\n/**\n * Data sources list response\n */\ninterface DataSourcesResponse {\n success: boolean;\n message: string;\n data?: {\n datasources: DataSource[];\n };\n}\n\n/**\n * Datasource metrics response\n */\ninterface DatasourceMetricsResponse {\n success: boolean;\n message: string;\n data?: {\n index: {\n datasourceId: number;\n datasourceName: string;\n catalogVersion: string;\n domainCategories: string[];\n metrics: Array<{\n metricName: string;\n displayName: string;\n domain: string;\n shortDesc: string;\n searchKeywords: string[];\n registered: boolean;\n }>;\n tables?: Array<{\n tableName: string;\n displayName: string;\n docType: string;\n docTypeEn: string;\n mainTable?: string;\n lineTable?: string;\n columnCount: number;\n shortDesc: string;\n }>;\n };\n metricsDetails: Array<{\n datasourceId: number;\n metricName: string;\n displayName: string;\n domain: string;\n description: string;\n dataType: string;\n format: string;\n defaultTimeContext: {\n timeDimension: string;\n label: string;\n granularity: string;\n window: string;\n supportedGrains: string[];\n };\n supportedDimensions: Array<{\n dim_id: string;\n field_name: string;\n type: string;\n filter_operators?: string[];\n filter_example?: object;\n group_by_example?: string;\n }>;\n aiAgentContext: {\n polarity: string;\n synonyms: string[];\n thresholds: Array<{\n metric: string;\n operator: string;\n value: number;\n level: string;\n }>;\n diagnosticWorkflow: {\n trigger: {\n any_of: Array<{\n metric: string;\n operator: string;\n value: number;\n }>;\n };\n actions: Array<{\n type: string;\n metric?: string;\n dimensions?: string[];\n intent: string;\n }>;\n analysis_logic: string;\n };\n humanReadableExplanation: string;\n };\n }>;\n tablesDetails?: Array<{\n tableName: string;\n docType: string;\n docTypeEn: string;\n objTypeCode?: number;\n mainTable?: string;\n lineTable?: string;\n selectSql: string;\n columns: Array<{\n name: string;\n label: string;\n description?: string;\n type?: string;\n example?: string;\n } | null>;\n }>;\n };\n}\n\n/**\n * Semantic query response\n */\ninterface SemanticQueryResponse {\n success: boolean;\n message: string;\n data?: {\n semanticModel: string;\n columns: string[];\n dataPoints: Array<{\n timestamp?: number;\n value: number;\n labels?: Record<string, string>;\n }>;\n metadata?: {\n rowCount?: number;\n columnCount?: number;\n };\n };\n}\n\n/**\n * Get all metrics server configs for a tenant\n */\nexport async function getMetricsServerConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n\n return {\n success: true,\n message: \"Metrics server configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get metrics server configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics server configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get metrics server config by key\n */\nexport async function getMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"Metrics server configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics server configuration\",\n };\n }\n}\n\n/**\n * Create new metrics server config\n */\nexport async function createMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateMetricsServerConfigRequest & { \n id?: string;\n selectedDataSources?: string[];\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"Metrics server configuration with this key already exists\",\n };\n }\n\n if (body.config.type === \"semantic\" && !body.selectedDataSources) {\n reply.code(400);\n return {\n success: false,\n message: \"selectedDataSources is required for semantic metrics servers\",\n };\n }\n\n const id = body.id || randomUUID();\n const configData: CreateMetricsServerConfigRequest = {\n key: body.key,\n name: body.name,\n description: body.description,\n config: body.config.type === \"semantic\" \n ? {\n ...body.config,\n selectedDataSources: body.selectedDataSources || [],\n } as SemanticMetricsServerConfig\n : body.config,\n };\n\n const config = await store.createConfig(tenantId, id, configData);\n\n // Auto-register to MetricsServerManager\n try {\n metricsServerManager.registerServer(tenantId, config.key, config.config);\n } catch (error) {\n console.warn(\"Failed to auto-register metrics server:\", error);\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"Metrics server configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to create metrics server configuration\",\n };\n }\n}\n\n/**\n * Update metrics server config\n */\nexport async function updateMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateMetricsServerConfigRequest> & {\n selectedDataSources?: string[];\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n const isSemantic = updates.config?.type === \"semantic\" ||\n (existing.config.type === \"semantic\" && !updates.config?.type);\n\n if (isSemantic && updates.selectedDataSources !== undefined) {\n updates.config = {\n ...existing.config,\n ...updates.config,\n type: \"semantic\",\n selectedDataSources: updates.selectedDataSources,\n } as SemanticMetricsServerConfig;\n }\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update metrics server configuration\",\n };\n }\n\n if (updates.config) {\n try {\n metricsServerManager.registerServer(tenantId, updated.key, updated.config);\n } catch (error) {\n console.warn(\"Failed to re-register metrics server:\", error);\n }\n }\n\n return {\n success: true,\n message: \"Metrics server configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to update metrics server configuration\",\n };\n }\n}\n\n/**\n * Delete metrics server config by key or id\n */\nexport async function deleteMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete metrics server configuration\",\n };\n }\n\n // Remove from MetricsServerManager\n try {\n if (metricsServerManager.hasServer(tenantId, configKey)) {\n metricsServerManager.removeServer(tenantId, configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from MetricsServerManager:\", error);\n }\n\n return {\n success: true,\n message: \"Metrics server configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to delete metrics server configuration\",\n };\n }\n}\n\n/**\n * Test metrics server connection\n */\nexport async function testMetricsServerConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n // Register temporarily for testing\n const testKey = `__test_${key}_${Date.now()}`;\n metricsServerManager.registerServer(tenantId, testKey, config.config);\n\n try {\n const client = metricsServerManager.getClient(tenantId, testKey);\n const result = await client.testConnection();\n\n // Cleanup\n metricsServerManager.removeServer(tenantId, testKey);\n\n return {\n success: true,\n message: result.connected ? \"Connection test successful\" : \"Connection test failed\",\n data: result,\n };\n } catch (error) {\n // Cleanup on error\n try {\n metricsServerManager.removeServer(tenantId, testKey);\n } catch {}\n\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test metrics server connection:\", error);\n return {\n success: false,\n message: \"Failed to test metrics server connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * List available metrics from a server\n */\nexport async function listAvailableMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListMetricsResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n // Ensure server is registered\n if (!metricsServerManager.hasServer(tenantId, key)) {\n metricsServerManager.registerServer(tenantId, key, config.config);\n }\n\n const client = metricsServerManager.getClient(tenantId, key);\n const metrics = await client.listMetrics();\n\n return {\n success: true,\n message: \"Metrics retrieved successfully\",\n data: {\n metrics: metrics.map(m => ({\n name: m.name,\n type: m.type,\n description: m.description,\n })),\n },\n };\n } catch (error) {\n console.error(\"Failed to list metrics:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics\",\n };\n }\n}\n\n/**\n * Query metric data from a server\n */\nexport async function queryMetricsData(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<QueryMetricDataResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const { metricName, startTime, endTime, step, labels } = request.body as {\n metricName: string;\n startTime?: number;\n endTime?: number;\n step?: number;\n labels?: Record<string, string>;\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (!metricName) {\n reply.code(400);\n return {\n success: false,\n message: \"metricName is required\",\n };\n }\n\n // Ensure server is registered\n if (!metricsServerManager.hasServer(tenantId, key)) {\n metricsServerManager.registerServer(tenantId, key, config.config);\n }\n\n const client = metricsServerManager.getClient(tenantId, key);\n const result = await client.queryMetricData(metricName, {\n startTime,\n endTime,\n step,\n labels,\n });\n\n return {\n success: true,\n message: \"Metric data retrieved successfully\",\n data: {\n metricName: result.metricName,\n dataPoints: result.dataPoints,\n },\n };\n } catch (error) {\n console.error(\"Failed to query metric data:\", error);\n return {\n success: false,\n message: \"Failed to query metric data\",\n };\n }\n}\n\n/**\n * Get data sources for a semantic metrics server\n * GET /api/metrics-configs/:key/datasources\n */\nexport async function getDataSources(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataSourcesResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const allDatasources = await client.getDataSources();\n\n // Filter datasources by selectedDataSources if configured\n const selectedIds = semanticConfig.selectedDataSources || [];\n const filteredDatasources = selectedIds.length > 0\n ? allDatasources.filter(ds => selectedIds.includes(String(ds.id)))\n : allDatasources;\n\n return {\n success: true,\n message: \"Data sources retrieved successfully\",\n data: {\n datasources: filteredDatasources,\n },\n };\n } catch (error) {\n console.error(\"Failed to get data sources:\", error);\n return {\n success: false,\n message: \"Failed to retrieve data sources\",\n };\n }\n}\n\n/**\n * Get metrics for a specific data source\n * GET /api/metrics-configs/:key/datasources/:datasourceId/metrics\n */\nexport async function getDatasourceMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatasourceMetricsResponse> {\n const tenantId = getTenantId(request);\n const { key, datasourceId } = request.params as { key: string; datasourceId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const metrics = await client.getDatasourceMetrics(datasourceId);\n\n return {\n success: true,\n message: \"Datasource metrics retrieved successfully\",\n data: metrics,\n };\n } catch (error) {\n console.error(\"Failed to get datasource metrics:\", error);\n return {\n success: false,\n message: \"Failed to retrieve datasource metrics\",\n };\n }\n}\n\n/**\n * Query semantic metrics data\n * POST /api/metrics-configs/:key/semantic-query\n */\nexport async function querySemanticMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<SemanticQueryResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const body = request.body as SemanticMetricsQueryRequest;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n if (!body.datasourceId || !body.metrics || body.metrics.length === 0) {\n reply.code(400);\n return {\n success: false,\n message: \"datasourceId and metrics array are required\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const result = await client.semanticQuery(body);\n\n // Transform SemanticMetricsQueryResponse to response format\n // The response contains columns and rows arrays\n const columnNames = result.columns.map(col => col.name);\n const allDataPoints: Array<{\n timestamp?: number;\n value: number;\n labels?: Record<string, string>;\n }> = [];\n\n // Find timestamp column and value column indices\n const timestampColIdx = columnNames.findIndex(col => \n col.toLowerCase().includes('date') || col.toLowerCase().includes('time')\n );\n const valueColIdx = columnNames.findIndex(col => \n col.toLowerCase().includes('value') || col.toLowerCase().includes('rate') || col.toLowerCase().includes('amt')\n );\n\n for (const row of result.rows ?? []) {\n const timestamp = timestampColIdx >= 0 ? row[timestampColIdx] : undefined;\n const value = valueColIdx >= 0 ? row[valueColIdx] : row[row.length - 1];\n \n allDataPoints.push({\n timestamp: timestamp ? new Date(String(timestamp)).getTime() : undefined,\n value: typeof value === 'number' ? value : Number(value) || 0,\n labels: Object.fromEntries(\n columnNames.map((col, idx) => [col, String(row[idx] ?? '')])\n ),\n });\n }\n\n return {\n success: true,\n message: \"Semantic query executed successfully\",\n data: {\n semanticModel: result.semanticModel,\n columns: columnNames,\n dataPoints: allDataPoints,\n metadata: {\n rowCount: result.rows?.length ?? 0,\n columnCount: result.columns.length,\n },\n },\n };\n } catch (error) {\n console.error(\"Failed to query semantic metrics:\", error);\n return {\n success: false,\n message: \"Failed to query semantic metrics\",\n };\n }\n}\n\n/**\n * Test datasources endpoint without saving config\n * Used for multi-step configuration flow\n * POST /api/metrics-configs/test-datasources\n */\nexport async function testSemanticDataSources(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataSourcesResponse> {\n const body = request.body as {\n serverUrl: string;\n apiKey?: string;\n username?: string;\n password?: string;\n headers?: Record<string, string>;\n };\n\n try {\n if (!body.serverUrl) {\n reply.code(400);\n return {\n success: false,\n message: \"serverUrl is required\",\n };\n }\n\n const testConfig: SemanticMetricsServerConfig = {\n type: \"semantic\",\n serverUrl: body.serverUrl,\n apiKey: body.apiKey,\n username: body.username,\n password: body.password,\n headers: body.headers,\n };\n\n const client = new SemanticMetricsClient(testConfig);\n\n const datasources = await client.getDataSources();\n\n return {\n success: true,\n message: \"Data sources retrieved successfully\",\n data: {\n datasources,\n },\n };\n } catch (error) {\n console.error(\"Failed to test datasources:\", error);\n return {\n success: false,\n message: `Failed to retrieve data sources: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Test datasource metrics endpoint without saving config\n * Used for multi-step configuration flow\n * POST /api/metrics-configs/test-datasources/:datasourceId/metrics\n */\nexport async function testDatasourceMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatasourceMetricsResponse> {\n const { datasourceId } = request.params as { datasourceId: string };\n const body = request.body as {\n serverUrl: string;\n apiKey?: string;\n username?: string;\n password?: string;\n headers?: Record<string, string>;\n };\n\n try {\n if (!body.serverUrl) {\n reply.code(400);\n return {\n success: false,\n message: \"serverUrl is required\",\n };\n }\n\n const testConfig: SemanticMetricsServerConfig = {\n type: \"semantic\",\n serverUrl: body.serverUrl,\n apiKey: body.apiKey,\n username: body.username,\n password: body.password,\n headers: body.headers,\n };\n\n const client = new SemanticMetricsClient(testConfig);\n const metrics = await client.getDatasourceMetrics(datasourceId);\n\n return {\n success: true,\n message: \"Datasource metrics retrieved successfully\",\n data: metrics,\n };\n } catch (error) {\n console.error(\"Failed to test datasource metrics:\", error);\n return {\n success: false,\n message: `Failed to retrieve datasource metrics: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Register metrics server config routes\n */\nexport function registerMetricsServerConfigRoutes(app: any): void {\n // Get all configs\n app.get(\"/api/metrics-configs\", getMetricsServerConfigList);\n\n // Get config by key\n app.get(\"/api/metrics-configs/:key\", getMetricsServerConfig);\n\n // Create config\n app.post(\"/api/metrics-configs\", createMetricsServerConfig);\n\n // Update config\n app.put(\"/api/metrics-configs/:key\", updateMetricsServerConfig);\n\n // Delete config by key or id\n app.delete(\"/api/metrics-configs/:keyOrId\", deleteMetricsServerConfig);\n\n // Test connection\n app.post(\"/api/metrics-configs/:key/test\", testMetricsServerConnection);\n\n // List available metrics\n app.get(\"/api/metrics-configs/:key/metrics\", listAvailableMetrics);\n\n // Query metric data\n app.post(\"/api/metrics-configs/:key/query\", queryMetricsData);\n\n // Semantic-specific routes\n // Get data sources for a semantic server\n app.get(\"/api/metrics-configs/:key/datasources\", getDataSources);\n\n // Get metrics meta for a specific datasource\n app.get(\"/api/metrics-configs/:key/datasources/:datasourceId/meta\", getDatasourceMetrics);\n\n // Query semantic metrics data\n app.post(\"/api/metrics-configs/:key/semantic-query\", querySemanticMetrics);\n\n // Test datasources without saving config (for multi-step config flow)\n app.post(\"/api/metrics-configs/test-datasources\", testSemanticDataSources);\n\n // Test datasource metrics meta without saving config (for multi-step config flow)\n app.post(\"/api/metrics-configs/test-datasources/:datasourceId/meta\", testDatasourceMetrics);\n}\n","/**\n * MCP Server Config Controller\n * Handles MCP server configuration CRUD operations with automatic tool registration\n */\n\nimport { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n mcpManager,\n toolLatticeManager,\n} from \"@axiom-lattice/core\";\nimport type {\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n McpServerConfig,\n McpTool,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * MCP server config list response\n */\ninterface McpServerConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: McpServerConfigEntry[];\n total: number;\n };\n}\n\n/**\n * MCP server config response\n */\ninterface McpServerConfigResponse {\n success: boolean;\n message: string;\n data?: McpServerConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * List tools response\n */\ninterface ListToolsResponse {\n success: boolean;\n message: string;\n data?: {\n tools: McpTool[];\n };\n}\n\n/**\n * Get all MCP server configs for a tenant\n */\nexport async function getMcpServerConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n\n return {\n success: true,\n message: \"MCP server configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get MCP server configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get MCP server config by key\n */\nexport async function getMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configuration\",\n };\n }\n}\n\n/**\n * Create new MCP server config\n */\nexport async function createMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateMcpServerConfigRequest & {\n id?: string;\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"MCP server configuration with this key already exists\",\n };\n }\n\n const id = body.id || randomUUID();\n const config = await store.createConfig(tenantId, id, body);\n\n // Auto-connect and register tools\n try {\n await connectAndRegisterTools(config);\n // Update status to connected\n await store.updateConfig(tenantId, id, { status: \"connected\" });\n config.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to auto-connect MCP server:\", error);\n // Update status to error but don't fail the creation\n await store.updateConfig(tenantId, id, { status: \"error\" });\n config.status = \"error\";\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"MCP server configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to create MCP server configuration\",\n };\n }\n}\n\n/**\n * Update MCP server config\n */\nexport async function updateMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateMcpServerConfigRequest>;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // If config is being updated, we need to reconnect\n const shouldReconnect = updates.config !== undefined;\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n\n // Reconnect and re-register tools if config changed\n if (shouldReconnect) {\n try {\n // Disconnect existing connection if any\n if (mcpManager.hasServer(key)) {\n await mcpManager.removeServer(key);\n }\n // Reconnect with new config\n await connectAndRegisterTools(updated);\n await store.updateConfig(tenantId, existing.id, { status: \"connected\" });\n updated.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to reconnect MCP server:\", error);\n await store.updateConfig(tenantId, existing.id, { status: \"error\" });\n updated.status = \"error\";\n }\n }\n\n return {\n success: true,\n message: \"MCP server configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n}\n\n/**\n * Delete MCP server config by key or id\n */\nexport async function deleteMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect and remove from MCP manager\n try {\n if (mcpManager.hasServer(configKey)) {\n await mcpManager.removeServer(configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from MCP manager:\", error);\n }\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n}\n\n/**\n * Test MCP server connection\n */\nexport async function testMcpServerConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n const startTime = Date.now();\n\n // Test connection by trying to list tools\n try {\n // Create temporary connection\n const testKey = `__test_${key}_${Date.now()}`;\n const connection = convertToConnection(config.config);\n mcpManager.addServer(testKey, connection);\n\n await mcpManager.connect();\n const tools = await mcpManager.getAllTools();\n const latency = Date.now() - startTime;\n\n // Cleanup\n await mcpManager.removeServer(testKey);\n\n return {\n success: true,\n message: \"Connection test successful\",\n data: {\n connected: true,\n latency,\n },\n };\n } catch (error) {\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test MCP server connection:\", error);\n return {\n success: false,\n message: \"Failed to test MCP server connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * List available tools from an MCP server\n */\nexport async function listMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Ensure server is connected\n if (!mcpManager.hasServer(key)) {\n await connectAndRegisterTools(config);\n }\n\n const tools = await mcpManager.getAllTools();\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to list MCP tools:\", error);\n return {\n success: false,\n message: \"Failed to retrieve tools\",\n };\n }\n}\n\n/**\n * Connect to MCP server and register tools\n */\nexport async function connectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n await connectAndRegisterTools(config);\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"connected\",\n });\n\n return {\n success: true,\n message: \"MCP server connected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to connect MCP server:\", error);\n\n // Update status to error\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n const config = await store.getConfigByKey(tenantId, key);\n if (config) {\n await store.updateConfig(tenantId, config.id, { status: \"error\" });\n }\n\n return {\n success: false,\n message: `Failed to connect MCP server: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n}\n\n/**\n * Disconnect from MCP server\n */\nexport async function disconnectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect from MCP manager\n if (mcpManager.hasServer(key)) {\n await mcpManager.removeServer(key);\n }\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"disconnected\",\n });\n\n return {\n success: true,\n message: \"MCP server disconnected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to disconnect MCP server:\", error);\n return {\n success: false,\n message: \"Failed to disconnect MCP server\",\n };\n }\n}\n\n/**\n * Test MCP server connection and list tools without saving config\n * Used for multi-step configuration flow\n */\nexport async function testMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const body = request.body as {\n config: McpServerConfig;\n };\n\n try {\n if (!body.config) {\n reply.code(400);\n return {\n success: false,\n message: \"config is required\",\n };\n }\n\n const testKey = `__test_${Date.now()}`;\n\n // Create temporary connection\n const connection = convertToConnection(body.config);\n mcpManager.addServer(testKey, connection);\n\n await mcpManager.connect();\n const tools = await mcpManager.getAllTools();\n\n // Cleanup\n await mcpManager.removeServer(testKey);\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to test MCP server tools:\", error);\n return {\n success: false,\n message: `Failed to retrieve tools: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n}\n\n/**\n * Convert McpServerConfig to Connection format compatible with @langchain/mcp-adapters\n */\nfunction convertToConnection(config: McpServerConfig): any {\n const baseConfig = {\n env: config.env,\n };\n\n if (config.transport === \"stdio\") {\n return {\n ...baseConfig,\n transport: \"stdio\" as const,\n command: config.command!,\n args: config.args || [],\n };\n } else {\n // For HTTP/SSE transports\n return {\n ...baseConfig,\n transport: config.transport === \"streamable_http\" ? \"http\" : config.transport,\n url: config.url!,\n };\n }\n}\n\n/**\n * Helper function to connect to MCP server and register selected tools\n */\nasync function connectAndRegisterTools(\n config: McpServerConfigEntry\n): Promise<void> {\n // Add server to MCP manager\n const connection = convertToConnection(config.config);\n mcpManager.addServer(config.key, connection);\n\n // Connect to server\n await mcpManager.connect();\n\n // Get all available tools\n const allTools = await mcpManager.getAllTools();\n\n // Filter to only selected tools\n const selectedTools = allTools.filter((tool) =>\n config.selectedTools.includes(tool.name)\n );\n\n // Register selected tools to ToolLattice\n for (const tool of selectedTools) {\n toolLatticeManager.registerExistingTool(tool.name, tool);\n }\n}\n\n/**\n * Register MCP server config routes\n */\nexport function registerMcpServerConfigRoutes(app: any): void {\n // Get all configs\n app.get(\"/api/mcp-servers\", getMcpServerConfigList);\n\n // Get config by key\n app.get(\"/api/mcp-servers/:key\", getMcpServerConfig);\n\n // Create config\n app.post(\"/api/mcp-servers\", createMcpServerConfig);\n\n // Update config\n app.put(\"/api/mcp-servers/:key\", updateMcpServerConfig);\n\n // Delete config by key or id\n app.delete(\"/api/mcp-servers/:keyOrId\", deleteMcpServerConfig);\n\n // Test connection\n app.post(\"/api/mcp-servers/:key/test\", testMcpServerConnection);\n\n // List available tools\n app.get(\"/api/mcp-servers/:key/tools\", listMcpServerTools);\n\n // Connect to server\n app.post(\"/api/mcp-servers/:key/connect\", connectMcpServer);\n\n // Disconnect from server\n app.post(\"/api/mcp-servers/:key/disconnect\", disconnectMcpServer);\n\n // Test tools without saving config (for multi-step config flow)\n app.post(\"/api/mcp-servers/test-tools\", testMcpServerTools);\n}\n","import { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n CreateUserRequest,\n UpdateUserRequest,\n} from \"@axiom-lattice/protocols\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ninterface UserParams {\n userId: string;\n}\n\ninterface ListUsersQuery {\n email?: string;\n}\n\nexport class UsersController {\n private userStore;\n\n constructor() {\n this.userStore = getStoreLattice(\"default\", \"user\").store;\n }\n\n async listUsers(\n request: FastifyRequest<{ Querystring: ListUsersQuery }>,\n reply: FastifyReply\n ) {\n const { email } = request.query;\n\n if (email) {\n const user = await this.userStore.getUserByEmail(email);\n return { success: true, data: user ? [user] : [] };\n }\n\n const users = await this.userStore.getAllUsers();\n return { success: true, data: users };\n }\n\n async createUser(\n request: FastifyRequest<{ Body: CreateUserRequest }>,\n reply: FastifyReply\n ) {\n const data = request.body;\n const id = uuidv4();\n\n const existingUser = await this.userStore.getUserByEmail(data.email);\n if (existingUser) {\n return reply.status(409).send({\n success: false,\n error: `User with email ${data.email} already exists`,\n });\n }\n\n const user = await this.userStore.createUser(id, data);\n return reply.status(201).send({ success: true, data: user });\n }\n\n async getUser(\n request: FastifyRequest<{ Params: UserParams }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n\n const user = await this.userStore.getUserById(userId);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true, data: user };\n }\n\n async updateUser(\n request: FastifyRequest<{\n Params: UserParams;\n Body: UpdateUserRequest;\n }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n const updates = request.body;\n\n if (updates.email) {\n const existingUser = await this.userStore.getUserByEmail(updates.email);\n if (existingUser && existingUser.id !== userId) {\n return reply.status(409).send({\n success: false,\n error: `User with email ${updates.email} already exists`,\n });\n }\n }\n\n const user = await this.userStore.updateUser(userId, updates);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true, data: user };\n }\n\n async deleteUser(\n request: FastifyRequest<{ Params: UserParams }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n\n const deleted = await this.userStore.deleteUser(userId);\n\n if (!deleted) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true };\n }\n}\n\nexport function registerUserRoutes(app: FastifyInstance) {\n const controller = new UsersController();\n\n app.get(\"/api/users\", controller.listUsers.bind(controller));\n app.post(\"/api/users\", controller.createUser.bind(controller));\n app.get(\"/api/users/:userId\", controller.getUser.bind(controller));\n app.patch(\"/api/users/:userId\", controller.updateUser.bind(controller));\n app.delete(\"/api/users/:userId\", controller.deleteUser.bind(controller));\n}\n","/**\n * TenantsController\n *\n * Controller for tenant management\n * Handles CRUD operations for tenants (top-level entities)\n */\n\nimport { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n CreateTenantRequest,\n UpdateTenantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ninterface TenantParams {\n tenantId: string;\n}\n\nexport class TenantsController {\n private tenantStore;\n\n constructor() {\n this.tenantStore = getStoreLattice(\"default\", \"tenant\").store;\n }\n\n // ==================== Tenant CRUD ====================\n\n async listTenants(request: FastifyRequest, reply: FastifyReply) {\n const tenants = await this.tenantStore.getAllTenants();\n return { success: true, data: tenants };\n }\n\n async createTenant(\n request: FastifyRequest<{ Body: CreateTenantRequest }>,\n reply: FastifyReply\n ) {\n const data = request.body;\n const id = uuidv4();\n\n const tenant = await this.tenantStore.createTenant(id, data);\n return reply.status(201).send({ success: true, data: tenant });\n }\n\n async getTenant(\n request: FastifyRequest<{ Params: TenantParams }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true, data: tenant };\n }\n\n async updateTenant(\n request: FastifyRequest<{\n Params: TenantParams;\n Body: UpdateTenantRequest;\n }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n const updates = request.body;\n\n const tenant = await this.tenantStore.updateTenant(tenantId, updates);\n\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true, data: tenant };\n }\n\n async deleteTenant(\n request: FastifyRequest<{ Params: TenantParams }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n\n // Prevent deletion of the default tenant\n if (tenantId === \"default\") {\n return reply.status(403).send({\n success: false,\n error: \"Cannot delete the default tenant\",\n });\n }\n\n const deleted = await this.tenantStore.deleteTenant(tenantId);\n\n if (!deleted) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true };\n }\n}\n\nexport function registerTenantRoutes(app: FastifyInstance) {\n const controller = new TenantsController();\n\n // Tenant routes\n app.get(\"/api/tenants\", controller.listTenants.bind(controller));\n app.post(\"/api/tenants\", controller.createTenant.bind(controller));\n app.get(\"/api/tenants/:tenantId\", controller.getTenant.bind(controller));\n app.patch(\"/api/tenants/:tenantId\", controller.updateTenant.bind(controller));\n app.delete(\"/api/tenants/:tenantId\", controller.deleteTenant.bind(controller));\n}\n","import { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { CreateUserRequest, CreateTenantRequest, UserTenantRole } from \"@axiom-lattice/protocols\";\n\ninterface RegisterRequest {\n email: string;\n password: string;\n name: string;\n}\n\ninterface LoginRequest {\n email: string;\n password: string;\n}\n\ninterface SelectTenantRequest {\n tenantId: string;\n}\n\ninterface ApproveUserRequest {\n userId: string;\n approved: boolean;\n}\n\ninterface AssignTenantRequest {\n userId: string;\n tenantId: string;\n role?: UserTenantRole;\n}\n\ninterface ChangePasswordRequest {\n currentPassword: string;\n newPassword: string;\n}\n\nexport interface AuthConfig {\n autoApproveUsers: boolean;\n allowTenantRegistration: boolean;\n jwtSecret?: string;\n tokenExpiration: number;\n}\n\nconst defaultAuthConfig: AuthConfig = {\n autoApproveUsers: true,\n allowTenantRegistration: true,\n tokenExpiration: 86400,\n};\n\nexport class AuthController {\n private userStore;\n private tenantStore;\n private userTenantLinkStore;\n private config: AuthConfig;\n\n constructor(config: Partial<AuthConfig> = {}) {\n this.userStore = getStoreLattice(\"default\", \"user\").store;\n this.tenantStore = getStoreLattice(\"default\", \"tenant\").store;\n this.userTenantLinkStore = getStoreLattice(\"default\", \"userTenantLink\").store;\n this.config = { ...defaultAuthConfig, ...config };\n }\n\n async register(\n request: FastifyRequest<{ Body: RegisterRequest }>,\n reply: FastifyReply\n ) {\n const { email, password, name } = request.body;\n\n try {\n const existingUser = await this.userStore.getUserByEmail(email);\n if (existingUser) {\n return reply.status(409).send({\n success: false,\n error: \"User with this email already exists\",\n });\n }\n\n const userId = uuidv4();\n const userStatus = this.config.autoApproveUsers ? \"active\" : \"pending\";\n \n const userData: CreateUserRequest = {\n email,\n name,\n status: userStatus,\n metadata: {\n passwordHash: await this.hashPassword(password),\n },\n };\n\n const user = await this.userStore.createUser(userId, userData);\n\n return reply.status(201).send({\n success: true,\n message: this.config.autoApproveUsers\n ? \"Registration successful\"\n : \"Registration successful. Please wait for admin approval.\",\n data: {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n status: user.status,\n },\n },\n });\n } catch (error) {\n console.error(\"Registration error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Registration failed\",\n });\n }\n }\n\n async login(\n request: FastifyRequest<{ Body: LoginRequest }>,\n reply: FastifyReply\n ) {\n const { email, password } = request.body;\n\n try {\n const user = await this.userStore.getUserByEmail(email);\n if (!user) {\n return reply.status(401).send({\n success: false,\n error: \"Invalid credentials\",\n });\n }\n\n if (user.status !== \"active\") {\n return reply.status(403).send({\n success: false,\n error: `Account is ${user.status}. Please wait for admin approval.`,\n });\n }\n\n const isValidPassword = await this.verifyPassword(\n password,\n user.metadata?.passwordHash || \"\"\n );\n\n if (!isValidPassword) {\n return reply.status(401).send({\n success: false,\n error: \"Invalid credentials\",\n });\n }\n\n const tenantLinks = await this.userTenantLinkStore.getTenantsByUser(user.id);\n \n const token = await this.generateToken(user.id);\n\n return {\n success: true,\n data: {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n status: user.status,\n },\n tenants: tenantLinks.map(link => ({\n id: link.tenantId,\n role: link.role,\n })),\n token,\n requiresTenantSelection: tenantLinks.length > 1,\n hasTenants: tenantLinks.length > 0,\n },\n };\n } catch (error) {\n console.error(\"Login error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Login failed\",\n });\n }\n }\n\n async getUserTenants(\n request: FastifyRequest,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n \n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const links = await this.userTenantLinkStore.getTenantsByUser(userId);\n \n const tenantsWithDetails = await Promise.all(\n links.map(async (link) => {\n const tenant = await this.tenantStore.getTenantById(link.tenantId);\n return {\n ...link,\n tenant: tenant || null,\n };\n })\n );\n\n return {\n success: true,\n data: tenantsWithDetails,\n };\n } catch (error) {\n console.error(\"Get user tenants error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to get user tenants\",\n });\n }\n }\n\n async selectTenant(\n request: FastifyRequest<{ Body: SelectTenantRequest }>,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n const { tenantId } = request.body;\n\n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const hasLink = await this.userTenantLinkStore.hasLink(userId, tenantId);\n \n if (!hasLink) {\n return reply.status(403).send({\n success: false,\n error: \"You do not have access to this tenant\",\n });\n }\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n \n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n const token = await this.generateToken(userId, tenantId);\n\n return {\n success: true,\n data: {\n tenant: {\n id: tenant.id,\n name: tenant.name,\n status: tenant.status,\n },\n token,\n },\n };\n } catch (error) {\n console.error(\"Select tenant error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to select tenant\",\n });\n }\n }\n\n async approveUser(\n request: FastifyRequest<{ Body: ApproveUserRequest }>,\n reply: FastifyReply\n ) {\n const { userId, approved } = request.body;\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n if (user.status !== \"pending\") {\n return reply.status(400).send({\n success: false,\n error: `User is already ${user.status}`,\n });\n }\n\n const updatedUser = await this.userStore.updateUser(userId, {\n status: approved ? \"active\" : \"suspended\",\n });\n\n return {\n success: true,\n data: updatedUser,\n };\n } catch (error) {\n console.error(\"Approval error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Approval failed\",\n });\n }\n }\n\n async listPendingUsers(\n request: FastifyRequest,\n reply: FastifyReply\n ) {\n try {\n const users = await this.userStore.getAllUsers();\n const pendingUsers = users.filter((u) => u.status === \"pending\");\n\n return {\n success: true,\n data: pendingUsers,\n };\n } catch (error) {\n console.error(\"List pending users error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to list pending users\",\n });\n }\n }\n\n async assignTenant(\n request: FastifyRequest<{ Body: AssignTenantRequest }>,\n reply: FastifyReply\n ) {\n const { userId, tenantId, role = \"member\" } = request.body;\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n const link = await this.userTenantLinkStore.createLink({\n userId,\n tenantId,\n role,\n });\n\n return {\n success: true,\n data: link,\n };\n } catch (error) {\n console.error(\"Assign tenant error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to assign tenant\",\n });\n }\n }\n\n private async hashPassword(password: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(password + \"salt\");\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n private async verifyPassword(password: string, hash: string): Promise<boolean> {\n const hashedPassword = await this.hashPassword(password);\n return hashedPassword === hash;\n }\n\n private async generateToken(userId: string, tenantId?: string): Promise<string> {\n const payload: any = {\n userId,\n exp: Date.now() + this.config.tokenExpiration * 1000,\n };\n if (tenantId) {\n payload.tenantId = tenantId;\n }\n return btoa(JSON.stringify(payload));\n }\n\n async changePassword(\n request: FastifyRequest<{ Body: ChangePasswordRequest }>,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n const { currentPassword, newPassword } = request.body;\n\n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n // Verify current password\n const isValidPassword = await this.verifyPassword(\n currentPassword,\n user.metadata?.passwordHash || \"\"\n );\n\n if (!isValidPassword) {\n return reply.status(401).send({\n success: false,\n error: \"Current password is incorrect\",\n });\n }\n\n // Validate new password length\n if (newPassword.length < 6) {\n return reply.status(400).send({\n success: false,\n error: \"New password must be at least 6 characters\",\n });\n }\n\n // Update password\n await this.userStore.updateUser(userId, {\n metadata: {\n ...user.metadata,\n passwordHash: await this.hashPassword(newPassword),\n },\n });\n\n return reply.send({\n success: true,\n message: \"Password changed successfully\",\n });\n } catch (error) {\n console.error(\"Change password error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to change password\",\n });\n }\n }\n}\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n config?: Partial<AuthConfig>\n) {\n const controller = new AuthController(config);\n\n const authHook = async (request: FastifyRequest, reply: FastifyReply) => {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith(\"Bearer \")) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Missing or invalid token\",\n });\n }\n\n const token = authHeader.substring(7);\n\n try {\n const payload = JSON.parse(atob(token));\n\n if (payload.exp && payload.exp < Date.now()) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Token expired\",\n });\n }\n\n (request as any).user = {\n id: payload.userId,\n tenantId: payload.tenantId,\n };\n } catch {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Invalid token\",\n });\n }\n };\n\n app.post(\"/api/auth/register\", controller.register.bind(controller));\n app.post(\"/api/auth/login\", controller.login.bind(controller));\n app.get(\"/api/auth/tenants\", { preHandler: authHook }, (req, res) => controller.getUserTenants(req, res));\n app.post(\"/api/auth/select-tenant\", { preHandler: authHook }, (req, res) => controller.selectTenant(req as any, res));\n app.post(\"/api/auth/approve\", { preHandler: authHook }, (req, res) => controller.approveUser(req as any, res));\n app.get(\"/api/auth/pending\", { preHandler: authHook }, (req, res) => controller.listPendingUsers(req, res));\n app.post(\"/api/auth/assign-tenant\", { preHandler: authHook }, (req, res) => controller.assignTenant(req as any, res));\n app.post(\"/api/auth/change-password\", { preHandler: authHook }, \n (req, res) => controller.changePassword(req as any, res)\n );\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport {\n ChannelIdentityMappingStore,\n PostgreSQLChannelInstallationStore,\n} from \"@axiom-lattice/pg-stores\";\nimport {\n createLarkEventHandler,\n type LarkEventHandlerDependencies,\n} from \"./controller\";\nimport {\n isLarkIngressEnabled,\n loadLarkIngressConfig,\n} from \"./config\";\nimport { createChannelThreadMappingService } from \"./mapping-service\";\nimport { parseLarkMessageEvent } from \"./parser\";\nimport { runAgentAndCollectLarkReply } from \"./runner\";\nimport { createLarkSender } from \"./sender\";\nimport { createLarkRequestVerifier, parseLarkRequestBody } from \"./verification\";\n\nexport function registerLarkChannelRoutes(\n app: FastifyInstance,\n dependencies?: LarkEventHandlerDependencies,\n): void {\n const config = loadLarkIngressConfig();\n if (!dependencies && !isLarkIngressEnabled(config)) {\n return;\n }\n const handlerDependencies = dependencies || createDefaultLarkDependencies();\n\n app.post(\n \"/api/channels/lark/installations/:installationId/events\",\n createLarkEventHandler({\n ...handlerDependencies,\n }),\n );\n}\n\nfunction createDefaultLarkDependencies(): LarkEventHandlerDependencies {\n const installationStore = new PostgreSQLChannelInstallationStore({\n poolConfig: getDatabaseUrl(),\n });\n const threadStore = getStoreLattice(\"default\", \"thread\").store;\n const mappingStore = new ChannelIdentityMappingStore({\n poolConfig: getDatabaseUrl(),\n });\n const mappingService = createChannelThreadMappingService({\n mappingStore,\n threadStore,\n });\n\n return {\n getInstallationConfig: async (installationId) => {\n const installation = await installationStore.getInstallationById(\n installationId,\n );\n\n if (!installation || installation.channel !== \"lark\") {\n return null;\n }\n\n return {\n enabled: true,\n installationId: installation.id,\n tenantId: installation.tenantId,\n assistantId: installation.config.assistantId,\n appId: installation.config.appId,\n appSecret: installation.config.appSecret,\n verificationToken: installation.config.verificationToken,\n encryptKey: installation.config.encryptKey,\n workspaceId: installation.config.workspaceId,\n projectId: installation.config.projectId,\n mappingMode: installation.config.mappingMode,\n };\n },\n parseRequestBody: (body, encryptKey) => parseLarkRequestBody(body, encryptKey),\n verifyParsedBody: (body, config) => {\n if (!config.verificationToken) {\n return true;\n }\n\n return createLarkRequestVerifier(config)({\n body,\n } as unknown as Parameters<ReturnType<typeof createLarkRequestVerifier>>[0]);\n },\n parseEvent: parseLarkMessageEvent,\n claimInboundReceipt: (input) => mappingStore.claimInboundReceipt(input),\n markInboundReceiptCompleted: (input) =>\n mappingStore.markInboundReceiptCompleted(input),\n markInboundReceiptFailed: (input) =>\n mappingStore.markInboundReceiptFailed(input),\n resolveThread: (input) => mappingService.getOrCreateThread(input),\n runAgentAndCollectText: ({ tenantId, assistantId, threadId, text, workspaceId, projectId }) =>\n runAgentAndCollectLarkReply({\n tenantId,\n assistantId,\n threadId,\n text,\n workspaceId,\n projectId,\n }),\n sendTextReply: async ({ chatId, text, config }) => {\n const sender = await createLarkSender({\n appId: config.appId,\n appSecret: config.appSecret,\n });\n\n await sender.sendTextReply({ chatId, text });\n },\n };\n}\n\nfunction getDatabaseUrl(): string {\n const databaseUrl = process.env.DATABASE_URL;\n\n if (!databaseUrl) {\n throw new Error(\"DATABASE_URL is required for Lark channel ingress\");\n }\n\n return databaseUrl;\n}\n","import type { ParsedLarkMessageEvent } from \"./types\";\n\ninterface RawLarkPayload {\n header?: {\n event_type?: string;\n };\n event?: {\n sender?: {\n sender_id?: {\n open_id?: string;\n };\n };\n message?: {\n message_id?: string;\n chat_id?: string;\n chat_type?: string;\n message_type?: string;\n content?: string;\n };\n };\n}\n\nexport function parseLarkMessageEvent(\n payload: unknown,\n): ParsedLarkMessageEvent | null {\n const raw = payload as RawLarkPayload;\n\n if (raw.header?.event_type !== \"im.message.receive_v1\") {\n return null;\n }\n\n const message = raw.event?.message;\n const openId = raw.event?.sender?.sender_id?.open_id;\n\n if (!message || !openId || message.message_type !== \"text\") {\n return null;\n }\n\n const parsedContent = parseLarkTextContent(message.content);\n if (!message.message_id || !message.chat_id || !parsedContent) {\n return null;\n }\n\n return {\n messageId: message.message_id,\n openId,\n chatId: message.chat_id,\n chatType: normalizeChatType(message.chat_type),\n text: parsedContent,\n };\n}\n\nfunction parseLarkTextContent(content: string | undefined): string | null {\n if (!content) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(content) as { text?: string };\n return typeof parsed.text === \"string\" ? parsed.text : null;\n } catch {\n return null;\n }\n}\n\nfunction normalizeChatType(chatType: string | undefined): \"direct\" | \"group\" {\n return chatType === \"p2p\" ? \"direct\" : \"group\";\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { parseLarkMessageEvent } from \"./parser\";\nimport type {\n LarkIngressConfig,\n LarkUrlVerificationPayload,\n ParsedLarkMessageEvent,\n} from \"./types\";\n\nexport interface LarkEventHandlerDependencies {\n getInstallationConfig: (\n installationId: string,\n ) => Promise<LarkIngressConfig | null>;\n parseRequestBody: (\n body: unknown,\n encryptKey?: string,\n ) => LarkUrlVerificationPayload;\n verifyParsedBody: (\n body: LarkUrlVerificationPayload,\n config: LarkIngressConfig,\n ) => boolean;\n parseEvent: (payload: unknown) => ParsedLarkMessageEvent | null;\n claimInboundReceipt: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }) => Promise<{ accepted: boolean; status: \"processing\" | \"completed\" }>;\n markInboundReceiptCompleted: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n threadId: string;\n }) => Promise<void>;\n markInboundReceiptFailed: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }) => Promise<void>;\n resolveThread: (input: {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n openId: string;\n chatId: string;\n chatType: \"direct\" | \"group\";\n messageId: string;\n workspaceId?: string;\n projectId?: string;\n }) => Promise<{ threadId: string }>;\n runAgentAndCollectText: (input: {\n tenantId: string;\n assistantId: string;\n threadId: string;\n text: string;\n workspaceId?: string;\n projectId?: string;\n }) => Promise<string>;\n sendTextReply: (input: {\n chatId: string;\n text: string;\n config: LarkIngressConfig;\n }) => Promise<void>;\n}\n\nexport function createLarkEventHandler(\n dependencies: LarkEventHandlerDependencies,\n) {\n return async function handleLarkEvent(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void> {\n const installationId = (request.params as { installationId?: string })\n ?.installationId;\n\n if (!installationId) {\n reply.status(400).send({ success: false, message: \"Missing installationId\" });\n return;\n }\n\n const config = await dependencies.getInstallationConfig(installationId);\n if (!config) {\n reply.status(404).send({ success: false, message: \"Lark installation not found\" });\n return;\n }\n\n const body = dependencies.parseRequestBody(\n request.body,\n config.encryptKey,\n ) as LarkUrlVerificationPayload;\n\n if (!dependencies.verifyParsedBody(body, config)) {\n reply.status(401).send({ success: false, message: \"Invalid Lark request\" });\n return;\n }\n\n if (body.type === \"url_verification\" && body.challenge) {\n reply.status(200).send({ challenge: body.challenge });\n return;\n }\n\n const parsed = dependencies.parseEvent(request.body);\n if (!parsed) {\n reply.status(200).send({ success: true, ignored: true });\n return;\n }\n\n const receipt = await dependencies.claimInboundReceipt({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n });\n\n if (!receipt.accepted) {\n reply.status(200).send(\n receipt.status === \"processing\"\n ? { success: true, processing: true }\n : { success: true, duplicate: true },\n );\n return;\n }\n\n try {\n const { threadId } = await dependencies.resolveThread({\n channel: \"lark\",\n channelAppId: config.appId,\n tenantId: config.tenantId,\n assistantId: config.assistantId,\n mappingMode: config.mappingMode,\n openId: parsed.openId,\n chatId: parsed.chatId,\n chatType: parsed.chatType,\n messageId: parsed.messageId,\n workspaceId: config.workspaceId,\n projectId: config.projectId,\n });\n\n const text = await dependencies.runAgentAndCollectText({\n tenantId: config.tenantId,\n assistantId: config.assistantId,\n threadId,\n text: parsed.text,\n workspaceId: config.workspaceId,\n projectId: config.projectId,\n });\n\n await dependencies.sendTextReply({\n chatId: parsed.chatId,\n text,\n config,\n });\n\n await dependencies.markInboundReceiptCompleted({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n threadId,\n });\n\n reply.status(200).send({ success: true, threadId });\n } catch (error) {\n await dependencies.markInboundReceiptFailed({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n });\n throw error;\n }\n };\n}\n\nexport const handleLarkEvent = createLarkEventHandler({\n getInstallationConfig: async () => null,\n parseRequestBody: (body) => (body || {}) as LarkUrlVerificationPayload,\n verifyParsedBody: () => true,\n parseEvent: parseLarkMessageEvent,\n claimInboundReceipt: async () => ({ accepted: true, status: \"processing\" }),\n markInboundReceiptCompleted: async () => undefined,\n markInboundReceiptFailed: async () => undefined,\n resolveThread: async () => ({ threadId: \"\" }),\n runAgentAndCollectText: async () => \"\",\n sendTextReply: async () => undefined,\n});\n","import type { LarkIngressConfig } from \"./types\";\n\nexport function loadLarkIngressConfig(): LarkIngressConfig {\n return {\n enabled: process.env.LARK_ENABLED !== \"false\",\n appId: process.env.LARK_APP_ID || \"\",\n appSecret: process.env.LARK_APP_SECRET || \"\",\n verificationToken: process.env.LARK_VERIFICATION_TOKEN,\n encryptKey: process.env.LARK_ENCRYPT_KEY,\n tenantId: process.env.LARK_TENANT_ID || \"default\",\n assistantId: process.env.LARK_ASSISTANT_ID || \"default_agent\",\n workspaceId: process.env.LARK_WORKSPACE_ID,\n projectId: process.env.LARK_PROJECT_ID,\n mappingMode:\n (process.env.LARK_MAPPING_MODE as \"user\" | \"group\" | \"hybrid\") ||\n \"hybrid\",\n };\n}\n\nexport function isLarkIngressEnabled(config: LarkIngressConfig): boolean {\n return config.enabled;\n}\n\nexport function assertLarkIngressConfig(config: LarkIngressConfig): void {\n if (!config.enabled) {\n return;\n }\n\n if (!config.appId) {\n throw new Error(\"LARK_APP_ID is required when Lark ingress is enabled\");\n }\n\n if (!config.appSecret) {\n throw new Error(\"LARK_APP_SECRET is required when Lark ingress is enabled\");\n }\n\n if (!config.tenantId) {\n throw new Error(\"LARK_TENANT_ID is required when Lark ingress is enabled\");\n }\n\n if (!config.assistantId) {\n throw new Error(\"LARK_ASSISTANT_ID is required when Lark ingress is enabled\");\n }\n}\n","import type { ThreadStore } from \"@axiom-lattice/protocols\";\nimport type { ChannelIdentityMappingStore } from \"@axiom-lattice/pg-stores\";\nimport { randomUUID } from \"crypto\";\n\ninterface GetOrCreateThreadInput {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n openId: string;\n chatId: string;\n chatType: \"direct\" | \"group\";\n messageId: string;\n workspaceId?: string;\n projectId?: string;\n}\n\ninterface ChannelThreadMappingServiceDeps {\n mappingStore: Pick<\n ChannelIdentityMappingStore,\n \"getMappingBySubject\" | \"createMapping\"\n >;\n threadStore: Pick<ThreadStore, \"createThread\" | \"deleteThread\">;\n uuid?: () => string;\n}\n\nexport function createChannelThreadMappingService(\n deps: ChannelThreadMappingServiceDeps,\n) {\n return {\n async getOrCreateThread(input: GetOrCreateThreadInput): Promise<{ threadId: string }> {\n const externalSubjectKey = buildExternalSubjectKey(input);\n const existing = await deps.mappingStore.getMappingBySubject({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n externalSubjectKey,\n });\n\n if (existing) {\n return { threadId: existing.threadId };\n }\n\n const threadId = (deps.uuid || randomUUID)();\n\n await deps.threadStore.createThread(input.tenantId, input.assistantId, threadId, {\n metadata: {\n tenantId: input.tenantId,\n workspaceId: input.workspaceId,\n projectId: input.projectId,\n channel: input.channel,\n larkChatId: input.chatId,\n larkOpenId: input.openId,\n },\n });\n\n try {\n await deps.mappingStore.createMapping({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n mappingMode: input.mappingMode,\n externalSubjectType:\n resolveSubjectType(input.mappingMode, input.chatType) === \"user\"\n ? \"user\"\n : \"chat\",\n externalSubjectKey,\n larkOpenId: input.openId,\n larkChatId: input.chatId,\n larkMessageId: input.messageId,\n threadId,\n });\n } catch (error) {\n if (!isUniqueViolation(error)) {\n throw error;\n }\n\n const canonical = await deps.mappingStore.getMappingBySubject({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n externalSubjectKey,\n });\n\n if (!canonical) {\n throw error;\n }\n\n await deps.threadStore.deleteThread(input.tenantId, threadId);\n\n return { threadId: canonical.threadId };\n }\n\n return { threadId };\n },\n };\n}\n\nfunction isUniqueViolation(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"23505\"\n );\n}\n\nfunction buildExternalSubjectKey(input: GetOrCreateThreadInput): string {\n const subjectType = resolveSubjectType(input.mappingMode, input.chatType);\n const subjectValue = subjectType === \"user\" ? input.openId : input.chatId;\n\n return [\n input.channel,\n input.channelAppId,\n `tenant:${input.tenantId}`,\n `assistant:${input.assistantId}`,\n `${subjectType}:${subjectValue}`,\n ].join(\":\");\n}\n\nfunction resolveSubjectType(\n mappingMode: \"user\" | \"group\" | \"hybrid\",\n chatType: \"direct\" | \"group\",\n): \"user\" | \"chat\" {\n if (mappingMode === \"user\") {\n return \"user\";\n }\n\n if (mappingMode === \"group\") {\n return \"chat\";\n }\n\n return chatType === \"direct\" ? \"user\" : \"chat\";\n}\n","import { agentInstanceManager } from \"@axiom-lattice/core\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\nimport { aggregateLarkReply } from \"./aggregator\";\n\nexport async function runAgentAndCollectLarkReply(input: {\n tenantId: string;\n assistantId: string;\n threadId: string;\n text: string;\n workspaceId?: string;\n projectId?: string;\n}): Promise<string> {\n const agent = agentInstanceManager.getAgent({\n tenant_id: input.tenantId,\n assistant_id: input.assistantId,\n thread_id: input.threadId,\n workspace_id: input.workspaceId,\n project_id: input.projectId,\n });\n\n const result = await agent.addMessage({\n input: {\n message: input.text,\n },\n });\n\n const chunks = [];\n const stream = agent.chunkStream(result.messageId, [\n MessageChunkTypes.MESSAGE_COMPLETED,\n ]);\n\n for await (const chunk of stream) {\n chunks.push(chunk);\n }\n\n return aggregateLarkReply(result.messageId, chunks);\n}\n","import type { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\n\nexport function aggregateLarkReply(\n messageId: string,\n chunks: MessageChunk[],\n): string {\n return chunks\n .filter(\n (chunk) =>\n chunk.type === MessageChunkTypes.AI && chunk.data.id === messageId,\n )\n .map((chunk) => chunk.data.content || \"\")\n .join(\"\")\n .trim();\n}\n","interface LarkSenderConfig {\n appId: string;\n appSecret: string;\n}\n\ninterface LarkSdkMessageClient {\n im: {\n v1: {\n message: {\n create(input: {\n params: {\n receive_id_type: \"chat_id\";\n };\n data: {\n receive_id: string;\n msg_type: \"text\";\n content: string;\n };\n }): Promise<{ code?: number }>;\n };\n };\n };\n}\n\nexport async function createLarkSender(\n config: LarkSenderConfig,\n client?: LarkSdkMessageClient,\n) {\n const resolved = client ?? (await createDefaultLarkClient(config));\n\n return {\n async sendTextReply(input: { chatId: string; text: string }): Promise<void> {\n const response = await resolved.im.v1.message.create({\n params: {\n receive_id_type: \"chat_id\",\n },\n data: {\n receive_id: input.chatId,\n msg_type: \"text\",\n content: JSON.stringify({ text: input.text }),\n },\n });\n\n if (response.code && response.code !== 0) {\n throw new Error(\"Failed to send Lark reply\");\n }\n },\n };\n}\n\nasync function createDefaultLarkClient(config: LarkSenderConfig): Promise<LarkSdkMessageClient> {\n const Lark = await import(\"@larksuiteoapi/node-sdk\");\n\n return new Lark.Client({\n appId: config.appId,\n appSecret: config.appSecret,\n }) as LarkSdkMessageClient;\n}\n","import crypto from \"crypto\";\nimport type { FastifyRequest } from \"fastify\";\nimport type { LarkIngressConfig, LarkUrlVerificationPayload } from \"./types\";\n\nexport function parseLarkRequestBody(\n body: unknown,\n encryptKey?: string,\n): LarkUrlVerificationPayload {\n const parsed = (body || {}) as LarkUrlVerificationPayload;\n\n if (encryptKey && typeof parsed.encrypt === \"string\") {\n return decryptLarkPayload(encryptKey, parsed.encrypt);\n }\n\n return parsed;\n}\n\nexport function decryptLarkPayload(\n encryptKey: string,\n encryptedPayload: string,\n): LarkUrlVerificationPayload {\n const key = crypto.createHash(\"sha256\").update(encryptKey).digest();\n const buffer = Buffer.from(encryptedPayload, \"base64\");\n const iv = buffer.subarray(0, 16);\n const ciphertext = buffer.subarray(16);\n const decipher = crypto.createDecipheriv(\"aes-256-cbc\", key, iv);\n const plaintext = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf8\");\n\n return JSON.parse(plaintext) as LarkUrlVerificationPayload;\n}\n\nexport function createLarkRequestVerifier(config: LarkIngressConfig) {\n return function verifyRequest(request: FastifyRequest): boolean {\n const body = parseLarkRequestBody(request.body, config.encryptKey);\n\n return verifyLarkParsedBody(body, config);\n };\n}\n\nexport function verifyLarkParsedBody(\n body: LarkUrlVerificationPayload,\n config: LarkIngressConfig,\n): boolean {\n \n if (!config.verificationToken) {\n return true;\n }\n\n return extractVerificationToken(body) === config.verificationToken;\n}\n\nfunction extractVerificationToken(\n body: LarkUrlVerificationPayload,\n): string | undefined {\n if (typeof body.token === \"string\") {\n return body.token;\n }\n\n if (typeof body.header?.token === \"string\") {\n return body.header.token;\n }\n\n return undefined;\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { LarkEventHandlerDependencies } from \"./lark/controller\";\nimport { registerLarkChannelRoutes } from \"./lark/routes\";\n\ninterface ChannelRouteDependencies {\n lark?: LarkEventHandlerDependencies;\n}\n\ntype ChannelRouteRegistrar = (\n app: FastifyInstance,\n dependencies: ChannelRouteDependencies,\n) => void;\n\nconst channelRouteRegistrars: ChannelRouteRegistrar[] = [\n (app, dependencies) => registerLarkChannelRoutes(app, dependencies.lark),\n];\n\nexport function registerChannelRoutes(\n app: FastifyInstance,\n dependencies: ChannelRouteDependencies = {},\n): void {\n for (const registerRoutes of channelRouteRegistrars) {\n registerRoutes(app, dependencies);\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { randomUUID } from \"crypto\";\nimport {\n ChannelInstallationStore,\n ChannelInstallation,\n CreateChannelInstallationRequest,\n UpdateChannelInstallationRequest,\n ChannelInstallationType,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Channel Installation Controller\n * Handles channel installation CRUD operations for Lark/Feishu and future channels\n * All operations are scoped to a tenant ID\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Channel installation list response\n */\ninterface ChannelInstallationListResponse {\n success: boolean;\n message: string;\n data: {\n records: ChannelInstallation[];\n total: number;\n };\n}\n\n/**\n * Channel installation response\n */\ninterface ChannelInstallationResponse {\n success: boolean;\n message: string;\n data?: ChannelInstallation;\n}\n\n/**\n * Get channel installation store\n */\nasync function getInstallationStore(): Promise<ChannelInstallationStore> {\n // Import dynamically to avoid circular dependencies\n const { PostgreSQLChannelInstallationStore } = await import(\"@axiom-lattice/pg-stores\");\n const databaseUrl = process.env.DATABASE_URL;\n \n if (!databaseUrl) {\n throw new Error(\"DATABASE_URL is required for channel installation store\");\n }\n \n return new PostgreSQLChannelInstallationStore({\n poolConfig: databaseUrl,\n });\n}\n\n/**\n * Get all channel installations for a tenant\n */\nexport async function getChannelInstallationList(\n request: FastifyRequest<{\n Querystring: { channel?: ChannelInstallationType };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationListResponse> {\n const tenantId = getTenantId(request);\n const { channel } = request.query;\n\n try {\n const store = await getInstallationStore();\n const installations = await store.getInstallationsByTenant(tenantId, channel);\n\n return {\n success: true,\n message: \"Channel installations retrieved successfully\",\n data: {\n records: installations,\n total: installations.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get channel installations:\", error);\n return {\n success: false,\n message: \"Failed to retrieve channel installations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get a single channel installation by ID\n */\nexport async function getChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n\n try {\n const store = await getInstallationStore();\n const installation = await store.getInstallationById(installationId);\n\n if (!installation) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n // Verify tenant access\n if (installation.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation retrieved successfully\",\n data: installation,\n };\n } catch (error) {\n console.error(\"Failed to get channel installation:\", error);\n return {\n success: false,\n message: \"Failed to retrieve channel installation\",\n };\n }\n}\n\n/**\n * Create new channel installation\n */\nexport async function createChannelInstallation(\n request: FastifyRequest<{\n Body: CreateChannelInstallationRequest & { id?: string };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const body = request.body;\n\n try {\n // Validate required fields\n if (!body.channel) {\n reply.code(400);\n return {\n success: false,\n message: \"Channel type is required\",\n };\n }\n\n if (!body.config) {\n reply.code(400);\n return {\n success: false,\n message: \"Configuration is required\",\n };\n }\n\n // Validate Lark-specific config\n if (body.channel === \"lark\") {\n const larkConfig = body.config;\n if (!larkConfig.appId || !larkConfig.appSecret) {\n reply.code(400);\n return {\n success: false,\n message: \"appId and appSecret are required for Lark installations\",\n };\n }\n if (!larkConfig.assistantId) {\n reply.code(400);\n return {\n success: false,\n message: \"assistantId is required for Lark installations\",\n };\n }\n }\n\n const store = await getInstallationStore();\n const installationId = body.id || randomUUID();\n \n const installation = await store.createInstallation(\n tenantId,\n installationId,\n body,\n );\n\n reply.code(201);\n return {\n success: true,\n message: \"Channel installation created successfully\",\n data: installation,\n };\n } catch (error: any) {\n console.error(\"Failed to create channel installation:\", error);\n \n // Check for duplicate key error\n if (error.message?.includes(\"duplicate\") || error.code === \"23505\") {\n reply.code(409);\n return {\n success: false,\n message: \"Channel installation with this ID already exists\",\n };\n }\n\n return {\n success: false,\n message: \"Failed to create channel installation\",\n };\n }\n}\n\n/**\n * Update channel installation\n */\nexport async function updateChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n Body: UpdateChannelInstallationRequest;\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n const body = request.body;\n\n try {\n const store = await getInstallationStore();\n\n // Verify installation exists and belongs to tenant\n const existing = await store.getInstallationById(installationId);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n if (existing.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n const installation = await store.updateInstallation(\n tenantId,\n installationId,\n body,\n );\n\n if (!installation) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation updated successfully\",\n data: installation,\n };\n } catch (error) {\n console.error(\"Failed to update channel installation:\", error);\n return {\n success: false,\n message: \"Failed to update channel installation\",\n };\n }\n}\n\n/**\n * Delete channel installation\n */\nexport async function deleteChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n }>,\n reply: FastifyReply,\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n\n try {\n const store = await getInstallationStore();\n\n // Verify installation exists and belongs to tenant\n const existing = await store.getInstallationById(installationId);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n if (existing.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n const deleted = await store.deleteInstallation(tenantId, installationId);\n\n if (!deleted) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete channel installation:\", error);\n return {\n success: false,\n message: \"Failed to delete channel installation\",\n };\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport * as channelInstallationController from \"../controllers/channel-installations\";\n\n/**\n * Register channel installation management routes\n */\nexport function registerChannelInstallationRoutes(app: FastifyInstance): void {\n // List all installations for current tenant\n app.get<{\n Querystring: { channel?: \"lark\" };\n }>(\"/api/channel-installations\", channelInstallationController.getChannelInstallationList);\n\n // Get single installation by ID\n app.get<{\n Params: { installationId: string };\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.getChannelInstallation);\n\n // Create new installation\n app.post<{\n Body: any;\n }>(\"/api/channel-installations\", channelInstallationController.createChannelInstallation);\n\n // Update installation\n app.put<{\n Params: { installationId: string };\n Body: any;\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.updateChannelInstallation);\n\n // Delete installation\n app.delete<{\n Params: { installationId: string };\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.deleteChannelInstallation);\n}\n","import { FastifyInstance } from \"fastify\";\nimport { ScheduledTaskStatus } from \"@axiom-lattice/protocols\";\nimport * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport * as agentTaskController from \"../controllers/agent_task\";\nimport * as threadsController from \"../controllers/threads\";\nimport * as schedulesController from \"../controllers/schedules\";\nimport * as configController from \"../controllers/config\";\nimport * as modelsController from \"../controllers/models\";\nimport * as healthController from \"../controllers/health\";\nimport * as skillsController from \"../controllers/skills\";\nimport * as toolsController from \"../controllers/tools\";\nimport * as dataQueryController from \"../controllers/data-query\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n triggerAgentTaskSchema,\n updateConfigSchema,\n getConfigSchema,\n getHealthSchema,\n getSandboxUrlSchema,\n dataQuerySchema,\n} from \"../schemas\";\nimport { removePendingMessageHandler } from \"../controllers/thread_status\";\nimport { registerSandboxProxyRoutes } from \"../controllers/sandbox\";\nimport { registerWorkspaceRoutes } from \"../controllers/workspace\";\nimport { registerDatabaseConfigRoutes } from \"../controllers/database-configs\";\nimport { registerMetricsServerConfigRoutes } from \"../controllers/metrics-configs\";\nimport { registerMcpServerConfigRoutes } from \"../controllers/mcp-configs\";\nimport { registerUserRoutes } from \"../controllers/users\";\nimport { registerTenantRoutes } from \"../controllers/tenants\";\nimport { registerAuthRoutes } from \"../controllers/auth\";\nimport { registerChannelRoutes } from \"../channels/routes\";\nimport { registerChannelInstallationRoutes } from \"./channel-installations\";\n// import {\n// getThreadStatusHandler,\n// getAgentThreadsHandler,\n// getActiveThreadsHandler,\n// addMessageHandler,\n// removeMessageHandler,\n// updateQueueConfigHandler,\n// } from \"../controllers/thread_status\";\n\nexport const registerLatticeRoutes = (app: FastifyInstance): void => {\n // 运行路由\n app.post<{\n Body: any;\n }>(\"/api/runs\", runController.createRun);\n\n // Resume stream route\n app.post<{\n Body: any;\n }>(\"/api/resume_stream\", runController.resumeStream);\n\n // Abort agent execution for a thread\n app.post<{\n Params: { assistantId: string; threadId: string };\n }>(\"/api/assistants/:assistantId/threads/:threadId/abort\", runController.abortRun);\n\n // app.get<{\n // Params: { id: string };\n // }>(\"/api/runs/:id\", runController.getRun);\n\n // app.get<{\n // Params: { assistantId: string };\n // }>(\"/api/assistants/:assistantId/runs\", runController.getRunsByAssistant);\n\n // app.post<{\n // Params: { id: string };\n // }>(\"/api/runs/:id/cancel\", runController.cancelRun);\n\n // 内存路由\n app.get<{\n Params: { assistantId: string; thread_id: string };\n }>(\n \"/api/assistants/:assistantId/:thread_id/memory\",\n { schema: getAllMemoryItemsSchema },\n memoryController.getAllMemoryItems\n );\n\n app.get<{\n Params: { assistantId: string; thread_id: string };\n }>(\n \"/api/assistants/:assistantId/:thread_id/state\",\n { schema: getAgentStateSchema },\n memoryController.getAgentState\n );\n\n app.get<{\n Params: { assistantId: string; key: string };\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: getMemoryItemSchema },\n memoryController.getMemoryItem\n );\n\n app.put<{\n Params: { assistantId: string; key: string };\n Body: any;\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: setMemoryItemSchema },\n memoryController.setMemoryItem\n );\n\n app.delete<{\n Params: { assistantId: string; key: string };\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: deleteMemoryItemSchema },\n memoryController.deleteMemoryItem\n );\n\n app.delete<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/memory\",\n { schema: clearMemorySchema },\n memoryController.clearMemory\n );\n\n // Assistant CRUD routes\n app.get(\"/api/assistants\", assistantController.getAssistantList);\n\n app.get<{\n Params: { id: string };\n }>(\"/api/assistants/:id\", assistantController.getAssistant);\n\n app.post<{\n Body: any;\n }>(\"/api/assistants\", assistantController.createAssistant);\n\n app.put<{\n Params: { id: string };\n Body: any;\n }>(\"/api/assistants/:id\", assistantController.updateAssistant);\n\n app.delete<{\n Params: { id: string };\n }>(\"/api/assistants/:id\", assistantController.deleteAssistant);\n\n // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n\n // Agent Task路由\n app.post<{\n Body: any;\n }>(\n \"/api/agent-tasks/trigger\",\n { schema: triggerAgentTaskSchema },\n agentTaskController.triggerAgentTask\n );\n\n // Thread CRUD routes for a specific assistant\n app.get<{\n Params: { assistantId: string };\n }>(\"/api/assistants/:assistantId/threads\", threadsController.getThreadList);\n\n app.get<{\n Params: { assistantId: string; threadId: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.getThread\n );\n\n app.post<{\n Params: { assistantId: string };\n Body: any;\n }>(\"/api/assistants/:assistantId/threads\", threadsController.createThread);\n\n app.put<{\n Params: { assistantId: string; threadId: string };\n Body: any;\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.updateThread\n );\n\n app.delete<{\n Params: { assistantId: string; threadId: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.deleteThread\n );\n\n // Configuration routes\n app.get(\n \"/api/config\",\n { schema: getConfigSchema },\n configController.getConfig\n );\n\n app.put<{\n Body: { config: Record<string, any> };\n }>(\n \"/api/config\",\n { schema: updateConfigSchema },\n configController.updateConfig\n );\n\n // Models routes\n app.get(\"/api/models\", modelsController.getModels);\n\n app.put<{\n Body: { models: any[] };\n }>(\"/api/models\", modelsController.updateModels);\n\n // Tools config meta route\n app.get(\"/api/tools\", toolsController.getToolConfigs);\n\n // Health check route\n app.get(\n \"/health\",\n { schema: getHealthSchema },\n healthController.getHealth\n );\n\n // Schedule routes for viewing scheduled tasks by thread\n app.get<{\n Params: { assistantId: string; threadId: string };\n Querystring: {\n status?: ScheduledTaskStatus;\n limit?: string;\n offset?: string;\n };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId/schedules\",\n schedulesController.getThreadSchedules\n );\n\n // Get a specific scheduled task\n app.get<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId\", schedulesController.getScheduledTask);\n\n // Cancel a scheduled task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/cancel\", schedulesController.cancelScheduledTask);\n\n // Pause a scheduled cron task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/pause\", schedulesController.pauseScheduledTask);\n\n // Resume a paused cron task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/resume\", schedulesController.resumeScheduledTask);\n\n // Skills CRUD routes\n app.get(\"/api/skills\", skillsController.getSkillList);\n\n app.get<{\n Params: { id: string };\n }>(\n \"/api/skills/:id\",\n skillsController.getSkill\n );\n\n app.post<{\n Body: any;\n }>(\n \"/api/skills\",\n skillsController.createSkill\n );\n\n app.put<{\n Params: { id: string };\n Body: any;\n }>(\n \"/api/skills/:id\",\n skillsController.updateSkill\n );\n\n app.delete<{\n Params: { id: string };\n }>(\n \"/api/skills/:id\",\n skillsController.deleteSkill\n );\n\n // Skills search and filter routes\n app.get<{\n Querystring: { key: string; value: string };\n }>(\n \"/api/skills/search/metadata\",\n skillsController.searchSkillsByMetadata\n );\n\n app.get<{\n Querystring: { compatibility: string };\n }>(\n \"/api/skills/filter/compatibility\",\n skillsController.filterSkillsByCompatibility\n );\n\n app.get<{\n Querystring: { license: string };\n }>(\n \"/api/skills/filter/license\",\n skillsController.filterSkillsByLicense\n );\n\n registerSandboxProxyRoutes(app);\n\n registerWorkspaceRoutes(app);\n\n registerDatabaseConfigRoutes(app);\n\n registerMetricsServerConfigRoutes(app);\n\n // Data query route\n app.post<{\n Body: any;\n }>(\n \"/api/data/query\",\n { schema: dataQuerySchema },\n dataQueryController.executeDataQuery\n );\n\n registerMcpServerConfigRoutes(app);\n\n registerUserRoutes(app);\n\n registerTenantRoutes(app);\n\n registerAuthRoutes(app, {\n autoApproveUsers: process.env.AUTO_APPROVE_USERS !== \"false\",\n allowTenantRegistration: process.env.ALLOW_TENANT_REGISTRATION !== \"false\",\n });\n\n registerChannelRoutes(app);\n\n registerChannelInstallationRoutes(app);\n\n // // Thread 状态查询路由\n // app.get(\"/api/threads/:thread_id/status\", getThreadStatusHandler);\n // app.get(\"/api/assistants/:assistant_id/threads/status\", getAgentThreadsHandler);\n // app.get(\"/api/threads/active\", getActiveThreadsHandler);\n\n // // Thread 消息队列路由\n // app.post(\"/api/threads/:thread_id/messages\", addMessageHandler);\n // app.delete(\"/api/threads/:thread_id/messages/:message_id\", removeMessageHandler);\n // app.put(\"/api/threads/:thread_id/queue-config\", updateQueueConfigHandler);\n\n // Delete pending message route\n app.delete<{\n Params: { assistant_id: string; thread_id: string; message_id: string };\n }>(\n \"/api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id\",\n removePendingMessageHandler\n );\n};\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n","import { eventBus, AGENT_TASK_EVENT, agentInstanceManager, QueueMode } from \"@axiom-lattice/core\";\nimport { popAgentTaskFromQueue } from \"./queue_service\";\n\n// 任务请求结构\nexport interface AgentTaskRequest {\n assistant_id: string;\n input: any;\n thread_id: string;\n \"x-tenant-id\": string;\n command?: any;\n callback_event?: string; // 可选的回调事件名称\n runConfig?: Record<string, any>; // RunConfig for subagent execution\n}\n\n/**\n * 处理Agent任务事件\n * @param taskRequest 任务请求\n * @param retryCount 重试次数\n */\nconst handleAgentTask = async (\n taskRequest: AgentTaskRequest,\n retryCount: number = 0\n): Promise<boolean> => {\n const {\n assistant_id,\n input = {},\n thread_id,\n \"x-tenant-id\": tenant_id,\n command,\n callback_event,\n runConfig,\n } = taskRequest;\n\n\n try {\n console.log(\n `开始处理任务 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n\n // 检查API服务器是否可用\n // const apiUrl = AgentTaskConsumer.agent_run_endpoint;\n\n // console.log(`apiUrl: ${apiUrl}`);\n const agent = agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig })\n await agent.addMessage({ input, command, custom_run_config: runConfig }, QueueMode.STEER);\n if (callback_event) {\n agent.subscribeOnce(\"message:completed\", (evt) => {\n eventBus.publish(callback_event, {\n success: true,\n state: evt.state,\n config: { assistant_id, thread_id, tenant_id },\n });\n })\n agent.subscribeOnce(\"message:interrupted\", (evt) => {\n eventBus.publish(callback_event, {\n success: true,\n state: evt.state,\n config: { assistant_id, thread_id, tenant_id },\n });\n })\n }\n\n return true;\n\n\n\n } catch (error) {\n console.error(\n `Agent任务执行失败: ${assistant_id}, 线程: ${thread_id}`,\n error\n );\n\n // 重试逻辑,暂不用重试\n const maxRetries = 0;\n if (retryCount < maxRetries) {\n const nextRetryCount = retryCount + 1;\n const delayMs = Math.pow(2, nextRetryCount) * 1000; // 指数退避策略\n\n console.log(\n `将在 ${delayMs}ms 后重试任务 (${nextRetryCount}/${maxRetries})`\n );\n\n // 延迟后重试\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n return handleAgentTask(taskRequest, nextRetryCount);\n }\n\n if (callback_event) {\n eventBus.publish(callback_event, {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.error(\n `任务处理失败,已达到最大重试次数 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return false;\n }\n};\n\n/**\n * Agent任务消费者\n * 负责监听和执行Agent任务事件,同时从队列中消费任务\n */\nexport class AgentTaskConsumer {\n private isPolling: boolean = false;\n private pollingInterval: NodeJS.Timeout | null = null;\n private pollingIntervalMs: number = 5000; // 默认5秒轮询一次\n private maxConcurrentTasks: number = 15; // 最大并发任务数\n private activeTasks: number = 0; // 当前活跃的任务数\n private processing: boolean = false; // 是否正在处理任务批次\n private immediateProcessingEnabled: boolean = true; // 是否启用即时处理模式\n public gatewayPort: number = 4001;\n public static agent_run_endpoint: string = \"http://localhost:4001/api/runs\";\n\n constructor(gatewayPort: number, pollingIntervalMs?: number) {\n this.gatewayPort = gatewayPort;\n AgentTaskConsumer.agent_run_endpoint = `http://localhost:${this.gatewayPort}/api/runs`;\n if (pollingIntervalMs) {\n this.pollingIntervalMs = pollingIntervalMs;\n }\n this.initialize();\n }\n\n /**\n * 初始化事件监听和队列轮询\n */\n private initialize(): void {\n // 监听事件总线上的任务\n eventBus.subscribe(AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));\n\n // 启动队列轮询\n this.startPollingQueue();\n\n console.log(\"Agent任务消费者已启动并监听任务事件和队列\");\n }\n\n /**\n * 启动队列轮询\n */\n startPollingQueue(): void {\n if (this.isPolling) {\n return;\n }\n\n this.isPolling = true;\n\n this.pollingInterval = setInterval(async () => {\n try {\n // 如果上一批次任务还在处理中,跳过本次轮询\n if (this.processing) {\n console.log(\"队列处理中,跳过本次轮询\");\n return;\n }\n\n await this.consumeFromQueue();\n } catch (error) {\n console.error(\"队列轮询出错:\", error);\n }\n }, this.pollingIntervalMs);\n\n console.log(\n `开始轮询队列,间隔: ${this.pollingIntervalMs}ms,最大并发任务数: ${this.maxConcurrentTasks}`\n );\n }\n\n /**\n * 停止队列轮询\n */\n stopPollingQueue(): void {\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = null;\n this.isPolling = false;\n console.log(\"已停止队列轮询\");\n }\n }\n\n /**\n * 处理单个任务并在完成后立即尝试处理下一个\n */\n async processNextTask(): Promise<boolean> {\n try {\n // 从队列中获取任务\n const queueResult = await popAgentTaskFromQueue();\n\n // 检查队列结果\n if (queueResult && queueResult.data) {\n const taskItem = queueResult.data;\n\n if (taskItem && typeof taskItem === \"object\") {\n const taskRequest = taskItem as AgentTaskRequest;\n\n console.log(\n `从队列中获取到任务 [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`\n );\n\n // 增加活跃任务计数\n this.activeTasks++;\n\n // 处理任务(不使用await,允许并发执行)\n handleAgentTask(taskRequest)\n .then((success) => {\n if (!success) {\n console.error(`任务 处理失败`);\n // 可以在这里记录失败任务或执行补偿逻辑\n } else {\n console.log(`任务 处理成功`);\n }\n })\n .catch((error) => {\n console.error(`任务 处理时出错:`, error);\n })\n .finally(() => {\n // 减少活跃任务计数\n this.activeTasks--;\n\n // 如果启用了即时处理模式,尝试处理更多任务\n if (this.immediateProcessingEnabled && !this.processing) {\n this.checkQueueForTasks();\n }\n });\n\n // 任务已派发,返回true表示有任务被处理\n return true;\n } else {\n console.log(\"队列任务格式无效:\", taskItem);\n return false;\n }\n } else {\n // 队列为空\n return false;\n }\n } catch (error) {\n console.error(\"处理任务失败:\", error);\n return false;\n }\n }\n\n /**\n * 检查队列中是否有任务并处理\n */\n async checkQueueForTasks(): Promise<void> {\n // 如果已经在处理中或者并发任务已达上限,则不处理\n if (this.processing || this.activeTasks >= this.maxConcurrentTasks) {\n return;\n }\n\n this.processing = true;\n\n try {\n // 尝试获取并处理任务,直到达到并发上限\n while (this.activeTasks < this.maxConcurrentTasks) {\n const taskProcessed = await this.processNextTask();\n if (!taskProcessed) {\n // 没有更多任务,退出循环\n break;\n }\n }\n } catch (error) {\n console.error(\"检查队列任务失败:\", error);\n } finally {\n this.processing = false;\n }\n }\n\n /**\n * 从队列中消费任务\n */\n async consumeFromQueue(): Promise<void> {\n // 如果已经在处理中,跳过\n if (this.processing) {\n return;\n }\n\n // 调用任务检查方法\n await this.checkQueueForTasks();\n }\n\n /**\n * 处理通过事件触发的任务\n */\n trigger_agent_task(taskRequest: AgentTaskRequest): void {\n console.log(\n `通过事件触发任务: [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`\n );\n\n // 处理任务,不阻塞事件处理流程\n handleAgentTask(taskRequest).catch((error) => {\n console.error(\"处理Agent任务时发生未捕获的错误:\", error);\n\n // 如果有回调事件,确保即使发生错误也能通知\n if (taskRequest.callback_event) {\n eventBus.publish(taskRequest.callback_event, {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n config: {\n assistant_id: taskRequest.assistant_id,\n thread_id: taskRequest.thread_id,\n tenant_id: taskRequest[\"x-tenant-id\"],\n },\n });\n }\n });\n\n // 如果启用了即时处理且当前活跃任务数低于阈值,检查队列\n if (\n this.immediateProcessingEnabled &&\n this.activeTasks < this.maxConcurrentTasks\n ) {\n setImmediate(() => this.checkQueueForTasks());\n }\n }\n}\n"],"mappings":"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","names":["import_core","exists","import_core","import_core","import_core","import_core","import_crypto","getTenantId","import_core","getTenantId","import_core","import_protocols","import_core","import_core","getTenantId","import_core","import_core","getTenantId","import_core","import_core","import_core","path","app","import_core","import_uuid","uuidv4","filename","content","path","result","stat","app","import_core","import_crypto","getTenantId","app","import_core","import_crypto","getTenantId","app","import_core","import_crypto","getTenantId","app","import_core","import_uuid","uuidv4","app","import_core","import_uuid","uuidv4","app","import_core","import_uuid","uuidv4","app","import_core","handleLarkEvent","import_crypto","import_core","import_protocols","import_protocols","import_crypto","crypto","app","app","import_crypto","getTenantId","PostgreSQLChannelInstallationStore","app","app","app","swagger","swaggerUi","import_core","import_core","import_protocols","fastify","cors","sensible","multipart","websocket","path","staticPlugin"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/controllers/assistant.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/agent_task.ts","../src/controllers/threads.ts","../src/controllers/schedules.ts","../src/config.ts","../src/services/queue_service.ts","../src/controllers/config.ts","../src/controllers/models.ts","../src/controllers/health.ts","../src/services/skill_service.ts","../src/controllers/skills.ts","../src/controllers/tools.ts","../src/controllers/data-query.ts","../src/controllers/workflow-tracking.ts","../src/schemas/data-query.ts","../src/schemas/index.ts","../src/controllers/thread_status.ts","../src/services/sandbox_service.ts","../src/controllers/sandbox.ts","../src/controllers/workspace.ts","../src/controllers/database-configs.ts","../src/controllers/metrics-configs.ts","../src/controllers/mcp-configs.ts","../src/controllers/users.ts","../src/controllers/tenants.ts","../src/controllers/auth.ts","../src/channels/lark/routes.ts","../src/channels/lark/parser.ts","../src/channels/lark/controller.ts","../src/channels/lark/config.ts","../src/channels/lark/mapping-service.ts","../src/channels/lark/runner.ts","../src/channels/lark/aggregator.ts","../src/channels/lark/sender.ts","../src/channels/lark/verification.ts","../src/channels/routes.ts","../src/controllers/channel-installations.ts","../src/routes/channel-installations.ts","../src/routes/index.ts","../src/swagger.ts","../src/services/agent_task_consumer.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport websocket from \"@fastify/websocket\";\nimport staticPlugin from \"@fastify/static\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { registerLatticeRoutes } from \"./routes\";\nimport { configureSwagger } from \"./swagger\";\nimport {\n setQueueServiceType,\n QueueServiceType,\n} from \"./services/queue_service\";\nimport { AgentTaskConsumer } from \"./services/agent_task_consumer\";\nimport {\n registerLoggerLattice,\n getLoggerLattice,\n loggerLatticeManager,\n sandboxLatticeManager,\n sqlDatabaseManager,\n getStoreLattice,\n storeLatticeManager,\n agentInstanceManager,\n createSandboxProvider,\n type CreateSandboxProviderConfig,\n} from \"@axiom-lattice/core\";\nimport type { DatabaseConfigStore } from \"@axiom-lattice/protocols\";\nimport {\n LoggerType,\n LoggerConfig,\n PinoFileOptions,\n} from \"@axiom-lattice/protocols\";\n\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// Default logger configuration\nconst DEFAULT_LOGGER_CONFIG: LoggerConfig = {\n name: \"default\",\n description: \"Default logger for lattice-gateway service\",\n type: LoggerType.PINO,\n serviceName: \"lattice/gateway\",\n loggerName: \"lattice/gateway\",\n};\n\n// Initialize logger with default config (can be overridden in start function)\nlet loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);\nlet logger = loggerLattice.client;\n\n/**\n * Initialize logger lattice with given configuration\n */\nfunction initializeLogger(config: LoggerConfig) {\n // Remove existing logger if it exists\n if (loggerLatticeManager.hasLattice(\"default\")) {\n loggerLatticeManager.removeLattice(\"default\");\n }\n\n // Register logger with provided config\n registerLoggerLattice(\"default\", config);\n\n // Get and return logger lattice instance\n return getLoggerLattice(\"default\");\n}\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n bodyLimit: Number(process.env.BODY_LIMIT) || 50 * 1024 * 1024, // Default 50MB, configurable via BODY_LIMIT env var\n});\n\n// Custom content type parser to handle DELETE requests with Content-Type but no body\n// This prevents \"Body cannot be empty when content-type is set to 'application/json'\" error\napp.addContentTypeParser('application/json', { parseAs: 'string' }, function (request, body, done) {\n // For DELETE requests or empty body, return empty object\n if (request.method === 'DELETE' || !body || body.length === 0) {\n done(null, {});\n return;\n }\n try {\n const json = JSON.parse(body as string);\n done(null, json);\n } catch (err) {\n done(err as Error, undefined);\n }\n});\n\n\n// Add custom logging hooks\napp.addHook(\"onRequest\", (request, reply, done) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n // Update logger context for this request\n if (loggerLattice.updateContext) {\n loggerLattice.updateContext(context);\n }\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n //loggerLattice.info(`${request.method} ${request.url} - ${reply.statusCode}`);\n done();\n});\n\n// cors\napp.register(cors, {\n origin: true,\n methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\", \"PATCH\"],\n allowedHeaders: \"*\",\n exposedHeaders: [\"Content-Type\"],\n credentials: true,\n});\napp.register(sensible);\napp.register(multipart, {\n limits: {\n fileSize: Number(process.env.BODY_LIMIT) || 50 * 1024 * 1024,\n },\n});\napp.register(websocket);\n\n// Register static file serving for SDK\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\napp.register(staticPlugin, {\n root: path.join(__dirname, \"../public\"),\n prefix: \"/\",\n});\n\n// Error handler\napp.setErrorHandler((error, request, reply) => {\n // Convert headers to strings (Fastify headers can be string | string[])\n const getHeaderValue = (\n header: string | string[] | undefined\n ): string | undefined => {\n if (Array.isArray(header)) {\n return header[0];\n }\n return header;\n };\n\n const context = {\n \"x-tenant-id\": getHeaderValue(request.headers[\"x-tenant-id\"]),\n \"x-request-id\": getHeaderValue(request.headers[\"x-request-id\"]),\n };\n logger.error(\n `请求错误: ${request.method} ${request.url} error:${error.message}`,\n {\n ...context,\n error: error.message,\n stack: error.stack,\n statusCode: error.statusCode || 500,\n }\n );\n reply.status(error.statusCode || 500).send({\n success: false,\n error: error.message || \"服务器内部错误\",\n });\n});\n\n// Logger lattice will be decorated in start() function\n\n/**\n * Logger configuration for gateway\n */\nexport interface GatewayLoggerConfig {\n name?: string;\n description?: string;\n type?: LoggerType;\n serviceName?: string;\n loggerName?: string;\n file?: string | PinoFileOptions;\n context?: Record<string, any>;\n}\n\n// Gateway configuration interface\nexport interface LatticeGatewayConfig {\n port?: number;\n queueServiceConfig?: {\n type: QueueServiceType;\n defaultStartPollingQueue: boolean;\n };\n loggerConfig?: Partial<GatewayLoggerConfig>; // Optional logger configuration to override defaults\n}\n\nfunction getConfiguredSandboxProvider(): ReturnType<typeof createSandboxProvider> {\n const sandboxProviderType =\n (process.env.SANDBOX_PROVIDER_TYPE as CreateSandboxProviderConfig[\"type\"] | undefined) ||\n \"microsandbox-remote\";\n\n return createSandboxProvider({\n type: sandboxProviderType,\n remoteBaseURL: process.env.SANDBOX_BASE_URL,\n microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,\n e2bApiKey: process.env.E2B_API_KEY,\n e2bTemplate: process.env.E2B_TEMPLATE,\n e2bTimeoutMs: process.env.E2B_TIMEOUT_MS\n ? parseInt(process.env.E2B_TIMEOUT_MS, 10)\n : undefined,\n daytonaApiKey: process.env.DAYTONA_API_KEY,\n daytonaApiUrl: process.env.DAYTONA_API_URL,\n daytonaTarget: process.env.DAYTONA_TARGET,\n daytonaTimeout: process.env.DAYTONA_TIMEOUT\n ? parseInt(process.env.DAYTONA_TIMEOUT, 10)\n : undefined,\n daytonaVolumeName: process.env.DAYTONA_VOLUME_NAME,\n });\n}\n\n// Start server\nconst start = async (config?: LatticeGatewayConfig) => {\n try {\n // Initialize or update logger configuration if provided\n if (config?.loggerConfig) {\n const loggerConfig: LoggerConfig = {\n ...DEFAULT_LOGGER_CONFIG,\n ...config.loggerConfig,\n // Merge file config if provided\n file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file,\n };\n loggerLattice = initializeLogger(loggerConfig);\n logger = loggerLattice.client;\n }\n\n // Decorate app with logger lattice (only once, in start function)\n // Access via: request.server.loggerLattice or app.loggerLattice\n app.decorate(\"loggerLattice\", loggerLattice);\n\n // Register all routes\n registerLatticeRoutes(app);\n\n // Set up database config store for on-demand loading\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n sqlDatabaseManager.setConfigStore(store);\n logger.info(\"Database config store set for SqlDatabaseManager\");\n } catch (error) {\n logger.warn(\"Failed to set database config store: \" + (error instanceof Error ? error.message : String(error)));\n }\n\n // Register sandbox manager if not already registered\n if (!sandboxLatticeManager.hasLattice(\"default\")) {\n sandboxLatticeManager.registerLattice(\"default\", getConfiguredSandboxProvider());\n logger.info(\"Registered sandbox manager from env configuration\");\n }\n\n // Swap workflow tracking to PostgreSQL if DATABASE_URL is set\n if (process.env.DATABASE_URL) {\n try {\n const { PostgreSQLWorkflowTrackingStore } = await import(\"@axiom-lattice/pg-stores\");\n const pgStore = new PostgreSQLWorkflowTrackingStore({\n poolConfig: process.env.DATABASE_URL,\n });\n if (storeLatticeManager.hasLattice(\"default\", \"workflowTracking\")) {\n storeLatticeManager.removeLattice(\"default\", \"workflowTracking\");\n }\n storeLatticeManager.registerLattice(\"default\", \"workflowTracking\", pgStore);\n logger.info(\"Workflow tracking store switched to PostgreSQL\");\n } catch (error) {\n logger.warn(\"Failed to switch workflow tracking to PostgreSQL, keeping in-memory: \" + (error instanceof Error ? error.message : String(error)));\n }\n }\n\n const target_port = config?.port || Number(process.env.PORT) || 4001;\n\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${target_port}`);\n\n // Initialize AgentLifecycleManager\n try {\n logger.info(\"AgentLifecycleManager initialized\");\n } catch (error) {\n logger.warn(\"Failed to initialize AgentLifecycleManager\", { error });\n }\n\n // Configure queue service\n const queueServiceConfig = config?.queueServiceConfig;\n if (queueServiceConfig) {\n setQueueServiceType(queueServiceConfig.type);\n if (queueServiceConfig.defaultStartPollingQueue) {\n const agentTaskConsumer = new AgentTaskConsumer(target_port);\n agentTaskConsumer.startPollingQueue();\n }\n }\n\n // Restore agent instances with pending messages\n try {\n logger.info(\"Starting agent instance recovery...\");\n const restoreStats = await agentInstanceManager.restore();\n logger.info(`Agent recovery complete: ${restoreStats.restored} threads restored, ${restoreStats.errors} errors`);\n } catch (error) {\n logger.error(\"Agent recovery failed\", { error });\n // Don't exit - server can still function even if recovery fails\n }\n } catch (err) {\n logger.error(\"Server start failed\", { error: err });\n process.exit(1);\n }\n};\n\nconst LatticeGateway = {\n startAsHttpEndpoint: start,\n configureSwagger,\n registerLatticeRoutes,\n app,\n AgentTaskConsumer,\n};\n\nexport { LatticeGateway };\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager, getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\nimport type { AgentConfig } from \"@axiom-lattice/core\";\nimport { agentLatticeManager, eventBus } from \"@axiom-lattice/core\";\n\n/**\n * Assistant Controller\n * Handles assistant-related CRUD operations\n * Merges code-configured agents (from @axiom-lattice/core) with in-memory stored assistants\n * GET operations return both code-configured and stored assistants\n * CUD operations only work on stored assistants\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Convert AgentConfig to Assistant format\n */\nfunction convertAgentConfigToAssistant(config: AgentConfig): Assistant {\n return {\n id: config.key,\n tenantId: \"default\", // Code-configured agents belong to default tenant\n name: config.name,\n description: config.description,\n graphDefinition: config, // Store the full config as graphDefinition\n createdAt: new Date(0), // Code-configured agents have no creation date\n updatedAt: new Date(0), // Code-configured agents have no update date\n };\n}\n\n/**\n * Assistant list response interface\n */\ninterface AssistantListResponse {\n success: boolean;\n message: string;\n data: {\n records: Assistant[];\n total: number;\n };\n}\n\n/**\n * Assistant response interface\n */\ninterface AssistantResponse {\n success: boolean;\n message: string;\n data?: Assistant;\n}\n\n/**\n * Assistant update request body interface\n */\ninterface AssistantUpdateBody {\n name?: string;\n description?: string;\n graphDefinition?: any;\n}\n\n/**\n * Get list of all assistants\n * Merges code-configured agents with stored assistants\n */\nexport async function getAssistantList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<AssistantListResponse> {\n const tenantId = getTenantId(request);\n\n // Get code-configured agents for the tenant\n const agentConfigs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId);\n const codeConfiguredAssistants = agentConfigs.map(\n convertAgentConfigToAssistant\n );\n\n // Get stored assistants for the tenant\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const storedAssistants = await assistantStore.getAllAssistants(tenantId);\n\n // Merge both sources, stored assistants take precedence if ID conflicts\n const assistantMap = new Map<string, Assistant>();\n\n // First add code-configured agents\n codeConfiguredAssistants.forEach((assistant) => {\n assistantMap.set(assistant.id, assistant);\n });\n\n // Then add stored assistants (overwrite if ID exists)\n storedAssistants.forEach((assistant) => {\n assistantMap.set(assistant.id, assistant);\n });\n\n const allAssistants = Array.from(assistantMap.values());\n\n return {\n success: true,\n message: \"Successfully retrieved assistant list\",\n data: {\n records: allAssistants,\n total: allAssistants.length,\n },\n };\n}\n\n/**\n * Get a single assistant by ID\n * Checks both code-configured agents and stored assistants\n */\nexport async function getAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const { id } = request.params;\n const tenantId = getTenantId(request);\n\n // First check stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n let assistant = await assistantStore.getAssistantById(tenantId, id);\n\n // If not found in store, check code-configured agents for the tenant\n if (!assistant) {\n const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);\n if (agentConfig) {\n assistant = convertAgentConfigToAssistant(agentConfig);\n }\n }\n\n if (!assistant) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved assistant\",\n data: assistant,\n };\n}\n\n/**\n * Upsert assistant - create if not exists in store, update if exists\n */\nasync function upsertAssistant(\n tenantId: string,\n id: string,\n data: CreateAssistantRequest | AssistantUpdateBody,\n reply: FastifyReply,\n requireFields: boolean = false\n): Promise<AssistantResponse> {\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n const exists = await assistantStore.hasAssistant(tenantId, id);\n\n let assistant: Assistant | null;\n if (exists) {\n assistant = await assistantStore.updateAssistant(tenantId, id, data);\n if (!assistant) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update assistant\",\n });\n }\n eventBus.publish(\"assistant:updated\", { id: assistant.id, name: assistant.name, tenantId });\n return {\n success: true,\n message: \"Updated assistant\",\n data: assistant,\n };\n }\n\n if (requireFields) {\n const createData = data as CreateAssistantRequest;\n if (!createData.name || !createData.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"name and graphDefinition are required\",\n });\n }\n }\n\n assistant = await assistantStore.createAssistant(tenantId, id, data as CreateAssistantRequest);\n eventBus.publish(\"assistant:created\", { id: assistant.id, name: assistant.name, tenantId });\n return reply.status(201).send({\n success: true,\n message: \"Created assistant\",\n data: assistant,\n });\n}\n\n/**\n * Create a new assistant\n */\nexport async function createAssistant(\n request: FastifyRequest<{ Body: CreateAssistantRequest & { id?: string } }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const tenantId = getTenantId(request);\n const data = request.body;\n\n if (!data.name || !data.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"name and graphDefinition are required\",\n });\n }\n\n const id = data.id ?? randomUUID();\n return upsertAssistant(tenantId, id, data, reply, true);\n}\n\n/**\n * Update an existing assistant by ID\n */\nexport async function updateAssistant(\n request: FastifyRequest<{\n Params: { id: string };\n Body: AssistantUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const tenantId = getTenantId(request);\n const { id } = request.params;\n const updates = request.body;\n\n return upsertAssistant(tenantId, id, updates, reply, false);\n}\n\n/**\n * Delete an assistant by ID\n * For stored assistants: deletes from store\n * For code-configured assistants: only deletes from store if exists (code registration remains)\n */\nexport async function deleteAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { id } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);\n const isCodeConfigured = !!agentConfig;\n\n if (isCodeConfigured) {\n const exists = await assistantStore.hasAssistant(tenantId, id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found (code-configured assistants cannot be deleted from code, only from store)\",\n });\n }\n await assistantStore.deleteAssistant(tenantId, id);\n eventBus.publish(\"assistant:deleted\", { id, tenantId });\n return {\n success: true,\n message: \"Deleted assistant from store (code-configured registration remains)\",\n };\n }\n\n const exists = await assistantStore.hasAssistant(tenantId, id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n const deleted = await assistantStore.deleteAssistant(tenantId, id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete assistant\",\n });\n }\n\n eventBus.publish(\"assistant:deleted\", { id, tenantId });\n\n return {\n success: true,\n message: \"Successfully deleted assistant\",\n };\n}\n\n/**\n * Get agent graph visualization\n */\nexport const getAgentGraph = async (\n request: FastifyRequest<{\n Params: { assistantId: string };\n }>,\n reply: FastifyReply\n) => {\n try {\n const { assistantId } = request.params;\n const tenant_id = getTenantId(request);\n\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: '' })\n\n // Call drawing service to get image data\n const imageData = await agent.get_draw_graph()\n\n // Set response header and return image data\n reply.header(\"Content-Type\", \"application/json\").send({\n image: imageData,\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get agent graph\",\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { CreateRunRequest } from \"../types\";\nimport { v4 } from \"uuid\";\nimport {\n Agent,\n ThreadStatus,\n agentLatticeManager,\n agentInstanceManager,\n QueueMode,\n} from \"@axiom-lattice/core\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\n\ninterface ResumeStreamRequest {\n thread_id: string;\n assistant_id: string\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}\n\n// Create run\nexport const createRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const {\n assistant_id,\n thread_id,\n message_id,\n command,\n streaming,\n background,\n custom_run_config,\n mode,\n ...input\n } = request.body as CreateRunRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n const x_request_id = (request.headers[\"x-request-id\"] as string) || v4();\n\n // Validate request\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n // Get or create Agent instance (ensures single instance per thread)\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n custom_run_config,\n });\n\n\n // Handle streaming requests\n if (streaming) {\n // Setup SSE\n reply.hijack();\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n\n // Execute agent with streaming\n // Only pass id if message_id is provided (for backward compatibility)\n const messageInput = message_id \n ? { ...input, id: message_id }\n : input;\n \n const result = await agent.addMessage({\n input: messageInput,\n command,\n custom_run_config,\n }, mode as QueueMode);\n\n // const agentStatus = await agent.getRunStatus()\n // console.log(agentStatus)\n // if (agentStatus === \"busy\") {\n // reply.status(200).send({\n // success: true,\n\n // });\n // return\n // }\n\n const stream = agent.chunkStream((result).messageId, [MessageChunkTypes.MESSAGE_COMPLETED])\n\n // Forward all chunks to SSE\n for await (const chunk of stream) {\n const success = reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n if (!success) {\n await new Promise(resolve => reply.raw.once('drain', resolve));\n }\n }\n } catch (error: any) {\n // Send error as SSE event\n const errorEvent = {\n type: 'error',\n data: {\n id: v4(),\n content: error.message || 'Stream processing error',\n },\n };\n reply.raw.write(`data: ${JSON.stringify(errorEvent)}\\n\\n`);\n } finally {\n reply.raw.end();\n }\n } else {\n // Non-streaming: use agentExecutor\n const { message: msg, ...restInputNonStream } = input;\n const result = await agent.invoke({\n input: { message: msg, ...restInputNonStream },\n command,\n custom_run_config,\n });\n reply.status(200).send({\n success: true,\n ...result,\n });\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `创建运行时发生错误: ${error.message}`,\n });\n }\n};\n\n// Resume stream from known position\nexport const resumeStream = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n\n\n\n\n const { thread_id, message_id, assistant_id, known_content, poll_interval } =\n request.body as ResumeStreamRequest;\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n\n // Validate request data\n if (!thread_id || !message_id || !assistant_id || known_content === undefined) {\n reply.status(400).send({\n success: false,\n error: \"thread_id, message_id, assistant_id, and known_content are required\",\n });\n return;\n }\n\n // Notify Fastify that we will manually handle the response\n reply.hijack();\n\n // Set SSE response headers\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n\n try {\n // Create Agent instance for accessing chunk buffer\n // Get or create Agent instance (ensures single instance per thread)\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n // Get the stream from agent's chunk buffer\n const stream = agent.chunkStream(message_id, [MessageChunkTypes.THREAD_IDLE]);\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\n // console.log(chunk);\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error: any) {\n // Send error as SSE event before closing (following MessageChunk format)\n const errorEvent = {\n type: 'error',\n data: {\n id: v4(),\n content: error.message || 'Resume stream processing error'\n }\n };\n reply.raw.write(`data: ${JSON.stringify(errorEvent)}\\n\\n`);\n } finally {\n reply.raw.end();\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Error resuming stream: ${error.message}`,\n });\n }\n};\n\n// Abort agent execution for a thread\nexport const abortRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, threadId } = request.params as {\n assistantId: string;\n threadId: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = (request.headers[\"x-workspace-id\"] as string) || \"default\";\n const project_id = (request.headers[\"x-project-id\"] as string) || \"default\";\n\n const agent = agentInstanceManager.getAgent({\n assistant_id: assistantId,\n thread_id: threadId,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n await agent.abort();\n\n reply.status(200).send({\n success: true,\n message: \"Agent aborted\",\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Abort failed: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager } from \"@axiom-lattice/core\";\n\n// 设置内存项\nexport const setMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n const value = request.body;\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n if (value === undefined) {\n reply.status(400).send({\n success: false,\n error: \"值是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.setMemoryItem(assistantId, key, value);\n\n // if (!result.success) {\n reply.status(500).send();\n return;\n // }\n\n //reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `设置内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取内存项\nexport const getMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.getMemoryItem(assistantId, key);\n\n // if (!result.success) {\n reply.status(404).send();\n return;\n // }\n\n //reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取所有内存项\nexport const getAllMemoryItems = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, thread_id } = request.params as {\n assistantId: string;\n thread_id: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"线程ID是必需的\",\n });\n return;\n }\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: thread_id })\n\n const result = await agent.getCurrentMessages();\n\n if (!result) {\n reply.status(500).send(result);\n return;\n }\n\n reply.send(result);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取所有内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 获取助手状态\nexport const getAgentState = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, thread_id } = request.params as {\n assistantId: string;\n thread_id: string;\n };\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"线程ID是必需的\",\n });\n return;\n }\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: thread_id })\n\n // 1. 获取 LangGraph 状态(现有逻辑)\n const result = await agent.getCurrentState();\n const pendingMessages = await agent.getPendingMessages();\n\n\n if (!result) {\n reply.status(500).send(result);\n return;\n }\n\n // 3. 合并返回\n // Normalize pendingMessages content to string for consistent frontend format\n const normalizedPendingMessages = pendingMessages.map(msg => ({\n ...msg,\n content: typeof msg.content === 'object' && msg.content !== null\n ? ('message' in msg.content ? msg.content.message : JSON.stringify(msg.content))\n : String(msg.content || '')\n }));\n\n const mergedResult = {\n ...result,\n pendingMessages: normalizedPendingMessages\n };\n\n reply.send(mergedResult);\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `获取助手状态时发生错误: ${error.message}`,\n });\n }\n};\n\n// 删除内存项\nexport const deleteMemoryItem = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId, key } = request.params as {\n assistantId: string;\n key: string;\n };\n\n if (!assistantId || !key) {\n reply.status(400).send({\n success: false,\n error: \"助手ID和键是必需的\",\n });\n return;\n }\n\n //const result = await memoryModel.deleteMemoryItem(assistantId, key);\n\n // if (!result.success) {\n reply.status(500).send();\n return;\n // }\n\n reply.status(204).send();\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `删除内存项时发生错误: ${error.message}`,\n });\n }\n};\n\n// 清除内存\nexport const clearMemory = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistantId } = request.params as { assistantId: string };\n\n if (!assistantId) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n let result: any; //= await memoryModel.clearMemory(assistantId);\n\n if (!result.success) {\n reply.status(500).send(result);\n return;\n }\n\n reply.status(204).send();\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `清除内存时发生错误: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { AgentManager } from \"@axiom-lattice/core\";\n\n/**\n * Request body interface for triggering agent task\n */\ninterface TriggerAgentTaskRequest {\n assistant_id: string;\n thread_id: string;\n input: any;\n command?: any;\n}\n\n/**\n * Trigger an agent task\n * This endpoint triggers an agent task through the AgentManager,\n * which publishes the task to the event bus for processing\n */\nexport const triggerAgentTask = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const { assistant_id, thread_id, input, command } =\n request.body as TriggerAgentTaskRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n\n // Validate required fields\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"assistant_id is required\",\n });\n return;\n }\n\n if (!thread_id) {\n reply.status(400).send({\n success: false,\n error: \"thread_id is required\",\n });\n return;\n }\n\n // Get AgentManager instance and trigger the task\n const agentManager = AgentManager.getInstance();\n const result = await agentManager.callAgentInQueue({\n assistant_id,\n thread_id,\n input,\n command,\n \"x-tenant-id\": tenant_id,\n });\n\n reply.status(200).send({\n success: true,\n });\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Failed to trigger agent task: ${error.message}`,\n });\n }\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { Thread, CreateThreadRequest } from \"../types\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Thread Controller\n * Handles thread-related CRUD operations for a specific assistant\n * All operations are scoped to a tenant ID and assistant ID\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Thread list response interface\n */\ninterface ThreadListResponse {\n success: boolean;\n message: string;\n data: {\n records: Thread[];\n total: number;\n };\n}\n\n/**\n * Thread response interface\n */\ninterface ThreadResponse {\n success: boolean;\n message: string;\n data?: Thread;\n}\n\n/**\n * Thread update request body interface\n */\ninterface ThreadUpdateBody {\n metadata?: Record<string, any>;\n}\n\n/**\n * Get list of all threads for a specific assistant\n */\nexport async function getThreadList(\n request: FastifyRequest<{\n Params: { assistantId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadListResponse> {\n const tenantId = getTenantId(request);\n const { assistantId } = request.params;\n\n // Build metadata filter from headers (workspace/project isolation)\n const metadataFilter: Record<string, string> = {};\n const workspaceId = request.headers[\"x-workspace-id\"] as string | undefined;\n const projectId = request.headers[\"x-project-id\"] as string | undefined;\n \n if (workspaceId) {\n metadataFilter.workspaceId = workspaceId;\n }\n if (projectId) {\n metadataFilter.projectId = projectId;\n }\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const threads = await threadStore.getThreadsByAssistantId(\n tenantId,\n assistantId,\n Object.keys(metadataFilter).length > 0 ? metadataFilter : undefined\n );\n\n return {\n success: true,\n message: \"Successfully retrieved thread list\",\n data: {\n records: threads,\n total: threads.length,\n },\n };\n}\n\n/**\n * Get a single thread by ID for a specific tenant\n */\nexport async function getThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const thread = await threadStore.getThreadById(tenantId, threadId);\n\n if (!thread) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved thread\",\n data: thread,\n };\n}\n\n/**\n * Create a new thread for an assistant\n */\nexport async function createThread(\n request: FastifyRequest<{\n Params: { assistantId: string };\n Body: CreateThreadRequest;\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { assistantId } = request.params;\n const data = request.body;\n\n // Generate thread ID if not provided\n const threadId = randomUUID();\n\n // Extract workspace and project from headers\n const workspaceId = request.headers[\"x-workspace-id\"] as string | undefined;\n const projectId = request.headers[\"x-project-id\"] as string | undefined;\n\n // Enrich metadata with tenant/workspace/project\n const enrichedMetadata: Record<string, any> = {\n ...data.metadata,\n tenantId,\n };\n\n if (workspaceId) {\n enrichedMetadata.workspaceId = workspaceId;\n }\n if (projectId) {\n enrichedMetadata.projectId = projectId;\n }\n\n // Create thread with enriched metadata\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const newThread = await threadStore.createThread(tenantId, assistantId, threadId, {\n metadata: enrichedMetadata,\n });\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created thread\",\n data: newThread,\n });\n}\n\n/**\n * Update an existing thread by ID\n */\nexport async function updateThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n Body: ThreadUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n const updates = request.body;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n\n // Check if thread exists\n const exists = await threadStore.hasThread(tenantId, threadId);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n // Update thread\n const updatedThread = await threadStore.updateThread(\n tenantId,\n threadId,\n updates\n );\n\n if (!updatedThread) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update thread\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated thread\",\n data: updatedThread,\n };\n}\n\n/**\n * Delete a thread by ID\n */\nexport async function deleteThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n\n // Check if thread exists\n const exists = await threadStore.hasThread(tenantId, threadId);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Thread not found\",\n });\n }\n\n // Delete the thread\n const deleted = await threadStore.deleteThread(tenantId, threadId);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete thread\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully deleted thread\",\n };\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { scheduleLatticeManager } from \"@axiom-lattice/core\";\nimport {\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Schedule Controller\n * Handles schedule-related operations for viewing and managing scheduled tasks\n * All operations are scoped to a tenant ID\n */\n\n/**\n * Get tenant ID from request headers or user context\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Scheduled tasks list response interface\n */\ninterface ScheduledTasksListResponse {\n success: boolean;\n message: string;\n data: {\n records: ScheduledTaskDefinition[];\n total: number;\n };\n}\n\n/**\n * Scheduled task response interface\n */\ninterface ScheduledTaskResponse {\n success: boolean;\n message: string;\n data?: ScheduledTaskDefinition | null;\n}\n\n/**\n * Helper function to get the schedule lattice safely\n * Returns null if no schedule lattice is registered\n */\nfunction getScheduleLattice() {\n // Try to get the first available schedule lattice\n const keys = scheduleLatticeManager.getLatticeKeys();\n if (keys.length === 0) {\n return null;\n }\n // Use \"default\" if available, otherwise use the first one\n if (scheduleLatticeManager.hasLattice(\"default\")) {\n return scheduleLatticeManager.getScheduleLattice(\"default\");\n }\n return scheduleLatticeManager.getScheduleLattice(keys[0]);\n}\n\n/**\n * Get scheduled tasks for a specific thread\n */\nexport async function getThreadSchedules(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n Querystring: {\n status?: ScheduledTaskStatus;\n limit?: string;\n offset?: string;\n };\n }>,\n reply: FastifyReply\n): Promise<ScheduledTasksListResponse> {\n const { assistantId, threadId } = request.params;\n const { status, limit, offset } = request.query;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n // If no schedule lattice is registered, return empty result\n if (!scheduleLattice) {\n return {\n success: true,\n message: \"No schedule lattice configured\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n\n const storage = scheduleLattice.client.getStorage();\n\n if (!storage) {\n return {\n success: true,\n message: \"No schedule storage configured\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n\n const tenantId = getTenantId(request);\n\n const filters: {\n tenantId: string;\n threadId: string;\n assistantId?: string;\n status?: ScheduledTaskStatus;\n limit?: number;\n offset?: number;\n } = {\n tenantId,\n threadId,\n assistantId,\n };\n\n if (status) {\n filters.status = status;\n }\n if (limit) {\n filters.limit = parseInt(limit, 10);\n }\n if (offset) {\n filters.offset = parseInt(offset, 10);\n }\n\n const tasks = await storage.getAllTasks(filters);\n const total = await storage.countTasks({\n tenantId,\n threadId,\n assistantId,\n status,\n });\n\n return {\n success: true,\n message: \"Successfully retrieved scheduled tasks\",\n data: {\n records: tasks,\n total,\n },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get thread schedules\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to retrieve scheduled tasks\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single scheduled task by ID\n */\nexport async function getScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<ScheduledTaskResponse> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const task = await scheduleLattice.client.getTask(taskId);\n\n if (!task) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved scheduled task\",\n data: task,\n };\n } catch (error) {\n request.log.error(error, \"Failed to get scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to retrieve scheduled task\",\n });\n }\n}\n\n/**\n * Cancel a scheduled task\n */\nexport async function cancelScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.cancel(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or already cancelled\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully cancelled scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to cancel scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to cancel scheduled task\",\n });\n }\n}\n\n/**\n * Pause a scheduled cron task\n */\nexport async function pauseScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.pause(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or cannot be paused\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully paused scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to pause scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to pause scheduled task\",\n });\n }\n}\n\n/**\n * Resume a paused cron task\n */\nexport async function resumeScheduledTask(\n request: FastifyRequest<{\n Params: { taskId: string };\n }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { taskId } = request.params;\n\n try {\n const scheduleLattice = getScheduleLattice();\n\n if (!scheduleLattice) {\n return reply.status(404).send({\n success: false,\n message: \"No schedule lattice configured\",\n });\n }\n\n const result = await scheduleLattice.client.resume(taskId);\n\n if (!result) {\n return reply.status(404).send({\n success: false,\n message: \"Scheduled task not found or cannot be resumed\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully resumed scheduled task\",\n };\n } catch (error) {\n request.log.error(error, \"Failed to resume scheduled task\");\n return reply.status(500).send({\n success: false,\n message: \"Failed to resume scheduled task\",\n });\n }\n}\n","/**\n * Configuration service\n * Manages environment variables and supports dynamic updates\n */\n\nexport interface GatewayConfig {\n port?: number;\n queueServiceType?: string;\n redisUrl?: string;\n redisPassword?: string;\n queueName?: string;\n [key: string]: any; // Allow additional config keys\n}\n\n/**\n * Get configuration from environment variables\n * Supports dynamic updates via updateConfig method\n */\nclass ConfigService {\n private config: GatewayConfig;\n\n constructor() {\n this.config = this.loadFromEnv();\n }\n\n /**\n * Load configuration from environment variables\n */\n private loadFromEnv(): GatewayConfig {\n return {\n port: process.env.PORT ? Number(process.env.PORT) : undefined,\n queueServiceType: process.env.QUEUE_SERVICE_TYPE,\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n queueName: process.env.QUEUE_NAME,\n };\n }\n\n /**\n * Update configuration from JSON object\n * This will update both the internal config and process.env\n */\n updateConfig(jsonConfig: Record<string, any>): void {\n // Update process.env for all provided keys\n for (const [key, value] of Object.entries(jsonConfig)) {\n if (value !== null && value !== undefined) {\n // Convert nested objects to environment variable format\n if (typeof value === \"object\" && !Array.isArray(value)) {\n // Handle nested objects like supabase: { url: \"...\", key: \"...\" }\n for (const [nestedKey, nestedValue] of Object.entries(value)) {\n const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;\n process.env[envKey] = String(nestedValue);\n }\n } else {\n // Handle flat keys\n process.env[key.toUpperCase()] = String(value);\n }\n }\n }\n\n // Reload config from updated environment variables\n this.config = this.loadFromEnv();\n\n // Deep merge the JSON config into our config object\n this.config = this.deepMerge(this.config, jsonConfig);\n }\n\n /**\n * Deep merge two objects\n */\n private deepMerge(target: any, source: any): any {\n const output = { ...target };\n if (this.isObject(target) && this.isObject(source)) {\n Object.keys(source).forEach((key) => {\n if (this.isObject(source[key])) {\n if (!(key in target)) {\n Object.assign(output, { [key]: source[key] });\n } else {\n output[key] = this.deepMerge(target[key], source[key]);\n }\n } else {\n Object.assign(output, { [key]: source[key] });\n }\n });\n }\n return output;\n }\n\n /**\n * Check if value is a plain object\n */\n private isObject(item: any): boolean {\n return item && typeof item === \"object\" && !Array.isArray(item);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): GatewayConfig {\n return { ...this.config };\n }\n}\n\n// Export singleton instance\nexport const configService = new ConfigService();\n\n// Export config getter for backward compatibility\nexport const config = {\n get port() {\n return configService.getConfig().port;\n },\n get queueServiceType() {\n return configService.getConfig().queueServiceType;\n },\n get redisUrl() {\n return configService.getConfig().redisUrl;\n },\n get redisPassword() {\n return configService.getConfig().redisPassword;\n },\n get queueName() {\n return configService.getConfig().queueName;\n },\n};\n","// Queue service adapter that uses QueueLatticeManager from core package\n// Provides backward-compatible API for gateway services\n\nimport {\n queueLatticeManager,\n registerQueueLattice,\n getQueueLattice,\n} from \"@axiom-lattice/core\";\nimport { QueueType } from \"@axiom-lattice/protocols\";\nimport type { QueueConfig, QueueClient } from \"@axiom-lattice/protocols\";\nimport { RedisQueueClient } from \"@axiom-lattice/queue-redis\";\n\nexport type QueueServiceType = \"memory\" | \"redis\";\n\n// Default queue key\nconst DEFAULT_QUEUE_KEY = \"default\";\n\n// Global configuration for queue service type\n// Can be set via environment variable QUEUE_SERVICE_TYPE or via LatticeGateway configuration\nlet queueServiceType: QueueServiceType =\n (process.env.QUEUE_SERVICE_TYPE as QueueServiceType) || \"memory\";\n\n/**\n * Configure the queue service type\n * This will register or update the default queue service\n * @param type - \"memory\" or \"redis\"\n */\nexport const setQueueServiceType = (type: QueueServiceType): void => {\n queueServiceType = type;\n console.log(`Queue service type set to: ${type}`);\n\n // Register or update the queue service\n const queueName = process.env.QUEUE_NAME || \"tasks\";\n const config: QueueConfig = {\n name: \"Default Queue Service\",\n description: `Default ${type} queue service`,\n type: type === \"redis\" ? QueueType.REDIS : QueueType.MEMORY,\n queueName,\n options:\n type === \"redis\"\n ? {\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n }\n : undefined,\n };\n\n // Remove existing queue if it exists\n if (queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {\n queueLatticeManager.removeLattice(DEFAULT_QUEUE_KEY);\n }\n\n // Create client for Redis type\n let client: QueueClient | undefined;\n if (type === \"redis\") {\n client = new RedisQueueClient(queueName, {\n redisUrl: process.env.REDIS_URL,\n redisPassword: process.env.REDIS_PASSWORD,\n });\n }\n\n // Register the new queue service\n registerQueueLattice(DEFAULT_QUEUE_KEY, config, client);\n};\n\n/**\n * Get the current queue service type\n */\nexport const getQueueServiceType = (): QueueServiceType => {\n return queueServiceType;\n};\n\n/**\n * Get the default queue service\n * If not registered, register it with the current configuration\n */\nconst getQueueService = () => {\n // Check if queue is already registered\n if (!queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {\n // Auto-register with current configuration\n setQueueServiceType(queueServiceType);\n }\n\n return getQueueLattice(DEFAULT_QUEUE_KEY);\n};\n\n/**\n * Push agent task to queue\n * @param agentTask - Agent task to push\n */\nexport const pushAgentTaskToQueue = async (agentTask: any) => {\n const queue = getQueueService();\n const result = await queue.push(agentTask);\n return result;\n};\n\n/**\n * Pop agent task from queue\n */\nexport const popAgentTaskFromQueue = async () => {\n const queue = getQueueService();\n const result = await queue.pop();\n return result;\n};\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { configService } from \"../config\";\nimport {\n setQueueServiceType,\n QueueServiceType,\n} from \"../services/queue_service\";\n\n/**\n * Configuration Controller\n * Handles configuration updates from frontend\n */\n\ninterface UpdateConfigRequest {\n Body: {\n config: Record<string, any>;\n };\n}\n\n/**\n * Update gateway configuration\n * Accepts JSON config and loads it into environment variables\n */\nexport async function updateConfig(\n request: FastifyRequest<UpdateConfigRequest>,\n reply: FastifyReply\n) {\n try {\n const { config: jsonConfig } = request.body;\n\n if (!jsonConfig || typeof jsonConfig !== \"object\") {\n return reply.status(400).send({\n success: false,\n error: \"Invalid configuration: config must be an object\",\n });\n }\n\n // Update configuration service\n configService.updateConfig(jsonConfig);\n\n const warnings: string[] = [];\n const requiresRestart: string[] = [];\n\n // Check if port is being changed (requires restart)\n if (jsonConfig.port !== undefined) {\n requiresRestart.push(\"PORT\");\n warnings.push(\"Port change requires server restart to take effect\");\n }\n\n // If queue service type is being updated, reconfigure the queue service\n if (jsonConfig.queueServiceType) {\n setQueueServiceType(jsonConfig.queueServiceType as QueueServiceType);\n }\n\n // If Redis configuration is being updated and queue service is Redis, reconfigure\n if (\n (jsonConfig.redisUrl || jsonConfig.redisPassword) &&\n (process.env.QUEUE_SERVICE_TYPE === \"redis\" ||\n jsonConfig.queueServiceType === \"redis\")\n ) {\n // Reconfigure queue service to pick up new Redis settings\n const currentType =\n (jsonConfig.queueServiceType as QueueServiceType) ||\n (process.env.QUEUE_SERVICE_TYPE as QueueServiceType) ||\n \"memory\";\n if (currentType === \"redis\") {\n setQueueServiceType(\"redis\");\n }\n }\n\n // Get updated config (without sensitive data)\n const updatedConfig = configService.getConfig();\n const safeConfig = {\n ...updatedConfig,\n redisPassword: updatedConfig.redisPassword\n ? \"***\"\n : updatedConfig.redisPassword,\n };\n\n return reply.send({\n success: true,\n message: \"Configuration updated successfully\",\n data: safeConfig,\n warnings: warnings.length > 0 ? warnings : undefined,\n requiresRestart: requiresRestart.length > 0 ? requiresRestart : undefined,\n });\n } catch (error: any) {\n console.error(\"Failed to update configuration\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to update configuration\",\n });\n }\n}\n\n/**\n * Get current gateway configuration\n * Returns current configuration (with sensitive data masked)\n */\nexport async function getConfig(request: FastifyRequest, reply: FastifyReply) {\n try {\n const currentConfig = configService.getConfig();\n const safeConfig = {\n ...currentConfig,\n redisPassword: currentConfig.redisPassword\n ? \"***\"\n : currentConfig.redisPassword,\n };\n\n return reply.send({\n success: true,\n data: safeConfig,\n });\n } catch (error: any) {\n console.error(\"Failed to get configuration\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get configuration\",\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { registerModelLattice, modelLatticeManager } from \"@axiom-lattice/core\";\nimport type { LLMConfig } from \"@axiom-lattice/protocols\";\n\n/**\n * Models Controller\n * Handles model lattice registration and management\n * Models are tenant-isolated using key prefix: {tenantId}:{modelKey}\n */\n\n/**\n * Get tenant ID from request headers or user context\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Get tenant-scoped model key\n */\nfunction getTenantModelKey(tenantId: string, modelKey: string): string {\n return `${tenantId}:${modelKey}`;\n}\n\n/**\n * Extract model key from tenant-scoped key\n */\nfunction extractModelKey(tenantId: string, tenantModelKey: string): string {\n const prefix = `${tenantId}:`;\n if (tenantModelKey.startsWith(prefix)) {\n return tenantModelKey.substring(prefix.length);\n }\n return tenantModelKey;\n}\n\ninterface ModelConfig {\n key: string;\n model: string;\n displayName?: string;\n provider: \"azure\" | \"openai\" | \"deepseek\" | \"siliconcloud\" | \"volcengine\";\n streaming?: boolean;\n apiKey?: string;\n baseURL?: string;\n maxTokens?: number;\n temperature?: number;\n timeout?: number;\n maxRetries?: number;\n}\n\ninterface UpdateModelsRequest {\n Body: {\n models: ModelConfig[];\n };\n}\n\ninterface UpdateModelsRequest {\n Body: {\n models: ModelConfig[];\n };\n}\n\n/**\n * Get all registered models\n */\nexport async function getModels(request: FastifyRequest, reply: FastifyReply) {\n try {\n const allLattices = modelLatticeManager.getAllLattices();\n const models = allLattices.map((lattice) => {\n // Extract config from the lattice client\n // Note: This is a simplified approach - you may need to adjust based on actual implementation\n const config = (lattice.client as any).config || {};\n // Use provided displayName or auto-generate from key\n const displayName = config.displayName || lattice.key\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n return {\n key: lattice.key,\n model: config.model || \"\",\n provider: config.provider || \"openai\",\n displayName: displayName,\n streaming: config.streaming || false,\n apiKey: config.apiKey || \"\",\n baseURL: config.baseURL || \"\",\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n timeout: config.timeout,\n maxRetries: config.maxRetries,\n };\n });\n\n return reply.send({\n success: true,\n data: models,\n });\n } catch (error: any) {\n console.error(\"Failed to get models\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to get models\",\n });\n }\n}\n\n/**\n * Update models configuration\n * Registers or updates model lattices\n */\nexport async function updateModels(\n request: FastifyRequest<UpdateModelsRequest>,\n reply: FastifyReply\n) {\n try {\n const { models } = request.body;\n\n if (!models || !Array.isArray(models)) {\n return reply.status(400).send({\n success: false,\n error: \"Invalid request: models must be an array\",\n });\n }\n\n const registeredModels: string[] = [];\n const errors: string[] = [];\n\n for (const modelConfig of models) {\n if (!modelConfig.key || !modelConfig.model || !modelConfig.provider) {\n errors.push(\n `Model configuration is incomplete: key, model, and provider are required`\n );\n continue;\n }\n\n try {\n // Remove existing model with the same key if it exists\n if (modelLatticeManager.hasLattice(modelConfig.key)) {\n modelLatticeManager.removeLattice(modelConfig.key);\n }\n\n // Convert to LLMConfig format\n const llmConfig: LLMConfig = {\n provider: modelConfig.provider,\n model: modelConfig.model,\n displayName: modelConfig.displayName,\n streaming: modelConfig.streaming ?? false,\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n maxTokens: modelConfig.maxTokens,\n temperature: modelConfig.temperature,\n timeout: modelConfig.timeout,\n maxRetries: modelConfig.maxRetries,\n };\n\n // Register the new model lattice\n registerModelLattice(modelConfig.key, llmConfig);\n registeredModels.push(modelConfig.key);\n } catch (error: any) {\n errors.push(\n `Failed to register model ${modelConfig.key}: ${error.message}`\n );\n }\n }\n\n if (errors.length > 0 && registeredModels.length === 0) {\n return reply.status(400).send({\n success: false,\n error: errors.join(\"; \"),\n });\n }\n\n return reply.send({\n success: true,\n message: `Successfully registered ${registeredModels.length} model(s)`,\n data: {\n registered: registeredModels,\n errors: errors.length > 0 ? errors : undefined,\n },\n });\n } catch (error: any) {\n console.error(\"Failed to update models\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n error: error.message || \"Failed to update models\",\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\n\n/**\n * Health Controller\n * Handles health check endpoints for monitoring and load balancer checks\n */\n\n/**\n * Health check endpoint\n * Returns service status and basic information\n */\nexport async function getHealth(\n request: FastifyRequest,\n reply: FastifyReply\n) {\n try {\n const healthStatus = {\n status: \"healthy\",\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n service: \"lattice-gateway\",\n version: process.env.npm_package_version || \"1.0.0\",\n };\n\n return reply.send({\n success: true,\n data: healthStatus,\n });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n status: \"unhealthy\",\n error: error.message || \"Health check failed\",\n });\n }\n}\n","/**\n * SkillService\n *\n * Business logic layer for skill management.\n * Wraps SandboxSkillStore from @axiom-lattice/core.\n * Controllers should consume this service, not directly manipulate storage.\n */\n\nimport { SandboxSkillStore } from \"@axiom-lattice/core\";\nimport type {\n Skill,\n SkillStoreContext,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\nimport { FastifyRequest } from \"fastify\";\n\nfunction getTenantId(request: FastifyRequest): string {\n return (request as any).user?.tenantId || (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\nfunction getWorkspaceId(request: FastifyRequest): string | undefined {\n return request.headers[\"x-workspace-id\"] as string | undefined;\n}\n\nfunction getProjectId(request: FastifyRequest): string | undefined {\n return request.headers[\"x-project-id\"] as string | undefined;\n}\n\nfunction buildContext(request: FastifyRequest): SkillStoreContext {\n return {\n workspaceId: getWorkspaceId(request),\n projectId: getProjectId(request),\n };\n}\n\nexport class SkillService {\n private store: SandboxSkillStore;\n\n constructor() {\n this.store = new SandboxSkillStore();\n }\n\n async getAllSkills(request: FastifyRequest): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.getAllSkills(tenantId, buildContext(request));\n }\n\n async getSkillById(request: FastifyRequest, id: string): Promise<Skill | null> {\n const tenantId = getTenantId(request);\n return this.store.getSkillById(tenantId, id, buildContext(request));\n }\n\n async createSkill(\n request: FastifyRequest,\n id: string,\n data: CreateSkillRequest\n ): Promise<Skill> {\n const tenantId = getTenantId(request);\n return this.store.createSkill(tenantId, id, data, buildContext(request));\n }\n\n async updateSkill(\n request: FastifyRequest,\n id: string,\n updates: Partial<CreateSkillRequest>\n ): Promise<Skill | null> {\n const tenantId = getTenantId(request);\n return this.store.updateSkill(tenantId, id, updates, buildContext(request));\n }\n\n async deleteSkill(request: FastifyRequest, id: string): Promise<boolean> {\n const tenantId = getTenantId(request);\n return this.store.deleteSkill(tenantId, id, buildContext(request));\n }\n\n async searchByMetadata(\n request: FastifyRequest,\n key: string,\n value: string\n ): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.searchByMetadata(tenantId, key, value, buildContext(request));\n }\n\n async filterByCompatibility(\n request: FastifyRequest,\n compatibility: string\n ): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.filterByCompatibility(tenantId, compatibility, buildContext(request));\n }\n\n async filterByLicense(request: FastifyRequest, license: string): Promise<Skill[]> {\n const tenantId = getTenantId(request);\n return this.store.filterByLicense(tenantId, license, buildContext(request));\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { SkillService } from \"../services/skill_service\";\nimport type { Skill, CreateSkillRequest } from \"@axiom-lattice/protocols\";\n\nconst skillService = new SkillService();\n\nfunction serializeSkill(skill: Skill): any {\n const serialized: any = {\n id: skill.id,\n name: skill.name,\n description: skill.description,\n license: skill.license,\n compatibility: skill.compatibility,\n metadata: skill.metadata || {},\n content: skill.content,\n subSkills: skill.subSkills,\n createdAt: skill.createdAt instanceof Date ? skill.createdAt.toISOString() : new Date().toISOString(),\n updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : new Date().toISOString(),\n };\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) delete serialized[key];\n });\n return serialized;\n}\n\ninterface SkillListResponse {\n success: boolean;\n message: string;\n data: { records: any[]; total: number };\n}\n\ninterface SkillResponse {\n success: boolean;\n message: string;\n data?: any;\n}\n\ninterface SkillUpdateBody {\n name?: string;\n description?: string;\n license?: string;\n compatibility?: string;\n metadata?: Record<string, string>;\n content?: string;\n subSkills?: string[];\n}\n\nexport async function getSkillList(request: FastifyRequest, reply: FastifyReply): Promise<SkillListResponse> {\n try {\n const skills = await skillService.getAllSkills(request);\n return {\n success: true,\n message: \"Successfully retrieved skill list\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function getSkill(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const skill = await skillService.getSkillById(request, id);\n\n if (!skill) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully retrieved skill\", data: serializeSkill(skill) };\n } catch (error: any) {\n return reply.status(500).send({ success: false, message: `Failed to retrieve skill: ${error.message}` });\n }\n}\n\nexport async function createSkill(\n request: FastifyRequest<{ Body: CreateSkillRequest }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const data = request.body;\n if (!data.name) {\n return reply.status(400).send({ success: false, message: \"name is required\" });\n }\n if (!data.description) {\n return reply.status(400).send({ success: false, message: \"description is required\" });\n }\n\n const id = (request.body as any).id || data.name;\n if (id !== data.name) {\n return reply.status(400).send({\n success: false,\n message: `id \"${id}\" must equal name \"${data.name}\"`,\n });\n }\n\n const skill = await skillService.createSkill(request, id, data);\n return reply.status(201).send({\n success: true,\n message: \"Successfully created skill\",\n data: serializeSkill(skill),\n });\n } catch (error: any) {\n if (error.message?.includes(\"already exists\")) {\n return reply.status(409).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"must equal name\") || error.message?.includes(\"Invalid skill name\")) {\n return reply.status(400).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to create skill: ${error.message}` });\n }\n}\n\nexport async function updateSkill(\n request: FastifyRequest<{ Params: { id: string }; Body: SkillUpdateBody }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const updates = request.body;\n\n const skill = await skillService.updateSkill(request, id, updates);\n\n if (!skill) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully updated skill\", data: serializeSkill(skill) };\n } catch (error: any) {\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n if (error.message?.includes(\"Invalid skill name\")) {\n return reply.status(400).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to update skill: ${error.message}` });\n }\n}\n\nexport async function deleteSkill(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n try {\n const { id } = request.params;\n const result = await skillService.deleteSkill(request, id);\n\n if (!result) {\n return reply.status(404).send({ success: false, message: \"Skill not found\" });\n }\n\n return { success: true, message: \"Successfully deleted skill\" };\n } catch (error: any) {\n if (error.message?.includes(\"built-in skill\")) {\n return reply.status(403).send({ success: false, message: error.message });\n }\n return reply.status(500).send({ success: false, message: `Failed to delete skill: ${error.message}` });\n }\n}\n\nexport async function searchSkillsByMetadata(\n request: FastifyRequest<{ Querystring: { key: string; value: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { key, value } = request.query;\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.searchByMetadata(request, key, value);\n return {\n success: true,\n message: \"Successfully searched skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function filterSkillsByCompatibility(\n request: FastifyRequest<{ Querystring: { compatibility: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { compatibility } = request.query;\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.filterByCompatibility(request, compatibility);\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n\nexport async function filterSkillsByLicense(\n request: FastifyRequest<{ Querystring: { license: string } }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { license } = request.query;\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: { records: [], total: 0 },\n });\n }\n\n const skills = await skillService.filterByLicense(request, license);\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: { records: skills.map(serializeSkill), total: skills.length },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: { records: [], total: 0 },\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { toolLatticeManager } from \"@axiom-lattice/core\";\nimport type {\n ToolConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Tools Controller\n * Handles tool-related operations\n */\n\n/**\n * Tool config meta response interface\n */\ninterface ToolConfigMetaResponse {\n success: boolean;\n message: string;\n data: {\n records: Array<{\n id: string;\n name: string;\n description: string;\n schema?: any; // Serialized schema\n returnDirect?: boolean;\n needUserApprove?: boolean;\n }>;\n total: number;\n };\n}\n\n/**\n * Serialize ZodSchema to JSON-serializable format\n * Attempts to extract schema information for API response\n */\nfunction serializeSchema(schema: any): any {\n if (!schema) {\n return undefined;\n }\n\n try {\n // Try to get JSON schema if available (zod-to-json-schema or similar)\n if (schema._def) {\n // For Zod schemas, try to extract basic info\n const def = schema._def;\n if (def.typeName === \"ZodObject\") {\n // Extract shape information\n const shape = def.shape();\n const properties: Record<string, any> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n const fieldDef = (value as any)._def;\n if (fieldDef) {\n properties[key] = {\n type: fieldDef.typeName === \"ZodString\" ? \"string\" :\n fieldDef.typeName === \"ZodNumber\" ? \"number\" :\n fieldDef.typeName === \"ZodBoolean\" ? \"boolean\" :\n fieldDef.typeName === \"ZodArray\" ? \"array\" :\n fieldDef.typeName === \"ZodObject\" ? \"object\" : \"unknown\",\n description: fieldDef.description,\n };\n if (!(value as any).isOptional()) {\n required.push(key);\n }\n }\n }\n\n return {\n type: \"object\",\n properties,\n required: required.length > 0 ? required : undefined,\n };\n }\n }\n\n // Fallback: return schema description or type name\n return {\n type: \"object\",\n description: schema.description || \"Schema definition\",\n };\n } catch (error) {\n // If serialization fails, return a safe fallback\n return {\n type: \"object\",\n description: \"Schema definition\",\n };\n }\n}\n\n/**\n * Get tool config meta from ToolLatticeManager\n * Exposes tool configuration metadata via /api/tools endpoint\n */\nexport async function getToolConfigs(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ToolConfigMetaResponse> {\n try {\n const allLattices = toolLatticeManager.getAllLattices();\n \n const toolConfigs = allLattices.map((lattice) => {\n const config = { ...lattice.config };\n \n // Serialize schema if present\n const serializedSchema = config.schema ? serializeSchema(config.schema) : undefined;\n\n return {\n id: lattice.key,\n name: config.name,\n description: config.description,\n schema: serializedSchema,\n returnDirect: config.returnDirect,\n needUserApprove: config.needUserApprove,\n };\n });\n\n return reply.send({\n success: true,\n message: \"Successfully retrieved tool configs\",\n data: {\n records: toolConfigs,\n total: toolConfigs.length,\n },\n });\n } catch (error: any) {\n console.error(\"Failed to get tool configs\", {\n error: error.message,\n stack: error.stack,\n });\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tool configs: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n metricsServerManager,\n SemanticMetricsClient,\n} from \"@axiom-lattice/core\";\nimport type {\n MetricsServerConfigStore,\n SemanticMetricsServerConfig,\n SemanticMetricsFilter,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Get tenant ID from request headers\n */\nfunction getTenantId(request: FastifyRequest): string {\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Data query request body\n */\ninterface DataQueryRequest {\n serverKey?: string;\n datasourceId?: string;\n metrics?: string[];\n groupBy?: string[];\n filters?: Array<{\n dimension: string;\n operator: string;\n values: (string | number | boolean)[];\n }>;\n customSql?: string;\n params?: Record<string, string | number | boolean>;\n limit?: number;\n}\n\n/**\n * Data query response - 只返回原始数据\n */\ninterface DataQueryResponse {\n success: boolean;\n message: string;\n data?: {\n // 语义查询结果\n semanticModel?: string;\n columns: Array<{ name: string; type: string }>;\n rows?: Array<Array<unknown>>;\n rowsObject?: Array<Record<string, unknown>>;\n // SQL 查询结果\n tableName?: string;\n executedSql?: string;\n // 通用元数据\n metadata: {\n rowCount: number;\n executionTimeMs?: number;\n };\n };\n}\n\n/**\n * Execute data query (semantic or SQL)\n */\nexport async function executeDataQuery(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as DataQueryRequest;\n\n try {\n // Validate request\n if (!body.serverKey && !body.datasourceId) {\n reply.code(400);\n return {\n success: false,\n message: \"Either serverKey or datasourceId must be provided\",\n };\n }\n\n // Determine query type\n const isSemanticQuery = body.metrics && body.metrics.length > 0;\n const isSqlQuery = body.customSql && body.customSql.trim().length > 0;\n\n if (!isSemanticQuery && !isSqlQuery) {\n reply.code(400);\n return {\n success: false,\n message: \"Either metrics (for semantic query) or customSql (for SQL query) must be provided\",\n };\n }\n\n if (isSemanticQuery && isSqlQuery) {\n reply.code(400);\n return {\n success: false,\n message: \"Cannot provide both metrics and customSql. Use one query type only.\",\n };\n }\n\n // Get server config\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n if (!body.serverKey) {\n reply.code(400);\n return {\n success: false,\n message: \"serverKey is required\",\n };\n }\n\n const config = await store.getConfigByKey(tenantId, body.serverKey);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: `Metrics server configuration not found: ${body.serverKey}`,\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint only supports semantic metrics servers\",\n };\n }\n\n if (!body.datasourceId) {\n reply.code(400);\n return {\n success: false,\n message: \"datasourceId is required\",\n };\n }\n\n // Check if server is registered\n if (!metricsServerManager.hasServer(tenantId, body.serverKey)) {\n reply.code(400);\n return {\n success: false,\n message: `Metrics server not registered: ${body.serverKey}. Please register the server first.`,\n };\n }\n\n // Get client from manager (read-only, no registration)\n const client = metricsServerManager.getClient(tenantId, body.serverKey) as SemanticMetricsClient;\n\n // Execute query based on type\n if (isSemanticQuery) {\n return await executeSemanticQuery(client, body, reply);\n } else {\n return await executeSqlQuery(client, body, reply);\n }\n } catch (error) {\n console.error(\"Failed to execute data query:\", error);\n reply.code(500);\n return {\n success: false,\n message: `Failed to execute data query: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Execute semantic query\n */\nasync function executeSemanticQuery(\n client: SemanticMetricsClient,\n body: DataQueryRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const semanticFilters: SemanticMetricsFilter[] = (body.filters || []).map(f => ({\n dimension: f.dimension,\n operator: f.operator,\n values: f.values,\n }));\n\n const result = await client.semanticQuery({\n datasourceId: body.datasourceId!,\n metrics: body.metrics!,\n groupBy: body.groupBy,\n filters: semanticFilters,\n limit: body.limit || 1000,\n });\n\n // 直接返回原始数据,不做 ECharts 转换\n return {\n success: true,\n message: \"Semantic query executed successfully\",\n data: {\n semanticModel: result.semanticModel,\n columns: result.columns,\n rows: result.rows,\n rowsObject: result.rowsObject,\n metadata: {\n rowCount: result.rowCount,\n executionTimeMs: result.executionTimeMs,\n },\n },\n };\n}\n\n/**\n * Execute SQL query\n */\nasync function executeSqlQuery(\n client: SemanticMetricsClient,\n body: DataQueryRequest,\n reply: FastifyReply\n): Promise<DataQueryResponse> {\n const result = await client.executeSqlQuery({\n datasourceId: body.datasourceId!,\n customSql: body.customSql!,\n params: body.params,\n limit: body.limit || 100,\n });\n\n // 直接返回原始数据,不做 ECharts 转换\n return {\n success: true,\n message: \"SQL query executed successfully\",\n data: {\n tableName: result.tableName,\n columns: result.columns.map(name => ({ name, type: 'unknown' })),\n rows: result.rows,\n rowsObject: result.rowsObject,\n executedSql: result.executedSql,\n metadata: {\n rowCount: result.rowCount,\n executionTimeMs: result.executionTimeMs,\n },\n },\n };\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice, agentInstanceManager } from \"@axiom-lattice/core\";\nimport type { WorkflowTrackingStore, WorkflowRun, RunStep } from \"@axiom-lattice/protocols\";\n\nfunction getTenantId(request: FastifyRequest): string {\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) return userTenantId;\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\nfunction getTrackingStore(): WorkflowTrackingStore | null {\n try {\n const storeLattice = getStoreLattice(\"default\", \"workflowTracking\");\n return storeLattice.store;\n } catch {\n return null;\n }\n}\n\ninterface ApiResponse<T = any> {\n success: boolean;\n message: string;\n data?: T;\n}\n\nasync function getDefinitionsFromAssistants(tenantId: string): Promise<Array<{\n assistantId: string;\n assistantName: string;\n topologyEdges: { from: string; to: string; purpose: string }[];\n totalEdges: number;\n}>> {\n try {\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const assistants = await assistantStore.getAllAssistants(tenantId);\n\n const results: Array<{\n assistantId: string;\n assistantName: string;\n topologyEdges: { from: string; to: string; purpose: string }[];\n totalEdges: number;\n }> = [];\n\n for (const a of assistants) {\n const def = a.graphDefinition;\n if (!def || def.type !== \"processing\") continue;\n if (!def.middleware) continue;\n for (const mw of def.middleware) {\n if (mw.type === \"topology\" && mw.enabled && mw.config?.edges?.length > 0) {\n results.push({\n assistantId: a.id,\n assistantName: a.name,\n topologyEdges: mw.config.edges,\n totalEdges: mw.config.edges.length,\n });\n }\n }\n }\n return results;\n } catch {\n return [];\n }\n}\n\nexport async function getAllWorkflowDefinitions(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: any[] }>> {\n const tenantId = getTenantId(request);\n\n try {\n // Get definitions from assistant configs (always available, even before first run)\n const configDefs = await getDefinitionsFromAssistants(tenantId);\n\n if (configDefs.length === 0) {\n return {\n success: true,\n message: \"No workflow definitions found\",\n data: { records: [] },\n };\n }\n\n // Merge in run-derived data (lastRunAt, runCount) if tracking store exists\n const runMap = new Map<string, { lastRunAt?: string; runCount: number }>();\n try {\n const store = getTrackingStore();\n if (store) {\n const runs = await store.getWorkflowRunsByTenantId(tenantId);\n for (const r of runs) {\n const entry = runMap.get(r.assistantId) || { runCount: 0 };\n entry.runCount++;\n if (!entry.lastRunAt || new Date(r.startedAt) > new Date(entry.lastRunAt)) {\n entry.lastRunAt = r.startedAt instanceof Date ? r.startedAt.toISOString() : String(r.startedAt);\n }\n runMap.set(r.assistantId, entry);\n }\n }\n } catch {\n // tracking store unavailable, definitions from config only\n }\n\n const definitions = configDefs.map((d) => {\n const runInfo = runMap.get(d.assistantId);\n return {\n ...d,\n lastRunAt: runInfo?.lastRunAt || null,\n runCount: runInfo?.runCount || 0,\n };\n });\n\n return {\n success: true,\n message: \"Successfully retrieved workflow definitions\",\n data: { records: definitions },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get workflow definitions\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve workflow definitions\" });\n }\n}\n\nexport async function getAllWorkflowRuns(\n request: FastifyRequest<{ Querystring: { assistantId?: string; status?: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: WorkflowRun[]; total: number }>> {\n const tenantId = getTenantId(request);\n const { assistantId, status } = request.query;\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n let runs: WorkflowRun[];\n if (assistantId) {\n runs = await store.getWorkflowRunsByAssistantId(tenantId, assistantId);\n } else {\n runs = await store.getWorkflowRunsByTenantId(tenantId);\n }\n\n if (status) {\n runs = runs.filter(r => r.status === status);\n }\n\n return {\n success: true,\n message: \"Successfully retrieved workflow runs\",\n data: { records: runs, total: runs.length },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get workflow runs\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve workflow runs\" });\n }\n}\n\n// GET /api/workflows/inbox\nexport async function getInboxItems(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: any[] }>> {\n const tenantId = getTenantId(request);\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return { success: true, message: \"No tracking store configured\", data: { records: [] } };\n }\n\n // Resolve assistant names\n const nameMap: Record<string, string> = {};\n try {\n const asStoreLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = asStoreLattice.store;\n const assistants = await assistantStore.getAllAssistants(tenantId);\n for (const a of assistants) {\n nameMap[a.id] = a.name;\n }\n } catch {\n // names unavailable, will fall back to ID\n }\n\n const runs = await store.getWorkflowRunsByTenantId(tenantId);\n const runningRuns = runs.filter(r => r.status === \"running\");\n if (runningRuns.length === 0) {\n return { success: true, message: \"No running workflows\", data: { records: [] } };\n }\n\n const inboxItems: any[] = [];\n for (const r of runningRuns) {\n try {\n const agent = agentInstanceManager.getAgent({\n assistant_id: r.assistantId,\n thread_id: r.threadId,\n tenant_id: r.tenantId,\n });\n const runStatus = await agent.getRunStatus();\n\n if (runStatus !== \"interrupted\") continue;\n\n const state = await agent.getCurrentState();\n const interrupts = state.tasks\n ?.flatMap((t: any) => t.interrupts || []) || [];\n\n for (const i of interrupts) {\n inboxItems.push({\n runId: r.id,\n assistantId: r.assistantId,\n assistantName: nameMap[r.assistantId] || r.assistantId,\n threadId: r.threadId,\n tenantId: r.tenantId,\n interruptId: i.id,\n interruptValue: i.value,\n startedAt: r.startedAt,\n totalEdges: r.totalEdges,\n completedEdges: r.completedEdges,\n });\n }\n } catch {\n // agent unavailable, skip\n }\n }\n\n inboxItems.sort((a, b) =>\n new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()\n );\n\n return {\n success: true,\n message: \"Successfully retrieved inbox items\",\n data: { records: inboxItems },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get inbox items\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve inbox items\" });\n }\n}\n\nexport async function getWorkflowDefinitions(\n request: FastifyRequest<{ Params: { assistantId: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: any[] }>> {\n const { assistantId } = request.params;\n const tenantId = getTenantId(request);\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n const runs = await store.getWorkflowRunsByAssistantId(tenantId, assistantId);\n const seen = new Set<string>();\n const definitions = runs\n .filter(r => {\n const key = JSON.stringify(r.topologyEdges);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map(r => ({\n assistantId: r.assistantId,\n topologyEdges: r.topologyEdges,\n totalEdges: r.totalEdges,\n lastRunAt: r.startedAt,\n }));\n\n return {\n success: true,\n message: \"Successfully retrieved workflow definitions\",\n data: { records: definitions },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get workflow definitions\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve workflow definitions\" });\n }\n}\n\nexport async function getWorkflowRuns(\n request: FastifyRequest<{ Params: { assistantId: string; threadId: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: WorkflowRun[]; total: number }>> {\n const { threadId } = request.params;\n const tenantId = getTenantId(request);\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n const runs = await store.getWorkflowRunsByThreadId(tenantId, threadId);\n return {\n success: true,\n message: \"Successfully retrieved workflow runs\",\n data: { records: runs, total: runs.length },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get workflow runs\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve workflow runs\" });\n }\n}\n\nexport async function getWorkflowRun(\n request: FastifyRequest<{ Params: { runId: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<WorkflowRun>> {\n const { runId } = request.params;\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n const run = await store.getWorkflowRun(runId);\n if (!run) {\n return reply.status(404).send({ success: false, message: \"Workflow run not found\" });\n }\n\n return { success: true, message: \"Successfully retrieved workflow run\", data: run };\n } catch (error) {\n request.log.error(error, \"Failed to get workflow run\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve workflow run\" });\n }\n}\n\nexport async function getRunSteps(\n request: FastifyRequest<{ Params: { runId: string }; Querystring: { step_type?: string; status?: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: RunStep[]; total: number }>> {\n const { runId } = request.params;\n const { step_type, status: stepStatus } = request.query;\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n let steps: RunStep[];\n if (step_type) {\n steps = await store.getRunStepsByType(runId, step_type as any);\n } else {\n steps = await store.getRunSteps(runId);\n }\n\n if (stepStatus) {\n steps = steps.filter(s => s.status === stepStatus);\n }\n\n return {\n success: true,\n message: \"Successfully retrieved run steps\",\n data: { records: steps, total: steps.length },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get run steps\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve run steps\" });\n }\n}\n\nexport async function getRunTasks(\n request: FastifyRequest<{ Params: { runId: string } }>,\n reply: FastifyReply\n): Promise<ApiResponse<{ records: RunStep[]; total: number }>> {\n const { runId } = request.params;\n\n try {\n const store = getTrackingStore();\n if (!store) {\n return reply.status(404).send({ success: false, message: \"No workflow tracking store configured\" });\n }\n\n const steps = await store.getInterruptedSteps(runId);\n return {\n success: true,\n message: \"Successfully retrieved user tasks\",\n data: { records: steps, total: steps.length },\n };\n } catch (error) {\n request.log.error(error, \"Failed to get run tasks\");\n return reply.status(500).send({ success: false, message: \"Failed to retrieve user tasks\" });\n }\n}\n","import { FastifySchema } from \"fastify\";\n\nexport const dataQuerySchema: FastifySchema = {\n description: \"Execute data query (semantic or SQL)\",\n tags: [\"Data Query\"],\n summary: \"Query Data\",\n body: {\n type: \"object\",\n properties: {\n serverKey: { \n type: \"string\", \n description: \"Target semantic metrics server key (optional if configured in runConfig)\" \n },\n datasourceId: { \n type: \"string\", \n description: \"Data source ID (optional if configured in runConfig)\" \n },\n // Semantic query parameters\n metrics: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of metric names for semantic query\"\n },\n groupBy: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional array of dimensions to group by\"\n },\n filters: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n dimension: { type: \"string\" },\n operator: { type: \"string\" },\n values: {\n type: \"array\",\n items: { type: [\"string\", \"number\", \"boolean\"] }\n }\n },\n required: [\"dimension\", \"operator\", \"values\"]\n },\n description: \"Optional array of filters\"\n },\n // SQL query parameters\n customSql: {\n type: \"string\",\n description: \"Custom SQL query string with named parameters\"\n },\n params: {\n type: \"object\",\n additionalProperties: { type: [\"string\", \"number\", \"boolean\"] },\n description: \"Optional parameters for SQL query\"\n },\n // Common parameters\n limit: {\n type: \"number\",\n description: \"Maximum number of results (default: 1000)\"\n },\n format: {\n type: \"string\",\n enum: [\"echarts\", \"raw\"],\n description: \"Response format (default: echarts)\"\n }\n }\n },\n // Response schema temporarily removed - format not yet finalized\n // TODO: Add proper response schema once data format is confirmed\n};\n","import { FastifySchema } from \"fastify\";\n\n// Create Run Schemas\nexport const createRunSchema: FastifySchema = {\n description: \"Create a new agent run\",\n tags: [\"Runs\"],\n summary: \"Create Agent Run\",\n body: {\n type: \"object\",\n properties: {\n thread_id: { type: \"string\", description: \"Thread ID\" },\n assistant_id: { type: \"string\", description: \"Assistant ID\" },\n message: { type: \"string\", description: \"Message data for the run\" },\n command: {\n type: \"object\",\n description: \"Command data for the run\",\n nullable: true,\n },\n streaming: {\n type: \"boolean\",\n description: \"Whether to stream the response\",\n nullable: true,\n },\n background: {\n type: \"boolean\",\n description: \"Whether to run in background\",\n nullable: true,\n },\n },\n required: [\"thread_id\", \"assistant_id\", \"message\"],\n },\n response: {\n 200: {},\n 400: {},\n },\n};\n\n// Memory Schemas\nexport const getAllMemoryItemsSchema: FastifySchema = {\n description: \"Get all memory items for an assistant thread\",\n tags: [\"Memory\"],\n summary: \"Get All Memory Items\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n thread_id: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"thread_id\"],\n },\n response: {\n 200: {},\n 400: {},\n 500: {},\n },\n};\n\nexport const getAgentStateSchema: FastifySchema = {\n description: \"Get agent state for an assistant thread\",\n tags: [\"Memory\"],\n summary: \"Get Agent State\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n thread_id: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"thread_id\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const getMemoryItemSchema: FastifySchema = {\n description: \"Get a specific memory item by key\",\n tags: [\"Memory\"],\n summary: \"Get Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const setMemoryItemSchema: FastifySchema = {\n description: \"Set or update a memory item\",\n tags: [\"Memory\"],\n summary: \"Set Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n body: {\n type: \"object\",\n description: \"Memory item data\",\n },\n response: {\n 200: {},\n },\n};\n\nexport const deleteMemoryItemSchema: FastifySchema = {\n description: \"Delete a specific memory item\",\n tags: [\"Memory\"],\n summary: \"Delete Memory Item\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n key: { type: \"string\", description: \"Memory key\" },\n },\n required: [\"assistantId\", \"key\"],\n },\n response: {\n 200: {},\n },\n};\n\nexport const clearMemorySchema: FastifySchema = {\n description: \"Clear all memory items for an assistant\",\n tags: [\"Memory\"],\n summary: \"Clear Memory\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n },\n required: [\"assistantId\"],\n },\n response: {\n 200: {},\n },\n};\n\n// Graph Schema\nexport const getAgentGraphSchema: FastifySchema = {\n description: \"Get agent graph visualization\",\n tags: [\"Graph\"],\n summary: \"Get Agent Graph\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n },\n required: [\"assistantId\"],\n },\n response: {\n 200: {},\n },\n};\n\n// Resume Stream Schema\nexport const resumeStreamSchema: FastifySchema = {\n description: \"Resume streaming from a known position\",\n tags: [\"Streaming\"],\n summary: \"Resume Stream\",\n body: {\n type: \"object\",\n properties: {\n thread_id: { type: \"string\", description: \"Thread ID\" },\n message_id: {\n type: \"string\",\n description: \"Message ID (usually run_id)\",\n },\n known_content: {\n type: \"string\",\n description: \"Content already received\",\n },\n poll_interval: {\n type: \"number\",\n description: \"Polling interval in milliseconds\",\n nullable: true,\n default: 100,\n },\n },\n required: [\"thread_id\", \"message_id\"],\n },\n response: {\n 200: {},\n 400: {},\n 500: {},\n },\n};\n\n// Trigger Agent Task Schema\nexport const triggerAgentTaskSchema: FastifySchema = {\n description: \"Trigger an agent task\",\n tags: [\"Agent Tasks\"],\n summary: \"Trigger Agent Task\",\n body: {\n type: \"object\",\n properties: {\n assistant_id: {\n type: \"string\",\n description: \"Assistant ID\",\n },\n thread_id: {\n type: \"string\",\n description: \"Thread ID\",\n },\n input: {\n type: \"object\",\n description: \"Task input data\",\n },\n command: {\n type: \"object\",\n description: \"Command data for the task\",\n nullable: true,\n },\n },\n required: [\"assistant_id\", \"thread_id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n result: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Configuration Schemas\nexport const updateConfigSchema: FastifySchema = {\n description: \"Update gateway configuration\",\n tags: [\"Configuration\"],\n summary: \"Update Configuration\",\n body: {\n type: \"object\",\n properties: {\n config: {\n type: \"object\",\n description: \"Configuration object to update\",\n properties: {\n port: { type: \"number\", description: \"Server port\" },\n queueServiceType: {\n type: \"string\",\n enum: [\"memory\", \"redis\"],\n description: \"Queue service type\",\n },\n redisUrl: { type: \"string\", description: \"Redis URL\" },\n redisPassword: { type: \"string\", description: \"Redis password\" },\n queueName: { type: \"string\", description: \"Queue name\" },\n },\n },\n },\n required: [\"config\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\nexport const getConfigSchema: FastifySchema = {\n description: \"Get current gateway configuration\",\n tags: [\"Configuration\"],\n summary: \"Get Configuration\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n data: { type: \"object\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Health Check Schema\nexport const getHealthSchema: FastifySchema = {\n description: \"Health check endpoint for monitoring and load balancer checks\",\n tags: [\"Health\"],\n summary: \"Health Check\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n data: {\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"healthy\", \"unhealthy\"] },\n timestamp: { type: \"string\" },\n uptime: { type: \"number\" },\n service: { type: \"string\" },\n version: { type: \"string\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n status: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n};\n\n// Skills Schemas\nexport const getSkillListSchema: FastifySchema = {\n description: \"Get list of all skills\",\n tags: [\"Skills\"],\n summary: \"Get Skill List\",\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const getSkillSchema: FastifySchema = {\n description: \"Get a single skill by ID\",\n tags: [\"Skills\"],\n summary: \"Get Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const createSkillSchema: FastifySchema = {\n description: \"Create a new skill\",\n tags: [\"Skills\"],\n summary: \"Create Skill\",\n body: {\n type: \"object\",\n properties: {\n id: { \n type: \"string\", \n description: \"Skill ID (optional, defaults to name if not provided; must equal name, name is used for path addressing)\" \n },\n name: { \n type: \"string\", \n description: \"Skill name (1-64 chars, lowercase alphanumeric with single hyphens, pattern: ^[a-z0-9]+(-[a-z0-9]+)*$)\",\n pattern: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n minLength: 1,\n maxLength: 64\n },\n description: { type: \"string\", description: \"Skill description\" },\n license: { type: \"string\", description: \"License information\" },\n compatibility: { type: \"string\", description: \"Compatibility information\" },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Additional metadata\",\n },\n content: { type: \"string\", description: \"Skill detailed content (markdown)\" },\n subSkills: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of sub-skill names (hierarchical structure)\",\n },\n },\n required: [\"name\", \"description\"],\n },\n response: {\n 201: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 409: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const updateSkillSchema: FastifySchema = {\n description: \"Update an existing skill\",\n tags: [\"Skills\"],\n summary: \"Update Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n body: {\n type: \"object\",\n properties: {\n name: { \n type: \"string\", \n description: \"Skill name (1-64 chars, lowercase alphanumeric with single hyphens, pattern: ^[a-z0-9]+(-[a-z0-9]+)*$)\",\n pattern: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n minLength: 1,\n maxLength: 64\n },\n description: { type: \"string\", description: \"Skill description\" },\n license: { type: \"string\", description: \"License information\" },\n compatibility: { type: \"string\", description: \"Compatibility information\" },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n description: \"Additional metadata\",\n },\n content: { type: \"string\", description: \"Skill detailed content (markdown)\" },\n subSkills: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of sub-skill names (hierarchical structure)\",\n },\n },\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: { type: \"object\" },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const deleteSkillSchema: FastifySchema = {\n description: \"Delete a skill by ID\",\n tags: [\"Skills\"],\n summary: \"Delete Skill\",\n params: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Skill ID\" },\n },\n required: [\"id\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\nexport const searchSkillsByMetadataSchema: FastifySchema = {\n description: \"Search skills by metadata\",\n tags: [\"Skills\"],\n summary: \"Search Skills by Metadata\",\n querystring: {\n type: \"object\",\n properties: {\n key: { type: \"string\", description: \"Metadata key\" },\n value: { type: \"string\", description: \"Metadata value\" },\n },\n required: [\"key\", \"value\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const filterSkillsByCompatibilitySchema: FastifySchema = {\n description: \"Filter skills by compatibility\",\n tags: [\"Skills\"],\n summary: \"Filter Skills by Compatibility\",\n querystring: {\n type: \"object\",\n properties: {\n compatibility: { type: \"string\", description: \"Compatibility string\" },\n },\n required: [\"compatibility\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const filterSkillsByLicenseSchema: FastifySchema = {\n description: \"Filter skills by license\",\n tags: [\"Skills\"],\n summary: \"Filter Skills by License\",\n querystring: {\n type: \"object\",\n properties: {\n license: { type: \"string\", description: \"License string\" },\n },\n required: [\"license\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 400: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n 500: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n records: {\n type: \"array\",\n items: { type: \"object\" },\n },\n total: { type: \"number\" },\n },\n },\n },\n },\n },\n};\n\nexport const getSandboxUrlSchema: FastifySchema = {\n description: \"Get sandbox URL based on assistant and thread configuration\",\n tags: [\"Sandbox\"],\n summary: \"Get Sandbox URL\",\n params: {\n type: \"object\",\n properties: {\n assistantId: { type: \"string\", description: \"Assistant ID\" },\n threadId: { type: \"string\", description: \"Thread ID\" },\n },\n required: [\"assistantId\", \"threadId\"],\n },\n response: {\n 200: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n data: {\n type: \"object\",\n properties: {\n sandboxUrl: { type: \"string\", description: \"Sandbox URL\" },\n sandboxName: { type: \"string\", description: \"Sandbox name\" },\n vmIsolation: {\n type: \"string\",\n enum: [\"agent\", \"project\", \"global\"],\n description: \"Sandbox isolation level\",\n },\n },\n },\n },\n },\n 404: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\" },\n message: { type: \"string\" },\n },\n },\n },\n};\n\n// Data Query Schema\nexport { dataQuerySchema } from \"./data-query\";\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agentInstanceManager } from \"@axiom-lattice/core\";\n\n/**\n * DELETE /api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id\n * Remove pending message from queue\n */\nexport async function removePendingMessageHandler(\n request: FastifyRequest,\n reply: FastifyReply\n) {\n try {\n const { assistant_id, thread_id, message_id } = request.params as {\n assistant_id: string;\n thread_id: string;\n message_id: string;\n };\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const workspace_id = request.headers[\"x-workspace-id\"] as string;\n const project_id = request.headers[\"x-project-id\"] as string;\n\n if (!tenant_id) {\n return reply.code(400).send({ error: \"Missing x-tenant-id header\" });\n }\n\n if (!assistant_id) {\n return reply.code(400).send({ error: \"Missing assistant_id parameter\" });\n }\n\n // Get agent instance\n const agent = agentInstanceManager.getAgent({\n assistant_id,\n thread_id,\n tenant_id,\n workspace_id,\n project_id,\n });\n\n if (!agent) {\n return reply.code(404).send({\n error: \"Thread not found\",\n threadId: thread_id,\n });\n }\n\n const success = await agent.removePendingMessage(message_id);\n\n if (!success) {\n return reply.code(404).send({\n error: \"Message not found\",\n messageId: message_id,\n });\n }\n\n return reply.send({\n success: true,\n messageId: message_id,\n });\n } catch (error) {\n console.error(\"Error removing pending message:\", error);\n return reply.code(500).send({\n error: \"Internal server error\",\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\n","import { agentLatticeManager, getSandBoxManager, normalizeSandboxName, sandboxLatticeManager } from \"@axiom-lattice/core\";\nimport { SandboxMiddlewareConfig } from \"@axiom-lattice/protocols\";\n\n\nconst ERROR_HTML = `<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Sandbox 连接错误</title>\n <style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n .container {\n background: white;\n border-radius: 16px;\n padding: 40px;\n max-width: 500px;\n width: 100%;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n }\n .error-icon {\n width: 80px;\n height: 80px;\n background: #fee2e2;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .error-icon svg {\n width: 40px;\n height: 40px;\n color: #dc2626;\n }\n h1 { color: #1f2937; margin-bottom: 16px; text-align: center; }\n p { color: #6b7280; margin-bottom: 12px; line-height: 1.6; }\n .info {\n background: #f3f4f6;\n border-radius: 8px;\n padding: 16px;\n margin: 20px 0;\n }\n .info-item {\n display: flex;\n justify-content: space-between;\n padding: 8px 0;\n border-bottom: 1px solid #e5e7eb;\n }\n .info-item:last-child { border-bottom: none; }\n .label { color: #6b7280; font-size: 14px; }\n .value { color: #1f2937; font-weight: 500; font-family: monospace; }\n .retry-btn {\n width: 100%;\n padding: 14px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n cursor: pointer;\n transition: transform 0.2s;\n }\n .retry-btn:hover { transform: translateY(-2px); }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"/>\n </svg>\n </div>\n <h1>无法连接到 Sandbox</h1>\n <p>无法连接到沙箱环境,请检查配置后重试。</p>\n <div class=\"info\">\n <div class=\"info-item\">\n <span class=\"label\">Assistant ID</span>\n <span class=\"value\" id=\"assistantId\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">Thread ID</span>\n <span class=\"value\" id=\"threadId\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">隔离级别</span>\n <span class=\"value\" id=\"vmIsolation\">-</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">错误信息</span>\n <span class=\"value\" id=\"errorMsg\">-</span>\n </div>\n </div>\n <button class=\"retry-btn\" onclick=\"window.location.reload()\">重新连接</button>\n </div>\n <script>\n const params = new URLSearchParams(window.location.search);\n document.getElementById('assistantId').textContent = params.get('assistantId') || '-';\n document.getElementById('threadId').textContent = params.get('threadId') || '-';\n document.getElementById('vmIsolation').textContent = params.get('vmIsolation') || '-';\n document.getElementById('errorMsg').textContent = params.get('error') || '未知错误';\n </script>\n</body>\n</html>`;\n\nexport class SandboxService {\n\n getFilesystemVmIsolation(tenantId: string, assistantId: string): \"agent\" | \"project\" | \"global\" | null {\n const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);\n if (!agentLattice) {\n return null;\n }\n\n const filesystemConfig = agentLattice?.config?.middleware?.find((m: any) => m.type === \"filesystem\");\n if (!filesystemConfig) {\n return null;\n }\n\n const config = filesystemConfig.config as SandboxMiddlewareConfig;\n return config?.vmIsolation || null;\n }\n\n computeSandboxName(\n assistantId: string,\n threadId: string,\n vmIsolation: string,\n tenantId?: string,\n workspaceId?: string,\n projectId?: string,\n ): string {\n switch (vmIsolation) {\n case \"agent\":\n return normalizeSandboxName(`${tenantId ?? \"default\"}-${assistantId}`);\n case \"project\":\n return normalizeSandboxName(\n `${tenantId ?? \"default\"}-${workspaceId ?? \"default\"}-${projectId ?? \"default\"}`\n );\n case \"global\":\n default:\n return \"global\";\n }\n }\n\n private getBrowserSandboxBaseURL(): string {\n return process.env.AGENT_INFRA_SANDBOX_BASE_URL || \"http://localhost:8080\";\n }\n\n getTargetUrl(sandboxName: string): string {\n return `${this.getBrowserSandboxBaseURL()}/sandbox/${sandboxName}`;\n }\n\n async getVncHtml(sandboxName: string): Promise<string> {\n const response = await fetch(`${this.getTargetUrl(sandboxName)}/vnc/index.html`);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch VNC HTML: ${response.statusText}`);\n }\n\n return response.text();\n }\n\n rewriteHtml(\n html: string,\n assistantId: string,\n threadId: string\n ): string {\n const prefix = `/api/assistants/${assistantId}/threads/${threadId}/sandbox/vnc`;\n\n let rewritten = html;\n\n rewritten = rewritten.replace(\n /(src|href)=[\"']([^\"']*)[\"']/g,\n (match, attr, url) => {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\") || url.startsWith(\"//\")) {\n return match;\n }\n const rewrittenUrl = url.startsWith(\"/\") ? `${prefix}${url}` : `${prefix}/${url}`;\n return `${attr}=\"${rewrittenUrl}\"`;\n }\n );\n\n rewritten = rewritten.replace(\n /path=sandbox\\/[^&\"']+/g,\n (match) => {\n return `path=${prefix}/websockify`;\n }\n );\n\n rewritten = rewritten.replace(\n /new WebSocket\\([^)]*\\?path=sandbox[^)]*\\)/g,\n (match) => {\n return match.replace(/path=sandbox[^)]+/, `path=${prefix}/websockify`);\n }\n );\n\n return rewritten;\n }\n\n generateErrorHtml(\n assistantId: string,\n threadId: string,\n vmIsolation: string,\n errorMessage: string\n ): string {\n const encodedError = encodeURIComponent(errorMessage);\n return ERROR_HTML\n .replace(\"{assistantId}\", assistantId)\n .replace(\"{threadId}\", threadId)\n .replace(\"{vmIsolation}\", vmIsolation)\n .replace(\"{errorMessage}\", errorMessage);\n }\n}\n\nexport const sandboxService = new SandboxService();\n","import { FastifyInstance } from \"fastify\";\nimport { sandboxService } from \"../services/sandbox_service\";\nimport { getSandBoxManager } from \"@axiom-lattice/core\";\n\n/** Get filename from path (e.g. /home/gem/uploads/foo.pdf -> foo.pdf) */\nfunction getFilenameFromPath(path: string): string {\n const segments = path.replace(/\\/+$/, \"\").split(\"/\");\n return segments[segments.length - 1] || \"download\";\n}\n\n/** Common extension -> MIME type for download response */\nconst EXT_TO_MIME: Record<string, string> = {\n \".txt\": \"text/plain\",\n \".html\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n \".json\": \"application/json\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".zip\": \"application/zip\",\n \".csv\": \"text/csv\",\n \".xml\": \"application/xml\",\n};\n\nfunction getContentTypeFromFilename(filename: string): string {\n const ext = filename.includes(\".\") ? filename.slice(filename.lastIndexOf(\".\")).toLowerCase() : \"\";\n return EXT_TO_MIME[ext] ?? \"application/octet-stream\";\n}\n\ninterface SandboxParams {\n assistantId: string;\n threadId: string;\n}\n\ninterface ProxyParams extends SandboxParams {\n \"*\": string;\n}\n\ninterface ResourceParams extends SandboxParams {\n resourcePath: string;\n}\n\nexport function registerSandboxProxyRoutes(app: FastifyInstance): void {\n // Register uploadfile route FIRST before wildcard routes to ensure it matches\n app.post<{ Params: SandboxParams }>(\n \"/api/assistants/:assistantId/threads/:threadId/sandbox/uploadfile\",\n async (request, reply) => {\n console.log(\"[Sandbox Upload] Route matched:\", request.url);\n const { assistantId, threadId } = request.params;\n const tenantId = (request.headers[\"x-tenant-id\"] as string) || \"default\";\n\n const vmIsolation = sandboxService.getFilesystemVmIsolation(tenantId, assistantId);\n if (!vmIsolation) {\n return reply.status(500).send({ error: \"Assistant sandbox config not found\" });\n }\n\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n vmIsolation\n );\n\n const sandboxManager = getSandBoxManager()\n const sandbox = await sandboxManager.createSandbox(sandboxName)\n\n try {\n const data = await request.file();\n if (!data) {\n return reply.status(400).send({ error: \"No file in request\" });\n }\n\n const buffer = await data.toBuffer();\n const pathEntry = data.fields?.path;\n const pathValue =\n pathEntry && typeof pathEntry === \"object\" && \"value\" in pathEntry\n ? String((pathEntry as { value: unknown }).value)\n : typeof pathEntry === \"string\"\n ? pathEntry\n : undefined;\n\n const filePath = `/uploads/${pathValue ? pathValue : \"\"}${data.filename}`;\n try {\n await sandbox.file.uploadFile({ file: filePath, data: buffer });\n } catch (err) {\n reply.status(500).send({ error: String(err) });\n return;\n }\n\n const relativePath = filePath.replace(`~/`, \"\");\n const result = { id: relativePath, name: data.filename, size: buffer.length };\n\n return reply.status(200).send({ message: \"File uploaded successfully\", ...result });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ error: `Upload proxy error: ${message}` });\n }\n }\n );\n\n // Download file from sandbox: GET with query param path (file path in sandbox, e.g. /home/gem/uploads/foo.txt)\n app.get<{\n Params: SandboxParams;\n Querystring: { path: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId/sandbox/downloadfile\",\n async (request, reply) => {\n const { assistantId, threadId } = request.params;\n const { path: filePath } = request.query;\n const tenantId = (request.headers[\"x-tenant-id\"] as string) || \"default\";\n\n if (!filePath || typeof filePath !== \"string\") {\n return reply.status(400).send({ error: \"Query parameter 'path' is required\" });\n }\n\n const vmIsolation = sandboxService.getFilesystemVmIsolation(tenantId, assistantId);\n if (!vmIsolation) {\n return reply.status(500).send({ error: \"Assistant filesystem vmIsolation not found\" });\n }\n\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n vmIsolation\n );\n\n const sandboxManager = getSandBoxManager();\n const sandbox = await sandboxManager.createSandbox(sandboxName);\n\n try {\n // Normalize path to /-prefixed absolute path\n const resolvedPath = filePath.startsWith(\"/\") ? filePath : `/${filePath}`;\n const filename = getFilenameFromPath(resolvedPath);\n const inferredContentType = getContentTypeFromFilename(filename);\n\n try {\n const buf = await sandbox.file.downloadFile({ file: resolvedPath });\n const contentDisposition = `inline; filename=\"${filename.replace(/\"/g, '\\\\\"')}\"; filename*=UTF-8''${encodeURIComponent(filename)}`;\n reply = reply.status(200).type(inferredContentType).header(\"Content-Disposition\", contentDisposition).send(buf);\n return reply;\n } catch (err) {\n reply.status(500).send({ error: String(err) });\n return;\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ error: `Download proxy error: ${message}` });\n }\n }\n );\n\n // app.get<{ Params: SandboxParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/browser\",\n // async (request, reply) => {\n // const { assistantId, threadId } = request.params;\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // const errorHtml = sandboxService.generateErrorHtml(\n // assistantId,\n // threadId,\n // \"unknown\",\n // `Assistant ${assistantId} not found`\n // );\n // return reply.status(404).type(\"text/html\").send(errorHtml);\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // try {\n // const html = await sandboxService.getVncHtml(sandboxName);\n // const rewrittenHtml = sandboxService.rewriteHtml(html, assistantId, threadId);\n // return reply.type(\"text/html\").send(rewrittenHtml);\n // } catch (error: any) {\n // const errorHtml = sandboxService.generateErrorHtml(\n // assistantId,\n // threadId,\n // vmIsolation,\n // error.message || \"Failed to connect to sandbox\"\n // );\n // return reply.status(502).type(\"text/html\").send(errorHtml);\n // }\n // }\n // );\n\n\n // app.get<{ Params: SandboxParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/websockify\",\n // { websocket: true },\n\n // (connection, request) => {\n\n // const url = (connection?.url) as string;\n // console.log(`[WebSocket] Received connection from URL: ${url}`);\n\n // const urlMatch = url.match(/\\/api\\/assistants\\/([^/]+)\\/threads\\/([^/]+)\\/sandbox\\/websockify/);\n // if (!urlMatch) {\n // console.error(`[WebSocket] Failed to parse params from URL: ${url}`);\n // connection.close(1008, \"Invalid URL format\");\n // return;\n // }\n\n // const assistantId = urlMatch[1];\n // const threadId = urlMatch[2];\n // console.log(`[WebSocket] Parsed params - assistantId: ${assistantId}, threadId: ${threadId}`);\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // console.error(`[WebSocket] Assistant ${assistantId} not found`);\n // connection.close(1008, \"Assistant not found\");\n // return;\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // const targetUrl = sandboxService.getTargetUrl(sandboxName);\n // const targetWsUrl = targetUrl.replace(/^http/, \"ws\").replace(/^https/, \"wss\") + \"/websockify\";\n\n // console.log(`[WebSocket] Connecting to target: ${targetWsUrl}`);\n\n // const targetSocket = new WebSocket(targetWsUrl);\n // const clientStream = createWebSocketStream(connection, { encoding: \"utf8\" });\n\n // const targetStream = createWebSocketStream(targetSocket, { encoding: \"utf8\" });\n\n // const forward = pipeline(clientStream, targetStream);\n // const backward = pipeline(targetStream, clientStream);\n\n // Promise.all([forward, backward]).catch((err) => {\n // console.error(`[WebSocket] Proxy pipeline failed:`, err.message);\n // targetSocket.terminate();\n // connection.terminate();\n // });\n // }\n // );\n\n // app.get<{ Params: ProxyParams }>(\n // \"/api/assistants/:assistantId/threads/:threadId/sandbox/browser/vnc/*\",\n // async (request, reply) => {\n // const { assistantId, threadId, \"*\": restPath } = request.params;\n\n // const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n // if (!sandboxConfig) {\n // return reply.status(404).send(\"Assistant not found\");\n // }\n\n // const { vmIsolation } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // vmIsolation\n // );\n\n // const targetPath = restPath ? `/vnc/${restPath}` : \"/vnc/\";\n // const targetUrl = `${sandboxService.getTargetUrl(sandboxName)}${targetPath}`;\n\n // try {\n // const response = await fetch(targetUrl);\n // const contentType = response.headers.get(\"content-type\") || \"application/octet-stream\";\n\n // const body = await response.arrayBuffer();\n // reply.status(response.status).type(contentType).send(Buffer.from(body));\n // } catch (error: any) {\n // reply.status(502).send(`Proxy error: ${error.message}`);\n // }\n // }\n // );\n\n\n}\n","/**\n * WorkspaceController\n *\n * Controller for workspace and project management\n * Handles CRUD operations, file browsing, and file uploads\n */\n\nimport { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { SandboxFilesystem, FilesystemBackend } from \"@axiom-lattice/core\";\nimport { getSandBoxManager } from \"@axiom-lattice/core\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type {\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n CreateProjectRequest,\n UpdateProjectRequest,\n Workspace,\n Project,\n} from \"@axiom-lattice/protocols\";\n\ninterface WorkspaceParams {\n workspaceId: string;\n}\n\ninterface ProjectParams {\n workspaceId: string;\n projectId: string;\n}\n\ninterface ListPathQuery {\n path?: string;\n assistantId?: string;\n}\n\ninterface ReadFileQuery {\n path: string;\n offset?: number;\n limit?: number;\n assistantId?: string;\n}\n\nexport class WorkspaceController {\n private workspaceStore;\n private projectStore;\n\n constructor() {\n this.workspaceStore = getStoreLattice(\"default\", \"workspace\").store;\n this.projectStore = getStoreLattice(\"default\", \"project\").store;\n }\n\n private getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Try to get from query parameters (for direct URL access like file downloads)\n const queryTenantId = (request.query as any)?.tenantId;\n if (queryTenantId) {\n return String(queryTenantId);\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n }\n\n // ==================== Workspace CRUD ====================\n\n async listWorkspaces(request: FastifyRequest, reply: FastifyReply) {\n const tenantId = this.getTenantId(request);\n const workspaces = await this.workspaceStore.getAllWorkspaces(tenantId);\n return { success: true, data: workspaces };\n }\n\n async createWorkspace(\n request: FastifyRequest<{ Body: CreateWorkspaceRequest }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const data = request.body;\n const id = uuidv4();\n\n const workspace = await this.workspaceStore.createWorkspace(\n tenantId,\n id,\n data\n );\n\n return reply.status(201).send({ success: true, data: workspace });\n }\n\n async getWorkspace(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true, data: workspace };\n }\n\n async updateWorkspace(\n request: FastifyRequest<{\n Params: WorkspaceParams;\n Body: UpdateWorkspaceRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n const updates = request.body;\n\n const workspace = await this.workspaceStore.updateWorkspace(\n tenantId,\n workspaceId,\n updates\n );\n\n if (!workspace) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true, data: workspace };\n }\n\n async deleteWorkspace(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const deleted = await this.workspaceStore.deleteWorkspace(\n tenantId,\n workspaceId\n );\n\n if (!deleted) {\n return reply.status(404).send({ success: false, error: \"Workspace not found\" });\n }\n\n return { success: true };\n }\n\n // ==================== Project CRUD ====================\n\n async listProjects(\n request: FastifyRequest<{ Params: WorkspaceParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n\n const projects = await this.projectStore.getProjectsByWorkspace(\n tenantId,\n workspaceId\n );\n\n return { success: true, data: projects };\n }\n\n async createProject(\n request: FastifyRequest<{\n Params: WorkspaceParams;\n Body: CreateProjectRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId } = request.params;\n const data = request.body;\n const id = uuidv4();\n\n const project = await this.projectStore.createProject(\n tenantId,\n workspaceId,\n id,\n data\n );\n\n return reply.status(201).send({ success: true, data: project });\n }\n\n async getProject(\n request: FastifyRequest<{ Params: ProjectParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n\n const project = await this.projectStore.getProjectById(tenantId, projectId);\n\n if (!project) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true, data: project };\n }\n\n async updateProject(\n request: FastifyRequest<{\n Params: ProjectParams;\n Body: UpdateProjectRequest;\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n const updates = request.body;\n\n const project = await this.projectStore.updateProject(\n tenantId,\n projectId,\n updates\n );\n\n if (!project) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true, data: project };\n }\n\n async deleteProject(\n request: FastifyRequest<{ Params: ProjectParams }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { projectId } = request.params;\n\n const deleted = await this.projectStore.deleteProject(tenantId, projectId);\n\n if (!deleted) {\n return reply.status(404).send({ success: false, error: \"Project not found\" });\n }\n\n return { success: true };\n }\n\n // ==================== File Operations ====================\n\n private async getBackend(tenantId: string, workspaceId: string, projectId: string, assistantId?: string, filePath?: string) {\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n throw new Error(\"Workspace not found\");\n }\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, filePath || \"/project\");\n if (volumeBackend) {\n return { backend: volumeBackend, workspace };\n }\n\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n return {\n backend: new SandboxFilesystem({\n sandboxInstance: sandbox,\n }), workspace\n };\n } else {\n return {\n backend: new FilesystemBackend({\n rootDir: `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`,\n virtualMode: true,\n }), workspace\n };\n }\n }\n\n private getFilenameFromPath(filePath: string): string {\n const segments = filePath.split(\"/\");\n return segments[segments.length - 1] || \"download\";\n }\n\n private getMimeType(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase() || \"\";\n const mimeTypes: Record<string, string> = {\n pdf: \"application/pdf\",\n csv: \"text/csv\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n xls: \"application/vnd.ms-excel\",\n txt: \"text/plain\",\n json: \"application/json\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n html: \"text/html\",\n htm: \"text/html\",\n mp3: \"audio/mpeg\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n };\n return mimeTypes[ext] || \"application/octet-stream\";\n }\n\n private isBinaryContentType(filename: string): boolean {\n const ext = filename.split(\".\").pop()?.toLowerCase() || \"\";\n const binaryExtensions = new Set([\n \"pdf\", \"xlsx\", \"xls\", \"docx\", \"doc\", \"pptx\", \"ppt\",\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"bmp\", \"ico\", \"webp\",\n \"mp3\", \"mp4\", \"webm\", \"ogg\", \"wav\", \"avi\", \"mov\",\n \"zip\", \"tar\", \"gz\", \"rar\", \"7z\",\n ]);\n return binaryExtensions.has(ext);\n }\n\n async downloadFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { path: string; assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const filePath = request.query.path;\n const assistantId = request.query.assistantId;\n\n if (!filePath) {\n return reply.status(400).send({ success: false, error: \"Path is required\" });\n }\n\n try {\n const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);\n const resolvedPath = filePath;\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const filename = this.getFilenameFromPath(resolvedPath);\n const isBinary = this.isBinaryContentType(filename);\n\n // Try volume backend for text files; binary files must use sandbox\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);\n\n let buf: Buffer;\n if (volumeBackend && !isBinary) {\n const fileData = await volumeBackend.readRaw(resolvedPath);\n buf = Buffer.from(fileData.content.join(\"\\n\"), \"utf-8\");\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n buf = await sandbox.file.downloadFile({ file: resolvedPath });\n }\n\n const inferredContentType = this.getMimeType(filename);\n\n const contentDisposition = `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`;\n return reply.status(200).type(inferredContentType).header(\"Content-Disposition\", contentDisposition).send(buf);\n }\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);\n const content = await backend.read(resolvedPath, 0, Infinity);\n const filename = this.getFilenameFromPath(resolvedPath);\n const mimeType = this.getMimeType(filename);\n const buffer = Buffer.from(content, \"utf-8\");\n\n return reply\n .status(200)\n .type(mimeType)\n .header(\"Content-Disposition\", `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`)\n .send(buffer);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ success: false, error: `Download proxy error: ${message}` });\n }\n }\n\n /**\n * View a file inline in the browser (not download).\n * Returns file content with inline Content-Disposition for preview.\n */\n async viewFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { path: string; assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const filePath = request.query.path;\n const assistantId = request.query.assistantId;\n\n if (!filePath) {\n return reply.status(400).send({ success: false, error: \"Path is required\" });\n }\n\n try {\n const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);\n const resolvedPath = filePath;\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const filename = this.getFilenameFromPath(resolvedPath);\n const isBinary = this.isBinaryContentType(filename);\n\n // Try volume backend for text files; binary files must use sandbox\n // (volume backend's readRaw API is text-based and corrupts binary data)\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, resolvedPath);\n\n let buf: Buffer;\n if (volumeBackend && !isBinary) {\n const fileData = await volumeBackend.readRaw(resolvedPath);\n buf = Buffer.from(fileData.content.join(\"\\n\"), \"utf-8\");\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n buf = await sandbox.file.downloadFile({ file: resolvedPath });\n }\n\n const inferredContentType = this.getMimeType(filename);\n\n try {\n let contentType = inferredContentType;\n\n // Inject AI2APP context script for HTML files (sandbox storage)\n const isHtml = contentType?.toLowerCase().includes(\"text/html\") || \n filename.toLowerCase().endsWith(\".html\") || \n filename.toLowerCase().endsWith(\".htm\");\n let outputBuf = buf;\n if (isHtml) {\n console.log(`[viewFile] Injecting AI2APP context for sandbox HTML file: ${filename}, tenantId: ${tenantId}, contentType: ${contentType}`);\n let content = buf.toString(\"utf-8\");\n const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({\n tenantId,\n workspaceId,\n projectId,\n timestamp: Date.now()\n })};</script>`;\n \n if (content.toLowerCase().includes(\"</head>\")) {\n content = content.replace(/<\\/head>/i, `${contextScript}</head>`);\n console.log(`[viewFile] Context script injected before </head>`);\n } else if (content.toLowerCase().includes(\"<html>\")) {\n content = content.replace(/<html>/i, `<html>${contextScript}`);\n console.log(`[viewFile] Context script injected after <html>`);\n } else {\n content = contextScript + content;\n console.log(`[viewFile] Context script prepended to content`);\n }\n outputBuf = Buffer.from(content, \"utf-8\");\n }\n\n return reply\n .status(200)\n .type(contentType)\n .header(\"Content-Disposition\", \"inline\")\n .send(outputBuf);\n } catch (err) {\n return reply.status(502).send({ success: false, error: String(err) });\n }\n }\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, resolvedPath);\n const content = await backend.read(resolvedPath, 0, Infinity);\n const filename = this.getFilenameFromPath(resolvedPath);\n const mimeType = this.getMimeType(filename);\n\n // Inject AI2APP context script for HTML files\n let finalContent = content;\n const isHtmlFs = mimeType?.toLowerCase().includes(\"text/html\") || \n filename.toLowerCase().endsWith(\".html\") || \n filename.toLowerCase().endsWith(\".htm\");\n if (isHtmlFs) {\n console.log(`[viewFile] Injecting AI2APP context for filesystem HTML file: ${filename}, tenantId: ${tenantId}, mimeType: ${mimeType}`);\n const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({\n tenantId,\n workspaceId,\n projectId,\n timestamp: Date.now()\n })};</script>`;\n // Insert before </head> or </html>\n if (content.toLowerCase().includes(\"</head>\")) {\n finalContent = content.replace(/<\\/head>/i, `${contextScript}</head>`);\n console.log(`[viewFile] Context script injected before </head>`);\n } else if (content.toLowerCase().includes(\"</html>\")) {\n finalContent = content.replace(/<\\/html>/i, `${contextScript}</html>`);\n console.log(`[viewFile] Context script injected before </html>`);\n } else {\n finalContent = content + contextScript;\n console.log(`[viewFile] Context script appended to content`);\n }\n }\n\n const buffer = Buffer.from(finalContent, \"utf-8\");\n\n return reply\n .status(200)\n .type(mimeType)\n .header(\"Content-Disposition\", \"inline\")\n .send(buffer);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return reply.status(502).send({ success: false, error: `View proxy error: ${message}` });\n }\n }\n\n async listPath(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: ListPathQuery;\n }>\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const path = (request.query.path as string) || \"/\";\n const assistantId = request.query.assistantId;\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path);\n const files = await backend.lsInfo(path);\n\n return { success: true, data: files };\n }\n\n async readFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: ReadFileQuery;\n }>\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const { path, offset = 0, limit = 1000, assistantId } = request.query;\n\n const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path);\n const content = await backend.read(path, Number(offset), Number(limit));\n\n return { success: true, data: { content, offset, limit } };\n }\n\n /**\n * Upload a file to the workspace project storage.\n *\n * Route: POST /api/workspaces/:workspaceId/projects/:projectId/uploadfile\n * Accepts multipart/form-data with:\n * - `file`: the file to upload (required)\n * - `path`: optional directory path relative to project root (e.g., \"docs\", \"src/utils\")\n * - `assistantId`: optional query parameter for sandbox identity matching\n * For sandbox storage, delegates to the sandbox upload API.\n * For filesystem storage, writes directly under /lattice_store/workspaces/{workspaceId}/{projectId}.\n */\n async uploadFile(\n request: FastifyRequest<{\n Params: ProjectParams;\n Querystring: { assistantId?: string };\n }>,\n reply: FastifyReply\n ) {\n const tenantId = this.getTenantId(request);\n const { workspaceId, projectId } = request.params;\n const assistantId = (request.query as any).assistantId;\n\n const workspace = await this.workspaceStore.getWorkspaceById(\n tenantId,\n workspaceId\n );\n\n if (!workspace) {\n return reply\n .status(404)\n .send({ success: false, error: \"Workspace not found\" });\n }\n\n try {\n const data = await (request as any).file();\n if (!data) {\n return reply\n .status(400)\n .send({ success: false, error: \"No file in request\" });\n }\n\n const buffer: Buffer = await data.toBuffer();\n const filename: string = data.filename || \"file\";\n\n const pathEntry = data.fields?.path;\n const pathValue =\n pathEntry && typeof pathEntry === \"object\" && \"value\" in pathEntry\n ? String((pathEntry as { value: unknown }).value)\n : typeof pathEntry === \"string\"\n ? pathEntry\n : undefined;\n\n if (pathValue && !/^[a-zA-Z0-9_./~\\-]+$/.test(pathValue)) {\n return reply\n .status(400)\n .send({ success: false, error: \"Invalid path parameter\" });\n }\n\n if (workspace.storageType === \"sandbox\") {\n const sandboxManager = getSandBoxManager();\n const volumeConfig = {\n assistant_id: assistantId || \"\",\n thread_id: \"\",\n tenantId,\n workspaceId,\n projectId,\n };\n\n const realPath = pathValue\n ? path.posix.join(pathValue, filename)\n : path.posix.join(\"/project/uploads\", filename);\n\n // Try volume backend for text files; binary files must use sandbox\n // (volume backend's write API is text-based and corrupts binary data)\n const isBinary = this.isBinaryContentType(filename);\n const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, realPath);\n if (volumeBackend && !isBinary) {\n await volumeBackend.write(realPath, buffer.toString(\"utf-8\"));\n } else {\n const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);\n await sandbox.file.uploadFile({ file: realPath, data: buffer });\n }\n\n const relativePath = pathValue\n ? path.posix.join(pathValue, filename)\n : path.posix.join(\"/project/uploads\", filename);\n\n const result = {\n path: relativePath,\n name: filename,\n is_dir: false,\n size: buffer.length,\n modified_at: new Date().toISOString(),\n };\n\n return reply.status(200).send({ success: true, data: result });\n }\n\n // Filesystem storage: write under /lattice_store/tenants/{tenantId}/workspaces/{workspaceId}/{projectId} and expose as virtual path \"/<filename>\"\n const rootDir = `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;\n const targetDir = pathValue ? path.join(rootDir, pathValue) : rootDir;\n const targetPath = path.join(targetDir, filename);\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.writeFile(targetPath, buffer);\n const stat = await fs.stat(targetPath);\n\n const result = {\n path: pathValue ? `/${pathValue}/${filename}` : `/${filename}`,\n name: filename,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n };\n\n return reply.status(200).send({ success: true, data: result });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n error: `Upload handler error: ${error?.message || String(error)}`,\n });\n }\n }\n}\n\nexport function registerWorkspaceRoutes(app: FastifyInstance) {\n const controller = new WorkspaceController();\n\n // Workspace routes\n app.get(\"/api/workspaces\", controller.listWorkspaces.bind(controller));\n app.post(\"/api/workspaces\", controller.createWorkspace.bind(controller));\n app.get(\n \"/api/workspaces/:workspaceId\",\n controller.getWorkspace.bind(controller)\n );\n app.patch(\n \"/api/workspaces/:workspaceId\",\n controller.updateWorkspace.bind(controller)\n );\n app.delete(\n \"/api/workspaces/:workspaceId\",\n controller.deleteWorkspace.bind(controller)\n );\n\n // Project routes\n app.get(\n \"/api/workspaces/:workspaceId/projects\",\n controller.listProjects.bind(controller)\n );\n app.post(\n \"/api/workspaces/:workspaceId/projects\",\n controller.createProject.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.getProject.bind(controller)\n );\n app.patch(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.updateProject.bind(controller)\n );\n app.delete(\n \"/api/workspaces/:workspaceId/projects/:projectId\",\n controller.deleteProject.bind(controller)\n );\n\n // File operations\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/listpath\",\n controller.listPath.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/readfile\",\n controller.readFile.bind(controller)\n );\n app.post(\n \"/api/workspaces/:workspaceId/projects/:projectId/uploadfile\",\n controller.uploadFile.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/downloadfile\",\n controller.downloadFile.bind(controller)\n );\n app.get(\n \"/api/workspaces/:workspaceId/projects/:projectId/viewfile\",\n controller.viewFile.bind(controller)\n );\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n sqlDatabaseManager,\n} from \"@axiom-lattice/core\";\nimport type {\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Database Config Controller\n * Handles database configuration CRUD operations\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Database config list response\n */\ninterface DatabaseConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: DatabaseConfigEntry[];\n total: number;\n };\n}\n\n/**\n * Database config response\n */\ninterface DatabaseConfigResponse {\n success: boolean;\n message: string;\n data?: DatabaseConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * Get all database configs for a tenant\n */\nexport async function getDatabaseConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n \n console.log('Backend: getAllConfigs returned:', configs);\n if (configs.length > 0) {\n console.log('Backend: First config key:', configs[0].key);\n }\n\n return {\n success: true,\n message: \"Database configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get database configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve database configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get database config by key\n */\nexport async function getDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"Database configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get database config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve database configuration\",\n };\n }\n}\n\n/**\n * Create new database config\n */\nexport async function createDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateDatabaseConfigRequest & { id?: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"Database configuration with this key already exists\",\n };\n }\n\n const id = body.id || randomUUID();\n const config = await store.createConfig(tenantId, id, body);\n\n // Auto-register to SqlDatabaseManager\n try {\n sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);\n } catch (error) {\n console.warn(\"Failed to auto-register database:\", error);\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"Database configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create database config:\", error);\n return {\n success: false,\n message: \"Failed to create database configuration\",\n };\n }\n}\n\n/**\n * Update database config\n */\nexport async function updateDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateDatabaseConfigRequest>;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update database configuration\",\n };\n }\n\n // Re-register to SqlDatabaseManager if config changed\n if (updates.config) {\n try {\n sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);\n } catch (error) {\n console.warn(\"Failed to re-register database:\", error);\n }\n }\n\n return {\n success: true,\n message: \"Database configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update database config:\", error);\n return {\n success: false,\n message: \"Failed to update database configuration\",\n };\n }\n}\n\n/**\n * Delete database config by key or id\n */\nexport async function deleteDatabaseConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatabaseConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n console.log('Delete request - keyOrId:', keyOrId);\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n console.log('Found config to delete:', { id: config.id, key: config.key });\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete database configuration\",\n };\n }\n\n // Remove from SqlDatabaseManager\n try {\n if (sqlDatabaseManager.hasDatabase(tenantId, configKey)) {\n await sqlDatabaseManager.removeDatabase(tenantId, configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from SqlDatabaseManager:\", error);\n }\n\n return {\n success: true,\n message: \"Database configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete database config:\", error);\n return {\n success: false,\n message: \"Failed to delete database configuration\",\n };\n }\n}\n\n/**\n * Test database connection\n */\nexport async function testDatabaseConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"database\");\n const store: DatabaseConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Database configuration not found\",\n };\n }\n\n // Register temporarily for testing\n const testKey = `__test_${key}_${Date.now()}`;\n sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);\n\n const startTime = Date.now();\n const db = await sqlDatabaseManager.getDatabase(tenantId, testKey);\n\n try {\n // Try to connect and list tables\n await db.connect();\n await db.listTables();\n const latency = Date.now() - startTime;\n\n // Disconnect gracefully with delay to ensure all operations complete\n await new Promise(resolve => setTimeout(resolve, 100));\n await db.disconnect();\n \n // Cleanup\n await sqlDatabaseManager.removeDatabase(tenantId, testKey);\n\n return {\n success: true,\n message: \"Connection test successful\",\n data: {\n connected: true,\n latency,\n },\n };\n } catch (error) {\n // Cleanup on error\n try {\n await db.disconnect();\n await sqlDatabaseManager.removeDatabase(tenantId, testKey);\n } catch {}\n\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test database connection:\", error);\n return {\n success: false,\n message: \"Failed to test database connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * Register database config routes\n */\nexport function registerDatabaseConfigRoutes(app: any): void {\n // Get all configs\n app.get(\n \"/api/database-configs\",\n getDatabaseConfigList\n );\n\n // Get config by key\n app.get(\n \"/api/database-configs/:key\",\n getDatabaseConfig\n );\n\n // Create config\n app.post(\n \"/api/database-configs\",\n createDatabaseConfig\n );\n\n // Update config\n app.put(\n \"/api/database-configs/:key\",\n updateDatabaseConfig\n );\n\n // Delete config by key or id\n app.delete(\n \"/api/database-configs/:keyOrId\",\n deleteDatabaseConfig\n );\n\n // Test connection\n app.post(\n \"/api/database-configs/:key/test\",\n testDatabaseConnection\n );\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n metricsServerManager,\n SemanticMetricsClient,\n} from \"@axiom-lattice/core\";\nimport type {\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n DataSource,\n SemanticMetricsQueryRequest,\n SemanticMetricsServerConfig,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Metrics Server Config Controller\n * Handles metrics server configuration CRUD operations\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Metrics server config list response\n */\ninterface MetricsServerConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: MetricsServerConfigEntry[];\n total: number;\n };\n}\n\n/**\n * Metrics server config response\n */\ninterface MetricsServerConfigResponse {\n success: boolean;\n message: string;\n data?: MetricsServerConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * List available metrics response\n */\ninterface ListMetricsResponse {\n success: boolean;\n message: string;\n data?: {\n metrics: Array<{\n name: string;\n type?: string;\n description?: string;\n }>;\n };\n}\n\n/**\n * Query metric data response\n */\ninterface QueryMetricDataResponse {\n success: boolean;\n message: string;\n data?: {\n metricName: string;\n dataPoints: Array<{\n timestamp: number;\n value: number;\n labels?: Record<string, string>;\n }>;\n };\n}\n\n/**\n * Data sources list response\n */\ninterface DataSourcesResponse {\n success: boolean;\n message: string;\n data?: {\n datasources: DataSource[];\n };\n}\n\n/**\n * Datasource metrics response\n */\ninterface DatasourceMetricsResponse {\n success: boolean;\n message: string;\n data?: {\n index: {\n datasourceId: number;\n datasourceName: string;\n catalogVersion: string;\n domainCategories: string[];\n metrics: Array<{\n metricName: string;\n displayName: string;\n domain: string;\n shortDesc: string;\n searchKeywords: string[];\n registered: boolean;\n }>;\n tables?: Array<{\n tableName: string;\n displayName: string;\n docType: string;\n docTypeEn: string;\n mainTable?: string;\n lineTable?: string;\n columnCount: number;\n shortDesc: string;\n }>;\n };\n metricsDetails: Array<{\n datasourceId: number;\n metricName: string;\n displayName: string;\n domain: string;\n description: string;\n dataType: string;\n format: string;\n defaultTimeContext: {\n timeDimension: string;\n label: string;\n granularity: string;\n window: string;\n supportedGrains: string[];\n };\n supportedDimensions: Array<{\n dim_id: string;\n field_name: string;\n type: string;\n filter_operators?: string[];\n filter_example?: object;\n group_by_example?: string;\n }>;\n aiAgentContext: {\n polarity: string;\n synonyms: string[];\n thresholds: Array<{\n metric: string;\n operator: string;\n value: number;\n level: string;\n }>;\n diagnosticWorkflow: {\n trigger: {\n any_of: Array<{\n metric: string;\n operator: string;\n value: number;\n }>;\n };\n actions: Array<{\n type: string;\n metric?: string;\n dimensions?: string[];\n intent: string;\n }>;\n analysis_logic: string;\n };\n humanReadableExplanation: string;\n };\n }>;\n tablesDetails?: Array<{\n tableName: string;\n docType: string;\n docTypeEn: string;\n objTypeCode?: number;\n mainTable?: string;\n lineTable?: string;\n selectSql: string;\n columns: Array<{\n name: string;\n label: string;\n description?: string;\n type?: string;\n example?: string;\n } | null>;\n }>;\n };\n}\n\n/**\n * Semantic query response\n */\ninterface SemanticQueryResponse {\n success: boolean;\n message: string;\n data?: {\n semanticModel: string;\n columns: string[];\n dataPoints: Array<{\n timestamp?: number;\n value: number;\n labels?: Record<string, string>;\n }>;\n metadata?: {\n rowCount?: number;\n columnCount?: number;\n };\n };\n}\n\n/**\n * Get all metrics server configs for a tenant\n */\nexport async function getMetricsServerConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n\n return {\n success: true,\n message: \"Metrics server configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get metrics server configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics server configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get metrics server config by key\n */\nexport async function getMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"Metrics server configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics server configuration\",\n };\n }\n}\n\n/**\n * Create new metrics server config\n */\nexport async function createMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateMetricsServerConfigRequest & { \n id?: string;\n selectedDataSources?: string[];\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"Metrics server configuration with this key already exists\",\n };\n }\n\n if (body.config.type === \"semantic\" && !body.selectedDataSources) {\n reply.code(400);\n return {\n success: false,\n message: \"selectedDataSources is required for semantic metrics servers\",\n };\n }\n\n const id = body.id || randomUUID();\n const configData: CreateMetricsServerConfigRequest = {\n key: body.key,\n name: body.name,\n description: body.description,\n config: body.config.type === \"semantic\" \n ? {\n ...body.config,\n selectedDataSources: body.selectedDataSources || [],\n } as SemanticMetricsServerConfig\n : body.config,\n };\n\n const config = await store.createConfig(tenantId, id, configData);\n\n // Auto-register to MetricsServerManager\n try {\n metricsServerManager.registerServer(tenantId, config.key, config.config);\n } catch (error) {\n console.warn(\"Failed to auto-register metrics server:\", error);\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"Metrics server configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to create metrics server configuration\",\n };\n }\n}\n\n/**\n * Update metrics server config\n */\nexport async function updateMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateMetricsServerConfigRequest> & {\n selectedDataSources?: string[];\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n const isSemantic = updates.config?.type === \"semantic\" ||\n (existing.config.type === \"semantic\" && !updates.config?.type);\n\n if (isSemantic && updates.selectedDataSources !== undefined) {\n updates.config = {\n ...existing.config,\n ...updates.config,\n type: \"semantic\",\n selectedDataSources: updates.selectedDataSources,\n } as SemanticMetricsServerConfig;\n }\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update metrics server configuration\",\n };\n }\n\n if (updates.config) {\n try {\n metricsServerManager.registerServer(tenantId, updated.key, updated.config);\n } catch (error) {\n console.warn(\"Failed to re-register metrics server:\", error);\n }\n }\n\n return {\n success: true,\n message: \"Metrics server configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to update metrics server configuration\",\n };\n }\n}\n\n/**\n * Delete metrics server config by key or id\n */\nexport async function deleteMetricsServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<MetricsServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete metrics server configuration\",\n };\n }\n\n // Remove from MetricsServerManager\n try {\n if (metricsServerManager.hasServer(tenantId, configKey)) {\n metricsServerManager.removeServer(tenantId, configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from MetricsServerManager:\", error);\n }\n\n return {\n success: true,\n message: \"Metrics server configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete metrics server config:\", error);\n return {\n success: false,\n message: \"Failed to delete metrics server configuration\",\n };\n }\n}\n\n/**\n * Test metrics server connection\n */\nexport async function testMetricsServerConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n // Register temporarily for testing\n const testKey = `__test_${key}_${Date.now()}`;\n metricsServerManager.registerServer(tenantId, testKey, config.config);\n\n try {\n const client = metricsServerManager.getClient(tenantId, testKey);\n const result = await client.testConnection();\n\n // Cleanup\n metricsServerManager.removeServer(tenantId, testKey);\n\n return {\n success: true,\n message: result.connected ? \"Connection test successful\" : \"Connection test failed\",\n data: result,\n };\n } catch (error) {\n // Cleanup on error\n try {\n metricsServerManager.removeServer(tenantId, testKey);\n } catch {}\n\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test metrics server connection:\", error);\n return {\n success: false,\n message: \"Failed to test metrics server connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * List available metrics from a server\n */\nexport async function listAvailableMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListMetricsResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n // Ensure server is registered\n if (!metricsServerManager.hasServer(tenantId, key)) {\n metricsServerManager.registerServer(tenantId, key, config.config);\n }\n\n const client = metricsServerManager.getClient(tenantId, key);\n const metrics = await client.listMetrics();\n\n return {\n success: true,\n message: \"Metrics retrieved successfully\",\n data: {\n metrics: metrics.map(m => ({\n name: m.name,\n type: m.type,\n description: m.description,\n })),\n },\n };\n } catch (error) {\n console.error(\"Failed to list metrics:\", error);\n return {\n success: false,\n message: \"Failed to retrieve metrics\",\n };\n }\n}\n\n/**\n * Query metric data from a server\n */\nexport async function queryMetricsData(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<QueryMetricDataResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const { metricName, startTime, endTime, step, labels } = request.body as {\n metricName: string;\n startTime?: number;\n endTime?: number;\n step?: number;\n labels?: Record<string, string>;\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (!metricName) {\n reply.code(400);\n return {\n success: false,\n message: \"metricName is required\",\n };\n }\n\n // Ensure server is registered\n if (!metricsServerManager.hasServer(tenantId, key)) {\n metricsServerManager.registerServer(tenantId, key, config.config);\n }\n\n const client = metricsServerManager.getClient(tenantId, key);\n const result = await client.queryMetricData(metricName, {\n startTime,\n endTime,\n step,\n labels,\n });\n\n return {\n success: true,\n message: \"Metric data retrieved successfully\",\n data: {\n metricName: result.metricName,\n dataPoints: result.dataPoints,\n },\n };\n } catch (error) {\n console.error(\"Failed to query metric data:\", error);\n return {\n success: false,\n message: \"Failed to query metric data\",\n };\n }\n}\n\n/**\n * Get data sources for a semantic metrics server\n * GET /api/metrics-configs/:key/datasources\n */\nexport async function getDataSources(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataSourcesResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const allDatasources = await client.getDataSources();\n\n // Filter datasources by selectedDataSources if configured\n const selectedIds = semanticConfig.selectedDataSources || [];\n const filteredDatasources = selectedIds.length > 0\n ? allDatasources.filter(ds => selectedIds.includes(String(ds.id)))\n : allDatasources;\n\n return {\n success: true,\n message: \"Data sources retrieved successfully\",\n data: {\n datasources: filteredDatasources,\n },\n };\n } catch (error) {\n console.error(\"Failed to get data sources:\", error);\n return {\n success: false,\n message: \"Failed to retrieve data sources\",\n };\n }\n}\n\n/**\n * Get metrics for a specific data source\n * GET /api/metrics-configs/:key/datasources/:datasourceId/metrics\n */\nexport async function getDatasourceMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatasourceMetricsResponse> {\n const tenantId = getTenantId(request);\n const { key, datasourceId } = request.params as { key: string; datasourceId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const metrics = await client.getDatasourceMetrics(datasourceId);\n\n return {\n success: true,\n message: \"Datasource metrics retrieved successfully\",\n data: metrics,\n };\n } catch (error) {\n console.error(\"Failed to get datasource metrics:\", error);\n return {\n success: false,\n message: \"Failed to retrieve datasource metrics\",\n };\n }\n}\n\n/**\n * Query semantic metrics data\n * POST /api/metrics-configs/:key/semantic-query\n */\nexport async function querySemanticMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<SemanticQueryResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const body = request.body as SemanticMetricsQueryRequest;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"metrics\");\n const store: MetricsServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"Metrics server configuration not found\",\n };\n }\n\n if (config.config.type !== \"semantic\") {\n reply.code(400);\n return {\n success: false,\n message: \"This endpoint is only available for semantic metrics servers\",\n };\n }\n\n if (!body.datasourceId || !body.metrics || body.metrics.length === 0) {\n reply.code(400);\n return {\n success: false,\n message: \"datasourceId and metrics array are required\",\n };\n }\n\n const semanticConfig = config.config as SemanticMetricsServerConfig;\n\n const client = new SemanticMetricsClient(semanticConfig);\n const result = await client.semanticQuery(body);\n\n // Transform SemanticMetricsQueryResponse to response format\n // The response contains columns and rows arrays\n const columnNames = result.columns.map(col => col.name);\n const allDataPoints: Array<{\n timestamp?: number;\n value: number;\n labels?: Record<string, string>;\n }> = [];\n\n // Find timestamp column and value column indices\n const timestampColIdx = columnNames.findIndex(col => \n col.toLowerCase().includes('date') || col.toLowerCase().includes('time')\n );\n const valueColIdx = columnNames.findIndex(col => \n col.toLowerCase().includes('value') || col.toLowerCase().includes('rate') || col.toLowerCase().includes('amt')\n );\n\n for (const row of result.rows ?? []) {\n const timestamp = timestampColIdx >= 0 ? row[timestampColIdx] : undefined;\n const value = valueColIdx >= 0 ? row[valueColIdx] : row[row.length - 1];\n \n allDataPoints.push({\n timestamp: timestamp ? new Date(String(timestamp)).getTime() : undefined,\n value: typeof value === 'number' ? value : Number(value) || 0,\n labels: Object.fromEntries(\n columnNames.map((col, idx) => [col, String(row[idx] ?? '')])\n ),\n });\n }\n\n return {\n success: true,\n message: \"Semantic query executed successfully\",\n data: {\n semanticModel: result.semanticModel,\n columns: columnNames,\n dataPoints: allDataPoints,\n metadata: {\n rowCount: result.rows?.length ?? 0,\n columnCount: result.columns.length,\n },\n },\n };\n } catch (error) {\n console.error(\"Failed to query semantic metrics:\", error);\n return {\n success: false,\n message: \"Failed to query semantic metrics\",\n };\n }\n}\n\n/**\n * Test datasources endpoint without saving config\n * Used for multi-step configuration flow\n * POST /api/metrics-configs/test-datasources\n */\nexport async function testSemanticDataSources(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DataSourcesResponse> {\n const body = request.body as {\n serverUrl: string;\n apiKey?: string;\n username?: string;\n password?: string;\n headers?: Record<string, string>;\n };\n\n try {\n if (!body.serverUrl) {\n reply.code(400);\n return {\n success: false,\n message: \"serverUrl is required\",\n };\n }\n\n const testConfig: SemanticMetricsServerConfig = {\n type: \"semantic\",\n serverUrl: body.serverUrl,\n apiKey: body.apiKey,\n username: body.username,\n password: body.password,\n headers: body.headers,\n };\n\n const client = new SemanticMetricsClient(testConfig);\n\n const datasources = await client.getDataSources();\n\n return {\n success: true,\n message: \"Data sources retrieved successfully\",\n data: {\n datasources,\n },\n };\n } catch (error) {\n console.error(\"Failed to test datasources:\", error);\n return {\n success: false,\n message: `Failed to retrieve data sources: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Test datasource metrics endpoint without saving config\n * Used for multi-step configuration flow\n * POST /api/metrics-configs/test-datasources/:datasourceId/metrics\n */\nexport async function testDatasourceMetrics(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<DatasourceMetricsResponse> {\n const { datasourceId } = request.params as { datasourceId: string };\n const body = request.body as {\n serverUrl: string;\n apiKey?: string;\n username?: string;\n password?: string;\n headers?: Record<string, string>;\n };\n\n try {\n if (!body.serverUrl) {\n reply.code(400);\n return {\n success: false,\n message: \"serverUrl is required\",\n };\n }\n\n const testConfig: SemanticMetricsServerConfig = {\n type: \"semantic\",\n serverUrl: body.serverUrl,\n apiKey: body.apiKey,\n username: body.username,\n password: body.password,\n headers: body.headers,\n };\n\n const client = new SemanticMetricsClient(testConfig);\n const metrics = await client.getDatasourceMetrics(datasourceId);\n\n return {\n success: true,\n message: \"Datasource metrics retrieved successfully\",\n data: metrics,\n };\n } catch (error) {\n console.error(\"Failed to test datasource metrics:\", error);\n return {\n success: false,\n message: `Failed to retrieve datasource metrics: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\n/**\n * Register metrics server config routes\n */\nexport function registerMetricsServerConfigRoutes(app: any): void {\n // Get all configs\n app.get(\"/api/metrics-configs\", getMetricsServerConfigList);\n\n // Get config by key\n app.get(\"/api/metrics-configs/:key\", getMetricsServerConfig);\n\n // Create config\n app.post(\"/api/metrics-configs\", createMetricsServerConfig);\n\n // Update config\n app.put(\"/api/metrics-configs/:key\", updateMetricsServerConfig);\n\n // Delete config by key or id\n app.delete(\"/api/metrics-configs/:keyOrId\", deleteMetricsServerConfig);\n\n // Test connection\n app.post(\"/api/metrics-configs/:key/test\", testMetricsServerConnection);\n\n // List available metrics\n app.get(\"/api/metrics-configs/:key/metrics\", listAvailableMetrics);\n\n // Query metric data\n app.post(\"/api/metrics-configs/:key/query\", queryMetricsData);\n\n // Semantic-specific routes\n // Get data sources for a semantic server\n app.get(\"/api/metrics-configs/:key/datasources\", getDataSources);\n\n // Get metrics meta for a specific datasource\n app.get(\"/api/metrics-configs/:key/datasources/:datasourceId/meta\", getDatasourceMetrics);\n\n // Query semantic metrics data\n app.post(\"/api/metrics-configs/:key/semantic-query\", querySemanticMetrics);\n\n // Test datasources without saving config (for multi-step config flow)\n app.post(\"/api/metrics-configs/test-datasources\", testSemanticDataSources);\n\n // Test datasource metrics meta without saving config (for multi-step config flow)\n app.post(\"/api/metrics-configs/test-datasources/:datasourceId/meta\", testDatasourceMetrics);\n}\n","/**\n * MCP Server Config Controller\n * Handles MCP server configuration CRUD operations with automatic tool registration\n */\n\nimport { FastifyRequest, FastifyReply } from \"fastify\";\nimport {\n getStoreLattice,\n mcpManager,\n toolLatticeManager,\n} from \"@axiom-lattice/core\";\nimport type {\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n McpServerConfig,\n McpTool,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * MCP server config list response\n */\ninterface McpServerConfigListResponse {\n success: boolean;\n message: string;\n data: {\n records: McpServerConfigEntry[];\n total: number;\n };\n}\n\n/**\n * MCP server config response\n */\ninterface McpServerConfigResponse {\n success: boolean;\n message: string;\n data?: McpServerConfigEntry;\n}\n\n/**\n * Test connection response\n */\ninterface TestConnectionResponse {\n success: boolean;\n message: string;\n data?: {\n connected: boolean;\n latency?: number;\n error?: string;\n };\n}\n\n/**\n * List tools response\n */\ninterface ListToolsResponse {\n success: boolean;\n message: string;\n data?: {\n tools: McpTool[];\n };\n}\n\n/**\n * Get all MCP server configs for a tenant\n */\nexport async function getMcpServerConfigList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigListResponse> {\n const tenantId = getTenantId(request);\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const configs = await store.getAllConfigs(tenantId);\n\n return {\n success: true,\n message: \"MCP server configurations retrieved successfully\",\n data: {\n records: configs,\n total: configs.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get MCP server configs:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configurations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get MCP server config by key\n */\nexport async function getMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n\n if (!config) {\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration retrieved successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to get MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to retrieve MCP server configuration\",\n };\n }\n}\n\n/**\n * Create new MCP server config\n */\nexport async function createMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const body = request.body as CreateMcpServerConfigRequest & {\n id?: string;\n };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Check if key already exists\n const existing = await store.getConfigByKey(tenantId, body.key);\n if (existing) {\n reply.code(409);\n return {\n success: false,\n message: \"MCP server configuration with this key already exists\",\n };\n }\n\n const id = body.id || randomUUID();\n const config = await store.createConfig(tenantId, id, body);\n\n // Auto-connect and register tools\n try {\n await connectAndRegisterTools(config);\n // Update status to connected\n await store.updateConfig(tenantId, id, { status: \"connected\" });\n config.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to auto-connect MCP server:\", error);\n // Update status to error but don't fail the creation\n await store.updateConfig(tenantId, id, { status: \"error\" });\n config.status = \"error\";\n }\n\n reply.code(201);\n return {\n success: true,\n message: \"MCP server configuration created successfully\",\n data: config,\n };\n } catch (error) {\n console.error(\"Failed to create MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to create MCP server configuration\",\n };\n }\n}\n\n/**\n * Update MCP server config\n */\nexport async function updateMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n const updates = request.body as Partial<UpdateMcpServerConfigRequest>;\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const existing = await store.getConfigByKey(tenantId, key);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // If config is being updated, we need to reconnect\n const shouldReconnect = updates.config !== undefined;\n\n const updated = await store.updateConfig(tenantId, existing.id, updates);\n\n if (!updated) {\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n\n // Reconnect and re-register tools if config changed\n if (shouldReconnect) {\n try {\n // Disconnect existing connection if any\n if (mcpManager.hasServer(key)) {\n await mcpManager.removeServer(key);\n }\n // Reconnect with new config\n await connectAndRegisterTools(updated);\n await store.updateConfig(tenantId, existing.id, { status: \"connected\" });\n updated.status = \"connected\";\n } catch (error) {\n console.warn(\"Failed to reconnect MCP server:\", error);\n await store.updateConfig(tenantId, existing.id, { status: \"error\" });\n updated.status = \"error\";\n }\n }\n\n return {\n success: true,\n message: \"MCP server configuration updated successfully\",\n data: updated,\n };\n } catch (error) {\n console.error(\"Failed to update MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to update MCP server configuration\",\n };\n }\n}\n\n/**\n * Delete MCP server config by key or id\n */\nexport async function deleteMcpServerConfig(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { keyOrId } = request.params as { keyOrId: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n // Try to find by key first, then by id\n let config = await store.getConfigByKey(tenantId, keyOrId);\n let configKey = keyOrId;\n\n if (!config) {\n // Try to find by id\n config = await store.getConfigById(tenantId, keyOrId);\n if (config) {\n configKey = config.key;\n }\n }\n\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect and remove from MCP manager\n try {\n if (mcpManager.hasServer(configKey)) {\n await mcpManager.removeServer(configKey);\n }\n } catch (error) {\n console.warn(\"Failed to remove from MCP manager:\", error);\n }\n\n const deleted = await store.deleteConfig(tenantId, config.id);\n\n if (!deleted) {\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n\n return {\n success: true,\n message: \"MCP server configuration deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete MCP server config:\", error);\n return {\n success: false,\n message: \"Failed to delete MCP server configuration\",\n };\n }\n}\n\n/**\n * Test MCP server connection\n */\nexport async function testMcpServerConnection(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<TestConnectionResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n const startTime = Date.now();\n\n // Test connection by trying to list tools\n try {\n // Create temporary connection\n const testKey = `__test_${key}_${Date.now()}`;\n const connection = convertToConnection(config.config);\n mcpManager.addServer(testKey, connection);\n\n await mcpManager.connect();\n const tools = await mcpManager.getAllTools();\n const latency = Date.now() - startTime;\n\n // Cleanup\n await mcpManager.removeServer(testKey);\n\n return {\n success: true,\n message: \"Connection test successful\",\n data: {\n connected: true,\n latency,\n },\n };\n } catch (error) {\n return {\n success: true,\n message: \"Connection test failed\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n } catch (error) {\n console.error(\"Failed to test MCP server connection:\", error);\n return {\n success: false,\n message: \"Failed to test MCP server connection\",\n data: {\n connected: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n };\n }\n}\n\n/**\n * List available tools from an MCP server\n */\nexport async function listMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Ensure server is connected\n if (!mcpManager.hasServer(key)) {\n await connectAndRegisterTools(config);\n }\n\n const tools = await mcpManager.getAllTools();\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to list MCP tools:\", error);\n return {\n success: false,\n message: \"Failed to retrieve tools\",\n };\n }\n}\n\n/**\n * Connect to MCP server and register tools\n */\nexport async function connectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n await connectAndRegisterTools(config);\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"connected\",\n });\n\n return {\n success: true,\n message: \"MCP server connected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to connect MCP server:\", error);\n\n // Update status to error\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n const config = await store.getConfigByKey(tenantId, key);\n if (config) {\n await store.updateConfig(tenantId, config.id, { status: \"error\" });\n }\n\n return {\n success: false,\n message: `Failed to connect MCP server: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n}\n\n/**\n * Disconnect from MCP server\n */\nexport async function disconnectMcpServer(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<McpServerConfigResponse> {\n const tenantId = getTenantId(request);\n const { key } = request.params as { key: string };\n\n try {\n const storeLattice = getStoreLattice(\"default\", \"mcp\");\n const store: McpServerConfigStore = storeLattice.store;\n\n const config = await store.getConfigByKey(tenantId, key);\n if (!config) {\n reply.code(404);\n return {\n success: false,\n message: \"MCP server configuration not found\",\n };\n }\n\n // Disconnect from MCP manager\n if (mcpManager.hasServer(key)) {\n await mcpManager.removeServer(key);\n }\n\n // Update status\n const updated = await store.updateConfig(tenantId, config.id, {\n status: \"disconnected\",\n });\n\n return {\n success: true,\n message: \"MCP server disconnected successfully\",\n data: updated || config,\n };\n } catch (error) {\n console.error(\"Failed to disconnect MCP server:\", error);\n return {\n success: false,\n message: \"Failed to disconnect MCP server\",\n };\n }\n}\n\n/**\n * Test MCP server connection and list tools without saving config\n * Used for multi-step configuration flow\n */\nexport async function testMcpServerTools(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ListToolsResponse> {\n const body = request.body as {\n config: McpServerConfig;\n };\n\n try {\n if (!body.config) {\n reply.code(400);\n return {\n success: false,\n message: \"config is required\",\n };\n }\n\n const testKey = `__test_${Date.now()}`;\n\n // Create temporary connection\n const connection = convertToConnection(body.config);\n mcpManager.addServer(testKey, connection);\n\n await mcpManager.connect();\n const tools = await mcpManager.getAllTools();\n\n // Cleanup\n await mcpManager.removeServer(testKey);\n\n return {\n success: true,\n message: \"Tools retrieved successfully\",\n data: {\n tools,\n },\n };\n } catch (error) {\n console.error(\"Failed to test MCP server tools:\", error);\n return {\n success: false,\n message: `Failed to retrieve tools: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n}\n\n/**\n * Convert McpServerConfig to Connection format compatible with @langchain/mcp-adapters\n */\nfunction convertToConnection(config: McpServerConfig): any {\n const baseConfig = {\n env: config.env,\n };\n\n if (config.transport === \"stdio\") {\n return {\n ...baseConfig,\n transport: \"stdio\" as const,\n command: config.command!,\n args: config.args || [],\n };\n } else {\n // For HTTP/SSE transports\n return {\n ...baseConfig,\n transport: config.transport === \"streamable_http\" ? \"http\" : config.transport,\n url: config.url!,\n };\n }\n}\n\n/**\n * Helper function to connect to MCP server and register selected tools\n */\nasync function connectAndRegisterTools(\n config: McpServerConfigEntry\n): Promise<void> {\n // Add server to MCP manager\n const connection = convertToConnection(config.config);\n mcpManager.addServer(config.key, connection);\n\n // Connect to server\n await mcpManager.connect();\n\n // Get all available tools\n const allTools = await mcpManager.getAllTools();\n\n // Filter to only selected tools\n const selectedTools = allTools.filter((tool) =>\n config.selectedTools.includes(tool.name)\n );\n\n // Register selected tools to ToolLattice\n for (const tool of selectedTools) {\n toolLatticeManager.registerExistingTool(tool.name, tool);\n }\n}\n\n/**\n * Register MCP server config routes\n */\nexport function registerMcpServerConfigRoutes(app: any): void {\n // Get all configs\n app.get(\"/api/mcp-servers\", getMcpServerConfigList);\n\n // Get config by key\n app.get(\"/api/mcp-servers/:key\", getMcpServerConfig);\n\n // Create config\n app.post(\"/api/mcp-servers\", createMcpServerConfig);\n\n // Update config\n app.put(\"/api/mcp-servers/:key\", updateMcpServerConfig);\n\n // Delete config by key or id\n app.delete(\"/api/mcp-servers/:keyOrId\", deleteMcpServerConfig);\n\n // Test connection\n app.post(\"/api/mcp-servers/:key/test\", testMcpServerConnection);\n\n // List available tools\n app.get(\"/api/mcp-servers/:key/tools\", listMcpServerTools);\n\n // Connect to server\n app.post(\"/api/mcp-servers/:key/connect\", connectMcpServer);\n\n // Disconnect from server\n app.post(\"/api/mcp-servers/:key/disconnect\", disconnectMcpServer);\n\n // Test tools without saving config (for multi-step config flow)\n app.post(\"/api/mcp-servers/test-tools\", testMcpServerTools);\n}\n","import { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n CreateUserRequest,\n UpdateUserRequest,\n} from \"@axiom-lattice/protocols\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ninterface UserParams {\n userId: string;\n}\n\ninterface ListUsersQuery {\n email?: string;\n}\n\nexport class UsersController {\n private userStore;\n\n constructor() {\n this.userStore = getStoreLattice(\"default\", \"user\").store;\n }\n\n async listUsers(\n request: FastifyRequest<{ Querystring: ListUsersQuery }>,\n reply: FastifyReply\n ) {\n const { email } = request.query;\n\n if (email) {\n const user = await this.userStore.getUserByEmail(email);\n return { success: true, data: user ? [user] : [] };\n }\n\n const users = await this.userStore.getAllUsers();\n return { success: true, data: users };\n }\n\n async createUser(\n request: FastifyRequest<{ Body: CreateUserRequest }>,\n reply: FastifyReply\n ) {\n const data = request.body;\n const id = uuidv4();\n\n const existingUser = await this.userStore.getUserByEmail(data.email);\n if (existingUser) {\n return reply.status(409).send({\n success: false,\n error: `User with email ${data.email} already exists`,\n });\n }\n\n const user = await this.userStore.createUser(id, data);\n return reply.status(201).send({ success: true, data: user });\n }\n\n async getUser(\n request: FastifyRequest<{ Params: UserParams }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n\n const user = await this.userStore.getUserById(userId);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true, data: user };\n }\n\n async updateUser(\n request: FastifyRequest<{\n Params: UserParams;\n Body: UpdateUserRequest;\n }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n const updates = request.body;\n\n if (updates.email) {\n const existingUser = await this.userStore.getUserByEmail(updates.email);\n if (existingUser && existingUser.id !== userId) {\n return reply.status(409).send({\n success: false,\n error: `User with email ${updates.email} already exists`,\n });\n }\n }\n\n const user = await this.userStore.updateUser(userId, updates);\n\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true, data: user };\n }\n\n async deleteUser(\n request: FastifyRequest<{ Params: UserParams }>,\n reply: FastifyReply\n ) {\n const { userId } = request.params;\n\n const deleted = await this.userStore.deleteUser(userId);\n\n if (!deleted) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n return { success: true };\n }\n}\n\nexport function registerUserRoutes(app: FastifyInstance) {\n const controller = new UsersController();\n\n app.get(\"/api/users\", controller.listUsers.bind(controller));\n app.post(\"/api/users\", controller.createUser.bind(controller));\n app.get(\"/api/users/:userId\", controller.getUser.bind(controller));\n app.patch(\"/api/users/:userId\", controller.updateUser.bind(controller));\n app.delete(\"/api/users/:userId\", controller.deleteUser.bind(controller));\n}\n","/**\n * TenantsController\n *\n * Controller for tenant management\n * Handles CRUD operations for tenants (top-level entities)\n */\n\nimport { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n CreateTenantRequest,\n UpdateTenantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { v4 as uuidv4 } from \"uuid\";\n\ninterface TenantParams {\n tenantId: string;\n}\n\nexport class TenantsController {\n private tenantStore;\n\n constructor() {\n this.tenantStore = getStoreLattice(\"default\", \"tenant\").store;\n }\n\n // ==================== Tenant CRUD ====================\n\n async listTenants(request: FastifyRequest, reply: FastifyReply) {\n const tenants = await this.tenantStore.getAllTenants();\n return { success: true, data: tenants };\n }\n\n async createTenant(\n request: FastifyRequest<{ Body: CreateTenantRequest }>,\n reply: FastifyReply\n ) {\n const data = request.body;\n const id = uuidv4();\n\n const tenant = await this.tenantStore.createTenant(id, data);\n return reply.status(201).send({ success: true, data: tenant });\n }\n\n async getTenant(\n request: FastifyRequest<{ Params: TenantParams }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true, data: tenant };\n }\n\n async updateTenant(\n request: FastifyRequest<{\n Params: TenantParams;\n Body: UpdateTenantRequest;\n }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n const updates = request.body;\n\n const tenant = await this.tenantStore.updateTenant(tenantId, updates);\n\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true, data: tenant };\n }\n\n async deleteTenant(\n request: FastifyRequest<{ Params: TenantParams }>,\n reply: FastifyReply\n ) {\n const { tenantId } = request.params;\n\n // Prevent deletion of the default tenant\n if (tenantId === \"default\") {\n return reply.status(403).send({\n success: false,\n error: \"Cannot delete the default tenant\",\n });\n }\n\n const deleted = await this.tenantStore.deleteTenant(tenantId);\n\n if (!deleted) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n return { success: true };\n }\n}\n\nexport function registerTenantRoutes(app: FastifyInstance) {\n const controller = new TenantsController();\n\n // Tenant routes\n app.get(\"/api/tenants\", controller.listTenants.bind(controller));\n app.post(\"/api/tenants\", controller.createTenant.bind(controller));\n app.get(\"/api/tenants/:tenantId\", controller.getTenant.bind(controller));\n app.patch(\"/api/tenants/:tenantId\", controller.updateTenant.bind(controller));\n app.delete(\"/api/tenants/:tenantId\", controller.deleteTenant.bind(controller));\n}\n","import { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport type { CreateUserRequest, CreateTenantRequest, UserTenantRole } from \"@axiom-lattice/protocols\";\n\ninterface RegisterRequest {\n email: string;\n password: string;\n name: string;\n}\n\ninterface LoginRequest {\n email: string;\n password: string;\n}\n\ninterface SelectTenantRequest {\n tenantId: string;\n}\n\ninterface ApproveUserRequest {\n userId: string;\n approved: boolean;\n}\n\ninterface AssignTenantRequest {\n userId: string;\n tenantId: string;\n role?: UserTenantRole;\n}\n\ninterface ChangePasswordRequest {\n currentPassword: string;\n newPassword: string;\n}\n\nexport interface AuthConfig {\n autoApproveUsers: boolean;\n allowTenantRegistration: boolean;\n jwtSecret?: string;\n tokenExpiration: number;\n}\n\nconst defaultAuthConfig: AuthConfig = {\n autoApproveUsers: true,\n allowTenantRegistration: true,\n tokenExpiration: 86400,\n};\n\nexport class AuthController {\n private userStore;\n private tenantStore;\n private userTenantLinkStore;\n private config: AuthConfig;\n\n constructor(config: Partial<AuthConfig> = {}) {\n this.userStore = getStoreLattice(\"default\", \"user\").store;\n this.tenantStore = getStoreLattice(\"default\", \"tenant\").store;\n this.userTenantLinkStore = getStoreLattice(\"default\", \"userTenantLink\").store;\n this.config = { ...defaultAuthConfig, ...config };\n }\n\n async register(\n request: FastifyRequest<{ Body: RegisterRequest }>,\n reply: FastifyReply\n ) {\n const { email, password, name } = request.body;\n\n try {\n const existingUser = await this.userStore.getUserByEmail(email);\n if (existingUser) {\n return reply.status(409).send({\n success: false,\n error: \"User with this email already exists\",\n });\n }\n\n const userId = uuidv4();\n const userStatus = this.config.autoApproveUsers ? \"active\" : \"pending\";\n \n const userData: CreateUserRequest = {\n email,\n name,\n status: userStatus,\n metadata: {\n passwordHash: await this.hashPassword(password),\n },\n };\n\n const user = await this.userStore.createUser(userId, userData);\n\n return reply.status(201).send({\n success: true,\n message: this.config.autoApproveUsers\n ? \"Registration successful\"\n : \"Registration successful. Please wait for admin approval.\",\n data: {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n status: user.status,\n },\n },\n });\n } catch (error) {\n console.error(\"Registration error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Registration failed\",\n });\n }\n }\n\n async login(\n request: FastifyRequest<{ Body: LoginRequest }>,\n reply: FastifyReply\n ) {\n const { email, password } = request.body;\n\n try {\n const user = await this.userStore.getUserByEmail(email);\n if (!user) {\n return reply.status(401).send({\n success: false,\n error: \"Invalid credentials\",\n });\n }\n\n if (user.status !== \"active\") {\n return reply.status(403).send({\n success: false,\n error: `Account is ${user.status}. Please wait for admin approval.`,\n });\n }\n\n const isValidPassword = await this.verifyPassword(\n password,\n user.metadata?.passwordHash || \"\"\n );\n\n if (!isValidPassword) {\n return reply.status(401).send({\n success: false,\n error: \"Invalid credentials\",\n });\n }\n\n const tenantLinks = await this.userTenantLinkStore.getTenantsByUser(user.id);\n \n const token = await this.generateToken(user.id);\n\n return {\n success: true,\n data: {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n status: user.status,\n },\n tenants: tenantLinks.map(link => ({\n id: link.tenantId,\n role: link.role,\n })),\n token,\n requiresTenantSelection: tenantLinks.length > 1,\n hasTenants: tenantLinks.length > 0,\n },\n };\n } catch (error) {\n console.error(\"Login error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Login failed\",\n });\n }\n }\n\n async getUserTenants(\n request: FastifyRequest,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n \n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const links = await this.userTenantLinkStore.getTenantsByUser(userId);\n \n const tenantsWithDetails = await Promise.all(\n links.map(async (link) => {\n const tenant = await this.tenantStore.getTenantById(link.tenantId);\n return {\n ...link,\n tenant: tenant || null,\n };\n })\n );\n\n return {\n success: true,\n data: tenantsWithDetails,\n };\n } catch (error) {\n console.error(\"Get user tenants error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to get user tenants\",\n });\n }\n }\n\n async selectTenant(\n request: FastifyRequest<{ Body: SelectTenantRequest }>,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n const { tenantId } = request.body;\n\n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const hasLink = await this.userTenantLinkStore.hasLink(userId, tenantId);\n \n if (!hasLink) {\n return reply.status(403).send({\n success: false,\n error: \"You do not have access to this tenant\",\n });\n }\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n \n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n const token = await this.generateToken(userId, tenantId);\n\n return {\n success: true,\n data: {\n tenant: {\n id: tenant.id,\n name: tenant.name,\n status: tenant.status,\n },\n token,\n },\n };\n } catch (error) {\n console.error(\"Select tenant error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to select tenant\",\n });\n }\n }\n\n async approveUser(\n request: FastifyRequest<{ Body: ApproveUserRequest }>,\n reply: FastifyReply\n ) {\n const { userId, approved } = request.body;\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n if (user.status !== \"pending\") {\n return reply.status(400).send({\n success: false,\n error: `User is already ${user.status}`,\n });\n }\n\n const updatedUser = await this.userStore.updateUser(userId, {\n status: approved ? \"active\" : \"suspended\",\n });\n\n return {\n success: true,\n data: updatedUser,\n };\n } catch (error) {\n console.error(\"Approval error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Approval failed\",\n });\n }\n }\n\n async listPendingUsers(\n request: FastifyRequest,\n reply: FastifyReply\n ) {\n try {\n const users = await this.userStore.getAllUsers();\n const pendingUsers = users.filter((u) => u.status === \"pending\");\n\n return {\n success: true,\n data: pendingUsers,\n };\n } catch (error) {\n console.error(\"List pending users error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to list pending users\",\n });\n }\n }\n\n async assignTenant(\n request: FastifyRequest<{ Body: AssignTenantRequest }>,\n reply: FastifyReply\n ) {\n const { userId, tenantId, role = \"member\" } = request.body;\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n const tenant = await this.tenantStore.getTenantById(tenantId);\n if (!tenant) {\n return reply.status(404).send({\n success: false,\n error: \"Tenant not found\",\n });\n }\n\n const link = await this.userTenantLinkStore.createLink({\n userId,\n tenantId,\n role,\n });\n\n return {\n success: true,\n data: link,\n };\n } catch (error) {\n console.error(\"Assign tenant error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to assign tenant\",\n });\n }\n }\n\n private async hashPassword(password: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(password + \"salt\");\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n private async verifyPassword(password: string, hash: string): Promise<boolean> {\n const hashedPassword = await this.hashPassword(password);\n return hashedPassword === hash;\n }\n\n private async generateToken(userId: string, tenantId?: string): Promise<string> {\n const payload: any = {\n userId,\n exp: Date.now() + this.config.tokenExpiration * 1000,\n };\n if (tenantId) {\n payload.tenantId = tenantId;\n }\n return btoa(JSON.stringify(payload));\n }\n\n async changePassword(\n request: FastifyRequest<{ Body: ChangePasswordRequest }>,\n reply: FastifyReply\n ) {\n const userId = (request as any).user?.id;\n const { currentPassword, newPassword } = request.body;\n\n if (!userId) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized\",\n });\n }\n\n try {\n const user = await this.userStore.getUserById(userId);\n if (!user) {\n return reply.status(404).send({\n success: false,\n error: \"User not found\",\n });\n }\n\n // Verify current password\n const isValidPassword = await this.verifyPassword(\n currentPassword,\n user.metadata?.passwordHash || \"\"\n );\n\n if (!isValidPassword) {\n return reply.status(401).send({\n success: false,\n error: \"Current password is incorrect\",\n });\n }\n\n // Validate new password length\n if (newPassword.length < 6) {\n return reply.status(400).send({\n success: false,\n error: \"New password must be at least 6 characters\",\n });\n }\n\n // Update password\n await this.userStore.updateUser(userId, {\n metadata: {\n ...user.metadata,\n passwordHash: await this.hashPassword(newPassword),\n },\n });\n\n return reply.send({\n success: true,\n message: \"Password changed successfully\",\n });\n } catch (error) {\n console.error(\"Change password error:\", error);\n return reply.status(500).send({\n success: false,\n error: \"Failed to change password\",\n });\n }\n }\n}\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n config?: Partial<AuthConfig>\n) {\n const controller = new AuthController(config);\n\n const authHook = async (request: FastifyRequest, reply: FastifyReply) => {\n const authHeader = request.headers.authorization;\n\n if (!authHeader || !authHeader.startsWith(\"Bearer \")) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Missing or invalid token\",\n });\n }\n\n const token = authHeader.substring(7);\n\n try {\n const payload = JSON.parse(atob(token));\n\n if (payload.exp && payload.exp < Date.now()) {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Token expired\",\n });\n }\n\n (request as any).user = {\n id: payload.userId,\n tenantId: payload.tenantId,\n };\n } catch {\n return reply.status(401).send({\n success: false,\n error: \"Unauthorized - Invalid token\",\n });\n }\n };\n\n app.post(\"/api/auth/register\", controller.register.bind(controller));\n app.post(\"/api/auth/login\", controller.login.bind(controller));\n app.get(\"/api/auth/tenants\", { preHandler: authHook }, (req, res) => controller.getUserTenants(req, res));\n app.post(\"/api/auth/select-tenant\", { preHandler: authHook }, (req, res) => controller.selectTenant(req as any, res));\n app.post(\"/api/auth/approve\", { preHandler: authHook }, (req, res) => controller.approveUser(req as any, res));\n app.get(\"/api/auth/pending\", { preHandler: authHook }, (req, res) => controller.listPendingUsers(req, res));\n app.post(\"/api/auth/assign-tenant\", { preHandler: authHook }, (req, res) => controller.assignTenant(req as any, res));\n app.post(\"/api/auth/change-password\", { preHandler: authHook }, \n (req, res) => controller.changePassword(req as any, res)\n );\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport {\n ChannelIdentityMappingStore,\n PostgreSQLChannelInstallationStore,\n} from \"@axiom-lattice/pg-stores\";\nimport {\n createLarkEventHandler,\n type LarkEventHandlerDependencies,\n} from \"./controller\";\nimport {\n isLarkIngressEnabled,\n loadLarkIngressConfig,\n} from \"./config\";\nimport { createChannelThreadMappingService } from \"./mapping-service\";\nimport { parseLarkMessageEvent } from \"./parser\";\nimport { runAgentAndCollectLarkReply } from \"./runner\";\nimport { createLarkSender } from \"./sender\";\nimport { createLarkRequestVerifier, parseLarkRequestBody } from \"./verification\";\n\nexport function registerLarkChannelRoutes(\n app: FastifyInstance,\n dependencies?: LarkEventHandlerDependencies,\n): void {\n const config = loadLarkIngressConfig();\n if (!dependencies && !isLarkIngressEnabled(config)) {\n return;\n }\n const handlerDependencies = dependencies || createDefaultLarkDependencies();\n\n app.post(\n \"/api/channels/lark/installations/:installationId/events\",\n createLarkEventHandler({\n ...handlerDependencies,\n }),\n );\n}\n\nfunction createDefaultLarkDependencies(): LarkEventHandlerDependencies {\n const installationStore = new PostgreSQLChannelInstallationStore({\n poolConfig: getDatabaseUrl(),\n });\n const threadStore = getStoreLattice(\"default\", \"thread\").store;\n const mappingStore = new ChannelIdentityMappingStore({\n poolConfig: getDatabaseUrl(),\n });\n const mappingService = createChannelThreadMappingService({\n mappingStore,\n threadStore,\n });\n\n return {\n getInstallationConfig: async (installationId) => {\n const installation = await installationStore.getInstallationById(\n installationId,\n );\n\n if (!installation || installation.channel !== \"lark\") {\n return null;\n }\n\n return {\n enabled: true,\n installationId: installation.id,\n tenantId: installation.tenantId,\n assistantId: installation.config.assistantId,\n appId: installation.config.appId,\n appSecret: installation.config.appSecret,\n verificationToken: installation.config.verificationToken,\n encryptKey: installation.config.encryptKey,\n workspaceId: installation.config.workspaceId,\n projectId: installation.config.projectId,\n mappingMode: installation.config.mappingMode,\n };\n },\n parseRequestBody: (body, encryptKey) => parseLarkRequestBody(body, encryptKey),\n verifyParsedBody: (body, config) => {\n if (!config.verificationToken) {\n return true;\n }\n\n return createLarkRequestVerifier(config)({\n body,\n } as unknown as Parameters<ReturnType<typeof createLarkRequestVerifier>>[0]);\n },\n parseEvent: parseLarkMessageEvent,\n claimInboundReceipt: (input) => mappingStore.claimInboundReceipt(input),\n markInboundReceiptCompleted: (input) =>\n mappingStore.markInboundReceiptCompleted(input),\n markInboundReceiptFailed: (input) =>\n mappingStore.markInboundReceiptFailed(input),\n resolveThread: (input) => mappingService.getOrCreateThread(input),\n runAgentAndCollectText: ({ tenantId, assistantId, threadId, text, workspaceId, projectId }) =>\n runAgentAndCollectLarkReply({\n tenantId,\n assistantId,\n threadId,\n text,\n workspaceId,\n projectId,\n }),\n sendTextReply: async ({ chatId, text, config }) => {\n const sender = await createLarkSender({\n appId: config.appId,\n appSecret: config.appSecret,\n });\n\n await sender.sendTextReply({ chatId, text });\n },\n };\n}\n\nfunction getDatabaseUrl(): string {\n const databaseUrl = process.env.DATABASE_URL;\n\n if (!databaseUrl) {\n throw new Error(\"DATABASE_URL is required for Lark channel ingress\");\n }\n\n return databaseUrl;\n}\n","import type { ParsedLarkMessageEvent } from \"./types\";\n\ninterface RawLarkPayload {\n header?: {\n event_type?: string;\n };\n event?: {\n sender?: {\n sender_id?: {\n open_id?: string;\n };\n };\n message?: {\n message_id?: string;\n chat_id?: string;\n chat_type?: string;\n message_type?: string;\n content?: string;\n };\n };\n}\n\nexport function parseLarkMessageEvent(\n payload: unknown,\n): ParsedLarkMessageEvent | null {\n const raw = payload as RawLarkPayload;\n\n if (raw.header?.event_type !== \"im.message.receive_v1\") {\n return null;\n }\n\n const message = raw.event?.message;\n const openId = raw.event?.sender?.sender_id?.open_id;\n\n if (!message || !openId || message.message_type !== \"text\") {\n return null;\n }\n\n const parsedContent = parseLarkTextContent(message.content);\n if (!message.message_id || !message.chat_id || !parsedContent) {\n return null;\n }\n\n return {\n messageId: message.message_id,\n openId,\n chatId: message.chat_id,\n chatType: normalizeChatType(message.chat_type),\n text: parsedContent,\n };\n}\n\nfunction parseLarkTextContent(content: string | undefined): string | null {\n if (!content) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(content) as { text?: string };\n return typeof parsed.text === \"string\" ? parsed.text : null;\n } catch {\n return null;\n }\n}\n\nfunction normalizeChatType(chatType: string | undefined): \"direct\" | \"group\" {\n return chatType === \"p2p\" ? \"direct\" : \"group\";\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { parseLarkMessageEvent } from \"./parser\";\nimport type {\n LarkIngressConfig,\n LarkUrlVerificationPayload,\n ParsedLarkMessageEvent,\n} from \"./types\";\n\nexport interface LarkEventHandlerDependencies {\n getInstallationConfig: (\n installationId: string,\n ) => Promise<LarkIngressConfig | null>;\n parseRequestBody: (\n body: unknown,\n encryptKey?: string,\n ) => LarkUrlVerificationPayload;\n verifyParsedBody: (\n body: LarkUrlVerificationPayload,\n config: LarkIngressConfig,\n ) => boolean;\n parseEvent: (payload: unknown) => ParsedLarkMessageEvent | null;\n claimInboundReceipt: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }) => Promise<{ accepted: boolean; status: \"processing\" | \"completed\" }>;\n markInboundReceiptCompleted: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n threadId: string;\n }) => Promise<void>;\n markInboundReceiptFailed: (input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }) => Promise<void>;\n resolveThread: (input: {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n openId: string;\n chatId: string;\n chatType: \"direct\" | \"group\";\n messageId: string;\n workspaceId?: string;\n projectId?: string;\n }) => Promise<{ threadId: string }>;\n runAgentAndCollectText: (input: {\n tenantId: string;\n assistantId: string;\n threadId: string;\n text: string;\n workspaceId?: string;\n projectId?: string;\n }) => Promise<string>;\n sendTextReply: (input: {\n chatId: string;\n text: string;\n config: LarkIngressConfig;\n }) => Promise<void>;\n}\n\nexport function createLarkEventHandler(\n dependencies: LarkEventHandlerDependencies,\n) {\n return async function handleLarkEvent(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void> {\n const installationId = (request.params as { installationId?: string })\n ?.installationId;\n\n if (!installationId) {\n reply.status(400).send({ success: false, message: \"Missing installationId\" });\n return;\n }\n\n const config = await dependencies.getInstallationConfig(installationId);\n if (!config) {\n reply.status(404).send({ success: false, message: \"Lark installation not found\" });\n return;\n }\n\n const body = dependencies.parseRequestBody(\n request.body,\n config.encryptKey,\n ) as LarkUrlVerificationPayload;\n\n if (!dependencies.verifyParsedBody(body, config)) {\n reply.status(401).send({ success: false, message: \"Invalid Lark request\" });\n return;\n }\n\n if (body.type === \"url_verification\" && body.challenge) {\n reply.status(200).send({ challenge: body.challenge });\n return;\n }\n\n const parsed = dependencies.parseEvent(request.body);\n if (!parsed) {\n reply.status(200).send({ success: true, ignored: true });\n return;\n }\n\n const receipt = await dependencies.claimInboundReceipt({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n });\n\n if (!receipt.accepted) {\n reply.status(200).send(\n receipt.status === \"processing\"\n ? { success: true, processing: true }\n : { success: true, duplicate: true },\n );\n return;\n }\n\n try {\n const { threadId } = await dependencies.resolveThread({\n channel: \"lark\",\n channelAppId: config.appId,\n tenantId: config.tenantId,\n assistantId: config.assistantId,\n mappingMode: config.mappingMode,\n openId: parsed.openId,\n chatId: parsed.chatId,\n chatType: parsed.chatType,\n messageId: parsed.messageId,\n workspaceId: config.workspaceId,\n projectId: config.projectId,\n });\n\n const text = await dependencies.runAgentAndCollectText({\n tenantId: config.tenantId,\n assistantId: config.assistantId,\n threadId,\n text: parsed.text,\n workspaceId: config.workspaceId,\n projectId: config.projectId,\n });\n\n await dependencies.sendTextReply({\n chatId: parsed.chatId,\n text,\n config,\n });\n\n await dependencies.markInboundReceiptCompleted({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n threadId,\n });\n\n reply.status(200).send({ success: true, threadId });\n } catch (error) {\n await dependencies.markInboundReceiptFailed({\n channel: \"lark\",\n channelAppId: config.appId,\n externalMessageId: parsed.messageId,\n tenantId: config.tenantId,\n });\n throw error;\n }\n };\n}\n\nexport const handleLarkEvent = createLarkEventHandler({\n getInstallationConfig: async () => null,\n parseRequestBody: (body) => (body || {}) as LarkUrlVerificationPayload,\n verifyParsedBody: () => true,\n parseEvent: parseLarkMessageEvent,\n claimInboundReceipt: async () => ({ accepted: true, status: \"processing\" }),\n markInboundReceiptCompleted: async () => undefined,\n markInboundReceiptFailed: async () => undefined,\n resolveThread: async () => ({ threadId: \"\" }),\n runAgentAndCollectText: async () => \"\",\n sendTextReply: async () => undefined,\n});\n","import type { LarkIngressConfig } from \"./types\";\n\nexport function loadLarkIngressConfig(): LarkIngressConfig {\n return {\n enabled: process.env.LARK_ENABLED !== \"false\",\n appId: process.env.LARK_APP_ID || \"\",\n appSecret: process.env.LARK_APP_SECRET || \"\",\n verificationToken: process.env.LARK_VERIFICATION_TOKEN,\n encryptKey: process.env.LARK_ENCRYPT_KEY,\n tenantId: process.env.LARK_TENANT_ID || \"default\",\n assistantId: process.env.LARK_ASSISTANT_ID || \"default_agent\",\n workspaceId: process.env.LARK_WORKSPACE_ID,\n projectId: process.env.LARK_PROJECT_ID,\n mappingMode:\n (process.env.LARK_MAPPING_MODE as \"user\" | \"group\" | \"hybrid\") ||\n \"hybrid\",\n };\n}\n\nexport function isLarkIngressEnabled(config: LarkIngressConfig): boolean {\n return config.enabled;\n}\n\nexport function assertLarkIngressConfig(config: LarkIngressConfig): void {\n if (!config.enabled) {\n return;\n }\n\n if (!config.appId) {\n throw new Error(\"LARK_APP_ID is required when Lark ingress is enabled\");\n }\n\n if (!config.appSecret) {\n throw new Error(\"LARK_APP_SECRET is required when Lark ingress is enabled\");\n }\n\n if (!config.tenantId) {\n throw new Error(\"LARK_TENANT_ID is required when Lark ingress is enabled\");\n }\n\n if (!config.assistantId) {\n throw new Error(\"LARK_ASSISTANT_ID is required when Lark ingress is enabled\");\n }\n}\n","import type { ThreadStore } from \"@axiom-lattice/protocols\";\nimport type { ChannelIdentityMappingStore } from \"@axiom-lattice/pg-stores\";\nimport { randomUUID } from \"crypto\";\n\ninterface GetOrCreateThreadInput {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n openId: string;\n chatId: string;\n chatType: \"direct\" | \"group\";\n messageId: string;\n workspaceId?: string;\n projectId?: string;\n}\n\ninterface ChannelThreadMappingServiceDeps {\n mappingStore: Pick<\n ChannelIdentityMappingStore,\n \"getMappingBySubject\" | \"createMapping\"\n >;\n threadStore: Pick<ThreadStore, \"createThread\" | \"deleteThread\">;\n uuid?: () => string;\n}\n\nexport function createChannelThreadMappingService(\n deps: ChannelThreadMappingServiceDeps,\n) {\n return {\n async getOrCreateThread(input: GetOrCreateThreadInput): Promise<{ threadId: string }> {\n const externalSubjectKey = buildExternalSubjectKey(input);\n const existing = await deps.mappingStore.getMappingBySubject({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n externalSubjectKey,\n });\n\n if (existing) {\n return { threadId: existing.threadId };\n }\n\n const threadId = (deps.uuid || randomUUID)();\n\n await deps.threadStore.createThread(input.tenantId, input.assistantId, threadId, {\n metadata: {\n tenantId: input.tenantId,\n workspaceId: input.workspaceId,\n projectId: input.projectId,\n channel: input.channel,\n larkChatId: input.chatId,\n larkOpenId: input.openId,\n },\n });\n\n try {\n await deps.mappingStore.createMapping({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n mappingMode: input.mappingMode,\n externalSubjectType:\n resolveSubjectType(input.mappingMode, input.chatType) === \"user\"\n ? \"user\"\n : \"chat\",\n externalSubjectKey,\n larkOpenId: input.openId,\n larkChatId: input.chatId,\n larkMessageId: input.messageId,\n threadId,\n });\n } catch (error) {\n if (!isUniqueViolation(error)) {\n throw error;\n }\n\n const canonical = await deps.mappingStore.getMappingBySubject({\n channel: input.channel,\n channelAppId: input.channelAppId,\n tenantId: input.tenantId,\n assistantId: input.assistantId,\n externalSubjectKey,\n });\n\n if (!canonical) {\n throw error;\n }\n\n await deps.threadStore.deleteThread(input.tenantId, threadId);\n\n return { threadId: canonical.threadId };\n }\n\n return { threadId };\n },\n };\n}\n\nfunction isUniqueViolation(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"23505\"\n );\n}\n\nfunction buildExternalSubjectKey(input: GetOrCreateThreadInput): string {\n const subjectType = resolveSubjectType(input.mappingMode, input.chatType);\n const subjectValue = subjectType === \"user\" ? input.openId : input.chatId;\n\n return [\n input.channel,\n input.channelAppId,\n `tenant:${input.tenantId}`,\n `assistant:${input.assistantId}`,\n `${subjectType}:${subjectValue}`,\n ].join(\":\");\n}\n\nfunction resolveSubjectType(\n mappingMode: \"user\" | \"group\" | \"hybrid\",\n chatType: \"direct\" | \"group\",\n): \"user\" | \"chat\" {\n if (mappingMode === \"user\") {\n return \"user\";\n }\n\n if (mappingMode === \"group\") {\n return \"chat\";\n }\n\n return chatType === \"direct\" ? \"user\" : \"chat\";\n}\n","import { agentInstanceManager } from \"@axiom-lattice/core\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\nimport { aggregateLarkReply } from \"./aggregator\";\n\nexport async function runAgentAndCollectLarkReply(input: {\n tenantId: string;\n assistantId: string;\n threadId: string;\n text: string;\n workspaceId?: string;\n projectId?: string;\n}): Promise<string> {\n const agent = agentInstanceManager.getAgent({\n tenant_id: input.tenantId,\n assistant_id: input.assistantId,\n thread_id: input.threadId,\n workspace_id: input.workspaceId,\n project_id: input.projectId,\n });\n\n const result = await agent.addMessage({\n input: {\n message: input.text,\n },\n });\n\n const chunks = [];\n const stream = agent.chunkStream(result.messageId, [\n MessageChunkTypes.MESSAGE_COMPLETED,\n ]);\n\n for await (const chunk of stream) {\n chunks.push(chunk);\n }\n\n return aggregateLarkReply(result.messageId, chunks);\n}\n","import type { MessageChunk } from \"@axiom-lattice/protocols\";\nimport { MessageChunkTypes } from \"@axiom-lattice/protocols\";\n\nexport function aggregateLarkReply(\n messageId: string,\n chunks: MessageChunk[],\n): string {\n return chunks\n .filter(\n (chunk) =>\n chunk.type === MessageChunkTypes.AI && chunk.data.id === messageId,\n )\n .map((chunk) => chunk.data.content || \"\")\n .join(\"\")\n .trim();\n}\n","interface LarkSenderConfig {\n appId: string;\n appSecret: string;\n}\n\ninterface LarkSdkMessageClient {\n im: {\n v1: {\n message: {\n create(input: {\n params: {\n receive_id_type: \"chat_id\";\n };\n data: {\n receive_id: string;\n msg_type: \"text\";\n content: string;\n };\n }): Promise<{ code?: number }>;\n };\n };\n };\n}\n\nexport async function createLarkSender(\n config: LarkSenderConfig,\n client?: LarkSdkMessageClient,\n) {\n const resolved = client ?? (await createDefaultLarkClient(config));\n\n return {\n async sendTextReply(input: { chatId: string; text: string }): Promise<void> {\n const response = await resolved.im.v1.message.create({\n params: {\n receive_id_type: \"chat_id\",\n },\n data: {\n receive_id: input.chatId,\n msg_type: \"text\",\n content: JSON.stringify({ text: input.text }),\n },\n });\n\n if (response.code && response.code !== 0) {\n throw new Error(\"Failed to send Lark reply\");\n }\n },\n };\n}\n\nasync function createDefaultLarkClient(config: LarkSenderConfig): Promise<LarkSdkMessageClient> {\n const Lark = await import(\"@larksuiteoapi/node-sdk\");\n\n return new Lark.Client({\n appId: config.appId,\n appSecret: config.appSecret,\n }) as LarkSdkMessageClient;\n}\n","import crypto from \"crypto\";\nimport type { FastifyRequest } from \"fastify\";\nimport type { LarkIngressConfig, LarkUrlVerificationPayload } from \"./types\";\n\nexport function parseLarkRequestBody(\n body: unknown,\n encryptKey?: string,\n): LarkUrlVerificationPayload {\n const parsed = (body || {}) as LarkUrlVerificationPayload;\n\n if (encryptKey && typeof parsed.encrypt === \"string\") {\n return decryptLarkPayload(encryptKey, parsed.encrypt);\n }\n\n return parsed;\n}\n\nexport function decryptLarkPayload(\n encryptKey: string,\n encryptedPayload: string,\n): LarkUrlVerificationPayload {\n const key = crypto.createHash(\"sha256\").update(encryptKey).digest();\n const buffer = Buffer.from(encryptedPayload, \"base64\");\n const iv = buffer.subarray(0, 16);\n const ciphertext = buffer.subarray(16);\n const decipher = crypto.createDecipheriv(\"aes-256-cbc\", key, iv);\n const plaintext = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf8\");\n\n return JSON.parse(plaintext) as LarkUrlVerificationPayload;\n}\n\nexport function createLarkRequestVerifier(config: LarkIngressConfig) {\n return function verifyRequest(request: FastifyRequest): boolean {\n const body = parseLarkRequestBody(request.body, config.encryptKey);\n\n return verifyLarkParsedBody(body, config);\n };\n}\n\nexport function verifyLarkParsedBody(\n body: LarkUrlVerificationPayload,\n config: LarkIngressConfig,\n): boolean {\n \n if (!config.verificationToken) {\n return true;\n }\n\n return extractVerificationToken(body) === config.verificationToken;\n}\n\nfunction extractVerificationToken(\n body: LarkUrlVerificationPayload,\n): string | undefined {\n if (typeof body.token === \"string\") {\n return body.token;\n }\n\n if (typeof body.header?.token === \"string\") {\n return body.header.token;\n }\n\n return undefined;\n}\n","import type { FastifyInstance } from \"fastify\";\nimport type { LarkEventHandlerDependencies } from \"./lark/controller\";\nimport { registerLarkChannelRoutes } from \"./lark/routes\";\n\ninterface ChannelRouteDependencies {\n lark?: LarkEventHandlerDependencies;\n}\n\ntype ChannelRouteRegistrar = (\n app: FastifyInstance,\n dependencies: ChannelRouteDependencies,\n) => void;\n\nconst channelRouteRegistrars: ChannelRouteRegistrar[] = [\n (app, dependencies) => registerLarkChannelRoutes(app, dependencies.lark),\n];\n\nexport function registerChannelRoutes(\n app: FastifyInstance,\n dependencies: ChannelRouteDependencies = {},\n): void {\n for (const registerRoutes of channelRouteRegistrars) {\n registerRoutes(app, dependencies);\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { randomUUID } from \"crypto\";\nimport {\n ChannelInstallationStore,\n ChannelInstallation,\n CreateChannelInstallationRequest,\n UpdateChannelInstallationRequest,\n ChannelInstallationType,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Channel Installation Controller\n * Handles channel installation CRUD operations for Lark/Feishu and future channels\n * All operations are scoped to a tenant ID\n */\n\n/**\n * Get tenant ID from authenticated user context\n * Falls back to request headers for backward compatibility\n */\nfunction getTenantId(request: FastifyRequest): string {\n // First try to get from authenticated user context\n const userTenantId = (request as any).user?.tenantId;\n if (userTenantId) {\n return userTenantId;\n }\n\n // Fallback to request headers for backward compatibility\n return (request.headers[\"x-tenant-id\"] as string) || \"default\";\n}\n\n/**\n * Channel installation list response\n */\ninterface ChannelInstallationListResponse {\n success: boolean;\n message: string;\n data: {\n records: ChannelInstallation[];\n total: number;\n };\n}\n\n/**\n * Channel installation response\n */\ninterface ChannelInstallationResponse {\n success: boolean;\n message: string;\n data?: ChannelInstallation;\n}\n\n/**\n * Get channel installation store\n */\nasync function getInstallationStore(): Promise<ChannelInstallationStore> {\n // Import dynamically to avoid circular dependencies\n const { PostgreSQLChannelInstallationStore } = await import(\"@axiom-lattice/pg-stores\");\n const databaseUrl = process.env.DATABASE_URL;\n \n if (!databaseUrl) {\n throw new Error(\"DATABASE_URL is required for channel installation store\");\n }\n \n return new PostgreSQLChannelInstallationStore({\n poolConfig: databaseUrl,\n });\n}\n\n/**\n * Get all channel installations for a tenant\n */\nexport async function getChannelInstallationList(\n request: FastifyRequest<{\n Querystring: { channel?: ChannelInstallationType };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationListResponse> {\n const tenantId = getTenantId(request);\n const { channel } = request.query;\n\n try {\n const store = await getInstallationStore();\n const installations = await store.getInstallationsByTenant(tenantId, channel);\n\n return {\n success: true,\n message: \"Channel installations retrieved successfully\",\n data: {\n records: installations,\n total: installations.length,\n },\n };\n } catch (error) {\n console.error(\"Failed to get channel installations:\", error);\n return {\n success: false,\n message: \"Failed to retrieve channel installations\",\n data: {\n records: [],\n total: 0,\n },\n };\n }\n}\n\n/**\n * Get a single channel installation by ID\n */\nexport async function getChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n\n try {\n const store = await getInstallationStore();\n const installation = await store.getInstallationById(installationId);\n\n if (!installation) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n // Verify tenant access\n if (installation.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation retrieved successfully\",\n data: installation,\n };\n } catch (error) {\n console.error(\"Failed to get channel installation:\", error);\n return {\n success: false,\n message: \"Failed to retrieve channel installation\",\n };\n }\n}\n\n/**\n * Create new channel installation\n */\nexport async function createChannelInstallation(\n request: FastifyRequest<{\n Body: CreateChannelInstallationRequest & { id?: string };\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const body = request.body;\n\n try {\n // Validate required fields\n if (!body.channel) {\n reply.code(400);\n return {\n success: false,\n message: \"Channel type is required\",\n };\n }\n\n if (!body.config) {\n reply.code(400);\n return {\n success: false,\n message: \"Configuration is required\",\n };\n }\n\n // Validate Lark-specific config\n if (body.channel === \"lark\") {\n const larkConfig = body.config;\n if (!larkConfig.appId || !larkConfig.appSecret) {\n reply.code(400);\n return {\n success: false,\n message: \"appId and appSecret are required for Lark installations\",\n };\n }\n if (!larkConfig.assistantId) {\n reply.code(400);\n return {\n success: false,\n message: \"assistantId is required for Lark installations\",\n };\n }\n }\n\n const store = await getInstallationStore();\n const installationId = body.id || randomUUID();\n \n const installation = await store.createInstallation(\n tenantId,\n installationId,\n body,\n );\n\n reply.code(201);\n return {\n success: true,\n message: \"Channel installation created successfully\",\n data: installation,\n };\n } catch (error: any) {\n console.error(\"Failed to create channel installation:\", error);\n \n // Check for duplicate key error\n if (error.message?.includes(\"duplicate\") || error.code === \"23505\") {\n reply.code(409);\n return {\n success: false,\n message: \"Channel installation with this ID already exists\",\n };\n }\n\n return {\n success: false,\n message: \"Failed to create channel installation\",\n };\n }\n}\n\n/**\n * Update channel installation\n */\nexport async function updateChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n Body: UpdateChannelInstallationRequest;\n }>,\n reply: FastifyReply,\n): Promise<ChannelInstallationResponse> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n const body = request.body;\n\n try {\n const store = await getInstallationStore();\n\n // Verify installation exists and belongs to tenant\n const existing = await store.getInstallationById(installationId);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n if (existing.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n const installation = await store.updateInstallation(\n tenantId,\n installationId,\n body,\n );\n\n if (!installation) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation updated successfully\",\n data: installation,\n };\n } catch (error) {\n console.error(\"Failed to update channel installation:\", error);\n return {\n success: false,\n message: \"Failed to update channel installation\",\n };\n }\n}\n\n/**\n * Delete channel installation\n */\nexport async function deleteChannelInstallation(\n request: FastifyRequest<{\n Params: { installationId: string };\n }>,\n reply: FastifyReply,\n): Promise<{ success: boolean; message: string }> {\n const tenantId = getTenantId(request);\n const { installationId } = request.params;\n\n try {\n const store = await getInstallationStore();\n\n // Verify installation exists and belongs to tenant\n const existing = await store.getInstallationById(installationId);\n if (!existing) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n if (existing.tenantId !== tenantId) {\n reply.code(403);\n return {\n success: false,\n message: \"Access denied\",\n };\n }\n\n const deleted = await store.deleteInstallation(tenantId, installationId);\n\n if (!deleted) {\n reply.code(404);\n return {\n success: false,\n message: \"Channel installation not found\",\n };\n }\n\n return {\n success: true,\n message: \"Channel installation deleted successfully\",\n };\n } catch (error) {\n console.error(\"Failed to delete channel installation:\", error);\n return {\n success: false,\n message: \"Failed to delete channel installation\",\n };\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport * as channelInstallationController from \"../controllers/channel-installations\";\n\n/**\n * Register channel installation management routes\n */\nexport function registerChannelInstallationRoutes(app: FastifyInstance): void {\n // List all installations for current tenant\n app.get<{\n Querystring: { channel?: \"lark\" };\n }>(\"/api/channel-installations\", channelInstallationController.getChannelInstallationList);\n\n // Get single installation by ID\n app.get<{\n Params: { installationId: string };\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.getChannelInstallation);\n\n // Create new installation\n app.post<{\n Body: any;\n }>(\"/api/channel-installations\", channelInstallationController.createChannelInstallation);\n\n // Update installation\n app.put<{\n Params: { installationId: string };\n Body: any;\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.updateChannelInstallation);\n\n // Delete installation\n app.delete<{\n Params: { installationId: string };\n }>(\"/api/channel-installations/:installationId\", channelInstallationController.deleteChannelInstallation);\n}\n","import { FastifyInstance } from \"fastify\";\nimport { ScheduledTaskStatus } from \"@axiom-lattice/protocols\";\nimport * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport * as agentTaskController from \"../controllers/agent_task\";\nimport * as threadsController from \"../controllers/threads\";\nimport * as schedulesController from \"../controllers/schedules\";\nimport * as configController from \"../controllers/config\";\nimport * as modelsController from \"../controllers/models\";\nimport * as healthController from \"../controllers/health\";\nimport * as skillsController from \"../controllers/skills\";\nimport * as toolsController from \"../controllers/tools\";\nimport * as dataQueryController from \"../controllers/data-query\";\nimport * as workflowTrackingController from \"../controllers/workflow-tracking\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n triggerAgentTaskSchema,\n updateConfigSchema,\n getConfigSchema,\n getHealthSchema,\n getSandboxUrlSchema,\n dataQuerySchema,\n} from \"../schemas\";\nimport { removePendingMessageHandler } from \"../controllers/thread_status\";\nimport { registerSandboxProxyRoutes } from \"../controllers/sandbox\";\nimport { registerWorkspaceRoutes } from \"../controllers/workspace\";\nimport { registerDatabaseConfigRoutes } from \"../controllers/database-configs\";\nimport { registerMetricsServerConfigRoutes } from \"../controllers/metrics-configs\";\nimport { registerMcpServerConfigRoutes } from \"../controllers/mcp-configs\";\nimport { registerUserRoutes } from \"../controllers/users\";\nimport { registerTenantRoutes } from \"../controllers/tenants\";\nimport { registerAuthRoutes } from \"../controllers/auth\";\nimport { registerChannelRoutes } from \"../channels/routes\";\nimport { registerChannelInstallationRoutes } from \"./channel-installations\";\n// import {\n// getThreadStatusHandler,\n// getAgentThreadsHandler,\n// getActiveThreadsHandler,\n// addMessageHandler,\n// removeMessageHandler,\n// updateQueueConfigHandler,\n// } from \"../controllers/thread_status\";\n\nexport const registerLatticeRoutes = (app: FastifyInstance): void => {\n // 运行路由\n app.post<{\n Body: any;\n }>(\"/api/runs\", runController.createRun);\n\n // Resume stream route\n app.post<{\n Body: any;\n }>(\"/api/resume_stream\", runController.resumeStream);\n\n // Abort agent execution for a thread\n app.post<{\n Params: { assistantId: string; threadId: string };\n }>(\"/api/assistants/:assistantId/threads/:threadId/abort\", runController.abortRun);\n\n // app.get<{\n // Params: { id: string };\n // }>(\"/api/runs/:id\", runController.getRun);\n\n // app.get<{\n // Params: { assistantId: string };\n // }>(\"/api/assistants/:assistantId/runs\", runController.getRunsByAssistant);\n\n // app.post<{\n // Params: { id: string };\n // }>(\"/api/runs/:id/cancel\", runController.cancelRun);\n\n // 内存路由\n app.get<{\n Params: { assistantId: string; thread_id: string };\n }>(\n \"/api/assistants/:assistantId/:thread_id/memory\",\n { schema: getAllMemoryItemsSchema },\n memoryController.getAllMemoryItems\n );\n\n app.get<{\n Params: { assistantId: string; thread_id: string };\n }>(\n \"/api/assistants/:assistantId/:thread_id/state\",\n { schema: getAgentStateSchema },\n memoryController.getAgentState\n );\n\n app.get<{\n Params: { assistantId: string; key: string };\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: getMemoryItemSchema },\n memoryController.getMemoryItem\n );\n\n app.put<{\n Params: { assistantId: string; key: string };\n Body: any;\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: setMemoryItemSchema },\n memoryController.setMemoryItem\n );\n\n app.delete<{\n Params: { assistantId: string; key: string };\n }>(\n \"/api/assistants/:assistantId/memory/:key\",\n { schema: deleteMemoryItemSchema },\n memoryController.deleteMemoryItem\n );\n\n app.delete<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/memory\",\n { schema: clearMemorySchema },\n memoryController.clearMemory\n );\n\n // Assistant CRUD routes\n app.get(\"/api/assistants\", assistantController.getAssistantList);\n\n app.get<{\n Params: { id: string };\n }>(\"/api/assistants/:id\", assistantController.getAssistant);\n\n app.post<{\n Body: any;\n }>(\"/api/assistants\", assistantController.createAssistant);\n\n app.put<{\n Params: { id: string };\n Body: any;\n }>(\"/api/assistants/:id\", assistantController.updateAssistant);\n\n app.delete<{\n Params: { id: string };\n }>(\"/api/assistants/:id\", assistantController.deleteAssistant);\n\n // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n\n // Agent Task路由\n app.post<{\n Body: any;\n }>(\n \"/api/agent-tasks/trigger\",\n { schema: triggerAgentTaskSchema },\n agentTaskController.triggerAgentTask\n );\n\n // Thread CRUD routes for a specific assistant\n app.get<{\n Params: { assistantId: string };\n }>(\"/api/assistants/:assistantId/threads\", threadsController.getThreadList);\n\n app.get<{\n Params: { assistantId: string; threadId: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.getThread\n );\n\n app.post<{\n Params: { assistantId: string };\n Body: any;\n }>(\"/api/assistants/:assistantId/threads\", threadsController.createThread);\n\n app.put<{\n Params: { assistantId: string; threadId: string };\n Body: any;\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.updateThread\n );\n\n app.delete<{\n Params: { assistantId: string; threadId: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId\",\n threadsController.deleteThread\n );\n\n // Configuration routes\n app.get(\n \"/api/config\",\n { schema: getConfigSchema },\n configController.getConfig\n );\n\n app.put<{\n Body: { config: Record<string, any> };\n }>(\n \"/api/config\",\n { schema: updateConfigSchema },\n configController.updateConfig\n );\n\n // Models routes\n app.get(\"/api/models\", modelsController.getModels);\n\n app.put<{\n Body: { models: any[] };\n }>(\"/api/models\", modelsController.updateModels);\n\n // Tools config meta route\n app.get(\"/api/tools\", toolsController.getToolConfigs);\n\n // Health check route\n app.get(\n \"/health\",\n { schema: getHealthSchema },\n healthController.getHealth\n );\n\n // Schedule routes for viewing scheduled tasks by thread\n app.get<{\n Params: { assistantId: string; threadId: string };\n Querystring: {\n status?: ScheduledTaskStatus;\n limit?: string;\n offset?: string;\n };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId/schedules\",\n schedulesController.getThreadSchedules\n );\n\n // Get a specific scheduled task\n app.get<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId\", schedulesController.getScheduledTask);\n\n // Cancel a scheduled task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/cancel\", schedulesController.cancelScheduledTask);\n\n // Pause a scheduled cron task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/pause\", schedulesController.pauseScheduledTask);\n\n // Resume a paused cron task\n app.post<{\n Params: { taskId: string };\n }>(\"/api/schedules/:taskId/resume\", schedulesController.resumeScheduledTask);\n\n // Skills CRUD routes\n app.get(\"/api/skills\", skillsController.getSkillList);\n\n app.get<{\n Params: { id: string };\n }>(\n \"/api/skills/:id\",\n skillsController.getSkill\n );\n\n app.post<{\n Body: any;\n }>(\n \"/api/skills\",\n skillsController.createSkill\n );\n\n app.put<{\n Params: { id: string };\n Body: any;\n }>(\n \"/api/skills/:id\",\n skillsController.updateSkill\n );\n\n app.delete<{\n Params: { id: string };\n }>(\n \"/api/skills/:id\",\n skillsController.deleteSkill\n );\n\n // Skills search and filter routes\n app.get<{\n Querystring: { key: string; value: string };\n }>(\n \"/api/skills/search/metadata\",\n skillsController.searchSkillsByMetadata\n );\n\n app.get<{\n Querystring: { compatibility: string };\n }>(\n \"/api/skills/filter/compatibility\",\n skillsController.filterSkillsByCompatibility\n );\n\n app.get<{\n Querystring: { license: string };\n }>(\n \"/api/skills/filter/license\",\n skillsController.filterSkillsByLicense\n );\n\n registerSandboxProxyRoutes(app);\n\n registerWorkspaceRoutes(app);\n\n registerDatabaseConfigRoutes(app);\n\n registerMetricsServerConfigRoutes(app);\n\n // Data query route\n app.post<{\n Body: any;\n }>(\n \"/api/data/query\",\n { schema: dataQuerySchema },\n dataQueryController.executeDataQuery\n );\n\n registerMcpServerConfigRoutes(app);\n\n registerUserRoutes(app);\n\n registerTenantRoutes(app);\n\n registerAuthRoutes(app, {\n autoApproveUsers: process.env.AUTO_APPROVE_USERS !== \"false\",\n allowTenantRegistration: process.env.ALLOW_TENANT_REGISTRATION !== \"false\",\n });\n\n registerChannelRoutes(app);\n\n registerChannelInstallationRoutes(app);\n\n // Workflow tracking routes\n app.get(\n \"/api/workflows/definitions\",\n workflowTrackingController.getAllWorkflowDefinitions\n );\n\n app.get<{\n Querystring: { assistantId?: string; status?: string };\n }>(\n \"/api/workflows/runs\",\n workflowTrackingController.getAllWorkflowRuns\n );\n\n app.get(\n \"/api/workflows/inbox\",\n workflowTrackingController.getInboxItems\n );\n\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/workflows/definitions\",\n workflowTrackingController.getWorkflowDefinitions\n );\n\n app.get<{\n Params: { assistantId: string; threadId: string };\n }>(\n \"/api/assistants/:assistantId/threads/:threadId/workflows/runs\",\n workflowTrackingController.getWorkflowRuns\n );\n\n app.get<{\n Params: { runId: string };\n }>(\"/api/workflows/runs/:runId\", workflowTrackingController.getWorkflowRun);\n\n app.get<{\n Params: { runId: string };\n Querystring: { step_type?: string; status?: string };\n }>(\"/api/workflows/runs/:runId/steps\", workflowTrackingController.getRunSteps);\n\n app.get<{\n Params: { runId: string };\n }>(\"/api/workflows/runs/:runId/tasks\", workflowTrackingController.getRunTasks);\n\n // // Thread 状态查询路由\n // app.get(\"/api/threads/:thread_id/status\", getThreadStatusHandler);\n // app.get(\"/api/assistants/:assistant_id/threads/status\", getAgentThreadsHandler);\n // app.get(\"/api/threads/active\", getActiveThreadsHandler);\n\n // // Thread 消息队列路由\n // app.post(\"/api/threads/:thread_id/messages\", addMessageHandler);\n // app.delete(\"/api/threads/:thread_id/messages/:message_id\", removeMessageHandler);\n // app.put(\"/api/threads/:thread_id/queue-config\", updateQueueConfigHandler);\n\n // Delete pending message route\n app.delete<{\n Params: { assistant_id: string; thread_id: string; message_id: string };\n }>(\n \"/api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id\",\n removePendingMessageHandler\n );\n};\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n","import { eventBus, AGENT_TASK_EVENT, agentInstanceManager, QueueMode } from \"@axiom-lattice/core\";\nimport { popAgentTaskFromQueue } from \"./queue_service\";\n\n// 任务请求结构\nexport interface AgentTaskRequest {\n assistant_id: string;\n input: any;\n thread_id: string;\n \"x-tenant-id\": string;\n command?: any;\n callback_event?: string;\n runConfig?: Record<string, any>;\n main_thread_id?: string;\n main_tenant_id?: string;\n main_assistant_id?: string;\n}\n\n/**\n * 处理Agent任务事件\n * @param taskRequest 任务请求\n * @param retryCount 重试次数\n */\nconst handleAgentTask = async (\n taskRequest: AgentTaskRequest,\n retryCount: number = 0\n): Promise<boolean> => {\n const {\n assistant_id,\n input = {},\n thread_id,\n \"x-tenant-id\": tenant_id,\n command,\n callback_event,\n runConfig,\n main_thread_id,\n main_tenant_id,\n main_assistant_id,\n } = taskRequest;\n\n\n try {\n console.log(\n `开始处理任务 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n\n // 检查API服务器是否可用\n // const apiUrl = AgentTaskConsumer.agent_run_endpoint;\n\n // console.log(`apiUrl: ${apiUrl}`);\n const agent = agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig })\n await agent.addMessage({ input, command, custom_run_config: runConfig }, QueueMode.STEER);\n if (callback_event) {\n agent.subscribeOnce(\"message:completed\", (evt) => {\n eventBus.publish(callback_event, {\n success: true,\n state: evt.state,\n config: { assistant_id, thread_id, tenant_id },\n });\n\n if (main_thread_id && main_tenant_id) {\n try {\n const mainAgent = agentInstanceManager.getAgent({\n assistant_id: main_assistant_id ?? assistant_id,\n thread_id: main_thread_id,\n tenant_id: main_tenant_id,\n });\n if (mainAgent) {\n const messages = evt.state?.values?.messages;\n const lastAIMessage = messages\n ?.filter((m: any) => m.type === 'ai' || m.getType?.() === 'ai')\n .pop();\n const summary = lastAIMessage?.content\n ?.substring(0, 500) ?? '(no output)';\n\n mainAgent.addMessage(\n {\n input: {\n message: `[Async task completed]\\ntask_id: ${thread_id}\\n${summary}`,\n },\n },\n ).catch((err: Error) => {\n console.error('Failed to notify main thread:', err);\n });\n\n mainAgent.updateAsyncTaskStatus(thread_id, 'completed');\n }\n } catch (err) {\n console.error('Failed to notify main thread:', err);\n }\n }\n })\n agent.subscribeOnce(\"message:interrupted\", (evt) => {\n eventBus.publish(callback_event, {\n success: true,\n state: evt.state,\n config: { assistant_id, thread_id, tenant_id },\n });\n })\n }\n\n return true;\n\n\n\n } catch (error) {\n console.error(\n `Agent任务执行失败: ${assistant_id}, 线程: ${thread_id}`,\n error\n );\n\n // 重试逻辑,暂不用重试\n const maxRetries = 0;\n if (retryCount < maxRetries) {\n const nextRetryCount = retryCount + 1;\n const delayMs = Math.pow(2, nextRetryCount) * 1000; // 指数退避策略\n\n console.log(\n `将在 ${delayMs}ms 后重试任务 (${nextRetryCount}/${maxRetries})`\n );\n\n // 延迟后重试\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n return handleAgentTask(taskRequest, nextRetryCount);\n }\n\n if (callback_event) {\n eventBus.publish(callback_event, {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.error(\n `任务处理失败,已达到最大重试次数 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return false;\n }\n};\n\n/**\n * Agent任务消费者\n * 负责监听和执行Agent任务事件,同时从队列中消费任务\n */\nexport class AgentTaskConsumer {\n private isPolling: boolean = false;\n private pollingInterval: NodeJS.Timeout | null = null;\n private pollingIntervalMs: number = 5000; // 默认5秒轮询一次\n private maxConcurrentTasks: number = 15; // 最大并发任务数\n private activeTasks: number = 0; // 当前活跃的任务数\n private processing: boolean = false; // 是否正在处理任务批次\n private immediateProcessingEnabled: boolean = true; // 是否启用即时处理模式\n public gatewayPort: number = 4001;\n public static agent_run_endpoint: string = \"http://localhost:4001/api/runs\";\n\n constructor(gatewayPort: number, pollingIntervalMs?: number) {\n this.gatewayPort = gatewayPort;\n AgentTaskConsumer.agent_run_endpoint = `http://localhost:${this.gatewayPort}/api/runs`;\n if (pollingIntervalMs) {\n this.pollingIntervalMs = pollingIntervalMs;\n }\n this.initialize();\n }\n\n /**\n * 初始化事件监听和队列轮询\n */\n private initialize(): void {\n // 监听事件总线上的任务\n eventBus.subscribe(AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));\n\n // 启动队列轮询\n this.startPollingQueue();\n\n console.log(\"Agent任务消费者已启动并监听任务事件和队列\");\n }\n\n /**\n * 启动队列轮询\n */\n startPollingQueue(): void {\n if (this.isPolling) {\n return;\n }\n\n this.isPolling = true;\n\n this.pollingInterval = setInterval(async () => {\n try {\n // 如果上一批次任务还在处理中,跳过本次轮询\n if (this.processing) {\n console.log(\"队列处理中,跳过本次轮询\");\n return;\n }\n\n await this.consumeFromQueue();\n } catch (error) {\n console.error(\"队列轮询出错:\", error);\n }\n }, this.pollingIntervalMs);\n\n console.log(\n `开始轮询队列,间隔: ${this.pollingIntervalMs}ms,最大并发任务数: ${this.maxConcurrentTasks}`\n );\n }\n\n /**\n * 停止队列轮询\n */\n stopPollingQueue(): void {\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = null;\n this.isPolling = false;\n console.log(\"已停止队列轮询\");\n }\n }\n\n /**\n * 处理单个任务并在完成后立即尝试处理下一个\n */\n async processNextTask(): Promise<boolean> {\n try {\n // 从队列中获取任务\n const queueResult = await popAgentTaskFromQueue();\n\n // 检查队列结果\n if (queueResult && queueResult.data) {\n const taskItem = queueResult.data;\n\n if (taskItem && typeof taskItem === \"object\") {\n const taskRequest = taskItem as AgentTaskRequest;\n\n console.log(\n `从队列中获取到任务 [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`\n );\n\n // 增加活跃任务计数\n this.activeTasks++;\n\n // 处理任务(不使用await,允许并发执行)\n handleAgentTask(taskRequest)\n .then((success) => {\n if (!success) {\n console.error(`任务 处理失败`);\n // 可以在这里记录失败任务或执行补偿逻辑\n } else {\n console.log(`任务 处理成功`);\n }\n })\n .catch((error) => {\n console.error(`任务 处理时出错:`, error);\n })\n .finally(() => {\n // 减少活跃任务计数\n this.activeTasks--;\n\n // 如果启用了即时处理模式,尝试处理更多任务\n if (this.immediateProcessingEnabled && !this.processing) {\n this.checkQueueForTasks();\n }\n });\n\n // 任务已派发,返回true表示有任务被处理\n return true;\n } else {\n console.log(\"队列任务格式无效:\", taskItem);\n return false;\n }\n } else {\n // 队列为空\n return false;\n }\n } catch (error) {\n console.error(\"处理任务失败:\", error);\n return false;\n }\n }\n\n /**\n * 检查队列中是否有任务并处理\n */\n async checkQueueForTasks(): Promise<void> {\n // 如果已经在处理中或者并发任务已达上限,则不处理\n if (this.processing || this.activeTasks >= this.maxConcurrentTasks) {\n return;\n }\n\n this.processing = true;\n\n try {\n // 尝试获取并处理任务,直到达到并发上限\n while (this.activeTasks < this.maxConcurrentTasks) {\n const taskProcessed = await this.processNextTask();\n if (!taskProcessed) {\n // 没有更多任务,退出循环\n break;\n }\n }\n } catch (error) {\n console.error(\"检查队列任务失败:\", error);\n } finally {\n this.processing = false;\n }\n }\n\n /**\n * 从队列中消费任务\n */\n async consumeFromQueue(): Promise<void> {\n // 如果已经在处理中,跳过\n if (this.processing) {\n return;\n }\n\n // 调用任务检查方法\n await this.checkQueueForTasks();\n }\n\n /**\n * 处理通过事件触发的任务\n */\n trigger_agent_task(taskRequest: AgentTaskRequest): void {\n console.log(\n `通过事件触发任务: [assistant: ${taskRequest.assistant_id}, thread: ${taskRequest.thread_id}]`\n );\n\n // 处理任务,不阻塞事件处理流程\n handleAgentTask(taskRequest).catch((error) => {\n console.error(\"处理Agent任务时发生未捕获的错误:\", error);\n\n // 如果有回调事件,确保即使发生错误也能通知\n if (taskRequest.callback_event) {\n eventBus.publish(taskRequest.callback_event, {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n config: {\n assistant_id: taskRequest.assistant_id,\n thread_id: taskRequest.thread_id,\n tenant_id: taskRequest[\"x-tenant-id\"],\n },\n });\n }\n });\n\n // 如果启用了即时处理且当前活跃任务数低于阈值,检查队列\n if (\n this.immediateProcessingEnabled &&\n this.activeTasks < this.maxConcurrentTasks\n ) {\n setImmediate(() => this.checkQueueForTasks());\n }\n }\n}\n"],"mappings":"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","names":["import_core","exists","import_core","import_core","import_core","import_core","import_crypto","getTenantId","import_core","getTenantId","import_core","import_protocols","import_core","import_core","getTenantId","import_core","import_core","getTenantId","import_core","getTenantId","import_core","import_core","import_core","path","app","import_core","import_uuid","uuidv4","filename","content","path","result","stat","app","import_core","import_crypto","getTenantId","app","import_core","import_crypto","getTenantId","app","import_core","import_crypto","getTenantId","app","import_core","import_uuid","uuidv4","app","import_core","import_uuid","uuidv4","app","import_core","import_uuid","uuidv4","app","import_core","handleLarkEvent","import_crypto","import_core","import_protocols","import_protocols","import_crypto","crypto","app","app","import_crypto","getTenantId","PostgreSQLChannelInstallationStore","app","app","app","swagger","swaggerUi","import_core","import_core","import_protocols","fastify","cors","sensible","multipart","websocket","path","staticPlugin"]}