@axiom-lattice/gateway 1.0.50 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/gateway@1.0.13 build /home/runner/work/agentic/agentic/packages/gateway
2
+ > @axiom-lattice/gateway@2.0.0 build /home/runner/work/agentic/agentic/packages/gateway
3
3
  > tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,13 +9,13 @@
9
9
  CLI Cleaning output folder
10
10
  CJS Build start
11
11
  ESM Build start
12
- CJS dist/index.js 26.50 KB
13
- CJS dist/index.js.map 56.67 KB
14
- CJS ⚡️ Build success in 114ms
15
- ESM dist/index.mjs 24.41 KB
16
- ESM dist/index.mjs.map 56.59 KB
17
- ESM ⚡️ Build success in 116ms
12
+ ESM dist/index.mjs 23.98 KB
13
+ ESM dist/index.mjs.map 51.37 KB
14
+ ESM ⚡️ Build success in 87ms
15
+ CJS dist/index.js 26.07 KB
16
+ CJS dist/index.js.map 51.45 KB
17
+ CJS ⚡️ Build success in 88ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 6501ms
19
+ DTS ⚡️ Build success in 6652ms
20
20
  DTS dist/index.d.ts 1.97 KB
21
21
  DTS dist/index.d.mts 1.97 KB
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @axiom-lattice/gateway
2
+
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - dbfac55: streaming 断开续传
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [dbfac55]
12
+ - @axiom-lattice/protocols@2.0.0
13
+ - @axiom-lattice/core@2.0.0
@@ -323,3 +323,4 @@ await resume_stream({
323
323
 
324
324
 
325
325
 
326
+
package/dist/index.js CHANGED
@@ -231,18 +231,31 @@ async function draw_graph(assistant_id) {
231
231
  const image = await drawableGraph.drawMermaid();
232
232
  return image;
233
233
  }
234
- async function* resume_stream({
234
+ async function resume_stream({
235
235
  thread_id,
236
236
  message_id,
237
237
  known_content,
238
238
  poll_interval = 100
239
239
  }) {
240
240
  const chunkBuffer = getOrCreateChunkBuffer();
241
- return chunkBuffer.getNewChunksSinceContent(
241
+ const stream = await chunkBuffer.getNewChunksSinceContentIterator(
242
242
  thread_id,
243
243
  message_id,
244
244
  known_content
245
245
  );
246
+ return {
247
+ [Symbol.asyncIterator]: async function* () {
248
+ try {
249
+ for await (const chunk of stream) {
250
+ console.log(chunk.data?.content);
251
+ yield chunk;
252
+ }
253
+ } catch (error) {
254
+ console.error("Resume stream error:", error);
255
+ throw error;
256
+ }
257
+ }
258
+ };
246
259
  }
247
260
 
248
261
  // src/controllers/run.ts
@@ -275,6 +288,7 @@ var createRun = async (request, reply) => {
275
288
  tenant_id,
276
289
  run_id: x_request_id
277
290
  });
291
+ reply.hijack();
278
292
  reply.raw.writeHead(200, {
279
293
  "Content-Type": "text/event-stream",
280
294
  "Cache-Control": "no-cache",
@@ -291,7 +305,6 @@ var createRun = async (request, reply) => {
291
305
  console.error("Stream processing error:", error);
292
306
  } finally {
293
307
  reply.raw.end();
294
- return reply.hijack();
295
308
  }
296
309
  } else {
297
310
  const result = await agent_invoke({
@@ -321,12 +334,7 @@ var resumeStream = async (request, reply) => {
321
334
  });
322
335
  return;
323
336
  }
324
- const stream = await resume_stream({
325
- thread_id,
326
- message_id,
327
- known_content,
328
- poll_interval: poll_interval || 100
329
- });
337
+ reply.hijack();
330
338
  reply.raw.writeHead(200, {
331
339
  "Content-Type": "text/event-stream",
332
340
  "Cache-Control": "no-cache",
@@ -334,6 +342,12 @@ var resumeStream = async (request, reply) => {
334
342
  "Access-Control-Allow-Origin": "*"
335
343
  });
336
344
  try {
345
+ const stream = await resume_stream({
346
+ thread_id,
347
+ message_id,
348
+ known_content: "",
349
+ poll_interval: poll_interval || 100
350
+ });
337
351
  for await (const chunk of stream) {
338
352
  reply.raw.write(`data: ${JSON.stringify(chunk)}
339
353
 
@@ -343,7 +357,6 @@ var resumeStream = async (request, reply) => {
343
357
  console.error("Resume stream processing error:", error);
344
358
  } finally {
345
359
  reply.raw.end();
346
- return reply.hijack();
347
360
  }
348
361
  } catch (error) {
349
362
  reply.status(500).send({
@@ -645,46 +658,11 @@ var getAgentGraphSchema = {
645
658
  200: {}
646
659
  }
647
660
  };
648
- var resumeStreamSchema = {
649
- description: "Resume streaming from a known position",
650
- tags: ["Streaming"],
651
- summary: "Resume Stream",
652
- body: {
653
- type: "object",
654
- properties: {
655
- thread_id: { type: "string", description: "Thread ID" },
656
- message_id: {
657
- type: "string",
658
- description: "Message ID (usually run_id)"
659
- },
660
- known_content: {
661
- type: "string",
662
- description: "Content already received"
663
- },
664
- poll_interval: {
665
- type: "number",
666
- description: "Polling interval in milliseconds",
667
- nullable: true,
668
- default: 100
669
- }
670
- },
671
- required: ["thread_id", "message_id"]
672
- },
673
- response: {
674
- 200: {},
675
- 400: {},
676
- 500: {}
677
- }
678
- };
679
661
 
680
662
  // src/routes/index.ts
681
663
  var registerLatticeRoutes = (app2) => {
682
664
  app2.post("/api/runs", createRun);
683
- app2.post(
684
- "/api/resume_stream",
685
- { schema: resumeStreamSchema },
686
- resumeStream
687
- );
665
+ app2.post("/api/resume_stream", resumeStream);
688
666
  app2.get(
689
667
  "/api/assistants/:assistantId/:thread_id/memory",
690
668
  { schema: getAllMemoryItemsSchema },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/services/agent_service.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/assistant.ts","../src/schemas/index.ts","../src/routes/index.ts","../src/logger/Logger.ts","../src/swagger.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport sensible from \"@fastify/sensible\";\nimport { registerLatticeRoutes } from \"./routes\";\n// 导入自定义 Logger 类\nimport { Logger } from \"./logger/Logger\";\nimport { configureSwagger } from \"./swagger\";\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// 创建自定义日志记录器\nconst logger = new Logger({\n serviceName: \"lattice-gateway\",\n name: \"fastify-server\",\n});\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n});\n\n// 添加自定义日志记录\napp.addHook(\"onRequest\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\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);\n\n// 错误处理\napp.setErrorHandler((error, request, reply) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": 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// 将日志记录器添加到应用实例中,以便在路由中使用\napp.decorate(\"logger\", logger);\n\n// 启动服务器\nconst start = async ({ port }: { port: number }) => {\n try {\n const target_port = port || Number(process.env.PORT) || 4001;\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${port}`);\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};\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\nfunction isAIMessageChunk(msg: any): msg is AIMessageChunk {\n return msg && msg.constructor.name === \"AIMessageChunk\";\n}\nfunction isToolMessageChunk(msg: any): msg is ToolMessageChunk {\n return msg && msg.constructor.name === \"ToolMessageChunk\";\n}\nfunction isAIMessage(msg: any): msg is AIMessage {\n return msg && msg.constructor.name === \"AIMessage\";\n}\nfunction isToolMessage(msg: any): msg is ToolMessage {\n return msg && msg.constructor.name === \"ToolMessage\";\n}\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 runnable_agent = getAgentClient(assistant_id);\n const { files, message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n humanMessage.additional_kwargs = { files: files };\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\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 },\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);\n const { files, message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n humanMessage.additional_kwargs = { files: files };\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\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 },\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].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: \"ai\",\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\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 files: message.additional_kwargs.files,\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, ...action_messages];\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 * Get accumulated content for a thread from ChunkBuffer\n */\nexport async function get_accumulated_content(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n return await chunkBuffer.getAccumulatedContent(thread_id);\n}\n\n/**\n * Get thread status and metadata from ChunkBuffer\n */\nexport async function get_thread_status(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n const threadBuffer = await chunkBuffer.getThreadBuffer(thread_id);\n return {\n exists: !!threadBuffer,\n status: threadBuffer?.status,\n chunkCount: threadBuffer?.chunks.length || 0,\n createdAt: threadBuffer?.createdAt,\n updatedAt: threadBuffer?.updatedAt,\n };\n}\n\n/**\n * Get all active streaming threads\n */\nexport async function get_active_threads() {\n const chunkBuffer = getOrCreateChunkBuffer();\n return await chunkBuffer.getActiveThreads();\n}\n\n/**\n * Get ChunkBuffer statistics\n */\nexport async function get_buffer_stats() {\n const chunkBuffer = getOrCreateChunkBuffer();\n return chunkBuffer.getStats();\n}\n\n/**\n * Clear specific thread buffer\n */\nexport async function clear_thread_buffer(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n await chunkBuffer.clearThread(thread_id);\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 return chunkBuffer.getNewChunksSinceContent(\n thread_id,\n message_id,\n known_content\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 // 设置 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 // 通知 Fastify 我们将手动处理响应\n return reply.hijack();\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 // Get the stream from agent service\n const stream = await agentService.resume_stream({\n thread_id,\n message_id,\n known_content,\n poll_interval: poll_interval || 100,\n });\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 // Stream the chunks to the client\n for await (const chunk of stream) {\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 // Notify Fastify that we will manually handle the response\n return reply.hijack();\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Error resuming stream: ${error.message}`,\n });\n }\n};\n\n// // 获取运行\n// export const getRun = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { id } = request.params as { id: string };\n\n// if (!id) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await runModel.getRun(id);\n\n// if (!result.success) {\n// reply.status(404).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// // 获取助手的所有运行\n// export const getRunsByAssistant = 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// const result = await runModel.getRunsByAssistant(assistantId);\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// // 取消运行\n// export const cancelRun = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { id } = request.params as { id: string };\n\n// if (!id) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await runModel.updateRunStatus(id, RunStatus.CANCELLED);\n\n// if (!result.success) {\n// reply.status(404).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// // 添加消息\n// export const addMessage = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const data = request.body as AddMessageRequest;\n\n// // 验证请求数据\n// if (!data.runId || !data.role || !data.content) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID、角色和内容是必需的\",\n// });\n// return;\n// }\n\n// const result = await messageModel.addMessage(data);\n\n// if (!result.success) {\n// reply.status(500).send(result);\n// return;\n// }\n\n// reply.status(201).send(result);\n// } catch (error: any) {\n// reply.status(500).send({\n// success: false,\n// error: `添加消息时发生错误: ${error.message}`,\n// });\n// }\n// };\n\n// // 获取运行的所有消息\n// export const getMessages = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { runId } = request.params as { runId: string };\n\n// if (!runId) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await messageModel.getMessagesByRun(runId);\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","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 { draw_graph } from \"../services/agent_service\";\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 // 调用绘图服务获取图片数据\n const imageData = await draw_graph(assistantId);\n\n // 设置响应头并返回图片数据\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 || \"获取代理图表失败\",\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","import { FastifyInstance } from \"fastify\";\n//import * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n} from \"../schemas\";\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 }>(\n \"/api/resume_stream\",\n { schema: resumeStreamSchema },\n runController.resumeStream\n );\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 // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n};\n","import pino from \"pino\";\nimport \"pino-pretty\";\nimport \"pino-roll\";\nimport { AsyncLocalStorage } from \"async_hooks\";\n\nexport interface LoggerContext {\n \"x-user-id\"?: string;\n \"x-tenant-id\"?: string;\n \"x-request-id\"?: string;\n \"x-task-id\"?: string;\n \"x-thread-id\"?: string;\n}\n\nexport interface LoggerOptions {\n name?: string;\n serviceName?: string;\n context?: LoggerContext;\n}\n\n/**\n * 单例的Pino日志工厂类,管理底层pino实例\n */\nclass PinoLoggerFactory {\n private static instance: PinoLoggerFactory;\n private pinoLogger: pino.Logger;\n\n private constructor() {\n const isProd = process.env.NODE_ENV === \"production\";\n\n const loggerConfig: pino.LoggerOptions = {\n // 自定义时间戳格式\n timestamp: () => `,\"@timestamp\":\"${new Date().toISOString()}\"`,\n\n // 关闭默认的时间戳键\n base: {\n \"@version\": \"1\",\n app_name: \"lattice\",\n service_name: \"lattice/graph-server\",\n thread_name: \"main\",\n logger_name: \"lattice-graph-logger\",\n },\n\n formatters: {\n level: (label, number) => {\n return {\n level: label.toUpperCase(),\n level_value: number * 1000,\n };\n },\n },\n };\n\n // 生产环境使用文件日志\n if (isProd) {\n try {\n this.pinoLogger = pino(\n loggerConfig,\n pino.transport({\n target: \"pino-roll\",\n options: {\n file: \"./logs/fin_ai_graph_server\",\n frequency: \"daily\",\n mkdir: true,\n },\n })\n );\n } catch (error) {\n console.error(\n \"无法初始化 pino-roll 日志记录器,回退到控制台日志\",\n error\n );\n // 回退到开发环境的配置\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n } else {\n // 开发环境使用格式化输出\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n }\n\n public static getInstance(): PinoLoggerFactory {\n if (!PinoLoggerFactory.instance) {\n PinoLoggerFactory.instance = new PinoLoggerFactory();\n }\n return PinoLoggerFactory.instance;\n }\n\n public getPinoLogger(): pino.Logger {\n return this.pinoLogger;\n }\n}\n\n/**\n * Logger类,可以创建多个实例,每个实例有自己的上下文\n */\nexport class Logger {\n private context: LoggerContext;\n private name: string;\n private serviceName: string;\n\n constructor(options?: LoggerOptions) {\n this.context = options?.context || {};\n this.name = options?.name || \"lattice-graph-logger\";\n this.serviceName = options?.serviceName || \"lattice/graph-server\";\n }\n\n /**\n * 获取合并了上下文的日志对象\n * @param additionalContext 额外的上下文数据\n * @returns 带有上下文的pino日志对象\n */\n private getContextualLogger(additionalContext?: object): pino.Logger {\n const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();\n\n // 合并Logger实例的上下文和额外上下文\n const contextObj = {\n \"x-user-id\": this.context[\"x-user-id\"] || \"\",\n \"x-tenant-id\": this.context[\"x-tenant-id\"] || \"\",\n \"x-request-id\": this.context[\"x-request-id\"] || \"\",\n \"x-task-id\": this.context[\"x-task-id\"] || \"\",\n \"x-thread-id\": this.context[\"x-thread-id\"] || \"\",\n service_name: this.serviceName,\n logger_name: this.name,\n ...additionalContext,\n };\n\n // 创建带有上下文的子日志记录器\n return pinoLogger.child(contextObj);\n }\n\n info(msg: string, obj?: object): void {\n this.getContextualLogger(obj).info(msg);\n }\n\n error(msg: string, obj?: object | Error): void {\n this.getContextualLogger(obj).error(msg);\n }\n\n warn(msg: string, obj?: object): void {\n this.getContextualLogger(obj).warn(msg);\n }\n\n debug(msg: string, obj?: object): void {\n this.getContextualLogger(obj).debug(msg);\n }\n\n /**\n * 更新Logger实例的上下文\n */\n updateContext(context: Partial<LoggerContext>): void {\n this.context = {\n ...this.context,\n ...context,\n };\n }\n\n /**\n * 创建一个新的Logger实例,继承当前Logger的上下文\n */\n child(options: Partial<LoggerOptions>): Logger {\n return new Logger({\n name: options.name || this.name,\n serviceName: options.serviceName || this.serviceName,\n context: {\n ...this.context,\n ...options.context,\n },\n });\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n"],"mappings":"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","names":["message","data","messages","import_uuid","app","pino","app","swagger","swaggerUi","fastify","cors","sensible"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/services/agent_service.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/assistant.ts","../src/schemas/index.ts","../src/routes/index.ts","../src/logger/Logger.ts","../src/swagger.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport sensible from \"@fastify/sensible\";\nimport { registerLatticeRoutes } from \"./routes\";\n// 导入自定义 Logger 类\nimport { Logger } from \"./logger/Logger\";\nimport { configureSwagger } from \"./swagger\";\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// 创建自定义日志记录器\nconst logger = new Logger({\n serviceName: \"lattice-gateway\",\n name: \"fastify-server\",\n});\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n});\n\n// 添加自定义日志记录\napp.addHook(\"onRequest\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\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);\n\n// 错误处理\napp.setErrorHandler((error, request, reply) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": 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// 将日志记录器添加到应用实例中,以便在路由中使用\napp.decorate(\"logger\", logger);\n\n// 启动服务器\nconst start = async ({ port }: { port: number }) => {\n try {\n const target_port = port || Number(process.env.PORT) || 4001;\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${port}`);\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};\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 runnable_agent = getAgentClient(assistant_id);\n const { files, message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n humanMessage.additional_kwargs = { files: files };\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\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 },\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);\n const { files, message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n humanMessage.additional_kwargs = { files: files };\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\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 },\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].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: \"ai\",\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\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 files: message.additional_kwargs.files,\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, ...action_messages];\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 console.log(chunk.data?.content);\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 * 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: \"\",\n poll_interval: poll_interval || 100,\n });\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\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 { draw_graph } from \"../services/agent_service\";\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 // 调用绘图服务获取图片数据\n const imageData = await draw_graph(assistantId);\n\n // 设置响应头并返回图片数据\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 || \"获取代理图表失败\",\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","import { FastifyInstance } from \"fastify\";\n//import * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n} from \"../schemas\";\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 // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n};\n","import pino from \"pino\";\nimport \"pino-pretty\";\nimport \"pino-roll\";\nimport { AsyncLocalStorage } from \"async_hooks\";\n\nexport interface LoggerContext {\n \"x-user-id\"?: string;\n \"x-tenant-id\"?: string;\n \"x-request-id\"?: string;\n \"x-task-id\"?: string;\n \"x-thread-id\"?: string;\n}\n\nexport interface LoggerOptions {\n name?: string;\n serviceName?: string;\n context?: LoggerContext;\n}\n\n/**\n * 单例的Pino日志工厂类,管理底层pino实例\n */\nclass PinoLoggerFactory {\n private static instance: PinoLoggerFactory;\n private pinoLogger: pino.Logger;\n\n private constructor() {\n const isProd = process.env.NODE_ENV === \"production\";\n\n const loggerConfig: pino.LoggerOptions = {\n // 自定义时间戳格式\n timestamp: () => `,\"@timestamp\":\"${new Date().toISOString()}\"`,\n\n // 关闭默认的时间戳键\n base: {\n \"@version\": \"1\",\n app_name: \"lattice\",\n service_name: \"lattice/graph-server\",\n thread_name: \"main\",\n logger_name: \"lattice-graph-logger\",\n },\n\n formatters: {\n level: (label, number) => {\n return {\n level: label.toUpperCase(),\n level_value: number * 1000,\n };\n },\n },\n };\n\n // 生产环境使用文件日志\n if (isProd) {\n try {\n this.pinoLogger = pino(\n loggerConfig,\n pino.transport({\n target: \"pino-roll\",\n options: {\n file: \"./logs/fin_ai_graph_server\",\n frequency: \"daily\",\n mkdir: true,\n },\n })\n );\n } catch (error) {\n console.error(\n \"无法初始化 pino-roll 日志记录器,回退到控制台日志\",\n error\n );\n // 回退到开发环境的配置\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n } else {\n // 开发环境使用格式化输出\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n }\n\n public static getInstance(): PinoLoggerFactory {\n if (!PinoLoggerFactory.instance) {\n PinoLoggerFactory.instance = new PinoLoggerFactory();\n }\n return PinoLoggerFactory.instance;\n }\n\n public getPinoLogger(): pino.Logger {\n return this.pinoLogger;\n }\n}\n\n/**\n * Logger类,可以创建多个实例,每个实例有自己的上下文\n */\nexport class Logger {\n private context: LoggerContext;\n private name: string;\n private serviceName: string;\n\n constructor(options?: LoggerOptions) {\n this.context = options?.context || {};\n this.name = options?.name || \"lattice-graph-logger\";\n this.serviceName = options?.serviceName || \"lattice/graph-server\";\n }\n\n /**\n * 获取合并了上下文的日志对象\n * @param additionalContext 额外的上下文数据\n * @returns 带有上下文的pino日志对象\n */\n private getContextualLogger(additionalContext?: object): pino.Logger {\n const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();\n\n // 合并Logger实例的上下文和额外上下文\n const contextObj = {\n \"x-user-id\": this.context[\"x-user-id\"] || \"\",\n \"x-tenant-id\": this.context[\"x-tenant-id\"] || \"\",\n \"x-request-id\": this.context[\"x-request-id\"] || \"\",\n \"x-task-id\": this.context[\"x-task-id\"] || \"\",\n \"x-thread-id\": this.context[\"x-thread-id\"] || \"\",\n service_name: this.serviceName,\n logger_name: this.name,\n ...additionalContext,\n };\n\n // 创建带有上下文的子日志记录器\n return pinoLogger.child(contextObj);\n }\n\n info(msg: string, obj?: object): void {\n this.getContextualLogger(obj).info(msg);\n }\n\n error(msg: string, obj?: object | Error): void {\n this.getContextualLogger(obj).error(msg);\n }\n\n warn(msg: string, obj?: object): void {\n this.getContextualLogger(obj).warn(msg);\n }\n\n debug(msg: string, obj?: object): void {\n this.getContextualLogger(obj).debug(msg);\n }\n\n /**\n * 更新Logger实例的上下文\n */\n updateContext(context: Partial<LoggerContext>): void {\n this.context = {\n ...this.context,\n ...context,\n };\n }\n\n /**\n * 创建一个新的Logger实例,继承当前Logger的上下文\n */\n child(options: Partial<LoggerOptions>): Logger {\n return new Logger({\n name: options.name || this.name,\n serviceName: options.serviceName || this.serviceName,\n context: {\n ...this.context,\n ...options.context,\n },\n });\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n"],"mappings":"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","names":["message","data","messages","import_uuid","app","pino","app","swagger","swaggerUi","fastify","cors","sensible"]}
package/dist/index.mjs CHANGED
@@ -206,18 +206,31 @@ async function draw_graph(assistant_id) {
206
206
  const image = await drawableGraph.drawMermaid();
207
207
  return image;
208
208
  }
209
- async function* resume_stream({
209
+ async function resume_stream({
210
210
  thread_id,
211
211
  message_id,
212
212
  known_content,
213
213
  poll_interval = 100
214
214
  }) {
215
215
  const chunkBuffer = getOrCreateChunkBuffer();
216
- return chunkBuffer.getNewChunksSinceContent(
216
+ const stream = await chunkBuffer.getNewChunksSinceContentIterator(
217
217
  thread_id,
218
218
  message_id,
219
219
  known_content
220
220
  );
221
+ return {
222
+ [Symbol.asyncIterator]: async function* () {
223
+ try {
224
+ for await (const chunk of stream) {
225
+ console.log(chunk.data?.content);
226
+ yield chunk;
227
+ }
228
+ } catch (error) {
229
+ console.error("Resume stream error:", error);
230
+ throw error;
231
+ }
232
+ }
233
+ };
221
234
  }
222
235
 
223
236
  // src/controllers/run.ts
@@ -250,6 +263,7 @@ var createRun = async (request, reply) => {
250
263
  tenant_id,
251
264
  run_id: x_request_id
252
265
  });
266
+ reply.hijack();
253
267
  reply.raw.writeHead(200, {
254
268
  "Content-Type": "text/event-stream",
255
269
  "Cache-Control": "no-cache",
@@ -266,7 +280,6 @@ var createRun = async (request, reply) => {
266
280
  console.error("Stream processing error:", error);
267
281
  } finally {
268
282
  reply.raw.end();
269
- return reply.hijack();
270
283
  }
271
284
  } else {
272
285
  const result = await agent_invoke({
@@ -296,12 +309,7 @@ var resumeStream = async (request, reply) => {
296
309
  });
297
310
  return;
298
311
  }
299
- const stream = await resume_stream({
300
- thread_id,
301
- message_id,
302
- known_content,
303
- poll_interval: poll_interval || 100
304
- });
312
+ reply.hijack();
305
313
  reply.raw.writeHead(200, {
306
314
  "Content-Type": "text/event-stream",
307
315
  "Cache-Control": "no-cache",
@@ -309,6 +317,12 @@ var resumeStream = async (request, reply) => {
309
317
  "Access-Control-Allow-Origin": "*"
310
318
  });
311
319
  try {
320
+ const stream = await resume_stream({
321
+ thread_id,
322
+ message_id,
323
+ known_content: "",
324
+ poll_interval: poll_interval || 100
325
+ });
312
326
  for await (const chunk of stream) {
313
327
  reply.raw.write(`data: ${JSON.stringify(chunk)}
314
328
 
@@ -318,7 +332,6 @@ var resumeStream = async (request, reply) => {
318
332
  console.error("Resume stream processing error:", error);
319
333
  } finally {
320
334
  reply.raw.end();
321
- return reply.hijack();
322
335
  }
323
336
  } catch (error) {
324
337
  reply.status(500).send({
@@ -620,46 +633,11 @@ var getAgentGraphSchema = {
620
633
  200: {}
621
634
  }
622
635
  };
623
- var resumeStreamSchema = {
624
- description: "Resume streaming from a known position",
625
- tags: ["Streaming"],
626
- summary: "Resume Stream",
627
- body: {
628
- type: "object",
629
- properties: {
630
- thread_id: { type: "string", description: "Thread ID" },
631
- message_id: {
632
- type: "string",
633
- description: "Message ID (usually run_id)"
634
- },
635
- known_content: {
636
- type: "string",
637
- description: "Content already received"
638
- },
639
- poll_interval: {
640
- type: "number",
641
- description: "Polling interval in milliseconds",
642
- nullable: true,
643
- default: 100
644
- }
645
- },
646
- required: ["thread_id", "message_id"]
647
- },
648
- response: {
649
- 200: {},
650
- 400: {},
651
- 500: {}
652
- }
653
- };
654
636
 
655
637
  // src/routes/index.ts
656
638
  var registerLatticeRoutes = (app2) => {
657
639
  app2.post("/api/runs", createRun);
658
- app2.post(
659
- "/api/resume_stream",
660
- { schema: resumeStreamSchema },
661
- resumeStream
662
- );
640
+ app2.post("/api/resume_stream", resumeStream);
663
641
  app2.get(
664
642
  "/api/assistants/:assistantId/:thread_id/memory",
665
643
  { schema: getAllMemoryItemsSchema },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/services/agent_service.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/assistant.ts","../src/schemas/index.ts","../src/routes/index.ts","../src/logger/Logger.ts","../src/swagger.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport sensible from \"@fastify/sensible\";\nimport { registerLatticeRoutes } from \"./routes\";\n// 导入自定义 Logger 类\nimport { Logger } from \"./logger/Logger\";\nimport { configureSwagger } from \"./swagger\";\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// 创建自定义日志记录器\nconst logger = new Logger({\n serviceName: \"lattice-gateway\",\n name: \"fastify-server\",\n});\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n});\n\n// 添加自定义日志记录\napp.addHook(\"onRequest\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\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);\n\n// 错误处理\napp.setErrorHandler((error, request, reply) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": 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// 将日志记录器添加到应用实例中,以便在路由中使用\napp.decorate(\"logger\", logger);\n\n// 启动服务器\nconst start = async ({ port }: { port: number }) => {\n try {\n const target_port = port || Number(process.env.PORT) || 4001;\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${port}`);\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};\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\nfunction isAIMessageChunk(msg: any): msg is AIMessageChunk {\n return msg && msg.constructor.name === \"AIMessageChunk\";\n}\nfunction isToolMessageChunk(msg: any): msg is ToolMessageChunk {\n return msg && msg.constructor.name === \"ToolMessageChunk\";\n}\nfunction isAIMessage(msg: any): msg is AIMessage {\n return msg && msg.constructor.name === \"AIMessage\";\n}\nfunction isToolMessage(msg: any): msg is ToolMessage {\n return msg && msg.constructor.name === \"ToolMessage\";\n}\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 runnable_agent = getAgentClient(assistant_id);\n const { files, message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n humanMessage.additional_kwargs = { files: files };\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\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 },\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);\n const { files, message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n humanMessage.additional_kwargs = { files: files };\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\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 },\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].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: \"ai\",\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\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 files: message.additional_kwargs.files,\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, ...action_messages];\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 * Get accumulated content for a thread from ChunkBuffer\n */\nexport async function get_accumulated_content(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n return await chunkBuffer.getAccumulatedContent(thread_id);\n}\n\n/**\n * Get thread status and metadata from ChunkBuffer\n */\nexport async function get_thread_status(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n const threadBuffer = await chunkBuffer.getThreadBuffer(thread_id);\n return {\n exists: !!threadBuffer,\n status: threadBuffer?.status,\n chunkCount: threadBuffer?.chunks.length || 0,\n createdAt: threadBuffer?.createdAt,\n updatedAt: threadBuffer?.updatedAt,\n };\n}\n\n/**\n * Get all active streaming threads\n */\nexport async function get_active_threads() {\n const chunkBuffer = getOrCreateChunkBuffer();\n return await chunkBuffer.getActiveThreads();\n}\n\n/**\n * Get ChunkBuffer statistics\n */\nexport async function get_buffer_stats() {\n const chunkBuffer = getOrCreateChunkBuffer();\n return chunkBuffer.getStats();\n}\n\n/**\n * Clear specific thread buffer\n */\nexport async function clear_thread_buffer(thread_id: string) {\n const chunkBuffer = getOrCreateChunkBuffer();\n await chunkBuffer.clearThread(thread_id);\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 return chunkBuffer.getNewChunksSinceContent(\n thread_id,\n message_id,\n known_content\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 // 设置 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 // 通知 Fastify 我们将手动处理响应\n return reply.hijack();\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 // Get the stream from agent service\n const stream = await agentService.resume_stream({\n thread_id,\n message_id,\n known_content,\n poll_interval: poll_interval || 100,\n });\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 // Stream the chunks to the client\n for await (const chunk of stream) {\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 // Notify Fastify that we will manually handle the response\n return reply.hijack();\n }\n } catch (error: any) {\n reply.status(500).send({\n success: false,\n error: `Error resuming stream: ${error.message}`,\n });\n }\n};\n\n// // 获取运行\n// export const getRun = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { id } = request.params as { id: string };\n\n// if (!id) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await runModel.getRun(id);\n\n// if (!result.success) {\n// reply.status(404).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// // 获取助手的所有运行\n// export const getRunsByAssistant = 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// const result = await runModel.getRunsByAssistant(assistantId);\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// // 取消运行\n// export const cancelRun = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { id } = request.params as { id: string };\n\n// if (!id) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await runModel.updateRunStatus(id, RunStatus.CANCELLED);\n\n// if (!result.success) {\n// reply.status(404).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// // 添加消息\n// export const addMessage = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const data = request.body as AddMessageRequest;\n\n// // 验证请求数据\n// if (!data.runId || !data.role || !data.content) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID、角色和内容是必需的\",\n// });\n// return;\n// }\n\n// const result = await messageModel.addMessage(data);\n\n// if (!result.success) {\n// reply.status(500).send(result);\n// return;\n// }\n\n// reply.status(201).send(result);\n// } catch (error: any) {\n// reply.status(500).send({\n// success: false,\n// error: `添加消息时发生错误: ${error.message}`,\n// });\n// }\n// };\n\n// // 获取运行的所有消息\n// export const getMessages = async (\n// request: FastifyRequest,\n// reply: FastifyReply\n// ): Promise<void> => {\n// try {\n// const { runId } = request.params as { runId: string };\n\n// if (!runId) {\n// reply.status(400).send({\n// success: false,\n// error: \"运行ID是必需的\",\n// });\n// return;\n// }\n\n// const result = await messageModel.getMessagesByRun(runId);\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","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 { draw_graph } from \"../services/agent_service\";\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 // 调用绘图服务获取图片数据\n const imageData = await draw_graph(assistantId);\n\n // 设置响应头并返回图片数据\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 || \"获取代理图表失败\",\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","import { FastifyInstance } from \"fastify\";\n//import * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n} from \"../schemas\";\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 }>(\n \"/api/resume_stream\",\n { schema: resumeStreamSchema },\n runController.resumeStream\n );\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 // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n};\n","import pino from \"pino\";\nimport \"pino-pretty\";\nimport \"pino-roll\";\nimport { AsyncLocalStorage } from \"async_hooks\";\n\nexport interface LoggerContext {\n \"x-user-id\"?: string;\n \"x-tenant-id\"?: string;\n \"x-request-id\"?: string;\n \"x-task-id\"?: string;\n \"x-thread-id\"?: string;\n}\n\nexport interface LoggerOptions {\n name?: string;\n serviceName?: string;\n context?: LoggerContext;\n}\n\n/**\n * 单例的Pino日志工厂类,管理底层pino实例\n */\nclass PinoLoggerFactory {\n private static instance: PinoLoggerFactory;\n private pinoLogger: pino.Logger;\n\n private constructor() {\n const isProd = process.env.NODE_ENV === \"production\";\n\n const loggerConfig: pino.LoggerOptions = {\n // 自定义时间戳格式\n timestamp: () => `,\"@timestamp\":\"${new Date().toISOString()}\"`,\n\n // 关闭默认的时间戳键\n base: {\n \"@version\": \"1\",\n app_name: \"lattice\",\n service_name: \"lattice/graph-server\",\n thread_name: \"main\",\n logger_name: \"lattice-graph-logger\",\n },\n\n formatters: {\n level: (label, number) => {\n return {\n level: label.toUpperCase(),\n level_value: number * 1000,\n };\n },\n },\n };\n\n // 生产环境使用文件日志\n if (isProd) {\n try {\n this.pinoLogger = pino(\n loggerConfig,\n pino.transport({\n target: \"pino-roll\",\n options: {\n file: \"./logs/fin_ai_graph_server\",\n frequency: \"daily\",\n mkdir: true,\n },\n })\n );\n } catch (error) {\n console.error(\n \"无法初始化 pino-roll 日志记录器,回退到控制台日志\",\n error\n );\n // 回退到开发环境的配置\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n } else {\n // 开发环境使用格式化输出\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n }\n\n public static getInstance(): PinoLoggerFactory {\n if (!PinoLoggerFactory.instance) {\n PinoLoggerFactory.instance = new PinoLoggerFactory();\n }\n return PinoLoggerFactory.instance;\n }\n\n public getPinoLogger(): pino.Logger {\n return this.pinoLogger;\n }\n}\n\n/**\n * Logger类,可以创建多个实例,每个实例有自己的上下文\n */\nexport class Logger {\n private context: LoggerContext;\n private name: string;\n private serviceName: string;\n\n constructor(options?: LoggerOptions) {\n this.context = options?.context || {};\n this.name = options?.name || \"lattice-graph-logger\";\n this.serviceName = options?.serviceName || \"lattice/graph-server\";\n }\n\n /**\n * 获取合并了上下文的日志对象\n * @param additionalContext 额外的上下文数据\n * @returns 带有上下文的pino日志对象\n */\n private getContextualLogger(additionalContext?: object): pino.Logger {\n const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();\n\n // 合并Logger实例的上下文和额外上下文\n const contextObj = {\n \"x-user-id\": this.context[\"x-user-id\"] || \"\",\n \"x-tenant-id\": this.context[\"x-tenant-id\"] || \"\",\n \"x-request-id\": this.context[\"x-request-id\"] || \"\",\n \"x-task-id\": this.context[\"x-task-id\"] || \"\",\n \"x-thread-id\": this.context[\"x-thread-id\"] || \"\",\n service_name: this.serviceName,\n logger_name: this.name,\n ...additionalContext,\n };\n\n // 创建带有上下文的子日志记录器\n return pinoLogger.child(contextObj);\n }\n\n info(msg: string, obj?: object): void {\n this.getContextualLogger(obj).info(msg);\n }\n\n error(msg: string, obj?: object | Error): void {\n this.getContextualLogger(obj).error(msg);\n }\n\n warn(msg: string, obj?: object): void {\n this.getContextualLogger(obj).warn(msg);\n }\n\n debug(msg: string, obj?: object): void {\n this.getContextualLogger(obj).debug(msg);\n }\n\n /**\n * 更新Logger实例的上下文\n */\n updateContext(context: Partial<LoggerContext>): void {\n this.context = {\n ...this.context,\n ...context,\n };\n }\n\n /**\n * 创建一个新的Logger实例,继承当前Logger的上下文\n */\n child(options: Partial<LoggerOptions>): Logger {\n return new Logger({\n name: options.name || this.name,\n serviceName: options.serviceName || this.serviceName,\n context: {\n ...this.context,\n ...options.context,\n },\n });\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n"],"mappings":"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","names":["message","data","messages","v4","app","app"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/services/agent_service.ts","../src/controllers/run.ts","../src/controllers/memory.ts","../src/controllers/assistant.ts","../src/schemas/index.ts","../src/routes/index.ts","../src/logger/Logger.ts","../src/swagger.ts"],"sourcesContent":["import fastify from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport sensible from \"@fastify/sensible\";\nimport { registerLatticeRoutes } from \"./routes\";\n// 导入自定义 Logger 类\nimport { Logger } from \"./logger/Logger\";\nimport { configureSwagger } from \"./swagger\";\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n console.error(\"未处理的Promise拒绝:\", reason);\n // 可以在这里进行日志记录或其他处理\n});\n\n// 创建自定义日志记录器\nconst logger = new Logger({\n serviceName: \"lattice-gateway\",\n name: \"fastify-server\",\n});\n\n// 创建 Fastify 应用\nconst app = fastify({\n logger: false, // 禁用内置日志记录器\n});\n\n// 添加自定义日志记录\napp.addHook(\"onRequest\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\n done();\n});\n\napp.addHook(\"onResponse\", (request, reply, done) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": request.headers[\"x-request-id\"],\n };\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);\n\n// 错误处理\napp.setErrorHandler((error, request, reply) => {\n const context = {\n \"x-tenant-id\": request.headers[\"x-tenant-id\"],\n \"x-request-id\": 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// 将日志记录器添加到应用实例中,以便在路由中使用\napp.decorate(\"logger\", logger);\n\n// 启动服务器\nconst start = async ({ port }: { port: number }) => {\n try {\n const target_port = port || Number(process.env.PORT) || 4001;\n await app.listen({ port: target_port, host: \"0.0.0.0\" });\n logger.info(`Lattice Gateway is running on port: ${port}`);\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};\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 runnable_agent = getAgentClient(assistant_id);\n const { files, message, ...rest } = input;\n const humanMessage = new HumanMessage(message || \"\");\n humanMessage.additional_kwargs = { files: files };\n const messages = [humanMessage];\n if (!runnable_agent) {\n throw new Error(`Agent ${assistant_id} not found`);\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 },\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);\n const { files, message, ...rest } = input;\n let messages: BaseMessage[] = [];\n if (!command) {\n const humanMessage = new HumanMessage(message);\n humanMessage.additional_kwargs = { files: files };\n messages = [humanMessage];\n }\n\n // Get ChunkBuffer instance\n const chunkBuffer = getOrCreateChunkBuffer();\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 },\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].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: \"ai\",\n data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },\n };\n }\n\n if (data) {\n //console.log(data);\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 files: message.additional_kwargs.files,\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, ...action_messages];\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 console.log(chunk.data?.content);\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 * 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: \"\",\n poll_interval: poll_interval || 100,\n });\n\n // Stream the chunks to the client\n for await (const chunk of stream) {\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 { draw_graph } from \"../services/agent_service\";\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 // 调用绘图服务获取图片数据\n const imageData = await draw_graph(assistantId);\n\n // 设置响应头并返回图片数据\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 || \"获取代理图表失败\",\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","import { FastifyInstance } from \"fastify\";\n//import * as assistantController from \"../controllers/assistant\";\nimport * as runController from \"../controllers/run\";\nimport * as memoryController from \"../controllers/memory\";\nimport * as graphController from \"../controllers/assistant\";\nimport {\n createRunSchema,\n getAllMemoryItemsSchema,\n getAgentStateSchema,\n getMemoryItemSchema,\n setMemoryItemSchema,\n deleteMemoryItemSchema,\n clearMemorySchema,\n getAgentGraphSchema,\n resumeStreamSchema,\n} from \"../schemas\";\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 // 图表路由\n app.get<{\n Params: { assistantId: string };\n }>(\n \"/api/assistants/:assistantId/graph\",\n { schema: getAgentGraphSchema },\n graphController.getAgentGraph\n );\n};\n","import pino from \"pino\";\nimport \"pino-pretty\";\nimport \"pino-roll\";\nimport { AsyncLocalStorage } from \"async_hooks\";\n\nexport interface LoggerContext {\n \"x-user-id\"?: string;\n \"x-tenant-id\"?: string;\n \"x-request-id\"?: string;\n \"x-task-id\"?: string;\n \"x-thread-id\"?: string;\n}\n\nexport interface LoggerOptions {\n name?: string;\n serviceName?: string;\n context?: LoggerContext;\n}\n\n/**\n * 单例的Pino日志工厂类,管理底层pino实例\n */\nclass PinoLoggerFactory {\n private static instance: PinoLoggerFactory;\n private pinoLogger: pino.Logger;\n\n private constructor() {\n const isProd = process.env.NODE_ENV === \"production\";\n\n const loggerConfig: pino.LoggerOptions = {\n // 自定义时间戳格式\n timestamp: () => `,\"@timestamp\":\"${new Date().toISOString()}\"`,\n\n // 关闭默认的时间戳键\n base: {\n \"@version\": \"1\",\n app_name: \"lattice\",\n service_name: \"lattice/graph-server\",\n thread_name: \"main\",\n logger_name: \"lattice-graph-logger\",\n },\n\n formatters: {\n level: (label, number) => {\n return {\n level: label.toUpperCase(),\n level_value: number * 1000,\n };\n },\n },\n };\n\n // 生产环境使用文件日志\n if (isProd) {\n try {\n this.pinoLogger = pino(\n loggerConfig,\n pino.transport({\n target: \"pino-roll\",\n options: {\n file: \"./logs/fin_ai_graph_server\",\n frequency: \"daily\",\n mkdir: true,\n },\n })\n );\n } catch (error) {\n console.error(\n \"无法初始化 pino-roll 日志记录器,回退到控制台日志\",\n error\n );\n // 回退到开发环境的配置\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n } else {\n // 开发环境使用格式化输出\n this.pinoLogger = pino({\n ...loggerConfig,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n },\n },\n });\n }\n }\n\n public static getInstance(): PinoLoggerFactory {\n if (!PinoLoggerFactory.instance) {\n PinoLoggerFactory.instance = new PinoLoggerFactory();\n }\n return PinoLoggerFactory.instance;\n }\n\n public getPinoLogger(): pino.Logger {\n return this.pinoLogger;\n }\n}\n\n/**\n * Logger类,可以创建多个实例,每个实例有自己的上下文\n */\nexport class Logger {\n private context: LoggerContext;\n private name: string;\n private serviceName: string;\n\n constructor(options?: LoggerOptions) {\n this.context = options?.context || {};\n this.name = options?.name || \"lattice-graph-logger\";\n this.serviceName = options?.serviceName || \"lattice/graph-server\";\n }\n\n /**\n * 获取合并了上下文的日志对象\n * @param additionalContext 额外的上下文数据\n * @returns 带有上下文的pino日志对象\n */\n private getContextualLogger(additionalContext?: object): pino.Logger {\n const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();\n\n // 合并Logger实例的上下文和额外上下文\n const contextObj = {\n \"x-user-id\": this.context[\"x-user-id\"] || \"\",\n \"x-tenant-id\": this.context[\"x-tenant-id\"] || \"\",\n \"x-request-id\": this.context[\"x-request-id\"] || \"\",\n \"x-task-id\": this.context[\"x-task-id\"] || \"\",\n \"x-thread-id\": this.context[\"x-thread-id\"] || \"\",\n service_name: this.serviceName,\n logger_name: this.name,\n ...additionalContext,\n };\n\n // 创建带有上下文的子日志记录器\n return pinoLogger.child(contextObj);\n }\n\n info(msg: string, obj?: object): void {\n this.getContextualLogger(obj).info(msg);\n }\n\n error(msg: string, obj?: object | Error): void {\n this.getContextualLogger(obj).error(msg);\n }\n\n warn(msg: string, obj?: object): void {\n this.getContextualLogger(obj).warn(msg);\n }\n\n debug(msg: string, obj?: object): void {\n this.getContextualLogger(obj).debug(msg);\n }\n\n /**\n * 更新Logger实例的上下文\n */\n updateContext(context: Partial<LoggerContext>): void {\n this.context = {\n ...this.context,\n ...context,\n };\n }\n\n /**\n * 创建一个新的Logger实例,继承当前Logger的上下文\n */\n child(options: Partial<LoggerOptions>): Logger {\n return new Logger({\n name: options.name || this.name,\n serviceName: options.serviceName || this.serviceName,\n context: {\n ...this.context,\n ...options.context,\n },\n });\n }\n}\n","import { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n// Example usage:\n// configureSwagger(app)\n// configureSwagger(app, { openapi: { info: { version: \"2.0.0\" } } })\n// configureSwagger(app, undefined, { routePrefix: \"/docs\" })\n\n// Default swagger configuration\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Axiom Lattice Gateway API\",\n description: \"API Gateway for LangGraph agent-based applications\",\n version: \"1.0.0\",\n contact: {\n name: \"Axiom Lattice Team\",\n email: \"support@axiom-lattice.com\",\n },\n },\n servers: [\n {\n url: \"http://localhost:4001\",\n description: \"Development environment\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"JWT\",\n },\n },\n },\n security: [\n {\n bearerAuth: [],\n },\n ],\n tags: [\n { name: \"Runs\", description: \"Agent run management\" },\n { name: \"Memory\", description: \"Agent memory management\" },\n { name: \"Graph\", description: \"Agent graph visualization\" },\n { name: \"Health\", description: \"System health checks\" },\n ],\n },\n};\n\n// Default swagger UI configuration\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"full\" as const,\n deepLinking: false,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\n// Configure Swagger with optional custom configuration\nexport const configureSwagger = async (\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) => {\n // Merge default config with custom config\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n};\n"],"mappings":"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","names":["message","data","messages","v4","app","app"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/gateway",
3
- "version": "1.0.50",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -32,8 +32,8 @@
32
32
  "pino-roll": "^3.1.0",
33
33
  "redis": "^5.0.1",
34
34
  "uuid": "^9.0.1",
35
- "@axiom-lattice/core": "1.0.50",
36
- "@axiom-lattice/protocols": "1.0.50"
35
+ "@axiom-lattice/core": "2.0.0",
36
+ "@axiom-lattice/protocols": "2.0.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/jest": "^29.5.14",
@@ -49,6 +49,9 @@ export const createRun = async (
49
49
  run_id: x_request_id,
50
50
  });
51
51
 
52
+ // 通知 Fastify 我们将手动处理响应
53
+ reply.hijack();
54
+
52
55
  // 设置 SSE 响应头
53
56
  reply.raw.writeHead(200, {
54
57
  "Content-Type": "text/event-stream",
@@ -65,8 +68,6 @@ export const createRun = async (
65
68
  console.error("Stream processing error:", error);
66
69
  } finally {
67
70
  reply.raw.end();
68
- // 通知 Fastify 我们将手动处理响应
69
- return reply.hijack();
70
71
  }
71
72
  } else {
72
73
  // 后台运行的情况
@@ -106,13 +107,8 @@ export const resumeStream = async (
106
107
  return;
107
108
  }
108
109
 
109
- // Get the stream from agent service
110
- const stream = await agentService.resume_stream({
111
- thread_id,
112
- message_id,
113
- known_content,
114
- poll_interval: poll_interval || 100,
115
- });
110
+ // Notify Fastify that we will manually handle the response
111
+ reply.hijack();
116
112
 
117
113
  // Set SSE response headers
118
114
  reply.raw.writeHead(200, {
@@ -123,6 +119,14 @@ export const resumeStream = async (
123
119
  });
124
120
 
125
121
  try {
122
+ // Get the stream from agent service
123
+ const stream = await agentService.resume_stream({
124
+ thread_id,
125
+ message_id,
126
+ known_content: "",
127
+ poll_interval: poll_interval || 100,
128
+ });
129
+
126
130
  // Stream the chunks to the client
127
131
  for await (const chunk of stream) {
128
132
  reply.raw.write(`data: ${JSON.stringify(chunk)}\n\n`);
@@ -131,8 +135,6 @@ export const resumeStream = async (
131
135
  console.error("Resume stream processing error:", error);
132
136
  } finally {
133
137
  reply.raw.end();
134
- // Notify Fastify that we will manually handle the response
135
- return reply.hijack();
136
138
  }
137
139
  } catch (error: any) {
138
140
  reply.status(500).send({
@@ -141,154 +143,3 @@ export const resumeStream = async (
141
143
  });
142
144
  }
143
145
  };
144
-
145
- // // 获取运行
146
- // export const getRun = async (
147
- // request: FastifyRequest,
148
- // reply: FastifyReply
149
- // ): Promise<void> => {
150
- // try {
151
- // const { id } = request.params as { id: string };
152
-
153
- // if (!id) {
154
- // reply.status(400).send({
155
- // success: false,
156
- // error: "运行ID是必需的",
157
- // });
158
- // return;
159
- // }
160
-
161
- // const result = await runModel.getRun(id);
162
-
163
- // if (!result.success) {
164
- // reply.status(404).send(result);
165
- // return;
166
- // }
167
-
168
- // reply.send(result);
169
- // } catch (error: any) {
170
- // reply.status(500).send({
171
- // success: false,
172
- // error: `获取运行时发生错误: ${error.message}`,
173
- // });
174
- // }
175
- // };
176
-
177
- // // 获取助手的所有运行
178
- // export const getRunsByAssistant = async (
179
- // request: FastifyRequest,
180
- // reply: FastifyReply
181
- // ): Promise<void> => {
182
- // try {
183
- // const { assistantId } = request.params as { assistantId: string };
184
-
185
- // if (!assistantId) {
186
- // reply.status(400).send({
187
- // success: false,
188
- // error: "助手ID是必需的",
189
- // });
190
- // return;
191
- // }
192
-
193
- // const result = await runModel.getRunsByAssistant(assistantId);
194
-
195
- // reply.send(result);
196
- // } catch (error: any) {
197
- // reply.status(500).send({
198
- // success: false,
199
- // error: `获取助手运行时发生错误: ${error.message}`,
200
- // });
201
- // }
202
- // };
203
-
204
- // // 取消运行
205
- // export const cancelRun = async (
206
- // request: FastifyRequest,
207
- // reply: FastifyReply
208
- // ): Promise<void> => {
209
- // try {
210
- // const { id } = request.params as { id: string };
211
-
212
- // if (!id) {
213
- // reply.status(400).send({
214
- // success: false,
215
- // error: "运行ID是必需的",
216
- // });
217
- // return;
218
- // }
219
-
220
- // const result = await runModel.updateRunStatus(id, RunStatus.CANCELLED);
221
-
222
- // if (!result.success) {
223
- // reply.status(404).send(result);
224
- // return;
225
- // }
226
-
227
- // reply.send(result);
228
- // } catch (error: any) {
229
- // reply.status(500).send({
230
- // success: false,
231
- // error: `取消运行时发生错误: ${error.message}`,
232
- // });
233
- // }
234
- // };
235
-
236
- // // 添加消息
237
- // export const addMessage = async (
238
- // request: FastifyRequest,
239
- // reply: FastifyReply
240
- // ): Promise<void> => {
241
- // try {
242
- // const data = request.body as AddMessageRequest;
243
-
244
- // // 验证请求数据
245
- // if (!data.runId || !data.role || !data.content) {
246
- // reply.status(400).send({
247
- // success: false,
248
- // error: "运行ID、角色和内容是必需的",
249
- // });
250
- // return;
251
- // }
252
-
253
- // const result = await messageModel.addMessage(data);
254
-
255
- // if (!result.success) {
256
- // reply.status(500).send(result);
257
- // return;
258
- // }
259
-
260
- // reply.status(201).send(result);
261
- // } catch (error: any) {
262
- // reply.status(500).send({
263
- // success: false,
264
- // error: `添加消息时发生错误: ${error.message}`,
265
- // });
266
- // }
267
- // };
268
-
269
- // // 获取运行的所有消息
270
- // export const getMessages = async (
271
- // request: FastifyRequest,
272
- // reply: FastifyReply
273
- // ): Promise<void> => {
274
- // try {
275
- // const { runId } = request.params as { runId: string };
276
-
277
- // if (!runId) {
278
- // reply.status(400).send({
279
- // success: false,
280
- // error: "运行ID是必需的",
281
- // });
282
- // return;
283
- // }
284
-
285
- // const result = await messageModel.getMessagesByRun(runId);
286
-
287
- // reply.send(result);
288
- // } catch (error: any) {
289
- // reply.status(500).send({
290
- // success: false,
291
- // error: `获取消息时发生错误: ${error.message}`,
292
- // });
293
- // }
294
- // };
@@ -24,11 +24,7 @@ export const registerLatticeRoutes = (app: FastifyInstance): void => {
24
24
  // Resume stream route
25
25
  app.post<{
26
26
  Body: any;
27
- }>(
28
- "/api/resume_stream",
29
- { schema: resumeStreamSchema },
30
- runController.resumeStream
31
- );
27
+ }>("/api/resume_stream", runController.resumeStream);
32
28
 
33
29
  // app.get<{
34
30
  // Params: { id: string };
@@ -19,19 +19,6 @@ import {
19
19
  hasChunkBuffer,
20
20
  } from "@axiom-lattice/core";
21
21
 
22
- function isAIMessageChunk(msg: any): msg is AIMessageChunk {
23
- return msg && msg.constructor.name === "AIMessageChunk";
24
- }
25
- function isToolMessageChunk(msg: any): msg is ToolMessageChunk {
26
- return msg && msg.constructor.name === "ToolMessageChunk";
27
- }
28
- function isAIMessage(msg: any): msg is AIMessage {
29
- return msg && msg.constructor.name === "AIMessage";
30
- }
31
- function isToolMessage(msg: any): msg is ToolMessage {
32
- return msg && msg.constructor.name === "ToolMessage";
33
- }
34
-
35
22
  /**
36
23
  * Get or create the global ChunkBuffer instance
37
24
  */
@@ -280,53 +267,6 @@ export async function draw_graph(assistant_id: string) {
280
267
  return image;
281
268
  }
282
269
 
283
- /**
284
- * Get accumulated content for a thread from ChunkBuffer
285
- */
286
- export async function get_accumulated_content(thread_id: string) {
287
- const chunkBuffer = getOrCreateChunkBuffer();
288
- return await chunkBuffer.getAccumulatedContent(thread_id);
289
- }
290
-
291
- /**
292
- * Get thread status and metadata from ChunkBuffer
293
- */
294
- export async function get_thread_status(thread_id: string) {
295
- const chunkBuffer = getOrCreateChunkBuffer();
296
- const threadBuffer = await chunkBuffer.getThreadBuffer(thread_id);
297
- return {
298
- exists: !!threadBuffer,
299
- status: threadBuffer?.status,
300
- chunkCount: threadBuffer?.chunks.length || 0,
301
- createdAt: threadBuffer?.createdAt,
302
- updatedAt: threadBuffer?.updatedAt,
303
- };
304
- }
305
-
306
- /**
307
- * Get all active streaming threads
308
- */
309
- export async function get_active_threads() {
310
- const chunkBuffer = getOrCreateChunkBuffer();
311
- return await chunkBuffer.getActiveThreads();
312
- }
313
-
314
- /**
315
- * Get ChunkBuffer statistics
316
- */
317
- export async function get_buffer_stats() {
318
- const chunkBuffer = getOrCreateChunkBuffer();
319
- return chunkBuffer.getStats();
320
- }
321
-
322
- /**
323
- * Clear specific thread buffer
324
- */
325
- export async function clear_thread_buffer(thread_id: string) {
326
- const chunkBuffer = getOrCreateChunkBuffer();
327
- await chunkBuffer.clearThread(thread_id);
328
- }
329
-
330
270
  /**
331
271
  * Resume streaming from a known position
332
272
  * Creates an async iterator that yields new chunks as they arrive
@@ -336,7 +276,7 @@ export async function clear_thread_buffer(thread_id: string) {
336
276
  * @param known_content - Content already received (used to find resume position)
337
277
  * @param poll_interval - Polling interval in milliseconds (default: 100ms)
338
278
  */
339
- export async function* resume_stream({
279
+ export async function resume_stream({
340
280
  thread_id,
341
281
  message_id,
342
282
  known_content,
@@ -349,9 +289,22 @@ export async function* resume_stream({
349
289
  }) {
350
290
  const chunkBuffer = getOrCreateChunkBuffer();
351
291
 
352
- return chunkBuffer.getNewChunksSinceContent(
292
+ const stream = await chunkBuffer.getNewChunksSinceContentIterator(
353
293
  thread_id,
354
294
  message_id,
355
295
  known_content
356
296
  );
297
+ return {
298
+ [Symbol.asyncIterator]: async function* () {
299
+ try {
300
+ for await (const chunk of stream) {
301
+ console.log(chunk.data?.content);
302
+ yield chunk;
303
+ }
304
+ } catch (error) {
305
+ console.error("Resume stream error:", error);
306
+ throw error;
307
+ }
308
+ },
309
+ };
357
310
  }