langgraph-api 0.2.8__tar.gz → 0.2.10__tar.gz

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.

Potentially problematic release.


This version of langgraph-api might be problematic. Click here for more details.

Files changed (107) hide show
  1. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/PKG-INFO +1 -1
  2. langgraph_api-0.2.10/langgraph_api/__init__.py +1 -0
  3. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/build.mts +3 -6
  4. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/client.mts +50 -29
  5. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/package.json +2 -2
  6. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/graph.mts +5 -32
  7. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/api.test.mts +7 -5
  8. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/yarn.lock +9 -9
  9. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/worker.py +21 -0
  10. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/pyproject.toml +1 -1
  11. langgraph_api-0.2.8/langgraph_api/__init__.py +0 -1
  12. langgraph_api-0.2.8/langgraph_api/js/src/parser/parser.mts +0 -474
  13. langgraph_api-0.2.8/langgraph_api/js/src/parser/parser.worker.mjs +0 -12
  14. langgraph_api-0.2.8/langgraph_api/js/src/parser/schema/types.mts +0 -2016
  15. langgraph_api-0.2.8/langgraph_api/js/src/parser/schema/types.template.mts +0 -78
  16. langgraph_api-0.2.8/langgraph_api/js/tests/parser.test.mts +0 -885
  17. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/LICENSE +0 -0
  18. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/README.md +0 -0
  19. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/__init__.py +0 -0
  20. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/assistants.py +0 -0
  21. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/mcp.py +0 -0
  22. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/meta.py +0 -0
  23. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/openapi.py +0 -0
  24. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/runs.py +0 -0
  25. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/store.py +0 -0
  26. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/threads.py +0 -0
  27. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/api/ui.py +0 -0
  28. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/asyncio.py +0 -0
  29. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/__init__.py +0 -0
  30. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/custom.py +0 -0
  31. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/langsmith/__init__.py +0 -0
  32. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/langsmith/backend.py +0 -0
  33. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/langsmith/client.py +0 -0
  34. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/middleware.py +0 -0
  35. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/noop.py +0 -0
  36. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/auth/studio_user.py +0 -0
  37. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/cli.py +0 -0
  38. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/command.py +0 -0
  39. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/config.py +0 -0
  40. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/cron_scheduler.py +0 -0
  41. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/errors.py +0 -0
  42. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/graph.py +0 -0
  43. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/http.py +0 -0
  44. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/.gitignore +0 -0
  45. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/.prettierrc +0 -0
  46. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/__init__.py +0 -0
  47. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/base.py +0 -0
  48. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/client.http.mts +0 -0
  49. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/errors.py +0 -0
  50. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/global.d.ts +0 -0
  51. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/remote.py +0 -0
  52. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/schema.py +0 -0
  53. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/load.hooks.mjs +0 -0
  54. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/preload.mjs +0 -0
  55. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/utils/files.mts +0 -0
  56. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/utils/importMap.mts +0 -0
  57. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  58. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/src/utils/serde.mts +0 -0
  59. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/sse.py +0 -0
  60. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/auth.test.mts +0 -0
  61. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/compose-postgres.auth.yml +0 -0
  62. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/compose-postgres.yml +0 -0
  63. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/.gitignore +0 -0
  64. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/agent.css +0 -0
  65. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/agent.mts +0 -0
  66. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/agent.ui.tsx +0 -0
  67. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/agent_simple.mts +0 -0
  68. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/auth.mts +0 -0
  69. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/command.mts +0 -0
  70. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/delay.mts +0 -0
  71. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/dynamic.mts +0 -0
  72. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/error.mts +0 -0
  73. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/http.mts +0 -0
  74. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/langgraph.json +0 -0
  75. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/nested.mts +0 -0
  76. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/package.json +0 -0
  77. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/weather.mts +0 -0
  78. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
  79. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tests/utils.mts +0 -0
  80. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/tsconfig.json +0 -0
  81. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/js/ui.py +0 -0
  82. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/logging.py +0 -0
  83. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/metadata.py +0 -0
  84. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/middleware/__init__.py +0 -0
  85. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/middleware/http_logger.py +0 -0
  86. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/middleware/private_network.py +0 -0
  87. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/models/__init__.py +0 -0
  88. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/models/run.py +0 -0
  89. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/patch.py +0 -0
  90. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/queue_entrypoint.py +0 -0
  91. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/route.py +0 -0
  92. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/schema.py +0 -0
  93. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/serde.py +0 -0
  94. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/server.py +0 -0
  95. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/sse.py +0 -0
  96. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/state.py +0 -0
  97. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/stream.py +0 -0
  98. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/thread_ttl.py +0 -0
  99. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/tunneling/cloudflare.py +0 -0
  100. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/utils.py +0 -0
  101. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/validation.py +0 -0
  102. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_api/webhook.py +0 -0
  103. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_license/__init__.py +0 -0
  104. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_license/validation.py +0 -0
  105. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/langgraph_runtime/__init__.py +0 -0
  106. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/logging.json +0 -0
  107. {langgraph_api-0.2.8 → langgraph_api-0.2.10}/openapi.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langgraph-api
