@langgraph-js/pure-graph 2.1.6 → 2.2.8

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 (34) hide show
  1. package/README.md +3 -2
  2. package/dist/adapter/hono/index.js +2 -4
  3. package/dist/adapter/hono/index.js.map +1 -1
  4. package/dist/adapter/nextjs/index.js +2 -2
  5. package/dist/adapter/zod.d.ts +2 -2
  6. package/dist/checkpoint-DnfHhpJw.js +1418 -0
  7. package/dist/checkpoint-DnfHhpJw.js.map +1 -0
  8. package/dist/{createEndpoint-C-7CCNeN.js → createEndpoint-DHnODS67.js} +2 -2
  9. package/dist/{createEndpoint-C-7CCNeN.js.map → createEndpoint-DHnODS67.js.map} +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/pg-adapter-BFtir1GE.js +67 -0
  12. package/dist/pg-adapter-BFtir1GE.js.map +1 -0
  13. package/dist/{queue-CVAmN8_S.js → queue-CwCW8m0q.js} +8 -4
  14. package/dist/queue-CwCW8m0q.js.map +1 -0
  15. package/dist/{router-DgmIokTx.js → router-AADuUgGy.js} +3 -3
  16. package/dist/{router-DgmIokTx.js.map → router-AADuUgGy.js.map} +1 -1
  17. package/dist/sqlite-adapter-BNYk10Gl.js +76 -0
  18. package/dist/sqlite-adapter-BNYk10Gl.js.map +1 -0
  19. package/dist/storage/index.d.ts +2 -3
  20. package/dist/storage/kysely/adapter.d.ts +44 -0
  21. package/dist/storage/kysely/index.d.ts +9 -0
  22. package/dist/storage/kysely/pg-adapter.d.ts +23 -0
  23. package/dist/storage/kysely/sqlite-adapter.d.ts +22 -0
  24. package/dist/storage/{sqlite → kysely}/threads.d.ts +9 -6
  25. package/dist/storage/kysely/types.d.ts +27 -0
  26. package/dist/{stream-BwdFJfJb.js → stream-SJdqjfOM.js} +232 -602
  27. package/dist/stream-SJdqjfOM.js.map +1 -0
  28. package/package.json +2 -2
  29. package/dist/checkpoint-DYSXoBLt.js +0 -390
  30. package/dist/checkpoint-DYSXoBLt.js.map +0 -1
  31. package/dist/queue-CVAmN8_S.js.map +0 -1
  32. package/dist/storage/pg/threads.d.ts +0 -44
  33. package/dist/storage/sqlite/DB.d.ts +0 -3
  34. package/dist/stream-BwdFJfJb.js.map +0 -1
@@ -397,6 +397,227 @@ class StreamQueueManager {
397
397
  }
398
398
  }
399
399
 
