@axiom-lattice/gateway 2.1.44 → 2.1.45

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
@@ -7,279 +7,10 @@ import websocket from "@fastify/websocket";
7
7
  import staticPlugin from "@fastify/static";
8
8
  import path2 from "path";
9
9
 
10
- // src/services/agent_service.ts
11
- import {
12
- filterMessages,
13
- HumanMessage
14
- } from "@langchain/core/messages";
15
- import { Command } from "@langchain/langgraph";
16
- import { v4 } from "uuid";
17
- import {
18
- getAgentClient,
19
- agentLatticeManager,
20
- InMemoryChunkBuffer,
21
- registerChunkBuffer,
22
- getChunkBuffer,
23
- hasChunkBuffer
24
- } from "@axiom-lattice/core";
25
- async function checkAgentExists(tenant_id, assistant_id) {
26
- try {
27
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
28
- return agentLattice !== void 0;
29
- } catch {
30
- return false;
31
- }
32
- }
33
- function getOrCreateChunkBuffer() {
34
- if (!hasChunkBuffer("default")) {
35
- const buffer = new InMemoryChunkBuffer({
36
- ttl: 60 * 60 * 1e3,
37
- // 1 hour TTL
38
- cleanupInterval: 5 * 60 * 1e3
39
- // Clean every 5 minutes
40
- });
41
- registerChunkBuffer("default", buffer);
42
- }
43
- return getChunkBuffer("default");
44
- }
45
- async function agent_invoke({
46
- input,
47
- thread_id,
48
- assistant_id,
49
- tenant_id,
50
- workspace_id,
51
- project_id,
52
- command,
53
- run_id,
54
- custom_run_config
55
- }) {
56
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
57
- const runnable_agent = agentLattice?.client;
58
- const { message, ...rest } = input;
59
- const humanMessage = new HumanMessage(message || "");
60
- const messages = [humanMessage];
61
- if (!runnable_agent) {
62
- throw new Error(`Agent ${assistant_id} not found`);
63
- }
64
- const runConfig = {
65
- ...agentLattice?.config?.runConfig || {},
66
- tenantId: tenant_id,
67
- workspaceId: workspace_id,
68
- projectId: project_id,
69
- ...custom_run_config || {},
70
- assistant_id
71
- };
72
- const result = await runnable_agent.invoke(
73
- command ? new Command(command) : { ...rest, messages, "x-tenant-id": tenant_id },
74
- {
75
- context: {
76
- runConfig
77
- },
78
- configurable: {
79
- thread_id,
80
- run_id: run_id || v4(),
81
- "x-tenant-id": tenant_id,
82
- "x-workspace-id": workspace_id,
83
- "x-project-id": project_id,
84
- "x-request-id": run_id,
85
- "x-thread-id": thread_id,
86
- "x-assistant-id": assistant_id,
87
- runConfig
88
- },
89
- recursionLimit: 200
90
- }
91
- );
92
- const data = result.messages.map((message2) => {
93
- const { type, data: data2 } = message2.toDict();
94
- return {
95
- ...data2,
96
- role: type
97
- };
98
- });
99
- return { messages: data };
100
- }
101
- async function agent_stream({
102
- input,
103
- thread_id,
104
- command,
105
- tenant_id,
106
- workspace_id,
107
- project_id,
108
- assistant_id,
109
- run_id,
110
- custom_run_config
111
- }) {
112
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
113
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
114
- const { message, ...rest } = input;
115
- let messages = [];
116
- if (!command) {
117
- const humanMessage = new HumanMessage(message);
118
- messages = [humanMessage];
119
- }
120
- const chunkBuffer = getOrCreateChunkBuffer();
121
- const runConfig = {
122
- ...agentLattice?.config?.runConfig || {},
123
- tenantId: tenant_id,
124
- workspaceId: workspace_id,
125
- projectId: project_id,
126
- ...custom_run_config || {},
127
- assistant_id
128
- };
129
- try {
130
- if (!runnable_agent) {
131
- throw new Error(`Agent ${assistant_id} not found`);
132
- }
133
- const agentStream = await runnable_agent.stream(
134
- command ? new Command(command) : {
135
- ...rest,
136
- messages,
137
- "x-tenant-id": tenant_id
138
- },
139
- {
140
- context: {
141
- runConfig
142
- },
143
- configurable: {
144
- thread_id,
145
- run_id: run_id || v4(),
146
- "x-tenant-id": tenant_id,
147
- "x-workspace-id": workspace_id,
148
- "x-project-id": project_id,
149
- "x-request-id": run_id,
150
- "x-thread-id": thread_id,
151
- "x-assistant-id": assistant_id,
152
- runConfig
153
- // Inject runConfig for tools to access
154
- },
155
- streamMode: ["updates", "messages"],
156
- subgraphs: false,
157
- recursionLimit: 200
158
- }
159
- );
160
- return {
161
- [Symbol.asyncIterator]: async function* () {
162
- try {
163
- for await (const chunk of agentStream) {
164
- let data;
165
- let chunkContent = "";
166
- if (chunk[0] === "updates") {
167
- const update = chunk[1];
168
- const values = Object.values(update);
169
- const messages2 = values[0]?.messages;
170
- if (messages2?.[0]?.tool_call_id) {
171
- data = messages2[0].toDict();
172
- }
173
- } else if (chunk[0] === "messages") {
174
- const messages2 = chunk[1];
175
- data = messages2?.[0]?.toDict();
176
- }
177
- if (chunk?.[1]?.__interrupt__) {
178
- data = {
179
- type: "interrupt",
180
- id: chunk?.[1]?.__interrupt__[0].id,
181
- data: { content: chunk?.[1]?.__interrupt__[0].value }
182
- };
183
- }
184
- if (data) {
185
- if (data.type !== "interrupt") {
186
- await chunkBuffer.addChunk(thread_id, data);
187
- }
188
- yield data;
189
- }
190
- }
191
- await chunkBuffer.completeThread(thread_id);
192
- } catch (error) {
193
- console.error("Stream error:", error);
194
- await chunkBuffer.abortThread(thread_id);
195
- throw error;
196
- }
197
- }
198
- };
199
- } catch (error) {
200
- await chunkBuffer.abortThread(thread_id);
201
- throw error;
202
- }
203
- }
204
- async function agent_state({
205
- assistant_id,
206
- thread_id,
207
- tenant_id
208
- }) {
209
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
210
- if (!runnable_agent) {
211
- throw new Error(`Agent ${assistant_id} not found`);
212
- }
213
- const state = await runnable_agent.getState({
214
- configurable: { thread_id, subgraphs: false }
215
- });
216
- return state;
217
- }
218
- async function agent_messages({
219
- thread_id,
220
- tenant_id,
221
- assistant_id
222
- }) {
223
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
224
- if (!runnable_agent) {
225
- throw new Error(`Agent ${assistant_id} not found`);
226
- }
227
- const state = await runnable_agent.getState({
228
- configurable: { thread_id, subgraphs: false }
229
- });
230
- const messages = state.values.messages || [];
231
- const filteredMessages = filterMessages(messages, {
232
- includeTypes: ["ai", "human", "tool"]
233
- //["human", "ai", "tool"],
234
- });
235
- let messagesArray = filteredMessages.map((message) => ({
236
- id: message.id,
237
- role: message.getType(),
238
- content: message.content,
239
- ...message.lc_kwargs
240
- }));
241
- const new_messages = messagesArray;
242
- return new_messages;
243
- }
244
- async function draw_graph(assistant_id, tenant_id) {
245
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
246
- if (!runnable_agent) {
247
- throw new Error(`Agent ${assistant_id} not found`);
248
- }
249
- const drawableGraph = await runnable_agent.getGraphAsync();
250
- const image = await drawableGraph.drawMermaid();
251
- return image;
252
- }
253
- async function resume_stream({
254
- thread_id,
255
- message_id,
256
- known_content,
257
- poll_interval = 100
258
- }) {
259
- const chunkBuffer = getOrCreateChunkBuffer();
260
- const stream = await chunkBuffer.getNewChunksSinceContentIterator(
261
- thread_id,
262
- message_id,
263
- known_content
264
- );
265
- return {
266
- [Symbol.asyncIterator]: async function* () {
267
- try {
268
- for await (const chunk of stream) {
269
- yield chunk;
270
- }
271
- } catch (error) {
272
- console.error("Resume stream error:", error);
273
- throw error;
274
- }
275
- }
276
- };
277
- }
278
-
279
10
  // src/controllers/assistant.ts
