@langchain/langgraph-api 0.0.38 → 0.0.40

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,12 +1,12 @@
1
- import { Hono } from "hono";
2
1
  import { zValidator } from "@hono/zod-validator";
2
+ import { Hono } from "hono";
3
3
  import { v4 as uuid } from "uuid";
4
4
  import { z } from "zod";
5
- import { getAssistantId, getGraph, getCachedStaticGraphSchema, } from "../graph/load.mjs";
5
+ import { getAssistantId, getCachedStaticGraphSchema, getGraph, } from "../graph/load.mjs";
6
6
  import { getRuntimeGraphSchema } from "../graph/parser/index.mjs";
7
- import { Assistants } from "../storage/ops.mjs";
8
- import * as schemas from "../schemas.mjs";
9
7
  import { HTTPException } from "hono/http-exception";
8
+ import * as schemas from "../schemas.mjs";
9
+ import { Assistants } from "../storage/ops.mjs";
10
10
  const api = new Hono();
11
11
  const RunnableConfigSchema = z.object({
12
12
  tags: z.array(z.string()).optional(),
@@ -46,14 +46,19 @@ api.post("/assistants/search", zValidator("json", schemas.AssistantSearchRequest
46
46
  // Search Assistants
47
47
  const payload = c.req.valid("json");
48
48
  const result = [];
49
+ let total = 0;
49
50
  for await (const item of Assistants.search({
50
51
  graph_id: payload.graph_id,
51
52
  metadata: payload.metadata,
52
53
  limit: payload.limit ?? 10,
53
54
  offset: payload.offset ?? 0,
54
55
  }, c.var.auth)) {
55
- result.push(item);
56
+ result.push(item.assistant);
57
+ if (total === 0) {
58
+ total = item.total;
59
+ }
56
60
  }
61
+ c.res.headers.set("X-Pagination-Total", total.toString());
57
62
  return c.json(result);
58
63
  });
59
64
  api.get("/assistants/:assistant_id", async (c) => {
package/dist/api/meta.mjs CHANGED
@@ -1,5 +1,45 @@
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();
3
- api.get("/info", (c) => c.json({ flags: { assistants: true, crons: false } }));
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
+ }
15
+ // read env variable
16
+ const env = process.env;
17
+ api.get("/info", (c) => {
18
+ const langsmithApiKey = env["LANGSMITH_API_KEY"] || env["LANGCHAIN_API_KEY"];
19
+ const langsmithTracing = (() => {
20
+ if (langsmithApiKey) {
21
+ // Check if any tracing variable is explicitly set to "false"
22
+ const tracingVars = [
23
+ env["LANGCHAIN_TRACING_V2"],
24
+ env["LANGCHAIN_TRACING"],
25
+ env["LANGSMITH_TRACING_V2"],
26
+ env["LANGSMITH_TRACING"],
27
+ ];
28
+ // Return true unless explicitly disabled
29
+ return !tracingVars.some((val) => val === "false" || val === "False");
30
+ }
31
+ return undefined;
32
+ })();
33
+ return c.json({
34
+ version,
35
+ context: "js",
36
+ flags: {
37
+ assistants: true,
38
+ crons: false,
39
+ langsmith: !!langsmithTracing,
40
+ langsmith_tracing_replicas: true,
41
+ },
42
+ });
43
+ });
4
44
  api.get("/ok", (c) => c.json({ ok: true }));
5
45
  export default api;
package/dist/api/runs.mjs CHANGED
@@ -1,15 +1,15 @@
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 { zValidator } from "@hono/zod-validator";
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 { logError, logger } from "../logging.mjs";
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;
@@ -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();
@@ -1,6 +1,6 @@
1
1
  import { HTTPException } from "hono/http-exception";
2
2
  import * as url from "node:url";
3
- import * as path from "path";
3
+ import * as path from "node:path";
4
4
  let CUSTOM_AUTH;
5
5
  let DISABLE_STUDIO_AUTH = false;
6
6
  export const isAuthRegistered = () => CUSTOM_AUTH != null;
@@ -3,7 +3,7 @@ export const cors = (cors) => {
3
3
  if (cors == null) {
4
4
  return honoCors({
5
5
  origin: "*",
6
- exposeHeaders: ["content-location"],
6
+ exposeHeaders: ["content-location", "x-pagination-total"],
7
7
  });
8
8
  }
9
9
  const originRegex = cors.allow_origin_regex
@@ -17,10 +17,16 @@ export const cors = (cors) => {
17
17
  return undefined;
18
18
  }
19
19
  : (cors.allow_origins ?? []);
20
- if (!!cors.expose_headers?.length &&
21
- cors.expose_headers.some((i) => i.toLocaleLowerCase() === "content-location")) {
22
- console.warn("Adding missing `Content-Location` header in `cors.expose_headers`.");
23
- cors.expose_headers.push("content-location");
20
+ if (cors.expose_headers?.length) {
21
+ const headersSet = new Set(cors.expose_headers.map((h) => h.toLowerCase()));
22
+ if (!headersSet.has("content-location")) {
23
+ console.warn("Adding missing `Content-Location` header in `cors.expose_headers`.");
24
+ cors.expose_headers.push("content-location");
25
+ }
26
+ if (!headersSet.has("x-pagination-total")) {
27
+ console.warn("Adding missing `X-Pagination-Total` header in `cors.expose_headers`.");
28
+ cors.expose_headers.push("x-pagination-total");
29
+ }
24
30
  }
25
31
  // TODO: handle `cors.allow_credentials`
26
32
  return honoCors({
package/dist/logging.mjs CHANGED
@@ -2,7 +2,7 @@ import { createLogger, format, transports } from "winston";
2
2
  import { logger as honoLogger } from "hono/logger";
3
3
  import { consoleFormat } from "winston-console-format";
4
4
  import { parse as stacktraceParser } from "stacktrace-parser";
5
- import { readFileSync } from "fs";
5
+ import { readFileSync } from "node:fs";
6
6
  import { codeFrameColumns } from "@babel/code-frame";
7
7
  import path from "node:path";
8
8
  const LOG_JSON = process.env.LOG_JSON === "true";
@@ -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">>>;
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
@@ -119,7 +119,10 @@ export declare class Assistants {
119
119
  metadata?: Metadata;
120
120
  limit: number;
121
121
  offset: number;
122
- }, auth: AuthContext | undefined): AsyncGenerator<any, void, any>;
122
+ }, auth: AuthContext | undefined): AsyncGenerator<{
123
+ assistant: Assistant;
124
+ total: number;
125
+ }>;
123
126
  static get(assistant_id: string, auth: AuthContext | undefined): Promise<Assistant>;
124
127
  static put(assistant_id: string, options: {
125
128
  config: RunnableConfig;
@@ -177,8 +177,16 @@ export class Assistants {
177
177
  const bCreatedAt = b["created_at"]?.getTime() ?? 0;
178
178
  return bCreatedAt - aCreatedAt;
179
179
  });
180
+ // Calculate total count before pagination
181
+ const total = filtered.length;
180
182
  for (const assistant of filtered.slice(options.offset, options.offset + options.limit)) {
181
- yield { ...assistant, name: assistant.name ?? assistant.graph_id };
183
+ yield {
184
+ assistant: {
185
+ ...assistant,
186
+ name: assistant.name ?? assistant.graph_id,
187
+ },
188
+ total,
189
+ };
182
190
  }
183
191
  });
184
192
  }
package/dist/stream.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import type { Run, RunnableConfig, Checkpoint } from "./storage/ops.mjs";
2
1
  import { type CheckpointMetadata, type Interrupt, type StateSnapshot } from "@langchain/langgraph";
2
+ import type { Checkpoint, Run, RunnableConfig } from "./storage/ops.mjs";
3
3
  interface DebugTask {
4
4
  id: string;
5
5
  name: string;
package/dist/stream.mjs CHANGED
@@ -1,9 +1,10 @@
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";
5
+ import { getGraph } from "./graph/load.mjs";
6
6
  import { checkLangGraphSemver } from "./semver/index.mjs";
7
+ import { runnableConfigToCheckpoint, taskRunnableConfigToCheckpoint, } from "./utils/runnableConfig.mjs";
7
8
  const isRunnableConfig = (config) => {
8
9
  if (typeof config !== "object" || config == null)
9
10
  return false;
@@ -88,6 +89,19 @@ export async function* streamState(run, attempt = 1, options) {
88
89
  langgraph_host: "self-hosted",
89
90
  langgraph_api_url: process.env.LANGGRAPH_API_URL ?? undefined,
90
91
  };
92
+ const tracer = run.kwargs?.config?.configurable?.langsmith_project
93
+ ? new LangChainTracer({
94
+ replicas: [
95
+ [
96
+ run.kwargs?.config?.configurable?.langsmith_project,
97
+ {
98
+ reference_example_id: run.kwargs?.config?.configurable?.langsmith_example_id,
99
+ },
100
+ ],
101
+ [getDefaultProjectName(), undefined],
102
+ ],
103
+ })
104
+ : undefined;
91
105
  const events = graph.streamEvents(kwargs.command != null
92
106
  ? getLangGraphCommand(kwargs.command)
93
107
  : (kwargs.input ?? null), {
@@ -102,6 +116,7 @@ export async function* streamState(run, attempt = 1, options) {
102
116
  runId: run.run_id,
103
117
  streamMode: [...libStreamMode],
104
118
  signal: options?.signal,
119
+ ...(tracer && { callbacks: [tracer] }),
105
120
  });
106
121
  const messages = {};
107
122
  const completedIds = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-api",
3
- "version": "0.0.38",
3
+ "version": "0.0.40",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^18.19.0 || >=20.16.0"
@@ -33,17 +33,30 @@
33
33
  "type": "git",
34
34
  "url": "git@github.com:langchain-ai/langgraphjs-api.git"
35
35
  },
36
+ "scripts": {
37
+ "clean": "npx -y bun scripts/clean.mjs",
38
+ "build": "npx -y bun scripts/build.mjs",
39
+ "dev": "tsx ./tests/utils.server.mts --dev",
40
+ "prepack": "yarn run build",
41
+ "typecheck": "tsc --noEmit",
42
+ "test": "vitest",
43
+ "test:parser": "vitest run ./tests/parser.test.mts --testTimeout 15000",
44
+ "test:api": "npx -y bun scripts/test.mjs",
45
+ "format": "prettier --write .",
46
+ "format:check": "prettier --check ."
47
+ },
36
48
  "dependencies": {
37
49
  "@babel/code-frame": "^7.26.2",
38
50
  "@hono/node-server": "^1.12.0",
39
51
  "@hono/zod-validator": "^0.2.2",
52
+ "@langchain/langgraph-ui": "0.0.40",
40
53
  "@types/json-schema": "^7.0.15",
41
54
  "@typescript/vfs": "^1.6.0",
42
55
  "dedent": "^1.5.3",
43
56
  "dotenv": "^16.4.7",
44
57
  "exit-hook": "^4.0.0",
45
58
  "hono": "^4.5.4",
46
- "langsmith": "^0.2.15",
59
+ "langsmith": "^0.3.33",
47
60
  "open": "^10.1.0",
48
61
  "semver": "^7.7.1",
49
62
  "stacktrace-parser": "^0.1.10",
@@ -52,11 +65,10 @@
52
65
  "uuid": "^10.0.0",
53
66
  "winston": "^3.17.0",
54
67
  "winston-console-format": "^1.0.8",
55
- "zod": "^3.23.8",
56
- "@langchain/langgraph-ui": "0.0.38"
68
+ "zod": "^3.23.8"
57
69
  },
58
70
  "peerDependencies": {
59
- "@langchain/core": "^0.3.42",
71
+ "@langchain/core": "^0.3.59",
60
72
  "@langchain/langgraph": "^0.2.57 || ^0.3.0",
61
73
  "@langchain/langgraph-checkpoint": "~0.0.16",
62
74
  "@langchain/langgraph-sdk": "~0.0.70",
@@ -68,7 +80,7 @@
68
80
  }
69
81
  },
70
82
  "devDependencies": {
71
- "@langchain/core": "^0.3.42",
83
+ "@langchain/core": "^0.3.59",
72
84
  "@langchain/langgraph": "^0.2.57",
73
85
  "@langchain/langgraph-checkpoint": "~0.0.16",
74
86
  "@langchain/langgraph-sdk": "^0.0.77",
@@ -83,16 +95,5 @@
83
95
  "prettier": "^3.3.3",
84
96
  "typescript": "^5.5.4",
85
97
  "vitest": "^3.0.5"
86
- },
87
- "scripts": {
88
- "clean": "npx -y bun scripts/clean.mjs",
89
- "build": "npx -y bun scripts/build.mjs",
90
- "dev": "tsx ./tests/utils.server.mts --dev",
91
- "typecheck": "tsc --noEmit",
92
- "test": "vitest",
93
- "test:parser": "vitest run ./tests/parser.test.mts --testTimeout 15000",
94
- "test:api": "npx -y bun scripts/test.mjs",
95
- "format": "prettier --write .",
96
- "format:check": "prettier --check ."
97
98
  }
98
99
  }