400
+ const GRAPHS = {};
401
+ async function registerGraph(graphId, graph) {
402
+ GRAPHS[graphId] = graph;
403
+ }
404
+ async function getGraph(graphId, config, options) {
405
+ if (!GRAPHS[graphId]) throw new Error(`Graph "${graphId}" not found`);
406
+ const compiled = typeof GRAPHS[graphId] === "function" ? await GRAPHS[graphId](config ?? { configurable: {} }) : GRAPHS[graphId];
407
+ if (typeof options?.checkpointer !== "undefined") {
408
+ compiled.checkpointer = options?.checkpointer ?? LangGraphGlobal.globalCheckPointer;
409
+ } else {
410
+ compiled.checkpointer = LangGraphGlobal.globalCheckPointer;
411
+ }
412
+ compiled.store = options?.store ?? void 0;
413
+ return compiled;
414
+ }
415
+
416
+ class KyselyThreadsManager {
417
+ db;
418
+ adapter;
419
+ constructor(adapter) {
420
+ this.db = adapter.db;
421
+ this.adapter = adapter;
422
+ }
423
+ async setup() {
424
+ await this.adapter.createTables(this.db);
425
+ await this.adapter.createIndexes(this.db);
426
+ }
427
+ async create(payload) {
428
+ const threadId = payload?.threadId || crypto.randomUUID();
429
+ if (payload?.ifExists === "raise") {
430
+ const existing = await this.db.selectFrom("threads").select("thread_id").where("thread_id", "=", threadId).executeTakeFirst();
431
+ if (existing) {
432
+ throw new Error(`Thread with ID ${threadId} already exists.`);
433
+ }
434
+ }
435
+ const now = /* @__PURE__ */ new Date();
436
+ const metadata = payload?.metadata || {};
437
+ const interrupts = {};
438
+ await this.db.insertInto("threads").values({
439
+ thread_id: threadId,
440
+ created_at: this.adapter.dateToDb(now),
441
+ updated_at: this.adapter.dateToDb(now),
442
+ metadata: this.adapter.jsonToDb(metadata),
443
+ status: "idle",
444
+ values: null,
445
+ interrupts: this.adapter.jsonToDb(interrupts)
446
+ }).execute();
447
+ return {
448
+ thread_id: threadId,
449
+ created_at: now.toISOString(),
450
+ updated_at: now.toISOString(),
451
+ metadata,
452
+ status: "idle",
453
+ values: null,
454
+ interrupts
455
+ };
456
+ }
457
+ async search(query) {
458
+ let queryBuilder = this.db.selectFrom("threads").selectAll();
459
+ if (query?.status) {
460
+ queryBuilder = queryBuilder.where("status", "=", query.status);
461
+ }
462
+ if (query?.metadata) {
463
+ for (const [key, value] of Object.entries(query.metadata)) {
464
+ queryBuilder = queryBuilder.where(this.adapter.buildJsonQuery(this.db, "metadata", key, value));
465
+ }
466
+ }
467
+ if (query?.sortBy) {
468
+ const order = query.sortOrder === "desc" ? "desc" : "asc";
469
+ queryBuilder = queryBuilder.orderBy(query.sortBy, order);
470
+ }
471
+ if (query?.limit !== void 0) {
472
+ queryBuilder = queryBuilder.limit(query.limit);
473
+ if (query?.offset !== void 0) {
474
+ queryBuilder = queryBuilder.offset(query.offset);
475
+ }
476
+ }
477
+ const rows = await queryBuilder.execute();
478
+ return rows.map((row) => ({
479
+ thread_id: row.thread_id,
480
+ created_at: this.adapter.dbToDate(row.created_at).toISOString(),
481
+ updated_at: this.adapter.dbToDate(row.updated_at).toISOString(),
482
+ metadata: this.adapter.dbToJson(row.metadata),
483
+ status: row.status,
484
+ values: row.values ? this.adapter.dbToJson(row.values) : null,
485
+ interrupts: this.adapter.dbToJson(row.interrupts)
486
+ }));
487
+ }
488
+ async get(threadId) {
489
+ const row = await this.db.selectFrom("threads").selectAll().where("thread_id", "=", threadId).executeTakeFirst();
490
+ if (!row) {
491
+ throw new Error(`Thread with ID ${threadId} not found.`);
492
+ }
493
+ return {
494
+ thread_id: row.thread_id,
495
+ created_at: this.adapter.dbToDate(row.created_at).toISOString(),
496
+ updated_at: this.adapter.dbToDate(row.updated_at).toISOString(),
497
+ metadata: this.adapter.dbToJson(row.metadata),
498
+ status: row.status,
499
+ values: row.values ? this.adapter.dbToJson(row.values) : null,
500
+ interrupts: this.adapter.dbToJson(row.interrupts)
501
+ };
502
+ }
503
+ async set(threadId, thread) {
504
+ const existing = await this.db.selectFrom("threads").select("thread_id").where("thread_id", "=", threadId).executeTakeFirst();
505
+ if (!existing) {
506
+ throw new Error(`Thread with ID ${threadId} not found.`);
507
+ }
508
+ const updates = {
509
+ updated_at: this.adapter.dateToDb(/* @__PURE__ */ new Date())
510
+ };
511
+ if (thread.metadata !== void 0) {
512
+ updates.metadata = this.adapter.jsonToDb(thread.metadata);
513
+ }
514
+ if (thread.status !== void 0) {
515
+ updates.status = thread.status;
516
+ }
517
+ if (thread.values !== void 0) {
518
+ updates.values = thread.values ? this.adapter.jsonToDb(thread.values) : null;
519
+ }
520
+ if (thread.interrupts !== void 0) {
521
+ updates.interrupts = this.adapter.jsonToDb(thread.interrupts);
522
+ }
523
+ await this.db.updateTable("threads").set(updates).where("thread_id", "=", threadId).execute();
524
+ }
525
+ async updateState(threadId, thread) {
526
+ const targetThread = await this.get(threadId);
527
+ if (targetThread.status === "busy") {
528
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
529
+ }
530
+ if (!targetThread.metadata?.graph_id) {
531
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
532
+ }
533
+ const graphId = targetThread.metadata?.graph_id;
534
+ const config = {
535
+ configurable: {
536
+ thread_id: threadId,
537
+ graph_id: graphId
538
+ }
539
+ };
540
+ const graph = await getGraph(graphId, config);
541
+ const nextConfig = await graph.updateState(config, thread.values);
542
+ const graphState = await graph.getState(config);
543
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
544
+ return nextConfig;
545
+ }
546
+ async delete(threadId) {
547
+ const result = await this.db.deleteFrom("threads").where("thread_id", "=", threadId).executeTakeFirst();
548
+ if (result.numDeletedRows === 0n) {
549
+ throw new Error(`Thread with ID ${threadId} not found.`);
550
+ }
551
+ }
552
+ async createRun(threadId, assistantId, payload) {
553
+ const runId = crypto.randomUUID();
554
+ const now = /* @__PURE__ */ new Date();
555
+ const metadata = payload?.metadata ?? {};
556
+ await this.db.insertInto("runs").values({
557
+ run_id: runId,
558
+ thread_id: threadId,
559
+ assistant_id: assistantId,
560
+ created_at: this.adapter.dateToDb(now),
561
+ updated_at: this.adapter.dateToDb(now),
562
+ status: "pending",
563
+ metadata: this.adapter.jsonToDb(metadata),
564
+ multitask_strategy: "reject"
565
+ }).execute();
566
+ return {
567
+ run_id: runId,
568
+ thread_id: threadId,
569
+ assistant_id: assistantId,
570
+ created_at: now.toISOString(),
571
+ updated_at: now.toISOString(),
572
+ status: "pending",
573
+ metadata,
574
+ multitask_strategy: "reject"
575
+ };
576
+ }
577
+ async listRuns(threadId, options) {
578
+ let queryBuilder = this.db.selectFrom("runs").selectAll().where("thread_id", "=", threadId).orderBy("created_at", "desc");
579
+ if (options?.status) {
580
+ queryBuilder = queryBuilder.where("status", "=", options.status);
581
+ }
582
+ if (options?.limit !== void 0) {
583
+ queryBuilder = queryBuilder.limit(options.limit);
584
+ if (options?.offset !== void 0) {
585
+ queryBuilder = queryBuilder.offset(options.offset);
586
+ }
587
+ }
588
+ const rows = await queryBuilder.execute();
589
+ return rows.map((row) => ({
590
+ run_id: row.run_id,
591
+ thread_id: row.thread_id,
592
+ assistant_id: row.assistant_id,
593
+ created_at: this.adapter.dbToDate(row.created_at).toISOString(),
594
+ updated_at: this.adapter.dbToDate(row.updated_at).toISOString(),
595
+ status: row.status,
596
+ metadata: this.adapter.dbToJson(row.metadata),
597
+ multitask_strategy: row.multitask_strategy
598
+ }));
599
+ }
600
+ async updateRun(runId, run) {
601
+ const existing = await this.db.selectFrom("runs").select("run_id").where("run_id", "=", runId).executeTakeFirst();
602
+ if (!existing) {
603
+ throw new Error(`Run with ID ${runId} not found.`);
604
+ }
605
+ const updates = {
606
+ updated_at: this.adapter.dateToDb(/* @__PURE__ */ new Date())
607
+ };
608
+ if (run.status !== void 0) {
609
+ updates.status = run.status;
610
+ }
611
+ if (run.metadata !== void 0) {
612
+ updates.metadata = this.adapter.jsonToDb(run.metadata);
613
+ }
614
+ if (run.multitask_strategy !== void 0) {
615
+ updates.multitask_strategy = run.multitask_strategy;
616
+ }
617
+ await this.db.updateTable("runs").set(updates).where("run_id", "=", runId).execute();
618
+ }
619
+ }
620
+
400
621
  class EventMessage {
401
622
  event;
402
623
  data;
@@ -498,22 +719,6 @@ class MemoryStreamQueue extends BaseStreamQueue {
498
719
  }
499
720
  }
