@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.
@@ -1,375 +0,0 @@
1
- import {
2
- AIMessage,
3
- AIMessageChunk,
4
- BaseMessage,
5
- filterMessages,
6
- HumanMessage,
7
- ToolMessage,
8
- ToolMessageChunk,
9
- } from "@langchain/core/messages";
10
- import { Command, CommandParams } from "@langchain/langgraph";
11
- import { v4 } from "uuid";
12
- import {
13
- getAgentClient,
14
- agentLatticeManager,
15
- InMemoryChunkBuffer,
16
- registerChunkBuffer,
17
- getChunkBuffer,
18
- hasChunkBuffer,
19
- } from "@axiom-lattice/core";
20
-
21
- /**
22
- * Check if an agent exists for the given tenant and assistant ID
23
- */
24
- export async function checkAgentExists(
25
- tenant_id: string,
26
- assistant_id: string
27
- ): Promise<boolean> {
28
- try {
29
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
30
- return agentLattice !== undefined;
31
- } catch {
32
- return false;
33
- }
34
- }
35
-
36
- /**
37
- * Get or create the global ChunkBuffer instance
38
- */
39
- function getOrCreateChunkBuffer(): InMemoryChunkBuffer {
40
- if (!hasChunkBuffer("default")) {
41
- const buffer = new InMemoryChunkBuffer({
42
- ttl: 60 * 60 * 1000, // 1 hour TTL
43
- cleanupInterval: 5 * 60 * 1000, // Clean every 5 minutes
44
- });
45
- registerChunkBuffer("default", buffer);
46
- }
47
- return getChunkBuffer("default") as InMemoryChunkBuffer;
48
- }
49
-
50
- export async function agent_invoke({
51
- input,
52
- thread_id,
53
- assistant_id,
54
- tenant_id,
55
- workspace_id,
56
- project_id,
57
- command,
58
- run_id,
59
- custom_run_config,
60
- }: {
61
- assistant_id: string;
62
- input: any;
63
- thread_id: string;
64
- tenant_id: string;
65
- workspace_id?: string;
66
- project_id?: string;
67
- run_id?: string;
68
- command?: CommandParams<any>;
69
- custom_run_config?: Record<string, any>;
70
- }) {
71
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
72
- const runnable_agent = agentLattice?.client;
73
-
74
- const { message, ...rest } = input;
75
- const humanMessage = new HumanMessage(message || "");
76
- const messages = [humanMessage];
77
- if (!runnable_agent) {
78
- throw new Error(`Agent ${assistant_id} not found`);
79
- }
80
-
81
- // Get runConfig from agent config and merge with custom_run_config
82
- const runConfig = {
83
- ...agentLattice?.config?.runConfig || {},
84
- tenantId: tenant_id,
85
- workspaceId: workspace_id,
86
- projectId: project_id,
87
- ...custom_run_config || {},
88
- assistant_id,
89
-
90
- }
91
-
92
- const result = await runnable_agent.invoke(
93
- command
94
- ? new Command(command)
95
- : { ...rest, messages, "x-tenant-id": tenant_id },
96
- {
97
- context: {
98
- runConfig
99
- },
100
- configurable: {
101
- thread_id: thread_id,
102
- run_id: run_id || v4(),
103
- "x-tenant-id": tenant_id,
104
- "x-workspace-id": workspace_id,
105
- "x-project-id": project_id,
106
- "x-request-id": run_id,
107
- "x-thread-id": thread_id,
108
- "x-assistant-id": assistant_id,
109
- runConfig,
110
- },
111
- recursionLimit: 200,
112
- }
113
- );
114
-
115
- const data = result.messages.map((message: BaseMessage) => {
116
- const { type, data } = message.toDict();
117
- return {
118
- ...data,
119
- role: type,
120
- };
121
- });
122
- return { messages: data };
123
- }
124
-
125
- export async function agent_stream({
126
- input,
127
- thread_id,
128
- command,
129
- tenant_id,
130
- workspace_id,
131
- project_id,
132
- assistant_id,
133
- run_id,
134
- custom_run_config,
135
- }: {
136
- assistant_id: string;
137
- input: any;
138
- thread_id: string;
139
- command?: CommandParams<any>;
140
- tenant_id: string;
141
- workspace_id?: string;
142
- project_id?: string;
143
- run_id?: string;
144
- custom_run_config?: Record<string, any>;
145
- }) {
146
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
147
- const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(tenant_id, assistant_id);
148
- const { message, ...rest } = input;
149
- let messages: BaseMessage[] = [];
150
- if (!command) {
151
- const humanMessage = new HumanMessage(message);
152
- messages = [humanMessage];
153
- }
154
-
155
- // Get ChunkBuffer instance
156
- const chunkBuffer = getOrCreateChunkBuffer();
157
-
158
- // Get runConfig from agent config and merge with custom_run_config
159
- const runConfig = {
160
- ...agentLattice?.config?.runConfig || {},
161
- tenantId: tenant_id,
162
- workspaceId: workspace_id,
163
- projectId: project_id,
164
- ...custom_run_config || {},
165
- assistant_id,
166
-
167
- }
168
-
169
- try {
170
- if (!runnable_agent) {
171
- throw new Error(`Agent ${assistant_id} not found`);
172
- }
173
- const agentStream = await (runnable_agent as any).stream(
174
- command
175
- ? new Command(command)
176
- : {
177
- ...rest,
178
- messages,
179
- "x-tenant-id": tenant_id,
180
- },
181
-
182
- {
183
- context: {
184
- runConfig
185
- },
186
- configurable: {
187
- thread_id: thread_id,
188
- run_id: run_id || v4(),
189
- "x-tenant-id": tenant_id,
190
- "x-workspace-id": workspace_id,
191
- "x-project-id": project_id,
192
- "x-request-id": run_id,
193
- "x-thread-id": thread_id,
194
- "x-assistant-id": assistant_id,
195
- runConfig, // Inject runConfig for tools to access
196
- },
197
- streamMode: ["updates", "messages"],
198
- subgraphs: false,
199
- recursionLimit: 200,
200
- }
201
- );
202
-
203
- // 创建一个可迭代的 ReadableStream with ChunkBuffer integration
204
- return {
205
- [Symbol.asyncIterator]: async function* () {
206
- try {
207
- for await (const chunk of agentStream) {
208
- let data;
209
- let chunkContent = "";
210
-
211
- if (chunk[0] === "updates") {
212
- const update = chunk[1];
213
- const values = Object.values(update);
214
- const messages = (values[0] as any)?.messages;
215
- if (messages?.[0]?.tool_call_id) {
216
- data = messages[0].toDict();
217
- }
218
- } else if (chunk[0] === "messages") {
219
- const messages = chunk[1];
220
- // console.log(messages);
221
- data = messages?.[0]?.toDict();
222
- }
223
-
224
- if ((chunk?.[1] as any)?.__interrupt__) {
225
- //data = chunk?.[1]?.[0]?.toDict();
226
- // 原有的中断消息处理
227
- data = {
228
- type: "interrupt",
229
- id: (chunk?.[1] as any)?.__interrupt__[0].id,
230
- data: { content: (chunk?.[1] as any)?.__interrupt__[0].value },
231
- };
232
- }
233
-
234
- if (data) {
235
- //console.log(data);
236
- if (data.type !== "interrupt") {
237
- await chunkBuffer.addChunk(thread_id, data);
238
- }
239
- yield data;
240
- }
241
- }
242
-
243
- // Mark thread as completed when streaming finishes successfully
244
- await chunkBuffer.completeThread(thread_id);
245
- } catch (error) {
246
- console.error("Stream error:", error);
247
- // Mark thread as aborted on error
248
- await chunkBuffer.abortThread(thread_id);
249
- throw error;
250
- }
251
- },
252
- };
253
- } catch (error) {
254
- // Mark thread as aborted on initialization error
255
- await chunkBuffer.abortThread(thread_id);
256
- throw error;
257
- }
258
- }
259
-
260
- export async function agent_state({
261
- assistant_id,
262
- thread_id,
263
- tenant_id,
264
- }: {
265
- assistant_id: string;
266
- thread_id: string;
267
- tenant_id: string;
268
- }) {
269
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
270
- if (!runnable_agent) {
271
- throw new Error(`Agent ${assistant_id} not found`);
272
- }
273
- const state = await runnable_agent.getState({
274
- configurable: { thread_id: thread_id, subgraphs: false },
275
- });
276
- return state;
277
- }
278
-
279
- export async function agent_messages({
280
- thread_id,
281
- tenant_id,
282
- assistant_id,
283
- }: {
284
- assistant_id: string;
285
- thread_id: string;
286
- tenant_id: string;
287
- }) {
288
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
289
- if (!runnable_agent) {
290
- throw new Error(`Agent ${assistant_id} not found`);
291
- }
292
- const state = await runnable_agent.getState({
293
- configurable: { thread_id: thread_id, subgraphs: false },
294
- });
295
-
296
- const messages = state.values.messages || [];
297
- const filteredMessages = filterMessages(messages, {
298
- includeTypes: ["ai", "human", "tool"], //["human", "ai", "tool"],
299
- });
300
-
301
- // console.log(filteredMessages);
302
-
303
- let messagesArray = filteredMessages.map((message: BaseMessage) => ({
304
- id: message.id,
305
- role: message.getType(),
306
- content: message.content,
307
- ...message.lc_kwargs,
308
- }));
309
-
310
- // const action_messages = state.tasks.flatMap((task) => {
311
- // return task.interrupts.map((interrupt) => {
312
- // return {
313
- // role: "ai",
314
- // content: interrupt.value,
315
- // type: "action",
316
- // };
317
- // });
318
- // });
319
-
320
- const new_messages = messagesArray;
321
- // console.log(messagesArray);
322
-
323
- return new_messages;
324
- }
325
-
326
- export async function draw_graph(assistant_id: string, tenant_id: string) {
327
- const runnable_agent = await getAgentClient(tenant_id, assistant_id);
328
- if (!runnable_agent) {
329
- throw new Error(`Agent ${assistant_id} not found`);
330
- }
331
- const drawableGraph = await runnable_agent.getGraphAsync();
332
- const image = await drawableGraph.drawMermaid();
333
- return image;
334
- }
335
-
336
- /**
337
- * Resume streaming from a known position
338
- * Creates an async iterator that yields new chunks as they arrive
339
- *
340
- * @param thread_id - Thread identifier
341
- * @param message_id - Message identifier (usually run_id)
342
- * @param known_content - Content already received (used to find resume position)
343
- * @param poll_interval - Polling interval in milliseconds (default: 100ms)
344
- */
345
- export async function resume_stream({
346
- thread_id,
347
- message_id,
348
- known_content,
349
- poll_interval = 100,
350
- }: {
351
- thread_id: string;
352
- message_id: string;
353
- known_content: string;
354
- poll_interval?: number;
355
- }) {
356
- const chunkBuffer = getOrCreateChunkBuffer();
357
-
358
- const stream = await chunkBuffer.getNewChunksSinceContentIterator(
359
- thread_id,
360
- message_id,
361
- known_content
362
- );
363
- return {
364
- [Symbol.asyncIterator]: async function* () {
365
- try {
366
- for await (const chunk of stream) {
367
- yield chunk;
368
- }
369
- } catch (error) {
370
- console.error("Resume stream error:", error);
371
- throw error;
372
- }
373
- },
374
- };
375
- }