@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.mjs CHANGED
@@ -10,7 +10,25 @@ import {
10
10
  } from "@langchain/core/messages";
11
11
  import { Command } from "@langchain/langgraph";
12
12
  import { v4 } from "uuid";
13
- import { getAgentClient } from "@axiom-lattice/core";
13
+ import {
14
+ getAgentClient,
15
+ InMemoryChunkBuffer,
16
+ registerChunkBuffer,
17
+ getChunkBuffer,
18
+ hasChunkBuffer
19
+ } from "@axiom-lattice/core";
20
+ function getOrCreateChunkBuffer() {
21
+ if (!hasChunkBuffer("default")) {
22
+ const buffer = new InMemoryChunkBuffer({
23
+ ttl: 60 * 60 * 1e3,
24
+ // 1 hour TTL
25
+ cleanupInterval: 5 * 60 * 1e3
26
+ // Clean every 5 minutes
27
+ });
28
+ registerChunkBuffer("default", buffer);
29
+ }
30
+ return getChunkBuffer("default");
31
+ }
14
32
  async function agent_invoke({
15
33
  input,
16
34
  thread_id,
@@ -33,14 +51,21 @@ async function agent_invoke({
33
51
  configurable: {
34
52
  thread_id,
35
53
  run_id: run_id || v4(),
36
- recursionLimit: 200,
37
54
  "x-tenant-id": tenant_id,
38
55
  "x-request-id": run_id,
39
56
  "x-thread-id": thread_id
40
- }
57
+ },
58
+ recursionLimit: 200
41
59
  }
42
60
  );
43
- return result;
61
+ const data = result.messages.map((message2) => {
62
+ const { type, data: data2 } = message2.toDict();
63
+ return {
64
+ ...data2,
65
+ role: type
66
+ };
67
+ });
68
+ return { messages: data };
44
69
  }
