@langchain/langgraph-api 0.0.17 → 0.0.19
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.
- package/dist/api/assistants.mjs +5 -3
- package/dist/api/threads.mjs +3 -0
- package/dist/cli/entrypoint.mjs +1 -1
- package/dist/cli/spawn.d.mts +3 -0
- package/dist/cli/spawn.mjs +1 -0
- package/dist/command.mjs +15 -0
- package/dist/graph/load.mjs +4 -3
- package/dist/graph/load.utils.mjs +11 -4
- package/dist/schemas.mjs +29 -23
- package/dist/server.mjs +5 -1
- package/dist/storage/ops.mjs +53 -4
- package/dist/storage/persist.mjs +5 -2
- package/dist/stream.mjs +2 -16
- package/dist/ui/bundler.d.mts +6 -0
- package/dist/ui/bundler.mjs +1 -0
- package/dist/ui/load.mjs +1 -1
- package/package.json +5 -5
package/dist/api/assistants.mjs
CHANGED
|
@@ -76,9 +76,10 @@ api.get("/assistants/:assistant_id/graph", zValidator("query", z.object({ xray:
|
|
|
76
76
|
const assistantId = getAssistantId(c.req.param("assistant_id"));
|
|
77
77
|
const assistant = await Assistants.get(assistantId);
|
|
78
78
|
const { xray } = c.req.valid("query");
|
|
79
|
-
const
|
|
79
|
+
const config = getRunnableConfig(assistant.config);
|
|
80
|
+
const graph = await getGraph(assistant.graph_id, config);
|
|
80
81
|
const drawable = await graph.getGraphAsync({
|
|
81
|
-
...
|
|
82
|
+
...config,
|
|
82
83
|
xray: xray ?? undefined,
|
|
83
84
|
});
|
|
84
85
|
return c.json(drawable.toJSON());
|
|
@@ -106,7 +107,8 @@ api.get("/assistants/:assistant_id/subgraphs/:namespace?", zValidator("param", z
|
|
|
106
107
|
const { recurse } = c.req.valid("query");
|
|
107
108
|
const assistantId = getAssistantId(assistant_id);
|
|
108
109
|
const assistant = await Assistants.get(assistantId);
|
|
109
|
-
const
|
|
110
|
+
const config = getRunnableConfig(assistant.config);
|
|
111
|
+
const graph = await getGraph(assistant.graph_id, config);
|
|
110
112
|
const graphSchema = await getGraphSchema(assistant.graph_id);
|
|
111
113
|
const rootGraphId = Object.keys(graphSchema).find((i) => !i.includes("|"));
|
|
112
114
|
if (!rootGraphId) {
|
package/dist/api/threads.mjs
CHANGED
|
@@ -15,6 +15,9 @@ api.post("/threads", zValidator("json", schemas.ThreadCreate), async (c) => {
|
|
|
15
15
|
metadata: payload.metadata,
|
|
16
16
|
if_exists: payload.if_exists ?? "raise",
|
|
17
17
|
});
|
|
18
|
+
if (payload.supersteps?.length) {
|
|
19
|
+
await Threads.State.bulk({ configurable: { thread_id: thread.thread_id } }, payload.supersteps);
|
|
20
|
+
}
|
|
18
21
|
return jsonExtra(c, thread);
|
|
19
22
|
});
|
|
20
23
|
api.post("/threads/search", zValidator("json", schemas.ThreadSearchRequest), async (c) => {
|
package/dist/cli/entrypoint.mjs
CHANGED
|
@@ -37,5 +37,5 @@ logger.info(`Server running at ${host}`);
|
|
|
37
37
|
let queryParams = `?baseUrl=http://${options.host}:${options.port}`;
|
|
38
38
|
if (organizationId)
|
|
39
39
|
queryParams += `&organizationId=${organizationId}`;
|
|
40
|
-
asyncExitHook(cleanup, { wait:
|
|
40
|
+
asyncExitHook(cleanup, { wait: 3_000 });
|
|
41
41
|
sendToParent?.({ queryParams });
|
package/dist/cli/spawn.d.mts
CHANGED
package/dist/cli/spawn.mjs
CHANGED
package/dist/command.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command, Send } from "@langchain/langgraph";
|
|
2
|
+
export const getLangGraphCommand = (command) => {
|
|
3
|
+
let goto = command.goto != null && !Array.isArray(command.goto)
|
|
4
|
+
? [command.goto]
|
|
5
|
+
: command.goto;
|
|
6
|
+
return new Command({
|
|
7
|
+
goto: goto?.map((item) => {
|
|
8
|
+
if (typeof item !== "string")
|
|
9
|
+
return new Send(item.node, item.input);
|
|
10
|
+
return item;
|
|
11
|
+
}),
|
|
12
|
+
update: command.update,
|
|
13
|
+
resume: command.resume,
|
|
14
|
+
});
|
|
15
|
+
};
|
package/dist/graph/load.mjs
CHANGED
|
@@ -41,11 +41,12 @@ export async function registerFromEnv(specs, options) {
|
|
|
41
41
|
return resolved;
|
|
42
42
|
}));
|
|
43
43
|
}
|
|
44
|
-
export function getGraph(graphId, options) {
|
|
44
|
+
export async function getGraph(graphId, config, options) {
|
|
45
45
|
if (!GRAPHS[graphId])
|
|
46
46
|
throw new HTTPException(404, { message: `Graph "${graphId}" not found` });
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const compiled = typeof GRAPHS[graphId] === "function"
|
|
48
|
+
? await GRAPHS[graphId](config ?? { configurable: {} })
|
|
49
|
+
: GRAPHS[graphId];
|
|
49
50
|
if (typeof options?.checkpointer !== "undefined") {
|
|
50
51
|
compiled.checkpointer = options?.checkpointer ?? undefined;
|
|
51
52
|
}
|
|
@@ -23,10 +23,17 @@ export async function resolveGraph(spec, options) {
|
|
|
23
23
|
const resolved = await (async () => {
|
|
24
24
|
if (!graph)
|
|
25
25
|
throw new Error("Failed to load graph: graph is nullush");
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
|
|
26
|
+
const afterResolve = (graphLike) => {
|
|
27
|
+
const graph = isGraph(graphLike) ? graphLike.compile() : graphLike;
|
|
28
|
+
return graph;
|
|
29
|
+
};
|
|
30
|
+
if (typeof graph === "function") {
|
|
31
|
+
return async (config) => {
|
|
32
|
+
const graphLike = await graph(config);
|
|
33
|
+
return afterResolve(graphLike);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return afterResolve(await graph);
|
|
30
37
|
})();
|
|
31
38
|
return { sourceFile, exportSymbol, resolved };
|
|
32
39
|
}
|
package/dist/schemas.mjs
CHANGED
|
@@ -140,35 +140,31 @@ export const Run = z.object({
|
|
|
140
140
|
kwargs: z.object({}).catchall(z.any()),
|
|
141
141
|
multitask_strategy: z.enum(["reject", "rollback", "interrupt", "enqueue"]),
|
|
142
142
|
});
|
|
143
|
+
export const CommandSchema = z.object({
|
|
144
|
+
goto: z
|
|
145
|
+
.union([
|
|
146
|
+
z.union([
|
|
147
|
+
z.string(),
|
|
148
|
+
z.object({ node: z.string(), input: z.unknown().optional() }),
|
|
149
|
+
]),
|
|
150
|
+
z.array(z.union([
|
|
151
|
+
z.string(),
|
|
152
|
+
z.object({ node: z.string(), input: z.unknown().optional() }),
|
|
153
|
+
])),
|
|
154
|
+
])
|
|
155
|
+
.optional(),
|
|
156
|
+
update: z
|
|
157
|
+
.union([z.record(z.unknown()), z.array(z.tuple([z.string(), z.unknown()]))])
|
|
158
|
+
.optional(),
|
|
159
|
+
resume: z.unknown().optional(),
|
|
160
|
+
});
|
|
143
161
|
export const RunCreate = z
|
|
144
162
|
.object({
|
|
145
163
|
assistant_id: z.union([z.string().uuid(), z.string()]),
|
|
146
164
|
checkpoint_id: z.string().optional(),
|
|
147
165
|
checkpoint: CheckpointSchema.optional(),
|
|
148
166
|
input: z.union([z.unknown(), z.null()]).optional(),
|
|
149
|
-
command:
|
|
150
|
-
.object({
|
|
151
|
-
goto: z
|
|
152
|
-
.union([
|
|
153
|
-
z.union([
|
|
154
|
-
z.string(),
|
|
155
|
-
z.object({ node: z.string(), input: z.unknown().optional() }),
|
|
156
|
-
]),
|
|
157
|
-
z.array(z.union([
|
|
158
|
-
z.string(),
|
|
159
|
-
z.object({ node: z.string(), input: z.unknown().optional() }),
|
|
160
|
-
])),
|
|
161
|
-
])
|
|
162
|
-
.optional(),
|
|
163
|
-
update: z
|
|
164
|
-
.union([
|
|
165
|
-
z.record(z.unknown()),
|
|
166
|
-
z.array(z.tuple([z.string(), z.unknown()])),
|
|
167
|
-
])
|
|
168
|
-
.optional(),
|
|
169
|
-
resume: z.unknown().optional(),
|
|
170
|
-
})
|
|
171
|
-
.optional(),
|
|
167
|
+
command: CommandSchema.optional(),
|
|
172
168
|
metadata: z
|
|
173
169
|
.object({})
|
|
174
170
|
.catchall(z.any())
|
|
@@ -301,6 +297,16 @@ export const Thread = z.object({
|
|
|
301
297
|
});
|
|
302
298
|
export const ThreadCreate = z
|
|
303
299
|
.object({
|
|
300
|
+
supersteps: z
|
|
301
|
+
.array(z.object({
|
|
302
|
+
updates: z.array(z.object({
|
|
303
|
+
values: z.unknown().nullish(),
|
|
304
|
+
command: CommandSchema.nullish(),
|
|
305
|
+
as_node: z.string(),
|
|
306
|
+
})),
|
|
307
|
+
}))
|
|
308
|
+
.describe("The supersteps to apply to the thread.")
|
|
309
|
+
.optional(),
|
|
304
310
|
thread_id: z
|
|
305
311
|
.string()
|
|
306
312
|
.uuid()
|
package/dist/server.mjs
CHANGED
|
@@ -50,6 +50,7 @@ export const StartServerSchema = z.object({
|
|
|
50
50
|
cwd: z.string(),
|
|
51
51
|
graphs: z.record(z.string()),
|
|
52
52
|
ui: z.record(z.string()).optional(),
|
|
53
|
+
ui_config: z.object({ shared: z.array(z.string()).optional() }).optional(),
|
|
53
54
|
});
|
|
54
55
|
export async function startServer(options) {
|
|
55
56
|
logger.info(`Initializing storage...`);
|
|
@@ -69,7 +70,10 @@ export async function startServer(options) {
|
|
|
69
70
|
const { api, registerGraphUi } = await import("./ui/load.mjs");
|
|
70
71
|
app.route("/", api);
|
|
71
72
|
logger.info(`Registering UI from ${options.cwd}`);
|
|
72
|
-
await registerGraphUi(options.ui, {
|
|
73
|
+
await registerGraphUi(options.ui, {
|
|
74
|
+
cwd: options.cwd,
|
|
75
|
+
config: options.ui_config,
|
|
76
|
+
});
|
|
73
77
|
}
|
|
74
78
|
logger.info(`Starting ${options.nWorkers} workers`);
|
|
75
79
|
for (let i = 0; i < options.nWorkers; i++)
|
package/dist/storage/ops.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { store } from "./store.mjs";
|
|
|
6
6
|
import { logger } from "../logging.mjs";
|
|
7
7
|
import { serializeError } from "../utils/serde.mjs";
|
|
8
8
|
import { FileSystemPersistence } from "./persist.mjs";
|
|
9
|
+
import { getLangGraphCommand } from "../command.mjs";
|
|
9
10
|
export const conn = new FileSystemPersistence(".langgraphjs_ops.json", () => ({
|
|
10
11
|
runs: {},
|
|
11
12
|
threads: {},
|
|
@@ -446,7 +447,10 @@ export class Threads {
|
|
|
446
447
|
tasks: [],
|
|
447
448
|
};
|
|
448
449
|
}
|
|
449
|
-
const graph = await getGraph(graphId,
|
|
450
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
451
|
+
checkpointer,
|
|
452
|
+
store,
|
|
453
|
+
});
|
|
450
454
|
const result = await graph.getState(config, { subgraphs });
|
|
451
455
|
if (result.metadata != null &&
|
|
452
456
|
"checkpoint_ns" in result.metadata &&
|
|
@@ -470,7 +474,10 @@ export class Threads {
|
|
|
470
474
|
}
|
|
471
475
|
config.configurable ??= {};
|
|
472
476
|
config.configurable.graph_id ??= graphId;
|
|
473
|
-
const graph = await getGraph(graphId,
|
|
477
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
478
|
+
checkpointer,
|
|
479
|
+
store,
|
|
480
|
+
});
|
|
474
481
|
const updateConfig = structuredClone(config);
|
|
475
482
|
updateConfig.configurable ??= {};
|
|
476
483
|
updateConfig.configurable.checkpoint_ns ??= "";
|
|
@@ -487,6 +494,44 @@ export class Threads {
|
|
|
487
494
|
});
|
|
488
495
|
return { checkpoint: nextConfig.configurable };
|
|
489
496
|
}
|
|
497
|
+
static async bulk(config, supersteps) {
|
|
498
|
+
const threadId = config.configurable?.thread_id;
|
|
499
|
+
if (!threadId)
|
|
500
|
+
return [];
|
|
501
|
+
const thread = await Threads.get(threadId);
|
|
502
|
+
const graphId = thread.metadata?.graph_id;
|
|
503
|
+
if (graphId == null) {
|
|
504
|
+
throw new HTTPException(400, {
|
|
505
|
+
message: `Thread ${threadId} has no graph ID`,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
config.configurable ??= {};
|
|
509
|
+
config.configurable.graph_id ??= graphId;
|
|
510
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
511
|
+
checkpointer,
|
|
512
|
+
store,
|
|
513
|
+
});
|
|
514
|
+
const updateConfig = structuredClone(config);
|
|
515
|
+
updateConfig.configurable ??= {};
|
|
516
|
+
updateConfig.configurable.checkpoint_ns ??= "";
|
|
517
|
+
const nextConfig = await graph.bulkUpdateState(updateConfig, supersteps.map((i) => ({
|
|
518
|
+
updates: i.updates.map((j) => ({
|
|
519
|
+
values: j.command != null ? getLangGraphCommand(j.command) : j.values,
|
|
520
|
+
asNode: j.as_node,
|
|
521
|
+
})),
|
|
522
|
+
})));
|
|
523
|
+
const state = await Threads.State.get(config, { subgraphs: false });
|
|
524
|
+
// update thread values
|
|
525
|
+
await conn.with(async (STORE) => {
|
|
526
|
+
for (const thread of Object.values(STORE.threads)) {
|
|
527
|
+
if (thread.thread_id === threadId) {
|
|
528
|
+
thread.values = state.values;
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
return { checkpoint: nextConfig.configurable };
|
|
534
|
+
}
|
|
490
535
|
static async list(config, options) {
|
|
491
536
|
const threadId = config.configurable?.thread_id;
|
|
492
537
|
if (!threadId)
|
|
@@ -495,7 +540,10 @@ export class Threads {
|
|
|
495
540
|
const graphId = thread.metadata?.graph_id;
|
|
496
541
|
if (graphId == null)
|
|
497
542
|
return [];
|
|
498
|
-
const graph = await getGraph(graphId,
|
|
543
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
544
|
+
checkpointer,
|
|
545
|
+
store,
|
|
546
|
+
});
|
|
499
547
|
const before = typeof options?.before === "string"
|
|
500
548
|
? { configurable: { checkpoint_id: options.before } }
|
|
501
549
|
: options?.before;
|
|
@@ -513,7 +561,7 @@ export class Threads {
|
|
|
513
561
|
}
|
|
514
562
|
export class Runs {
|
|
515
563
|
static async *next() {
|
|
516
|
-
yield* conn.withGenerator(async function* (STORE) {
|
|
564
|
+
yield* conn.withGenerator(async function* (STORE, options) {
|
|
517
565
|
const now = new Date();
|
|
518
566
|
const pendingRuns = Object.values(STORE.runs)
|
|
519
567
|
.filter((run) => run.status === "pending" && run.created_at < now)
|
|
@@ -533,6 +581,7 @@ export class Runs {
|
|
|
533
581
|
continue;
|
|
534
582
|
try {
|
|
535
583
|
const signal = StreamManager.lock(runId);
|
|
584
|
+
options.schedulePersist();
|
|
536
585
|
STORE.retry_counter[runId] ??= 0;
|
|
537
586
|
STORE.retry_counter[runId] += 1;
|
|
538
587
|
yield { run, attempt: STORE.retry_counter[runId], signal };
|
package/dist/storage/persist.mjs
CHANGED
|
@@ -67,12 +67,15 @@ export class FileSystemPersistence {
|
|
|
67
67
|
if (this.filepath == null || this.data == null) {
|
|
68
68
|
throw new Error(`${this.name} not initialized`);
|
|
69
69
|
}
|
|
70
|
+
let shouldPersist = false;
|
|
71
|
+
let schedulePersist = () => void (shouldPersist = true);
|
|
70
72
|
try {
|
|
71
|
-
const gen = typeof fn === "function" ? fn(this.data) : fn;
|
|
73
|
+
const gen = typeof fn === "function" ? fn(this.data, { schedulePersist }) : fn;
|
|
72
74
|
yield* gen;
|
|
73
75
|
}
|
|
74
76
|
finally {
|
|
75
|
-
|
|
77
|
+
if (shouldPersist)
|
|
78
|
+
this.schedulePersist();
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
}
|
package/dist/stream.mjs
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
import { getGraph } from "./graph/load.mjs";
|
|
2
2
|
import { Client as LangSmithClient } from "langsmith";
|
|
3
|
-
import { Command, Send, } from "@langchain/langgraph";
|
|
4
3
|
import { runnableConfigToCheckpoint, taskRunnableConfigToCheckpoint, } from "./utils/runnableConfig.mjs";
|
|
5
4
|
import { isBaseMessage } from "@langchain/core/messages";
|
|
6
|
-
|
|
7
|
-
let goto = command.goto != null && !Array.isArray(command.goto)
|
|
8
|
-
? [command.goto]
|
|
9
|
-
: command.goto;
|
|
10
|
-
return new Command({
|
|
11
|
-
goto: goto?.map((item) => {
|
|
12
|
-
if (typeof item !== "string")
|
|
13
|
-
return new Send(item.node, item.input);
|
|
14
|
-
return item;
|
|
15
|
-
}),
|
|
16
|
-
update: command.update,
|
|
17
|
-
resume: command.resume,
|
|
18
|
-
});
|
|
19
|
-
};
|
|
5
|
+
import { getLangGraphCommand } from "./command.mjs";
|
|
20
6
|
const isRunnableConfig = (config) => {
|
|
21
7
|
if (typeof config !== "object" || config == null)
|
|
22
8
|
return false;
|
|
@@ -71,7 +57,7 @@ export async function* streamState(run, attempt = 1, options) {
|
|
|
71
57
|
if (!graphId || typeof graphId !== "string") {
|
|
72
58
|
throw new Error("Invalid or missing graph_id");
|
|
73
59
|
}
|
|
74
|
-
const graph = getGraph(graphId, {
|
|
60
|
+
const graph = await getGraph(graphId, kwargs.config, {
|
|
75
61
|
checkpointer: kwargs.temporary ? null : undefined,
|
|
76
62
|
});
|
|
77
63
|
const userStreamMode = kwargs.stream_mode ?? [];
|
package/dist/ui/bundler.d.mts
CHANGED
|
@@ -2,6 +2,9 @@ import { type BuildOptions } from "esbuild";
|
|
|
2
2
|
export declare function build(agentName: string, args: {
|
|
3
3
|
cwd: string;
|
|
4
4
|
userPath: string;
|
|
5
|
+
config?: {
|
|
6
|
+
shared?: string[];
|
|
7
|
+
};
|
|
5
8
|
}): Promise<{
|
|
6
9
|
basename: string;
|
|
7
10
|
contents: Uint8Array;
|
|
@@ -9,6 +12,9 @@ export declare function build(agentName: string, args: {
|
|
|
9
12
|
export declare function watch(agentName: string, args: {
|
|
10
13
|
cwd: string;
|
|
11
14
|
userPath: string;
|
|
15
|
+
config?: {
|
|
16
|
+
shared?: string[];
|
|
17
|
+
};
|
|
12
18
|
}, onResult: (result: {
|
|
13
19
|
basename: string;
|
|
14
20
|
contents: Uint8Array;
|
package/dist/ui/bundler.mjs
CHANGED
|
@@ -68,6 +68,7 @@ function setup(agentName, args, onResult) {
|
|
|
68
68
|
"react-dom",
|
|
69
69
|
"@langchain/langgraph-sdk",
|
|
70
70
|
"@langchain/langgraph-sdk/react-ui",
|
|
71
|
+
...(args.config?.shared ?? []),
|
|
71
72
|
],
|
|
72
73
|
plugins: [tailwind(), entrypointPlugin(args), registerPlugin(onResult)],
|
|
73
74
|
globalName: `__LGUI_${agentName}`,
|
package/dist/ui/load.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { watch } from "./bundler.mjs";
|
|
|
7
7
|
const GRAPH_UI = {};
|
|
8
8
|
export async function registerGraphUi(defs, options) {
|
|
9
9
|
const result = await Promise.all(Object.entries(defs).map(async ([agentName, userPath]) => {
|
|
10
|
-
const ctx = await watch(agentName, { cwd: options.cwd, userPath }, (result) => {
|
|
10
|
+
const ctx = await watch(agentName, { cwd: options.cwd, userPath, config: options.config }, (result) => {
|
|
11
11
|
GRAPH_UI[agentName] = result;
|
|
12
12
|
});
|
|
13
13
|
return [agentName, ctx];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^18.19.0 || >=20.16.0"
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"zod": "^3.23.8"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@langchain/core": "^0.3.
|
|
51
|
-
"@langchain/langgraph": "^0.2.
|
|
52
|
-
"@langchain/langgraph-checkpoint": "^0.0.
|
|
50
|
+
"@langchain/core": "^0.3.42",
|
|
51
|
+
"@langchain/langgraph": "^0.2.57",
|
|
52
|
+
"@langchain/langgraph-checkpoint": "^0.0.16",
|
|
53
53
|
"typescript": "^5.5.4"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@langchain/langgraph-sdk": "^0.0.
|
|
56
|
+
"@langchain/langgraph-sdk": "^0.0.60",
|
|
57
57
|
"@types/babel__code-frame": "^7.0.6",
|
|
58
58
|
"@types/react": "^19.0.8",
|
|
59
59
|
"@types/react-dom": "^19.0.3",
|