@langgraph-js/pure-graph 1.0.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.
Files changed (71) hide show
  1. package/README.md +16 -0
  2. package/dist/adapter/hono/assistants.d.ts +3 -0
  3. package/dist/adapter/hono/assistants.js +27 -0
  4. package/dist/adapter/hono/endpoint.d.ts +1 -0
  5. package/dist/adapter/hono/endpoint.js +3 -0
  6. package/dist/adapter/hono/index.d.ts +3 -0
  7. package/dist/adapter/hono/index.js +11 -0
  8. package/dist/adapter/hono/runs.d.ts +3 -0
  9. package/dist/adapter/hono/runs.js +71 -0
  10. package/dist/adapter/hono/threads.d.ts +3 -0
  11. package/dist/adapter/hono/threads.js +71 -0
  12. package/dist/adapter/hono/zod.d.ts +203 -0
  13. package/dist/adapter/hono/zod.js +43 -0
  14. package/dist/createEndpoint.d.ts +5 -0
  15. package/dist/createEndpoint.js +77 -0
  16. package/dist/global.d.ts +4 -0
  17. package/dist/global.js +5 -0
  18. package/dist/graph/stream.d.ts +39 -0
  19. package/dist/graph/stream.js +187 -0
  20. package/dist/graph/stringify.d.ts +1 -0
  21. package/dist/graph/stringify.js +214 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +4 -0
  24. package/dist/queue/JsonPlusSerializer.d.ts +7 -0
  25. package/dist/queue/JsonPlusSerializer.js +138 -0
  26. package/dist/queue/event_message.d.ts +15 -0
  27. package/dist/queue/event_message.js +27 -0
  28. package/dist/queue/stream_queue.d.ts +161 -0
  29. package/dist/queue/stream_queue.js +175 -0
  30. package/dist/storage/index.d.ts +5 -0
  31. package/dist/storage/index.js +11 -0
  32. package/dist/storage/memory/checkpoint.d.ts +2 -0
  33. package/dist/storage/memory/checkpoint.js +2 -0
  34. package/dist/storage/memory/queue.d.ts +17 -0
  35. package/dist/storage/memory/queue.js +72 -0
  36. package/dist/storage/memory/threads.d.ts +39 -0
  37. package/dist/storage/memory/threads.js +115 -0
  38. package/dist/threads/index.d.ts +36 -0
  39. package/dist/threads/index.js +26 -0
  40. package/dist/types.d.ts +94 -0
  41. package/dist/types.js +1 -0
  42. package/dist/utils/getGraph.d.ts +10 -0
  43. package/dist/utils/getGraph.js +18 -0
  44. package/dist/utils/getLangGraphCommand.d.ts +9 -0
  45. package/dist/utils/getLangGraphCommand.js +13 -0
  46. package/package.json +39 -0
  47. package/src/adapter/hono/assistants.ts +41 -0
  48. package/src/adapter/hono/endpoint.ts +4 -0
  49. package/src/adapter/hono/index.ts +14 -0
  50. package/src/adapter/hono/runs.ts +102 -0
  51. package/src/adapter/hono/threads.ts +92 -0
  52. package/src/adapter/hono/zod.ts +49 -0
  53. package/src/createEndpoint.ts +106 -0
  54. package/src/global.ts +6 -0
  55. package/src/graph/stream.ts +253 -0
  56. package/src/graph/stringify.ts +219 -0
  57. package/src/index.ts +5 -0
  58. package/src/queue/JsonPlusSerializer.ts +143 -0
  59. package/src/queue/event_message.ts +30 -0
  60. package/src/queue/stream_queue.ts +236 -0
  61. package/src/storage/index.ts +14 -0
  62. package/src/storage/memory/checkpoint.ts +2 -0
  63. package/src/storage/memory/queue.ts +83 -0
  64. package/src/storage/memory/threads.ts +154 -0
  65. package/src/threads/index.ts +51 -0
  66. package/src/types.ts +116 -0
  67. package/src/utils/getGraph.ts +44 -0
  68. package/src/utils/getLangGraphCommand.ts +21 -0
  69. package/test/graph/index.ts +21 -0
  70. package/test/hono.ts +10 -0
  71. package/tsconfig.json +20 -0
