@langgraph-js/pure-graph 3.2.5 → 3.3.0
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 +4 -3
- package/dist/adapter/fetch/index.js.map +1 -1
- package/dist/adapter/nextjs/index.js +1 -1
- package/dist/adapter/zod.d.ts +1 -0
- package/dist/{createEndpoint-Cz6LSXYH.js → createEndpoint-D27R5Yhn.js} +53 -11
- package/dist/createEndpoint-D27R5Yhn.js.map +1 -0
- package/dist/createEndpoint.d.ts +2 -1
- package/dist/global.d.ts +15 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/{queue-swFecaQs.js → queue-CS3K-zd_.js} +2 -2
- package/dist/{queue-swFecaQs.js.map → queue-CS3K-zd_.js.map} +1 -1
- package/dist/remote/index.js +1 -1
- package/dist/{remote-threads-CrG03ZS7.js → remote-threads-UpSB8X-e.js} +19 -1
- package/dist/remote-threads-UpSB8X-e.js.map +1 -0
- package/dist/{sqlite-adapter-CJXgit1j.js → sqlite-adapter-D5g0LbUq.js} +15 -2
- package/dist/sqlite-adapter-D5g0LbUq.js.map +1 -0
- package/dist/storage/kysely/remote-threads.d.ts +4 -0
- package/dist/storage/kysely/sqlite-adapter.d.ts +5 -0
- package/dist/storage/kysely/threads.d.ts +3 -2
- package/dist/storage/kysely/types.d.ts +1 -0
- package/dist/storage/memory/threads.d.ts +4 -3
- package/dist/{stream-Dm5628RW.js → stream-Bleed1lp.js} +104 -13
- package/dist/stream-Bleed1lp.js.map +1 -0
- package/dist/threads/index.d.ts +9 -3
- package/dist/types.d.ts +10 -2
- package/dist/utils/titleGenerator.d.ts +20 -0
- package/dist/utils/titleGeneratorHelper.d.ts +17 -0
- package/package.json +1 -1
- package/dist/createEndpoint-Cz6LSXYH.js.map +0 -1
- package/dist/remote-threads-CrG03ZS7.js.map +0 -1
- package/dist/sqlite-adapter-CJXgit1j.js.map +0 -1
- package/dist/stream-Dm5628RW.js.map +0 -1
|
@@ -486,7 +486,8 @@ class KyselyThreadsManager {
|
|
|
486
486
|
metadata: this.adapter.dbToJson(existing.metadata),
|
|
487
487
|
status: existing.status,
|
|
488
488
|
values: existing.values ? this.adapter.dbToJson(existing.values) : null,
|
|
489
|
-
interrupts: this.adapter.dbToJson(existing.interrupts)
|
|
489
|
+
interrupts: this.adapter.dbToJson(existing.interrupts),
|
|
490
|
+
title: existing.title
|
|
490
491
|
};
|
|
491
492
|
}
|
|
492
493
|
}
|
|
@@ -507,7 +508,8 @@ class KyselyThreadsManager {
|
|
|
507
508
|
metadata,
|
|
508
509
|
status: "idle",
|
|
509
510
|
values: null,
|
|
510
|
-
interrupts
|
|
511
|
+
interrupts,
|
|
512
|
+
title: null
|
|
511
513
|
};
|
|
512
514
|
}
|
|
513
515
|
async search(query) {
|
|
@@ -516,7 +518,7 @@ class KyselyThreadsManager {
|
|
|
516
518
|
if (query?.select) {
|
|
517
519
|
selectedFields = new Set(query.select);
|
|
518
520
|
} else if (query?.withoutDetails) {
|
|
519
|
-
selectedFields = /* @__PURE__ */ new Set(["thread_id", "created_at", "updated_at", "metadata", "status"]);
|
|
521
|
+
selectedFields = /* @__PURE__ */ new Set(["thread_id", "created_at", "updated_at", "metadata", "status", "title"]);
|
|
520
522
|
} else {
|
|
521
523
|
selectedFields = /* @__PURE__ */ new Set([
|
|
522
524
|
"thread_id",
|
|
@@ -525,7 +527,8 @@ class KyselyThreadsManager {
|
|
|
525
527
|
"metadata",
|
|
526
528
|
"status",
|
|
527
529
|
"values",
|
|
528
|
-
"interrupts"
|
|
530
|
+
"interrupts",
|
|
531
|
+
"title"
|
|
529
532
|
]);
|
|
530
533
|
}
|
|
531
534
|
const selections = [];
|
|
@@ -536,6 +539,7 @@ class KyselyThreadsManager {
|
|
|
536
539
|
if (selectedFields.has("status")) selections.push("status");
|
|
537
540
|
if (selectedFields.has("values")) selections.push("values");
|
|
538
541
|
if (selectedFields.has("interrupts")) selections.push("interrupts");
|
|
542
|
+
if (selectedFields.has("title")) selections.push("title");
|
|
539
543
|
if (selections.length > 0) {
|
|
540
544
|
queryBuilder = queryBuilder.select(selections);
|
|
541
545
|
} else {
|
|
@@ -579,6 +583,7 @@ class KyselyThreadsManager {
|
|
|
579
583
|
if (selectedFields.has("values"))
|
|
580
584
|
result.values = row.values ? this.adapter.dbToJson(row.values) : null;
|
|
581
585
|
if (selectedFields.has("interrupts")) result.interrupts = this.adapter.dbToJson(row.interrupts);
|
|
586
|
+
if (selectedFields.has("title")) result.title = row.title;
|
|
582
587
|
return result;
|
|
583
588
|
});
|
|
584
589
|
}
|
|
@@ -595,7 +600,8 @@ class KyselyThreadsManager {
|
|
|
595
600
|
metadata: this.adapter.dbToJson(row.metadata),
|
|
596
601
|
status: row.status,
|
|
597
602
|
values: row.values ? this.adapter.dbToJson(row.values) : null,
|
|
598
|
-
interrupts: this.adapter.dbToJson(row.interrupts)
|
|
603
|
+
interrupts: this.adapter.dbToJson(row.interrupts),
|
|
604
|
+
title: row.title
|
|
599
605
|
};
|
|
600
606
|
}
|
|
601
607
|
async set(threadId, thread) {
|
|
@@ -618,6 +624,9 @@ class KyselyThreadsManager {
|
|
|
618
624
|
if (thread.interrupts !== void 0) {
|
|
619
625
|
updates.interrupts = this.adapter.jsonToDb(thread.interrupts);
|
|
620
626
|
}
|
|
627
|
+
if (thread.title !== void 0) {
|
|
628
|
+
updates.title = thread.title;
|
|
629
|
+
}
|
|
621
630
|
await this.db.updateTable("threads").set(updates).where("thread_id", "=", threadId).execute();
|
|
622
631
|
}
|
|
623
632
|
async delete(threadId) {
|
|
@@ -747,6 +756,9 @@ class KyselyThreadsManager {
|
|
|
747
756
|
if (updates.interrupts !== void 0) {
|
|
748
757
|
patchUpdates.interrupts = this.adapter.jsonToDb(updates.interrupts);
|
|
749
758
|
}
|
|
759
|
+
if (updates.title !== void 0) {
|
|
760
|
+
patchUpdates.title = updates.title;
|
|
761
|
+
}
|
|
750
762
|
await this.db.updateTable("threads").set(patchUpdates).where("thread_id", "=", threadId).execute();
|
|
751
763
|
return await this.get(threadId);
|
|
752
764
|
}
|
|
@@ -828,7 +840,8 @@ class KyselyThreadsManager {
|
|
|
828
840
|
metadata: this.adapter.jsonToDb(originalThread.metadata),
|
|
829
841
|
status: originalThread.status,
|
|
830
842
|
values: originalThread.values ? this.adapter.jsonToDb(originalThread.values) : null,
|
|
831
|
-
interrupts: this.adapter.jsonToDb(originalThread.interrupts)
|
|
843
|
+
interrupts: this.adapter.jsonToDb(originalThread.interrupts),
|
|
844
|
+
title: originalThread.title
|
|
832
845
|
}).execute();
|
|
833
846
|
const checkpoints = await this.db.selectFrom("checkpoints").selectAll().where("thread_id", "=", threadId).orderBy("created_at", "asc").execute();
|
|
834
847
|
for (const cp of checkpoints) {
|
|
@@ -861,6 +874,13 @@ class KyselyThreadsManager {
|
|
|
861
874
|
metadata: this.adapter.jsonToDb(metadata || {})
|
|
862
875
|
}).execute();
|
|
863
876
|
}
|
|
877
|
+
async setTitleIfNull(threadId, title) {
|
|
878
|
+
const result = await this.db.updateTable("threads").set({
|
|
879
|
+
title,
|
|
880
|
+
updated_at: this.adapter.dateToDb(/* @__PURE__ */ new Date())
|
|
881
|
+
}).where("thread_id", "=", threadId).where("title", "is", null).executeTakeFirst();
|
|
882
|
+
return result.numUpdatedRows > 0n;
|
|
883
|
+
}
|
|
864
884
|
}
|
|
865
885
|
|
|
866
886
|
function _parseShallowKey(key) {
|
|
@@ -1366,7 +1386,8 @@ class MemoryThreadsManager {
|
|
|
1366
1386
|
metadata: payload?.metadata || {},
|
|
1367
1387
|
status: "idle",
|
|
1368
1388
|
values: null,
|
|
1369
|
-
interrupts: {}
|
|
1389
|
+
interrupts: {},
|
|
1390
|
+
title: null
|
|
1370
1391
|
};
|
|
1371
1392
|
this.checkpoints.set(threadId, []);
|
|
1372
1393
|
this.threads.push(thread);
|
|
@@ -1444,7 +1465,8 @@ class MemoryThreadsManager {
|
|
|
1444
1465
|
"metadata",
|
|
1445
1466
|
"status",
|
|
1446
1467
|
"values",
|
|
1447
|
-
"interrupts"
|
|
1468
|
+
"interrupts",
|
|
1469
|
+
"title"
|
|
1448
1470
|
]);
|
|
1449
1471
|
}
|
|
1450
1472
|
if (includeFields.has("thread_id")) result.thread_id = i.thread_id;
|
|
@@ -1454,6 +1476,7 @@ class MemoryThreadsManager {
|
|
|
1454
1476
|
if (includeFields.has("status")) result.status = i.status;
|
|
1455
1477
|
if (includeFields.has("values")) result.values = i.values;
|
|
1456
1478
|
if (includeFields.has("interrupts")) result.interrupts = i.interrupts;
|
|
1479
|
+
if (includeFields.has("title")) result.title = i.title;
|
|
1457
1480
|
return result;
|
|
1458
1481
|
});
|
|
1459
1482
|
}
|
|
@@ -1684,6 +1707,21 @@ class MemoryThreadsManager {
|
|
|
1684
1707
|
checkpoints.push(checkpoint);
|
|
1685
1708
|
this.checkpoints.set(threadId, checkpoints);
|
|
1686
1709
|
}
|
|
1710
|
+
async setTitleIfNull(threadId, title) {
|
|
1711
|
+
const index = this.threads.findIndex((t) => t.thread_id === threadId);
|
|
1712
|
+
if (index === -1) {
|
|
1713
|
+
throw new Error(`Thread with ID ${threadId} not found.`);
|
|
1714
|
+
}
|
|
1715
|
+
if (this.threads[index].title === null) {
|
|
1716
|
+
this.threads[index] = {
|
|
1717
|
+
...this.threads[index],
|
|
1718
|
+
title,
|
|
1719
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1720
|
+
};
|
|
1721
|
+
return true;
|
|
1722
|
+
}
|
|
1723
|
+
return false;
|
|
1724
|
+
}
|
|
1687
1725
|
}
|
|
1688
1726
|
|
|
1689
1727
|
const createCheckPointer = async () => {
|
|
@@ -1735,7 +1773,7 @@ const createMessageQueue = async () => {
|
|
|
1735
1773
|
let q;
|
|
1736
1774
|
if (process.env.REDIS_URL) {
|
|
1737
1775
|
console.debug("LG | Using redis as stream queue");
|
|
1738
|
-
const { RedisStreamQueue } = await import('./queue-
|
|
1776
|
+
const { RedisStreamQueue } = await import('./queue-CS3K-zd_.js');
|
|
1739
1777
|
q = RedisStreamQueue;
|
|
1740
1778
|
} else {
|
|
1741
1779
|
q = MemoryStreamQueue;
|
|
@@ -1754,7 +1792,7 @@ const createThreadManager = async (config) => {
|
|
|
1754
1792
|
const dbType = getDatabaseType(process.env.DATABASE_URL);
|
|
1755
1793
|
if (dbType === "remote") {
|
|
1756
1794
|
console.debug("LG | Using Remote PostgreSQL ThreadsManager");
|
|
1757
|
-
const { RemoteKyselyThreadsManager } = await import('./remote-threads-
|
|
1795
|
+
const { RemoteKyselyThreadsManager } = await import('./remote-threads-UpSB8X-e.js');
|
|
1758
1796
|
const threadsManager = new RemoteKyselyThreadsManager(process.env.DATABASE_URL);
|
|
1759
1797
|
if (process.env.DATABASE_INIT === "true") {
|
|
1760
1798
|
await threadsManager.setup();
|
|
@@ -1775,7 +1813,7 @@ const createThreadManager = async (config) => {
|
|
|
1775
1813
|
}
|
|
1776
1814
|
if (process.env.SQLITE_DATABASE_URI && config.checkpointer) {
|
|
1777
1815
|
console.debug("LG | Using SQLite ThreadsManager");
|
|
1778
|
-
const { SQLiteAdapter } = await import('./sqlite-adapter-
|
|
1816
|
+
const { SQLiteAdapter } = await import('./sqlite-adapter-D5g0LbUq.js');
|
|
1779
1817
|
const database = config.checkpointer.db;
|
|
1780
1818
|
const threadsManager = new KyselyThreadsManager(new SQLiteAdapter(database));
|
|
1781
1819
|
await threadsManager.setup();
|
|
@@ -1784,11 +1822,64 @@ const createThreadManager = async (config) => {
|
|
|
1784
1822
|
return new MemoryThreadsManager();
|
|
1785
1823
|
};
|
|
1786
1824
|
|
|
1825
|
+
function extractTextContent(content) {
|
|
1826
|
+
if (typeof content === "string") {
|
|
1827
|
+
return content;
|
|
1828
|
+
}
|
|
1829
|
+
if (Array.isArray(content)) {
|
|
1830
|
+
const textPart = content.find((part) => part.type === "text");
|
|
1831
|
+
return textPart?.text || "";
|
|
1832
|
+
}
|
|
1833
|
+
if (content?.text) {
|
|
1834
|
+
return content.text;
|
|
1835
|
+
}
|
|
1836
|
+
return "";
|
|
1837
|
+
}
|
|
1838
|
+
const defaultTitleGenerator = (state, context) => {
|
|
1839
|
+
const messages = state?.messages;
|
|
1840
|
+
if (!messages || !Array.isArray(messages) || messages.length === 0) {
|
|
1841
|
+
return null;
|
|
1842
|
+
}
|
|
1843
|
+
const firstMessage = messages[0];
|
|
1844
|
+
if (!firstMessage) {
|
|
1845
|
+
return null;
|
|
1846
|
+
}
|
|
1847
|
+
const content = extractTextContent(firstMessage.content);
|
|
1848
|
+
if (!content) {
|
|
1849
|
+
return null;
|
|
1850
|
+
}
|
|
1851
|
+
const cleanedContent = content.trim().replace(/\n/g, " ");
|
|
1852
|
+
if (!cleanedContent) {
|
|
1853
|
+
return null;
|
|
1854
|
+
}
|
|
1855
|
+
const maxLength = 15;
|
|
1856
|
+
const title = cleanedContent.slice(0, maxLength);
|
|
1857
|
+
return title.length < cleanedContent.length ? `${title}...` : title;
|
|
1858
|
+
};
|
|
1859
|
+
|
|
1787
1860
|
class LangGraphGlobal {
|
|
1788
1861
|
static globalMessageQueue = null;
|
|
1789
1862
|
static globalCheckPointer = null;
|
|
1790
1863
|
static globalThreadsManager = null;
|
|
1791
1864
|
static isInitialized = null;
|
|
1865
|
+
/**
|
|
1866
|
+
* 全局标题生成器
|
|
1867
|
+
* 可通过 setTitleGenerator 替换
|
|
1868
|
+
*/
|
|
1869
|
+
static _titleGenerator = defaultTitleGenerator;
|
|
1870
|
+
/**
|
|
1871
|
+
* 设置自定义标题生成器
|
|
1872
|
+
* @param generator 标题生成函数,传入 null 可禁用标题生成
|
|
1873
|
+
*/
|
|
1874
|
+
static setTitleGenerator(generator) {
|
|
1875
|
+
LangGraphGlobal._titleGenerator = generator;
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* 获取当前标题生成器
|
|
1879
|
+
*/
|
|
1880
|
+
static getTitleGenerator() {
|
|
1881
|
+
return LangGraphGlobal._titleGenerator;
|
|
1882
|
+
}
|
|
1792
1883
|
static async initGlobal() {
|
|
1793
1884
|
if (LangGraphGlobal.isInitialized) {
|
|
1794
1885
|
return LangGraphGlobal.isInitialized;
|
|
@@ -2017,5 +2108,5 @@ async function* streamState(threads, run, payload, options) {
|
|
|
2017
2108
|
}
|
|
2018
2109
|
}
|
|
2019
2110
|
|
|
2020
|
-
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 };
|
|
2021
|
-
//# sourceMappingURL=stream-
|
|
2111
|
+
export { BaseStreamQueue as B, CancelEventMessage as C, GRAPHS as G, KyselyThreadsManager as K, LangGraphGlobal as L, streamState as a, defaultTitleGenerator as d, getGraph as g, registerGraph as r, serialiseAsDict as s };
|
|
2112
|
+
//# sourceMappingURL=stream-Bleed1lp.js.map
|