@langgraph-js/pure-graph 3.1.2 → 3.2.2
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 +128 -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-1sAx_j1E.js → checkpoint-CY59Lr2q.js} +79 -36
- package/dist/checkpoint-CY59Lr2q.js.map +1 -0
- package/dist/{createEndpoint-D1nfguxg.js → createEndpoint-vMmFiMSz.js} +20 -5
- package/dist/createEndpoint-vMmFiMSz.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-Cu_nO_wt.js → queue-CUe5TDP1.js} +120 -16
- package/dist/queue-CUe5TDP1.js.map +1 -0
- package/dist/remote/index.js +1 -1
- package/dist/shallow-checkpoint-ImbLxYNR.js +466 -0
- package/dist/shallow-checkpoint-ImbLxYNR.js.map +1 -0
- package/dist/{sqlite-adapter-BKOLSdoL.js → sqlite-adapter-CJXgit1j.js} +25 -12
- package/dist/sqlite-adapter-CJXgit1j.js.map +1 -0
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/kysely/sqlite-adapter.d.ts +7 -0
- package/dist/storage/memory/queue.d.ts +6 -0
- package/dist/storage/redis/queue.d.ts +14 -1
- package/dist/storage/sqlite/shallow-checkpoint.d.ts +59 -0
- package/dist/{stream-CsqWsCjt.js → stream-jYlUzTZO.js} +199 -64
- package/dist/stream-jYlUzTZO.js.map +1 -0
- package/package.json +2 -1
- package/dist/checkpoint-1sAx_j1E.js.map +0 -1
- package/dist/createEndpoint-D1nfguxg.js.map +0 -1
- package/dist/queue-Cu_nO_wt.js.map +0 -1
- package/dist/sqlite-adapter-BKOLSdoL.js.map +0 -1
- package/dist/stream-CsqWsCjt.js.map +0 -1
|
@@ -5,6 +5,7 @@ import { EventEmitter } from 'eventemitter3';
|
|
|
5
5
|
import { load } from '@langchain/core/load';
|
|
6
6
|
import { v7 } from 'uuid';
|
|
7
7
|
import { BaseCheckpointSaver, TASKS, maxChannelVersion, getCheckpointId, copyCheckpoint, uuid6, WRITES_IDX_MAP } from '@langchain/langgraph-checkpoint';
|
|
8
|
+
import 'kysely';
|
|
8
9
|
|
|
9
10
|
const getLangGraphCommand = (command) => {
|
|
10
11
|
let goto = command.goto != null && !Array.isArray(command.goto) ? [command.goto] : command.goto;
|
|
@@ -320,11 +321,7 @@ class StreamQueueManager {
|
|
|
320
321
|
* @param id 队列 ID / Queue ID
|
|
321
322
|
*/
|
|
322
323
|
async cancelQueue(id) {
|
|
323
|
-
|
|
324
|
-
if (queue) {
|
|
325
|
-
await queue.cancel();
|
|
326
|
-
this.removeQueue(id);
|
|
327
|
-
}
|
|
324
|
+
await this.removeQueue(id);
|
|
328
325
|
}
|
|
329
326
|
/**
|
|
330
327
|
* 向指定 id 的队列推送数据
|
|
@@ -369,10 +366,32 @@ class StreamQueueManager {
|
|
|
369
366
|
* @param id 队列 ID / Queue ID
|
|
370
367
|
* @returns 是否成功删除 / Whether successfully deleted
|
|
371
368
|
*/
|
|
372
|
-
removeQueue(id) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
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);
|
|
376
395
|
}
|
|
377
396
|
/**
|
|
378
397
|
* 获取所有队列的 ID
|
|
@@ -447,15 +466,29 @@ class KyselyThreadsManager {
|
|
|
447
466
|
}
|
|
448
467
|
async create(payload) {
|
|
449
468
|
const threadId = payload?.threadId || v7();
|
|
469
|
+
const now = /* @__PURE__ */ new Date();
|
|
470
|
+
const metadata = payload?.metadata || {};
|
|
471
|
+
const interrupts = {};
|
|
450
472
|
if (payload?.ifExists === "raise") {
|
|
451
473
|
const existing = await this.db.selectFrom("threads").select("thread_id").where("thread_id", "=", threadId).executeTakeFirst();
|
|
452
474
|
if (existing) {
|
|
453
475
|
throw new Error(`Thread with ID ${threadId} already exists.`);
|
|
454
476
|
}
|
|
455
477
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
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
|
+
}
|
|
459
492
|
await this.db.insertInto("threads").values({
|
|
460
493
|
thread_id: threadId,
|
|
461
494
|
created_at: this.adapter.dateToDb(now),
|
|
@@ -595,10 +628,17 @@ class KyselyThreadsManager {
|
|
|
595
628
|
if (targetThread.status === "busy") {
|
|
596
629
|
throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
|
|
597
630
|
}
|
|
598
|
-
if (!targetThread.metadata?.graph_id) {
|
|
599
|
-
throw new Error(`Thread with ID ${threadId} has no graph_id.`);
|
|
600
|
-
}
|
|
601
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
|
+
}
|
|
602
642
|
const config = {
|
|
603
643
|
configurable: {
|
|
604
644
|
thread_id: threadId,
|
|
@@ -1145,13 +1185,19 @@ class StreamErrorEventMessage extends EventMessage {
|
|
|
1145
1185
|
|
|
1146
1186
|
class MemoryStreamQueue extends BaseStreamQueue {
|
|
1147
1187
|
data = [];
|
|
1188
|
+
activeGenerators = /* @__PURE__ */ new Set();
|
|
1189
|
+
isDestroyed = false;
|
|
1148
1190
|
async push(item) {
|
|
1191
|
+
if (this.isDestroyed) return;
|
|
1149
1192
|
const data = this.compressMessages ? await this.encodeData(item) : item;
|
|
1150
1193
|
this.data.push(data);
|
|
1151
1194
|
this.emit("dataChange", data);
|
|
1152
1195
|
}
|
|
1153
1196
|
onDataChange(listener) {
|
|
1197
|
+
if (this.isDestroyed) return () => {
|
|
1198
|
+
};
|
|
1154
1199
|
this.on("dataChange", async (item) => {
|
|
1200
|
+
if (this.isDestroyed) return;
|
|
1155
1201
|
listener(this.compressMessages ? await this.decodeData(item) : item);
|
|
1156
1202
|
});
|
|
1157
1203
|
return () => this.off("dataChange", listener);
|
|
@@ -1160,16 +1206,27 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1160
1206
|
* 异步生成器:支持 for await...of 方式消费队列数据
|
|
1161
1207
|
*/
|
|
1162
1208
|
async *onDataReceive() {
|
|
1163
|
-
|
|
1209
|
+
if (this.isDestroyed) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const localAbortController = new AbortController();
|
|
1213
|
+
this.activeGenerators.add(localAbortController);
|
|
1214
|
+
let localQueue = [];
|
|
1164
1215
|
let pendingResolve = null;
|
|
1165
1216
|
let isStreamEnded = false;
|
|
1166
1217
|
let isCleanupDone = false;
|
|
1218
|
+
let endTimeoutId = null;
|
|
1167
1219
|
const handleData = async (item) => {
|
|
1220
|
+
if (isCleanupDone || localAbortController.signal.aborted) return;
|
|
1168
1221
|
try {
|
|
1169
1222
|
const data = this.compressMessages ? await this.decodeData(item) : item;
|
|
1170
|
-
|
|
1223
|
+
localQueue.push(data);
|
|
1171
1224
|
if (data.event === "__stream_end__" || data.event === "__stream_error__" || data.event === "__stream_cancel__") {
|
|
1172
|
-
|
|
1225
|
+
if (endTimeoutId) {
|
|
1226
|
+
clearTimeout(endTimeoutId);
|
|
1227
|
+
endTimeoutId = null;
|
|
1228
|
+
}
|
|
1229
|
+
endTimeoutId = setTimeout(() => {
|
|
1173
1230
|
isStreamEnded = true;
|
|
1174
1231
|
if (pendingResolve) {
|
|
1175
1232
|
pendingResolve();
|
|
@@ -1177,7 +1234,7 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1177
1234
|
}
|
|
1178
1235
|
}, 300);
|
|
1179
1236
|
if (data.event === "__stream_cancel__") {
|
|
1180
|
-
|
|
1237
|
+
localAbortController.abort("stream cancelled");
|
|
1181
1238
|
}
|
|
1182
1239
|
}
|
|
1183
1240
|
if (pendingResolve) {
|
|
@@ -1200,35 +1257,39 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1200
1257
|
pendingResolve = null;
|
|
1201
1258
|
}
|
|
1202
1259
|
};
|
|
1203
|
-
|
|
1260
|
+
localAbortController.signal.addEventListener("abort", abortHandler);
|
|
1204
1261
|
const cleanup = () => {
|
|
1205
1262
|
if (isCleanupDone) return;
|
|
1206
1263
|
isCleanupDone = true;
|
|
1264
|
+
if (endTimeoutId) {
|
|
1265
|
+
clearTimeout(endTimeoutId);
|
|
1266
|
+
endTimeoutId = null;
|
|
1267
|
+
}
|
|
1207
1268
|
try {
|
|
1208
1269
|
this.off("dataChange", handleData);
|
|
1209
1270
|
} catch (e) {
|
|
1210
|
-
console.error("Error removing dataChange listener:", e);
|
|
1211
1271
|
}
|
|
1212
1272
|
try {
|
|
1213
|
-
|
|
1273
|
+
localAbortController.signal.removeEventListener("abort", abortHandler);
|
|
1214
1274
|
} catch (e) {
|
|
1215
|
-
console.error("Error removing abort listener:", e);
|
|
1216
1275
|
}
|
|
1217
1276
|
if (pendingResolve) {
|
|
1218
1277
|
pendingResolve();
|
|
1219
1278
|
pendingResolve = null;
|
|
1220
1279
|
}
|
|
1280
|
+
localQueue.length = 0;
|
|
1281
|
+
this.activeGenerators.delete(localAbortController);
|
|
1221
1282
|
};
|
|
1222
1283
|
try {
|
|
1223
|
-
if (
|
|
1284
|
+
if (localAbortController.signal.aborted || this.isDestroyed) {
|
|
1224
1285
|
return;
|
|
1225
1286
|
}
|
|
1226
|
-
while (!isStreamEnded && !
|
|
1227
|
-
if (
|
|
1228
|
-
for (const item of
|
|
1287
|
+
while (!isStreamEnded && !localAbortController.signal.aborted && !this.isDestroyed) {
|
|
1288
|
+
if (localQueue.length > 0) {
|
|
1289
|
+
for (const item of localQueue) {
|
|
1229
1290
|
yield item;
|
|
1230
1291
|
}
|
|
1231
|
-
|
|
1292
|
+
localQueue.length = 0;
|
|
1232
1293
|
} else {
|
|
1233
1294
|
await new Promise((resolve) => {
|
|
1234
1295
|
pendingResolve = resolve;
|
|
@@ -1240,17 +1301,29 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1240
1301
|
}
|
|
1241
1302
|
}
|
|
1242
1303
|
async getAll() {
|
|
1304
|
+
if (this.isDestroyed) return [];
|
|
1243
1305
|
return this.compressMessages ? await Promise.all(
|
|
1244
1306
|
this.data.map((i) => this.decodeData(i))
|
|
1245
|
-
) : this.data;
|
|
1307
|
+
) : [...this.data];
|
|
1246
1308
|
}
|
|
1247
1309
|
clear() {
|
|
1248
|
-
this.data =
|
|
1310
|
+
this.data.length = 0;
|
|
1249
1311
|
}
|
|
1250
1312
|
cancelSignal = new AbortController();
|
|
1251
1313
|
async cancel() {
|
|
1252
|
-
|
|
1253
|
-
|
|
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
|
+
}
|
|
1254
1327
|
}
|
|
1255
1328
|
async copyToQueue(toId, ttl) {
|
|
1256
1329
|
const data = this.data.slice();
|
|
@@ -1258,6 +1331,17 @@ class MemoryStreamQueue extends BaseStreamQueue {
|
|
|
1258
1331
|
queue.data = data;
|
|
1259
1332
|
return queue;
|
|
1260
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
|
+
}
|
|
1261
1345
|
}
|
|
1262
1346
|
|
|
1263
1347
|
class MemoryThreadsManager {
|
|
@@ -1599,7 +1683,7 @@ class MemoryThreadsManager {
|
|
|
1599
1683
|
}
|
|
1600
1684
|
|
|
1601
1685
|
const createCheckPointer = async () => {
|
|
1602
|
-
if (process.env.REDIS_URL && process.env.CHECKPOINT_TYPE === "redis" || process.env.CHECKPOINT_TYPE === "shallow/redis") {
|
|
1686
|
+
if (process.env.REDIS_URL && (process.env.CHECKPOINT_TYPE === "redis" || process.env.CHECKPOINT_TYPE === "shallow/redis")) {
|
|
1603
1687
|
if (process.env.CHECKPOINT_TYPE === "redis") {
|
|
1604
1688
|
console.debug("LG | Using redis as checkpoint");
|
|
1605
1689
|
const { RedisSaver } = await import('@langchain/langgraph-checkpoint-redis');
|
|
@@ -1621,9 +1705,15 @@ const createCheckPointer = async () => {
|
|
|
1621
1705
|
return createPGCheckpoint();
|
|
1622
1706
|
}
|
|
1623
1707
|
if (process.env.SQLITE_DATABASE_URI) {
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1708
|
+
if (process.env.CHECKPOINT_TYPE === "sqlite") {
|
|
1709
|
+
console.debug("LG | Using sqlite (full) as checkpoint");
|
|
1710
|
+
const { SqliteSaver } = await import('./checkpoint-CY59Lr2q.js');
|
|
1711
|
+
const db2 = await SqliteSaver.fromConnStringAsync(process.env.SQLITE_DATABASE_URI);
|
|
1712
|
+
return db2;
|
|
1713
|
+
}
|
|
1714
|
+
console.debug("LG | Using shallow sqlite as checkpoint (default)");
|
|
1715
|
+
const { SqliteShallowSaver: SqliteShallowSaver2 } = await import('./shallow-checkpoint-ImbLxYNR.js');
|
|
1716
|
+
const db = await SqliteShallowSaver2.fromConnStringAsync(process.env.SQLITE_DATABASE_URI);
|
|
1627
1717
|
return db;
|
|
1628
1718
|
}
|
|
1629
1719
|
console.log("LG | You are using memory as checkpoint!");
|
|
@@ -1641,7 +1731,7 @@ const createMessageQueue = async () => {
|
|
|
1641
1731
|
let q;
|
|
1642
1732
|
if (process.env.REDIS_URL) {
|
|
1643
1733
|
console.debug("LG | Using redis as stream queue");
|
|
1644
|
-
const { RedisStreamQueue } = await import('./queue-
|
|
1734
|
+
const { RedisStreamQueue } = await import('./queue-CUe5TDP1.js');
|
|
1645
1735
|
q = RedisStreamQueue;
|
|
1646
1736
|
} else {
|
|
1647
1737
|
q = MemoryStreamQueue;
|
|
@@ -1681,7 +1771,7 @@ const createThreadManager = async (config) => {
|
|
|
1681
1771
|
}
|
|
1682
1772
|
if (process.env.SQLITE_DATABASE_URI && config.checkpointer) {
|
|
1683
1773
|
console.debug("LG | Using SQLite ThreadsManager");
|
|
1684
|
-
const { SQLiteAdapter } = await import('./sqlite-adapter-
|
|
1774
|
+
const { SQLiteAdapter } = await import('./sqlite-adapter-CJXgit1j.js');
|
|
1685
1775
|
const database = config.checkpointer.db;
|
|
1686
1776
|
const threadsManager = new KyselyThreadsManager(new SQLiteAdapter(database));
|
|
1687
1777
|
await threadsManager.setup();
|
|
@@ -1727,7 +1817,7 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1727
1817
|
const graph = await options.getGraph(graphId, payload.config, {
|
|
1728
1818
|
checkpointer: payload.temporary ? null : void 0
|
|
1729
1819
|
});
|
|
1730
|
-
const userStreamMode = payload.streamMode
|
|
1820
|
+
const userStreamMode = Array.isArray(payload.streamMode) ? payload.streamMode : payload.streamMode ? [payload.streamMode] : [];
|
|
1731
1821
|
const libStreamMode = /* @__PURE__ */ new Set([
|
|
1732
1822
|
"values",
|
|
1733
1823
|
...userStreamMode.filter((mode) => mode !== "events" && mode !== "messages-tuple")
|
|
@@ -1749,27 +1839,28 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1749
1839
|
...payload.config?.metadata,
|
|
1750
1840
|
run_attempt: options.attempt
|
|
1751
1841
|
};
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
interruptAfter: payload.interruptAfter,
|
|
1756
|
-
interruptBefore: payload.interruptBefore,
|
|
1757
|
-
tags: payload.config?.tags,
|
|
1758
|
-
configurable: payload.config?.configurable,
|
|
1759
|
-
recursionLimit: payload.config?.recursionLimit,
|
|
1760
|
-
subgraphs: payload.streamSubgraphs,
|
|
1761
|
-
metadata,
|
|
1762
|
-
runId: run.run_id,
|
|
1763
|
-
streamMode: [...libStreamMode],
|
|
1764
|
-
signal: queue.cancelSignal.signal
|
|
1765
|
-
}
|
|
1766
|
-
);
|
|
1767
|
-
let sendedMetadataMessage;
|
|
1768
|
-
let messageChunks;
|
|
1842
|
+
let sendedMetadataMessage = null;
|
|
1843
|
+
let messageChunks = null;
|
|
1844
|
+
let eventsIterator = null;
|
|
1769
1845
|
try {
|
|
1770
1846
|
sendedMetadataMessage = /* @__PURE__ */ new Set();
|
|
1771
1847
|
messageChunks = /* @__PURE__ */ new Map();
|
|
1772
|
-
|
|
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) {
|
|
1773
1864
|
let ns = [];
|
|
1774
1865
|
if (event.length === 3) {
|
|
1775
1866
|
ns = event.splice(0, 1);
|
|
@@ -1821,14 +1912,29 @@ async function streamStateWithQueue(threads, run, queue, payload, options) {
|
|
|
1821
1912
|
await queue.push(new EventMessage(getNameWithNs("updates"), updates));
|
|
1822
1913
|
}
|
|
1823
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;
|
|
1824
1924
|
} finally {
|
|
1825
|
-
|
|
1925
|
+
try {
|
|
1926
|
+
await queue.push(new StreamEndEventMessage());
|
|
1927
|
+
} catch (e) {
|
|
1928
|
+
}
|
|
1826
1929
|
if (sendedMetadataMessage) {
|
|
1827
1930
|
sendedMetadataMessage.clear();
|
|
1931
|
+
sendedMetadataMessage = null;
|
|
1828
1932
|
}
|
|
1829
1933
|
if (messageChunks) {
|
|
1830
1934
|
messageChunks.clear();
|
|
1935
|
+
messageChunks = null;
|
|
1831
1936
|
}
|
|
1937
|
+
eventsIterator = null;
|
|
1832
1938
|
}
|
|
1833
1939
|
}
|
|
1834
1940
|
const serialiseAsDict = (obj, indent = 0) => {
|
|
@@ -1849,12 +1955,17 @@ async function* streamState(threads, run, payload, options) {
|
|
|
1849
1955
|
run = await run;
|
|
1850
1956
|
const queueId = run.run_id;
|
|
1851
1957
|
const threadId = run.thread_id;
|
|
1958
|
+
let state = null;
|
|
1959
|
+
let queue = null;
|
|
1960
|
+
let backgroundTask = null;
|
|
1961
|
+
let isCleaningUp = false;
|
|
1852
1962
|
try {
|
|
1853
1963
|
await threads.set(threadId, { status: "busy" });
|
|
1854
1964
|
await threads.updateRun(run.run_id, { status: "running" });
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
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;
|
|
1858
1969
|
if (error.message !== "user cancel this run") console.error("Queue task error:", error);
|
|
1859
1970
|
LangGraphGlobal.globalMessageQueue.pushToQueue(queueId, new StreamErrorEventMessage(error));
|
|
1860
1971
|
});
|
|
@@ -1867,16 +1978,40 @@ async function* streamState(threads, run, payload, options) {
|
|
|
1867
1978
|
await threads.updateRun(run.run_id, { status: "error" });
|
|
1868
1979
|
await threads.set(threadId, { status: "error" });
|
|
1869
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([
|
|
1998
|
+
backgroundTask,
|
|
1999
|
+
new Promise((resolve) => setTimeout(resolve, 1e3))
|
|
2000
|
+
]);
|
|
2001
|
+
} catch (e) {
|
|
2002
|
+
}
|
|
2003
|
+
backgroundTask = null;
|
|
2004
|
+
}
|
|
1870
2005
|
const nowState = await threads.get(threadId);
|
|
1871
2006
|
if (nowState.status === "interrupted") {
|
|
1872
2007
|
await LangGraphGlobal.globalMessageQueue.copyQueue(queueId, threadId, 3e4);
|
|
1873
2008
|
} else {
|
|
1874
2009
|
await threads.set(threadId, { status: "idle", interrupts: {} });
|
|
1875
2010
|
}
|
|
1876
|
-
await LangGraphGlobal.globalMessageQueue.
|
|
1877
|
-
|
|
2011
|
+
await LangGraphGlobal.globalMessageQueue.removeQueue(queueId);
|
|
2012
|
+
queue = null;
|
|
1878
2013
|
}
|
|
1879
2014
|
}
|
|
1880
2015
|
|
|
1881
2016
|
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 };
|
|
1882
|
-
//# sourceMappingURL=stream-
|
|
2017
|
+
//# sourceMappingURL=stream-jYlUzTZO.js.map
|