@langgraph-js/pure-graph 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,9 @@ import { zValidator } from '@hono/zod-validator';
2
2
  import { Hono } from 'hono';
3
3
  import { streamSSE } from 'hono/streaming';
4
4
  import { client } from './endpoint';
5
- import { ThreadIdParamSchema, RunIdParamSchema, RunStreamPayloadSchema, RunListQuerySchema, RunCancelQuerySchema, } from '../zod';
5
+ import { ThreadIdParamSchema, RunIdParamSchema, RunStreamPayloadSchema, RunListQuerySchema, RunCancelQuerySchema, ThreadStateUpdate, } from '../zod';
6
6
  import { serialiseAsDict } from '../../graph/stream';
7
+ import z from 'zod';
7
8
  const api = new Hono();
8
9
  // 最常用的对话接口
9
10
  api.post('/threads/:thread_id/runs/stream', zValidator('param', ThreadIdParamSchema), zValidator('json', RunStreamPayloadSchema), async (c) => {
@@ -34,4 +35,20 @@ api.post('/threads/:thread_id/runs/:run_id/cancel', zValidator('param', RunIdPar
34
35
  }
35
36
  return c.body(null, wait ? 204 : 202);
36
37
  });
38
+ api.post('/threads/:thread_id/state', zValidator('param', z.object({ thread_id: z.string().uuid() })), zValidator('json', ThreadStateUpdate), async (c) => {
39
+ // Update Thread State
40
+ const { thread_id } = c.req.valid('param');
41
+ const payload = c.req.valid('json');
42
+ // const config: RunnableConfig = { configurable: { thread_id } };
43
+ // if (payload.checkpoint_id) {
44
+ // config.configurable ??= {};
45
+ // config.configurable.checkpoint_id = payload.checkpoint_id;
46
+ // }
47
+ // if (payload.checkpoint) {
48
+ // config.configurable ??= {};
49
+ // Object.assign(config.configurable, payload.checkpoint);
50
+ // }
51
+ const inserted = await client.threads.updateState(thread_id, payload);
52
+ return c.json(inserted);
53
+ });
37
54
  export default api;
@@ -0,0 +1,203 @@
1
+ import z from 'zod';
2
+ export declare const AssistantConfigurable: z.ZodObject<{
3
+ thread_id: z.ZodOptional<z.ZodString>;
4
+ thread_ts: z.ZodOptional<z.ZodString>;
5
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
6
+ thread_id: z.ZodOptional<z.ZodString>;
7
+ thread_ts: z.ZodOptional<z.ZodString>;
8
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
9
+ thread_id: z.ZodOptional<z.ZodString>;
10
+ thread_ts: z.ZodOptional<z.ZodString>;
11
+ }, z.ZodUnknown, "strip">>;
12
+ export declare const AssistantConfig: z.ZodObject<{
13
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
14
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
15
+ configurable: z.ZodOptional<z.ZodObject<{
16
+ thread_id: z.ZodOptional<z.ZodString>;
17
+ thread_ts: z.ZodOptional<z.ZodString>;
18
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
19
+ thread_id: z.ZodOptional<z.ZodString>;
20
+ thread_ts: z.ZodOptional<z.ZodString>;
21
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
22
+ thread_id: z.ZodOptional<z.ZodString>;
23
+ thread_ts: z.ZodOptional<z.ZodString>;
24
+ }, z.ZodUnknown, "strip">>>;
25
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
26
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
27
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
28
+ configurable: z.ZodOptional<z.ZodObject<{
29
+ thread_id: z.ZodOptional<z.ZodString>;
30
+ thread_ts: z.ZodOptional<z.ZodString>;
31
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
32
+ thread_id: z.ZodOptional<z.ZodString>;
33
+ thread_ts: z.ZodOptional<z.ZodString>;
34
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
35
+ thread_id: z.ZodOptional<z.ZodString>;
36
+ thread_ts: z.ZodOptional<z.ZodString>;
37
+ }, z.ZodUnknown, "strip">>>;
38
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
39
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
41
+ configurable: z.ZodOptional<z.ZodObject<{
42
+ thread_id: z.ZodOptional<z.ZodString>;
43
+ thread_ts: z.ZodOptional<z.ZodString>;
44
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
45
+ thread_id: z.ZodOptional<z.ZodString>;
46
+ thread_ts: z.ZodOptional<z.ZodString>;
47
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
48
+ thread_id: z.ZodOptional<z.ZodString>;
49
+ thread_ts: z.ZodOptional<z.ZodString>;
50
+ }, z.ZodUnknown, "strip">>>;
51
+ }, z.ZodUnknown, "strip">>;
52
+ export declare const Assistant: z.ZodObject<{
53
+ assistant_id: z.ZodString;
54
+ graph_id: z.ZodString;
55
+ config: z.ZodObject<{
56
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
57
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
58
+ configurable: z.ZodOptional<z.ZodObject<{
59
+ thread_id: z.ZodOptional<z.ZodString>;
60
+ thread_ts: z.ZodOptional<z.ZodString>;
61
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
62
+ thread_id: z.ZodOptional<z.ZodString>;
63
+ thread_ts: z.ZodOptional<z.ZodString>;
64
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
65
+ thread_id: z.ZodOptional<z.ZodString>;
66
+ thread_ts: z.ZodOptional<z.ZodString>;
67
+ }, z.ZodUnknown, "strip">>>;
68
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
69
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
70
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
71
+ configurable: z.ZodOptional<z.ZodObject<{
72
+ thread_id: z.ZodOptional<z.ZodString>;
73
+ thread_ts: z.ZodOptional<z.ZodString>;
74
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
75
+ thread_id: z.ZodOptional<z.ZodString>;
76
+ thread_ts: z.ZodOptional<z.ZodString>;
77
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
78
+ thread_id: z.ZodOptional<z.ZodString>;
79
+ thread_ts: z.ZodOptional<z.ZodString>;
80
+ }, z.ZodUnknown, "strip">>>;
81
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
82
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
83
+ recursion_limit: z.ZodOptional<z.ZodNumber>;
84
+ configurable: z.ZodOptional<z.ZodObject<{
85
+ thread_id: z.ZodOptional<z.ZodString>;
86
+ thread_ts: z.ZodOptional<z.ZodString>;
87
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
88
+ thread_id: z.ZodOptional<z.ZodString>;
89
+ thread_ts: z.ZodOptional<z.ZodString>;
90
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
91
+ thread_id: z.ZodOptional<z.ZodString>;
92
+ thread_ts: z.ZodOptional<z.ZodString>;
93
+ }, z.ZodUnknown, "strip">>>;
94
+ }, z.ZodUnknown, "strip">>;
95
+ created_at: z.ZodString;
96
+ updated_at: z.ZodString;
97
+ metadata: z.ZodObject<{}, "strip", z.ZodAny, z.objectOutputType<{}, z.ZodAny, "strip">, z.objectInputType<{}, z.ZodAny, "strip">>;
98
+ }, "strip", z.ZodTypeAny, {
99
+ created_at: string;
100
+ updated_at: string;
101
+ assistant_id: string;
102
+ graph_id: string;
103
+ metadata: {} & {
104
+ [k: string]: any;
105
+ };
106
+ config: {
107
+ configurable?: z.objectOutputType<{
108
+ thread_id: z.ZodOptional<z.ZodString>;
109
+ thread_ts: z.ZodOptional<z.ZodString>;
110
+ }, z.ZodUnknown, "strip"> | undefined;
111
+ tags?: string[] | undefined;
112
+ recursion_limit?: number | undefined;
113
+ } & {
114
+ [k: string]: unknown;
115
+ };
116
+ }, {
117
+ created_at: string;
118
+ updated_at: string;
119
+ assistant_id: string;
120
+ graph_id: string;
121
+ metadata: {} & {
122
+ [k: string]: any;
123
+ };
124
+ config: {
125
+ configurable?: z.objectInputType<{
126
+ thread_id: z.ZodOptional<z.ZodString>;
127
+ thread_ts: z.ZodOptional<z.ZodString>;
128
+ }, z.ZodUnknown, "strip"> | undefined;
129
+ tags?: string[] | undefined;
130
+ recursion_limit?: number | undefined;
131
+ } & {
132
+ [k: string]: unknown;
133
+ };
134
+ }>;
135
+ export declare const MetadataSchema: z.ZodObject<{
136
+ source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
137
+ step: z.ZodOptional<z.ZodNumber>;
138
+ writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
139
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
140
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
141
+ source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
142
+ step: z.ZodOptional<z.ZodNumber>;
143
+ writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
144
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
145
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
146
+ source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
147
+ step: z.ZodOptional<z.ZodNumber>;
148
+ writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
149
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
150
+ }, z.ZodUnknown, "strip">>;
151
+ export declare const SendSchema: z.ZodObject<{
152
+ node: z.ZodString;
153
+ input: z.ZodNullable<z.ZodUnknown>;
154
+ }, "strip", z.ZodTypeAny, {
155
+ node: string;
156
+ input?: unknown;
157
+ }, {
158
+ node: string;
159
+ input?: unknown;
160
+ }>;
161
+ export declare const CommandSchema: z.ZodObject<{
162
+ update: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodUnknown], null>, "many">]>>>;
163
+ resume: z.ZodOptional<z.ZodUnknown>;
164
+ goto: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
165
+ node: z.ZodString;
166
+ input: z.ZodNullable<z.ZodUnknown>;
167
+ }, "strip", z.ZodTypeAny, {
168
+ node: string;
169
+ input?: unknown;
170
+ }, {
171
+ node: string;
172
+ input?: unknown;
173
+ }>, z.ZodArray<z.ZodObject<{
174
+ node: z.ZodString;
175
+ input: z.ZodNullable<z.ZodUnknown>;
176
+ }, "strip", z.ZodTypeAny, {
177
+ node: string;
178
+ input?: unknown;
179
+ }, {
180
+ node: string;
181
+ input?: unknown;
182
+ }>, "many">, z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
183
+ }, "strip", z.ZodTypeAny, {
184
+ update?: Record<string, unknown> | [string, unknown][] | null | undefined;
185
+ resume?: unknown;
186
+ goto?: string | string[] | {
187
+ node: string;
188
+ input?: unknown;
189
+ } | {
190
+ node: string;
191
+ input?: unknown;
192
+ }[] | undefined;
193
+ }, {
194
+ update?: Record<string, unknown> | [string, unknown][] | null | undefined;
195
+ resume?: unknown;
196
+ goto?: string | string[] | {
197
+ node: string;
198
+ input?: unknown;
199
+ } | {
200
+ node: string;
201
+ input?: unknown;
202
+ }[] | undefined;
203
+ }>;
@@ -0,0 +1,43 @@
1
+ import z from 'zod';
2
+ export const AssistantConfigurable = z
3
+ .object({
4
+ thread_id: z.string().optional(),
5
+ thread_ts: z.string().optional(),
6
+ })
7
+ .catchall(z.unknown());
8
+ export const AssistantConfig = z
9
+ .object({
10
+ tags: z.array(z.string()).optional(),
11
+ recursion_limit: z.number().int().optional(),
12
+ configurable: AssistantConfigurable.optional(),
13
+ })
14
+ .catchall(z.unknown())
15
+ .describe('The configuration of an assistant.');
16
+ export const Assistant = z.object({
17
+ assistant_id: z.string().uuid(),
18
+ graph_id: z.string(),
19
+ config: AssistantConfig,
20
+ created_at: z.string(),
21
+ updated_at: z.string(),
22
+ metadata: z.object({}).catchall(z.any()),
23
+ });
24
+ export const MetadataSchema = z
25
+ .object({
26
+ source: z.union([z.literal('input'), z.literal('loop'), z.literal('update'), z.string()]).optional(),
27
+ step: z.number().optional(),
28
+ writes: z.record(z.unknown()).nullable().optional(),
29
+ parents: z.record(z.string()).optional(),
30
+ })
31
+ .catchall(z.unknown());
32
+ export const SendSchema = z.object({
33
+ node: z.string(),
34
+ input: z.unknown().nullable(),
35
+ });
36
+ export const CommandSchema = z.object({
37
+ update: z
38
+ .union([z.record(z.unknown()), z.array(z.tuple([z.string(), z.unknown()]))])
39
+ .nullable()
40
+ .optional(),
41
+ resume: z.unknown().optional(),
42
+ goto: z.union([SendSchema, z.array(SendSchema), z.string(), z.array(z.string())]).optional(),
43
+ });
@@ -1,7 +1,7 @@
1
1
  /** @ts-ignore */
