@axiom-lattice/gateway 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -42,6 +42,18 @@ var import_messages = require("@langchain/core/messages");
42
42
  var import_langgraph = require("@langchain/langgraph");
43
43
  var import_uuid = require("uuid");
44
44
  var import_core = require("@axiom-lattice/core");
45
+ function getOrCreateChunkBuffer() {
46
+ if (!(0, import_core.hasChunkBuffer)("default")) {
47
+ const buffer = new import_core.InMemoryChunkBuffer({
48
+ ttl: 60 * 60 * 1e3,
49
+ // 1 hour TTL
50
+ cleanupInterval: 5 * 60 * 1e3
51
+ // Clean every 5 minutes
52
+ });
53
+ (0, import_core.registerChunkBuffer)("default", buffer);
54
+ }
55
+ return (0, import_core.getChunkBuffer)("default");
56
+ }
45
57
  async function agent_invoke({
46
58
  input,
47
59
  thread_id,
@@ -64,14 +76,21 @@ async function agent_invoke({
64
76
  configurable: {
65
77
  thread_id,
66
78
  run_id: run_id || (0, import_uuid.v4)(),
67
- recursionLimit: 200,
68
79
  "x-tenant-id": tenant_id,
69
80
  "x-request-id": run_id,
70
81
  "x-thread-id": thread_id
71
- }
82
+ },
83
+ recursionLimit: 200
72
84
  }
73
85
  );
74
- return result;
86
+ const data = result.messages.map((message2) => {
87
+ const { type, data: data2 } = message2.toDict();
88
+ return {
89
+ ...data2,
90
+ role: type
91
+ };
92
+ });
93
+ return { messages: data };
75
94
  }
