@langgraph-js/pure-graph 1.4.0 → 1.4.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.
@@ -0,0 +1,302 @@
1
+ import { g as getGraph, s as serialiseAsDict } from './index-DcXE-SZb.js';
2
+
3
+ class PostgresThreadsManager {
4
+ pool;
5
+ isSetup = false;
6
+ constructor(checkpointer) {
7
+ this.pool = checkpointer.pool;
8
+ }
9
+ async setup() {
10
+ if (this.isSetup) {
11
+ return;
12
+ }
13
+ await this.pool.query(`
14
+ CREATE TABLE IF NOT EXISTS threads (
15
+ thread_id TEXT PRIMARY KEY,
16
+ created_at TIMESTAMP NOT NULL,
17
+ updated_at TIMESTAMP NOT NULL,
18
+ metadata JSONB NOT NULL DEFAULT '{}',
19
+ status TEXT NOT NULL DEFAULT 'idle',
20
+ "values" JSONB,
21
+ interrupts JSONB NOT NULL DEFAULT '{}'
22
+ )
23
+ `);
24
+ await this.pool.query(`
25
+ CREATE TABLE IF NOT EXISTS runs (
26
+ run_id TEXT PRIMARY KEY,
27
+ thread_id TEXT NOT NULL,
28
+ assistant_id TEXT NOT NULL,
29
+ created_at TIMESTAMP NOT NULL,
30
+ updated_at TIMESTAMP NOT NULL,
31
+ status TEXT NOT NULL DEFAULT 'pending',
32
+ metadata JSONB NOT NULL DEFAULT '{}',
33
+ multitask_strategy TEXT NOT NULL DEFAULT 'reject',
34
+ FOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE
35
+ )
36
+ `);
37
+ await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)`);
38
+ await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at)`);
39
+ await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_updated_at ON threads(updated_at)`);
40
+ await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_thread_id ON runs(thread_id)`);
41
+ await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status)`);
42
+ this.isSetup = true;
43
+ }
44
+ async create(payload) {
45
+ const threadId = payload?.threadId || crypto.randomUUID();
46
+ if (payload?.ifExists === "raise") {
47
+ const result = await this.pool.query("SELECT thread_id FROM threads WHERE thread_id = $1", [threadId]);
48
+ if (result.rows.length > 0) {
49
+ throw new Error(`Thread with ID ${threadId} already exists.`);
50
+ }
51
+ }
52
+ const now = /* @__PURE__ */ new Date();
53
+ const metadata = payload?.metadata || {};
54
+ const interrupts = {};
55
+ const thread = {
56
+ thread_id: threadId,
57
+ created_at: now.toISOString(),
58
+ updated_at: now.toISOString(),
59
+ metadata,
60
+ status: "idle",
61
+ values: null,
62
+ interrupts
63
+ };
64
+ await this.pool.query(
65
+ `
66
+ INSERT INTO threads (thread_id, created_at, updated_at, metadata, status, "values", interrupts)
67
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
68
+ `,
69
+ [threadId, now, now, JSON.stringify(metadata), "idle", null, JSON.stringify(interrupts)]
70
+ );
71
+ return thread;
72
+ }
73
+ async search(query) {
74
+ let sql = "SELECT * FROM threads";
75
+ const whereConditions = [];
76
+ const params = [];
77
+ let paramIndex = 1;
78
+ if (query?.status) {
79
+ whereConditions.push(`status = $${paramIndex++}`);
80
+ params.push(query.status);
81
+ }
82
+ if (query?.metadata) {
83
+ for (const [key, value] of Object.entries(query.metadata)) {
84
+ whereConditions.push(`metadata->$${paramIndex} = $${paramIndex + 1}`);
85
+ params.push(key, JSON.stringify(value));
86
+ paramIndex += 2;
87
+ }
88
+ }
89
+ if (whereConditions.length > 0) {
90
+ sql += " WHERE " + whereConditions.join(" AND ");
91
+ }
92
+ if (query?.sortBy) {
93
+ sql += ` ORDER BY ${query.sortBy}`;
94
+ if (query.sortOrder === "desc") {
95
+ sql += " DESC";
96
+ } else {
97
+ sql += " ASC";
98
+ }
99
+ }
100
+ if (query?.limit) {
101
+ sql += ` LIMIT $${paramIndex++}`;
102
+ params.push(query.limit);
103
+ if (query?.offset) {
104
+ sql += ` OFFSET $${paramIndex++}`;
105
+ params.push(query.offset);
106
+ }
107
+ }
108
+ const result = await this.pool.query(sql, params);
109
+ return result.rows.map((row) => ({
110
+ thread_id: row.thread_id,
111
+ created_at: new Date(row.created_at).toISOString(),
112
+ updated_at: new Date(row.updated_at).toISOString(),
113
+ metadata: row.metadata,
114
+ status: row.status,
115
+ values: row.values || null,
116
+ interrupts: row.interrupts
117
+ }));
118
+ }
119
+ async get(threadId) {
120
+ const result = await this.pool.query("SELECT * FROM threads WHERE thread_id = $1", [threadId]);
121
+ if (result.rows.length === 0) {
122
+ throw new Error(`Thread with ID ${threadId} not found.`);
123
+ }
124
+ const row = result.rows[0];
125
+ return {
126
+ thread_id: row.thread_id,
127
+ created_at: new Date(row.created_at).toISOString(),
128
+ updated_at: new Date(row.updated_at).toISOString(),
129
+ metadata: row.metadata,
130
+ status: row.status,
131
+ values: row.values || null,
132
+ interrupts: row.interrupts
133
+ };
134
+ }
135
+ async set(threadId, thread) {
136
+ const existingThread = await this.pool.query("SELECT thread_id FROM threads WHERE thread_id = $1", [threadId]);
137
+ if (existingThread.rows.length === 0) {
138
+ throw new Error(`Thread with ID ${threadId} not found.`);
139
+ }
140
+ const updateFields = [];
141
+ const values = [];
142
+ let paramIndex = 1;
143
+ if (thread.metadata !== void 0) {
144
+ updateFields.push(`metadata = $${paramIndex++}`);
145
+ values.push(JSON.stringify(thread.metadata));
146
+ }
147
+ if (thread.status !== void 0) {
148
+ updateFields.push(`status = $${paramIndex++}`);
149
+ values.push(thread.status);
150
+ }
151
+ if (thread.values !== void 0) {
152
+ updateFields.push(`"values" = $${paramIndex++}`);
153
+ values.push(thread.values ? JSON.stringify(thread.values) : null);
154
+ }
155
+ if (thread.interrupts !== void 0) {
156
+ updateFields.push(`interrupts = $${paramIndex++}`);
157
+ values.push(JSON.stringify(thread.interrupts));
158
+ }
159
+ updateFields.push(`updated_at = $${paramIndex++}`);
160
+ values.push(/* @__PURE__ */ new Date());
161
+ if (updateFields.length > 0) {
162
+ values.push(threadId);
163
+ await this.pool.query(
164
+ `
165
+ UPDATE threads
166
+ SET ${updateFields.join(", ")}
167
+ WHERE thread_id = $${paramIndex}
168
+ `,
169
+ values
170
+ );
171
+ }
172
+ }
173
+ async updateState(threadId, thread) {
174
+ const result = await this.pool.query("SELECT * FROM threads WHERE thread_id = $1", [threadId]);
175
+ if (result.rows.length === 0) {
176
+ throw new Error(`Thread with ID ${threadId} not found.`);
177
+ }
178
+ const row = result.rows[0];
179
+ const targetThread = {
180
+ thread_id: row.thread_id,
181
+ created_at: new Date(row.created_at).toISOString(),
182
+ updated_at: new Date(row.updated_at).toISOString(),
183
+ metadata: row.metadata,
184
+ status: row.status,
185
+ values: row.values || null,
186
+ interrupts: row.interrupts
187
+ };
188
+ if (targetThread.status === "busy") {
189
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
190
+ }
191
+ if (!targetThread.metadata?.graph_id) {
192
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
193
+ }
194
+ const graphId = targetThread.metadata?.graph_id;
195
+ const config = {
196
+ configurable: {
197
+ thread_id: threadId,
198
+ graph_id: graphId
199
+ }
200
+ };
201
+ const graph = await getGraph(graphId, config);
202
+ const nextConfig = await graph.updateState(config, thread.values);
203
+ const graphState = await graph.getState(config);
204
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
205
+ return nextConfig;
206
+ }
207
+ async delete(threadId) {
208
+ const result = await this.pool.query("DELETE FROM threads WHERE thread_id = $1", [threadId]);
209
+ if (result.rowCount === 0) {
210
+ throw new Error(`Thread with ID ${threadId} not found.`);
211
+ }
212
+ }
213
+ async createRun(threadId, assistantId, payload) {
214
+ const runId = crypto.randomUUID();
215
+ const now = /* @__PURE__ */ new Date();
216
+ const metadata = payload?.metadata ?? {};
217
+ const run = {
218
+ run_id: runId,
219
+ thread_id: threadId,
220
+ assistant_id: assistantId,
221
+ created_at: now.toISOString(),
222
+ updated_at: now.toISOString(),
223
+ status: "pending",
224
+ metadata,
225
+ multitask_strategy: "reject"
226
+ };
227
+ await this.pool.query(
228
+ `
229
+ INSERT INTO runs (run_id, thread_id, assistant_id, created_at, updated_at, status, metadata, multitask_strategy)
230
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
231
+ `,
232
+ [runId, threadId, assistantId, now, now, "pending", JSON.stringify(metadata), "reject"]
233
+ );
234
+ return run;
235
+ }
236
+ async listRuns(threadId, options) {
237
+ let sql = "SELECT * FROM runs WHERE thread_id = $1";
238
+ const params = [threadId];
239
+ let paramIndex = 2;
240
+ if (options?.status) {
241
+ sql += ` AND status = $${paramIndex++}`;
242
+ params.push(options.status);
243
+ }
244
+ sql += " ORDER BY created_at DESC";
245
+ if (options?.limit) {
246
+ sql += ` LIMIT $${paramIndex++}`;
247
+ params.push(options.limit);
248
+ if (options?.offset) {
249
+ sql += ` OFFSET $${paramIndex++}`;
250
+ params.push(options.offset);
251
+ }
252
+ }
253
+ const result = await this.pool.query(sql, params);
254
+ return result.rows.map((row) => ({
255
+ run_id: row.run_id,
256
+ thread_id: row.thread_id,
257
+ assistant_id: row.assistant_id,
258
+ created_at: new Date(row.created_at).toISOString(),
259
+ updated_at: new Date(row.updated_at).toISOString(),
260
+ status: row.status,
261
+ metadata: row.metadata,
262
+ multitask_strategy: row.multitask_strategy
263
+ }));
264
+ }
265
+ async updateRun(runId, run) {
266
+ const existingRun = await this.pool.query("SELECT run_id FROM runs WHERE run_id = $1", [runId]);
267
+ if (existingRun.rows.length === 0) {
268
+ throw new Error(`Run with ID ${runId} not found.`);
269
+ }
270
+ const updateFields = [];
271
+ const values = [];
272
+ let paramIndex = 1;
273
+ if (run.status !== void 0) {
274
+ updateFields.push(`status = $${paramIndex++}`);
275
+ values.push(run.status);
276
+ }
277
+ if (run.metadata !== void 0) {
278
+ updateFields.push(`metadata = $${paramIndex++}`);
279
+ values.push(JSON.stringify(run.metadata));
280
+ }
281
+ if (run.multitask_strategy !== void 0) {
282
+ updateFields.push(`multitask_strategy = $${paramIndex++}`);
283
+ values.push(run.multitask_strategy);
284
+ }
285
+ updateFields.push(`updated_at = $${paramIndex++}`);
286
+ values.push(/* @__PURE__ */ new Date());
287
+ if (updateFields.length > 0) {
288
+ values.push(runId);
289
+ await this.pool.query(
290
+ `
291
+ UPDATE runs
292
+ SET ${updateFields.join(", ")}
293
+ WHERE run_id = $${paramIndex}
294
+ `,
295
+ values
296
+ );
297
+ }
298
+ }
299
+ }
300
+
301
+ export { PostgresThreadsManager };
302
+ //# sourceMappingURL=threads-BUgBiCiK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threads-BUgBiCiK.js","sources":["../src/storage/pg/threads.ts"],"sourcesContent":["import { BaseThreadsManager } from '../../threads/index.js';\nimport {\n Command,\n Config,\n Metadata,\n OnConflictBehavior,\n Run,\n RunStatus,\n SortOrder,\n Thread,\n ThreadSortBy,\n ThreadStatus,\n} from '@langgraph-js/sdk';\nimport type { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';\nimport type { Pool } from 'pg';\nimport { getGraph } from '../../utils/getGraph.js';\nimport { serialiseAsDict } from '../../graph/stream.js';\n\ninterface ThreadRow {\n thread_id: string;\n created_at: Date;\n updated_at: Date;\n metadata: any;\n status: string;\n values: any;\n interrupts: any;\n}\n\ninterface RunRow {\n run_id: string;\n thread_id: string;\n assistant_id: string;\n created_at: Date;\n updated_at: Date;\n status: string;\n metadata: any;\n multitask_strategy: string;\n}\n\nexport class PostgresThreadsManager<ValuesType = unknown> implements BaseThreadsManager<ValuesType> {\n private pool: Pool;\n private isSetup: boolean = false;\n\n constructor(checkpointer: PostgresSaver) {\n // 访问 PostgresSaver 的 pool 属性(虽然是 private,但在运行时可以访问)\n this.pool = (checkpointer as any).pool;\n }\n\n public async setup(): Promise<void> {\n if (this.isSetup) {\n return;\n }\n\n // 创建 threads 表\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS threads (\n thread_id TEXT PRIMARY KEY,\n created_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP NOT NULL,\n metadata JSONB NOT NULL DEFAULT '{}',\n status TEXT NOT NULL DEFAULT 'idle',\n \"values\" JSONB,\n interrupts JSONB NOT NULL DEFAULT '{}'\n )\n `);\n\n // 创建 runs 表\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS runs (\n run_id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n assistant_id TEXT NOT NULL,\n created_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n metadata JSONB NOT NULL DEFAULT '{}',\n multitask_strategy TEXT NOT NULL DEFAULT 'reject',\n FOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE\n )\n `);\n\n // 创建索引以提高查询性能\n await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)`);\n await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at)`);\n await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_threads_updated_at ON threads(updated_at)`);\n await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_thread_id ON runs(thread_id)`);\n await this.pool.query(`CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status)`);\n\n this.isSetup = true;\n }\n\n async create(payload?: {\n metadata?: Metadata;\n threadId?: string;\n ifExists?: OnConflictBehavior;\n graphId?: string;\n supersteps?: Array<{ updates: Array<{ values: unknown; command?: Command; asNode: string }> }>;\n }): Promise<Thread<ValuesType>> {\n const threadId = payload?.threadId || crypto.randomUUID();\n\n // 检查线程是否已存在\n if (payload?.ifExists === 'raise') {\n const result = await this.pool.query('SELECT thread_id FROM threads WHERE thread_id = $1', [threadId]);\n if (result.rows.length > 0) {\n throw new Error(`Thread with ID ${threadId} already exists.`);\n }\n }\n\n const now = new Date();\n const metadata = payload?.metadata || {};\n const interrupts = {};\n\n const thread: Thread<ValuesType> = {\n thread_id: threadId,\n created_at: now.toISOString(),\n updated_at: now.toISOString(),\n metadata,\n status: 'idle',\n values: null as unknown as ValuesType,\n interrupts,\n };\n\n // 插入到数据库\n await this.pool.query(\n `\n INSERT INTO threads (thread_id, created_at, updated_at, metadata, status, \"values\", interrupts)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n `,\n [threadId, now, now, JSON.stringify(metadata), 'idle', null, JSON.stringify(interrupts)],\n );\n\n return thread;\n }\n\n async search(query?: {\n metadata?: Metadata;\n limit?: number;\n offset?: number;\n status?: ThreadStatus;\n sortBy?: ThreadSortBy;\n sortOrder?: SortOrder;\n }): Promise<Thread<ValuesType>[]> {\n let sql = 'SELECT * FROM threads';\n const whereConditions: string[] = [];\n const params: any[] = [];\n let paramIndex = 1;\n\n // 构建 WHERE 条件\n if (query?.status) {\n whereConditions.push(`status = $${paramIndex++}`);\n params.push(query.status);\n }\n\n if (query?.metadata) {\n for (const [key, value] of Object.entries(query.metadata)) {\n whereConditions.push(`metadata->$${paramIndex} = $${paramIndex + 1}`);\n params.push(key, JSON.stringify(value));\n paramIndex += 2;\n }\n }\n\n if (whereConditions.length > 0) {\n sql += ' WHERE ' + whereConditions.join(' AND ');\n }\n\n // 添加排序\n if (query?.sortBy) {\n sql += ` ORDER BY ${query.sortBy}`;\n if (query.sortOrder === 'desc') {\n sql += ' DESC';\n } else {\n sql += ' ASC';\n }\n }\n\n // 添加分页\n if (query?.limit) {\n sql += ` LIMIT $${paramIndex++}`;\n params.push(query.limit);\n if (query?.offset) {\n sql += ` OFFSET $${paramIndex++}`;\n params.push(query.offset);\n }\n }\n\n const result = await this.pool.query(sql, params);\n\n return result.rows.map((row: ThreadRow) => ({\n thread_id: row.thread_id,\n created_at: new Date(row.created_at).toISOString(),\n updated_at: new Date(row.updated_at).toISOString(),\n metadata: row.metadata,\n status: row.status as ThreadStatus,\n values: row.values || (null as unknown as ValuesType),\n interrupts: row.interrupts,\n }));\n }\n\n async get(threadId: string): Promise<Thread<ValuesType>> {\n const result = await this.pool.query('SELECT * FROM threads WHERE thread_id = $1', [threadId]);\n if (result.rows.length === 0) {\n throw new Error(`Thread with ID ${threadId} not found.`);\n }\n\n const row = result.rows[0] as ThreadRow;\n return {\n thread_id: row.thread_id,\n created_at: new Date(row.created_at).toISOString(),\n updated_at: new Date(row.updated_at).toISOString(),\n metadata: row.metadata,\n status: row.status as ThreadStatus,\n values: row.values || (null as unknown as ValuesType),\n interrupts: row.interrupts,\n };\n }\n\n async set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void> {\n // 检查线程是否存在\n const existingThread = await this.pool.query('SELECT thread_id FROM threads WHERE thread_id = $1', [threadId]);\n if (existingThread.rows.length === 0) {\n throw new Error(`Thread with ID ${threadId} not found.`);\n }\n\n const updateFields: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n if (thread.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n values.push(JSON.stringify(thread.metadata));\n }\n\n if (thread.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n values.push(thread.status);\n }\n\n if (thread.values !== undefined) {\n updateFields.push(`\"values\" = $${paramIndex++}`);\n values.push(thread.values ? JSON.stringify(thread.values) : null);\n }\n\n if (thread.interrupts !== undefined) {\n updateFields.push(`interrupts = $${paramIndex++}`);\n values.push(JSON.stringify(thread.interrupts));\n }\n\n // 总是更新 updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n values.push(new Date());\n\n if (updateFields.length > 0) {\n values.push(threadId);\n await this.pool.query(\n `\n UPDATE threads \n SET ${updateFields.join(', ')} \n WHERE thread_id = $${paramIndex}\n `,\n values,\n );\n }\n }\n\n async updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>> {\n // 从数据库查询线程信息\n const result = await this.pool.query('SELECT * FROM threads WHERE thread_id = $1', [threadId]);\n if (result.rows.length === 0) {\n throw new Error(`Thread with ID ${threadId} not found.`);\n }\n\n const row = result.rows[0] as ThreadRow;\n const targetThread = {\n thread_id: row.thread_id,\n created_at: new Date(row.created_at).toISOString(),\n updated_at: new Date(row.updated_at).toISOString(),\n metadata: row.metadata,\n status: row.status as ThreadStatus,\n values: row.values || (null as unknown as ValuesType),\n interrupts: row.interrupts,\n };\n\n if (targetThread.status === 'busy') {\n throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);\n }\n\n if (!targetThread.metadata?.graph_id) {\n throw new Error(`Thread with ID ${threadId} has no graph_id.`);\n }\n const graphId = targetThread.metadata?.graph_id as string;\n const config = {\n configurable: {\n thread_id: threadId,\n graph_id: graphId,\n },\n };\n const graph = await getGraph(graphId, config);\n const nextConfig = await graph.updateState(config, thread.values);\n const graphState = await graph.getState(config);\n await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) as ValuesType });\n return nextConfig;\n }\n\n async delete(threadId: string): Promise<void> {\n const result = await this.pool.query('DELETE FROM threads WHERE thread_id = $1', [threadId]);\n if (result.rowCount === 0) {\n throw new Error(`Thread with ID ${threadId} not found.`);\n }\n }\n\n async createRun(threadId: string, assistantId: string, payload?: { metadata?: Metadata }): Promise<Run> {\n const runId = crypto.randomUUID();\n const now = new Date();\n const metadata = payload?.metadata ?? {};\n\n const run: Run = {\n run_id: runId,\n thread_id: threadId,\n assistant_id: assistantId,\n created_at: now.toISOString(),\n updated_at: now.toISOString(),\n status: 'pending',\n metadata,\n multitask_strategy: 'reject',\n };\n\n // 插入到数据库\n await this.pool.query(\n `\n INSERT INTO runs (run_id, thread_id, assistant_id, created_at, updated_at, status, metadata, multitask_strategy)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n `,\n [runId, threadId, assistantId, now, now, 'pending', JSON.stringify(metadata), 'reject'],\n );\n\n return run;\n }\n\n async listRuns(\n threadId: string,\n options?: { limit?: number; offset?: number; status?: RunStatus },\n ): Promise<Run[]> {\n let sql = 'SELECT * FROM runs WHERE thread_id = $1';\n const params: any[] = [threadId];\n let paramIndex = 2;\n\n if (options?.status) {\n sql += ` AND status = $${paramIndex++}`;\n params.push(options.status);\n }\n\n sql += ' ORDER BY created_at DESC';\n\n if (options?.limit) {\n sql += ` LIMIT $${paramIndex++}`;\n params.push(options.limit);\n if (options?.offset) {\n sql += ` OFFSET $${paramIndex++}`;\n params.push(options.offset);\n }\n }\n\n const result = await this.pool.query(sql, params);\n\n return result.rows.map((row: RunRow) => ({\n run_id: row.run_id,\n thread_id: row.thread_id,\n assistant_id: row.assistant_id,\n created_at: new Date(row.created_at).toISOString(),\n updated_at: new Date(row.updated_at).toISOString(),\n status: row.status as RunStatus,\n metadata: row.metadata,\n multitask_strategy: row.multitask_strategy as 'reject',\n }));\n }\n\n async updateRun(runId: string, run: Partial<Run>): Promise<void> {\n // 检查运行是否存在\n const existingRun = await this.pool.query('SELECT run_id FROM runs WHERE run_id = $1', [runId]);\n if (existingRun.rows.length === 0) {\n throw new Error(`Run with ID ${runId} not found.`);\n }\n\n const updateFields: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n if (run.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n values.push(run.status);\n }\n\n if (run.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n values.push(JSON.stringify(run.metadata));\n }\n\n if (run.multitask_strategy !== undefined) {\n updateFields.push(`multitask_strategy = $${paramIndex++}`);\n values.push(run.multitask_strategy);\n }\n\n // 总是更新 updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n values.push(new Date());\n\n if (updateFields.length > 0) {\n values.push(runId);\n await this.pool.query(\n `\n UPDATE runs \n SET ${updateFields.join(', ')} \n WHERE run_id = $${paramIndex}\n `,\n values,\n );\n }\n }\n}\n"],"names":[],"mappings":"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"}