@langgraph-js/pure-graph 3.2.0 → 3.2.3
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/adapter/fetch/index.js +124 -30
- package/dist/adapter/fetch/index.js.map +1 -1
- package/dist/adapter/fetch/utils.d.ts +13 -3
- package/dist/adapter/nextjs/index.js +1 -1
- package/dist/{checkpoint-C5AFBYE-.js → checkpoint-Due32543.js} +71 -41
- package/dist/checkpoint-Due32543.js.map +1 -0
- package/dist/{createEndpoint-C2KsYHDx.js → createEndpoint-CTPbz_D8.js} +20 -5
- package/dist/createEndpoint-CTPbz_D8.js.map +1 -0
- package/dist/createEndpoint.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/queue/stream_queue.d.ts +3 -1
- package/dist/{queue-DySatFkr.js → queue-DPHwOl26.js} +120 -16
- package/dist/queue-DPHwOl26.js.map +1 -0
- package/dist/remote/index.js +1 -1
- package/dist/{shallow-checkpoint-BEhTdp7z.js → shallow-checkpoint-CHYRdSct.js} +79 -49
- package/dist/shallow-checkpoint-CHYRdSct.js.map +1 -0
- package/dist/{sqlite-adapter-oBA95xba.js → sqlite-adapter-CJXgit1j.js} +7 -12
- package/dist/sqlite-adapter-CJXgit1j.js.map +1 -0
- package/dist/storage/memory/queue.d.ts +6 -0
- package/dist/storage/redis/queue.d.ts +14 -1
- package/dist/{stream-pZfO6Y-p.js → stream-Zt8tbgEj.js} +188 -63
- package/dist/stream-Zt8tbgEj.js.map +1 -0
- package/package.json +2 -1
- package/dist/checkpoint-C5AFBYE-.js.map +0 -1
- package/dist/createEndpoint-C2KsYHDx.js.map +0 -1
- package/dist/queue-DySatFkr.js.map +0 -1
- package/dist/shallow-checkpoint-BEhTdp7z.js.map +0 -1
- package/dist/sqlite-adapter-oBA95xba.js.map +0 -1
- package/dist/stream-pZfO6Y-p.js.map +0 -1
|
@@ -16,7 +16,16 @@ export declare class RedisStreamQueue extends BaseStreamQueue implements BaseStr
|
|
|
16
16
|
cancelSignal: AbortController;
|
|
17
17
|
private lastStreamId;
|
|
18
18
|
private pollInterval;
|
|
19
|
+
private connectionReady;
|
|
19
20
|
constructor(id: string, compressMessages?: boolean, ttl?: number);
|
|
21
|
+
/**
|
|
22
|
+
* 初始化 Redis 连接(使用共享连接池)
|
|
23
|
+
*/
|
|
24
|
+
private initConnection;
|
|
25
|
+
/**
|
|
26
|
+
* 确保连接已建立
|
|
27
|
+
*/
|
|
28
|
+
private ensureConnected;
|
|
20
29
|
/**
|
|
21
30
|
* 推送消息到 Redis Stream 和 List
|
|
22
31
|
* - Stream: 用于实时推送(集群友好)
|
|
@@ -34,7 +43,11 @@ export declare class RedisStreamQueue extends BaseStreamQueue implements BaseStr
|
|
|
34
43
|
/**
|
|
35
44
|
* 清空队列
|
|
36
45
|
*/
|
|
37
|
-
clear(): void
|
|
46
|
+
clear(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* 销毁队列实例,释放 Redis 连接引用
|
|
49
|
+
*/
|
|
50
|
+
destroy(): Promise<void>;
|
|
38
51
|
/**
|
|
39
52
|
* 取消操作
|
|
40
53
|
*/
|
|
@@ -321,11 +321,7 @@ class StreamQueueManager {
|
|
|
321
321
|
* @param id 队列 ID / Queue ID
|
|
322
322
|
*/
|
|
323
323
|
async cancelQueue(id) {
|
|
324
|
-
|
|
325
|
-
if (queue) {
|
|
326
|
-
await queue.cancel();
|
|
327
|
-
this.removeQueue(id);
|
|
328
|
-
}
|
|
324
|
+
await this.removeQueue(id);
|
|
329
325
|
}
|
|
330
326
|
/**
|
|
331
327
|
* 向指定 id 的队列推送数据
|
|
@@ -370,10 +366,32 @@ class StreamQueueManager {
|
|
|
370
366
|
* @param id 队列 ID / Queue ID
|
|
371
367
|
* @returns 是否成功删除 / Whether successfully deleted
|
|
372
368
|
*/
|
|
373
|
-
removeQueue(id) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
369
|
+
async removeQueue(id) {
|
|
370
|
+
const queue = this.queues.get(id);
|
|
371
|
+
if (!queue) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
await queue.cancel();
|
|
376
|
+
} catch (e) {
|
|
377
|
+
console.error("Error cancelling queue:", e);
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
const clearResult = queue.clear();
|
|
381
|
+
if (clearResult instanceof Promise) {
|
|
382
|
+
await clearResult;
|
|
383
|
+
}
|
|
384
|
+
} catch (e) {
|
|
385
|
+
console.error("Error clearing queue:", e);
|
|
386
|
+
}
|
|
387
|
+
if (typeof queue.destroy === "function") {
|
|
388
|
+
try {
|
|
389
|
+
await queue.destroy();
|
|
390
|
+
} catch (e) {
|
|
391
|
+
console.error("Error destroying queue:", e);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return this.queues.delete(id);
|
|
377
395
|
}
|
|
378
396
|
/**
|
|
379
397
|
* 获取所有队列的 ID
|
|
@@ -448,15 +466,29 @@ class KyselyThreadsManager {
|
|
|
448
466
|
}
|
|
449
467
|
async create(payload) {
|
|
450
468
|
const threadId = payload?.threadId || v7();
|
|
469
|
+
const now = /* @__PURE__ */ new Date();
|
|
470
|
+
const metadata = payload?.metadata || {};
|
|
471
|
+
const interrupts = {};
|
|
451
472
|
if (payload?.ifExists === "raise") {
|
|
452
473
|
const existing = await this.db.selectFrom("threads").select("thread_id").where("thread_id", "=", threadId).executeTakeFirst();
|
|
453
474
|
if (existing) {
|
|
454
475
|
throw new Error(`Thread with ID ${threadId} already exists.`);
|
|
455
476
|
}
|
|
456
477
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
478
|
+
if (payload?.ifExists === "do_nothing" && payload?.threadId) {
|
|
479
|
+
const existing = await this.db.selectFrom("threads").selectAll().where("thread_id", "=", threadId).executeTakeFirst();
|
|
480
|
+
if (existing) {
|
|
481
|
+
return {
|
|
482
|
+
thread_id: existing.thread_id,
|
|
483
|
+
created_at: this.adapter.dbToDate(existing.created_at).toISOString(),
|
|
484
|
+
updated_at: this.adapter.dbToDate(existing.updated_at).toISOString(),
|
|
485
|
+
metadata: this.adapter.dbToJson(existing.metadata),
|
|
486
|
+
status: existing.status,
|
|
487
|
+
values: existing.values ? this.adapter.dbToJson(existing.values) : null,
|
|
488
|
+
interrupts: this.adapter.dbToJson(existing.interrupts)
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
460
492
|
await this.db.insertInto("threads").values({
|
|
461
493
|
thread_id: threadId,
|
|
462
494
|
created_at: this.adapter.dateToDb(now),
|
|
@@ -596,10 +628,17 @@ class KyselyThreadsManager {
|
|
|
596
628
|
if (targetThread.status === "busy") {
|
|
597
629
|
throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
|
|
598
630
|
}
|
|
599
|
-
if (!targetThread.metadata?.graph_id) {
|
|
600
|
-
throw new Error(`Thread with ID ${threadId} has no graph_id.`);
|
|
601
|
-
}
|
|
602
631
|
const graphId = targetThread.metadata?.graph_id;
|
|
632
|
+
if (!graphId) {
|
|
633
|
+
await this.set(threadId, {
|
|
634
|
+
values: thread.values ?? null
|
|
635
|
+
});
|
|
636
|
+
return {
|
|
637
|
+
configurable: {
|
|
638
|
+
thread_id: threadId
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
}
|
|
603
642
|
const config = {
|
|
604
643
|
configurable: {
|
|
605
644
|
thread_id: threadId,
|
|
@@ -1146,13 +1185,19 @@ class StreamErrorEventMessage extends EventMessage {
|
|
|
1146
1185
|
|
|
1147
1186
|
class MemoryStreamQueue extends BaseStreamQueue {
|
|
1148
1187
|
data = [];
|
|
1188
|
+
activeGenerators = /* @__PURE__ */ new Set();
|
|
1189
|
+
isDestroyed = false;
|
|
1149
1190
|
async push(item) {
|
|
1191
|
+
if (this.isDestroyed) return;
|
|
1150
1192
|
const data = this.compressMessages ? await this.encodeData(item) : item;
|
|
1151
1193
|
this.data.push(data);
|
|
1152
1194
|
this.emit("dataChange", data);
|
|
1153
1195
|
}
|
|
1154
1196
|
onDataChange(listener) {
|
|
1197
|
+
if (this.isDestroyed) return () => {
|
|
1198
|
+
};
|
|
1155
1199
|
this.on("dataChange", async (item) => {
|
|
1200
|
+
if (this.isDestroyed) return;
|
|
1156
1201
|
listener(this.compressMessages ? await this.decodeData(item) : item);
|
|
1157
1202
|
});
|
|
1158
1203
|
return () => this.off("dataChange", listener);
|
|
@@ -1161,16 +1206,27 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1161
1206
|
* 异步生成器:支持 for await...of 方式消费队列数据
|
|
1162
1207
|
*/
|
|
1163
1208
|
async *onDataReceive() {
|
|
1164
|
-
|
|
1209
|
+
if (this.isDestroyed) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const localAbortController = new AbortController();
|
|
1213
|
+
this.activeGenerators.add(localAbortController);
|
|
1214
|
+
let localQueue = [];
|
|
1165
1215
|
let pendingResolve = null;
|
|
1166
1216
|
let isStreamEnded = false;
|
|
1167
1217
|
let isCleanupDone = false;
|
|
1218
|
+
let endTimeoutId = null;
|
|
1168
1219
|
const handleData = async (item) => {
|
|
1220
|
+
if (isCleanupDone || localAbortController.signal.aborted) return;
|
|
1169
1221
|
try {
|
|
1170
1222
|
const data = this.compressMessages ? await this.decodeData(item) : item;
|
|
1171
|
-
|
|
1223
|
+
localQueue.push(data);
|
|
1172
1224
|
if (data.event === "__stream_end__" || data.event === "__stream_error__" || data.event === "__stream_cancel__") {
|
|
1173
|
-
|
|
1225
|
+
if (endTimeoutId) {
|
|
1226
|
+
clearTimeout(endTimeoutId);
|
|
1227
|
+
endTimeoutId = null;
|
|
1228
|
+
}
|
|
1229
|
+
endTimeoutId = setTimeout(() => {
|
|
1174
1230
|
isStreamEnded = true;
|
|
1175
1231
|
if (pendingResolve) {
|
|
1176
1232
|
pendingResolve();
|
|
@@ -1178,7 +1234,7 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1178
1234
|
}
|
|
1179
1235
|
}, 300);
|
|
1180
1236
|
if (data.event === "__stream_cancel__") {
|
|
1181
|
-
|
|
1237
|
+
localAbortController.abort("stream cancelled");
|
|
1182
1238
|
}
|
|
1183
1239
|
}
|
|
1184
1240
|
if (pendingResolve) {
|
|
@@ -1201,35 +1257,39 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1201
1257
|
pendingResolve = null;
|
|
1202
1258
|
}
|
|
1203
1259
|
};
|
|
1204
|
-
|
|
1260
|
+
localAbortController.signal.addEventListener("abort", abortHandler);
|
|
1205
1261
|
const cleanup = () => {
|
|
1206
1262
|
if (isCleanupDone) return;
|
|
1207
1263
|
isCleanupDone = true;
|
|
1264
|
+
if (endTimeoutId) {
|
|
1265
|
+
clearTimeout(endTimeoutId);
|
|
1266
|
+
endTimeoutId = null;
|
|
1267
|
+
}
|
|
1208
1268
|
try {
|
|
1209
1269
|
this.off("dataChange", handleData);
|
|
1210
1270
|
} catch (e) {
|
|
1211
|
-
console.error("Error removing dataChange listener:", e);
|
|
1212
1271
|
}
|
|
1213
1272
|
try {
|
|
1214
|
-
|
|
1273
|
+
localAbortController.signal.removeEventListener("abort", abortHandler);
|
|
1215
1274
|
} catch (e) {
|
|
1216
|
-
console.error("Error removing abort listener:", e);
|
|
1217
1275
|
}
|
|
1218
1276
|
if (pendingResolve) {
|
|
1219
1277
|
pendingResolve();
|
|
1220
1278
|
pendingResolve = null;
|
|
1221
1279
|
}
|
|
1280
|
+
localQueue.length = 0;
|
|
1281
|
+
this.activeGenerators.delete(localAbortController);
|
|
1222
1282
|
};
|
|
1223
1283
|
try {
|
|
1224
|
-
if (
|
|
1284
|
+
if (localAbortController.signal.aborted || this.isDestroyed) {
|
|
1225
1285
|
return;
|
|
1226
1286
|
}
|
|
1227
|
-
while (!isStreamEnded && !
|
|
1228
|
-
if (
|
|
1229
|
-
for (const item of
|
|
1287
|
+
while (!isStreamEnded && !localAbortController.signal.aborted && !this.isDestroyed) {
|
|
1288
|
+
if (localQueue.length > 0) {
|
|
1289
|
+
for (const item of localQueue) {
|
|
1230
1290
|
yield item;
|
|
1231
1291
|
}
|
|
1232
|
-
|
|
1292
|
+
localQueue.length = 0;
|
|
1233
1293
|
} else {
|
|
1234
1294
|
await new Promise((resolve) => {
|
|
1235
1295
|
pendingResolve = resolve;
|
|
@@ -1241,17 +1301,29 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1241
1301
|
}
|
|
1242
1302
|
}
|
|
1243
1303
|
async getAll() {
|
|
1304
|
+
if (this.isDestroyed) return [];
|
|
1244
1305
|
return this.compressMessages ? await Promise.all(
|
|
1245
1306
|
this.data.map((i) => this.decodeData(i))
|
|
1246
|
-
) : this.data;
|
|
1307
|
+
) : [...this.data];
|
|
1247
1308
|
}
|
|
1248
1309
|
clear() {
|
|
1249
|
-
this.data =
|
|
1310
|
+
this.data.length = 0;
|
|
1250
1311
|
}
|
|
1251
1312
|
cancelSignal = new AbortController();
|
|
1252
1313
|
async cancel() {
|
|
1253
|
-
|
|
1254
|
-
|
|
1314
|
+
for (const controller of this.activeGenerators) {
|
|
1315
|
+
try {
|
|
1316
|
+
controller.abort("user cancel this run");
|
|
1317
|
+
} catch (e) {
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
this.activeGenerators.clear();
|
|
1321
|
+
if (!this.cancelSignal.signal.aborted) {
|
|
1322
|
+
this.cancelSignal.abort("user cancel this run");
|
|
1323
|
+
}
|
|
1324
|
+
if (!this.isDestroyed) {
|
|
1325
|
+
await this.push(new CancelEventMessage());
|
|
1326
|
+
}
|
|
1255
1327
|
}
|
|
1256
1328
|
async copyToQueue(toId, ttl) {
|
|
1257
1329
|
const data = this.data.slice();
|
|
@@ -1259,6 +1331,17 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1259
1331
|
queue.data = data;
|
|
1260
1332
|
return queue;
|
|
1261
1333
|
}
|
|
1334
|
+
/**
|
|
1335
|
+
* 销毁队列,释放所有资源
|
|
1336
|
+
*/
|
|
1337
|
+
async destroy() {
|
|
1338
|
+
if (this.isDestroyed) return;
|
|
1339
|
+
this.isDestroyed = true;
|
|
1340
|
+
await this.cancel();
|
|
1341
|
+
this.clear();
|
|
1342
|
+
this.removeAllListeners();
|
|
1343
|
+
this.activeGenerators.clear();
|
|
1344
|
+
}
|
|
1262
1345
|
}
|
|
1263
1346
|
|
|
1264
1347
|
class MemoryThreadsManager {
|
|
@@ -1624,12 +1707,12 @@ const createCheckPointer = async () => {
|
|
|
1624
1707
|
if (process.env.SQLITE_DATABASE_URI) {
|
|
1625
1708
|
if (process.env.CHECKPOINT_TYPE === "sqlite") {
|
|
1626
1709
|
console.debug("LG | Using sqlite (full) as checkpoint");
|
|
1627
|
-
const { SqliteSaver } = await import('./checkpoint-
|
|
1710
|
+
const { SqliteSaver } = await import('./checkpoint-Due32543.js');
|
|
1628
1711
|
const db2 = await SqliteSaver.fromConnStringAsync(process.env.SQLITE_DATABASE_URI);
|
|
1629
1712
|
return db2;
|
|
1630
1713
|
}
|
|
1631
1714
|
console.debug("LG | Using shallow sqlite as checkpoint (default)");
|
|
1632
|
-
const { SqliteShallowSaver: SqliteShallowSaver2 } = await import('./shallow-checkpoint-
|
|
1715
|
+
const { SqliteShallowSaver: SqliteShallowSaver2 } = await import('./shallow-checkpoint-CHYRdSct.js');
|
|
1633
1716
|
const db = await SqliteShallowSaver2.fromConnStringAsync(process.env.SQLITE_DATABASE_URI);
|
|
1634
1717
|
return db;
|
|
1635
1718
|
}
|
|
@@ -1648,7 +1731,7 @@ const createMessageQueue = async () => {
|
|
|
1648
1731
|
let q;
|
|
1649
1732
|
if (process.env.REDIS_URL) {
|
|
1650
1733
|
console.debug("LG | Using redis as stream queue");
|
|
1651
|
-
const { RedisStreamQueue } = await import('./queue-
|
|
1734
|
+
const { RedisStreamQueue } = await import('./queue-DPHwOl26.js');
|
|
1652
1735
|
q = RedisStreamQueue;
|
|
1653
1736
|
} else {
|
|
1654
1737
|
q = MemoryStreamQueue;
|
|
@@ -1688,7 +1771,7 @@ const createThreadManager = async (config) => {
|
|
|
1688
1771
|
}
|
|
1689
1772
|
if (process.env.SQLITE_DATABASE_URI && config.checkpointer) {
|
|
1690
1773
|
console.debug("LG | Using SQLite ThreadsManager");
|
|
1691
|
-
const { SQLiteAdapter } = await import('./sqlite-adapter-
|
|
1774
|
+
const { SQLiteAdapter } = await import('./sqlite-adapter-CJXgit1j.js');
|
|
1692
1775
|
const database = config.checkpointer.db;
|
|
1693
1776
|
const threadsManager = new KyselyThreadsManager(new SQLiteAdapter(database));
|
|
1694
1777
|
await threadsManager.setup();
|
|
@@ -1734,7 +1817,7 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1734
1817
|
const graph = await options.getGraph(graphId, payload.config, {
|
|
1735
1818
|
checkpointer: payload.temporary ? null : void 0
|
|
1736
1819
|
});
|
|
1737
|
-
const userStreamMode = payload.streamMode
|
|
1820
|
+
const userStreamMode = Array.isArray(payload.streamMode) ? payload.streamMode : payload.streamMode ? [payload.streamMode] : [];
|
|
1738
1821
|
const libStreamMode = /* @__PURE__ */ new Set([
|
|
1739
1822
|
"values",
|
|
1740
1823
|
...userStreamMode.filter((mode) => mode !== "events" && mode !== "messages-tuple")
|
|
@@ -1756,27 +1839,28 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1756
1839
|
...payload.config?.metadata,
|
|
1757
1840
|
run_attempt: options.attempt
|
|
1758
1841
|
};
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
interruptAfter: payload.interruptAfter,
|
|
1763
|
-
interruptBefore: payload.interruptBefore,
|
|
1764
|
-
tags: payload.config?.tags,
|
|
1765
|
-
configurable: payload.config?.configurable,
|
|
1766
|
-
recursionLimit: payload.config?.recursionLimit,
|
|
1767
|
-
subgraphs: payload.streamSubgraphs,
|
|
1768
|
-
metadata,
|
|
1769
|
-
runId: run.run_id,
|
|
1770
|
-
streamMode: [...libStreamMode],
|
|
1771
|
-
signal: queue.cancelSignal.signal
|
|
1772
|
-
}
|
|
1773
|
-
);
|
|
1774
|
-
let sendedMetadataMessage;
|
|
1775
|
-
let messageChunks;
|
|
1842
|
+
let sendedMetadataMessage = null;
|
|
1843
|
+
let messageChunks = null;
|
|
1844
|
+
let eventsIterator = null;
|
|
1776
1845
|
try {
|
|
1777
1846
|
sendedMetadataMessage = /* @__PURE__ */ new Set();
|
|
1778
1847
|
messageChunks = /* @__PURE__ */ new Map();
|
|
1779
|
-
|
|
1848
|
+
eventsIterator = await graph.stream(
|
|
1849
|
+
payload.command != null ? getLangGraphCommand(payload.command) : payload.input ?? null,
|
|
1850
|
+
{
|
|
1851
|
+
interruptAfter: payload.interruptAfter,
|
|
1852
|
+
interruptBefore: payload.interruptBefore,
|
|
1853
|
+
tags: payload.config?.tags,
|
|
1854
|
+
configurable: payload.config?.configurable,
|
|
1855
|
+
recursionLimit: payload.config?.recursionLimit,
|
|
1856
|
+
subgraphs: payload.streamSubgraphs,
|
|
1857
|
+
metadata,
|
|
1858
|
+
runId: run.run_id,
|
|
1859
|
+
streamMode: [...libStreamMode],
|
|
1860
|
+
signal: queue.cancelSignal.signal
|
|
1861
|
+
}
|
|
1862
|
+
);
|
|
1863
|
+
for await (const event of eventsIterator) {
|
|
1780
1864
|
let ns = [];
|
|
1781
1865
|
if (event.length === 3) {
|
|
1782
1866
|
ns = event.splice(0, 1);
|
|
@@ -1788,8 +1872,8 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1788
1872
|
};
|
|
1789
1873
|
if (event[0] === "values") {
|
|
1790
1874
|
const value = event[1];
|
|
1791
|
-
await queue.push(new EventMessage(getNameWithNs("values"), value));
|
|
1792
1875
|
if (getNameWithNs("values") === "values") {
|
|
1876
|
+
await queue.push(new EventMessage(getNameWithNs("values"), value));
|
|
1793
1877
|
if (value?.__interrupt__) {
|
|
1794
1878
|
await threads.set(run.thread_id, {
|
|
1795
1879
|
status: "interrupted",
|
|
@@ -1828,14 +1912,29 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1828
1912
|
await queue.push(new EventMessage(getNameWithNs("updates"), updates));
|
|
1829
1913
|
}
|
|
1830
1914
|
}
|
|
1915
|
+
} catch (error) {
|
|
1916
|
+
if (!(error instanceof Error && error.message?.includes("cancel"))) {
|
|
1917
|
+
console.error("streamStateWithQueue error:", error);
|
|
1918
|
+
try {
|
|
1919
|
+
await queue.push(new StreamErrorEventMessage(error));
|
|
1920
|
+
} catch (e) {
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
throw error;
|
|
1831
1924
|
} finally {
|
|
1832
|
-
|
|
1925
|
+
try {
|
|
1926
|
+
await queue.push(new StreamEndEventMessage());
|
|
1927
|
+
} catch (e) {
|
|
1928
|
+
}
|
|
1833
1929
|
if (sendedMetadataMessage) {
|
|
1834
1930
|
sendedMetadataMessage.clear();
|
|
1931
|
+
sendedMetadataMessage = null;
|
|
1835
1932
|
}
|
|
1836
1933
|
if (messageChunks) {
|
|
1837
1934
|
messageChunks.clear();
|
|
1935
|
+
messageChunks = null;
|
|
1838
1936
|
}
|
|
1937
|
+
eventsIterator = null;
|
|
1839
1938
|
}
|
|
1840
1939
|
}
|
|
1841
1940
|
const serialiseAsDict = (obj, indent = 0) => {
|
|
@@ -1856,12 +1955,17 @@ async function* streamState(threads, run, payload, options) {
|
|
|
1856
1955
|
run = await run;
|
|
1857
1956
|
const queueId = run.run_id;
|
|
1858
1957
|
const threadId = run.thread_id;
|
|
1958
|
+
let state = null;
|
|
1959
|
+
let queue = null;
|
|
1960
|
+
let backgroundTask = null;
|
|
1961
|
+
let isCleaningUp = false;
|
|
1859
1962
|
try {
|
|
1860
1963
|
await threads.set(threadId, { status: "busy" });
|
|
1861
1964
|
await threads.updateRun(run.run_id, { status: "running" });
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
streamStateWithQueue(threads, run, queue, payload, options).catch((error) => {
|
|
1965
|
+
queue = LangGraphGlobal.globalMessageQueue.createQueue(queueId);
|
|
1966
|
+
state = queue.onDataReceive();
|
|
1967
|
+
backgroundTask = streamStateWithQueue(threads, run, queue, payload, options).catch((error) => {
|
|
1968
|
+
if (isCleaningUp) return;
|
|
1865
1969
|
if (error.message !== "user cancel this run") console.error("Queue task error:", error);
|
|
1866
1970
|
LangGraphGlobal.globalMessageQueue.pushToQueue(queueId, new StreamErrorEventMessage(error));
|
|
1867
1971
|
});
|
|
@@ -1874,16 +1978,37 @@ async function* streamState(threads, run, payload, options) {
|
|
|
1874
1978
|
await threads.updateRun(run.run_id, { status: "error" });
|
|
1875
1979
|
await threads.set(threadId, { status: "error" });
|
|
1876
1980
|
} finally {
|
|
1981
|
+
isCleaningUp = true;
|
|
1982
|
+
if (state) {
|
|
1983
|
+
try {
|
|
1984
|
+
await state.return(void 0);
|
|
1985
|
+
} catch (e) {
|
|
1986
|
+
}
|
|
1987
|
+
state = null;
|
|
1988
|
+
}
|
|
1989
|
+
if (queue && !queue.cancelSignal.signal.aborted) {
|
|
1990
|
+
try {
|
|
1991
|
+
queue.cancelSignal.abort("Stream consumer disconnected");
|
|
1992
|
+
} catch (e) {
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
if (backgroundTask) {
|
|
1996
|
+
try {
|
|
1997
|
+
await Promise.race([backgroundTask, new Promise((resolve) => setTimeout(resolve, 1e3))]);
|
|
1998
|
+
} catch (e) {
|
|
1999
|
+
}
|
|
2000
|
+
backgroundTask = null;
|
|
2001
|
+
}
|
|
1877
2002
|
const nowState = await threads.get(threadId);
|
|
1878
2003
|
if (nowState.status === "interrupted") {
|
|
1879
2004
|
await LangGraphGlobal.globalMessageQueue.copyQueue(queueId, threadId, 3e4);
|
|
1880
2005
|
} else {
|
|
1881
2006
|
await threads.set(threadId, { status: "idle", interrupts: {} });
|
|
1882
2007
|
}
|
|
1883
|
-
await LangGraphGlobal.globalMessageQueue.
|
|
1884
|
-
|
|
2008
|
+
await LangGraphGlobal.globalMessageQueue.removeQueue(queueId);
|
|
2009
|
+
queue = null;
|
|
1885
2010
|
}
|
|
1886
2011
|
}
|
|
1887
2012
|
|
|
1888
2013
|
export { BaseStreamQueue as B, CancelEventMessage as C, GRAPHS as G, KyselyThreadsManager as K, LangGraphGlobal as L, streamState as a, getGraph as g, registerGraph as r, serialiseAsDict as s };
|
|
1889
|
-
//# sourceMappingURL=stream-
|
|
2014
|
+
//# sourceMappingURL=stream-Zt8tbgEj.js.map
|