@langchain/langgraph-api 0.0.26 → 0.0.28
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/threads.mjs +13 -5
- package/dist/schemas.mjs +5 -0
- package/dist/semver/index.d.mts +15 -0
- package/dist/semver/index.mjs +35 -0
- package/dist/server.mjs +12 -3
- package/dist/storage/ops.mjs +24 -6
- package/package.json +15 -7
package/dist/api/threads.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { zValidator } from "@hono/zod-validator";
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import { v4 as uuid4 } from "uuid";
|
|
4
|
-
import * as schemas from "../schemas.mjs";
|
|
5
|
-
import { Threads } from "../storage/ops.mjs";
|
|
6
4
|
import { z } from "zod";
|
|
5
|
+
import * as schemas from "../schemas.mjs";
|
|
7
6
|
import { stateSnapshotToThreadState } from "../state.mjs";
|
|
7
|
+
import { Threads } from "../storage/ops.mjs";
|
|
8
8
|
import { jsonExtra } from "../utils/hono.mjs";
|
|
9
9
|
const api = new Hono();
|
|
10
10
|
// Threads Routes
|
|
@@ -21,19 +21,27 @@ api.post("/threads/search", zValidator("json", schemas.ThreadSearchRequest), asy
|
|
|
21
21
|
// Search Threads
|
|
22
22
|
const payload = c.req.valid("json");
|
|
23
23
|
const result = [];
|
|
24
|
+
let total = 0;
|
|
24
25
|
for await (const item of Threads.search({
|
|
25
26
|
status: payload.status,
|
|
26
27
|
values: payload.values,
|
|
27
28
|
metadata: payload.metadata,
|
|
28
29
|
limit: payload.limit ?? 10,
|
|
29
30
|
offset: payload.offset ?? 0,
|
|
31
|
+
sort_by: payload.sort_by ?? "created_at",
|
|
32
|
+
sort_order: payload.sort_order ?? "desc",
|
|
30
33
|
}, c.var.auth)) {
|
|
31
34
|
result.push({
|
|
32
|
-
...item,
|
|
33
|
-
created_at: item.created_at.toISOString(),
|
|
34
|
-
updated_at: item.updated_at.toISOString(),
|
|
35
|
+
...item.thread,
|
|
36
|
+
created_at: item.thread.created_at.toISOString(),
|
|
37
|
+
updated_at: item.thread.updated_at.toISOString(),
|
|
35
38
|
});
|
|
39
|
+
// Only set total if it's the first item
|
|
40
|
+
if (total === 0) {
|
|
41
|
+
total = item.total;
|
|
42
|
+
}
|
|
36
43
|
}
|
|
44
|
+
c.res.headers.set("X-Pagination-Total", total.toString());
|
|
37
45
|
return jsonExtra(c, result);
|
|
38
46
|
});
|
|
39
47
|
api.get("/threads/:thread_id/state", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("query", z.object({ subgraphs: schemas.coercedBoolean.optional() })), async (c) => {
|
package/dist/schemas.mjs
CHANGED
|
@@ -287,6 +287,11 @@ export const ThreadSearchRequest = z
|
|
|
287
287
|
.gte(0)
|
|
288
288
|
.describe("Offset to start from.")
|
|
289
289
|
.optional(),
|
|
290
|
+
sort_by: z
|
|
291
|
+
.enum(["thread_id", "status", "created_at", "updated_at"])
|
|
292
|
+
.describe("Sort by field.")
|
|
293
|
+
.optional(),
|
|
294
|
+
sort_order: z.enum(["asc", "desc"]).describe("Sort order.").optional(),
|
|
290
295
|
})
|
|
291
296
|
.describe("Payload for listing threads.");
|
|
292
297
|
export const Thread = z.object({
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function checkSemver(packages: {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
}[]): Promise<{
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
required: string;
|
|
8
|
+
satisfies: boolean;
|
|
9
|
+
}[]>;
|
|
10
|
+
export declare function checkLangGraphSemver(): Promise<{
|
|
11
|
+
name: string;
|
|
12
|
+
version: string;
|
|
13
|
+
required: string;
|
|
14
|
+
satisfies: boolean;
|
|
15
|
+
}[]>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as url from "node:url";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as semver from "semver";
|
|
4
|
+
const packageJsonPath = url.fileURLToPath(new URL("../../package.json", import.meta.url));
|
|
5
|
+
export async function checkSemver(packages) {
|
|
6
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
7
|
+
const peerDependencies = packageJson.peerDependencies ?? {};
|
|
8
|
+
return packages.flatMap((pkg) => {
|
|
9
|
+
const required = peerDependencies[pkg.name];
|
|
10
|
+
if (!required)
|
|
11
|
+
return [];
|
|
12
|
+
const satisfies = semver.satisfies(pkg.version, required);
|
|
13
|
+
return { ...pkg, required, satisfies };
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function checkLangGraphSemver() {
|
|
17
|
+
const resolveVersion = async (name) => {
|
|
18
|
+
let version = "0.0.0";
|
|
19
|
+
try {
|
|
20
|
+
const pkgJson = await import(`${name}/package.json`);
|
|
21
|
+
version = pkgJson.version || version;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// pass
|
|
25
|
+
}
|
|
26
|
+
return { name, version };
|
|
27
|
+
};
|
|
28
|
+
const validate = [
|
|
29
|
+
"@langchain/core",
|
|
30
|
+
"@langchain/langgraph",
|
|
31
|
+
"@langchain/langgraph-checkpoint",
|
|
32
|
+
];
|
|
33
|
+
const resolved = await Promise.all(validate.map((name) => resolveVersion(name)));
|
|
34
|
+
return checkSemver(resolved);
|
|
35
|
+
}
|
package/dist/server.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import { registerAuth } from "./auth/index.mjs";
|
|
|
18
18
|
import { registerHttp } from "./http/custom.mjs";
|
|
19
19
|
import { cors, ensureContentType } from "./http/middleware.mjs";
|
|
20
20
|
import { bindLoopbackFetch } from "./loopback.mjs";
|
|
21
|
+
import { checkLangGraphSemver } from "./semver/index.mjs";
|
|
21
22
|
export const StartServerSchema = z.object({
|
|
22
23
|
port: z.number(),
|
|
23
24
|
nWorkers: z.number(),
|
|
@@ -55,6 +56,14 @@ export const StartServerSchema = z.object({
|
|
|
55
56
|
.optional(),
|
|
56
57
|
});
|
|
57
58
|
export async function startServer(options) {
|
|
59
|
+
const semver = await checkLangGraphSemver();
|
|
60
|
+
const invalidPackages = semver.filter((s) => !s.satisfies);
|
|
61
|
+
if (invalidPackages.length > 0) {
|
|
62
|
+
logger.warn(`Some LangGraph.js dependencies are not up to date. Please make sure to update them to the required version.`, Object.fromEntries(invalidPackages.map(({ name, version, required }) => [
|
|
63
|
+
name,
|
|
64
|
+
{ version, required },
|
|
65
|
+
])));
|
|
66
|
+
}
|
|
58
67
|
logger.info(`Initializing storage...`);
|
|
59
68
|
const callbacks = await Promise.all([
|
|
60
69
|
opsConn.initialize(options.cwd),
|
|
@@ -81,9 +90,6 @@ export async function startServer(options) {
|
|
|
81
90
|
truncate({ runs, threads, assistants, checkpointer, store });
|
|
82
91
|
return c.json({ ok: true });
|
|
83
92
|
});
|
|
84
|
-
app.use(cors(options.http?.cors));
|
|
85
|
-
app.use(requestLogger());
|
|
86
|
-
app.use(ensureContentType());
|
|
87
93
|
if (options.auth?.path) {
|
|
88
94
|
logger.info(`Loading auth from ${options.auth.path}`);
|
|
89
95
|
await registerAuth(options.auth, { cwd: options.cwd });
|
|
@@ -94,6 +100,9 @@ export async function startServer(options) {
|
|
|
94
100
|
const { api } = await registerHttp(options.http.app, { cwd: options.cwd });
|
|
95
101
|
app.route("/", api);
|
|
96
102
|
}
|
|
103
|
+
app.use(cors(options.http?.cors));
|
|
104
|
+
app.use(requestLogger());
|
|
105
|
+
app.use(ensureContentType());
|
|
97
106
|
if (!options.http?.disable_meta)
|
|
98
107
|
app.route("/", meta);
|
|
99
108
|
if (!options.http?.disable_assistants)
|
package/dist/storage/ops.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { HTTPException } from "hono/http-exception";
|
|
2
2
|
import { v4 as uuid4, v5 as uuid5 } from "uuid";
|
|
3
|
+
import { handleAuthEvent, isAuthMatching } from "../auth/custom.mjs";
|
|
4
|
+
import { getLangGraphCommand } from "../command.mjs";
|
|
3
5
|
import { getGraph, NAMESPACE_GRAPH } from "../graph/load.mjs";
|
|
4
|
-
import { checkpointer } from "./checkpoint.mjs";
|
|
5
|
-
import { store } from "./store.mjs";
|
|
6
6
|
import { logger } from "../logging.mjs";
|
|
7
7
|
import { serializeError } from "../utils/serde.mjs";
|
|
8
|
+
import { checkpointer } from "./checkpoint.mjs";
|
|
8
9
|
import { FileSystemPersistence } from "./persist.mjs";
|
|
9
|
-
import {
|
|
10
|
-
import { handleAuthEvent, isAuthMatching } from "../auth/custom.mjs";
|
|
10
|
+
import { store } from "./store.mjs";
|
|
11
11
|
export const conn = new FileSystemPersistence(".langgraphjs_ops.json", () => ({
|
|
12
12
|
runs: {},
|
|
13
13
|
threads: {},
|
|
@@ -374,9 +374,27 @@ export class Threads {
|
|
|
374
374
|
return false;
|
|
375
375
|
return true;
|
|
376
376
|
})
|
|
377
|
-
.sort((a, b) =>
|
|
377
|
+
.sort((a, b) => {
|
|
378
|
+
const sortBy = options.sort_by ?? "created_at";
|
|
379
|
+
const sortOrder = options.sort_order ?? "desc";
|
|
380
|
+
if (sortBy === "created_at" || sortBy === "updated_at") {
|
|
381
|
+
const aTime = a[sortBy].getTime();
|
|
382
|
+
const bTime = b[sortBy].getTime();
|
|
383
|
+
return sortOrder === "desc" ? bTime - aTime : aTime - bTime;
|
|
384
|
+
}
|
|
385
|
+
if (sortBy === "thread_id" || sortBy === "status") {
|
|
386
|
+
const aVal = a[sortBy];
|
|
387
|
+
const bVal = b[sortBy];
|
|
388
|
+
return sortOrder === "desc"
|
|
389
|
+
? bVal.localeCompare(aVal)
|
|
390
|
+
: aVal.localeCompare(bVal);
|
|
391
|
+
}
|
|
392
|
+
return 0;
|
|
393
|
+
});
|
|
394
|
+
// Calculate total count before pagination
|
|
395
|
+
const total = filtered.length;
|
|
378
396
|
for (const thread of filtered.slice(options.offset, options.offset + options.limit)) {
|
|
379
|
-
yield thread;
|
|
397
|
+
yield { thread, total };
|
|
380
398
|
}
|
|
381
399
|
});
|
|
382
400
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^18.19.0 || >=20.16.0"
|
|
@@ -18,7 +18,12 @@
|
|
|
18
18
|
"./auth": {
|
|
19
19
|
"types": "./dist/auth/index.d.ts",
|
|
20
20
|
"default": "./dist/auth/index.mjs"
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
|
+
"./semver": {
|
|
23
|
+
"types": "./dist/semver/index.d.ts",
|
|
24
|
+
"default": "./dist/semver/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
22
27
|
},
|
|
23
28
|
"repository": {
|
|
24
29
|
"type": "git",
|
|
@@ -36,6 +41,7 @@
|
|
|
36
41
|
"hono": "^4.5.4",
|
|
37
42
|
"langsmith": "^0.2.15",
|
|
38
43
|
"open": "^10.1.0",
|
|
44
|
+
"semver": "^7.7.1",
|
|
39
45
|
"stacktrace-parser": "^0.1.10",
|
|
40
46
|
"superjson": "^2.2.2",
|
|
41
47
|
"tsx": "^4.19.3",
|
|
@@ -43,13 +49,13 @@
|
|
|
43
49
|
"winston": "^3.17.0",
|
|
44
50
|
"winston-console-format": "^1.0.8",
|
|
45
51
|
"zod": "^3.23.8",
|
|
46
|
-
"@langchain/langgraph-ui": "0.0.
|
|
52
|
+
"@langchain/langgraph-ui": "0.0.28"
|
|
47
53
|
},
|
|
48
54
|
"peerDependencies": {
|
|
49
55
|
"@langchain/core": "^0.3.42",
|
|
50
56
|
"@langchain/langgraph": "^0.2.57",
|
|
51
57
|
"@langchain/langgraph-checkpoint": "^0.0.16",
|
|
52
|
-
"@langchain/langgraph-sdk": "^0.0.
|
|
58
|
+
"@langchain/langgraph-sdk": "^0.0.70",
|
|
53
59
|
"typescript": "^5.5.4"
|
|
54
60
|
},
|
|
55
61
|
"peerDependenciesMeta": {
|
|
@@ -58,13 +64,15 @@
|
|
|
58
64
|
}
|
|
59
65
|
},
|
|
60
66
|
"devDependencies": {
|
|
61
|
-
"
|
|
67
|
+
"typescript": "^5.5.4",
|
|
68
|
+
"@langchain/langgraph-sdk": "^0.0.70",
|
|
62
69
|
"@types/babel__code-frame": "^7.0.6",
|
|
70
|
+
"@types/node": "^22.2.0",
|
|
63
71
|
"@types/react": "^19.0.8",
|
|
64
72
|
"@types/react-dom": "^19.0.3",
|
|
65
|
-
"@types/
|
|
66
|
-
"jose": "^6.0.10",
|
|
73
|
+
"@types/semver": "^7.7.0",
|
|
67
74
|
"@types/uuid": "^10.0.0",
|
|
75
|
+
"jose": "^6.0.10",
|
|
68
76
|
"postgres": "^3.4.5",
|
|
69
77
|
"prettier": "^3.3.3",
|
|
70
78
|
"vitest": "^3.0.5"
|