45
70
  async function agent_stream({
46
71
  input,
@@ -58,6 +83,7 @@ async function agent_stream({
58
83
  humanMessage.additional_kwargs = { files };
59
84
  messages = [humanMessage];
60
85
  }
86
+ const chunkBuffer = getOrCreateChunkBuffer();
61
87
  try {
62
88
  if (!runnable_agent) {
63
89
  throw new Error(`Agent ${assistant_id} not found`);
@@ -77,7 +103,8 @@ async function agent_stream({
77
103
  "x-thread-id": thread_id
78
104
  },
79
105
  streamMode: ["updates", "messages"],
80
- subgraphs: false
106
+ subgraphs: false,
107
+ recursionLimit: 200
81
108
  }
82
109
  );
83
110
  return {
@@ -85,6 +112,7 @@ async function agent_stream({
85
112
  try {
86
113
  for await (const chunk of agentStream) {
87
114
  let data;
115
+ let chunkContent = "";
88
116
  if (chunk[0] === "updates") {
89
117
  const update = chunk[1];
90
118
  const values = Object.values(update);
@@ -97,19 +125,26 @@ async function agent_stream({
97
125
  data = messages2?.[0]?.toDict();
98
126
  }
99
127
  if (chunk?.[1]?.__interrupt__) {
100
- data = chunk?.[1]?.[0]?.toDict();
128
+ data = {
129
+ type: "ai",
130
+ data: { content: chunk?.[1]?.__interrupt__[0].value }
131
+ };
101
132
  }
102
133
  if (data) {
134
+ await chunkBuffer.addChunk(thread_id, data);
103
135
  yield data;
104
136
  }
105
137
  }
138
+ await chunkBuffer.completeThread(thread_id);
106
139
  } catch (error) {
107
140
  console.error("Stream error:", error);
141
+ await chunkBuffer.abortThread(thread_id);
108
142
  throw error;
109
143
  }
110
144
  }
111
145
  };
112
146
  } catch (error) {
147
+ await chunkBuffer.abortThread(thread_id);
113
148
  throw error;
114
149
  }
115
150
  }
@@ -171,6 +206,19 @@ async function draw_graph(assistant_id) {
171
206
  const image = await drawableGraph.drawMermaid();
172
207
  return image;
173
208
  }
209
+ async function* resume_stream({
210
+ thread_id,
211
+ message_id,
212
+ known_content,
213
+ poll_interval = 100
214
+ }) {
215
+ const chunkBuffer = getOrCreateChunkBuffer();
216
+ return chunkBuffer.getNewChunksSinceContent(
217
+ thread_id,
218
+ message_id,
219
+ known_content
220
+ );
221
+ }
174
222
 
175
223
  // src/controllers/run.ts
176
224
  import { v4 as v42 } from "uuid";
@@ -215,6 +263,7 @@ var createRun = async (request, reply) => {
215
263
  `);
216
264
  }
217
265
  } catch (error) {
266
+ console.error("Stream processing error:", error);
218
267
  } finally {
219
268
  reply.raw.end();
220
269
  return reply.hijack();
@@ -237,6 +286,47 @@ var createRun = async (request, reply) => {
237
286
  });
238
287
  }
239
288
  };
289
+ var resumeStream = async (request, reply) => {
290
+ try {
291
+ const { thread_id, message_id, known_content, poll_interval } = request.body;
292
+ if (!thread_id || !message_id || known_content === void 0) {
293
+ reply.status(400).send({
294
+ success: false,
295
+ error: "thread_id, message_id, and known_content are required"
296
+ });
297
+ return;
298
+ }
299
+ const stream = await resume_stream({
300
+ thread_id,
301
+ message_id,
302
+ known_content,
303
+ poll_interval: poll_interval || 100
304
+ });
305
+ reply.raw.writeHead(200, {
306
+ "Content-Type": "text/event-stream",
307
+ "Cache-Control": "no-cache",
308
+ Connection: "keep-alive",
309
+ "Access-Control-Allow-Origin": "*"
310
+ });
311
+ try {
312
+ for await (const chunk of stream) {
313
+ reply.raw.write(`data: ${JSON.stringify(chunk)}
314
+
315
+ `);
316
+ }
317
+ } catch (error) {
318
+ console.error("Resume stream processing error:", error);
319
+ } finally {
320
+ reply.raw.end();
321
+ return reply.hijack();
322
+ }
323
+ } catch (error) {
324
+ reply.status(500).send({
325
+ success: false,
326
+ error: `Error resuming stream: ${error.message}`
327
+ });
328
+ }
329
+ };
240
330
 
241
331
  // src/controllers/memory.ts
242
332
  var setMemoryItem = async (request, reply) => {
@@ -413,31 +503,198 @@ var getAgentGraph = async (request, reply) => {
413
503
  }
414
504
  };
415
505
 
506
+ // src/schemas/index.ts
507
+ var getAllMemoryItemsSchema = {
508
+ description: "Get all memory items for an assistant thread",
509
+ tags: ["Memory"],
510
+ summary: "Get All Memory Items",
511
+ params: {
512
+ type: "object",
513
+ properties: {
514
+ assistantId: { type: "string", description: "Assistant ID" },
515
+ thread_id: { type: "string", description: "Thread ID" }
516
+ },
517
+ required: ["assistantId", "thread_id"]
518
+ },
519
+ response: {
520
+ 200: {},
521
+ 400: {},
522
+ 500: {}
523
+ }
524
+ };
525
+ var getAgentStateSchema = {
526
+ description: "Get agent state for an assistant thread",
527
+ tags: ["Memory"],
528
+ summary: "Get Agent State",
529
+ params: {
530
+ type: "object",
531
+ properties: {
532
+ assistantId: { type: "string", description: "Assistant ID" },
533
+ thread_id: { type: "string", description: "Thread ID" }
534
+ },
535
+ required: ["assistantId", "thread_id"]
536
+ },
537
+ response: {
538
+ 200: {}
539
+ }
540
+ };
541
+ var getMemoryItemSchema = {
542
+ description: "Get a specific memory item by key",
543
+ tags: ["Memory"],
544
+ summary: "Get Memory Item",
545
+ params: {
546
+ type: "object",
547
+ properties: {
548
+ assistantId: { type: "string", description: "Assistant ID" },
549
+ key: { type: "string", description: "Memory key" }
550
+ },
551
+ required: ["assistantId", "key"]
552
+ },
553
+ response: {
554
+ 200: {}
555
+ }
556
+ };
557
+ var setMemoryItemSchema = {
558
+ description: "Set or update a memory item",
559
+ tags: ["Memory"],
560
+ summary: "Set Memory Item",
561
+ params: {
562
+ type: "object",
563
+ properties: {
564
+ assistantId: { type: "string", description: "Assistant ID" },
565
+ key: { type: "string", description: "Memory key" }
566
+ },
567
+ required: ["assistantId", "key"]
568
+ },
569
+ body: {
570
+ type: "object",
571
+ description: "Memory item data"
572
+ },
573
+ response: {
574
+ 200: {}
575
+ }
576
+ };
577
+ var deleteMemoryItemSchema = {
578
+ description: "Delete a specific memory item",
579
+ tags: ["Memory"],
580
+ summary: "Delete Memory Item",
581
+ params: {
582
+ type: "object",
583
+ properties: {
584
+ assistantId: { type: "string", description: "Assistant ID" },
585
+ key: { type: "string", description: "Memory key" }
586
+ },
587
+ required: ["assistantId", "key"]
588
+ },
589
+ response: {
590
+ 200: {}
591
+ }
592
+ };
593
+ var clearMemorySchema = {
594
+ description: "Clear all memory items for an assistant",
595
+ tags: ["Memory"],
596
+ summary: "Clear Memory",
597
+ params: {
598
+ type: "object",
599
+ properties: {
600
+ assistantId: { type: "string", description: "Assistant ID" }
601
+ },
602
+ required: ["assistantId"]
603
+ },
604
+ response: {
605
+ 200: {}
606
+ }
607
+ };
608
+ var getAgentGraphSchema = {
609
+ description: "Get agent graph visualization",
610
+ tags: ["Graph"],
611
+ summary: "Get Agent Graph",
612
+ params: {
613
+ type: "object",
614
+ properties: {
615
+ assistantId: { type: "string", description: "Assistant ID" }
616
+ },
617
+ required: ["assistantId"]
618
+ },
619
+ response: {
620
+ 200: {}
621
+ }
622
+ };
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
+
416
655
  // src/routes/index.ts
417
- var registerRoutes = (app2) => {
656
+ var registerLatticeRoutes = (app2) => {
418
657
  app2.post("/api/runs", createRun);
658
+ app2.post(
659
+ "/api/resume_stream",
660
+ { schema: resumeStreamSchema },
661
+ resumeStream
662
+ );
419
663
  app2.get(
420
664
  "/api/assistants/:assistantId/:thread_id/memory",
665
+ { schema: getAllMemoryItemsSchema },
421
666
  getAllMemoryItems
422
667
  );
423
668
  app2.get(
424
669
  "/api/assistants/:assistantId/:thread_id/state",
670
+ { schema: getAgentStateSchema },
425
671
  getAgentState
426
672
  );
427
673
  app2.get(
428
674
  "/api/assistants/:assistantId/memory/:key",
675
+ { schema: getMemoryItemSchema },
429
676
  getMemoryItem
430
677
  );
431
678
  app2.put(
432
679
  "/api/assistants/:assistantId/memory/:key",
680
+ { schema: setMemoryItemSchema },
433
681
  setMemoryItem
434
682
  );
435
683
  app2.delete(
436
684
  "/api/assistants/:assistantId/memory/:key",
685
+ { schema: deleteMemoryItemSchema },
437
686
  deleteMemoryItem
438
687
  );
439
- app2.delete("/api/assistants/:assistantId/memory", clearMemory);
440
- app2.get("/api/assistants/:assistantId/graph", getAgentGraph);
688
+ app2.delete(
689
+ "/api/assistants/:assistantId/memory",
690
+ { schema: clearMemorySchema },
691
+ clearMemory
692
+ );
693
+ app2.get(
694
+ "/api/assistants/:assistantId/graph",
695
+ { schema: getAgentGraphSchema },
696
+ getAgentGraph
697
+ );
441
698
  };
442
699
 
443
700
  // src/logger/Logger.ts
@@ -578,6 +835,68 @@ var Logger = class _Logger {
578
835
  }
579
836
  };
580
837
 
838
+ // src/swagger.ts
839
+ import swagger from "@fastify/swagger";
840
+ import swaggerUi from "@fastify/swagger-ui";
841
+ var defaultSwaggerConfig = {
842
+ openapi: {
843
+ openapi: "3.0.0",
844
+ info: {
845
+ title: "Axiom Lattice Gateway API",
846
+ description: "API Gateway for LangGraph agent-based applications",
847
+ version: "1.0.0",
848
+ contact: {
849
+ name: "Axiom Lattice Team",
850
+ email: "support@axiom-lattice.com"
851
+ }
852
+ },
853
+ servers: [
854
+ {
855
+ url: "http://localhost:4001",
856
+ description: "Development environment"
857
+ }
858
+ ],
859
+ components: {
860
+ securitySchemes: {
861
+ bearerAuth: {
862
+ type: "http",
863
+ scheme: "bearer",
864
+ bearerFormat: "JWT"
865
+ }
866
+ }
867
+ },
868
+ security: [
869
+ {
870
+ bearerAuth: []
871
+ }
872
+ ],
873
+ tags: [
874
+ { name: "Runs", description: "Agent run management" },
875
+ { name: "Memory", description: "Agent memory management" },
876
+ { name: "Graph", description: "Agent graph visualization" },
877
+ { name: "Health", description: "System health checks" }
878
+ ]
879
+ }
880
+ };
881
+ var defaultSwaggerUiConfig = {
882
+ routePrefix: "/api-docs",
883
+ uiConfig: {
884
+ docExpansion: "full",
885
+ deepLinking: false
886
+ },
887
+ staticCSP: true,
888
+ transformStaticCSP: (header) => header
889
+ };
890
+ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig) => {
891
+ const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };
892
+ const swaggerUiConfig = {
893
+ ...defaultSwaggerUiConfig,
894
+ ...customSwaggerUiConfig
895
+ };
896
+ await app2.register(swagger, swaggerConfig);
897
+ await app2.register(swaggerUi, swaggerUiConfig);
898
+ };
899
+
581
900
  // src/index.ts
582
901
  process.on("unhandledRejection", (reason, promise) => {
583
902
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
@@ -638,7 +957,6 @@ app.setErrorHandler((error, request, reply) => {
638
957
  });
639
958
  });
640
959
  app.decorate("logger", logger);
641
- registerRoutes(app);
642
960
  var start = async ({ port }) => {
643
961
  try {
644
962
  const target_port = port || Number(process.env.PORT) || 4001;
@@ -651,6 +969,8 @@ var start = async ({ port }) => {
651
969
  };
652
970
  var LatticeGateway = {
653
971
  startAsHttpEndpoint: start,
972
+ configureSwagger,
973
+ registerLatticeRoutes,
654
974
  app
655
975
  };
656
976
  export {