@axiom-lattice/gateway 2.1.22 → 2.1.23

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/services/agent_service.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/controllers/skills.ts","../src/controllers/tools.ts","../src/schemas/index.ts","../src/services/sandbox_service.ts","../src/controllers/sandbox.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 sensible from \"@fastify/sensible\";\nimport websocket from \"@fastify/websocket\";\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} from \"@axiom-lattice/core\";\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\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\"],\n allowedHeaders: [\n \"Content-Type\",\n \"Authorization\",\n \"X-Requested-With\",\n \"x-tenant-id\",\n \"x-request-id\",\n ],\n exposedHeaders: [\"Content-Type\"],\n credentials: true,\n});\napp.register(sensible);\napp.register(websocket);\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\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 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 // 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 } 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 {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n filterMessages,\n HumanMessage,\n ToolMessage,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Command, CommandParams } from \"@langchain/langgraph\";\nimport { v4 } from \"uuid\";\n// 修改导入路径,使用 lattice_core 包\nimport {\n getAgentClient,\n getAgentLattice,\n InMemoryChunkBuffer,\n registerChunkBuffer,\n getChunkBuffer,\n hasChunkBuffer,\n} from \"@axiom-lattice/core\";\n\n/**\n * Get or create the global ChunkBuffer instance\n */\nfunction getOrCreateChunkBuffer(): InMemoryChunkBuffer {\n if (!hasChunkBuffer(\"default\")) {\n const buffer = new InMemoryChunkBuffer({\n ttl: 60 * 60 * 1000, // 1 hour TTL\n cleanupInterval: 5 * 60 * 1000, // Clean every 5 minutes\n });\n registerChunkBuffer(\"default\", buffer);\n }\n return getChunkBuffer(\"default\") as InMemoryChunkBuffer;\n}\n\nexport async function agent_invoke({\n input,\n thread_id,\n assistant_id,\n tenant_id,\n command,\n run_id,\n}: {\n assistant_id: string;\n input: any;\n thread_id: string;\n tenant_id: string;\n run_id?: string;\n command?: CommandParams<any>;\n}) {\n const agentLattice = getAgentLattice(assistant_id);\n const runnable_agent = agentLattice?.client;\n\n const { message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n\n // Get runConfig from agent config and merge into configurable\n const runConfig = {\n ...agentLattice?.config?.runConfig || {},\n assistant_id,\n sandboxConfig: agentLattice?.config?.connectedSandbox,\n }\n\n const result = await runnable_agent.invoke(\n command\n ? new Command(command)\n : { ...rest, messages, \"x-tenant-id\": tenant_id },\n {\n configurable: {\n thread_id: thread_id,\n run_id: run_id || v4(),\n \"x-tenant-id\": tenant_id,\n \"x-request-id\": run_id,\n \"x-thread-id\": thread_id,\n runConfig, // Inject runConfig for tools to access\n },\n recursionLimit: 200,\n }\n );\n\n const data = result.messages.map((message: BaseMessage) => {\n const { type, data } = message.toDict();\n return {\n ...data,\n role: type,\n };\n });\n return { messages: data };\n}\n\nexport async function agent_stream({\n input,\n thread_id,\n command,\n tenant_id,\n assistant_id,\n run_id,\n}: {\n assistant_id: string;\n input: any;\n thread_id: string;\n command?: CommandParams<any>;\n tenant_id: string;\n run_id?: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id) as any; // TODO: fix this\n const agentLattice = getAgentLattice(assistant_id);\n const { message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\n\n // Get runConfig from agent config and merge into configurable\n const runConfig = {\n ...agentLattice?.config?.runConfig || {},\n assistant_id,\n sandboxConfig: agentLattice?.config?.connectedSandbox,\n }\n\n try {\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const agentStream = await runnable_agent.stream(\n command\n ? new Command(command)\n : {\n ...rest,\n messages,\n \"x-tenant-id\": tenant_id,\n },\n\n {\n configurable: {\n thread_id: thread_id,\n run_id: run_id || v4(),\n \"x-tenant-id\": tenant_id,\n \"x-request-id\": run_id,\n \"x-thread-id\": thread_id,\n runConfig, // Inject runConfig for tools to access\n },\n streamMode: [\"updates\", \"messages\"],\n subgraphs: false,\n recursionLimit: 200,\n }\n );\n\n // 创建一个可迭代的 ReadableStream with ChunkBuffer integration\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of agentStream) {\n let data;\n let chunkContent = \"\";\n\n if (chunk[0] === \"updates\") {\n const update = chunk[1];\n const values = Object.values(update);\n const messages = (values[0] as any)?.messages;\n if (messages?.[0]?.tool_call_id) {\n data = messages[0].toDict();\n }\n } else if (chunk[0] === \"messages\") {\n const messages = chunk[1];\n // console.log(messages);\n data = messages?.[0]?.toDict();\n }\n\n if ((chunk?.[1] as any)?.__interrupt__) {\n //data = chunk?.[1]?.[0]?.toDict();\n // 原有的中断消息处理\n data = {\n type: \"interrupt\",\n id: (chunk?.[1] as any)?.__interrupt__[0].id,\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\n if (data.type !== \"interrupt\") {\n await chunkBuffer.addChunk(thread_id, data);\n }\n yield data;\n }\n }\n\n // Mark thread as completed when streaming finishes successfully\n await chunkBuffer.completeThread(thread_id);\n } catch (error) {\n console.error(\"Stream error:\", error);\n // Mark thread as aborted on error\n await chunkBuffer.abortThread(thread_id);\n throw error;\n }\n },\n };\n } catch (error) {\n // Mark thread as aborted on initialization error\n await chunkBuffer.abortThread(thread_id);\n throw error;\n }\n}\n\nexport async function agent_state({\n thread_id,\n assistant_id,\n}: {\n assistant_id: string;\n thread_id: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const state = await runnable_agent.getState({\n configurable: { thread_id: thread_id, subgraphs: false },\n });\n return state;\n}\n\nexport async function agent_messages({\n thread_id,\n tenant_id,\n assistant_id,\n}: {\n assistant_id: string;\n thread_id: string;\n tenant_id: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const state = await runnable_agent.getState({\n configurable: { thread_id: thread_id, subgraphs: false },\n });\n\n const messages = state.values.messages || [];\n const filteredMessages = filterMessages(messages, {\n includeTypes: [\"ai\", \"human\", \"tool\"], //[\"human\", \"ai\", \"tool\"],\n });\n\n // console.log(filteredMessages);\n\n let messagesArray = filteredMessages.map((message: BaseMessage) => ({\n id: message.id,\n role: message.getType(),\n content: message.content,\n ...message.lc_kwargs,\n }));\n\n // const action_messages = state.tasks.flatMap((task) => {\n // return task.interrupts.map((interrupt) => {\n // return {\n // role: \"ai\",\n // content: interrupt.value,\n // type: \"action\",\n // };\n // });\n // });\n\n const new_messages = messagesArray;\n // console.log(messagesArray);\n\n return new_messages;\n}\n\nexport async function draw_graph(assistant_id: string) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const drawableGraph = await runnable_agent.getGraphAsync();\n const image = await drawableGraph.drawMermaid();\n return image;\n}\n\n/**\n * Resume streaming from a known position\n * Creates an async iterator that yields new chunks as they arrive\n *\n * @param thread_id - Thread identifier\n * @param message_id - Message identifier (usually run_id)\n * @param known_content - Content already received (used to find resume position)\n * @param poll_interval - Polling interval in milliseconds (default: 100ms)\n */\nexport async function resume_stream({\n thread_id,\n message_id,\n known_content,\n poll_interval = 100,\n}: {\n thread_id: string;\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}) {\n const chunkBuffer = getOrCreateChunkBuffer();\n\n const stream = await chunkBuffer.getNewChunksSinceContentIterator(\n thread_id,\n message_id,\n known_content\n );\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of stream) {\n yield chunk;\n }\n } catch (error) {\n console.error(\"Resume stream error:\", error);\n throw error;\n }\n },\n };\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { draw_graph } from \"../services/agent_service\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\nimport { AgentConfig, getAllAgentConfigs } 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 * Convert AgentConfig to Assistant format\n */\nfunction convertAgentConfigToAssistant(config: AgentConfig): Assistant {\n return {\n id: config.key,\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 // Get code-configured agents\n const agentConfigs = await getAllAgentConfigs();\n const codeConfiguredAssistants = agentConfigs.map(\n convertAgentConfigToAssistant\n );\n\n // Get stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const storedAssistants = await assistantStore.getAllAssistants();\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\n // First check stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n let assistant = await assistantStore.getAssistantById(id);\n\n // If not found in store, check code-configured agents\n if (!assistant) {\n const agentConfigs = await getAllAgentConfigs();\n const agentConfig = agentConfigs.find((config) => config.key === 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 * Create a new assistant\n */\nexport async function createAssistant(\n request: FastifyRequest<{ Body: CreateAssistantRequest }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const data = request.body;\n\n // Validate required fields\n if (!data.name) {\n return reply.status(400).send({\n success: false,\n message: \"name is required\",\n });\n }\n\n if (!data.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"graphDefinition is required\",\n });\n }\n\n // Generate ID if not provided\n const id = randomUUID();\n\n // Create assistant\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const newAssistant = await assistantStore.createAssistant(id, data);\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created assistant\",\n data: newAssistant,\n });\n}\n\n/**\n * Update an existing assistant by ID\n * Only works on stored assistants, not code-configured ones\n */\nexport async function updateAssistant(\n request: FastifyRequest<{\n Params: { id: string };\n Body: AssistantUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const { id } = request.params;\n const updates = request.body;\n\n // Check if it's a code-configured agent\n const agentConfigs = await getAllAgentConfigs();\n const isCodeConfigured = agentConfigs.some((config) => config.key === id);\n\n if (isCodeConfigured) {\n return reply.status(403).send({\n success: false,\n message:\n \"Cannot update code-configured assistant. Only stored assistants can be updated.\",\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n // Check if assistant exists in store\n const exists = await assistantStore.hasAssistant(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n // Update assistant\n const updatedAssistant = await assistantStore.updateAssistant(id, updates);\n\n if (!updatedAssistant) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update assistant\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated assistant\",\n data: updatedAssistant,\n };\n}\n\n/**\n * Delete an assistant by ID\n * Only works on stored assistants, not code-configured ones\n */\nexport async function deleteAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { id } = request.params;\n\n // Check if it's a code-configured agent\n const agentConfigs = await getAllAgentConfigs();\n const isCodeConfigured = agentConfigs.some((config) => config.key === id);\n\n if (isCodeConfigured) {\n return reply.status(403).send({\n success: false,\n message:\n \"Cannot delete code-configured assistant. Only stored assistants can be deleted.\",\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n // Check if assistant exists in store\n const exists = await assistantStore.hasAssistant(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n // Delete the assistant\n const deleted = await assistantStore.deleteAssistant(id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete assistant\",\n });\n }\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\n // Call drawing service to get image data\n const imageData = await draw_graph(assistantId);\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 * as agentService from \"../services/agent_service\";\nimport { CreateRunRequest } from \"../types\";\nimport { v4 } from \"uuid\";\n\ninterface ResumeStreamRequest {\n thread_id: string;\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}\n\n// 创建运行\nexport const createRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const {\n assistant_id,\n thread_id,\n command,\n streaming,\n background,\n ...input\n } = request.body as CreateRunRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const x_request_id = (request.headers[\"x-request-id\"] as string) || v4();\n\n // 验证请求数据\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n // 如果请求streaming,则agent_stream\n if (streaming) {\n // 开始运行\n const stream = await agentService.agent_stream({\n assistant_id: assistant_id,\n input: input,\n thread_id: thread_id,\n command,\n tenant_id: tenant_id,\n run_id: x_request_id,\n });\n\n // 通知 Fastify 我们将手动处理响应\n reply.hijack();\n\n // 设置 SSE 响应头\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 for await (const chunk of stream) {\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error) {\n console.error(\"Stream processing error:\", error);\n } finally {\n reply.raw.end();\n }\n } else {\n // 后台运行的情况\n const result = await agentService.agent_invoke({\n assistant_id: assistant_id,\n input: input,\n command: command,\n thread_id: thread_id,\n tenant_id: tenant_id,\n run_id: x_request_id,\n });\n reply.status(200).send(result);\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 const { thread_id, message_id, known_content, poll_interval } =\n request.body as ResumeStreamRequest;\n\n // Validate request data\n if (!thread_id || !message_id || known_content === undefined) {\n reply.status(400).send({\n success: false,\n error: \"thread_id, message_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 // Get the stream from agent service\n const stream = await agentService.resume_stream({\n thread_id,\n message_id,\n known_content: known_content,\n poll_interval: poll_interval || 100,\n });\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\n // console.log(\"resume stream raw.write\", chunk);\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error) {\n console.error(\"Resume stream processing error:\", error);\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","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agent_messages, agent_state } from \"../services/agent_service\";\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 result = await agent_messages({\n assistant_id: assistantId,\n thread_id: thread_id,\n tenant_id: tenant_id,\n });\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 result = await agent_state({\n assistant_id: assistantId,\n thread_id: thread_id,\n });\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 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 an assistant ID\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<{ Params: { assistantId: string } }>,\n reply: FastifyReply\n): Promise<ThreadListResponse> {\n const { assistantId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const threads = await threadStore.getThreadsByAssistantId(assistantId);\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 assistant\n */\nexport async function getThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const { assistantId, threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const thread = await threadStore.getThreadById(assistantId, 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 { assistantId } = request.params;\n const data = request.body;\n\n // Generate thread ID if not provided\n const threadId = randomUUID();\n\n // Create thread\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const newThread = await threadStore.createThread(assistantId, threadId, data);\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 { assistantId, 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(assistantId, 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 assistantId,\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 { assistantId, 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(assistantId, 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(assistantId, 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 */\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 filters: {\n threadId: string;\n assistantId?: string;\n status?: ScheduledTaskStatus;\n limit?: number;\n offset?: number;\n } = {\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 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, 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 */\n\ninterface ModelConfig {\n key: string;\n model: 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\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 return {\n key: lattice.key,\n model: config.model || \"\",\n provider: config.provider || \"openai\",\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 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","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { validateSkillName } from \"@axiom-lattice/core\";\nimport type {\n Skill,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Skills Controller\n * Handles skill-related CRUD operations\n */\n\n/**\n * Skill list response interface\n */\ninterface SkillListResponse {\n success: boolean;\n message: string;\n data: {\n records: Skill[];\n total: number;\n };\n}\n\n/**\n * Skill response interface\n */\ninterface SkillResponse {\n success: boolean;\n message: string;\n data?: Skill;\n}\n\n/**\n * Skill update request body interface\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\n/**\n * Serialize Skill object for JSON response\n * Converts Date objects to ISO strings\n * Explicitly creates a plain object to ensure all fields are serializable\n */\nfunction serializeSkill(skill: Skill): any {\n // Explicitly create a plain object with all fields\n // This ensures Fastify can properly serialize the response\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() : (skill.createdAt ? new Date(skill.createdAt).toISOString() : new Date().toISOString()),\n updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : (skill.updatedAt ? new Date(skill.updatedAt).toISOString() : new Date().toISOString()),\n };\n\n // Remove undefined fields to avoid serialization issues\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) {\n delete serialized[key];\n }\n });\n\n return serialized;\n}\n\n/**\n * Get list of all skills\n */\nexport async function getSkillList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.getAllSkills();\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully retrieved skill list\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single skill by ID\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\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skill = await skillStore.getSkillById(id);\n\n if (!skill) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved skill\",\n data: serializeSkill(skill),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Create a new skill\n */\nexport async function createSkill(\n request: FastifyRequest<{ Body: CreateSkillRequest }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const data = request.body;\n\n // Validate required fields\n if (!data.name) {\n return reply.status(400).send({\n success: false,\n message: \"name is required\",\n });\n }\n\n if (!data.description) {\n return reply.status(400).send({\n success: false,\n message: \"description is required\",\n });\n }\n\n // Validate name format\n try {\n validateSkillName(data.name);\n } catch (error: any) {\n return reply.status(400).send({\n success: false,\n message: error.message || \"Invalid skill name format\",\n });\n }\n\n // ID must equal name (name is used for path addressing)\n const id = (request.body as any).id || data.name;\n \n if (id !== data.name) {\n return reply.status(400).send({\n success: false,\n message: `id \"${id}\" must equal name \"${data.name}\" (name is used for path addressing)`,\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill already exists\n const exists = await skillStore.hasSkill(id);\n if (exists) {\n return reply.status(409).send({\n success: false,\n message: `Skill with id \"${id}\" already exists`,\n });\n }\n\n // Create skill\n const newSkill = await skillStore.createSkill(id, data);\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created skill\",\n data: serializeSkill(newSkill),\n });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to create skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Update an existing skill by ID\n */\nexport async function updateSkill(\n request: FastifyRequest<{\n Params: { id: string };\n Body: SkillUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const updates = request.body;\n\n // Validate name format if name is being updated\n if (updates.name !== undefined) {\n try {\n validateSkillName(updates.name);\n } catch (error: any) {\n return reply.status(400).send({\n success: false,\n message: error.message || \"Invalid skill name format\",\n });\n }\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill exists\n const exists = await skillStore.hasSkill(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n // Update skill\n const updatedSkill = await skillStore.updateSkill(id, updates);\n\n if (!updatedSkill) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update skill\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated skill\",\n data: serializeSkill(updatedSkill),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to update skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Delete a skill by ID\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\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill exists\n const exists = await skillStore.hasSkill(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n // Delete the skill\n const deleted = await skillStore.deleteSkill(id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete skill\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully deleted skill\",\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to delete skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Search skills by metadata\n */\nexport async function searchSkillsByMetadata(\n request: FastifyRequest<{\n Querystring: { key: string; value: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { key, value } = request.query;\n\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.searchByMetadata(key, value);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully searched skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter skills by compatibility\n */\nexport async function filterSkillsByCompatibility(\n request: FastifyRequest<{\n Querystring: { compatibility: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { compatibility } = request.query;\n\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.filterByCompatibility(compatibility);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter skills by license\n */\nexport async function filterSkillsByLicense(\n request: FastifyRequest<{\n Querystring: { license: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { license } = request.query;\n\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.filterByLicense(license);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice, toolLatticeManager } from \"@axiom-lattice/core\";\nimport type {\n Tool,\n ToolConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Tools Controller\n * Handles tool-related CRUD operations\n */\n\n/**\n * Tool list response interface\n */\ninterface ToolListResponse {\n success: boolean;\n message: string;\n data: {\n records: Tool[];\n total: number;\n };\n}\n\n/**\n * Tool response interface\n */\ninterface ToolResponse {\n success: boolean;\n message: string;\n data?: Tool;\n}\n\n/**\n * Serialize Tool object for JSON response\n * Converts Date objects to ISO strings\n * Explicitly creates a plain object to ensure all fields are serializable\n */\nfunction serializeTool(tool: Tool): any {\n // Explicitly create a plain object with all fields\n // This ensures Fastify can properly serialize the response\n const serialized: any = {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n license: tool.license,\n compatibility: tool.compatibility,\n metadata: tool.metadata || {},\n config: tool.config,\n createdAt: tool.createdAt instanceof Date ? tool.createdAt.toISOString() : (tool.createdAt ? new Date(tool.createdAt).toISOString() : new Date().toISOString()),\n updatedAt: tool.updatedAt instanceof Date ? tool.updatedAt.toISOString() : (tool.updatedAt ? new Date(tool.updatedAt).toISOString() : new Date().toISOString()),\n };\n\n // Remove undefined fields to avoid serialization issues\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) {\n delete serialized[key];\n }\n });\n\n return serialized;\n}\n\n/**\n * Get list of all tools\n */\nexport async function getToolList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.getAllTools();\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully retrieved tool list\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single tool by ID\n */\nexport async function getTool(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<ToolResponse> {\n try {\n const { id } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tool = await toolStore.getToolById(id);\n\n if (!tool) {\n return reply.status(404).send({\n success: false,\n message: \"Tool not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved tool\",\n data: serializeTool(tool),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tool: ${error.message}`,\n });\n }\n}\n\n/**\n * Search tools by metadata\n */\nexport async function searchToolsByMetadata(\n request: FastifyRequest<{\n Querystring: { key: string; value: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { key, value } = request.query;\n\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.searchByMetadata(key, value);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully searched tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter tools by compatibility\n */\nexport async function filterToolsByCompatibility(\n request: FastifyRequest<{\n Querystring: { compatibility: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { compatibility } = request.query;\n\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.filterByCompatibility(compatibility);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully filtered tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter tools by license\n */\nexport async function filterToolsByLicense(\n request: FastifyRequest<{\n Querystring: { license: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { license } = request.query;\n\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.filterByLicense(license);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully filtered tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\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 { 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 isolatedLevel: {\n type: \"string\",\n enum: [\"agent\", \"thread\", \"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","import { getAgentConfig, getAgentLattice, normalizeSandboxName } from \"@axiom-lattice/core\";\nimport { ConnectedSandboxConfig } from \"@axiom-lattice/protocols\";\n\nconst SANDBOX_BASE_URL = process.env.SANDBOX_BASE_URL || \"http://localhost:8080\";\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=\"isolatedLevel\">-</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('isolatedLevel').textContent = params.get('isolatedLevel') || '-';\n document.getElementById('errorMsg').textContent = params.get('error') || '未知错误';\n </script>\n</body>\n</html>`;\n\nexport class SandboxService {\n private baseUrl: string;\n\n constructor(baseUrl?: string) {\n this.baseUrl = baseUrl || SANDBOX_BASE_URL;\n }\n\n getSandboxConfig(assistantId: string): ConnectedSandboxConfig | null {\n const agentConfig = getAgentConfig(assistantId);\n if (!agentConfig) {\n return null;\n }\n\n const agentLattice = getAgentLattice(assistantId);\n return agentLattice?.config?.connectedSandbox || null;\n }\n\n computeSandboxName(\n assistantId: string,\n threadId: string,\n isolatedLevel: string\n ): string {\n let sandboxName: string;\n\n switch (isolatedLevel) {\n case \"agent\":\n sandboxName = assistantId;\n break;\n case \"thread\":\n sandboxName = threadId;\n break;\n case \"global\":\n default:\n sandboxName = \"global\";\n break;\n }\n\n return normalizeSandboxName(sandboxName);\n }\n\n getTargetUrl(sandboxName: string): string {\n return `${this.baseUrl}/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 isolatedLevel: 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(\"{isolatedLevel}\", isolatedLevel)\n .replace(\"{errorMessage}\", errorMessage);\n }\n}\n\nexport const sandboxService = new SandboxService();\n","import { FastifyInstance, FastifyRequest, FastifyReply } from \"fastify\";\n// import { WebSocket, createWebSocketStream } from \"ws\";\nimport { pipeline } from \"stream/promises\";\nimport { sandboxService } from \"../services/sandbox_service\";\nconst SANDBOX_BASE_URL = process.env.SANDBOX_BASE_URL || \"http://localhost:8080\";\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 async function registerSandboxProxyRoutes(app: FastifyInstance): Promise<void> {\n app.get<{ Params: SandboxParams }>(\n \"/api/assistants/:assistantId/threads/:threadId/sandbox\",\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 { isolatedLevel } = sandboxConfig;\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n isolatedLevel\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 isolatedLevel,\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\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 { isolatedLevel } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // isolatedLevel\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/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 { isolatedLevel } = sandboxConfig;\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n isolatedLevel\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","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 {\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} from \"../schemas\";\nimport { registerSandboxProxyRoutes } from \"../controllers/sandbox\";\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 // 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","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 } from \"@axiom-lattice/core\";\nimport { popAgentTaskFromQueue } from \"./queue_service\";\nimport { agent_state } from \"./agent_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}\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 } = taskRequest;\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\n const response = await fetch(apiUrl, {\n method: \"POST\",\n body: JSON.stringify({\n assistant_id,\n streaming: true,\n ...input,\n thread_id,\n command,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-tenant-id\": tenant_id,\n },\n }).catch((err) => {\n console.error(`fetch请求失败: ${err.message || String(err)}`);\n throw new Error(`fetch失败: ${err.message || String(err)}`);\n });\n\n if (!response.ok) {\n throw new Error(`API请求失败: ${response.status} ${response.statusText}`);\n }\n\n // Check if response is SSE stream\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"text/event-stream\")) {\n // Handle SSE stream\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n let buffer = \"\";\n let streamEnded = false;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream has ended\n streamEnded = true;\n console.log(\n `SSE流已结束 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n break;\n }\n\n // // Decode the chunk and process SSE events\n // buffer += decoder.decode(value, { stream: true });\n // const lines = buffer.split(\"\\n\");\n // buffer = lines.pop() || \"\"; // Keep incomplete line in buffer\n\n // for (const line of lines) {\n // if (line.startsWith(\"data: \")) {\n // try {\n // const data = JSON.parse(line.slice(6));\n // // Process SSE event data here if needed\n // // You can emit events or handle the data as required\n // console.log(\"SSE event received:\", data);\n // } catch (e) {\n // // Ignore invalid JSON\n // console.warn(\"Failed to parse SSE data:\", line);\n // }\n // }\n // }\n }\n } catch (streamError) {\n console.error(\"Error reading SSE stream:\", streamError);\n throw streamError;\n } finally {\n reader.releaseLock();\n }\n\n // Stream has ended successfully\n if (callback_event) {\n const state = await agent_state({ assistant_id, thread_id });\n eventBus.publish(callback_event, {\n success: true,\n state: state,\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.log(\n `任务处理成功 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return true;\n } else {\n // Non-streaming response\n await response.text(); // Consume the response\n\n if (callback_event) {\n const state = await agent_state({ assistant_id, thread_id });\n eventBus.publish(callback_event, {\n success: true,\n state,\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.log(\n `任务处理成功 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return true;\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":["message","data","messages","import_core","import_uuid","import_core","import_core","import_crypto","import_core","import_core","import_core","import_core","import_core","import_core","SANDBOX_BASE_URL","app","app","app","swagger","swaggerUi","import_core","import_core","import_protocols","fastify","cors","sensible","websocket"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/services/agent_service.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/controllers/skills.ts","../src/controllers/tools.ts","../src/schemas/index.ts","../src/controllers/sandbox.ts","../src/services/sandbox_service.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 { 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} from \"@axiom-lattice/core\";\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\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\"],\n allowedHeaders: [\n \"Content-Type\",\n \"Authorization\",\n \"X-Requested-With\",\n \"x-tenant-id\",\n \"x-request-id\",\n \"x-assistant-id\",\n \"x-thread-id\",\n ],\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// 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\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 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 // 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 } 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 {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n filterMessages,\n HumanMessage,\n ToolMessage,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Command, CommandParams } from \"@langchain/langgraph\";\nimport { v4 } from \"uuid\";\n// 修改导入路径,使用 lattice_core 包\nimport {\n getAgentClient,\n getAgentLattice,\n InMemoryChunkBuffer,\n registerChunkBuffer,\n getChunkBuffer,\n hasChunkBuffer,\n} from \"@axiom-lattice/core\";\n\n/**\n * Get or create the global ChunkBuffer instance\n */\nfunction getOrCreateChunkBuffer(): InMemoryChunkBuffer {\n if (!hasChunkBuffer(\"default\")) {\n const buffer = new InMemoryChunkBuffer({\n ttl: 60 * 60 * 1000, // 1 hour TTL\n cleanupInterval: 5 * 60 * 1000, // Clean every 5 minutes\n });\n registerChunkBuffer(\"default\", buffer);\n }\n return getChunkBuffer(\"default\") as InMemoryChunkBuffer;\n}\n\nexport async function agent_invoke({\n input,\n thread_id,\n assistant_id,\n tenant_id,\n command,\n run_id,\n}: {\n assistant_id: string;\n input: any;\n thread_id: string;\n tenant_id: string;\n run_id?: string;\n command?: CommandParams<any>;\n}) {\n const agentLattice = getAgentLattice(assistant_id);\n const runnable_agent = agentLattice?.client;\n\n const { message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n\n // Get runConfig from agent config and merge into configurable\n const runConfig = {\n ...agentLattice?.config?.runConfig || {},\n assistant_id,\n sandboxConfig: agentLattice?.config?.connectedSandbox,\n }\n\n const result = await runnable_agent.invoke(\n command\n ? new Command(command)\n : { ...rest, messages, \"x-tenant-id\": tenant_id },\n {\n configurable: {\n thread_id: thread_id,\n run_id: run_id || v4(),\n \"x-tenant-id\": tenant_id,\n \"x-request-id\": run_id,\n \"x-thread-id\": thread_id,\n \"x-assistant-id\": assistant_id,\n runConfig, // Inject runConfig for tools to access\n },\n recursionLimit: 200,\n }\n );\n\n const data = result.messages.map((message: BaseMessage) => {\n const { type, data } = message.toDict();\n return {\n ...data,\n role: type,\n };\n });\n return { messages: data };\n}\n\nexport async function agent_stream({\n input,\n thread_id,\n command,\n tenant_id,\n assistant_id,\n run_id,\n}: {\n assistant_id: string;\n input: any;\n thread_id: string;\n command?: CommandParams<any>;\n tenant_id: string;\n run_id?: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id) as any; // TODO: fix this\n const agentLattice = getAgentLattice(assistant_id);\n const { message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\n\n // Get runConfig from agent config and merge into configurable\n const runConfig = {\n ...agentLattice?.config?.runConfig || {},\n assistant_id,\n sandboxConfig: agentLattice?.config?.connectedSandbox,\n }\n\n try {\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const agentStream = await runnable_agent.stream(\n command\n ? new Command(command)\n : {\n ...rest,\n messages,\n \"x-tenant-id\": tenant_id,\n },\n\n {\n configurable: {\n thread_id: thread_id,\n run_id: run_id || v4(),\n \"x-tenant-id\": tenant_id,\n \"x-request-id\": run_id,\n \"x-thread-id\": thread_id,\n \"x-assistant-id\": assistant_id,\n runConfig, // Inject runConfig for tools to access\n },\n streamMode: [\"updates\", \"messages\"],\n subgraphs: false,\n recursionLimit: 200,\n }\n );\n\n // 创建一个可迭代的 ReadableStream with ChunkBuffer integration\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of agentStream) {\n let data;\n let chunkContent = \"\";\n\n if (chunk[0] === \"updates\") {\n const update = chunk[1];\n const values = Object.values(update);\n const messages = (values[0] as any)?.messages;\n if (messages?.[0]?.tool_call_id) {\n data = messages[0].toDict();\n }\n } else if (chunk[0] === \"messages\") {\n const messages = chunk[1];\n // console.log(messages);\n data = messages?.[0]?.toDict();\n }\n\n if ((chunk?.[1] as any)?.__interrupt__) {\n //data = chunk?.[1]?.[0]?.toDict();\n // 原有的中断消息处理\n data = {\n type: \"interrupt\",\n id: (chunk?.[1] as any)?.__interrupt__[0].id,\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\n if (data.type !== \"interrupt\") {\n await chunkBuffer.addChunk(thread_id, data);\n }\n yield data;\n }\n }\n\n // Mark thread as completed when streaming finishes successfully\n await chunkBuffer.completeThread(thread_id);\n } catch (error) {\n console.error(\"Stream error:\", error);\n // Mark thread as aborted on error\n await chunkBuffer.abortThread(thread_id);\n throw error;\n }\n },\n };\n } catch (error) {\n // Mark thread as aborted on initialization error\n await chunkBuffer.abortThread(thread_id);\n throw error;\n }\n}\n\nexport async function agent_state({\n thread_id,\n assistant_id,\n}: {\n assistant_id: string;\n thread_id: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const state = await runnable_agent.getState({\n configurable: { thread_id: thread_id, subgraphs: false },\n });\n return state;\n}\n\nexport async function agent_messages({\n thread_id,\n tenant_id,\n assistant_id,\n}: {\n assistant_id: string;\n thread_id: string;\n tenant_id: string;\n}) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const state = await runnable_agent.getState({\n configurable: { thread_id: thread_id, subgraphs: false },\n });\n\n const messages = state.values.messages || [];\n const filteredMessages = filterMessages(messages, {\n includeTypes: [\"ai\", \"human\", \"tool\"], //[\"human\", \"ai\", \"tool\"],\n });\n\n // console.log(filteredMessages);\n\n let messagesArray = filteredMessages.map((message: BaseMessage) => ({\n id: message.id,\n role: message.getType(),\n content: message.content,\n ...message.lc_kwargs,\n }));\n\n // const action_messages = state.tasks.flatMap((task) => {\n // return task.interrupts.map((interrupt) => {\n // return {\n // role: \"ai\",\n // content: interrupt.value,\n // type: \"action\",\n // };\n // });\n // });\n\n const new_messages = messagesArray;\n // console.log(messagesArray);\n\n return new_messages;\n}\n\nexport async function draw_graph(assistant_id: string) {\n const runnable_agent = getAgentClient(assistant_id);\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\n }\n const drawableGraph = await runnable_agent.getGraphAsync();\n const image = await drawableGraph.drawMermaid();\n return image;\n}\n\n/**\n * Resume streaming from a known position\n * Creates an async iterator that yields new chunks as they arrive\n *\n * @param thread_id - Thread identifier\n * @param message_id - Message identifier (usually run_id)\n * @param known_content - Content already received (used to find resume position)\n * @param poll_interval - Polling interval in milliseconds (default: 100ms)\n */\nexport async function resume_stream({\n thread_id,\n message_id,\n known_content,\n poll_interval = 100,\n}: {\n thread_id: string;\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}) {\n const chunkBuffer = getOrCreateChunkBuffer();\n\n const stream = await chunkBuffer.getNewChunksSinceContentIterator(\n thread_id,\n message_id,\n known_content\n );\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of stream) {\n yield chunk;\n }\n } catch (error) {\n console.error(\"Resume stream error:\", error);\n throw error;\n }\n },\n };\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { draw_graph } from \"../services/agent_service\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport type {\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { randomUUID } from \"crypto\";\nimport { AgentConfig, getAllAgentConfigs } 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 * Convert AgentConfig to Assistant format\n */\nfunction convertAgentConfigToAssistant(config: AgentConfig): Assistant {\n return {\n id: config.key,\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 // Get code-configured agents\n const agentConfigs = await getAllAgentConfigs();\n const codeConfiguredAssistants = agentConfigs.map(\n convertAgentConfigToAssistant\n );\n\n // Get stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const storedAssistants = await assistantStore.getAllAssistants();\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\n // First check stored assistants\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n let assistant = await assistantStore.getAssistantById(id);\n\n // If not found in store, check code-configured agents\n if (!assistant) {\n const agentConfigs = await getAllAgentConfigs();\n const agentConfig = agentConfigs.find((config) => config.key === 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 * Create a new assistant\n */\nexport async function createAssistant(\n request: FastifyRequest<{ Body: CreateAssistantRequest }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const data = request.body;\n\n // Validate required fields\n if (!data.name) {\n return reply.status(400).send({\n success: false,\n message: \"name is required\",\n });\n }\n\n if (!data.graphDefinition) {\n return reply.status(400).send({\n success: false,\n message: \"graphDefinition is required\",\n });\n }\n\n // Generate ID if not provided\n const id = randomUUID();\n\n // Create assistant\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n const newAssistant = await assistantStore.createAssistant(id, data);\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created assistant\",\n data: newAssistant,\n });\n}\n\n/**\n * Update an existing assistant by ID\n * Only works on stored assistants, not code-configured ones\n */\nexport async function updateAssistant(\n request: FastifyRequest<{\n Params: { id: string };\n Body: AssistantUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<AssistantResponse> {\n const { id } = request.params;\n const updates = request.body;\n\n // Check if it's a code-configured agent\n const agentConfigs = await getAllAgentConfigs();\n const isCodeConfigured = agentConfigs.some((config) => config.key === id);\n\n if (isCodeConfigured) {\n return reply.status(403).send({\n success: false,\n message:\n \"Cannot update code-configured assistant. Only stored assistants can be updated.\",\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n // Check if assistant exists in store\n const exists = await assistantStore.hasAssistant(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n // Update assistant\n const updatedAssistant = await assistantStore.updateAssistant(id, updates);\n\n if (!updatedAssistant) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update assistant\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated assistant\",\n data: updatedAssistant,\n };\n}\n\n/**\n * Delete an assistant by ID\n * Only works on stored assistants, not code-configured ones\n */\nexport async function deleteAssistant(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<{ success: boolean; message: string }> {\n const { id } = request.params;\n\n // Check if it's a code-configured agent\n const agentConfigs = await getAllAgentConfigs();\n const isCodeConfigured = agentConfigs.some((config) => config.key === id);\n\n if (isCodeConfigured) {\n return reply.status(403).send({\n success: false,\n message:\n \"Cannot delete code-configured assistant. Only stored assistants can be deleted.\",\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"assistant\");\n const assistantStore = storeLattice.store;\n\n // Check if assistant exists in store\n const exists = await assistantStore.hasAssistant(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Assistant not found\",\n });\n }\n\n // Delete the assistant\n const deleted = await assistantStore.deleteAssistant(id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete assistant\",\n });\n }\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\n // Call drawing service to get image data\n const imageData = await draw_graph(assistantId);\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 * as agentService from \"../services/agent_service\";\nimport { CreateRunRequest } from \"../types\";\nimport { v4 } from \"uuid\";\n\ninterface ResumeStreamRequest {\n thread_id: string;\n message_id: string;\n known_content: string;\n poll_interval?: number;\n}\n\n// 创建运行\nexport const createRun = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n try {\n const {\n assistant_id,\n thread_id,\n command,\n streaming,\n background,\n ...input\n } = request.body as CreateRunRequest;\n\n const tenant_id = request.headers[\"x-tenant-id\"] as string;\n const x_request_id = (request.headers[\"x-request-id\"] as string) || v4();\n\n // 验证请求数据\n if (!assistant_id) {\n reply.status(400).send({\n success: false,\n error: \"助手ID是必需的\",\n });\n return;\n }\n\n // 如果请求streaming,则agent_stream\n if (streaming) {\n // 开始运行\n const stream = await agentService.agent_stream({\n assistant_id: assistant_id,\n input: input,\n thread_id: thread_id,\n command,\n tenant_id: tenant_id,\n run_id: x_request_id,\n });\n\n // 通知 Fastify 我们将手动处理响应\n reply.hijack();\n\n // 设置 SSE 响应头\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 for await (const chunk of stream) {\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error) {\n console.error(\"Stream processing error:\", error);\n } finally {\n reply.raw.end();\n }\n } else {\n // 后台运行的情况\n const result = await agentService.agent_invoke({\n assistant_id: assistant_id,\n input: input,\n command: command,\n thread_id: thread_id,\n tenant_id: tenant_id,\n run_id: x_request_id,\n });\n reply.status(200).send(result);\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 const { thread_id, message_id, known_content, poll_interval } =\n request.body as ResumeStreamRequest;\n\n // Validate request data\n if (!thread_id || !message_id || known_content === undefined) {\n reply.status(400).send({\n success: false,\n error: \"thread_id, message_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 // Get the stream from agent service\n const stream = await agentService.resume_stream({\n thread_id,\n message_id,\n known_content: known_content,\n poll_interval: poll_interval || 100,\n });\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\n // console.log(\"resume stream raw.write\", chunk);\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n } catch (error) {\n console.error(\"Resume stream processing error:\", error);\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","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { agent_messages, agent_state } from \"../services/agent_service\";\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 result = await agent_messages({\n assistant_id: assistantId,\n thread_id: thread_id,\n tenant_id: tenant_id,\n });\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 result = await agent_state({\n assistant_id: assistantId,\n thread_id: thread_id,\n });\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 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 an assistant ID\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<{ Params: { assistantId: string } }>,\n reply: FastifyReply\n): Promise<ThreadListResponse> {\n const { assistantId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const threads = await threadStore.getThreadsByAssistantId(assistantId);\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 assistant\n */\nexport async function getThread(\n request: FastifyRequest<{\n Params: { assistantId: string; threadId: string };\n }>,\n reply: FastifyReply\n): Promise<ThreadResponse> {\n const { assistantId, threadId } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const thread = await threadStore.getThreadById(assistantId, 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 { assistantId } = request.params;\n const data = request.body;\n\n // Generate thread ID if not provided\n const threadId = randomUUID();\n\n // Create thread\n const storeLattice = getStoreLattice(\"default\", \"thread\");\n const threadStore = storeLattice.store;\n const newThread = await threadStore.createThread(assistantId, threadId, data);\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 { assistantId, 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(assistantId, 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 assistantId,\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 { assistantId, 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(assistantId, 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(assistantId, 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 */\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 filters: {\n threadId: string;\n assistantId?: string;\n status?: ScheduledTaskStatus;\n limit?: number;\n offset?: number;\n } = {\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 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, 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 */\n\ninterface ModelConfig {\n key: string;\n model: 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\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 return {\n key: lattice.key,\n model: config.model || \"\",\n provider: config.provider || \"openai\",\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 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","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice } from \"@axiom-lattice/core\";\nimport { validateSkillName } from \"@axiom-lattice/core\";\nimport type {\n Skill,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Skills Controller\n * Handles skill-related CRUD operations\n */\n\n/**\n * Skill list response interface\n */\ninterface SkillListResponse {\n success: boolean;\n message: string;\n data: {\n records: Skill[];\n total: number;\n };\n}\n\n/**\n * Skill response interface\n */\ninterface SkillResponse {\n success: boolean;\n message: string;\n data?: Skill;\n}\n\n/**\n * Skill update request body interface\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\n/**\n * Serialize Skill object for JSON response\n * Converts Date objects to ISO strings\n * Explicitly creates a plain object to ensure all fields are serializable\n */\nfunction serializeSkill(skill: Skill): any {\n // Explicitly create a plain object with all fields\n // This ensures Fastify can properly serialize the response\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() : (skill.createdAt ? new Date(skill.createdAt).toISOString() : new Date().toISOString()),\n updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : (skill.updatedAt ? new Date(skill.updatedAt).toISOString() : new Date().toISOString()),\n };\n\n // Remove undefined fields to avoid serialization issues\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) {\n delete serialized[key];\n }\n });\n\n return serialized;\n}\n\n/**\n * Get list of all skills\n */\nexport async function getSkillList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.getAllSkills();\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully retrieved skill list\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single skill by ID\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\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skill = await skillStore.getSkillById(id);\n\n if (!skill) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved skill\",\n data: serializeSkill(skill),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Create a new skill\n */\nexport async function createSkill(\n request: FastifyRequest<{ Body: CreateSkillRequest }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const data = request.body;\n\n // Validate required fields\n if (!data.name) {\n return reply.status(400).send({\n success: false,\n message: \"name is required\",\n });\n }\n\n if (!data.description) {\n return reply.status(400).send({\n success: false,\n message: \"description is required\",\n });\n }\n\n // Validate name format\n try {\n validateSkillName(data.name);\n } catch (error: any) {\n return reply.status(400).send({\n success: false,\n message: error.message || \"Invalid skill name format\",\n });\n }\n\n // ID must equal name (name is used for path addressing)\n const id = (request.body as any).id || data.name;\n \n if (id !== data.name) {\n return reply.status(400).send({\n success: false,\n message: `id \"${id}\" must equal name \"${data.name}\" (name is used for path addressing)`,\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill already exists\n const exists = await skillStore.hasSkill(id);\n if (exists) {\n return reply.status(409).send({\n success: false,\n message: `Skill with id \"${id}\" already exists`,\n });\n }\n\n // Create skill\n const newSkill = await skillStore.createSkill(id, data);\n\n return reply.status(201).send({\n success: true,\n message: \"Successfully created skill\",\n data: serializeSkill(newSkill),\n });\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to create skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Update an existing skill by ID\n */\nexport async function updateSkill(\n request: FastifyRequest<{\n Params: { id: string };\n Body: SkillUpdateBody;\n }>,\n reply: FastifyReply\n): Promise<SkillResponse> {\n try {\n const { id } = request.params;\n const updates = request.body;\n\n // Validate name format if name is being updated\n if (updates.name !== undefined) {\n try {\n validateSkillName(updates.name);\n } catch (error: any) {\n return reply.status(400).send({\n success: false,\n message: error.message || \"Invalid skill name format\",\n });\n }\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill exists\n const exists = await skillStore.hasSkill(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n // Update skill\n const updatedSkill = await skillStore.updateSkill(id, updates);\n\n if (!updatedSkill) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to update skill\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully updated skill\",\n data: serializeSkill(updatedSkill),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to update skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Delete a skill by ID\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\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n\n // Check if skill exists\n const exists = await skillStore.hasSkill(id);\n if (!exists) {\n return reply.status(404).send({\n success: false,\n message: \"Skill not found\",\n });\n }\n\n // Delete the skill\n const deleted = await skillStore.deleteSkill(id);\n\n if (!deleted) {\n return reply.status(500).send({\n success: false,\n message: \"Failed to delete skill\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully deleted skill\",\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to delete skill: ${error.message}`,\n });\n }\n}\n\n/**\n * Search skills by metadata\n */\nexport async function searchSkillsByMetadata(\n request: FastifyRequest<{\n Querystring: { key: string; value: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { key, value } = request.query;\n\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.searchByMetadata(key, value);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully searched skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter skills by compatibility\n */\nexport async function filterSkillsByCompatibility(\n request: FastifyRequest<{\n Querystring: { compatibility: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { compatibility } = request.query;\n\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.filterByCompatibility(compatibility);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter skills by license\n */\nexport async function filterSkillsByLicense(\n request: FastifyRequest<{\n Querystring: { license: string };\n }>,\n reply: FastifyReply\n): Promise<SkillListResponse> {\n try {\n const { license } = request.query;\n\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"skill\");\n const skillStore = storeLattice.store;\n const skills = await skillStore.filterByLicense(license);\n\n // Serialize skills to convert Date objects to ISO strings\n const serializedSkills = skills.map(serializeSkill);\n\n return {\n success: true,\n message: \"Successfully filtered skills\",\n data: {\n records: serializedSkills,\n total: serializedSkills.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter skills: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n","import { FastifyRequest, FastifyReply } from \"fastify\";\nimport { getStoreLattice, toolLatticeManager } from \"@axiom-lattice/core\";\nimport type {\n Tool,\n ToolConfig,\n} from \"@axiom-lattice/protocols\";\n\n/**\n * Tools Controller\n * Handles tool-related CRUD operations\n */\n\n/**\n * Tool list response interface\n */\ninterface ToolListResponse {\n success: boolean;\n message: string;\n data: {\n records: Tool[];\n total: number;\n };\n}\n\n/**\n * Tool response interface\n */\ninterface ToolResponse {\n success: boolean;\n message: string;\n data?: Tool;\n}\n\n/**\n * Serialize Tool object for JSON response\n * Converts Date objects to ISO strings\n * Explicitly creates a plain object to ensure all fields are serializable\n */\nfunction serializeTool(tool: Tool): any {\n // Explicitly create a plain object with all fields\n // This ensures Fastify can properly serialize the response\n const serialized: any = {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n license: tool.license,\n compatibility: tool.compatibility,\n metadata: tool.metadata || {},\n config: tool.config,\n createdAt: tool.createdAt instanceof Date ? tool.createdAt.toISOString() : (tool.createdAt ? new Date(tool.createdAt).toISOString() : new Date().toISOString()),\n updatedAt: tool.updatedAt instanceof Date ? tool.updatedAt.toISOString() : (tool.updatedAt ? new Date(tool.updatedAt).toISOString() : new Date().toISOString()),\n };\n\n // Remove undefined fields to avoid serialization issues\n Object.keys(serialized).forEach((key) => {\n if (serialized[key] === undefined) {\n delete serialized[key];\n }\n });\n\n return serialized;\n}\n\n/**\n * Get list of all tools\n */\nexport async function getToolList(\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.getAllTools();\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully retrieved tool list\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Get a single tool by ID\n */\nexport async function getTool(\n request: FastifyRequest<{ Params: { id: string } }>,\n reply: FastifyReply\n): Promise<ToolResponse> {\n try {\n const { id } = request.params;\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tool = await toolStore.getToolById(id);\n\n if (!tool) {\n return reply.status(404).send({\n success: false,\n message: \"Tool not found\",\n });\n }\n\n return {\n success: true,\n message: \"Successfully retrieved tool\",\n data: serializeTool(tool),\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to retrieve tool: ${error.message}`,\n });\n }\n}\n\n/**\n * Search tools by metadata\n */\nexport async function searchToolsByMetadata(\n request: FastifyRequest<{\n Querystring: { key: string; value: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { key, value } = request.query;\n\n if (!key || !value) {\n return reply.status(400).send({\n success: false,\n message: \"key and value query parameters are required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.searchByMetadata(key, value);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully searched tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to search tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter tools by compatibility\n */\nexport async function filterToolsByCompatibility(\n request: FastifyRequest<{\n Querystring: { compatibility: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { compatibility } = request.query;\n\n if (!compatibility) {\n return reply.status(400).send({\n success: false,\n message: \"compatibility query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.filterByCompatibility(compatibility);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully filtered tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\n}\n\n/**\n * Filter tools by license\n */\nexport async function filterToolsByLicense(\n request: FastifyRequest<{\n Querystring: { license: string };\n }>,\n reply: FastifyReply\n): Promise<ToolListResponse> {\n try {\n const { license } = request.query;\n\n if (!license) {\n return reply.status(400).send({\n success: false,\n message: \"license query parameter is required\",\n data: {\n records: [],\n total: 0,\n },\n });\n }\n\n const storeLattice = getStoreLattice(\"default\", \"tool\");\n const toolStore = storeLattice.store;\n const tools = await toolStore.filterByLicense(license);\n\n // Serialize tools to convert Date objects to ISO strings\n const serializedTools = tools.map(serializeTool);\n\n return {\n success: true,\n message: \"Successfully filtered tools\",\n data: {\n records: serializedTools,\n total: serializedTools.length,\n },\n };\n } catch (error: any) {\n return reply.status(500).send({\n success: false,\n message: `Failed to filter tools: ${error.message}`,\n data: {\n records: [],\n total: 0,\n },\n });\n }\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 { 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 isolatedLevel: {\n type: \"string\",\n enum: [\"agent\", \"thread\", \"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","import { Readable } from \"stream\";\nimport { 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\n const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n if (!sandboxConfig) {\n return reply.status(500).send({ error: \"Assistant sandbox config not found\" });\n }\n\n const { isolatedLevel } = sandboxConfig;\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n isolatedLevel\n );\n\n const sandboxManager = getSandBoxManager(\"default\")\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 formData = new FormData();\n formData.append(\"file\", new Blob([buffer]), data.filename ?? \"file\");\n\n const path = `/home/gem/uploads/${pathValue ? pathValue : \"\"}${data.filename}`;\n const uploadResult = await sandbox.file.uploadFile({\n file: buffer,\n path: path,\n })\n\n if (!uploadResult.ok) {\n return reply.status(502).send({ error: `Upload error: ${uploadResult.error}` });\n }\n\n const relativePath = uploadResult.body?.data?.file_path.replace(`/home/gem`, \"\");\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\n if (!filePath || typeof filePath !== \"string\") {\n return reply.status(400).send({ error: \"Query parameter 'path' is required\" });\n }\n\n const sandboxConfig = sandboxService.getSandboxConfig(assistantId);\n if (!sandboxConfig) {\n return reply.status(404).send({ error: \"Assistant sandbox config not found\" });\n }\n\n const { isolatedLevel } = sandboxConfig;\n const sandboxName = sandboxService.computeSandboxName(\n assistantId,\n threadId,\n isolatedLevel\n );\n\n const sandboxManager = getSandBoxManager(\"default\");\n const sandbox = await sandboxManager.createSandbox(sandboxName);\n\n try {\n // Resolve path: if relative (no leading /), prefix with /home/gem\n const resolvedPath = filePath.startsWith(\"/home/gem\") ? filePath : `/home/gem/${filePath.replace(/^\\//, \"\")}`;\n const filename = getFilenameFromPath(resolvedPath);\n const inferredContentType = getContentTypeFromFilename(filename);\n\n const downloadResult = await sandbox.file.downloadFile({\n path: resolvedPath,\n });\n\n if (!downloadResult.ok) {\n return reply.status(502).send({\n error: `Download error: ${JSON.stringify(downloadResult.error)}`,\n });\n }\n\n // Use body.stream() to get ReadableStream and pipe directly (no buffering)\n const body = downloadResult.body as unknown as {\n stream?: () => ReadableStream<Uint8Array>;\n contentType?: string;\n contentDisposition?: string;\n };\n if (typeof body?.stream === \"function\") {\n const webStream = body.stream();\n const nodeStream = Readable.fromWeb(webStream);\n const contentType = body.contentType ?? inferredContentType;\n const contentDisposition =\n body.contentDisposition ?? `inline; filename=\"${filename.replace(/\"/g, '\\\\\"')}\"; filename*=UTF-8''${encodeURIComponent(filename)}`;\n reply = reply.status(200).type(contentType).header(\"Content-Disposition\", contentDisposition).send(nodeStream);\n return reply;\n }\n\n // Fallback: buffer body when stream is not available\n const bodyUnknown = downloadResult.body as unknown;\n let buf: Buffer;\n let contentType = inferredContentType;\n let contentDisposition = `inline; filename=\"${filename.replace(/\"/g, '\\\\\"')}\"; filename*=UTF-8''${encodeURIComponent(filename)}`;\n\n if (bodyUnknown instanceof ArrayBuffer) {\n buf = Buffer.from(bodyUnknown);\n } else if (bodyUnknown instanceof Buffer) {\n buf = bodyUnknown;\n } else if (\n bodyUnknown &&\n typeof (bodyUnknown as { arrayBuffer?: () => Promise<ArrayBuffer> }).arrayBuffer === \"function\"\n ) {\n const res = bodyUnknown as { arrayBuffer: () => Promise<ArrayBuffer>; headers?: Headers };\n buf = Buffer.from(await res.arrayBuffer());\n if (res.headers?.get(\"content-type\")) contentType = res.headers.get(\"content-type\")!;\n if (res.headers?.get(\"content-disposition\")) contentDisposition = res.headers.get(\"content-disposition\")!;\n } else if (bodyUnknown && typeof (bodyUnknown as { blob?: () => Promise<Blob> }).blob === \"function\") {\n const blob = await (bodyUnknown as { blob: () => Promise<Blob> }).blob();\n buf = Buffer.from(await blob.arrayBuffer());\n } else {\n return reply.status(502).send({ error: \"Unexpected download response format\" });\n }\n\n reply = reply.status(200).type(contentType).header(\"Content-Disposition\", contentDisposition).send(buf);\n return reply;\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 { isolatedLevel } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // isolatedLevel\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 // isolatedLevel,\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 { isolatedLevel } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // isolatedLevel\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 { isolatedLevel } = sandboxConfig;\n // const sandboxName = sandboxService.computeSandboxName(\n // assistantId,\n // threadId,\n // isolatedLevel\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","import { getAgentConfig, getAgentLattice, getSandBoxManager, normalizeSandboxName, sandboxLatticeManager } from \"@axiom-lattice/core\";\nimport { ConnectedSandboxConfig } 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=\"isolatedLevel\">-</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('isolatedLevel').textContent = params.get('isolatedLevel') || '-';\n document.getElementById('errorMsg').textContent = params.get('error') || '未知错误';\n </script>\n</body>\n</html>`;\n\nexport class SandboxService {\n\n getSandboxConfig(assistantId: string): ConnectedSandboxConfig | null {\n const agentConfig = getAgentConfig(assistantId);\n if (!agentConfig) {\n return null;\n }\n\n const agentLattice = getAgentLattice(assistantId);\n return agentLattice?.config?.connectedSandbox || null;\n }\n\n computeSandboxName(\n assistantId: string,\n threadId: string,\n isolatedLevel: string\n ): string {\n let sandboxName: string;\n\n switch (isolatedLevel) {\n case \"agent\":\n sandboxName = assistantId;\n break;\n case \"thread\":\n sandboxName = threadId;\n break;\n case \"global\":\n default:\n sandboxName = \"global\";\n break;\n }\n\n return normalizeSandboxName(sandboxName);\n }\n\n getTargetUrl(sandboxName: string): string {\n const sandboxManager = getSandBoxManager(\"default\")\n return `${sandboxManager.getBaseURL()}/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 isolatedLevel: 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(\"{isolatedLevel}\", isolatedLevel)\n .replace(\"{errorMessage}\", errorMessage);\n }\n}\n\nexport const sandboxService = new SandboxService();\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 {\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} from \"../schemas\";\nimport { registerSandboxProxyRoutes } from \"../controllers/sandbox\";\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 // 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","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 } from \"@axiom-lattice/core\";\nimport { popAgentTaskFromQueue } from \"./queue_service\";\nimport { agent_state } from \"./agent_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}\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 } = taskRequest;\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\n const response = await fetch(apiUrl, {\n method: \"POST\",\n body: JSON.stringify({\n assistant_id,\n streaming: true,\n ...input,\n thread_id,\n command,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-tenant-id\": tenant_id,\n },\n }).catch((err) => {\n console.error(`fetch请求失败: ${err.message || String(err)}`);\n throw new Error(`fetch失败: ${err.message || String(err)}`);\n });\n\n if (!response.ok) {\n throw new Error(`API请求失败: ${response.status} ${response.statusText}`);\n }\n\n // Check if response is SSE stream\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"text/event-stream\")) {\n // Handle SSE stream\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n\n if (!reader) {\n throw new Error(\"Response body is not readable\");\n }\n\n let buffer = \"\";\n let streamEnded = false;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream has ended\n streamEnded = true;\n console.log(\n `SSE流已结束 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n break;\n }\n\n // // Decode the chunk and process SSE events\n // buffer += decoder.decode(value, { stream: true });\n // const lines = buffer.split(\"\\n\");\n // buffer = lines.pop() || \"\"; // Keep incomplete line in buffer\n\n // for (const line of lines) {\n // if (line.startsWith(\"data: \")) {\n // try {\n // const data = JSON.parse(line.slice(6));\n // // Process SSE event data here if needed\n // // You can emit events or handle the data as required\n // console.log(\"SSE event received:\", data);\n // } catch (e) {\n // // Ignore invalid JSON\n // console.warn(\"Failed to parse SSE data:\", line);\n // }\n // }\n // }\n }\n } catch (streamError) {\n console.error(\"Error reading SSE stream:\", streamError);\n throw streamError;\n } finally {\n reader.releaseLock();\n }\n\n // Stream has ended successfully\n if (callback_event) {\n const state = await agent_state({ assistant_id, thread_id });\n eventBus.publish(callback_event, {\n success: true,\n state: state,\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.log(\n `任务处理成功 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return true;\n } else {\n // Non-streaming response\n await response.text(); // Consume the response\n\n if (callback_event) {\n const state = await agent_state({ assistant_id, thread_id });\n eventBus.publish(callback_event, {\n success: true,\n state,\n config: { assistant_id, thread_id, tenant_id },\n });\n }\n\n console.log(\n `任务处理成功 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`\n );\n return true;\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":["message","data","messages","import_core","import_uuid","import_core","import_core","import_crypto","import_core","import_core","import_core","import_core","import_core","import_core","import_core","app","contentType","contentDisposition","app","app","swagger","swaggerUi","import_core","import_core","import_protocols","fastify","cors","sensible","multipart","websocket"]}