2
2
  import { NextResponse } from 'next/server';
3
3
  import { client } from './endpoint';
4
- import { AssistantsSearchSchema, AssistantGraphQuerySchema, RunStreamPayloadSchema, RunListQuerySchema, RunCancelQuerySchema, ThreadCreatePayloadSchema, ThreadSearchPayloadSchema, } from '../zod';
4
+ import { AssistantsSearchSchema, AssistantGraphQuerySchema, RunStreamPayloadSchema, RunListQuerySchema, RunCancelQuerySchema, ThreadCreatePayloadSchema, ThreadSearchPayloadSchema, ThreadStateUpdate, } from '../zod';
5
5
  import { serialiseAsDict } from '../../graph/stream';
6
6
  // Next.js App Router 的 SSE 响应实现
7
7
  async function sseResponse(generator) {
@@ -120,6 +120,17 @@ export async function POST(req) {
120
120
  headers: { 'X-Pagination-Total': String(result.length) },
121
121
  });
122
122
  }
123
+ // Threads state update
124
+ if (pathname.match(/\/threads\/[0-9a-fA-F-]{36}\/state$/)) {
125
+ const match = pathname.match(/\/threads\/([0-9a-fA-F-]{36})\/state$/);
126
+ if (match) {
127
+ const thread_id = match[1];
128
+ const body = await req.json();
129
+ const payload = ThreadStateUpdate.parse(body);
130
+ const result = await client.threads.updateState(thread_id, payload);
131
+ return NextResponse.json(result);
132
+ }
133
+ }
123
134
  // Runs routes - stream
