@langgraph-js/pure-graph 3.2.5 → 3.3.1

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.
Files changed (33) hide show
  1. package/dist/adapter/fetch/index.js +4 -3
  2. package/dist/adapter/fetch/index.js.map +1 -1
  3. package/dist/adapter/nextjs/index.js +1 -1
  4. package/dist/adapter/zod.d.ts +1 -0
  5. package/dist/{createEndpoint-Cz6LSXYH.js → createEndpoint-D27R5Yhn.js} +53 -11
  6. package/dist/createEndpoint-D27R5Yhn.js.map +1 -0
  7. package/dist/createEndpoint.d.ts +2 -1
  8. package/dist/global.d.ts +15 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +2 -2
  11. package/dist/{queue-swFecaQs.js → queue-CS3K-zd_.js} +2 -2
  12. package/dist/{queue-swFecaQs.js.map → queue-CS3K-zd_.js.map} +1 -1
  13. package/dist/remote/index.js +1 -1
  14. package/dist/{remote-threads-CrG03ZS7.js → remote-threads-UpSB8X-e.js} +19 -1
  15. package/dist/remote-threads-UpSB8X-e.js.map +1 -0
  16. package/dist/{sqlite-adapter-CJXgit1j.js → sqlite-adapter-D5g0LbUq.js} +15 -2
  17. package/dist/sqlite-adapter-D5g0LbUq.js.map +1 -0
  18. package/dist/storage/kysely/remote-threads.d.ts +4 -0
  19. package/dist/storage/kysely/sqlite-adapter.d.ts +5 -0
  20. package/dist/storage/kysely/threads.d.ts +3 -2
  21. package/dist/storage/kysely/types.d.ts +1 -0
  22. package/dist/storage/memory/threads.d.ts +4 -3
  23. package/dist/{stream-Dm5628RW.js → stream-Bleed1lp.js} +104 -13
  24. package/dist/stream-Bleed1lp.js.map +1 -0
  25. package/dist/threads/index.d.ts +9 -3
  26. package/dist/types.d.ts +10 -2
  27. package/dist/utils/titleGenerator.d.ts +20 -0
  28. package/dist/utils/titleGeneratorHelper.d.ts +17 -0
  29. package/package.json +87 -86
  30. package/dist/createEndpoint-Cz6LSXYH.js.map +0 -1
  31. package/dist/remote-threads-CrG03ZS7.js.map +0 -1
  32. package/dist/sqlite-adapter-CJXgit1j.js.map +0 -1
  33. 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-swFecaQs.js');
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-CrG03ZS7.js');
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-CJXgit1j.js');
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-Dm5628RW.js.map
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