@langchain/langgraph-api 1.3.0 → 1.4.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.
@@ -1,6 +1,6 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
2
  import { Hono } from "hono";
3
- import { v7 as uuid } from "uuid";
3
+ import { v7 as uuid } from "@langchain/core/utils/uuid";
4
4
  import { z } from "zod/v3";
5
5
  import { getAssistantId, getCachedStaticGraphSchema, getGraph, } from "../graph/load.mjs";
6
6
  import { getRuntimeGraphSchema } from "../graph/parser/index.mjs";
@@ -1,7 +1,7 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
2
  import { Hono } from "hono";
3
3
  import { streamSSE } from "hono/streaming";
4
- import { v7 as uuid7 } from "uuid";
4
+ import { v7 as uuid7 } from "@langchain/core/utils/uuid";
5
5
  import { z } from "zod/v3";
6
6
  import { ProtocolService } from "../protocol/service.mjs";
7
7
  import { jsonExtra } from "../utils/hono.mjs";
package/dist/api/runs.mjs CHANGED
@@ -2,7 +2,7 @@ import { zValidator } from "@hono/zod-validator";
2
2
  import { Hono } from "hono";
3
3
  import { HTTPException } from "hono/http-exception";
4
4
  import { streamSSE } from "hono/streaming";
5
- import { v7 as uuid7 } from "uuid";
5
+ import { v7 as uuid7 } from "@langchain/core/utils/uuid";
6
6
  import { z } from "zod/v3";
7
7
  import { getAssistantId } from "../graph/load.mjs";
8
8
  import { logError, logger } from "../logging.mjs";
@@ -1,6 +1,6 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
2
  import { Hono } from "hono";
3
- import { v7 as uuid7 } from "uuid";
3
+ import { v7 as uuid7 } from "@langchain/core/utils/uuid";
4
4
  import { z } from "zod/v3";
5
5
  import * as schemas from "../schemas.mjs";
6
6
  import { stateSnapshotToThreadState } from "../state.mjs";
@@ -1,6 +1,6 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
2
  import { streamSSE } from "hono/streaming";
3
- import { v7 as uuidv7 } from "uuid";
3
+ import { v7 as uuidv7 } from "@langchain/core/utils/uuid";
4
4
  import { z } from "zod/v3";
5
5
  import { streamState } from "../../stream.mjs";
6
6
  import { serialiseAsDict } from "../../utils/serde.mjs";
@@ -298,11 +298,31 @@ export function registerProtocolRoutes(api, context, upgradeWebSocket) {
298
298
  message: "Thread has no active assistant; call run.start first.",
299
299
  });
300
300
  }