76
95
  async function agent_stream({
77
96
  input,
@@ -89,6 +108,7 @@ async function agent_stream({
89
108
  humanMessage.additional_kwargs = { files };
90
109
  messages = [humanMessage];
91
110
  }
111
+ const chunkBuffer = getOrCreateChunkBuffer();
92
112
  try {
93
113
  if (!runnable_agent) {
94
114
  throw new Error(`Agent ${assistant_id} not found`);
@@ -108,7 +128,8 @@ async function agent_stream({
108
128
  "x-thread-id": thread_id
109
129
  },
110
130
  streamMode: ["updates", "messages"],
111
- subgraphs: false
131
+ subgraphs: false,
132
+ recursionLimit: 200
112
133
  }
113
134
  );
114
135
  return {
@@ -116,6 +137,7 @@ async function agent_stream({
116
137
  try {
117
138
  for await (const chunk of agentStream) {
118
139
  let data;
140
+ let chunkContent = "";
119
141
  if (chunk[0] === "updates") {
120
142
  const update = chunk[1];
121
143
  const values = Object.values(update);
@@ -128,19 +150,26 @@ async function agent_stream({
128
150
  data = messages2?.[0]?.toDict();
129
151
  }
130
152
  if (chunk?.[1]?.__interrupt__) {
131
- data = chunk?.[1]?.[0]?.toDict();
153
+ data = {
154
+ type: "ai",
155
+ data: { content: chunk?.[1]?.__interrupt__[0].value }
156
+ };
132
157
  }
133
158
  if (data) {
159
+ await chunkBuffer.addChunk(thread_id, data);
134
160
  yield data;
135
161
  }
136
162
  }
163
+ await chunkBuffer.completeThread(thread_id);
137
164
  } catch (error) {
138
165
  console.error("Stream error:", error);
166
+ await chunkBuffer.abortThread(thread_id);
139
167
  throw error;
140
168
  }
141
169
  }
142
170
  };
143
171
  } catch (error) {
172
+ await chunkBuffer.abortThread(thread_id);
144
173
  throw error;
145
174
  }
146
175
  }
@@ -202,6 +231,19 @@ async function draw_graph(assistant_id) {
202
231
  const image = await drawableGraph.drawMermaid();
203
232
  return image;
204
233
  }
234
+ async function* resume_stream({
235
+ thread_id,
236
+ message_id,
237
+ known_content,
238
+ poll_interval = 100
239
+ }) {
240
+ const chunkBuffer = getOrCreateChunkBuffer();
241
+ return chunkBuffer.getNewChunksSinceContent(
242
+ thread_id,
243
+ message_id,
244
+ known_content
245
+ );
246
+ }
205
247
 
206
248
  // src/controllers/run.ts
207
249
  var import_uuid2 = require("uuid");
@@ -246,6 +288,7 @@ var createRun = async (request, reply) => {
246
288
  `);
247
289
  }
248
290
  } catch (error) {
291
+ console.error("Stream processing error:", error);
249
292
  } finally {
250
293
  reply.raw.end();
251
294
  return reply.hijack();
@@ -268,6 +311,47 @@ var createRun = async (request, reply) => {
268
311
  });
269
312
  }
270
313
  };
314
+ var resumeStream = async (request, reply) => {
315
+ try {
316
+ const { thread_id, message_id, known_content, poll_interval } = request.body;
317
+ if (!thread_id || !message_id || known_content === void 0) {
318
+ reply.status(400).send({
319
+ success: false,
320
+ error: "thread_id, message_id, and known_content are required"
321
+ });
322
+ return;
323
+ }
324
+ const stream = await resume_stream({
325
+ thread_id,
326
+ message_id,
327
+ known_content,
328
+ poll_interval: poll_interval || 100
329
+ });
330
+ reply.raw.writeHead(200, {
331
+ "Content-Type": "text/event-stream",
332
+ "Cache-Control": "no-cache",
333
+ Connection: "keep-alive",
334
+ "Access-Control-Allow-Origin": "*"
335
+ });
336
+ try {
337
+ for await (const chunk of stream) {
338
+ reply.raw.write(`data: ${JSON.stringify(chunk)}
339
+
340
+ `);
341
+ }
342
+ } catch (error) {
343
+ console.error("Resume stream processing error:", error);
344
+ } finally {
345
+ reply.raw.end();
346
+ return reply.hijack();
347
+ }
348
+ } catch (error) {
349
+ reply.status(500).send({
350
+ success: false,
351
+ error: `Error resuming stream: ${error.message}`
352
+ });
353
+ }
354
+ };
271
355
 
272
356
  // src/controllers/memory.ts
273
357
  var setMemoryItem = async (request, reply) => {
@@ -444,31 +528,198 @@ var getAgentGraph = async (request, reply) => {
444
528
  }
445
529
  };
446
530
 
531
+ // src/schemas/index.ts
532
+ var getAllMemoryItemsSchema = {
533
+ description: "Get all memory items for an assistant thread",
534
+ tags: ["Memory"],
535
+ summary: "Get All Memory Items",
536
+ params: {
537
+ type: "object",
538
+ properties: {
539
+ assistantId: { type: "string", description: "Assistant ID" },
540
+ thread_id: { type: "string", description: "Thread ID" }
541
+ },
542
+ required: ["assistantId", "thread_id"]
543
+ },
544
+ response: {
545
+ 200: {},
546
+ 400: {},
547
+ 500: {}
548
+ }
549
+ };
550
+ var getAgentStateSchema = {
551
+ description: "Get agent state for an assistant thread",
552
+ tags: ["Memory"],
553
+ summary: "Get Agent State",
554
+ params: {
555
+ type: "object",
556
+ properties: {
557
+ assistantId: { type: "string", description: "Assistant ID" },
558
+ thread_id: { type: "string", description: "Thread ID" }
559
+ },
560
+ required: ["assistantId", "thread_id"]
561
+ },
562
+ response: {
563
+ 200: {}
564
+ }
565
+ };
566
+ var getMemoryItemSchema = {
567
+ description: "Get a specific memory item by key",
568
+ tags: ["Memory"],
569
+ summary: "Get Memory Item",
570
+ params: {
571
+ type: "object",
572
+ properties: {
573
+ assistantId: { type: "string", description: "Assistant ID" },
574
+ key: { type: "string", description: "Memory key" }
575
+ },
576
+ required: ["assistantId", "key"]
577
+ },
578
+ response: {
579
+ 200: {}
580
+ }
581
+ };
582
+ var setMemoryItemSchema = {
583
+ description: "Set or update a memory item",
584
+ tags: ["Memory"],
585
+ summary: "Set Memory Item",
586
+ params: {
587
+ type: "object",
588
+ properties: {
589
+ assistantId: { type: "string", description: "Assistant ID" },
590
+ key: { type: "string", description: "Memory key" }
591
+ },
592
+ required: ["assistantId", "key"]
593
+ },
594
+ body: {
595
+ type: "object",
596
+ description: "Memory item data"
597
+ },
598
+ response: {
599
+ 200: {}
600
+ }
601
+ };
602
+ var deleteMemoryItemSchema = {
603
+ description: "Delete a specific memory item",
604
+ tags: ["Memory"],
605
+ summary: "Delete Memory Item",
606
+ params: {
607
+ type: "object",
608
+ properties: {
609
+ assistantId: { type: "string", description: "Assistant ID" },
610
+ key: { type: "string", description: "Memory key" }
611
+ },
612
+ required: ["assistantId", "key"]
613
+ },
614
+ response: {
615
+ 200: {}
616
+ }
617
+ };
618
+ var clearMemorySchema = {
619
+ description: "Clear all memory items for an assistant",
620
+ tags: ["Memory"],
621
+ summary: "Clear Memory",
622
+ params: {
623
+ type: "object",
624
+ properties: {
625
+ assistantId: { type: "string", description: "Assistant ID" }
626
+ },
627
+ required: ["assistantId"]
628
+ },
629
+ response: {
630
+ 200: {}
631
+ }
632
+ };
633
+ var getAgentGraphSchema = {
634
+ description: "Get agent graph visualization",
635
+ tags: ["Graph"],
636
+ summary: "Get Agent Graph",
637
+ params: {
638
+ type: "object",
639
+ properties: {
640
+ assistantId: { type: "string", description: "Assistant ID" }
641
+ },
642
+ required: ["assistantId"]
643
+ },
644
+ response: {
645
+ 200: {}
646
+ }
647
+ };
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
+
447
680
  // src/routes/index.ts
448
- var registerRoutes = (app2) => {
681
+ var registerLatticeRoutes = (app2) => {
449
682
  app2.post("/api/runs", createRun);
683
+ app2.post(
684
+ "/api/resume_stream",
685
+ { schema: resumeStreamSchema },
686
+ resumeStream
687
+ );
450
688
  app2.get(
451
689
  "/api/assistants/:assistantId/:thread_id/memory",
690
+ { schema: getAllMemoryItemsSchema },
452
691
  getAllMemoryItems
453
692
  );
454
693
  app2.get(
455
694
  "/api/assistants/:assistantId/:thread_id/state",
695
+ { schema: getAgentStateSchema },
456
696
  getAgentState
457
697
  );
458
698
  app2.get(
459
699
  "/api/assistants/:assistantId/memory/:key",
700
+ { schema: getMemoryItemSchema },
460
701
  getMemoryItem
461
702
  );
462
703
  app2.put(
463
704
  "/api/assistants/:assistantId/memory/:key",
705
+ { schema: setMemoryItemSchema },
464
706
  setMemoryItem
465
707
  );
466
708
  app2.delete(
467
709
  "/api/assistants/:assistantId/memory/:key",
710
+ { schema: deleteMemoryItemSchema },
468
711
  deleteMemoryItem
469
712
  );
470
- app2.delete("/api/assistants/:assistantId/memory", clearMemory);
471
- app2.get("/api/assistants/:assistantId/graph", getAgentGraph);
713
+ app2.delete(
714
+ "/api/assistants/:assistantId/memory",
715
+ { schema: clearMemorySchema },
716
+ clearMemory
717
+ );
718
+ app2.get(
719
+ "/api/assistants/:assistantId/graph",
720
+ { schema: getAgentGraphSchema },
721
+ getAgentGraph
722
+ );
472
723
  };
473
724
 
474
725
  // src/logger/Logger.ts
@@ -609,6 +860,68 @@ var Logger = class _Logger {
609
860
  }
610
861
  };
611
862
 
863
+ // src/swagger.ts
864
+ var import_swagger = __toESM(require("@fastify/swagger"));
865
+ var import_swagger_ui = __toESM(require("@fastify/swagger-ui"));
866
+ var defaultSwaggerConfig = {
867
+ openapi: {
868
+ openapi: "3.0.0",
869
+ info: {
870
+ title: "Axiom Lattice Gateway API",
871
+ description: "API Gateway for LangGraph agent-based applications",
872
+ version: "1.0.0",
873
+ contact: {
874
+ name: "Axiom Lattice Team",
875
+ email: "support@axiom-lattice.com"
876
+ }
877
+ },
878
+ servers: [
879
+ {
880
+ url: "http://localhost:4001",
881
+ description: "Development environment"
882
+ }
883
+ ],
884
+ components: {
885
+ securitySchemes: {
886
+ bearerAuth: {
887
+ type: "http",
888
+ scheme: "bearer",
889
+ bearerFormat: "JWT"
890
+ }
891
+ }
892
+ },
893
+ security: [
894
+ {
895
+ bearerAuth: []
896
+ }
897
+ ],
898
+ tags: [
899
+ { name: "Runs", description: "Agent run management" },
900
+ { name: "Memory", description: "Agent memory management" },
901
+ { name: "Graph", description: "Agent graph visualization" },
902
+ { name: "Health", description: "System health checks" }
903
+ ]
904
+ }
905
+ };
906
+ var defaultSwaggerUiConfig = {
907
+ routePrefix: "/api-docs",
908
+ uiConfig: {
909
+ docExpansion: "full",
910
+ deepLinking: false
911
+ },
912
+ staticCSP: true,
913
+ transformStaticCSP: (header) => header
914
+ };
915
+ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig) => {
916
+ const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };
917
+ const swaggerUiConfig = {
918
+ ...defaultSwaggerUiConfig,
919
+ ...customSwaggerUiConfig
920
+ };
921
+ await app2.register(import_swagger.default, swaggerConfig);
922
+ await app2.register(import_swagger_ui.default, swaggerUiConfig);
923
+ };
924
+
612
925
  // src/index.ts
613
926
  process.on("unhandledRejection", (reason, promise) => {
614
927
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
@@ -669,7 +982,6 @@ app.setErrorHandler((error, request, reply) => {
669
982
  });
670
983
  });
671
984
  app.decorate("logger", logger);
672
- registerRoutes(app);
673
985
  var start = async ({ port }) => {
674
986
  try {
675
987
  const target_port = port || Number(process.env.PORT) || 4001;
@@ -682,6 +994,8 @@ var start = async ({ port }) => {
682
994
  };
683
995
  var LatticeGateway = {
684
996
  startAsHttpEndpoint: start,
997
+ configureSwagger,
998
+ registerLatticeRoutes,
685
999
  app
686
1000
  };
687
1001
  // Annotate the CommonJS export names for ESM import in node: