@langchain/langgraph-api 1.1.16 → 1.2.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.
- package/dist/api/protocol.d.mts +7 -0
- package/dist/api/protocol.mjs +157 -0
- package/dist/api/runs.mjs +15 -4
- package/dist/command.mjs +1 -1
- package/dist/experimental/embed/constants.d.mts +3 -0
- package/dist/experimental/embed/constants.mjs +11 -0
- package/dist/experimental/embed/protocol.d.mts +9 -0
- package/dist/experimental/embed/protocol.mjs +453 -0
- package/dist/experimental/embed/runs.d.mts +8 -0
- package/dist/experimental/embed/runs.mjs +202 -0
- package/dist/experimental/embed/threads.d.mts +8 -0
- package/dist/experimental/embed/threads.mjs +151 -0
- package/dist/experimental/embed/types.d.mts +77 -0
- package/dist/experimental/embed/types.mjs +1 -0
- package/dist/experimental/embed/utils.d.mts +29 -0
- package/dist/experimental/embed/utils.mjs +62 -0
- package/dist/experimental/embed.d.mts +11 -31
- package/dist/experimental/embed.mjs +19 -399
- package/dist/graph/load.d.mts +2 -2
- package/dist/graph/load.utils.mjs +13 -3
- package/dist/protocol/constants.d.mts +7 -0
- package/dist/protocol/constants.mjs +7 -0
- package/dist/protocol/service.d.mts +101 -0
- package/dist/protocol/service.mjs +568 -0
- package/dist/protocol/session/event-normalizers.d.mts +52 -0
- package/dist/protocol/session/event-normalizers.mjs +162 -0
- package/dist/protocol/session/index.d.mts +261 -0
- package/dist/protocol/session/index.mjs +826 -0
- package/dist/protocol/session/internal-types.d.mts +67 -0
- package/dist/protocol/session/internal-types.mjs +28 -0
- package/dist/protocol/session/metadata.d.mts +24 -0
- package/dist/protocol/session/metadata.mjs +95 -0
- package/dist/protocol/session/namespace.d.mts +47 -0
- package/dist/protocol/session/namespace.mjs +62 -0
- package/dist/protocol/session/state-normalizers.d.mts +57 -0
- package/dist/protocol/session/state-normalizers.mjs +430 -0
- package/dist/protocol/session/tool-calls.d.mts +27 -0
- package/dist/protocol/session/tool-calls.mjs +59 -0
- package/dist/protocol/types.d.mts +121 -0
- package/dist/protocol/types.mjs +1 -0
- package/dist/queue.mjs +8 -2
- package/dist/schemas.d.mts +58 -58
- package/dist/semver/index.mjs +19 -1
- package/dist/server.mjs +22 -3
- package/dist/state.mjs +1 -1
- package/dist/storage/ops.mjs +17 -5
- package/dist/storage/persist.mjs +1 -1
- package/dist/storage/types.d.mts +10 -1
- package/dist/stream.d.mts +25 -4
- package/dist/stream.mjs +203 -11
- package/dist/utils/serde.mjs +1 -1
- package/package.json +16 -14
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { UpgradeWebSocket } from "hono/ws";
|
|
3
|
+
import type { Ops } from "../storage/types.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Register thread-centric protocol transport routes for LangGraph API.
|
|
6
|
+
*/
|
|
7
|
+
export default function createProtocolApi(upgradeWebSocket: UpgradeWebSocket, ops: Ops): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { zValidator } from "@hono/zod-validator";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { streamSSE } from "hono/streaming";
|
|
4
|
+
import { v7 as uuid7 } from "uuid";
|
|
5
|
+
import { z } from "zod/v3";
|
|
6
|
+
import { ProtocolService } from "../protocol/service.mjs";
|
|
7
|
+
import { jsonExtra } from "../utils/hono.mjs";
|
|
8
|
+
import { serialiseAsDict } from "../utils/serde.mjs";
|
|
9
|
+
const ThreadIdSchema = z.object({ thread_id: z.string() });
|
|
10
|
+
const EventsFilterSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
channels: z.array(z.string()),
|
|
13
|
+
namespaces: z.array(z.array(z.string())).optional(),
|
|
14
|
+
depth: z.number().int().nonnegative().optional(),
|
|
15
|
+
since: z.number().int().nonnegative().optional(),
|
|
16
|
+
})
|
|
17
|
+
.strict();
|
|
18
|
+
const ProtocolCommandSchema = z.object({
|
|
19
|
+
id: z.number().int().nonnegative(),
|
|
20
|
+
method: z.string(),
|
|
21
|
+
params: z.record(z.unknown()).optional(),
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Normalize browser/node websocket message payloads into UTF-8 text so the
|
|
25
|
+
* protocol layer only needs to handle JSON strings.
|
|
26
|
+
*/
|
|
27
|
+
const parseSocketPayload = async (event) => {
|
|
28
|
+
if (typeof event.data === "string")
|
|
29
|
+
return event.data;
|
|
30
|
+
if (event.data instanceof ArrayBuffer) {
|
|
31
|
+
return new TextDecoder().decode(new Uint8Array(event.data));
|
|
32
|
+
}
|
|
33
|
+
if (event.data instanceof Blob) {
|
|
34
|
+
const buffer = await event.data.arrayBuffer();
|
|
35
|
+
return new TextDecoder().decode(new Uint8Array(buffer));
|
|
36
|
+
}
|
|
37
|
+
return String(event.data);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Register thread-centric protocol transport routes for LangGraph API.
|
|
41
|
+
*/
|
|
42
|
+
export default function createProtocolApi(upgradeWebSocket, ops) {
|
|
43
|
+
const api = new Hono();
|
|
44
|
+
const protocolService = new ProtocolService({
|
|
45
|
+
runs: ops.runs,
|
|
46
|
+
threads: ops.threads,
|
|
47
|
+
});
|
|
48
|
+
api.get("/v2/threads/:thread_id/stream", zValidator("param", ThreadIdSchema), upgradeWebSocket((c) => {
|
|
49
|
+
const { thread_id } = c.req.valid("param");
|
|
50
|
+
const record = protocolService.ensureThread({
|
|
51
|
+
threadId: thread_id,
|
|
52
|
+
transport: "websocket",
|
|
53
|
+
auth: c.var.auth,
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
async onOpen(_event, ws) {
|
|
57
|
+
await protocolService.attachEventSink(thread_id, (event) => {
|
|
58
|
+
ws.send(serialiseAsDict(event));
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
async onMessage(event, ws) {
|
|
62
|
+
let payload;
|
|
63
|
+
try {
|
|
64
|
+
payload = JSON.parse(await parseSocketPayload(event));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
ws.send(serialiseAsDict({
|
|
68
|
+
type: "error",
|
|
69
|
+
id: null,
|
|
70
|
+
error: "invalid_argument",
|
|
71
|
+
message: "Protocol commands must be valid JSON.",
|
|
72
|
+
}));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (typeof payload !== "object" ||
|
|
76
|
+
payload == null ||
|
|
77
|
+
typeof payload.id !== "number" ||
|
|
78
|
+
typeof payload.method !== "string") {
|
|
79
|
+
ws.send(serialiseAsDict({
|
|
80
|
+
type: "error",
|
|
81
|
+
id: null,
|
|
82
|
+
error: "invalid_argument",
|
|
83
|
+
message: "Protocol commands must include an integer id and string method.",
|
|
84
|
+
}));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const response = await protocolService.handleCommand(record.threadId, payload);
|
|
88
|
+
// `null` means the session already wrote the response through
|
|
89
|
+
// the shared transport queue (see
|
|
90
|
+
// `ProtocolSession.handleSubscribeForResponse`). Sending again
|
|
91
|
+
// here would double-deliver the success and break ordering.
|
|
92
|
+
if (response != null) {
|
|
93
|
+
ws.send(serialiseAsDict(response));
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
onClose() {
|
|
97
|
+
void protocolService.closeThread(record.threadId);
|
|
98
|
+
},
|
|
99
|
+
onError() {
|
|
100
|
+
void protocolService.closeThread(record.threadId);
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}));
|
|
104
|
+
api.post("/v2/threads/:thread_id/commands", zValidator("param", ThreadIdSchema), zValidator("json", ProtocolCommandSchema), async (c) => {
|
|
105
|
+
const { thread_id } = c.req.valid("param");
|
|
106
|
+
protocolService.ensureThread({
|
|
107
|
+
threadId: thread_id,
|
|
108
|
+
transport: "sse-http",
|
|
109
|
+
auth: c.var.auth,
|
|
110
|
+
});
|
|
111
|
+
const payload = c.req.valid("json");
|
|
112
|
+
return jsonExtra(c, await protocolService.handleCommand(thread_id, payload));
|
|
113
|
+
});
|
|
114
|
+
api.post("/v2/threads/:thread_id/stream", zValidator("param", ThreadIdSchema), zValidator("json", EventsFilterSchema), async (c) => {
|
|
115
|
+
const { thread_id } = c.req.valid("param");
|
|
116
|
+
protocolService.ensureThread({
|
|
117
|
+
threadId: thread_id,
|
|
118
|
+
transport: "sse-http",
|
|
119
|
+
auth: c.var.auth,
|
|
120
|
+
});
|
|
121
|
+
const body = c.req.valid("json");
|
|
122
|
+
const sinkId = uuid7();
|
|
123
|
+
const filter = {
|
|
124
|
+
channels: new Set(body.channels),
|
|
125
|
+
namespaces: body.namespaces,
|
|
126
|
+
depth: body.depth,
|
|
127
|
+
since: body.since,
|
|
128
|
+
};
|
|
129
|
+
return streamSSE(c, async (stream) => {
|
|
130
|
+
const delivered = new Set();
|
|
131
|
+
const writeSse = async (event) => {
|
|
132
|
+
if (event.event_id == null)
|
|
133
|
+
return;
|
|
134
|
+
if (delivered.has(event.event_id))
|
|
135
|
+
return;
|
|
136
|
+
delivered.add(event.event_id);
|
|
137
|
+
await stream.writeSSE({
|
|
138
|
+
id: event.event_id,
|
|
139
|
+
event: event.method,
|
|
140
|
+
data: serialiseAsDict(event),
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
await protocolService.attachFilteredEventSink(thread_id, {
|
|
144
|
+
id: sinkId,
|
|
145
|
+
filter,
|
|
146
|
+
send: writeSse,
|
|
147
|
+
});
|
|
148
|
+
stream.onAbort(() => {
|
|
149
|
+
protocolService.detachEventSink(thread_id, sinkId);
|
|
150
|
+
});
|
|
151
|
+
await new Promise((resolve) => {
|
|
152
|
+
stream.onAbort(() => resolve());
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
return api;
|
|
157
|
+
}
|
package/dist/api/runs.mjs
CHANGED
|
@@ -150,7 +150,8 @@ api.post("/runs/stream", zValidator("json", schemas.RunCreate), async (c) => {
|
|
|
150
150
|
: undefined;
|
|
151
151
|
try {
|
|
152
152
|
for await (const { event, data } of runs().stream.join(run.run_id, undefined, {
|
|
153
|
-
cancelOnDisconnect,
|
|
153
|
+
signal: cancelOnDisconnect,
|
|
154
|
+
cancelOnDisconnect: cancelOnDisconnect != null,
|
|
154
155
|
lastEventId: run.kwargs.resumable ? "-1" : undefined,
|
|
155
156
|
ignore404: true,
|
|
156
157
|
}, c.var.auth)) {
|
|
@@ -173,7 +174,12 @@ api.get("/runs/:run_id/stream", zValidator("param", z.object({ run_id: z.string(
|
|
|
173
174
|
? getDisconnectAbortSignal(c, stream)
|
|
174
175
|
: undefined;
|
|
175
176
|
try {
|
|
176
|
-
for await (const { id, event, data } of runs().stream.join(run_id, undefined, {
|
|
177
|
+
for await (const { id, event, data } of runs().stream.join(run_id, undefined, {
|
|
178
|
+
signal: cancelOnDisconnect,
|
|
179
|
+
cancelOnDisconnect: cancelOnDisconnect != null,
|
|
180
|
+
lastEventId,
|
|
181
|
+
ignore404: true,
|
|
182
|
+
}, c.var.auth)) {
|
|
177
183
|
await stream.writeSSE({ id, data: serialiseAsDict(data), event });
|
|
178
184
|
}
|
|
179
185
|
}
|
|
@@ -252,7 +258,8 @@ api.post("/threads/:thread_id/runs/stream", zValidator("param", z.object({ threa
|
|
|
252
258
|
: undefined;
|
|
253
259
|
try {
|
|
254
260
|
for await (const { id, event, data } of runs().stream.join(run.run_id, thread_id, {
|
|
255
|
-
cancelOnDisconnect,
|
|
261
|
+
signal: cancelOnDisconnect,
|
|
262
|
+
cancelOnDisconnect: cancelOnDisconnect != null,
|
|
256
263
|
lastEventId: run.kwargs.resumable ? "-1" : undefined,
|
|
257
264
|
}, c.var.auth)) {
|
|
258
265
|
await stream.writeSSE({ id, data: serialiseAsDict(data), event });
|
|
@@ -304,7 +311,11 @@ api.get("/threads/:thread_id/runs/:run_id/stream", zValidator("param", z.object(
|
|
|
304
311
|
const signal = cancel_on_disconnect
|
|
305
312
|
? getDisconnectAbortSignal(c, stream)
|
|
306
313
|
: undefined;
|
|
307
|
-
for await (const { id, event, data } of runs().stream.join(run_id, thread_id, {
|
|
314
|
+
for await (const { id, event, data } of runs().stream.join(run_id, thread_id, {
|
|
315
|
+
signal,
|
|
316
|
+
cancelOnDisconnect: signal != null,
|
|
317
|
+
lastEventId,
|
|
318
|
+
}, c.var.auth)) {
|
|
308
319
|
await stream.writeSSE({ id, data: serialiseAsDict(data), event });
|
|
309
320
|
}
|
|
310
321
|
});
|
package/dist/command.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command, Send } from "@langchain/langgraph";
|
|
2
2
|
export const getLangGraphCommand = (command) => {
|
|
3
|
-
|
|
3
|
+
const goto = command.goto != null && !Array.isArray(command.goto)
|
|
4
4
|
? [command.goto]
|
|
5
5
|
: command.goto;
|
|
6
6
|
return new Command({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Hono } from "hono";
|
|
2
|
+
import type { UpgradeWebSocket } from "hono/ws";
|
|
3
|
+
import type { EmbedRouteContext } from "./types.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Register thread-centric v2 protocol routes on an embed server Hono app.
|
|
6
|
+
*
|
|
7
|
+
* @experimental Does not follow semver.
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerProtocolRoutes(api: Hono, context: EmbedRouteContext, upgradeWebSocket?: UpgradeWebSocket): void;
|