3
- Version: 0.2.8
3
+ Version: 0.2.10
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -0,0 +1 @@
1
+ __version__ = "0.2.10"
@@ -4,13 +4,10 @@ import "./src/preload.mjs";
4
4
  import { z } from "zod";
5
5
  import * as fs from "node:fs/promises";
6
6
  import * as path from "node:path";
7
- import {
8
- type GraphSchema,
9
- resolveGraph,
10
- runGraphSchemaWorker,
11
- } from "./src/graph.mts";
7
+ import { type GraphSchema, resolveGraph } from "./src/graph.mts";
12
8
  import { build } from "@langchain/langgraph-ui";
13
9
  import { checkLangGraphSemver } from "@langchain/langgraph-api/semver";
10
+ import { getStaticGraphSchema } from "@langchain/langgraph-api/schema";
14
11
  import { filterValidExportPath } from "./src/utils/files.mts";
15
12
 
16
13
  const __dirname = new URL(".", import.meta.url).pathname;
@@ -54,7 +51,7 @@ async function main() {
54
51
 
55
52
  try {
56
53
  console.info(`[${graphId}]: Extracting schema`);
57
- GRAPH_SCHEMAS[graphId] = await runGraphSchemaWorker(spec, {
54
+ GRAPH_SCHEMAS[graphId] = await getStaticGraphSchema(spec, {
58
55
  timeoutMs: 120_000,
59
56
  });
60
57
  } catch (error) {
@@ -38,7 +38,6 @@ import { BaseMessageChunk, isBaseMessage } from "@langchain/core/messages";
38
38
  import type { PyItem, PyResult } from "./src/utils/pythonSchemas.mts";
39
39
  import type { RunnableConfig } from "@langchain/core/runnables";
40
40
  import {
41
- runGraphSchemaWorker,
42
41
  GraphSchema,
43
42
  resolveGraph,
44
43
  GraphSpec,
@@ -52,6 +51,10 @@ import {
52
51
  authorize,
53
52
  registerAuth,
54
53
  } from "@langchain/langgraph-api/auth";
54
+ import {
55
+ getRuntimeGraphSchema,
56
+ getStaticGraphSchema,
57
+ } from "@langchain/langgraph-api/schema";
55
58
  import { filterValidExportPath } from "./src/utils/files.mts";
56
59
 
57
60
  const logger = createLogger({
@@ -177,7 +180,7 @@ async function getOrExtractSchema(graphId: string) {
177
180
  // ignore
178
181
  }
179
182
 
180
- GRAPH_SCHEMA[graphId] = await runGraphSchemaWorker(GRAPH_SPEC[graphId], {
183
+ GRAPH_SCHEMA[graphId] = await getStaticGraphSchema(GRAPH_SPEC[graphId], {
181
184
  timeoutMs,
182
185
  });
183
186
  timer.done({ message: `Extracting schema for ${graphId} finished` });
@@ -482,6 +485,15 @@ function pyItemToJs(item?: PyItem): Item | undefined {
482
485
  };
483
486
  }
484
487
 
488
+ function isPyItem(result: unknown): result is PyItem {
489
+ return (
490
+ result != null &&
491
+ typeof result === "object" &&
492
+ "value" in result &&
493
+ "key" in result
494
+ );
495
+ }
496
+
485
497
  export class RemoteStore extends BaseStore {
486
498
  async batch<Op extends Operation[]>(
487
499
  operations: Op,
@@ -492,16 +504,10 @@ export class RemoteStore extends BaseStore {
492
504
 
493
505
  return results.map((result) => {
494
506
  if (Array.isArray(result)) {
495
- return result.map((item) => pyItemToJs(item));
496
- } else if (
497
- result &&
498
- typeof result === "object" &&
499
- "value" in result &&
500
- "key" in result
501
- ) {
502
- return pyItemToJs(result);
507
+ return result.map((item) => (isPyItem(item) ? pyItemToJs(item) : item));
503
508
  }
504
- return result;
509
+
510
+ return isPyItem(result) ? pyItemToJs(result) : result;
505
511
  }) as OperationResults<Op>;
506
512
  }
507
513
 
@@ -788,25 +794,33 @@ async function getSubgraphsRequest(
788
794
  rawPayload: z.infer<typeof GetSubgraphsPayload>,
789
795
  ) {
790
796
  const { graph_id: graphId, ...payload } = rawPayload;
791
- const graphConfig = getRunnableConfig(payload.graph_config);
792
- const graph = await getGraph(graphId, graphConfig, payload.graph_name);
793
- const result: Array<[name: string, Record<string, any>]> = [];
794
797
 
795
- const graphSchema = await getOrExtractSchema(graphId);
796
- const rootGraphId = Object.keys(graphSchema).find((i) => !i.includes("|"));
798
+ const config = getRunnableConfig(payload.graph_config);
799
+ const graph = await getGraph(graphId, config, payload.graph_name);
797
800
 
798
- if (!rootGraphId) throw new Error("Failed to find root graph");
801
+ const result: Array<[name: string, schema: Record<string, any>]> = [];
802
+ let graphSchemaPromise: ReturnType<typeof getOrExtractSchema> | undefined;
799
803
 
800
- for await (const [name] of graph.getSubgraphsAsync(
804
+ for await (const [ns, subgraph] of graph.getSubgraphsAsync(
801
805
  payload.namespace ?? undefined,
802
806
  payload.recurse ?? undefined,
803
807
  )) {
804
- const schema =
805
- graphSchema[`${rootGraphId}|${name}`] || graphSchema[rootGraphId];
806
- result.push([name, schema]);
808
+ const schema = await (async () => {
809
+ const runtimeSchema = await getRuntimeGraphSchema(subgraph);
810
+ if (runtimeSchema) return runtimeSchema;
811
+
812
+ graphSchemaPromise ??= getOrExtractSchema(graphId);
813
+ const graphSchema = await graphSchemaPromise;
814
+ const rootGraphId = Object.keys(graphSchema).find(
815
+ (i) => !i.includes("|"),
816
+ );
817
+ if (!rootGraphId) throw new Error("Failed to find root graph");
818
+ return graphSchema[`${rootGraphId}|${ns}`] || graphSchema[rootGraphId];
819
+ })();
820
+
821
+ result.push([ns, schema]);
807
822
  }
808
823
 
809
- // TODO: make this a stream
810
824
  return Object.fromEntries(result);
811
825
  }
812
826
 
@@ -864,14 +878,21 @@ const GetSchemaPayload = z.object({
864
878
 
865
879
  async function getSchemaRequest(payload: z.infer<typeof GetSchemaPayload>) {
866
880
  const { graph_id: graphId } = payload;
867
- // TODO: add support for schema inference with dynamic graphs (now that Zod is supported)
868
881
 
869
- const schemas = await getOrExtractSchema(graphId);
870
- const rootGraphId = Object.keys(schemas).find((i) => !i.includes("|"));
871
- if (!rootGraphId) {
872
- throw new Error("Failed to find root graph");
873
- }
874
- return schemas[rootGraphId];
882
+ const config = getRunnableConfig(payload.graph_config);
883
+ const graph = await getGraph(graphId, config, payload.graph_name);
884
+
885
+ const schema = await (async () => {
886
+ const runtimeSchema = await getRuntimeGraphSchema(graph);
887
+ if (runtimeSchema) return runtimeSchema;
888
+
889
+ const graphSchema = await getOrExtractSchema(graphId);
890
+ const rootGraphId = Object.keys(graphSchema).find((i) => !i.includes("|"));
891
+ if (!rootGraphId) throw new Error("Failed to find root graph");
892
+ return graphSchema[rootGraphId];
893
+ })();
894
+
895
+ return schema;
875
896
  }
876
897
 
877
898
  const GetStateHistoryPayload = z.object({
@@ -24,8 +24,8 @@
24
24
  "undici": "^6.21.1",
25
25
  "uuid": "^10.0.0",
26
26
  "winston": "^3.17.0",
27
- "@langchain/langgraph-api": "~0.0.29",
28
- "@langchain/langgraph-ui": "~0.0.29",
27
+ "@langchain/langgraph-api": "~0.0.32",
28
+ "@langchain/langgraph-ui": "~0.0.32",
29
29
  "zod": "^3.23.8"
30
30
  },
31
31
  "resolutions": {
@@ -1,8 +1,7 @@
1
- import { Worker } from "node:worker_threads";
2
- import { register } from "node:module";
3
1
  import * as fs from "node:fs/promises";
4
- import type { CompiledGraph, Graph } from "@langchain/langgraph";
5
2
  import * as path from "node:path";
3
+
4
+ import type { CompiledGraph, Graph } from "@langchain/langgraph";
6
5
  import type { JSONSchema7 } from "json-schema";
7
6
 
8
7
  export interface GraphSchema {
@@ -40,14 +39,14 @@ export async function resolveGraph(
40
39
  options?: { onlyFilePresence?: boolean },
41
40
  ) {
42
41
  const [userFile, exportSymbol] = spec.split(":", 2);
42
+ const sourceFile = path.resolve(process.cwd(), userFile);
43
43
 
44
44
  // validate file exists
45
- await fs.stat(userFile);
45
+ await fs.stat(sourceFile);
46
46
  if (options?.onlyFilePresence) {
47
- return { sourceFile: userFile, exportSymbol, resolved: undefined };
47
+ return { sourceFile, exportSymbol, resolved: undefined };
48
48
  }
49
49
 
50
- const sourceFile = path.resolve(process.cwd(), userFile);
51
50
  type GraphLike = CompiledGraph<string> | Graph<string>;
52
51
 
53
52
  type GraphUnknown =
@@ -89,29 +88,3 @@ export async function resolveGraph(
89
88
 
90
89
  return { sourceFile, exportSymbol, resolved };
91
90
  }
92
-
93
- export async function runGraphSchemaWorker(
94
- spec: GraphSpec,
95
- options?: { timeoutMs?: number },
96
- ) {
97
- return await new Promise<Record<string, GraphSchema>>((resolve, reject) => {
98
- const worker = new Worker(
99
- new URL("./parser/parser.worker.mjs", import.meta.url).pathname,
100
- );
101
-
102
- // Set a timeout to reject if the worker takes too long
103
- const timeoutId = setTimeout(() => {
104
- worker.terminate();
105
- reject(new Error("Schema extract worker timed out"));
106
- }, options?.timeoutMs ?? 30_000);
107
-
108
- worker.on("message", (result) => {
109
- worker.terminate();
110
- clearTimeout(timeoutId);
111
- resolve(result);
112
- });
113
-
114
- worker.on("error", reject);
115
- worker.postMessage(spec);
116
- });
117
- }
@@ -303,7 +303,7 @@ describe("threads crud", () => {
303
303
  });
304
304
 
305
305
  describe("threads copy", () => {
306
- it.concurrent("copy", async () => {
306
+ it.concurrent("copy", { retry: 3 }, async () => {
307
307
  const assistantId = "agent";
308
308
  const thread = await client.threads.create();
309
309
  const input = { messages: [{ type: "human", content: "foo" }] };
@@ -377,7 +377,7 @@ describe("threads copy", () => {
377
377
  }
378
378
  });
379
379
 
380
- it.concurrent("copy runs", async () => {
380
+ it.concurrent("copy runs", { retry: 3 }, async () => {
381
381
  const assistantId = "agent";
382
382
  const thread = await client.threads.create();
383
383
 
@@ -423,7 +423,7 @@ describe("threads copy", () => {
423
423
  expect(currentOriginalThreadState).toEqual(originalThreadState);
424
424
  });
425
425
 
426
- it.concurrent("get thread history", async () => {
426
+ it.concurrent("get thread history", { retry: 3 }, async () => {
427
427
  const assistant = await client.assistants.create({ graphId: "agent" });
428
428
  const thread = await client.threads.create();
429
429
  const input = { messages: [{ type: "human", content: "foo" }] };
@@ -467,7 +467,7 @@ describe("threads copy", () => {
467
467
  expect(filteredHistory.at(-1)?.values.messages.length).toBe(4);
468
468
  });
469
469
 
470
- it.concurrent("copy update", async () => {
470
+ it.concurrent("copy update", { retry: 3 }, async () => {
471
471
  const assistantId = "agent";
472
472
  const thread = await client.threads.create();
473
473
  const input = {
@@ -561,7 +561,9 @@ describe("runs", () => {
561
561
  }
562
562
 
563
563
  if (chunk.event === "values") {
564
- const messageIds = chunk.data.messages.map((message) => message.id);
564
+ const messageIds = chunk.data.messages.map(
565
+ (message: any) => message.id,
566
+ );
565
567
  expect(messageIds.slice(0, -1)).toEqual(previousMessageIds);
566
568
  previousMessageIds = messageIds;
567
569
  }
@@ -203,15 +203,15 @@
203
203
  zod "^3.22.4"
204
204
  zod-to-json-schema "^3.22.3"
205
205
 
206
- "@langchain/langgraph-api@~0.0.29":
207
- version "0.0.29"
208
- resolved "https://registry.yarnpkg.com/@langchain/langgraph-api/-/langgraph-api-0.0.29.tgz#787e01675250720d293e3363ff579b601a9c94ab"
209
- integrity sha512-WJVOWFJBEo7sCUtzchFRhFWT4+Zn3evKakmLGDJihMZ2nrNeoaordEUmbsXMLiQVOe3bP7Fpweq3mSPIwxQyyQ==
206
+ "@langchain/langgraph-api@~0.0.32":
207
+ version "0.0.32"
208
+ resolved "https://registry.yarnpkg.com/@langchain/langgraph-api/-/langgraph-api-0.0.32.tgz#65f41373318055b330fa64e7d4ccd7c994f7dc8d"
209
+ integrity sha512-wYflud8iCGjwh3/GtzrTeWlwcc91kXBa49Goc2iaHcJRjMnTbl+loE3eklegDPnQGx1VKUCiB9qW/HutxuqXGA==
210
210
  dependencies:
211
211
  "@babel/code-frame" "^7.26.2"
212
212
  "@hono/node-server" "^1.12.0"
213
213
  "@hono/zod-validator" "^0.2.2"
214
- "@langchain/langgraph-ui" "0.0.29"
214
+ "@langchain/langgraph-ui" "0.0.32"
215
215
  "@types/json-schema" "^7.0.15"
216
216
  "@typescript/vfs" "^1.6.0"
217
217
  dedent "^1.5.3"
@@ -256,10 +256,10 @@
256
256
  p-retry "4"
257
257
  uuid "^9.0.0"
258
258
 
259
- "@langchain/langgraph-ui@0.0.29", "@langchain/langgraph-ui@~0.0.29":
260
- version "0.0.29"
261
- resolved "https://registry.yarnpkg.com/@langchain/langgraph-ui/-/langgraph-ui-0.0.29.tgz#98659cc56f0e8e074a9a0b2e33e967dc5f30e79f"
262
- integrity sha512-FADBt6B1/egKSpZFmTa6vxonBK9lF6EmeKoBEWh/XTkO6lD5zsejWoRgT+LR2x22CHJvfvCQtXxgP5y8AtxsQw==
259
+ "@langchain/langgraph-ui@0.0.32", "@langchain/langgraph-ui@~0.0.32":
260
+ version "0.0.32"
261
+ resolved "https://registry.yarnpkg.com/@langchain/langgraph-ui/-/langgraph-ui-0.0.32.tgz#7e0cab750ba1e65f47d7b1d2adf955a36e50664e"
262
+ integrity sha512-65QZpouvw4P+hCpklYebNiwR88M84h7awjNB6FaKWHvCZa6NcSzlruFa/PnvU1o/kRK5NNpXNPyDUQLhT3tmTA==
263
263
  dependencies:
264
264
  "@commander-js/extra-typings" "^13.0.0"
265
265
  commander "^13.0.0"
@@ -275,6 +275,27 @@ async def worker(
275
275
  # let it bubble up and rollback db transaction, thus marking the run
276
276
  # as available to be picked up by another worker
277
277
 
278
+ # If a stateful run succeeded but no checkoint was returned, it's likely because
279
+ # there was a retriable exception that resumed right at the end
280
+ if checkpoint is None and (not temporary) and webhook and status == "success":
281
+ await logger.ainfo(
282
+ "Fetching missing checkpoint for webhook",
283
+ run_id=str(run_id),
284
+ run_attempt=attempt,
285
+ )
286
+ try:
287
+ state_snapshot = await Threads.State.get(
288
+ conn, run["kwargs"]["config"], subgraphs=True
289
+ )
290
+ checkpoint = {"values": state_snapshot.values}
291
+ except Exception:
292
+ await logger.aerror(
293
+ "Failed to fetch missing checkpoint for webhook. Continuing...",
294
+ exc_info=True,
295
+ run_id=str(run_id),
296
+ run_attempt=attempt,
297
+ )
298
+
278
299
  return WorkerResult(
279
300
  checkpoint=checkpoint,
280
301
  status=status,
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langgraph-api"
3
- version = "0.2.8"
3
+ version = "0.2.10"
4
4
  description = ""
5
5
  authors = [
6
6
  "Nuno Campos <nuno@langchain.dev>",
@@ -1 +0,0 @@
1
- __version__ = "0.2.8"