@langchain/langgraph-api 0.0.39 → 0.0.41
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/meta.mjs +20 -1
- package/dist/api/runs.mjs +13 -6
- package/dist/api/threads.mjs +2 -13
- package/dist/experimental/embed.d.mts +26 -0
- package/dist/experimental/embed.mjs +167 -0
- package/dist/queue.mjs +6 -3
- package/dist/schemas.d.mts +89 -0
- package/dist/schemas.mjs +20 -0
- package/dist/storage/ops.mjs +24 -13
- package/dist/stream.d.mts +8 -3
- package/dist/stream.mjs +21 -7
- package/package.json +9 -5
package/dist/api/meta.mjs
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as url from "node:url";
|
|
2
4
|
const api = new Hono();
|
|
5
|
+
// Get the version using the same pattern as semver/index.mts
|
|
6
|
+
const packageJsonPath = url.fileURLToPath(new URL("../../package.json", import.meta.url));
|
|
7
|
+
let version;
|
|
8
|
+
try {
|
|
9
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
10
|
+
version = packageJson.version;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
console.warn("Could not determine version of langgraph-api");
|
|
14
|
+
}
|
|
3
15
|
// read env variable
|
|
4
16
|
const env = process.env;
|
|
5
17
|
api.get("/info", (c) => {
|
|
@@ -19,7 +31,14 @@ api.get("/info", (c) => {
|
|
|
19
31
|
return undefined;
|
|
20
32
|
})();
|
|
21
33
|
return c.json({
|
|
22
|
-
|
|
34
|
+
version,
|
|
35
|
+
context: "js",
|
|
36
|
+
flags: {
|
|
37
|
+
assistants: true,
|
|
38
|
+
crons: false,
|
|
39
|
+
langsmith: !!langsmithTracing,
|
|
40
|
+
langsmith_tracing_replicas: true,
|
|
41
|
+
},
|
|
23
42
|
});
|
|
24
43
|
});
|
|
25
44
|
api.get("/ok", (c) => c.json({ ok: true }));
|
package/dist/api/runs.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import { zValidator } from "@hono/zod-validator";
|
|
1
2
|
import { Hono } from "hono";
|
|
2
3
|
import { HTTPException } from "hono/http-exception";
|
|
3
4
|
import { streamSSE } from "hono/streaming";
|
|
5
|
+
import { v4 as uuid4 } from "uuid";
|
|
6
|
+
import { z } from "zod";
|
|
4
7
|
import { getAssistantId } from "../graph/load.mjs";
|
|
5
|
-
import {
|
|
8
|
+
import { logError, logger } from "../logging.mjs";
|
|
6
9
|
import * as schemas from "../schemas.mjs";
|
|
7
|
-
import { z } from "zod";
|
|
8
10
|
import { Runs, Threads } from "../storage/ops.mjs";
|
|
9
|
-
import { serialiseAsDict } from "../utils/serde.mjs";
|
|
10
11
|
import { getDisconnectAbortSignal, jsonExtra, waitKeepAlive, } from "../utils/hono.mjs";
|
|
11
|
-
import {
|
|
12
|
-
import { v4 as uuid4 } from "uuid";
|
|
12
|
+
import { serialiseAsDict } from "../utils/serde.mjs";
|
|
13
13
|
const api = new Hono();
|
|
14
14
|
const createValidRun = async (threadId, payload, kwargs) => {
|
|
15
15
|
const { assistant_id: assistantId, ...run } = payload;
|
|
16
|
-
const { auth, headers } = kwargs;
|
|
16
|
+
const { auth, headers } = kwargs ?? {};
|
|
17
17
|
const runId = uuid4();
|
|
18
18
|
const streamMode = Array.isArray(payload.stream_mode)
|
|
19
19
|
? payload.stream_mode
|
|
@@ -33,6 +33,13 @@ const createValidRun = async (threadId, payload, kwargs) => {
|
|
|
33
33
|
config.configurable ??= {};
|
|
34
34
|
Object.assign(config.configurable, run.checkpoint);
|
|
35
35
|
}
|
|
36
|
+
if (run.langsmith_tracer) {
|
|
37
|
+
config.configurable ??= {};
|
|
38
|
+
Object.assign(config.configurable, {
|
|
39
|
+
langsmith_project: run.langsmith_tracer.project_name,
|
|
40
|
+
langsmith_example_id: run.langsmith_tracer.example_id,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
36
43
|
if (headers) {
|
|
37
44
|
for (const [rawKey, value] of headers.entries()) {
|
|
38
45
|
const key = rawKey.toLowerCase();
|
package/dist/api/threads.mjs
CHANGED
|
@@ -111,18 +111,7 @@ api.get("/threads/:thread_id/history", zValidator("param", z.object({ thread_id:
|
|
|
111
111
|
const states = await Threads.State.list({ configurable: { thread_id, checkpoint_ns: "" } }, { limit, before }, c.var.auth);
|
|
112
112
|
return jsonExtra(c, states.map(stateSnapshotToThreadState));
|
|
113
113
|
});
|
|
114
|
-
api.post("/threads/:thread_id/history", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json",
|
|
115
|
-
limit: z.number().optional().default(10),
|
|
116
|
-
before: z.string().optional(),
|
|
117
|
-
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
118
|
-
checkpoint: z
|
|
119
|
-
.object({
|
|
120
|
-
checkpoint_id: z.string().uuid().optional(),
|
|
121
|
-
checkpoint_ns: z.string().optional(),
|
|
122
|
-
checkpoint_map: z.record(z.string(), z.unknown()).optional(),
|
|
123
|
-
})
|
|
124
|
-
.optional(),
|
|
125
|
-
})), async (c) => {
|
|
114
|
+
api.post("/threads/:thread_id/history", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.ThreadHistoryRequest), async (c) => {
|
|
126
115
|
// Get Thread History Post
|
|
127
116
|
const { thread_id } = c.req.valid("param");
|
|
128
117
|
const { limit, before, metadata, checkpoint } = c.req.valid("json");
|
|
@@ -140,7 +129,7 @@ api.delete("/threads/:thread_id", zValidator("param", z.object({ thread_id: z.st
|
|
|
140
129
|
await Threads.delete(thread_id, c.var.auth);
|
|
141
130
|
return new Response(null, { status: 204 });
|
|
142
131
|
});
|
|
143
|
-
api.patch("/threads/:thread_id", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json",
|
|
132
|
+
api.patch("/threads/:thread_id", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.ThreadPatchRequest), async (c) => {
|
|
144
133
|
// Patch Thread
|
|
145
134
|
const { thread_id } = c.req.valid("param");
|
|
146
135
|
const { metadata } = c.req.valid("json");
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BaseCheckpointSaver, BaseStore, Pregel } from "@langchain/langgraph";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import type { Metadata } from "../storage/ops.mjs";
|
|
4
|
+
type AnyPregel = Pregel<any, any, any, any, any>;
|
|
5
|
+
interface Thread {
|
|
6
|
+
thread_id: string;
|
|
7
|
+
metadata: Metadata;
|
|
8
|
+
}
|
|
9
|
+
interface ThreadSaver {
|
|
10
|
+
get: (id: string) => Promise<Thread>;
|
|
11
|
+
put: (id: string, options: {
|
|
12
|
+
metadata?: Metadata;
|
|
13
|
+
}) => Promise<void>;
|
|
14
|
+
delete: (id: string) => Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Attach LangGraph Platform-esque routes to a given Hono instance.
|
|
18
|
+
* @experimental Does not follow semver.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createEmbedServer(options: {
|
|
21
|
+
graph: Record<string, AnyPregel>;
|
|
22
|
+
threads: ThreadSaver;
|
|
23
|
+
checkpointer: BaseCheckpointSaver;
|
|
24
|
+
store?: BaseStore;
|
|
25
|
+
}): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { zValidator } from "@hono/zod-validator";
|
|
3
|
+
import { streamSSE } from "hono/streaming";
|
|
4
|
+
import { v4 as uuidv4 } from "uuid";
|
|
5
|
+
import * as schemas from "../schemas.mjs";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { streamState } from "../stream.mjs";
|
|
8
|
+
import { serialiseAsDict } from "../utils/serde.mjs";
|
|
9
|
+
import { getDisconnectAbortSignal, jsonExtra } from "../utils/hono.mjs";
|
|
10
|
+
import { stateSnapshotToThreadState } from "../state.mjs";
|
|
11
|
+
import { ensureContentType } from "../http/middleware.mjs";
|
|
12
|
+
function createStubRun(threadId, payload) {
|
|
13
|
+
const now = new Date();
|
|
14
|
+
const runId = uuidv4();
|
|
15
|
+
const streamMode = Array.isArray(payload.stream_mode)
|
|
16
|
+
? payload.stream_mode
|
|
17
|
+
: payload.stream_mode
|
|
18
|
+
? [payload.stream_mode]
|
|
19
|
+
: undefined;
|
|
20
|
+
const config = Object.assign({}, payload.config ?? {}, {
|
|
21
|
+
configurable: {
|
|
22
|
+
run_id: runId,
|
|
23
|
+
thread_id: threadId,
|
|
24
|
+
graph_id: payload.assistant_id,
|
|
25
|
+
},
|
|
26
|
+
}, { metadata: payload.metadata ?? {} });
|
|
27
|
+
return {
|
|
28
|
+
run_id: runId,
|
|
29
|
+
thread_id: threadId,
|
|
30
|
+
assistant_id: payload.assistant_id,
|
|
31
|
+
metadata: payload.metadata ?? {},
|
|
32
|
+
status: "running",
|
|
33
|
+
kwargs: {
|
|
34
|
+
input: payload.input,
|
|
35
|
+
command: payload.command,
|
|
36
|
+
config,
|
|
37
|
+
stream_mode: streamMode,
|
|
38
|
+
interrupt_before: payload.interrupt_before,
|
|
39
|
+
interrupt_after: payload.interrupt_after,
|
|
40
|
+
feedback_keys: payload.feedback_keys,
|
|
41
|
+
subgraphs: payload.stream_subgraphs,
|
|
42
|
+
temporary: false,
|
|
43
|
+
},
|
|
44
|
+
multitask_strategy: "reject",
|
|
45
|
+
created_at: now,
|
|
46
|
+
updated_at: now,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Attach LangGraph Platform-esque routes to a given Hono instance.
|
|
51
|
+
* @experimental Does not follow semver.
|
|
52
|
+
*/
|
|
53
|
+
export function createEmbedServer(options) {
|
|
54
|
+
async function getGraph(graphId) {
|
|
55
|
+
const targetGraph = options.graph[graphId];
|
|
56
|
+
targetGraph.store = options.store;
|
|
57
|
+
targetGraph.checkpointer = options.checkpointer;
|
|
58
|
+
return targetGraph;
|
|
59
|
+
}
|
|
60
|
+
const api = new Hono();
|
|
61
|
+
api.use(ensureContentType());
|
|
62
|
+
api.post("/threads", zValidator("json", schemas.ThreadCreate), async (c) => {
|
|
63
|
+
// create a new threaad
|
|
64
|
+
const payload = c.req.valid("json");
|
|
65
|
+
const threadId = payload.thread_id || uuidv4();
|
|
66
|
+
await options.threads.put(threadId, payload);
|
|
67
|
+
return jsonExtra(c, { thread_id: threadId });
|
|
68
|
+
});
|
|
69
|
+
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) => {
|
|
70
|
+
// Get Latest Thread State
|
|
71
|
+
const { thread_id } = c.req.valid("param");
|
|
72
|
+
const { subgraphs } = c.req.valid("query");
|
|
73
|
+
const thread = await options.threads.get(thread_id);
|
|
74
|
+
const graphId = thread.metadata?.graph_id;
|
|
75
|
+
const graph = graphId ? options.graph[graphId] : undefined;
|
|
76
|
+
if (graph == null) {
|
|
77
|
+
return jsonExtra(c, stateSnapshotToThreadState({
|
|
78
|
+
values: {},
|
|
79
|
+
next: [],
|
|
80
|
+
config: {},
|
|
81
|
+
metadata: undefined,
|
|
82
|
+
createdAt: undefined,
|
|
83
|
+
parentConfig: undefined,
|
|
84
|
+
tasks: [],
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
const config = { configurable: { thread_id } };
|
|
88
|
+
const result = await graph.getState(config, { subgraphs });
|
|
89
|
+
return jsonExtra(c, stateSnapshotToThreadState(result));
|
|
90
|
+
});
|
|
91
|
+
api.post("/threads/:thread_id/history", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.ThreadHistoryRequest), async (c) => {
|
|
92
|
+
// Get Thread History Post
|
|
93
|
+
const { thread_id } = c.req.valid("param");
|
|
94
|
+
const { limit, before, metadata, checkpoint } = c.req.valid("json");
|
|
95
|
+
const thread = await options.threads.get(thread_id);
|
|
96
|
+
const graphId = thread.metadata?.graph_id;
|
|
97
|
+
const graph = graphId ? options.graph[graphId] : undefined;
|
|
98
|
+
if (graph == null)
|
|
99
|
+
return jsonExtra(c, []);
|
|
100
|
+
const config = { configurable: { thread_id, ...checkpoint } };
|
|
101
|
+
const result = [];
|
|
102
|
+
const beforeConfig = typeof before === "string"
|
|
103
|
+
? { configurable: { checkpoint_id: before } }
|
|
104
|
+
: before;
|
|
105
|
+
for await (const state of graph.getStateHistory(config, {
|
|
106
|
+
limit,
|
|
107
|
+
before: beforeConfig,
|
|
108
|
+
filter: metadata,
|
|
109
|
+
})) {
|
|
110
|
+
result.push(stateSnapshotToThreadState(state));
|
|
111
|
+
}
|
|
112
|
+
return jsonExtra(c, result);
|
|
113
|
+
});
|
|
114
|
+
api.post("/threads/:thread_id/runs/stream", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.RunCreate), async (c) => {
|
|
115
|
+
// Stream Run
|
|
116
|
+
return streamSSE(c, async (stream) => {
|
|
117
|
+
const { thread_id } = c.req.valid("param");
|
|
118
|
+
const payload = c.req.valid("json");
|
|
119
|
+
const signal = getDisconnectAbortSignal(c, stream);
|
|
120
|
+
const run = createStubRun(thread_id, payload);
|
|
121
|
+
// update thread with new graph_id
|
|
122
|
+
const thread = await options.threads.get(thread_id);
|
|
123
|
+
await options.threads.put(thread_id, {
|
|
124
|
+
metadata: {
|
|
125
|
+
...thread.metadata,
|
|
126
|
+
graph_id: payload.assistant_id,
|
|
127
|
+
assistant_id: payload.assistant_id,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
for await (const { event, data } of streamState(run, {
|
|
131
|
+
attempt: 1,
|
|
132
|
+
getGraph,
|
|
133
|
+
signal,
|
|
134
|
+
})) {
|
|
135
|
+
await stream.writeSSE({ data: serialiseAsDict(data), event });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
api.post("/runs/stream", zValidator("json", schemas.RunCreate), async (c) => {
|
|
140
|
+
// Stream Stateless Run
|
|
141
|
+
return streamSSE(c, async (stream) => {
|
|
142
|
+
const payload = c.req.valid("json");
|
|
143
|
+
const signal = getDisconnectAbortSignal(c, stream);
|
|
144
|
+
const threadId = uuidv4();
|
|
145
|
+
await options.threads.put(threadId, {
|
|
146
|
+
metadata: {
|
|
147
|
+
graph_id: payload.assistant_id,
|
|
148
|
+
assistant_id: payload.assistant_id,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
const run = createStubRun(threadId, payload);
|
|
153
|
+
for await (const { event, data } of streamState(run, {
|
|
154
|
+
attempt: 1,
|
|
155
|
+
getGraph,
|
|
156
|
+
signal,
|
|
157
|
+
})) {
|
|
158
|
+
await stream.writeSSE({ data: serialiseAsDict(data), event });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await options.threads.delete(threadId);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
return api;
|
|
167
|
+
}
|
package/dist/queue.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { streamState, } from "./stream.mjs";
|
|
|
3
3
|
import { logError, logger } from "./logging.mjs";
|
|
4
4
|
import { serializeError } from "./utils/serde.mjs";
|
|
5
5
|
import { callWebhook } from "./webhook.mjs";
|
|
6
|
+
import { getGraph } from "./graph/load.mjs";
|
|
6
7
|
const MAX_RETRY_ATTEMPTS = 3;
|
|
7
8
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
9
|
export const queue = async () => {
|
|
@@ -14,7 +15,7 @@ export const queue = async () => {
|
|
|
14
15
|
await sleep(1000 * Math.random());
|
|
15
16
|
}
|
|
16
17
|
};
|
|
17
|
-
const worker = async (run, attempt,
|
|
18
|
+
const worker = async (run, attempt, signal) => {
|
|
18
19
|
const startedAt = new Date();
|
|
19
20
|
let endedAt = undefined;
|
|
20
21
|
let checkpoint = undefined;
|
|
@@ -48,8 +49,10 @@ const worker = async (run, attempt, abortSignal) => {
|
|
|
48
49
|
const runId = run.run_id;
|
|
49
50
|
const resumable = run.kwargs?.resumable ?? false;
|
|
50
51
|
try {
|
|
51
|
-
const stream = streamState(run,
|
|
52
|
-
|
|
52
|
+
const stream = streamState(run, {
|
|
53
|
+
getGraph,
|
|
54
|
+
attempt,
|
|
55
|
+
signal,
|
|
53
56
|
...(!temporary ? { onCheckpoint, onTaskResult } : undefined),
|
|
54
57
|
});
|
|
55
58
|
for await (const { event, data } of stream) {
|
package/dist/schemas.d.mts
CHANGED
|
@@ -579,6 +579,16 @@ export declare const CommandSchema: z.ZodObject<{
|
|
|
579
579
|
})[] | undefined;
|
|
580
580
|
resume?: unknown;
|
|
581
581
|
}>;
|
|
582
|
+
export declare const LangsmithTracer: z.ZodObject<{
|
|
583
|
+
project_name: z.ZodOptional<z.ZodString>;
|
|
584
|
+
example_id: z.ZodOptional<z.ZodString>;
|
|
585
|
+
}, "strip", z.ZodTypeAny, {
|
|
586
|
+
project_name?: string | undefined;
|
|
587
|
+
example_id?: string | undefined;
|
|
588
|
+
}, {
|
|
589
|
+
project_name?: string | undefined;
|
|
590
|
+
example_id?: string | undefined;
|
|
591
|
+
}>;
|
|
582
592
|
export declare const RunCreate: z.ZodObject<{
|
|
583
593
|
assistant_id: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
584
594
|
checkpoint_id: z.ZodOptional<z.ZodString>;
|
|
@@ -692,6 +702,16 @@ export declare const RunCreate: z.ZodObject<{
|
|
|
692
702
|
if_not_exists: z.ZodOptional<z.ZodEnum<["reject", "create"]>>;
|
|
693
703
|
on_completion: z.ZodOptional<z.ZodEnum<["delete", "keep"]>>;
|
|
694
704
|
feedback_keys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
705
|
+
langsmith_tracer: z.ZodOptional<z.ZodObject<{
|
|
706
|
+
project_name: z.ZodOptional<z.ZodString>;
|
|
707
|
+
example_id: z.ZodOptional<z.ZodString>;
|
|
708
|
+
}, "strip", z.ZodTypeAny, {
|
|
709
|
+
project_name?: string | undefined;
|
|
710
|
+
example_id?: string | undefined;
|
|
711
|
+
}, {
|
|
712
|
+
project_name?: string | undefined;
|
|
713
|
+
example_id?: string | undefined;
|
|
714
|
+
}>>;
|
|
695
715
|
}, "strip", z.ZodTypeAny, {
|
|
696
716
|
assistant_id: string;
|
|
697
717
|
on_disconnect: "cancel" | "continue";
|
|
@@ -739,6 +759,10 @@ export declare const RunCreate: z.ZodObject<{
|
|
|
739
759
|
stream_subgraphs?: boolean | undefined;
|
|
740
760
|
stream_resumable?: boolean | undefined;
|
|
741
761
|
on_completion?: "delete" | "keep" | undefined;
|
|
762
|
+
langsmith_tracer?: {
|
|
763
|
+
project_name?: string | undefined;
|
|
764
|
+
example_id?: string | undefined;
|
|
765
|
+
} | undefined;
|
|
742
766
|
}, {
|
|
743
767
|
assistant_id: string;
|
|
744
768
|
metadata?: z.objectInputType<{}, z.ZodAny, "strip"> | undefined;
|
|
@@ -786,6 +810,10 @@ export declare const RunCreate: z.ZodObject<{
|
|
|
786
810
|
stream_subgraphs?: boolean | undefined;
|
|
787
811
|
stream_resumable?: boolean | undefined;
|
|
788
812
|
on_completion?: "delete" | "keep" | undefined;
|
|
813
|
+
langsmith_tracer?: {
|
|
814
|
+
project_name?: string | undefined;
|
|
815
|
+
example_id?: string | undefined;
|
|
816
|
+
} | undefined;
|
|
789
817
|
}>;
|
|
790
818
|
export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
|
|
791
819
|
assistant_id: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
@@ -900,6 +928,16 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
|
|
|
900
928
|
if_not_exists: z.ZodOptional<z.ZodEnum<["reject", "create"]>>;
|
|
901
929
|
on_completion: z.ZodOptional<z.ZodEnum<["delete", "keep"]>>;
|
|
902
930
|
feedback_keys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
931
|
+
langsmith_tracer: z.ZodOptional<z.ZodObject<{
|
|
932
|
+
project_name: z.ZodOptional<z.ZodString>;
|
|
933
|
+
example_id: z.ZodOptional<z.ZodString>;
|
|
934
|
+
}, "strip", z.ZodTypeAny, {
|
|
935
|
+
project_name?: string | undefined;
|
|
936
|
+
example_id?: string | undefined;
|
|
937
|
+
}, {
|
|
938
|
+
project_name?: string | undefined;
|
|
939
|
+
example_id?: string | undefined;
|
|
940
|
+
}>>;
|
|
903
941
|
}, "strip", z.ZodTypeAny, {
|
|
904
942
|
assistant_id: string;
|
|
905
943
|
on_disconnect: "cancel" | "continue";
|
|
@@ -947,6 +985,10 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
|
|
|
947
985
|
stream_subgraphs?: boolean | undefined;
|
|
948
986
|
stream_resumable?: boolean | undefined;
|
|
949
987
|
on_completion?: "delete" | "keep" | undefined;
|
|
988
|
+
langsmith_tracer?: {
|
|
989
|
+
project_name?: string | undefined;
|
|
990
|
+
example_id?: string | undefined;
|
|
991
|
+
} | undefined;
|
|
950
992
|
}, {
|
|
951
993
|
assistant_id: string;
|
|
952
994
|
metadata?: z.objectInputType<{}, z.ZodAny, "strip"> | undefined;
|
|
@@ -994,6 +1036,10 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
|
|
|
994
1036
|
stream_subgraphs?: boolean | undefined;
|
|
995
1037
|
stream_resumable?: boolean | undefined;
|
|
996
1038
|
on_completion?: "delete" | "keep" | undefined;
|
|
1039
|
+
langsmith_tracer?: {
|
|
1040
|
+
project_name?: string | undefined;
|
|
1041
|
+
example_id?: string | undefined;
|
|
1042
|
+
} | undefined;
|
|
997
1043
|
}>, "many">;
|
|
998
1044
|
export declare const SearchResult: z.ZodObject<{
|
|
999
1045
|
metadata: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodAny, z.objectOutputType<{}, z.ZodAny, "strip">, z.objectInputType<{}, z.ZodAny, "strip">>>;
|
|
@@ -1294,6 +1340,49 @@ export declare const ThreadStateUpdate: z.ZodObject<{
|
|
|
1294
1340
|
checkpoint_id?: string | undefined;
|
|
1295
1341
|
as_node?: string | undefined;
|
|
1296
1342
|
}>;
|
|
1343
|
+
export declare const ThreadHistoryRequest: z.ZodObject<{
|
|
1344
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
1345
|
+
before: z.ZodOptional<z.ZodString>;
|
|
1346
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1347
|
+
checkpoint: z.ZodOptional<z.ZodObject<{
|
|
1348
|
+
checkpoint_id: z.ZodOptional<z.ZodString>;
|
|
1349
|
+
checkpoint_ns: z.ZodOptional<z.ZodString>;
|
|
1350
|
+
checkpoint_map: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1351
|
+
}, "strip", z.ZodTypeAny, {
|
|
1352
|
+
checkpoint_ns?: string | undefined;
|
|
1353
|
+
checkpoint_id?: string | undefined;
|
|
1354
|
+
checkpoint_map?: Record<string, unknown> | undefined;
|
|
1355
|
+
}, {
|
|
1356
|
+
checkpoint_ns?: string | undefined;
|
|
1357
|
+
checkpoint_id?: string | undefined;
|
|
1358
|
+
checkpoint_map?: Record<string, unknown> | undefined;
|
|
1359
|
+
}>>;
|
|
1360
|
+
}, "strip", z.ZodTypeAny, {
|
|
1361
|
+
limit: number;
|
|
1362
|
+
metadata?: Record<string, unknown> | undefined;
|
|
1363
|
+
checkpoint?: {
|
|
1364
|
+
checkpoint_ns?: string | undefined;
|
|
1365
|
+
checkpoint_id?: string | undefined;
|
|
1366
|
+
checkpoint_map?: Record<string, unknown> | undefined;
|
|
1367
|
+
} | undefined;
|
|
1368
|
+
before?: string | undefined;
|
|
1369
|
+
}, {
|
|
1370
|
+
metadata?: Record<string, unknown> | undefined;
|
|
1371
|
+
checkpoint?: {
|
|
1372
|
+
checkpoint_ns?: string | undefined;
|
|
1373
|
+
checkpoint_id?: string | undefined;
|
|
1374
|
+
checkpoint_map?: Record<string, unknown> | undefined;
|
|
1375
|
+
} | undefined;
|
|
1376
|
+
limit?: number | undefined;
|
|
1377
|
+
before?: string | undefined;
|
|
1378
|
+
}>;
|
|
1379
|
+
export declare const ThreadPatchRequest: z.ZodObject<{
|
|
1380
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
1381
|
+
}, "strip", z.ZodTypeAny, {
|
|
1382
|
+
metadata: Record<string, unknown>;
|
|
1383
|
+
}, {
|
|
1384
|
+
metadata: Record<string, unknown>;
|
|
1385
|
+
}>;
|
|
1297
1386
|
export declare const AssistantLatestVersion: z.ZodObject<{
|
|
1298
1387
|
version: z.ZodNumber;
|
|
1299
1388
|
}, "strip", z.ZodTypeAny, {
|
package/dist/schemas.mjs
CHANGED
|
@@ -159,6 +159,10 @@ export const CommandSchema = z.object({
|
|
|
159
159
|
.optional(),
|
|
160
160
|
resume: z.unknown().optional(),
|
|
161
161
|
});
|
|
162
|
+
export const LangsmithTracer = z.object({
|
|
163
|
+
project_name: z.string().optional(),
|
|
164
|
+
example_id: z.string().optional(),
|
|
165
|
+
});
|
|
162
166
|
export const RunCreate = z
|
|
163
167
|
.object({
|
|
164
168
|
assistant_id: z.union([z.string().uuid(), z.string()]),
|
|
@@ -210,6 +214,7 @@ export const RunCreate = z
|
|
|
210
214
|
if_not_exists: z.enum(["reject", "create"]).optional(),
|
|
211
215
|
on_completion: z.enum(["delete", "keep"]).optional(),
|
|
212
216
|
feedback_keys: z.array(z.string()).optional(),
|
|
217
|
+
langsmith_tracer: LangsmithTracer.optional(),
|
|
213
218
|
})
|
|
214
219
|
.describe("Payload for creating a stateful run.");
|
|
215
220
|
export const RunBatchCreate = z
|
|
@@ -383,6 +388,21 @@ export const ThreadStateUpdate = z
|
|
|
383
388
|
as_node: z.string().optional(),
|
|
384
389
|
})
|
|
385
390
|
.describe("Payload for adding state to a thread.");
|
|
391
|
+
export const ThreadHistoryRequest = z.object({
|
|
392
|
+
limit: z.number().optional().default(10),
|
|
393
|
+
before: z.string().optional(),
|
|
394
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
395
|
+
checkpoint: z
|
|
396
|
+
.object({
|
|
397
|
+
checkpoint_id: z.string().uuid().optional(),
|
|
398
|
+
checkpoint_ns: z.string().optional(),
|
|
399
|
+
checkpoint_map: z.record(z.string(), z.unknown()).optional(),
|
|
400
|
+
})
|
|
401
|
+
.optional(),
|
|
402
|
+
});
|
|
403
|
+
export const ThreadPatchRequest = z.object({
|
|
404
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
405
|
+
});
|
|
386
406
|
export const AssistantLatestVersion = z.object({
|
|
387
407
|
version: z.number(),
|
|
388
408
|
});
|
package/dist/storage/ops.mjs
CHANGED
|
@@ -744,27 +744,37 @@ export class Runs {
|
|
|
744
744
|
static async *next() {
|
|
745
745
|
yield* conn.withGenerator(async function* (STORE, options) {
|
|
746
746
|
const now = new Date();
|
|
747
|
-
const
|
|
747
|
+
const pendingRunIds = Object.values(STORE.runs)
|
|
748
748
|
.filter((run) => run.status === "pending" && run.created_at < now)
|
|
749
|
-
.sort((a, b) => a.created_at.getTime() - b.created_at.getTime())
|
|
750
|
-
|
|
749
|
+
.sort((a, b) => a.created_at.getTime() - b.created_at.getTime())
|
|
750
|
+
.map((run) => run.run_id);
|
|
751
|
+
if (!pendingRunIds.length) {
|
|
751
752
|
return;
|
|
752
753
|
}
|
|
753
|
-
for (const
|
|
754
|
-
const runId = run.run_id;
|
|
755
|
-
const threadId = run.thread_id;
|
|
756
|
-
const thread = STORE.threads[threadId];
|
|
757
|
-
if (!thread) {
|
|
758
|
-
await console.warn(`Unexpected missing thread in Runs.next: ${threadId}`);
|
|
759
|
-
continue;
|
|
760
|
-
}
|
|
754
|
+
for (const runId of pendingRunIds) {
|
|
761
755
|
if (StreamManager.isLocked(runId))
|
|
762
756
|
continue;
|
|
763
757
|
try {
|
|
764
758
|
const signal = StreamManager.lock(runId);
|
|
759
|
+
const run = STORE.runs[runId];
|
|
760
|
+
if (!run)
|
|
761
|
+
continue;
|
|
762
|
+
const threadId = run.thread_id;
|
|
763
|
+
const thread = STORE.threads[threadId];
|
|
764
|
+
if (!thread) {
|
|
765
|
+
logger.warn(`Unexpected missing thread in Runs.next: ${threadId}`);
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
// is the run still valid?
|
|
769
|
+
if (run.status !== "pending")
|
|
770
|
+
continue;
|
|
771
|
+
if (Object.values(STORE.runs).some((run) => run.thread_id === threadId && run.status === "running")) {
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
765
774
|
options.schedulePersist();
|
|
766
775
|
STORE.retry_counter[runId] ??= 0;
|
|
767
776
|
STORE.retry_counter[runId] += 1;
|
|
777
|
+
STORE.runs[runId].status = "running";
|
|
768
778
|
yield { run, attempt: STORE.retry_counter[runId], signal };
|
|
769
779
|
}
|
|
770
780
|
finally {
|
|
@@ -842,7 +852,8 @@ export class Runs {
|
|
|
842
852
|
}
|
|
843
853
|
// if multitask_mode = reject, check for inflight runs
|
|
844
854
|
// and if there are any, return them to reject putting a new run
|
|
845
|
-
const inflightRuns = Object.values(STORE.runs).filter((run) => run.thread_id === threadId &&
|
|
855
|
+
const inflightRuns = Object.values(STORE.runs).filter((run) => run.thread_id === threadId &&
|
|
856
|
+
(run.status === "pending" || run.status === "running"));
|
|
846
857
|
if (options?.preventInsertInInflight) {
|
|
847
858
|
if (inflightRuns.length > 0)
|
|
848
859
|
return inflightRuns;
|
|
@@ -1090,7 +1101,7 @@ export class Runs {
|
|
|
1090
1101
|
yield { event: "error", data: "Run not found" };
|
|
1091
1102
|
break;
|
|
1092
1103
|
}
|
|
1093
|
-
else if (run.status !== "pending") {
|
|
1104
|
+
else if (run.status !== "pending" && run.status !== "running") {
|
|
1094
1105
|
break;
|
|
1095
1106
|
}
|
|
1096
1107
|
}
|
package/dist/stream.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
1
|
+
import type { BaseCheckpointSaver, LangGraphRunnableConfig, CheckpointMetadata, Interrupt, StateSnapshot } from "@langchain/langgraph";
|
|
2
|
+
import type { Pregel } from "@langchain/langgraph/pregel";
|
|
3
|
+
import type { Checkpoint, Run, RunnableConfig } from "./storage/ops.mjs";
|
|
3
4
|
interface DebugTask {
|
|
4
5
|
id: string;
|
|
5
6
|
name: string;
|
|
@@ -27,7 +28,11 @@ export type StreamTaskResult = Prettify<Omit<DebugTask, "state"> & {
|
|
|
27
28
|
state?: StateSnapshot;
|
|
28
29
|
checkpoint?: Checkpoint;
|
|
29
30
|
}>;
|
|
30
|
-
export declare function streamState(run: Run,
|
|
31
|
+
export declare function streamState(run: Run, options: {
|
|
32
|
+
attempt: number;
|
|
33
|
+
getGraph: (graphId: string, config: LangGraphRunnableConfig | undefined, options?: {
|
|
34
|
+
checkpointer?: BaseCheckpointSaver | null;
|
|
35
|
+
}) => Promise<Pregel<any, any, any, any, any>>;
|
|
31
36
|
onCheckpoint?: (checkpoint: StreamCheckpoint) => void;
|
|
32
37
|
onTaskResult?: (taskResult: StreamTaskResult) => void;
|
|
33
38
|
signal?: AbortSignal;
|
package/dist/stream.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { getGraph } from "./graph/load.mjs";
|
|
2
|
-
import { Client as LangSmithClient } from "langsmith";
|
|
3
|
-
import { runnableConfigToCheckpoint, taskRunnableConfigToCheckpoint, } from "./utils/runnableConfig.mjs";
|
|
4
1
|
import { isBaseMessage } from "@langchain/core/messages";
|
|
2
|
+
import { LangChainTracer } from "@langchain/core/tracers/tracer_langchain";
|
|
3
|
+
import { Client as LangSmithClient, getDefaultProjectName } from "langsmith";
|
|
5
4
|
import { getLangGraphCommand } from "./command.mjs";
|
|
6
5
|
import { checkLangGraphSemver } from "./semver/index.mjs";
|
|
6
|
+
import { runnableConfigToCheckpoint, taskRunnableConfigToCheckpoint, } from "./utils/runnableConfig.mjs";
|
|
7
7
|
const isRunnableConfig = (config) => {
|
|
8
8
|
if (typeof config !== "object" || config == null)
|
|
9
9
|
return false;
|
|
@@ -53,13 +53,13 @@ function preprocessDebugCheckpoint(payload) {
|
|
|
53
53
|
return result;
|
|
54
54
|
}
|
|
55
55
|
let LANGGRAPH_VERSION;
|
|
56
|
-
export async function* streamState(run,
|
|
56
|
+
export async function* streamState(run, options) {
|
|
57
57
|
const kwargs = run.kwargs;
|
|
58
58
|
const graphId = kwargs.config?.configurable?.graph_id;
|
|
59
59
|
if (!graphId || typeof graphId !== "string") {
|
|
60
60
|
throw new Error("Invalid or missing graph_id");
|
|
61
61
|
}
|
|
62
|
-
const graph = await getGraph(graphId, kwargs.config, {
|
|
62
|
+
const graph = await options.getGraph(graphId, kwargs.config, {
|
|
63
63
|
checkpointer: kwargs.temporary ? null : undefined,
|
|
64
64
|
});
|
|
65
65
|
const userStreamMode = kwargs.stream_mode ?? [];
|
|
@@ -74,7 +74,7 @@ export async function* streamState(run, attempt = 1, options) {
|
|
|
74
74
|
libStreamMode.add("debug");
|
|
75
75
|
yield {
|
|
76
76
|
event: "metadata",
|
|
77
|
-
data: { run_id: run.run_id, attempt },
|
|
77
|
+
data: { run_id: run.run_id, attempt: options.attempt },
|
|
78
78
|
};
|
|
79
79
|
if (!LANGGRAPH_VERSION) {
|
|
80
80
|
const version = await checkLangGraphSemver();
|
|
@@ -82,12 +82,25 @@ export async function* streamState(run, attempt = 1, options) {
|
|
|
82
82
|
}
|
|
83
83
|
const metadata = {
|
|
84
84
|
...kwargs.config?.metadata,
|
|
85
|
-
run_attempt: attempt,
|
|
85
|
+
run_attempt: options.attempt,
|
|
86
86
|
langgraph_version: LANGGRAPH_VERSION?.version ?? "0.0.0",
|
|
87
87
|
langgraph_plan: "developer",
|
|
88
88
|
langgraph_host: "self-hosted",
|
|
89
89
|
langgraph_api_url: process.env.LANGGRAPH_API_URL ?? undefined,
|
|
90
90
|
};
|
|
91
|
+
const tracer = run.kwargs?.config?.configurable?.langsmith_project
|
|
92
|
+
? new LangChainTracer({
|
|
93
|
+
replicas: [
|
|
94
|
+
[
|
|
95
|
+
run.kwargs?.config?.configurable?.langsmith_project,
|
|
96
|
+
{
|
|
97
|
+
reference_example_id: run.kwargs?.config?.configurable?.langsmith_example_id,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
[getDefaultProjectName(), undefined],
|
|
101
|
+
],
|
|
102
|
+
})
|
|
103
|
+
: undefined;
|
|
91
104
|
const events = graph.streamEvents(kwargs.command != null
|
|
92
105
|
? getLangGraphCommand(kwargs.command)
|
|
93
106
|
: (kwargs.input ?? null), {
|
|
@@ -102,6 +115,7 @@ export async function* streamState(run, attempt = 1, options) {
|
|
|
102
115
|
runId: run.run_id,
|
|
103
116
|
streamMode: [...libStreamMode],
|
|
104
117
|
signal: options?.signal,
|
|
118
|
+
...(tracer && { callbacks: [tracer] }),
|
|
105
119
|
});
|
|
106
120
|
const messages = {};
|
|
107
121
|
const completedIds = new Set();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^18.19.0 || >=20.16.0"
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"types": "./dist/graph/parser/index.d.mts",
|
|
28
28
|
"default": "./dist/graph/parser/index.mjs"
|
|
29
29
|
},
|
|
30
|
+
"./experimental/embed": {
|
|
31
|
+
"types": "./dist/experimental/embed.d.mts",
|
|
32
|
+
"default": "./dist/experimental/embed.mjs"
|
|
33
|
+
},
|
|
30
34
|
"./package.json": "./package.json"
|
|
31
35
|
},
|
|
32
36
|
"repository": {
|
|
@@ -49,14 +53,14 @@
|
|
|
49
53
|
"@babel/code-frame": "^7.26.2",
|
|
50
54
|
"@hono/node-server": "^1.12.0",
|
|
51
55
|
"@hono/zod-validator": "^0.2.2",
|
|
52
|
-
"@langchain/langgraph-ui": "0.0.
|
|
56
|
+
"@langchain/langgraph-ui": "0.0.41",
|
|
53
57
|
"@types/json-schema": "^7.0.15",
|
|
54
58
|
"@typescript/vfs": "^1.6.0",
|
|
55
59
|
"dedent": "^1.5.3",
|
|
56
60
|
"dotenv": "^16.4.7",
|
|
57
61
|
"exit-hook": "^4.0.0",
|
|
58
62
|
"hono": "^4.5.4",
|
|
59
|
-
"langsmith": "^0.
|
|
63
|
+
"langsmith": "^0.3.33",
|
|
60
64
|
"open": "^10.1.0",
|
|
61
65
|
"semver": "^7.7.1",
|
|
62
66
|
"stacktrace-parser": "^0.1.10",
|
|
@@ -68,7 +72,7 @@
|
|
|
68
72
|
"zod": "^3.23.8"
|
|
69
73
|
},
|
|
70
74
|
"peerDependencies": {
|
|
71
|
-
"@langchain/core": "^0.3.
|
|
75
|
+
"@langchain/core": "^0.3.59",
|
|
72
76
|
"@langchain/langgraph": "^0.2.57 || ^0.3.0",
|
|
73
77
|
"@langchain/langgraph-checkpoint": "~0.0.16",
|
|
74
78
|
"@langchain/langgraph-sdk": "~0.0.70",
|
|
@@ -80,7 +84,7 @@
|
|
|
80
84
|
}
|
|
81
85
|
},
|
|
82
86
|
"devDependencies": {
|
|
83
|
-
"@langchain/core": "^0.3.
|
|
87
|
+
"@langchain/core": "^0.3.59",
|
|
84
88
|
"@langchain/langgraph": "^0.2.57",
|
|
85
89
|
"@langchain/langgraph-checkpoint": "~0.0.16",
|
|
86
90
|
"@langchain/langgraph-sdk": "^0.0.77",
|