280
- import { getStoreLattice } from "@axiom-lattice/core";
11
+ import { agentInstanceManager, getStoreLattice } from "@axiom-lattice/core";
281
12
  import { randomUUID } from "crypto";
282
- import { agentLatticeManager as agentLatticeManager2, eventBus } from "@axiom-lattice/core";
13
+ import { agentLatticeManager, eventBus } from "@axiom-lattice/core";
283
14
  function getTenantId(request) {
284
15
  const userTenantId = request.user?.tenantId;
285
16
  if (userTenantId) {
@@ -304,7 +35,7 @@ function convertAgentConfigToAssistant(config) {
304
35
  }
305
36
  async function getAssistantList(request, reply) {
306
37
  const tenantId = getTenantId(request);
307
- const agentConfigs = await agentLatticeManager2.getAllAgentConfigsByTenant(tenantId);
38
+ const agentConfigs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId);
308
39
  const codeConfiguredAssistants = agentConfigs.map(
309
40
  convertAgentConfigToAssistant
310
41
  );
@@ -335,7 +66,7 @@ async function getAssistant(request, reply) {
335
66
  const assistantStore = storeLattice.store;
336
67
  let assistant = await assistantStore.getAssistantById(tenantId, id);
337
68
  if (!assistant) {
338
- const agentConfig = await agentLatticeManager2.getAgentConfigWithTenant(tenantId, id);
69
+ const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);
339
70
  if (agentConfig) {
340
71
  assistant = convertAgentConfigToAssistant(agentConfig);
341
72
  }
@@ -412,7 +143,7 @@ async function deleteAssistant(request, reply) {
412
143
  const { id } = request.params;
413
144
  const storeLattice = getStoreLattice("default", "assistant");
414
145
  const assistantStore = storeLattice.store;
415
- const agentConfig = await agentLatticeManager2.getAgentConfigWithTenant(tenantId, id);
146
+ const agentConfig = await agentLatticeManager.getAgentConfigWithTenant(tenantId, id);
416
147
  const isCodeConfigured = !!agentConfig;
417
148
  if (isCodeConfigured) {
418
149
  const exists2 = await assistantStore.hasAssistant(tenantId, id);
@@ -453,7 +184,8 @@ var getAgentGraph = async (request, reply) => {
453
184
  try {
454
185
  const { assistantId } = request.params;
455
186
  const tenant_id = getTenantId(request);
456
- const imageData = await draw_graph(assistantId, tenant_id);
187
+ const agent = agentInstanceManager.getAgent({ assistant_id: assistantId, tenant_id, thread_id: "" });
188
+ const imageData = await agent.get_draw_graph();
457
189
  reply.header("Content-Type", "application/json").send({
458
190
  image: imageData
459
191
  });
@@ -466,7 +198,11 @@ var getAgentGraph = async (request, reply) => {
466
198
  };
467
199
 
468
200
  // src/controllers/run.ts
469
- import { v4 as v42 } from "uuid";
201
+ import { v4 } from "uuid";
202
+ import {
203
+ Agent,
204
+ agentInstanceManager as agentInstanceManager2
205
+ } from "@axiom-lattice/core";
470
206
  var createRun = async (request, reply) => {
471
207
  try {
472
208
  const {
@@ -481,7 +217,7 @@ var createRun = async (request, reply) => {
481
217
  const tenant_id = request.headers["x-tenant-id"];
482
218
  const workspace_id = request.headers["x-workspace-id"];
483
219
  const project_id = request.headers["x-project-id"];
484
- const x_request_id = request.headers["x-request-id"] || v42();
220
+ const x_request_id = request.headers["x-request-id"] || v4();
485
221
  if (!assistant_id) {
486
222
  reply.status(400).send({
487
223
  success: false,
@@ -489,26 +225,15 @@ var createRun = async (request, reply) => {
489
225
  });
490
226
  return;
491
227
  }
228
+ const agent = agentInstanceManager2.getAgent({
229
+ assistant_id,
230
+ thread_id,
231
+ tenant_id,
232
+ workspace_id,
233
+ project_id,
234
+ custom_run_config
235
+ });
492
236
  if (streaming) {
493
- const agentExists = await checkAgentExists(tenant_id, assistant_id);
494
- if (!agentExists) {
495
- reply.status(404).send({
496
- success: false,
497
- error: `Agent ${assistant_id} not found for tenant ${tenant_id}`
498
- });
499
- return;
500
- }
501
- const stream = await agent_stream({
502
- assistant_id,
503
- input,
504
- thread_id,
505
- command,
506
- tenant_id,
507
- workspace_id,
508
- project_id,
509
- run_id: x_request_id,
510
- custom_run_config
511
- });
512
237
  reply.hijack();
513
238
  reply.raw.writeHead(200, {
514
239
  "Content-Type": "text/event-stream",
@@ -517,9 +242,13 @@ var createRun = async (request, reply) => {
517
242
  "Access-Control-Allow-Origin": "*"
518
243
  });
519
244
  try {
520
- let chunkCount = 0;
245
+ const result = await agent.addMessage({
246
+ input,
247
+ command
248
+ });
249
+ const stream = agent.chunkStream(result.messageId);
521
250
  for await (const chunk of stream) {
522
- chunkCount++;
251
+ console.log(input.message, chunk.data.content);
523
252
  const success = reply.raw.write(`data: ${JSON.stringify(chunk)}
524
253
 
525
254
  `);
@@ -531,7 +260,7 @@ var createRun = async (request, reply) => {
531
260
  const errorEvent = {
532
261
  type: "error",
533
262
  data: {
534
- id: v42(),
263
+ id: v4(),
535
264
  content: error.message || "Stream processing error"
536
265
  }
537
266
  };
@@ -542,18 +271,15 @@ var createRun = async (request, reply) => {
542
271
  reply.raw.end();
543
272
  }
544
273
  } else {
545
- const result = await agent_invoke({
546
- assistant_id,
547
- input,
548
- command,
549
- thread_id,
550
- tenant_id,
551
- workspace_id,
552
- project_id,
553
- run_id: x_request_id,
554
- custom_run_config
274
+ const { message: msg, ...restInputNonStream } = input;
275
+ const result = await agent.invoke({
276
+ input: { message: msg, ...restInputNonStream },
277
+ command
278
+ });
279
+ reply.status(200).send({
280
+ success: true,
281
+ ...result
555
282
  });
556
- reply.status(200).send(result);
557
283
  }
558
284
  } catch (error) {
559
285
  reply.status(500).send({
@@ -580,12 +306,12 @@ var resumeStream = async (request, reply) => {
580
306
  "Access-Control-Allow-Origin": "*"
581
307
  });
582
308
  try {
583
- const stream = await resume_stream({
309
+ const agent = new Agent({
310
+ assistant_id: "",
584
311
  thread_id,
585
- message_id,
586
- known_content,
587
- poll_interval: poll_interval || 100
312
+ tenant_id: ""
588
313
  });
314
+ const stream = agent.chunkStream(message_id, known_content);
589
315
  for await (const chunk of stream) {
590
316
  reply.raw.write(`data: ${JSON.stringify(chunk)}
591
317
 
@@ -595,7 +321,7 @@ var resumeStream = async (request, reply) => {
595
321
  const errorEvent = {
596
322
  type: "error",
597
323
  data: {
598
- id: v42(),
324
+ id: v4(),
599
325
  content: error.message || "Resume stream processing error"
600
326
  }
601
327
  };
@@ -614,6 +340,7 @@ var resumeStream = async (request, reply) => {
614
340
  };
615
341
 
616
342
  // src/controllers/memory.ts
343
+ import { agentInstanceManager as agentInstanceManager3 } from "@axiom-lattice/core";
617
344
  var setMemoryItem = async (request, reply) => {
618
345
  try {
619
346
  const { assistantId, key } = request.params;
@@ -678,11 +405,8 @@ var getAllMemoryItems = async (request, reply) => {
678
405
  });
679
406
  return;
680
407
  }
681
- const result = await agent_messages({
682
- assistant_id: assistantId,
683
- thread_id,
684
- tenant_id
685
- });
408
+ const agent = agentInstanceManager3.getAgent({ assistant_id: assistantId, tenant_id, thread_id });
409
+ const result = await agent.getCurrentMessages();
686
410
  if (!result) {
687
411
  reply.status(500).send(result);
688
412
  return;
@@ -713,16 +437,18 @@ var getAgentState = async (request, reply) => {
713
437
  return;
714
438
  }
715
439
  const tenant_id = request.headers["x-tenant-id"];
716
- const result = await agent_state({
717
- assistant_id: assistantId,
718
- thread_id,
719
- tenant_id
720
- });
440
+ const agent = agentInstanceManager3.getAgent({ assistant_id: assistantId, tenant_id, thread_id });
441
+ const result = await agent.getCurrentState();
442
+ const pendingMessages = await agent.getPendingMessages();
721
443
  if (!result) {
722
444
  reply.status(500).send(result);
723
445
  return;
724
446
  }
725
- reply.send(result);
447
+ const mergedResult = {
448
+ ...result,
449
+ pendingMessages
450
+ };
451
+ reply.send(mergedResult);
726
452
  } catch (error) {
727
453
  reply.status(500).send({
728
454
  success: false,
@@ -5182,7 +4908,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
5182
4908
  };
5183
4909
 
5184
4910
  // src/services/agent_task_consumer.ts
5185
- import { eventBus as eventBus2, AGENT_TASK_EVENT } from "@axiom-lattice/core";
4911
+ import { eventBus as eventBus2, AGENT_TASK_EVENT, agentInstanceManager as agentInstanceManager4, QueueMode } from "@axiom-lattice/core";
5186
4912
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
5187
4913
  const {
5188
4914
  assistant_id,
@@ -5199,82 +4925,18 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
5199
4925
  );
5200
4926
  const apiUrl = AgentTaskConsumer.agent_run_endpoint;
5201
4927
  console.log(`apiUrl: ${apiUrl}`);
5202
- const response = await fetch(apiUrl, {
5203
- method: "POST",
5204
- body: JSON.stringify({
5205
- assistant_id,
5206
- streaming: true,
5207
- ...input,
5208
- thread_id,
5209
- command,
5210
- custom_run_config: runConfig
5211
- }),
5212
- headers: {
5213
- "Content-Type": "application/json",
5214
- "x-tenant-id": tenant_id,
5215
- "x-workspace-id": runConfig?.workspaceId,
5216
- "x-project-id": runConfig?.projectId
5217
- }
5218
- }).catch((err) => {
5219
- console.error(`fetch\u8BF7\u6C42\u5931\u8D25: ${err.message || String(err)}`);
5220
- throw new Error(`fetch\u5931\u8D25: ${err.message || String(err)}`);
5221
- });
5222
- if (!response.ok) {
5223
- throw new Error(`API\u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`);
5224
- }
5225
- const contentType = response.headers.get("content-type");
5226
- if (contentType?.includes("text/event-stream")) {
5227
- const reader = response.body?.getReader();
5228
- const decoder = new TextDecoder();
5229
- if (!reader) {
5230
- throw new Error("Response body is not readable");
5231
- }
5232
- let buffer = "";
5233
- let streamEnded = false;
5234
- try {
5235
- while (true) {
5236
- const { done, value } = await reader.read();
5237
- if (done) {
5238
- streamEnded = true;
5239
- console.log(
5240
- `SSE\u6D41\u5DF2\u7ED3\u675F [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
5241
- );
5242
- break;
5243
- }
5244
- }
5245
- } catch (streamError) {
5246
- console.error("Error reading SSE stream:", streamError);
5247
- throw streamError;
5248
- } finally {
5249
- reader.releaseLock();
5250
- }
5251
- if (callback_event) {
5252
- const state = await agent_state({ assistant_id, thread_id, tenant_id });
5253
- eventBus2.publish(callback_event, {
5254
- success: true,
5255
- state,
5256
- config: { assistant_id, thread_id, tenant_id }
5257
- });
5258
- }
5259
- console.log(
5260
- `\u4EFB\u52A1\u5904\u7406\u6210\u529F [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
5261
- );
5262
- return true;
5263
- } else {
5264
- await response.text();
5265
- if (callback_event) {
5266
- const state = await agent_state({ assistant_id, thread_id, tenant_id });
4928
+ const agent = agentInstanceManager4.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig });
4929
+ await agent.addMessage({ input, command }, QueueMode.STEER);
4930
+ if (callback_event) {
4931
+ agent.subscribeOnce("message:completed", (evt) => {
5267
4932
  eventBus2.publish(callback_event, {
5268
4933
  success: true,
5269
- state,
4934
+ state: evt.state,
5270
4935
  config: { assistant_id, thread_id, tenant_id }
5271
4936
  });
5272
- }
5273
- console.log(
5274
- `\u4EFB\u52A1\u5904\u7406\u6210\u529F [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
5275
- );
5276
- return true;
4937
+ });
5277
4938
  }
4939
+ return true;
5278
4940
  } catch (error) {
5279
4941
  console.error(
5280
4942
  `Agent\u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${assistant_id}, \u7EBF\u7A0B: ${thread_id}`,
@@ -5536,7 +5198,6 @@ app.addHook("onResponse", (request, reply, done) => {
5536
5198
  "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
5537
5199
  "x-request-id": getHeaderValue(request.headers["x-request-id"])
5538
5200
  };
5539
- loggerLattice.info(`${request.method} ${request.url} - ${reply.statusCode}`);
5540
5201
  done();
5541
5202
  });
5542
5203
  app.register(cors, {
@@ -5614,6 +5275,11 @@ var start = async (config) => {
5614
5275
  const target_port = config?.port || Number(process.env.PORT) || 4001;
5615
5276
  await app.listen({ port: target_port, host: "0.0.0.0" });
5616
5277
  logger.info(`Lattice Gateway is running on port: ${target_port}`);
5278
+ try {
5279
+ logger.info("AgentLifecycleManager initialized");
5280
+ } catch (error) {
5281
+ logger.warn("Failed to initialize AgentLifecycleManager", { error });
5282
+ }
5617
5283
  const queueServiceConfig = config?.queueServiceConfig;
5618
5284
  if (queueServiceConfig) {
5619
5285
  setQueueServiceType(queueServiceConfig.type);