@langchain/langgraph-api 0.0.18 → 0.0.20
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/cli/spawn.d.mts +3 -0
- package/dist/cli/spawn.mjs +1 -0
- package/dist/graph/load.mjs +4 -3
- package/dist/graph/load.utils.mjs +11 -4
- package/dist/server.mjs +5 -1
- package/dist/storage/ops.mjs +16 -4
- package/dist/stream.mjs +1 -1
- package/dist/ui/load.mjs +7 -8
- package/package.json +4 -9
- package/dist/ui/bundler.d.mts +0 -15
- package/dist/ui/bundler.mjs +0 -85
- package/dist/ui/render.template.mts +0 -27
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/cli/spawn.d.mts
CHANGED
package/dist/cli/spawn.mjs
CHANGED
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/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
|
@@ -447,7 +447,10 @@ export class Threads {
|
|
|
447
447
|
tasks: [],
|
|
448
448
|
};
|
|
449
449
|
}
|
|
450
|
-
const graph = await getGraph(graphId,
|
|
450
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
451
|
+
checkpointer,
|
|
452
|
+
store,
|
|
453
|
+
});
|
|
451
454
|
const result = await graph.getState(config, { subgraphs });
|
|
452
455
|
if (result.metadata != null &&
|
|
453
456
|
"checkpoint_ns" in result.metadata &&
|
|
@@ -471,7 +474,10 @@ export class Threads {
|
|
|
471
474
|
}
|
|
472
475
|
config.configurable ??= {};
|
|
473
476
|
config.configurable.graph_id ??= graphId;
|
|
474
|
-
const graph = await getGraph(graphId,
|
|
477
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
478
|
+
checkpointer,
|
|
479
|
+
store,
|
|
480
|
+
});
|
|
475
481
|
const updateConfig = structuredClone(config);
|
|
476
482
|
updateConfig.configurable ??= {};
|
|
477
483
|
updateConfig.configurable.checkpoint_ns ??= "";
|
|
@@ -501,7 +507,10 @@ export class Threads {
|
|
|
501
507
|
}
|
|
502
508
|
config.configurable ??= {};
|
|
503
509
|
config.configurable.graph_id ??= graphId;
|
|
504
|
-
const graph = await getGraph(graphId,
|
|
510
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
511
|
+
checkpointer,
|
|
512
|
+
store,
|
|
513
|
+
});
|
|
505
514
|
const updateConfig = structuredClone(config);
|
|
506
515
|
updateConfig.configurable ??= {};
|
|
507
516
|
updateConfig.configurable.checkpoint_ns ??= "";
|
|
@@ -531,7 +540,10 @@ export class Threads {
|
|
|
531
540
|
const graphId = thread.metadata?.graph_id;
|
|
532
541
|
if (graphId == null)
|
|
533
542
|
return [];
|
|
534
|
-
const graph = await getGraph(graphId,
|
|
543
|
+
const graph = await getGraph(graphId, thread.config, {
|
|
544
|
+
checkpointer,
|
|
545
|
+
store,
|
|
546
|
+
});
|
|
535
547
|
const before = typeof options?.before === "string"
|
|
536
548
|
? { configurable: { checkpoint_id: options.before } }
|
|
537
549
|
: options?.before;
|
package/dist/stream.mjs
CHANGED
|
@@ -57,7 +57,7 @@ export async function* streamState(run, attempt = 1, options) {
|
|
|
57
57
|
if (!graphId || typeof graphId !== "string") {
|
|
58
58
|
throw new Error("Invalid or missing graph_id");
|
|
59
59
|
}
|
|
60
|
-
const graph = getGraph(graphId, {
|
|
60
|
+
const graph = await getGraph(graphId, kwargs.config, {
|
|
61
61
|
checkpointer: kwargs.temporary ? null : undefined,
|
|
62
62
|
});
|
|
63
63
|
const userStreamMode = kwargs.stream_mode ?? [];
|
package/dist/ui/load.mjs
CHANGED
|
@@ -2,17 +2,16 @@ import { z } from "zod";
|
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import { getMimeType } from "hono/utils/mime";
|
|
4
4
|
import { zValidator } from "@hono/zod-validator";
|
|
5
|
+
import { watch } from "@langchain/langgraph-ui";
|
|
5
6
|
import * as path from "node:path";
|
|
6
|
-
import { watch } from "./bundler.mjs";
|
|
7
7
|
const GRAPH_UI = {};
|
|
8
8
|
export async function registerGraphUi(defs, options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})
|
|
15
|
-
return Object.fromEntries(result);
|
|
9
|
+
await watch({
|
|
10
|
+
defs,
|
|
11
|
+
cwd: options.cwd,
|
|
12
|
+
config: options.config,
|
|
13
|
+
onOutput: (graphId, files) => (GRAPH_UI[graphId] = files),
|
|
14
|
+
});
|
|
16
15
|
}
|
|
17
16
|
export const api = new Hono();
|
|
18
17
|
api.post("/ui/:agent", zValidator("json", z.object({ name: z.string() })), async (c) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^18.19.0 || >=20.16.0"
|
|
@@ -14,10 +14,6 @@
|
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/cli/spawn.d.ts",
|
|
16
16
|
"default": "./dist/cli/spawn.mjs"
|
|
17
|
-
},
|
|
18
|
-
"./ui/bundler": {
|
|
19
|
-
"types": "./dist/ui/bundler.d.ts",
|
|
20
|
-
"default": "./dist/ui/bundler.mjs"
|
|
21
17
|
}
|
|
22
18
|
},
|
|
23
19
|
"repository": {
|
|
@@ -39,12 +35,11 @@
|
|
|
39
35
|
"stacktrace-parser": "^0.1.10",
|
|
40
36
|
"superjson": "^2.2.2",
|
|
41
37
|
"tsx": "^4.19.3",
|
|
42
|
-
"esbuild": "^0.25.0",
|
|
43
|
-
"esbuild-plugin-tailwindcss": "^2.0.1",
|
|
44
38
|
"uuid": "^10.0.0",
|
|
45
39
|
"winston": "^3.17.0",
|
|
46
40
|
"winston-console-format": "^1.0.8",
|
|
47
|
-
"zod": "^3.23.8"
|
|
41
|
+
"zod": "^3.23.8",
|
|
42
|
+
"@langchain/langgraph-ui": "0.0.20"
|
|
48
43
|
},
|
|
49
44
|
"peerDependencies": {
|
|
50
45
|
"@langchain/core": "^0.3.42",
|
|
@@ -66,7 +61,7 @@
|
|
|
66
61
|
"scripts": {
|
|
67
62
|
"clean": "npx -y bun scripts/clean.mjs",
|
|
68
63
|
"build": "npx -y bun scripts/build.mjs",
|
|
69
|
-
"dev": "tsx ./tests/utils.server.mts",
|
|
64
|
+
"dev": "tsx ./tests/utils.server.mts --dev",
|
|
70
65
|
"typecheck": "tsc --noEmit",
|
|
71
66
|
"test": "vitest",
|
|
72
67
|
"test:parser": "vitest run ./tests/parser.test.mts --testTimeout 15000",
|
package/dist/ui/bundler.d.mts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type BuildOptions } from "esbuild";
|
|
2
|
-
export declare function build(agentName: string, args: {
|
|
3
|
-
cwd: string;
|
|
4
|
-
userPath: string;
|
|
5
|
-
}): Promise<{
|
|
6
|
-
basename: string;
|
|
7
|
-
contents: Uint8Array;
|
|
8
|
-
}[]>;
|
|
9
|
-
export declare function watch(agentName: string, args: {
|
|
10
|
-
cwd: string;
|
|
11
|
-
userPath: string;
|
|
12
|
-
}, onResult: (result: {
|
|
13
|
-
basename: string;
|
|
14
|
-
contents: Uint8Array;
|
|
15
|
-
}[]) => void): Promise<import("esbuild").BuildContext<BuildOptions>>;
|
package/dist/ui/bundler.mjs
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
|
-
import * as url from "node:url";
|
|
3
|
-
import * as fs from "node:fs";
|
|
4
|
-
import { build as runBuild, context as runContext, } from "esbuild";
|
|
5
|
-
import tailwind from "esbuild-plugin-tailwindcss";
|
|
6
|
-
const renderTemplate = await fs.promises.readFile(url.fileURLToPath(new URL("./render.template.mts", import.meta.url)), "utf-8");
|
|
7
|
-
function entrypointPlugin(paths) {
|
|
8
|
-
const fullPath = path.resolve(paths.cwd, paths.userPath);
|
|
9
|
-
let relativeUiPath = path
|
|
10
|
-
.relative(paths.cwd, fullPath)
|
|
11
|
-
.replaceAll(path.sep, "/");
|
|
12
|
-
if (relativeUiPath.startsWith("../")) {
|
|
13
|
-
throw new Error(`UI path must be relative to the project root. Received: "${relativeUiPath}"`);
|
|
14
|
-
}
|
|
15
|
-
if (!relativeUiPath.startsWith("./"))
|
|
16
|
-
relativeUiPath = `./${relativeUiPath}`;
|
|
17
|
-
return {
|
|
18
|
-
name: "entrypoint",
|
|
19
|
-
setup(build) {
|
|
20
|
-
build.onResolve({ filter: /^entrypoint$/ }, () => ({
|
|
21
|
-
path: path.resolve(path.dirname(fullPath), "ui.entrypoint.tsx"),
|
|
22
|
-
namespace: "entrypoint-ns",
|
|
23
|
-
}));
|
|
24
|
-
build.onLoad({ filter: /.*/, namespace: "entrypoint-ns" }, () => ({
|
|
25
|
-
resolveDir: paths.cwd,
|
|
26
|
-
contents: [
|
|
27
|
-
`import ui from "${relativeUiPath}"`,
|
|
28
|
-
renderTemplate,
|
|
29
|
-
`export const render = createRenderer(ui)`,
|
|
30
|
-
].join("\n"),
|
|
31
|
-
loader: "tsx",
|
|
32
|
-
}));
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function registerPlugin(onEnd) {
|
|
37
|
-
const textEncoder = new TextEncoder();
|
|
38
|
-
return {
|
|
39
|
-
name: "require-transform",
|
|
40
|
-
setup(build) {
|
|
41
|
-
build.onEnd(async (result) => {
|
|
42
|
-
const newResult = [];
|
|
43
|
-
for (const item of result.outputFiles ?? []) {
|
|
44
|
-
let basename = path.basename(item.path);
|
|
45
|
-
let contents = item.contents;
|
|
46
|
-
if (basename === "entrypoint.js") {
|
|
47
|
-
contents = textEncoder.encode(item.text.replaceAll(`typeof require !== "undefined" ? require`, `typeof globalThis[Symbol.for("LGUI_REQUIRE")] !== "undefined" ? globalThis[Symbol.for("LGUI_REQUIRE")]`));
|
|
48
|
-
}
|
|
49
|
-
newResult.push({ basename, contents });
|
|
50
|
-
}
|
|
51
|
-
if (newResult.length > 0)
|
|
52
|
-
onEnd(newResult);
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function setup(agentName, args, onResult) {
|
|
58
|
-
return {
|
|
59
|
-
write: false,
|
|
60
|
-
outdir: path.resolve(args.cwd, "dist"),
|
|
61
|
-
entryPoints: ["entrypoint"],
|
|
62
|
-
bundle: true,
|
|
63
|
-
platform: "browser",
|
|
64
|
-
target: "es2020",
|
|
65
|
-
jsx: "automatic",
|
|
66
|
-
external: [
|
|
67
|
-
"react",
|
|
68
|
-
"react-dom",
|
|
69
|
-
"@langchain/langgraph-sdk",
|
|
70
|
-
"@langchain/langgraph-sdk/react-ui",
|
|
71
|
-
],
|
|
72
|
-
plugins: [tailwind(), entrypointPlugin(args), registerPlugin(onResult)],
|
|
73
|
-
globalName: `__LGUI_${agentName}`,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
export async function build(agentName, args) {
|
|
77
|
-
let results = [];
|
|
78
|
-
await runBuild(setup(agentName, args, (result) => (results = result)));
|
|
79
|
-
return results;
|
|
80
|
-
}
|
|
81
|
-
export async function watch(agentName, args, onResult) {
|
|
82
|
-
const ctx = await runContext(setup(agentName, args, onResult));
|
|
83
|
-
await ctx.watch();
|
|
84
|
-
return ctx;
|
|
85
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { ComponentClass, FunctionComponent } from "react";
|
|
2
|
-
|
|
3
|
-
const STORE_SYMBOL = Symbol.for("LGUI_EXT_STORE");
|
|
4
|
-
|
|
5
|
-
declare global {
|
|
6
|
-
interface Window {
|
|
7
|
-
[STORE_SYMBOL]: {
|
|
8
|
-
respond: (
|
|
9
|
-
shadowRootId: string,
|
|
10
|
-
component: FunctionComponent | ComponentClass,
|
|
11
|
-
renderEl: HTMLElement,
|
|
12
|
-
) => void;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
function createRenderer(
|
|
19
|
-
components: Record<string, FunctionComponent | ComponentClass>,
|
|
20
|
-
) {
|
|
21
|
-
return (name: string, shadowRootId: string) => {
|
|
22
|
-
const root = document.getElementById(shadowRootId)!.shadowRoot;
|
|
23
|
-
const renderEl = document.createElement("div");
|
|
24
|
-
root!.appendChild(renderEl);
|
|
25
|
-
window[STORE_SYMBOL].respond(shadowRootId, components[name], renderEl);
|
|
26
|
-
};
|
|
27
|
-
}
|