500
721
 
501
- const GRAPHS = {};
502
- async function registerGraph(graphId, graph) {
503
- GRAPHS[graphId] = graph;
504
- }
505
- async function getGraph(graphId, config, options) {
506
- if (!GRAPHS[graphId]) throw new Error(`Graph "${graphId}" not found`);
507
- const compiled = typeof GRAPHS[graphId] === "function" ? await GRAPHS[graphId](config ?? { configurable: {} }) : GRAPHS[graphId];
508
- if (typeof options?.checkpointer !== "undefined") {
509
- compiled.checkpointer = options?.checkpointer ?? LangGraphGlobal.globalCheckPointer;
510
- } else {
511
- compiled.checkpointer = LangGraphGlobal.globalCheckPointer;
512
- }
513
- compiled.store = options?.store ?? void 0;
514
- return compiled;
515
- }
516
-
517
722
  class MemoryThreadsManager {
518
723
  threads = [];
519
724
  async setup() {
@@ -659,587 +864,6 @@ class MemoryThreadsManager {
659
864
  }
660
865
  }
661
866
 
662
- class SQLiteThreadsManager {
663
- db;
664
- isSetup = false;
665
- constructor(checkpointer) {
666
- this.db = checkpointer.db;
667
- }
668
- async setup() {
669
- if (this.isSetup) {
670
- return;
671
- }
672
- this.db.exec(`
673
- CREATE TABLE IF NOT EXISTS threads (
674
- thread_id TEXT PRIMARY KEY,
675
- created_at TEXT NOT NULL,
676
- updated_at TEXT NOT NULL,
677
- metadata TEXT NOT NULL DEFAULT '{}',
678
- status TEXT NOT NULL DEFAULT 'idle',
679
- [values] TEXT,
680
- interrupts TEXT NOT NULL DEFAULT '{}'
681
- )
682
- `);
683
- this.db.exec(`
684
- CREATE TABLE IF NOT EXISTS runs (
685
- run_id TEXT PRIMARY KEY,
686
- thread_id TEXT NOT NULL,
687
- assistant_id TEXT NOT NULL,
688
- created_at TEXT NOT NULL,
689
- updated_at TEXT NOT NULL,
690
- status TEXT NOT NULL DEFAULT 'pending',
691
- metadata TEXT NOT NULL DEFAULT '{}',
692
- multitask_strategy TEXT NOT NULL DEFAULT 'reject',
693
- FOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE
694
- )
695
- `);
696
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)`);
697
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at)`);
698
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_threads_updated_at ON threads(updated_at)`);
699
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_runs_thread_id ON runs(thread_id)`);
700
- this.db.exec(`CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status)`);
701
- this.isSetup = true;
702
- }
703
- async create(payload) {
704
- const threadId = payload?.threadId || crypto.randomUUID();
705
- if (payload?.ifExists === "raise") {
706
- const existingThread = this.db.prepare("SELECT thread_id FROM threads WHERE thread_id = ?").get(threadId);
707
- if (existingThread) {
708
- throw new Error(`Thread with ID ${threadId} already exists.`);
709
- }
710
- }
711
- const now = (/* @__PURE__ */ new Date()).toISOString();
712
- const metadata = JSON.stringify(payload?.metadata || {});
713
- const interrupts = JSON.stringify({});
714
- const thread = {
715
- thread_id: threadId,
716
- created_at: now,
717
- updated_at: now,
718
- metadata: payload?.metadata || {},
719
- status: "idle",
720
- values: null,
721
- interrupts: {}
722
- };
723
- this.db.prepare(
724
- `
725
- INSERT INTO threads (thread_id, created_at, updated_at, metadata, status, [values], interrupts)
726
- VALUES (?, ?, ?, ?, ?, ?, ?)
727
- `
728
- ).run(threadId, now, now, metadata, "idle", null, interrupts);
729
- return thread;
730
- }
731
- async search(query) {
732
- let sql = "SELECT * FROM threads";
733
- const whereConditions = [];
734
- const params = [];
735
- if (query?.status) {
736
- whereConditions.push("status = ?");
737
- params.push(query.status);
738
- }
739
- if (query?.metadata) {
740
- for (const [key, value] of Object.entries(query.metadata)) {
741
- whereConditions.push(`json_extract(metadata, '$.${key}') = ?`);
742
- params.push(JSON.stringify(value));
743
- }
744
- }
745
- if (whereConditions.length > 0) {
746
- sql += " WHERE " + whereConditions.join(" AND ");
747
- }
748
- if (query?.sortBy) {
749
- sql += ` ORDER BY ${query.sortBy}`;
750
- if (query.sortOrder === "desc") {
751
- sql += " DESC";
752
- } else {
753
- sql += " ASC";
754
- }
755
- }
756
- if (query?.limit) {
757
- sql += ` LIMIT ${query.limit}`;
758
- if (query?.offset) {
759
- sql += ` OFFSET ${query.offset}`;
760
- }
761
- }
762
- const rows = this.db.prepare(sql).all(...params);
763
- return rows.map((row) => ({
764
- thread_id: row.thread_id,
765
- created_at: row.created_at,
766
- updated_at: row.updated_at,
767
- metadata: JSON.parse(row.metadata),
768
- status: row.status,
769
- values: row.values ? JSON.parse(row.values) : null,
770
- interrupts: JSON.parse(row.interrupts)
771
- }));
772
- }
773
- async get(threadId) {
774
- const row = this.db.prepare("SELECT * FROM threads WHERE thread_id = ?").get(threadId);
775
- if (!row) {
776
- throw new Error(`Thread with ID ${threadId} not found.`);
777
- }
778
- return {
779
- thread_id: row.thread_id,
780
- created_at: row.created_at,
781
- updated_at: row.updated_at,
782
- metadata: JSON.parse(row.metadata),
783
- status: row.status,
784
- values: row.values ? JSON.parse(row.values) : null,
785
- interrupts: JSON.parse(row.interrupts)
786
- };
787
- }
788
- async set(threadId, thread) {
789
- const existingThread = this.db.prepare("SELECT thread_id FROM threads WHERE thread_id = ?").get(threadId);
790
- if (!existingThread) {
791
- throw new Error(`Thread with ID ${threadId} not found.`);
792
- }
793
- const updateFields = [];
794
- const values = [];
795
- if (thread.metadata !== void 0) {
796
- updateFields.push("metadata = ?");
797
- values.push(JSON.stringify(thread.metadata));
798
- }
799
- if (thread.status !== void 0) {
800
- updateFields.push("status = ?");
801
- values.push(thread.status);
802
- }
803
- if (thread.values !== void 0) {
804
- updateFields.push("[values] = ?");
805
- values.push(thread.values ? JSON.stringify(thread.values) : null);
806
- }
807
- if (thread.interrupts !== void 0) {
808
- updateFields.push("interrupts = ?");
809
- values.push(JSON.stringify(thread.interrupts));
810
- }
811
- updateFields.push("updated_at = ?");
812
- values.push((/* @__PURE__ */ new Date()).toISOString());
813
- if (updateFields.length > 0) {
814
- values.push(threadId);
815
- this.db.prepare(
816
- `
817
- UPDATE threads
818
- SET ${updateFields.join(", ")}
819
- WHERE thread_id = ?
820
- `
821
- ).run(...values);
822
- }
823
- }
824
- async updateState(threadId, thread) {
825
- const row = this.db.prepare("SELECT * FROM threads WHERE thread_id = ?").get(threadId);
826
- if (!row) {
827
- throw new Error(`Thread with ID ${threadId} not found.`);
828
- }
829
- const targetThread = {
830
- thread_id: row.thread_id,
831
- created_at: row.created_at,
832
- updated_at: row.updated_at,
833
- metadata: JSON.parse(row.metadata),
834
- status: row.status,
835
- values: row.values ? JSON.parse(row.values) : null,
836
- interrupts: JSON.parse(row.interrupts)
837
- };
838
- if (targetThread.status === "busy") {
839
- throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
840
- }
841
- if (!targetThread.metadata?.graph_id) {
842
- throw new Error(`Thread with ID ${threadId} has no graph_id.`);
843
- }
844
- const graphId = targetThread.metadata?.graph_id;
845
- const config = {
846
- configurable: {
847
- thread_id: threadId,
848
- graph_id: graphId
849
- }
850
- };
851
- const graph = await getGraph(graphId, config);
852
- const nextConfig = await graph.updateState(config, thread.values);
853
- const graphState = await graph.getState(config);
854
- await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
855
- return nextConfig;
856
- }
857
- async delete(threadId) {
858
- const result = this.db.prepare("DELETE FROM threads WHERE thread_id = ?").run(threadId);
859
- if (result.changes === 0) {
860
- throw new Error(`Thread with ID ${threadId} not found.`);
861
- }
862
- }
863
- async createRun(threadId, assistantId, payload) {
864
- const runId = crypto.randomUUID();
865
- const now = (/* @__PURE__ */ new Date()).toISOString();
866
- const metadata = JSON.stringify(payload?.metadata ?? {});
867
- const run = {
868
- run_id: runId,
869
- thread_id: threadId,
870
- assistant_id: assistantId,
871
- created_at: now,
872
- updated_at: now,
873
- status: "pending",
874
- metadata: payload?.metadata ?? {},
875
- multitask_strategy: "reject"
876
- };
877
- this.db.prepare(
878
- `
879
- INSERT INTO runs (run_id, thread_id, assistant_id, created_at, updated_at, status, metadata, multitask_strategy)
880
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
881
- `
882
- ).run(runId, threadId, assistantId, now, now, "pending", metadata, "reject");
883
- return run;
884
- }
885
- async listRuns(threadId, options) {
886
- let sql = "SELECT * FROM runs WHERE thread_id = ?";
887
- const params = [threadId];
888
- if (options?.status) {
889
- sql += " AND status = ?";
890
- params.push(options.status);
891
- }
892
- sql += " ORDER BY created_at DESC";
893
- if (options?.limit) {
894
- sql += ` LIMIT ${options.limit}`;
895
- if (options?.offset) {
896
- sql += ` OFFSET ${options.offset}`;
897
- }
898
- }
899
- const rows = this.db.prepare(sql).all(...params);
900
- return rows.map((row) => ({
901
- run_id: row.run_id,
902
- thread_id: row.thread_id,
903
- assistant_id: row.assistant_id,
904
- created_at: row.created_at,
905
- updated_at: row.updated_at,
906
- status: row.status,
907
- metadata: JSON.parse(row.metadata),
908
- multitask_strategy: row.multitask_strategy
909
- }));
910
- }
911
- async updateRun(runId, run) {
912
- const existingRun = this.db.prepare("SELECT run_id FROM runs WHERE run_id = ?").get(runId);
913
- if (!existingRun) {
914
- throw new Error(`Run with ID ${runId} not found.`);
915
- }
916
- const updateFields = [];
917
- const values = [];
918
- if (run.status !== void 0) {
919
- updateFields.push("status = ?");
920
- values.push(run.status);
921
- }
922
- if (run.metadata !== void 0) {
923
- updateFields.push("metadata = ?");
924
- values.push(JSON.stringify(run.metadata));
925
- }
926
- if (run.multitask_strategy !== void 0) {
927
- updateFields.push("multitask_strategy = ?");
928
- values.push(run.multitask_strategy);
929
- }
930
- updateFields.push("updated_at = ?");
931
- values.push((/* @__PURE__ */ new Date()).toISOString());
932
- if (updateFields.length > 0) {
933
- values.push(runId);
934
- this.db.prepare(
935
- `
936
- UPDATE runs
937
- SET ${updateFields.join(", ")}
938
- WHERE run_id = ?
939
- `
940
- ).run(...values);
941
- }
942
- }
943
- }
944
-
945
- class PostgresThreadsManager {
946
- pool;
947
- isSetup = false;
948
- constructor(checkpointer) {
949
- this.pool = checkpointer.pool;
950
- }
951
- async setup() {
952
- if (this.isSetup) {
953
- return;
954
- }
955
- await this.pool.query(`
956
- CREATE TABLE IF NOT EXISTS threads (
957
- thread_id TEXT PRIMARY KEY,
958
- created_at TIMESTAMP NOT NULL,
959
- updated_at TIMESTAMP NOT NULL,
960
- metadata JSONB NOT NULL DEFAULT '{}',
961
- status TEXT NOT NULL DEFAULT 'idle',
962
- "values" JSONB,
963
- interrupts JSONB NOT NULL DEFAULT '{}'
964
- )
965
- `);
966
- await this.pool.query(`
967
- CREATE TABLE IF NOT EXISTS runs (
968
- run_id TEXT PRIMARY KEY,
969
- thread_id TEXT NOT NULL,
970
- assistant_id TEXT NOT NULL,
971
- created_at TIMESTAMP NOT NULL,
972
- updated_at TIMESTAMP NOT NULL,
973
- status TEXT NOT NULL DEFAULT 'pending',
974
- metadata JSONB NOT NULL DEFAULT '{}',
975
- multitask_strategy TEXT NOT NULL DEFAULT 'reject',
976
- FOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE
977
- )
978
- `);
979
- await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)`);
980
- await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at)`);
981
- await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_updated_at ON threads(updated_at)`);
982
- await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_thread_id ON runs(thread_id)`);
983
- await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status)`);
984
- this.isSetup = true;
985
- }
986
- async create(payload) {
987
- const threadId = payload?.threadId || crypto.randomUUID();
988
- if (payload?.ifExists === "raise") {
989
- const result = await this.pool.query("SELECT thread_id FROM threads WHERE thread_id = $1", [threadId]);
990
- if (result.rows.length > 0) {
991
- throw new Error(`Thread with ID ${threadId} already exists.`);
992
- }
993
- }
994
- const now = /* @__PURE__ */ new Date();
995
- const metadata = payload?.metadata || {};
996
- const interrupts = {};
997
- const thread = {
998
- thread_id: threadId,
999
- created_at: now.toISOString(),
1000
- updated_at: now.toISOString(),
1001
- metadata,
1002
- status: "idle",
1003
- values: null,
1004
- interrupts
1005
- };
1006
- await this.pool.query(
1007
- `
1008
- INSERT INTO threads (thread_id, created_at, updated_at, metadata, status, "values", interrupts)
1009
- VALUES ($1, $2, $3, $4, $5, $6, $7)
1010
- `,
1011
- [threadId, now, now, JSON.stringify(metadata), "idle", null, JSON.stringify(interrupts)]
1012
- );
1013
- return thread;
1014
- }
1015
- async search(query) {
1016
- let sql = "SELECT * FROM threads";
1017
- const whereConditions = [];
1018
- const params = [];
1019
- let paramIndex = 1;
1020
- if (query?.status) {
1021
- whereConditions.push(`status = $${paramIndex++}`);
1022
- params.push(query.status);
1023
- }
1024
- if (query?.metadata) {
1025
- for (const [key, value] of Object.entries(query.metadata)) {
1026
- whereConditions.push(`metadata->$${paramIndex} = $${paramIndex + 1}`);
1027
- params.push(key, JSON.stringify(value));
1028
- paramIndex += 2;
1029
- }
1030
- }
1031
- if (whereConditions.length > 0) {
1032
- sql += " WHERE " + whereConditions.join(" AND ");
1033
- }
1034
- if (query?.sortBy) {
1035
- sql += ` ORDER BY ${query.sortBy}`;
1036
- if (query.sortOrder === "desc") {
1037
- sql += " DESC";
1038
- } else {
1039
- sql += " ASC";
1040
- }
1041
- }
1042
- if (query?.limit) {
1043
- sql += ` LIMIT $${paramIndex++}`;
1044
- params.push(query.limit);
1045
- if (query?.offset) {
1046
- sql += ` OFFSET $${paramIndex++}`;
1047
- params.push(query.offset);
1048
- }
1049
- }
1050
- const result = await this.pool.query(sql, params);
1051
- return result.rows.map((row) => ({
1052
- thread_id: row.thread_id,
1053
- created_at: new Date(row.created_at).toISOString(),
1054
- updated_at: new Date(row.updated_at).toISOString(),
1055
- metadata: row.metadata,
1056
- status: row.status,
1057
- values: row.values || null,
1058
- interrupts: row.interrupts
1059
- }));
1060
- }
1061
- async get(threadId) {
1062
- const result = await this.pool.query("SELECT * FROM threads WHERE thread_id = $1", [threadId]);
1063
- if (result.rows.length === 0) {
1064
- throw new Error(`Thread with ID ${threadId} not found.`);
1065
- }
1066
- const row = result.rows[0];
1067
- return {
1068
- thread_id: row.thread_id,
1069
- created_at: new Date(row.created_at).toISOString(),
1070
- updated_at: new Date(row.updated_at).toISOString(),
1071
- metadata: row.metadata,
1072
- status: row.status,
1073
- values: row.values || null,
1074
- interrupts: row.interrupts
1075
- };
1076
- }
1077
- async set(threadId, thread) {
1078
- const existingThread = await this.pool.query("SELECT thread_id FROM threads WHERE thread_id = $1", [threadId]);
1079
- if (existingThread.rows.length === 0) {
1080
- throw new Error(`Thread with ID ${threadId} not found.`);
1081
- }
1082
- const updateFields = [];
1083
- const values = [];
1084
- let paramIndex = 1;
1085
- if (thread.metadata !== void 0) {
1086
- updateFields.push(`metadata = $${paramIndex++}`);
1087
- values.push(JSON.stringify(thread.metadata));
1088
- }
1089
- if (thread.status !== void 0) {
1090
- updateFields.push(`status = $${paramIndex++}`);
1091
- values.push(thread.status);
1092
- }
1093
- if (thread.values !== void 0) {
1094
- updateFields.push(`"values" = $${paramIndex++}`);
1095
- values.push(thread.values ? JSON.stringify(thread.values) : null);
1096
- }
1097
- if (thread.interrupts !== void 0) {
1098
- updateFields.push(`interrupts = $${paramIndex++}`);
1099
- values.push(JSON.stringify(thread.interrupts));
1100
- }
1101
- updateFields.push(`updated_at = $${paramIndex++}`);
1102
- values.push(/* @__PURE__ */ new Date());
1103
- if (updateFields.length > 0) {
1104
- values.push(threadId);
1105
- await this.pool.query(
1106
- `
1107
- UPDATE threads
1108
- SET ${updateFields.join(", ")}
1109
- WHERE thread_id = $${paramIndex}
1110
- `,
1111
- values
1112
- );
1113
- }
1114
- }
1115
- async updateState(threadId, thread) {
1116
- const result = await this.pool.query("SELECT * FROM threads WHERE thread_id = $1", [threadId]);
1117
- if (result.rows.length === 0) {
1118
- throw new Error(`Thread with ID ${threadId} not found.`);
1119
- }
1120
- const row = result.rows[0];
1121
- const targetThread = {
1122
- thread_id: row.thread_id,
1123
- created_at: new Date(row.created_at).toISOString(),
1124
- updated_at: new Date(row.updated_at).toISOString(),
1125
- metadata: row.metadata,
1126
- status: row.status,
1127
- values: row.values || null,
1128
- interrupts: row.interrupts
1129
- };
1130
- if (targetThread.status === "busy") {
1131
- throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
1132
- }
1133
- if (!targetThread.metadata?.graph_id) {
1134
- throw new Error(`Thread with ID ${threadId} has no graph_id.`);
1135
- }
1136
- const graphId = targetThread.metadata?.graph_id;
1137
- const config = {
1138
- configurable: {
1139
- thread_id: threadId,
1140
- graph_id: graphId
1141
- }
1142
- };
1143
- const graph = await getGraph(graphId, config);
1144
- const nextConfig = await graph.updateState(config, thread.values);
1145
- const graphState = await graph.getState(config);
1146
- await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
1147
- return nextConfig;
1148
- }
1149
- async delete(threadId) {
1150
- const result = await this.pool.query("DELETE FROM threads WHERE thread_id = $1", [threadId]);
1151
- if (result.rowCount === 0) {
1152
- throw new Error(`Thread with ID ${threadId} not found.`);
1153
- }
1154
- }
1155
- async createRun(threadId, assistantId, payload) {
1156
- const runId = crypto.randomUUID();
1157
- const now = /* @__PURE__ */ new Date();
1158
- const metadata = payload?.metadata ?? {};
1159
- const run = {
1160
- run_id: runId,
1161
- thread_id: threadId,
1162
- assistant_id: assistantId,
1163
- created_at: now.toISOString(),
1164
- updated_at: now.toISOString(),
1165
- status: "pending",
1166
- metadata,
1167
- multitask_strategy: "reject"
1168
- };
1169
- await this.pool.query(
1170
- `
1171
- INSERT INTO runs (run_id, thread_id, assistant_id, created_at, updated_at, status, metadata, multitask_strategy)
1172
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
1173
- `,
1174
- [runId, threadId, assistantId, now, now, "pending", JSON.stringify(metadata), "reject"]
1175
- );
1176
- return run;
1177
- }
1178
- async listRuns(threadId, options) {
1179
- let sql = "SELECT * FROM runs WHERE thread_id = $1";
1180
- const params = [threadId];
1181
- let paramIndex = 2;
1182
- if (options?.status) {
1183
- sql += ` AND status = $${paramIndex++}`;
1184
- params.push(options.status);
1185
- }
1186
- sql += " ORDER BY created_at DESC";
1187
- if (options?.limit) {
1188
- sql += ` LIMIT $${paramIndex++}`;
1189
- params.push(options.limit);
1190
- if (options?.offset) {
1191
- sql += ` OFFSET $${paramIndex++}`;
1192
- params.push(options.offset);
1193
- }
1194
- }
1195
- const result = await this.pool.query(sql, params);
1196
- return result.rows.map((row) => ({
1197
- run_id: row.run_id,
1198
- thread_id: row.thread_id,
1199
- assistant_id: row.assistant_id,
1200
- created_at: new Date(row.created_at).toISOString(),
1201
- updated_at: new Date(row.updated_at).toISOString(),
1202
- status: row.status,
1203
- metadata: row.metadata,
1204
- multitask_strategy: row.multitask_strategy
1205
- }));
1206
- }
1207
- async updateRun(runId, run) {
1208
- const existingRun = await this.pool.query("SELECT run_id FROM runs WHERE run_id = $1", [runId]);
1209
- if (existingRun.rows.length === 0) {
1210
- throw new Error(`Run with ID ${runId} not found.`);
1211
- }
1212
- const updateFields = [];
1213
- const values = [];
1214
- let paramIndex = 1;
1215
- if (run.status !== void 0) {
1216
- updateFields.push(`status = $${paramIndex++}`);
1217
- values.push(run.status);
1218
- }
1219
- if (run.metadata !== void 0) {
1220
- updateFields.push(`metadata = $${paramIndex++}`);
1221
- values.push(JSON.stringify(run.metadata));
1222
- }
1223
- if (run.multitask_strategy !== void 0) {
1224
- updateFields.push(`multitask_strategy = $${paramIndex++}`);
1225
- values.push(run.multitask_strategy);
1226
- }
1227
- updateFields.push(`updated_at = $${paramIndex++}`);
1228
- values.push(/* @__PURE__ */ new Date());
1229
- if (updateFields.length > 0) {
1230
- values.push(runId);
1231
- await this.pool.query(
1232
- `
1233
- UPDATE runs
1234
- SET ${updateFields.join(", ")}
1235
- WHERE run_id = $${paramIndex}
1236
- `,
1237
- values
1238
- );
1239
- }
1240
- }
1241
- }
1242
-
1243
867
  const createCheckPointer = async () => {
1244
868
  if (process.env.REDIS_URL && process.env.CHECKPOINT_TYPE === "redis" || process.env.CHECKPOINT_TYPE === "shallow/redis") {
1245
869
  if (process.env.CHECKPOINT_TYPE === "redis") {
@@ -1264,7 +888,7 @@ const createCheckPointer = async () => {
1264
888
  }
1265
889
  if (process.env.SQLITE_DATABASE_URI) {
1266
890
  console.debug("LG | Using sqlite as checkpoint");
1267
- const { SqliteSaver } = await import('./checkpoint-DYSXoBLt.js');
891
+ const { SqliteSaver } = await import('./checkpoint-DnfHhpJw.js');
1268
892
  const db = SqliteSaver.fromConnString(process.env.SQLITE_DATABASE_URI);
1269
893
  return db;
1270
894
  }
@@ -1274,7 +898,7 @@ const createMessageQueue = async () => {
1274
898
  let q;
1275
899
  if (process.env.REDIS_URL) {
1276
900
  console.debug("LG | Using redis as stream queue");
1277
- const { RedisStreamQueue } = await import('./queue-CVAmN8_S.js');
901
+ const { RedisStreamQueue } = await import('./queue-CwCW8m0q.js');
1278
902
  q = RedisStreamQueue;
1279
903
  } else {
1280
904
  q = MemoryStreamQueue;
@@ -1283,14 +907,20 @@ const createMessageQueue = async () => {
1283
907
  };
1284
908
  const createThreadManager = async (config) => {
1285
909
  if (process.env.DATABASE_URL && config.checkpointer) {
1286
- const threadsManager = new PostgresThreadsManager(config.checkpointer);
910
+ console.debug("LG | Using PostgreSQL ThreadsManager");
911
+ const { PostgresAdapter } = await import('./pg-adapter-BFtir1GE.js');
912
+ const pool = config.checkpointer.pool;
913
+ const threadsManager = new KyselyThreadsManager(new PostgresAdapter(pool));
1287
914
  if (process.env.DATABASE_INIT === "true") {
1288
915
  await threadsManager.setup();
1289
916
  }
1290
917
  return threadsManager;
1291
918
  }
1292
919
  if (process.env.SQLITE_DATABASE_URI && config.checkpointer) {
1293
- const threadsManager = new SQLiteThreadsManager(config.checkpointer);
920
+ console.debug("LG | Using SQLite ThreadsManager");
921
+ const { SQLiteAdapter } = await import('./sqlite-adapter-BNYk10Gl.js');
922
+ const database = config.checkpointer.db;
923
+ const threadsManager = new KyselyThreadsManager(new SQLiteAdapter(database));
1294
924
  await threadsManager.setup();
1295
925
  return threadsManager;
1296
926
  }
@@ -1481,4 +1111,4 @@ async function* streamState(threads, run, payload, options) {
1481
1111
  }
1482
1112
 
1483
1113
  export { BaseStreamQueue as B, CancelEventMessage as C, GRAPHS as G, LangGraphGlobal as L, streamState as a, getGraph as g, registerGraph as r, serialiseAsDict as s };
1484
- //# sourceMappingURL=stream-BwdFJfJb.js.map
1114
+ //# sourceMappingURL=stream-SJdqjfOM.js.map