124
135
  if (pathname.match(/\/threads\/[0-9a-fA-F-]{36}\/runs\/stream$/)) {
125
136
  const match = pathname.match(/\/threads\/([0-9a-fA-F-]{36})\/runs\/stream$/);
@@ -101,6 +101,7 @@ export declare const Assistant: z.ZodObject<{
101
101
  metadata: {} & {
102
102
  [k: string]: any;
103
103
  };
104
+ graph_id: string;
104
105
  assistant_id: string;
105
106
  config: {
106
107
  configurable?: z.objectOutputType<{
@@ -112,13 +113,13 @@ export declare const Assistant: z.ZodObject<{
112
113
  } & {
113
114
  [k: string]: unknown;
114
115
  };
115
- graph_id: string;
116
116
  }, {
117
117
  created_at: string;
118
118
  updated_at: string;
119
119
  metadata: {} & {
120
120
  [k: string]: any;
121
121
  };
122
+ graph_id: string;
122
123
  assistant_id: string;
123
124
  config: {
124
125
  configurable?: z.objectInputType<{
@@ -130,7 +131,6 @@ export declare const Assistant: z.ZodObject<{
130
131
  } & {
131
132
  [k: string]: unknown;
132
133
  };
133
- graph_id: string;
134
134
  }>;
135
135
  export declare const MetadataSchema: z.ZodObject<{
136
136
  source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
@@ -101,6 +101,7 @@ export declare const Assistant: z.ZodObject<{
101
101
  metadata: {} & {
102
102
  [k: string]: any;
103
103
  };
104
+ graph_id: string;
104
105
  assistant_id: string;
105
106
  config: {
106
107
  configurable?: z.objectOutputType<{
@@ -112,13 +113,13 @@ export declare const Assistant: z.ZodObject<{
112
113
  } & {
113
114
  [k: string]: unknown;
114
115
  };
115
- graph_id: string;
116
116
  }, {
117
117
  created_at: string;
118
118
  updated_at: string;
119
119
  metadata: {} & {
120
120
  [k: string]: any;
121
121
  };
122
+ graph_id: string;
122
123
  assistant_id: string;
123
124
  config: {
124
125
  configurable?: z.objectInputType<{
@@ -130,7 +131,6 @@ export declare const Assistant: z.ZodObject<{
130
131
  } & {
131
132
  [k: string]: unknown;
132
133
  };
133
- graph_id: string;
134
134
  }>;
135
135
  export declare const MetadataSchema: z.ZodObject<{
136
136
  source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
@@ -255,9 +255,9 @@ export declare const AssistantsSearchSchema: z.ZodObject<{
255
255
  writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
256
256
  parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
257
257
  }, z.ZodUnknown, "strip"> | undefined;
258
+ graph_id?: string | undefined;
258
259
  limit?: number | undefined;
259
260
  offset?: number | undefined;
260
- graph_id?: string | undefined;
261
261
  }, {
262
262
  metadata?: z.objectInputType<{
263
263
  source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
@@ -265,9 +265,9 @@ export declare const AssistantsSearchSchema: z.ZodObject<{
265
265
  writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
266
266
  parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
267
267
  }, z.ZodUnknown, "strip"> | undefined;
268
+ graph_id?: string | undefined;
268
269
  limit?: number | undefined;
269
270
  offset?: number | undefined;
270
- graph_id?: string | undefined;
271
271
  }>;
272
272
  export declare const AssistantGraphQuerySchema: z.ZodObject<{
273
273
  xray: z.ZodOptional<z.ZodString>;
@@ -395,13 +395,13 @@ export declare const RunStreamPayloadSchema: z.ZodObject<{
395
395
  }, "strip", z.ZodTypeAny, {
396
396
  assistant_id: string;
397
397
  on_disconnect: "cancel" | "continue";
398
+ input?: any;
398
399
  metadata?: z.objectOutputType<{
399
400
  source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
400
401
  step: z.ZodOptional<z.ZodNumber>;
401
402
  writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
402
403
  parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
403
404
  }, z.ZodUnknown, "strip"> | undefined;
404
- input?: any;
405
405
  multitask_strategy?: "reject" | "interrupt" | "rollback" | "enqueue" | undefined;
406
406
  checkpoint_id?: string | undefined;
407
407
  config?: z.objectOutputType<{
@@ -432,7 +432,7 @@ export declare const RunStreamPayloadSchema: z.ZodObject<{
432
432
  webhook?: string | undefined;
433
433
  interrupt_before?: string[] | "*" | undefined;
434
434
  interrupt_after?: string[] | "*" | undefined;
435
- stream_mode?: ("values" | "events" | "messages" | "updates" | "debug" | "custom" | "messages-tuple")[] | undefined;
435
+ stream_mode?: ("values" | "updates" | "debug" | "messages" | "custom" | "events" | "messages-tuple")[] | undefined;
436
436
  stream_subgraphs?: boolean | undefined;
437
437
  stream_resumable?: boolean | undefined;
438
438
  after_seconds?: number | undefined;
@@ -442,13 +442,13 @@ export declare const RunStreamPayloadSchema: z.ZodObject<{
442
442
  langsmith_tracer?: unknown;
443
443
  }, {
444
444
  assistant_id: string;
445
+ input?: any;
445
446
  metadata?: z.objectInputType<{
446
447
  source: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"input">, z.ZodLiteral<"loop">, z.ZodLiteral<"update">, z.ZodString]>>;
447
448
  step: z.ZodOptional<z.ZodNumber>;
448
449
  writes: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
449
450
  parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
450
451
  }, z.ZodUnknown, "strip"> | undefined;
451
- input?: any;
452
452
  multitask_strategy?: "reject" | "interrupt" | "rollback" | "enqueue" | undefined;
453
453
  checkpoint_id?: string | undefined;
454
454
  config?: z.objectInputType<{
@@ -480,7 +480,7 @@ export declare const RunStreamPayloadSchema: z.ZodObject<{
480
480
  interrupt_before?: string[] | "*" | undefined;
481
481
  interrupt_after?: string[] | "*" | undefined;
482
482
  on_disconnect?: "cancel" | "continue" | undefined;
483
- stream_mode?: ("values" | "events" | "messages" | "updates" | "debug" | "custom" | "messages-tuple")[] | undefined;
483
+ stream_mode?: ("values" | "updates" | "debug" | "messages" | "custom" | "events" | "messages-tuple")[] | undefined;
484
484
  stream_subgraphs?: boolean | undefined;
485
485
  stream_resumable?: boolean | undefined;
486
486
  after_seconds?: number | undefined;
@@ -575,3 +575,10 @@ export declare const ThreadSearchPayloadSchema: z.ZodObject<{
575
575
  sort_by?: "thread_id" | "status" | "created_at" | "updated_at" | undefined;
576
576
  sort_order?: "asc" | "desc" | undefined;
577
577
  }>;
578
+ export declare const ThreadStateUpdate: z.ZodObject<{
579
+ values: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">]>>>;
580
+ }, "strip", z.ZodTypeAny, {
581
+ values?: Record<string, unknown> | Record<string, unknown>[] | null | undefined;
582
+ }, {
583
+ values?: Record<string, unknown> | Record<string, unknown>[] | null | undefined;
584
+ }>;
@@ -117,3 +117,11 @@ export const ThreadSearchPayloadSchema = z
117
117
  sort_order: z.enum(['asc', 'desc']).describe('Sort order.').optional(),
118
118
  })
119
119
  .describe('Payload for listing threads.');
120
+ export const ThreadStateUpdate = z
121
+ .object({
122
+ values: z.union([z.record(z.string(), z.unknown()), z.array(z.record(z.string(), z.unknown()))]).nullish(),
123
+ // as_node: z.string().optional(),
124
+ // checkpoint_id: z.string().optional(),
125
+ // checkpoint: CheckpointSchema.nullish(),
126
+ })
127
+ .describe('Payload for adding state to a thread.');
package/dist/global.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { SqliteSaver } from './storage/sqlite/checkpoint.js';
2
2
  export declare class LangGraphGlobal {
3
3
  static globalMessageQueue: import("./queue/stream_queue.js").StreamQueueManager<import("./queue/stream_queue.js").BaseStreamQueueInterface>;
4
- static globalCheckPointer: SqliteSaver | import("@langchain/langgraph-checkpoint-redis").RedisSaver | import("@langchain/langgraph-checkpoint-redis/shallow").ShallowRedisSaver | import("@langchain/langgraph-checkpoint").MemorySaver;
4
+ static globalCheckPointer: import("@langchain/langgraph-checkpoint-redis").RedisSaver | import("@langchain/langgraph-checkpoint-redis/shallow").ShallowRedisSaver | SqliteSaver | import("@langchain/langgraph-checkpoint").MemorySaver;
5
5
  static globalThreadsManager: import("./storage/sqlite/threads.js").SQLiteThreadsManager<unknown> | import("./storage/memory/threads.js").MemoryThreadsManager<unknown>;
6
6
  }
@@ -3,7 +3,7 @@ import { MemorySaver } from './memory/checkpoint';
3
3
  import { MemoryThreadsManager } from './memory/threads';
4
4
  import type { SqliteSaver as SqliteSaverType } from './sqlite/checkpoint';
5
5
  import { SQLiteThreadsManager } from './sqlite/threads';
6
- export declare const createCheckPointer: () => Promise<SqliteSaverType | import("@langchain/langgraph-checkpoint-redis").RedisSaver | import("@langchain/langgraph-checkpoint-redis/shallow").ShallowRedisSaver | MemorySaver>;
6
+ export declare const createCheckPointer: () => Promise<import("@langchain/langgraph-checkpoint-redis").RedisSaver | import("@langchain/langgraph-checkpoint-redis/shallow").ShallowRedisSaver | SqliteSaverType | MemorySaver>;
7
7
  export declare const createMessageQueue: () => Promise<StreamQueueManager<BaseStreamQueueInterface>>;
8
8
  export declare const createThreadManager: (config: {
9
9
  checkpointer?: SqliteSaverType;
@@ -1,6 +1,6 @@
1
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 {
2
+ import { Command, Config, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
3
+ export declare class MemoryThreadsManager<ValuesType = unknown> implements BaseThreadsManager<ValuesType> {
4
4
  private threads;
5
5
  create(payload?: {
6
6
  metadata?: Metadata;
@@ -26,6 +26,7 @@ export declare class MemoryThreadsManager<ValuesType = unknown> extends BaseThre
26
26
  get(threadId: string): Promise<Thread<ValuesType>>;
27
27
  set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void>;
28
28
  delete(threadId: string): Promise<void>;
29
+ updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>>;
29
30
  runs: Run[];
30
31
  createRun(threadId: string, assistantId: string, payload?: {
31
32
  metadata?: Metadata;
@@ -1,5 +1,6 @@
1
- import { BaseThreadsManager } from '../../threads/index.js';
2
- export class MemoryThreadsManager extends BaseThreadsManager {
1
+ import { getGraph } from '../../utils/getGraph.js';
2
+ import { serialiseAsDict } from '../../graph/stream.js';
3
+ export class MemoryThreadsManager {
3
4
  threads = [];
4
5
  async create(payload) {
5
6
  const threadId = payload?.threadId || crypto.randomUUID();
@@ -79,6 +80,32 @@ export class MemoryThreadsManager extends BaseThreadsManager {
79
80
  throw new Error(`Thread with ID ${threadId} not found.`);
80
81
  }
81
82
  }
83
+ async updateState(threadId, thread) {
84
+ const index = this.threads.findIndex((t) => t.thread_id === threadId);
85
+ if (index === -1) {
86
+ throw new Error(`Thread with ID ${threadId} not found.`);
87
+ }
88
+ const targetThread = this.threads[index];
89
+ if (targetThread.status === 'busy') {
90
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
91
+ }
92
+ this.threads[index] = { ...targetThread, values: thread.values };
93
+ if (!targetThread.metadata?.graph_id) {
94
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
95
+ }
96
+ const graphId = targetThread.metadata?.graph_id;
97
+ const config = {
98
+ configurable: {
99
+ thread_id: threadId,
100
+ graph_id: graphId,
101
+ },
102
+ };
103
+ const graph = await getGraph(graphId, config);
104
+ const nextConfig = await graph.updateState(config, thread.values);
105
+ const graphState = await graph.getState(config);
106
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
107
+ return nextConfig;
108
+ }
82
109
  runs = [];
83
110
  async createRun(threadId, assistantId, payload) {
84
111
  const runId = crypto.randomUUID();
@@ -1,8 +1,8 @@
1
1
  import { BaseThreadsManager } from '../../threads/index.js';
2
- import { Command, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
2
+ import { Command, Config, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
3
3
  import type { SqliteSaver } from './checkpoint.js';
4
4
  import type { DatabaseType } from './type.js';
5
- export declare class SQLiteThreadsManager<ValuesType = unknown> extends BaseThreadsManager {
5
+ export declare class SQLiteThreadsManager<ValuesType = unknown> implements BaseThreadsManager<ValuesType> {
6
6
  db: DatabaseType;
7
7
  private isSetup;
8
8
  constructor(checkpointer: SqliteSaver);
@@ -30,6 +30,7 @@ export declare class SQLiteThreadsManager<ValuesType = unknown> extends BaseThre
30
30
  }): Promise<Thread<ValuesType>[]>;
31
31
  get(threadId: string): Promise<Thread<ValuesType>>;
32
32
  set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void>;
33
+ updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>>;
33
34
  delete(threadId: string): Promise<void>;
34
35
  createRun(threadId: string, assistantId: string, payload?: {
35
36
  metadata?: Metadata;
@@ -1,9 +1,9 @@
1
- import { BaseThreadsManager } from '../../threads/index.js';
2
- export class SQLiteThreadsManager extends BaseThreadsManager {
1
+ import { getGraph } from '../../utils/getGraph.js';
2
+ import { serialiseAsDict } from '../../graph/stream.js';
3
+ export class SQLiteThreadsManager {
3
4
  db;
4
5
  isSetup = false;
5
6
  constructor(checkpointer) {
6
- super();
7
7
  this.db = checkpointer.db;
8
8
  this.setup();
9
9
  }
@@ -174,6 +174,40 @@ export class SQLiteThreadsManager extends BaseThreadsManager {
174
174
  .run(...values);
175
175
  }
176
176
  }
177
+ async updateState(threadId, thread) {
178
+ // 从数据库查询线程信息
179
+ const row = this.db.prepare('SELECT * FROM threads WHERE thread_id = ?').get(threadId);
180
+ if (!row) {
181
+ throw new Error(`Thread with ID ${threadId} not found.`);
182
+ }
183
+ const targetThread = {
184
+ thread_id: row.thread_id,
185
+ created_at: row.created_at,
186
+ updated_at: row.updated_at,
187
+ metadata: JSON.parse(row.metadata),
188
+ status: row.status,
189
+ values: row.values ? JSON.parse(row.values) : null,
190
+ interrupts: JSON.parse(row.interrupts),
191
+ };
192
+ if (targetThread.status === 'busy') {
193
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
194
+ }
195
+ if (!targetThread.metadata?.graph_id) {
196
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
197
+ }
198
+ const graphId = targetThread.metadata?.graph_id;
199
+ const config = {
200
+ configurable: {
201
+ thread_id: threadId,
202
+ graph_id: graphId,
203
+ },
204
+ };
205
+ const graph = await getGraph(graphId, config);
206
+ const nextConfig = await graph.updateState(config, thread.values);
207
+ const graphState = await graph.getState(config);
208
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) });
209
+ return nextConfig;
210
+ }
177
211
  async delete(threadId) {
178
212
  const result = this.db.prepare('DELETE FROM threads WHERE thread_id = ?').run(threadId);
179
213
  if (result.changes === 0) {
@@ -1,5 +1,5 @@
1
- import { Command, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
2
- export declare class BaseThreadsManager<ValuesType = unknown> {
1
+ import { Command, Config, Metadata, OnConflictBehavior, Run, RunStatus, SortOrder, Thread, ThreadSortBy, ThreadStatus } from '@langgraph-js/sdk';
2
+ export interface BaseThreadsManager<ValuesType = unknown> {
3
3
  create(payload?: {
4
4
  metadata?: Metadata;
5
5
  threadId?: string;
@@ -24,6 +24,7 @@ export declare class BaseThreadsManager<ValuesType = unknown> {
24
24
  }): Promise<Thread<ValuesType>[]>;
25
25
  get(threadId: string): Promise<Thread<ValuesType>>;
26
26
  delete(threadId: string): Promise<void>;
27
+ updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>>;
27
28
  createRun(threadId: string, assistantId: string, payload?: {
28
29
  metadata?: Metadata;
29
30
  }): Promise<Run>;
@@ -1,26 +1 @@
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
- }
1
+ export {};
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Thread, Assistant, Run, StreamMode, Command, Metadata, AssistantGraph, OnConflictBehavior, ThreadStatus, Checkpoint } from '@langchain/langgraph-sdk';
1
+ import { Thread, Assistant, Run, StreamMode, Command, Metadata, AssistantGraph, OnConflictBehavior, ThreadStatus, Checkpoint, Config } from '@langchain/langgraph-sdk';
2
2
  import { StreamEvent } from '@langchain/core/tracers/log_stream';
3
3
  import { EventMessage } from './queue/event_message';
4
4
  import { RunnableConfig } from '@langchain/core/runnables';
@@ -71,6 +71,7 @@ export interface ILangGraphClient<TStateType = unknown> {
71
71
  }): Promise<Thread<TStateType>[]>;
72
72
  get(threadId: string): Promise<Thread<TStateType>>;
73
73
  delete(threadId: string): Promise<void>;
74
+ updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<Config, 'configurable'>>;
74
75
  };
75
76
  runs: {
76
77
  list(threadId: string, options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgraph-js/pure-graph",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -17,12 +17,12 @@
17
17
  "zod": "^3"
18
18
  },
19
19
  "optionalDependencies": {
20
+ "@langchain/langgraph-checkpoint-redis": "^0.0.2",
20
21
  "@hono/zod-validator": "^0.7.3",
21
22
  "hono": "^4.9.9",
22
23
  "redis": "^5.8.3"
23
24
  },
24
25
  "devDependencies": {
25
- "@langchain/langgraph-checkpoint-redis": "^0.0.2",
26
26
  "@langchain/langgraph-sdk": "^0.1.7",
27
27
  "@langchain/openai": "^0.6.14",
28
28
  "@langgraph-js/sdk": "^2.0.1",
@@ -9,8 +9,11 @@ import {
9
9
  RunStreamPayloadSchema,
10
10
  RunListQuerySchema,
11
11
  RunCancelQuerySchema,
12
+ ThreadStateUpdate,
12
13
  } from '../zod';
13
14
  import { serialiseAsDict } from '../../graph/stream';
15
+ import { RunnableConfig } from '@langchain/core/runnables';
16
+ import z from 'zod';
14
17
 
15
18
  const api = new Hono();
16
19
 
@@ -62,4 +65,28 @@ api.post(
62
65
  },
63
66
  );
64
67
 
68
+ api.post(
69
+ '/threads/:thread_id/state',
70
+ zValidator('param', z.object({ thread_id: z.string().uuid() })),
71
+ zValidator('json', ThreadStateUpdate),
72
+ async (c) => {
73
+ // Update Thread State
74
+ const { thread_id } = c.req.valid('param');
75
+ const payload = c.req.valid('json');
76
+ // const config: RunnableConfig = { configurable: { thread_id } };
77
+
78
+ // if (payload.checkpoint_id) {
79
+ // config.configurable ??= {};
80
+ // config.configurable.checkpoint_id = payload.checkpoint_id;
81
+ // }
82
+ // if (payload.checkpoint) {
83
+ // config.configurable ??= {};
84
+ // Object.assign(config.configurable, payload.checkpoint);
85
+ // }
86
+
87
+ const inserted = await client.threads.updateState(thread_id, payload);
88
+
89
+ return c.json(inserted);
90
+ },
91
+ );
65
92
  export default api;
@@ -9,6 +9,7 @@ import {
9
9
  RunCancelQuerySchema,
10
10
  ThreadCreatePayloadSchema,
11
11
  ThreadSearchPayloadSchema,
12
+ ThreadStateUpdate,
12
13
  } from '../zod';
13
14
  import { serialiseAsDict } from '../../graph/stream';
14
15
 
@@ -141,6 +142,18 @@ export async function POST(req: NextRequest) {
141
142
  });
142
143
  }
143
144
 
145
+ // Threads state update
146
+ if (pathname.match(/\/threads\/[0-9a-fA-F-]{36}\/state$/)) {
147
+ const match = pathname.match(/\/threads\/([0-9a-fA-F-]{36})\/state$/);
148
+ if (match) {
149
+ const thread_id = match[1];
150
+ const body = await req.json();
151
+ const payload = ThreadStateUpdate.parse(body);
152
+ const result = await client.threads.updateState(thread_id, payload);
153
+ return NextResponse.json(result);
154
+ }
155
+ }
156
+
144
157
  // Runs routes - stream
145
158
  if (pathname.match(/\/threads\/[0-9a-fA-F-]{36}\/runs\/stream$/)) {
146
159
  const match = pathname.match(/\/threads\/([0-9a-fA-F-]{36})\/runs\/stream$/);
@@ -133,3 +133,12 @@ export const ThreadSearchPayloadSchema = z
133
133
  sort_order: z.enum(['asc', 'desc']).describe('Sort order.').optional(),
134
134
  })
135
135
  .describe('Payload for listing threads.');
136
+
137
+ export const ThreadStateUpdate = z
138
+ .object({
139
+ values: z.union([z.record(z.string(), z.unknown()), z.array(z.record(z.string(), z.unknown()))]).nullish(),
140
+ // as_node: z.string().optional(),
141
+ // checkpoint_id: z.string().optional(),
142
+ // checkpoint: CheckpointSchema.nullish(),
143
+ })
144
+ .describe('Payload for adding state to a thread.');
@@ -1,6 +1,7 @@
1
1
  import { BaseThreadsManager } from '../../threads/index.js';
2
2
  import {
3
3
  Command,
4
+ Config,
4
5
  Metadata,
5
6
  OnConflictBehavior,
6
7
  Run,
@@ -10,8 +11,10 @@ import {
10
11
  ThreadSortBy,
11
12
  ThreadStatus,
12
13
  } from '@langgraph-js/sdk';
14
+ import { getGraph } from '../../utils/getGraph.js';
15
+ import { serialiseAsDict } from '../../graph/stream.js';
13
16
 
14
- export class MemoryThreadsManager<ValuesType = unknown> extends BaseThreadsManager {
17
+ export class MemoryThreadsManager<ValuesType = unknown> implements BaseThreadsManager<ValuesType> {
15
18
  private threads: Thread<ValuesType>[] = [];
16
19
 
17
20
  async create(payload?: {
@@ -115,6 +118,32 @@ export class MemoryThreadsManager<ValuesType = unknown> extends BaseThreadsManag
115
118
  throw new Error(`Thread with ID ${threadId} not found.`);
116
119
  }
117
120
  }
121
+ async updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>> {
122
+ const index = this.threads.findIndex((t) => t.thread_id === threadId) as number;
123
+ if (index === -1) {
124
+ throw new Error(`Thread with ID ${threadId} not found.`);
125
+ }
126
+ const targetThread = this.threads[index];
127
+ if (targetThread.status === 'busy') {
128
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
129
+ }
130
+ this.threads[index] = { ...targetThread, values: thread.values as ValuesType };
131
+ if (!targetThread.metadata?.graph_id) {
132
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
133
+ }
134
+ const graphId = targetThread.metadata?.graph_id as string;
135
+ const config = {
136
+ configurable: {
137
+ thread_id: threadId,
138
+ graph_id: graphId,
139
+ },
140
+ };
141
+ const graph = await getGraph(graphId, config);
142
+ const nextConfig = await graph.updateState(config, thread.values);
143
+ const graphState = await graph.getState(config);
144
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) as ValuesType });
145
+ return nextConfig;
146
+ }
118
147
  runs: Run[] = [];
119
148
  async createRun(threadId: string, assistantId: string, payload?: { metadata?: Metadata }): Promise<Run> {
120
149
  const runId = crypto.randomUUID();
@@ -296,7 +296,6 @@ CREATE TABLE IF NOT EXISTS writes (
296
296
  whereClause.push(
297
297
  ...Object.entries(sanitizedFilter).map(([key]) => `jsonb(CAST(metadata AS TEXT))->'$.${key}' = ?`),
298
298
  );
299
-
300
299
  if (whereClause.length > 0) {
301
300
  sql += `WHERE\n ${whereClause.join(' AND\n ')}\n`;
302
301
  }
@@ -1,6 +1,7 @@
1
1
  import { BaseThreadsManager } from '../../threads/index.js';
2
2
  import {
3
3
  Command,
4
+ Config,
4
5
  Metadata,
5
6
  OnConflictBehavior,
6
7
  Run,
@@ -12,6 +13,8 @@ import {
12
13
  } from '@langgraph-js/sdk';
13
14
  import type { SqliteSaver } from './checkpoint.js';
14
15
  import type { DatabaseType } from './type.js';
16
+ import { getGraph } from '../../utils/getGraph.js';
17
+ import { serialiseAsDict } from '../../graph/stream.js';
15
18
  interface ThreadRow {
16
19
  thread_id: string;
17
20
  created_at: string;
@@ -33,12 +36,11 @@ interface RunRow {
33
36
  multitask_strategy: string;
34
37
  }
35
38
 
36
- export class SQLiteThreadsManager<ValuesType = unknown> extends BaseThreadsManager {
39
+ export class SQLiteThreadsManager<ValuesType = unknown> implements BaseThreadsManager<ValuesType> {
37
40
  db: DatabaseType;
38
41
  private isSetup: boolean = false;
39
42
 
40
43
  constructor(checkpointer: SqliteSaver) {
41
- super();
42
44
  this.db = checkpointer.db;
43
45
  this.setup();
44
46
  }
@@ -253,6 +255,43 @@ export class SQLiteThreadsManager<ValuesType = unknown> extends BaseThreadsManag
253
255
  .run(...values);
254
256
  }
255
257
  }
258
+ async updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>> {
259
+ // 从数据库查询线程信息
260
+ const row = this.db.prepare('SELECT * FROM threads WHERE thread_id = ?').get(threadId) as ThreadRow;
261
+ if (!row) {
262
+ throw new Error(`Thread with ID ${threadId} not found.`);
263
+ }
264
+
265
+ const targetThread = {
266
+ thread_id: row.thread_id,
267
+ created_at: row.created_at,
268
+ updated_at: row.updated_at,
269
+ metadata: JSON.parse(row.metadata),
270
+ status: row.status as ThreadStatus,
271
+ values: row.values ? JSON.parse(row.values) : (null as unknown as ValuesType),
272
+ interrupts: JSON.parse(row.interrupts),
273
+ };
274
+
275
+ if (targetThread.status === 'busy') {
276
+ throw new Error(`Thread with ID ${threadId} is busy, can't update state.`);
277
+ }
278
+
279
+ if (!targetThread.metadata?.graph_id) {
280
+ throw new Error(`Thread with ID ${threadId} has no graph_id.`);
281
+ }
282
+ const graphId = targetThread.metadata?.graph_id as string;
283
+ const config = {
284
+ configurable: {
285
+ thread_id: threadId,
286
+ graph_id: graphId,
287
+ },
288
+ };
289
+ const graph = await getGraph(graphId, config);
290
+ const nextConfig = await graph.updateState(config, thread.values);
291
+ const graphState = await graph.getState(config);
292
+ await this.set(threadId, { values: JSON.parse(serialiseAsDict(graphState.values)) as ValuesType });
293
+ return nextConfig;
294
+ }
256
295
  async delete(threadId: string): Promise<void> {
257
296
  const result = this.db.prepare('DELETE FROM threads WHERE thread_id = ?').run(threadId);
258
297
  if (result.changes === 0) {
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  Command,
3
+ Config,
3
4
  Metadata,
4
5
  OnConflictBehavior,
5
6
  Run,
@@ -10,19 +11,15 @@ import {
10
11
  ThreadStatus,
11
12
  } from '@langgraph-js/sdk';
12
13
 
13
- export class BaseThreadsManager<ValuesType = unknown> {
14
+ export interface BaseThreadsManager<ValuesType = unknown> {
14
15
  create(payload?: {
15
16
  metadata?: Metadata;
16
17
  threadId?: string;
17
18
  ifExists?: OnConflictBehavior;
18
19
  graphId?: string;
19
20
  supersteps?: Array<{ updates: Array<{ values: unknown; command?: Command; asNode: string }> }>;
20
- }): Promise<Thread<ValuesType>> {
21
- throw new Error('Function not implemented.');
22
- }
23
- set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void> {
24
- throw new Error('Function not implemented.');
25
- }
21
+ }): Promise<Thread<ValuesType>>;
22
+ set(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<void>;
26
23
  search(query?: {
27
24
  metadata?: Metadata;
28
25
  limit?: number;
@@ -30,22 +27,11 @@ export class BaseThreadsManager<ValuesType = unknown> {
30
27
  status?: ThreadStatus;
31
28
  sortBy?: ThreadSortBy;
32
29
  sortOrder?: SortOrder;
33
- }): Promise<Thread<ValuesType>[]> {
34
- throw new Error('Function not implemented.');
35
- }
36
- get(threadId: string): Promise<Thread<ValuesType>> {
37
- throw new Error('Function not implemented.');
38
- }
39
- delete(threadId: string): Promise<void> {
40
- throw new Error('Function not implemented.');
41
- }
42
- createRun(threadId: string, assistantId: string, payload?: { metadata?: Metadata }): Promise<Run> {
43
- throw new Error('Function not implemented.');
44
- }
45
- listRuns(threadId: string, options?: { limit?: number; offset?: number; status?: RunStatus }): Promise<Run[]> {
46
- throw new Error('Function not implemented.');
47
- }
48
- updateRun(runId: string, run: Partial<Run>): Promise<void> {
49
- throw new Error('Function not implemented.');
50
- }
30
+ }): Promise<Thread<ValuesType>[]>;
31
+ get(threadId: string): Promise<Thread<ValuesType>>;
32
+ delete(threadId: string): Promise<void>;
33
+ updateState(threadId: string, thread: Partial<Thread<ValuesType>>): Promise<Pick<Config, 'configurable'>>;
34
+ createRun(threadId: string, assistantId: string, payload?: { metadata?: Metadata }): Promise<Run>;
35
+ listRuns(threadId: string, options?: { limit?: number; offset?: number; status?: RunStatus }): Promise<Run[]>;
36
+ updateRun(runId: string, run: Partial<Run>): Promise<void>;
51
37
  }
package/src/types.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  OnConflictBehavior,
10
10
  ThreadStatus,
11
11
  Checkpoint,
12
+ Config,
12
13
  } from '@langchain/langgraph-sdk';
13
14
  import { StreamEvent } from '@langchain/core/tracers/log_stream';
14
15
  import { EventMessage } from './queue/event_message';
@@ -87,6 +88,7 @@ export interface ILangGraphClient<TStateType = unknown> {
87
88
  }): Promise<Thread<TStateType>[]>;
88
89
  get(threadId: string): Promise<Thread<TStateType>>;
89
90
  delete(threadId: string): Promise<void>;
91
+ updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<Config, 'configurable'>>;
90
92
  };
91
93
  runs: {
92
94
  list(