301
+ // `update` / `goto` are the optional state mutation and directed jump
302
+ // the SDK's `respond({ update, goto })` forwards on `input.respond`
303
+ // (`InputRespondOne` / `InputRespondMany`). Fold them into the same
304
+ // `Command(resume, update, goto)` as the resume so the resumed run
305
+ // produces a single checkpoint reflecting all of them — the HITL
306
+ // "push card into state + resume" flow. Read leniently (update: object
307
+ // or `[key, value][]` tuples; goto: node name, Send object, or a list
308
+ // of either), same posture as `config` / `metadata`.
309
+ const update = isRecord(params.update) || Array.isArray(params.update)
310
+ ? params.update
311
+ : undefined;
312
+ const goto = typeof params.goto === "string" ||
313
+ Array.isArray(params.goto) ||
314
+ isRecord(params.goto)
315
+ ? params.goto
316
+ : undefined;
301
317
  const run = createStubRun(thread.threadId, {
302
318
  assistant_id: assistantId,
303
319
  on_disconnect: "cancel",
304
320
  input: null,
305
- command: { resume: resumeInput },
321
+ command: {
322
+ resume: resumeInput,
323
+ ...(update != null ? { update } : {}),
324
+ ...(goto != null ? { goto } : {}),
325
+ },
306
326
  // Carry the SDK's `respond({ config, metadata })` onto the resumed
307
327
  // run so it applies the same run config / metadata a fresh
308
328
  // `run.start` would (both are part of the `input.respond` params).
@@ -1,6 +1,6 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
2
  import { streamSSE } from "hono/streaming";
3
- import { v7 as uuidv7 } from "uuid";
3
+ import { v7 as uuidv7 } from "@langchain/core/utils/uuid";
4
4
  import { z } from "zod/v3";
5
5
  import * as schemas from "../../schemas.mjs";
6
6
  import { streamState } from "../../stream.mjs";
@@ -1,5 +1,5 @@
1
1
  import { zValidator } from "@hono/zod-validator";
2
- import { v7 as uuidv7 } from "uuid";
2
+ import { v7 as uuidv7 } from "@langchain/core/utils/uuid";
3
3
  import { z } from "zod/v3";
4
4
  import * as schemas from "../../schemas.mjs";
5
5
  import { jsonExtra } from "../../utils/hono.mjs";
@@ -1,4 +1,4 @@
1
- import { v7 as uuidv7 } from "uuid";
1
+ import { v7 as uuidv7 } from "@langchain/core/utils/uuid";
2
2
  import { z } from "zod/v3";
3
3
  export const ProtocolCommandSchema = z.object({
4
4
  id: z.number().int().nonnegative(),
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod/v3";
2
- import * as uuid from "uuid";
2
+ import * as uuid from "@langchain/core/utils/uuid";
3
3
  import { HTTPException } from "hono/http-exception";
4
4
  import { resolveGraph } from "./load.utils.mjs";
5
5
  import { getStaticGraphSchema } from "./parser/index.mjs";
@@ -1,4 +1,4 @@
1
- import * as uuid from "uuid";
1
+ import * as uuid from "@langchain/core/utils/uuid";
2
2
  import * as path from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { pathToFileURL } from "node:url";
@@ -1,5 +1,5 @@
1
1
  import { inferChannel, isPrefixMatch } from "@langchain/langgraph/stream";
2
- import { v7 as uuid7 } from "uuid";
2
+ import { v7 as uuid7 } from "@langchain/core/utils/uuid";
3
3
  import { getAssistantId } from "../graph/load.mjs";
4
4
  import { PROTOCOL_STREAM_RUN_KEY } from "./constants.mjs";
5
5
  import { RunProtocolSession } from "./session/index.mjs";
@@ -267,9 +267,26 @@ export class ProtocolService {
267
267
  // context, …) and metadata (trigger source, test flags, …) a fresh
268
268
  // `run.start` would. Read them leniently — same posture as
269
269
  // `normalizeRunStart`.
270
+ // `update` / `goto` are the optional state mutation and directed jump
271
+ // applied in the same superstep as the resume (`InputRespondOne` /
272
+ // `InputRespondMany`). The SDK's `respond({ update, goto })` forwards them
273
+ // on the `input.respond` command; they are folded into
274
+ // `Command(resume, update, goto)` by `createOrResumeRun`. Read leniently
275
+ // (update: object or [key, value][] tuples; goto: node name, Send object,
276
+ // or a list of either) — same posture as `config` / `metadata`.
277
+ const update = isRecord(rawParams.update) || Array.isArray(rawParams.update)
278
+ ? rawParams.update
279
+ : undefined;
280
+ const goto = typeof rawParams.goto === "string" ||
281
+ Array.isArray(rawParams.goto) ||
282
+ isRecord(rawParams.goto)
283
+ ? rawParams.goto
284
+ : undefined;
270
285
  await this.createOrResumeRun(record, {
271
286
  assistant_id: record.assistantId,
272
287
  input: resumeInput,
288
+ update,
289
+ goto,
273
290
  config: isRecord(rawParams.config) ? rawParams.config : undefined,
274
291
  metadata: isRecord(rawParams.metadata) ? rawParams.metadata : undefined,
275
292
  });
@@ -313,7 +330,16 @@ export class ProtocolService {
313
330
  assistant_id: assistantId,
314
331
  input: isResume ? null : params.input,
315
332
  command: isResume
316
- ? { resume: params.input }
333
+ ? {
334
+ resume: params.input,
335
+ // Apply an optional state update and/or directed jump in the
336
+ // same superstep as the resume (HITL "push card into state +
337
+ // resume" flows, or resume-and-redirect). Mapped straight onto
338
+ // LangGraph's `Command(resume, update, goto)`, so the resumed
339
+ // run produces a single checkpoint reflecting all of them.
340
+ ...(params.update != null ? { update: params.update } : {}),
341
+ ...(params.goto != null ? { goto: params.goto } : {}),
342
+ }
317
343
  : undefined,
318
344
  config: runConfig,
319
345
  metadata: params.metadata,
@@ -1,5 +1,5 @@
1
1
  import { inferChannel, isSupportedChannel } from "@langchain/langgraph/stream";
2
- import { v7 as uuid7 } from "uuid";
2
+ import { v7 as uuid7 } from "@langchain/core/utils/uuid";
3
3
  import { serialiseAsDict, serializeError } from "../../utils/serde.mjs";
4
4
  import { normalizeInputRequestedData, normalizeToolData, stripInterruptsFromValues, toLifecycleStatus, } from "./event-normalizers.mjs";
5
5
  import { isRecord } from "./internal-types.mjs";
@@ -357,6 +357,15 @@ export const normalizeProtocolStateMessage = (value) => {
357
357
  if (typeof value.name === "string") {
358
358
  message.name = value.name;
359
359
  }
360
+ // Preserve `response_metadata` when present. It is a first-class protocol
361
+ // message field, and HITL flows rely on it: an interrupt's card is carried
362
+ // on `AIMessage.response_metadata` (e.g. `{ cards: ... }`) and the frontend
363
+ // pushes that message into state via `respond(decision, { update })`. We
364
+ // only forward a non-empty record to keep the common (empty) case minimal.
365
+ if (isRecord(value.response_metadata) &&
366
+ Object.keys(value.response_metadata).length > 0) {
367
+ message.response_metadata = value.response_metadata;
368
+ }
360
369
  if ((type === "ai" || type === "human") &&
361
370
  typeof value.example === "boolean") {
362
371
  message.example = value.example;
@@ -1,5 +1,5 @@
1
1
  import { HTTPException } from "hono/http-exception";
2
- import { v7 as uuid7, v5 as uuid5 } from "uuid";
2
+ import { v7 as uuid7, v5 as uuid5 } from "@langchain/core/utils/uuid";
3
3
  import { handleAuthEvent, isAuthMatching } from "../auth/index.mjs";
4
4
  import { getLangGraphCommand } from "../command.mjs";
5
5
  import { getGraph, NAMESPACE_GRAPH } from "../graph/load.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-api",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^18.19.0 || >=20.16.0"
@@ -55,29 +55,28 @@
55
55
  "@hono/node-server": "^1.19.13",
56
56
  "@hono/node-ws": "^1.3.0",
57
57
  "@hono/zod-validator": "^0.7.6",
58
- "@langchain/protocol": "^0.0.16",
58
+ "@langchain/protocol": "^0.0.18",
59
59
  "@types/json-schema": "^7.0.15",
60
60
  "@typescript/vfs": "^1.6.0",
61
61
  "dedent": "^1.5.3",
62
62
  "dotenv": "^16.4.7",
63
63
  "exit-hook": "^4.0.0",
64
- "hono": "^4.12.21",
64
+ "hono": "^4.12.25",
65
65
  "langsmith": ">=0.5.19 <1.0.0",
66
66
  "open": "^10.1.0",
67
67
  "semver": "^7.7.1",
68
68
  "stacktrace-parser": "^0.1.10",
69
69
  "superjson": "^2.2.2",
70
70
  "tsx": "^4.19.3",
71
- "uuid": "^14.0.0",
72
71
  "winston": "^3.17.0",
73
72
  "winston-console-format": "^1.0.8",
74
73
  "zod": "^3.25.76 || ^4",
75
- "@langchain/langgraph-ui": "1.3.0"
74
+ "@langchain/langgraph-ui": "1.4.0"
76
75
  },
77
76
  "peerDependencies": {
78
77
  "@langchain/core": "^1.1.48",
79
78
  "@langchain/langgraph": "^1.3.6",
80
- "@langchain/langgraph-checkpoint": "~0.0.16 || ^0.1.0 || ~1.0.0",
79
+ "@langchain/langgraph-checkpoint": "~0.0.16 || ^0.1.0 || ^1.0.0",
81
80
  "@langchain/langgraph-sdk": "^1.9.3-rc.0",
82
81
  "typescript": "^5.5.4"
83
82
  },
@@ -87,23 +86,22 @@
87
86
  }
88
87
  },
89
88
  "devDependencies": {
90
- "@langchain/core": "^1.1.48",
89
+ "@langchain/core": "^1.2.1",
91
90
  "@types/babel__code-frame": "^7.0.6",
92
91
  "@types/node": "^18.15.11",
93
92
  "@types/react": "^19.2.16",
94
93
  "@types/react-dom": "^19.0.3",
95
94
  "@types/semver": "^7.7.0",
96
- "@types/uuid": "^10.0.0",
97
- "deepagents": "^1.9.0",
95
+ "deepagents": "^1.10.5",
98
96
  "jose": "^6.0.10",
99
- "langchain": "^1.4.4",
97
+ "langchain": "^1.5.1",
100
98
  "postgres": "^3.4.5",
101
99
  "typescript": "^4.9.5 || ^5.4.5",
102
100
  "vitest": "^4.1.0",
103
101
  "wait-port": "^1.1.0",
104
- "@langchain/langgraph": "1.3.7",
105
- "@langchain/langgraph-checkpoint": "1.0.4",
106
- "@langchain/langgraph-sdk": "1.9.19"
102
+ "@langchain/langgraph": "1.4.5",
103
+ "@langchain/langgraph-checkpoint": "1.1.2",
104
+ "@langchain/langgraph-sdk": "1.9.24"
107
105
  },
108
106
  "scripts": {
109
107
  "clean": "rm -rf dist/ .turbo/ ./tests/graphs/.langgraph_api/ ./tests/protocol-v2/graphs/.langgraph_api/",