@@ -0,0 +1,161 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ import { JsonPlusSerializer } from './JsonPlusSerializer.js';
3
+ import { EventMessage } from './event_message.js';
4
+ /**
5
+ * 流队列事件接口
6
+ * Stream queue events interface
7
+ */
8
+ interface StreamQueueEvents<T extends EventMessage> {
9
+ /** 数据事件:当有新数据时触发 / Data event: triggered when new data arrives */
10
+ data: (data: T) => void;
11
+ /** 其他事件 / Other events */
12
+ [key: string]: ((...args: any[]) => void) | undefined;
13
+ }
14
+ /**
15
+ * 基础流队列类
16
+ * Base stream queue class
17
+ */
18
+ export declare class BaseStreamQueue extends EventEmitter<StreamQueueEvents<EventMessage>> {
19
+ readonly compressMessages: boolean;
20
+ /** 序列化器实例 / Serializer instance */
21
+ serializer: JsonPlusSerializer;
22
+ /**
23
+ * 构造函数
24
+ * Constructor
25
+ * @param compressMessages 是否压缩消息 / Whether to compress messages
26
+ */
27
+ constructor(compressMessages?: boolean);
28
+ /**
29
+ * 编码数据为 Uint8Array
30
+ * Encode data to Uint8Array
31
+ * @param message 要编码的消息 / Message to encode
32
+ * @returns 编码后的 Uint8Array / Encoded Uint8Array
33
+ */
34
+ encodeData(message: EventMessage): Promise<Uint8Array>;
35
+ /**
36
+ * 解码数据为 EventMessage
37
+ * Decode data to EventMessage
38
+ * @param serializedMessage 要解码的消息 / Message to decode
39
+ * @returns 解码后的 EventMessage / Decoded EventMessage
40
+ */
41
+ decodeData(serializedMessage: string | Uint8Array): Promise<EventMessage>;
42
+ }
43
+ /**
44
+ * 基础流队列接口
45
+ * Base stream queue interface
46
+ */
47
+ export interface BaseStreamQueueInterface {
48
+ /** 是否压缩消息 / Whether to compress messages */
49
+ compressMessages: boolean;
50
+ /**
51
+ * 推送数据项到队列
52
+ * Push item to queue
53
+ * @param item 要推送的数据项 / Item to push
54
+ */
55
+ push(item: EventMessage): Promise<void>;
56
+ /** 获取所有数据 / Get all data */
57
+ getAll(): Promise<EventMessage[]>;
58
+ /** 清空队列 / Clear queue */
59
+ clear(): void;
60
+ /**
61
+ * 监听数据变化
62
+ * Listen for data changes
63
+ * @param listener 数据变化监听器 / Data change listener
64
+ * @returns 取消监听函数 / Unsubscribe function
65
+ */
66
+ onDataChange(listener: (data: EventMessage) => void): () => void;
67
+ /** 取消信号控制器 / Cancel signal controller */
68
+ cancelSignal: AbortController;
69
+ /** 取消操作 / Cancel operation */
70
+ cancel(): void;
71
+ }
72
+ /**
73
+ * StreamQueue 管理器,通过 id 管理多个队列实例
74
+ * StreamQueue manager, manages multiple queue instances by id
75
+ */
76
+ export declare class StreamQueueManager<Q extends BaseStreamQueueInterface> {
77
+ /** 存储队列实例的 Map / Map storing queue instances */
78
+ private queues;
79
+ /** 默认是否压缩消息 / Default compress messages setting */
80
+ private defaultCompressMessages;
81
+ /** 队列构造函数 / Queue constructor */
82
+ private queueConstructor;
83
+ /**
84
+ * 构造函数
85
+ * Constructor
86
+ * @param queueConstructor 队列构造函数 / Queue constructor
87
+ * @param options 配置选项 / Configuration options
88
+ */
89
+ constructor(queueConstructor: new (compressMessages: boolean) => Q, options?: {
90
+ /** 默认是否压缩消息 / Default compress messages setting */
91
+ defaultCompressMessages?: boolean;
92
+ });
93
+ /**
94
+ * 创建指定 id 的队列
95
+ * Create queue with specified id
96
+ * @param id 队列 ID / Queue ID
97
+ * @param compressMessages 是否压缩消息 / Whether to compress messages
98
+ * @returns 创建的队列实例 / Created queue instance
99
+ */
100
+ createQueue(id: string, compressMessages?: boolean): Q;
101
+ /**
102
+ * 获取或创建指定 id 的队列
103
+ * Get or create queue with specified id
104
+ * @param id 队列 ID / Queue ID
105
+ * @param compressMessages 是否压缩消息,默认为构造函数中的默认值 / Whether to compress messages, defaults to constructor default
106
+ * @returns StreamQueue 实例 / StreamQueue instance
107
+ */
108
+ getQueue(id: string): Q;
109
+ /**
110
+ * 取消指定 id 的队列
111
+ * Cancel queue with specified id
112
+ * @param id 队列 ID / Queue ID
113
+ */
114
+ cancelQueue(id: string): void;
115
+ /**
116
+ * 向指定 id 的队列推送数据
117
+ * Push data to queue with specified id
118
+ * @param id 队列 ID / Queue ID
119
+ * @param item 要推送的数据项 / Item to push
120
+ * @param compressMessages 是否压缩消息,默认为构造函数中的默认值 / Whether to compress messages, defaults to constructor default
121
+ */
122
+ pushToQueue(id: string, item: EventMessage, compressMessages?: boolean): Promise<void>;
123
+ /**
124
+ * 获取指定 id 队列中的所有数据
125
+ * Get all data from queue with specified id
126
+ * @param id 队列 ID / Queue ID
127
+ * @returns 队列中的所有数据 / All data in the queue
128
+ */
129
+ getQueueData(id: string): Promise<EventMessage[]>;
130
+ /**
131
+ * 清空指定 id 的队列
132
+ * Clear queue with specified id
133
+ * @param id 队列 ID / Queue ID
134
+ */
135
+ clearQueue(id: string): void;
136
+ /**
137
+ * 删除指定 id 的队列
138
+ * Remove queue with specified id
139
+ * @param id 队列 ID / Queue ID
140
+ * @returns 是否成功删除 / Whether successfully deleted
141
+ */
142
+ removeQueue(id: string): void;
143
+ /**
144
+ * 获取所有队列的 ID
145
+ * Get all queue IDs
146
+ * @returns 所有队列 ID 的数组 / Array of all queue IDs
147
+ */
148
+ getAllQueueIds(): string[];
149
+ /**
150
+ * 获取所有队列及其数据的快照
151
+ * Get snapshot of all queues and their data
152
+ * @returns 包含所有队列数据的结果对象 / Result object containing all queue data
153
+ */
154
+ getAllQueuesData(): Promise<Record<string, EventMessage[]>>;
155
+ /**
156
+ * 清空所有队列
157
+ * Clear all queues
158
+ */
159
+ clearAllQueues(): void;
160
+ }
161
+ export {};
@@ -0,0 +1,175 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ import { JsonPlusSerializer } from './JsonPlusSerializer.js';
3
+ /**
4
+ * 基础流队列类
5
+ * Base stream queue class
6
+ */
7
+ export class BaseStreamQueue extends EventEmitter {
8
+ compressMessages;
9
+ /** 序列化器实例 / Serializer instance */
10
+ serializer = new JsonPlusSerializer();
11
+ /**
12
+ * 构造函数
13
+ * Constructor
14
+ * @param compressMessages 是否压缩消息 / Whether to compress messages
15
+ */
16
+ constructor(compressMessages = true) {
17
+ super();
18
+ this.compressMessages = compressMessages;
19
+ }
20
+ /**
21
+ * 编码数据为 Uint8Array
22
+ * Encode data to Uint8Array
23
+ * @param message 要编码的消息 / Message to encode
24
+ * @returns 编码后的 Uint8Array / Encoded Uint8Array
25
+ */
26
+ async encodeData(message) {
27
+ const [_, serializedMessage] = await this.serializer.dumpsTyped(message);
28
+ return serializedMessage;
29
+ }
30
+ /**
31
+ * 解码数据为 EventMessage
32
+ * Decode data to EventMessage
33
+ * @param serializedMessage 要解码的消息 / Message to decode
34
+ * @returns 解码后的 EventMessage / Decoded EventMessage
35
+ */
36
+ async decodeData(serializedMessage) {
37
+ const message = (await this.serializer.loadsTyped('json', serializedMessage));
38
+ return message;
39
+ }
40
+ }
41
+ /**
42
+ * StreamQueue 管理器,通过 id 管理多个队列实例
43
+ * StreamQueue manager, manages multiple queue instances by id
44
+ */
45
+ export class StreamQueueManager {
46
+ /** 存储队列实例的 Map / Map storing queue instances */
47
+ queues = new Map();
48
+ /** 默认是否压缩消息 / Default compress messages setting */
49
+ defaultCompressMessages;
50
+ /** 队列构造函数 / Queue constructor */
51
+ queueConstructor;
52
+ /**
53
+ * 构造函数
54
+ * Constructor
55
+ * @param queueConstructor 队列构造函数 / Queue constructor
56
+ * @param options 配置选项 / Configuration options
57
+ */
58
+ constructor(queueConstructor, options = {}) {
59
+ this.defaultCompressMessages = options.defaultCompressMessages ?? true;
60
+ this.queueConstructor = queueConstructor;
61
+ }
62
+ /**
63
+ * 创建指定 id 的队列
64
+ * Create queue with specified id
65
+ * @param id 队列 ID / Queue ID
66
+ * @param compressMessages 是否压缩消息 / Whether to compress messages
67
+ * @returns 创建的队列实例 / Created queue instance
68
+ */
69
+ createQueue(id, compressMessages) {
70
+ const compress = compressMessages ?? this.defaultCompressMessages;
71
+ this.queues.set(id, new this.queueConstructor(compress));
72
+ return this.queues.get(id);
73
+ }
74
+ /**
75
+ * 获取或创建指定 id 的队列
76
+ * Get or create queue with specified id
77
+ * @param id 队列 ID / Queue ID
78
+ * @param compressMessages 是否压缩消息,默认为构造函数中的默认值 / Whether to compress messages, defaults to constructor default
79
+ * @returns StreamQueue 实例 / StreamQueue instance
80
+ */
81
+ getQueue(id) {
82
+ const queue = this.queues.get(id);
83
+ if (!queue) {
84
+ throw new Error(`Queue with id '${id}' does not exist`);
85
+ }
86
+ return queue;
87
+ }
88
+ /**
89
+ * 取消指定 id 的队列
90
+ * Cancel queue with specified id
91
+ * @param id 队列 ID / Queue ID
92
+ */
93
+ cancelQueue(id) {
94
+ const queue = this.queues.get(id);
95
+ if (queue) {
96
+ queue.cancel();
97
+ this.removeQueue(id);
98
+ }
99
+ }
100
+ /**
101
+ * 向指定 id 的队列推送数据
102
+ * Push data to queue with specified id
103
+ * @param id 队列 ID / Queue ID
104
+ * @param item 要推送的数据项 / Item to push
105
+ * @param compressMessages 是否压缩消息,默认为构造函数中的默认值 / Whether to compress messages, defaults to constructor default
106
+ */
107
+ async pushToQueue(id, item, compressMessages) {
108
+ const queue = this.getQueue(id);
109
+ await queue.push(item);
110
+ }
111
+ /**
112
+ * 获取指定 id 队列中的所有数据
113
+ * Get all data from queue with specified id
114
+ * @param id 队列 ID / Queue ID
115
+ * @returns 队列中的所有数据 / All data in the queue
116
+ */
117
+ async getQueueData(id) {
118
+ const queue = this.queues.get(id);
119
+ if (!queue) {
120
+ throw new Error(`Queue with id '${id}' does not exist`);
121
+ }
122
+ return await queue.getAll();
123
+ }
124
+ /**
125
+ * 清空指定 id 的队列
126
+ * Clear queue with specified id
127
+ * @param id 队列 ID / Queue ID
128
+ */
129
+ clearQueue(id) {
130
+ const queue = this.queues.get(id);
131
+ if (queue) {
132
+ queue.clear();
133
+ }
134
+ }
135
+ /**
136
+ * 删除指定 id 的队列
137
+ * Remove queue with specified id
138
+ * @param id 队列 ID / Queue ID
139
+ * @returns 是否成功删除 / Whether successfully deleted
140
+ */
141
+ removeQueue(id) {
142
+ setTimeout(() => {
143
+ return this.queues.delete(id);
144
+ }, 500);
145
+ }
146
+ /**
147
+ * 获取所有队列的 ID
148
+ * Get all queue IDs
149
+ * @returns 所有队列 ID 的数组 / Array of all queue IDs
150
+ */
151
+ getAllQueueIds() {
152
+ return Array.from(this.queues.keys());
153
+ }
154
+ /**
155
+ * 获取所有队列及其数据的快照
156
+ * Get snapshot of all queues and their data
157
+ * @returns 包含所有队列数据的结果对象 / Result object containing all queue data
158
+ */
159
+ async getAllQueuesData() {
160
+ const result = {};
161
+ for (const [id, queue] of this.queues) {
162
+ result[id] = await queue.getAll();
163
+ }
164
+ return result;
165
+ }
166
+ /**
167
+ * 清空所有队列
168
+ * Clear all queues
169
+ */
170
+ clearAllQueues() {
171
+ for (const queue of this.queues.values()) {
172
+ queue.clear();
173
+ }
174
+ }
175
+ }
@@ -0,0 +1,5 @@
1
+ import { StreamQueueManager } from '../queue/stream_queue';
2
+ import { MemorySaver } from './memory/checkpoint';
3
+ import { MemoryStreamQueue } from './memory/queue';
4
+ export declare const createCheckPointer: () => MemorySaver;
5
+ export declare const createMessageQueue: () => StreamQueueManager<MemoryStreamQueue>;
@@ -0,0 +1,11 @@
1
+ import { StreamQueueManager } from '../queue/stream_queue';
2
+ import { MemorySaver } from './memory/checkpoint';
3
+ import { MemoryStreamQueue } from './memory/queue';
4
+ // 所有的适配实现,都请写到这里,通过环境变量进行判断使用哪种方式进行适配
5
+ export const createCheckPointer = () => {
6
+ return new MemorySaver();
7
+ };
8
+ export const createMessageQueue = () => {
9
+ const q = MemoryStreamQueue;
10
+ return new StreamQueueManager(q);
11
+ };
@@ -0,0 +1,2 @@
1
+ import { MemorySaver } from '@langchain/langgraph-checkpoint';
2
+ export { MemorySaver };
@@ -0,0 +1,2 @@
1
+ import { MemorySaver } from '@langchain/langgraph-checkpoint';
2
+ export { MemorySaver };
@@ -0,0 +1,17 @@
1
+ import { EventMessage } from '../../queue/event_message.js';
2
+ import { BaseStreamQueue } from '../../queue/stream_queue.js';
3
+ import { BaseStreamQueueInterface } from '../../queue/stream_queue.js';
4
+ /** 内存实现的消息队列,用于存储消息 */
5
+ export declare class MemoryStreamQueue extends BaseStreamQueue implements BaseStreamQueueInterface {
6
+ private data;
7
+ push(item: EventMessage): Promise<void>;
8
+ onDataChange(listener: (data: EventMessage) => void): () => void;
9
+ /**
10
+ * 异步生成器:支持 for await...of 方式消费队列数据
11
+ */
12
+ onDataReceive(): AsyncGenerator<EventMessage, void, unknown>;
13
+ getAll(): Promise<EventMessage[]>;
14
+ clear(): void;
15
+ cancelSignal: AbortController;
16
+ cancel(): void;
17
+ }
@@ -0,0 +1,72 @@
1
+ import { CancelEventMessage } from '../../queue/event_message.js';
2
+ import { BaseStreamQueue } from '../../queue/stream_queue.js';
3
+ /** 内存实现的消息队列,用于存储消息 */
4
+ export class MemoryStreamQueue extends BaseStreamQueue {
5
+ data = [];
6
+ async push(item) {
7
+ const data = this.compressMessages ? (await this.encodeData(item)) : item;
8
+ this.data.push(data);
9
+ this.emit('dataChange', data);
10
+ }
11
+ onDataChange(listener) {
12
+ this.on('dataChange', async (item) => {
13
+ listener(this.compressMessages ? (await this.decodeData(item)) : item);
14
+ });
15
+ return () => this.off('dataChange', listener);
16
+ }
17
+ /**
18
+ * 异步生成器:支持 for await...of 方式消费队列数据
19
+ */
20
+ async *onDataReceive() {
21
+ const queue = [];
22
+ let pendingResolve = null;
23
+ let isStreamEnded = false;
24
+ const handleData = async (item) => {
25
+ const data = this.compressMessages ? (await this.decodeData(item)) : item;
26
+ queue.push(data);
27
+ // 检查是否为流结束或错误信号
28
+ if (data.event === '__stream_end__' ||
29
+ data.event === '__stream_error__' ||
30
+ data.event === '__stream_cancel__') {
31
+ isStreamEnded = true;
32
+ if (data.event === '__stream_cancel__') {
33
+ this.cancel();
34
+ }
35
+ }
36
+ if (pendingResolve) {
37
+ pendingResolve();
38
+ pendingResolve = null;
39
+ }
40
+ };
41
+ this.on('dataChange', handleData);
42
+ try {
43
+ while (!isStreamEnded) {
44
+ if (queue.length > 0) {
45
+ const item = queue.shift();
46
+ yield item;
47
+ }
48
+ else {
49
+ await new Promise((resolve) => {
50
+ pendingResolve = resolve;
51
+ });
52
+ }
53
+ }
54
+ }
55
+ finally {
56
+ this.off('dataChange', handleData);
57
+ }
58
+ }
59
+ async getAll() {
60
+ return this.compressMessages
61
+ ? (await Promise.all(this.data.map((i) => this.decodeData(i))))
62
+ : this.data;
63
+ }
64
+ clear() {
65
+ this.data = [];
66
+ }
67
+ cancelSignal = new AbortController();
68
+ cancel() {
69
+ this.push(new CancelEventMessage());
70
+ this.cancelSignal.abort('user cancel this run');
71
+ }
72
+ }
@@ -0,0 +1,39 @@
1
+ import { BaseThreadsManager } from '../../threads/index.js';
2
+ import { Command, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
3
+ export declare class MemoryThreadsManager<ValuesType = unknown> extends BaseThreadsManager {
4
+ private threads;
5
+ create(payload?: {
6
+ metadata?: Metadata;
7
+ threadId?: string;
8
+ ifExists?: OnConflictBehavior;
9
+ graphId?: string;
10
+ supersteps?: Array<{
11
+ updates: Array<{
12
+ values: unknown;
13
+ command?: Command;
14
+ asNode: string;
15
+ }>;
16
+ }>;
17
+ }): Promise<Thread<ValuesType>>;
18
+ search(query?: {
19
+ metadata?: Metadata;
20
+ limit?: number;
21
+ offset?: number;
22
+ status?: ThreadStatus;
23
+ sortBy?: ThreadSortBy;
24
+ sortOrder?: SortOrder;
25
+ }): Promise<Thread<ValuesType>[]>;
26
+ get(threadId: string): Promise<Thread<ValuesType>>;
27
+ set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void>;
28
+ delete(threadId: string): Promise<void>;
29
+ runs: Run[];
30
+ createRun(threadId: string, assistantId: string, payload?: {
31
+ metadata?: Metadata;
32
+ }): Promise<Run>;
33
+ listRuns(threadId: string, options?: {
34
+ limit?: number;
35
+ offset?: number;
36
+ status?: RunStatus;
37
+ }): Promise<Run[]>;
38
+ updateRun(runId: string, run: Partial<Run>): Promise<void>;
39
+ }
@@ -0,0 +1,115 @@
1
+ import { BaseThreadsManager } from '../../threads/index.js';
2
+ export class MemoryThreadsManager extends BaseThreadsManager {
3
+ threads = [];
4
+ async create(payload) {
5
+ const threadId = payload?.threadId || crypto.randomUUID();
6
+ if (payload?.ifExists === 'raise' && this.threads.some((t) => t.thread_id === threadId)) {
7
+ throw new Error(`Thread with ID ${threadId} already exists.`);
8
+ }
9
+ const thread = {
10
+ thread_id: threadId,
11
+ created_at: new Date().toISOString(),
12
+ updated_at: new Date().toISOString(),
13
+ metadata: payload?.metadata || {},
14
+ status: 'idle',
15
+ values: null,
16
+ interrupts: {},
17
+ };
18
+ this.threads.push(thread);
19
+ return thread;
20
+ }
21
+ async search(query) {
22
+ let filteredThreads = [...this.threads];
23
+ if (query?.status) {
24
+ filteredThreads = filteredThreads.filter((t) => t.status === query.status);
25
+ }
26
+ if (query?.metadata) {
27
+ for (const key in query.metadata) {
28
+ if (Object.prototype.hasOwnProperty.call(query.metadata, key)) {
29
+ filteredThreads = filteredThreads.filter((t) => t.metadata && t.metadata[key] === query.metadata?.[key]);
30
+ }
31
+ }
32
+ }
33
+ if (query?.sortBy) {
34
+ filteredThreads.sort((a, b) => {
35
+ let aValue;
36
+ let bValue;
37
+ switch (query.sortBy) {
38
+ case 'created_at':
39
+ aValue = new Date(a.created_at).getTime();
40
+ bValue = new Date(b.created_at).getTime();
41
+ break;
42
+ case 'updated_at':
43
+ aValue = new Date(a.updated_at).getTime();
44
+ bValue = new Date(b.updated_at).getTime();
45
+ break;
46
+ default:
47
+ return 0;
48
+ }
49
+ if (query.sortOrder === 'desc') {
50
+ return bValue - aValue;
51
+ }
52
+ else {
53
+ return aValue - bValue;
54
+ }
55
+ });
56
+ }
57
+ const offset = query?.offset || 0;
58
+ const limit = query?.limit || filteredThreads.length;
59
+ return filteredThreads.slice(offset, offset + limit);
60
+ }
61
+ async get(threadId) {
62
+ const thread = this.threads.find((t) => t.thread_id === threadId);
63
+ if (!thread) {
64
+ throw new Error(`Thread with ID ${threadId} not found.`);
65
+ }
66
+ return thread;
67
+ }
68
+ async set(threadId, thread) {
69
+ const index = this.threads.findIndex((t) => t.thread_id === threadId);
70
+ if (index === -1) {
71
+ throw new Error(`Thread with ID ${threadId} not found.`);
72
+ }
73
+ this.threads[index] = { ...this.threads[index], ...thread };
74
+ }
75
+ async delete(threadId) {
76
+ const initialLength = this.threads.length;
77
+ this.threads = this.threads.filter((t) => t.thread_id !== threadId);
78
+ if (this.threads.length === initialLength) {
79
+ throw new Error(`Thread with ID ${threadId} not found.`);
80
+ }
81
+ }
82
+ runs = [];
83
+ async createRun(threadId, assistantId, payload) {
84
+ const runId = crypto.randomUUID();
85
+ const run = {
86
+ run_id: runId,
87
+ thread_id: threadId,
88
+ assistant_id: assistantId,
89
+ created_at: new Date().toISOString(),
90
+ updated_at: new Date().toISOString(),
91
+ status: 'pending',
92
+ metadata: payload?.metadata ?? {},
93
+ multitask_strategy: 'reject',
94
+ };
95
+ this.runs.push(run);
96
+ return run;
97
+ }
98
+ async listRuns(threadId, options) {
99
+ let filteredRuns = [...this.runs];
100
+ if (options?.status) {
101
+ filteredRuns = filteredRuns.filter((r) => r.status === options.status);
102
+ }
103
+ if (options?.limit) {
104
+ filteredRuns = filteredRuns.slice(options.offset || 0, (options.offset || 0) + options.limit);
105
+ }
106
+ return filteredRuns;
107
+ }
108
+ async updateRun(runId, run) {
109
+ const index = this.runs.findIndex((r) => r.run_id === runId);
110
+ if (index === -1) {
111
+ throw new Error(`Run with ID ${runId} not found.`);
112
+ }
113
+ this.runs[index] = { ...this.runs[index], ...run };
114
+ }
115
+ }
@@ -0,0 +1,36 @@
1
+ import { Command, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
2
+ export declare class BaseThreadsManager<ValuesType = unknown> {
3
+ create(payload?: {
4
+ metadata?: Metadata;
5
+ threadId?: string;
6
+ ifExists?: OnConflictBehavior;
7
+ graphId?: string;
8
+ supersteps?: Array<{
9
+ updates: Array<{
10
+ values: unknown;
11
+ command?: Command;
12
+ asNode: string;
13
+ }>;
14
+ }>;
15
+ }): Promise<Thread<ValuesType>>;
16
+ set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void>;
17
+ search(query?: {
18
+ metadata?: Metadata;
19
+ limit?: number;
20
+ offset?: number;
21
+ status?: ThreadStatus;
22
+ sortBy?: ThreadSortBy;
23
+ sortOrder?: SortOrder;
24
+ }): Promise<Thread<ValuesType>[]>;
25
+ get(threadId: string): Promise<Thread<ValuesType>>;
26
+ delete(threadId: string): Promise<void>;
27
+ createRun(threadId: string, assistantId: string, payload?: {
28
+ metadata?: Metadata;
29
+ }): Promise<Run>;
30
+ listRuns(threadId: string, options?: {
31
+ limit?: number;
32
+ offset?: number;
33
+ status?: RunStatus;
34
+ }): Promise<Run[]>;
35
+ updateRun(runId: string, run: Partial<Run>): Promise<void>;
36
+ }
@@ -0,0 +1,26 @@
1
+ export class BaseThreadsManager {
2
+ create(payload) {
3
+ throw new Error('Function not implemented.');
4
+ }
5
+ set(threadId, thread) {
6
+ throw new Error('Function not implemented.');
7
+ }
8
+ search(query) {
9
+ throw new Error('Function not implemented.');
10
+ }
11
+ get(threadId) {
12
+ throw new Error('Function not implemented.');
13
+ }
14
+ delete(threadId) {
15
+ throw new Error('Function not implemented.');
16
+ }
17
+ createRun(threadId, assistantId, payload) {
18
+ throw new Error('Function not implemented.');
19
+ }
20
+ listRuns(threadId, options) {
21
+ throw new Error('Function not implemented.');
22
+ }
23
+ updateRun(runId, run) {
24
+ throw new Error('Function not implemented.');
25
+ }
26
+ }