diff --git a/libs/langgraph-api/package.json b/libs/langgraph-api/package.json index 2aa5af3..883bc92 100644 --- a/libs/langgraph-api/package.json +++ b/libs/langgraph-api/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-api", - "version": "0.0.39", + "version": "0.0.40", "type": "module", "engines": { "node": "^18.19.0 || >=20.16.0" @@ -56,7 +56,7 @@ "dotenv": "^16.4.7", "exit-hook": "^4.0.0", "hono": "^4.5.4", - "langsmith": "^0.2.15", + "langsmith": "^0.3.33", "open": "^10.1.0", "semver": "^7.7.1", "stacktrace-parser": "^0.1.10", @@ -68,7 +68,7 @@ "zod": "^3.23.8" }, "peerDependencies": { - "@langchain/core": "^0.3.42", + "@langchain/core": "^0.3.59", "@langchain/langgraph": "^0.2.57 || ^0.3.0", "@langchain/langgraph-checkpoint": "~0.0.16", "@langchain/langgraph-sdk": "~0.0.70", @@ -80,7 +80,7 @@ } }, "devDependencies": { - "@langchain/core": "^0.3.42", + "@langchain/core": "^0.3.59", "@langchain/langgraph": "^0.2.57", "@langchain/langgraph-checkpoint": "~0.0.16", "@langchain/langgraph-sdk": "^0.0.77", diff --git a/libs/langgraph-api/src/api/meta.mts b/libs/langgraph-api/src/api/meta.mts index 298e3c2..5e43144 100644 --- a/libs/langgraph-api/src/api/meta.mts +++ b/libs/langgraph-api/src/api/meta.mts @@ -1,7 +1,22 @@ import { Hono } from "hono"; +import * as fs from "node:fs/promises"; +import * as url from "node:url"; const api = new Hono(); +// Get the version using the same pattern as semver/index.mts +const packageJsonPath = url.fileURLToPath( + new URL("../../package.json", import.meta.url), +); + +let version: string; +try { + const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8")); + version = packageJson.version; +} catch { + console.warn("Could not determine version of langgraph-api"); +} + // read env variable const env = process.env; @@ -24,7 +39,14 @@ api.get("/info", (c) => { return undefined; })(); return c.json({ - flags: { assistants: true, crons: false, langsmith: !!langsmithTracing }, + version, + context: "js", + flags: { + assistants: true, + crons: false, + langsmith: !!langsmithTracing, + langsmith_tracing_replicas: true, + }, }); }); diff --git a/libs/langgraph-api/src/api/runs.mts b/libs/langgraph-api/src/api/runs.mts index 3bcc83f..fbe17e0 100644 --- a/libs/langgraph-api/src/api/runs.mts +++ b/libs/langgraph-api/src/api/runs.mts @@ -1,20 +1,20 @@ +import { zValidator } from "@hono/zod-validator"; import { Hono } from "hono"; import { HTTPException } from "hono/http-exception"; import { streamSSE } from "hono/streaming"; +import { v4 as uuid4 } from "uuid"; +import { z } from "zod"; +import type { AuthContext } from "../auth/index.mjs"; import { getAssistantId } from "../graph/load.mjs"; -import { zValidator } from "@hono/zod-validator"; +import { logError, logger } from "../logging.mjs"; import * as schemas from "../schemas.mjs"; -import { z } from "zod"; import { type Run, type RunKwargs, Runs, Threads } from "../storage/ops.mjs"; -import { serialiseAsDict } from "../utils/serde.mjs"; import { getDisconnectAbortSignal, jsonExtra, waitKeepAlive, } from "../utils/hono.mjs"; -import { logError, logger } from "../logging.mjs"; -import { v4 as uuid4 } from "uuid"; -import type { AuthContext } from "../auth/index.mjs"; +import { serialiseAsDict } from "../utils/serde.mjs"; const api = new Hono(); @@ -52,6 +52,14 @@ const createValidRun = async ( Object.assign(config.configurable, run.checkpoint); } + if (run.langsmith_tracer) { + config.configurable ??= {}; + Object.assign(config.configurable, { + langsmith_project: run.langsmith_tracer.project_name, + langsmith_example_id: run.langsmith_tracer.example_id, + }); + } + if (headers) { for (const [rawKey, value] of headers.entries()) { const key = rawKey.toLowerCase(); diff --git a/libs/langgraph-api/src/schemas.mts b/libs/langgraph-api/src/schemas.mts index c964d43..1880b62 100644 --- a/libs/langgraph-api/src/schemas.mts +++ b/libs/langgraph-api/src/schemas.mts @@ -175,6 +175,11 @@ export const CommandSchema = z.object({ resume: z.unknown().optional(), }); +export const LangsmithTracer = z.object({ + project_name: z.string().optional(), + example_id: z.string().optional(), +}); + export const RunCreate = z .object({ assistant_id: z.union([z.string().uuid(), z.string()]), @@ -228,6 +233,7 @@ export const RunCreate = z if_not_exists: z.enum(["reject", "create"]).optional(), on_completion: z.enum(["delete", "keep"]).optional(), feedback_keys: z.array(z.string()).optional(), + langsmith_tracer: LangsmithTracer.optional(), }) .describe("Payload for creating a stateful run."); diff --git a/libs/langgraph-api/src/stream.mts b/libs/langgraph-api/src/stream.mts index 34dc97b..a7cf1a9 100644 --- a/libs/langgraph-api/src/stream.mts +++ b/libs/langgraph-api/src/stream.mts @@ -1,19 +1,20 @@ -import type { Run, RunnableConfig, Checkpoint } from "./storage/ops.mjs"; -import { getGraph } from "./graph/load.mjs"; -import { Client as LangSmithClient } from "langsmith"; +import { BaseMessageChunk, isBaseMessage } from "@langchain/core/messages"; +import { LangChainTracer } from "@langchain/core/tracers/tracer_langchain"; import { type CheckpointMetadata, type Interrupt, type StateSnapshot, } from "@langchain/langgraph"; import type { Pregel } from "@langchain/langgraph/pregel"; +import { Client as LangSmithClient, getDefaultProjectName } from "langsmith"; +import { getLangGraphCommand } from "./command.mjs"; +import { getGraph } from "./graph/load.mjs"; +import { checkLangGraphSemver } from "./semver/index.mjs"; +import type { Checkpoint, Run, RunnableConfig } from "./storage/ops.mjs"; import { runnableConfigToCheckpoint, taskRunnableConfigToCheckpoint, } from "./utils/runnableConfig.mjs"; -import { BaseMessageChunk, isBaseMessage } from "@langchain/core/messages"; -import { getLangGraphCommand } from "./command.mjs"; -import { checkLangGraphSemver } from "./semver/index.mjs"; type LangGraphStreamMode = Pregel["streamMode"][number]; @@ -197,6 +198,21 @@ export async function* streamState( langgraph_api_url: process.env.LANGGRAPH_API_URL ?? undefined, }; + const tracer = run.kwargs?.config?.configurable?.langsmith_project + ? new LangChainTracer({ + replicas: [ + [ + run.kwargs?.config?.configurable?.langsmith_project as string, + { + reference_example_id: + run.kwargs?.config?.configurable?.langsmith_example_id, + }, + ], + [getDefaultProjectName(), undefined], + ], + }) + : undefined; + const events = graph.streamEvents( kwargs.command != null ? getLangGraphCommand(kwargs.command) @@ -216,6 +232,7 @@ export async function* streamState( runId: run.run_id, streamMode: [...libStreamMode], signal: options?.signal, + ...(tracer && { callbacks: [tracer] }), }, ); diff --git a/libs/langgraph-cli/package.json b/libs/langgraph-cli/package.json index b4db907..7992a11 100644 --- a/libs/langgraph-cli/package.json +++ b/libs/langgraph-cli/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-cli", - "version": "0.0.39", + "version": "0.0.40", "type": "module", "engines": { "node": "^18.19.0 || >=20.16.0" diff --git a/libs/langgraph-ui/package.json b/libs/langgraph-ui/package.json index 6dce253..51b07d5 100644 --- a/libs/langgraph-ui/package.json +++ b/libs/langgraph-ui/package.json @@ -1,6 +1,6 @@ { "name": "@langchain/langgraph-ui", - "version": "0.0.39", + "version": "0.0.40", "type": "module", "engines": { "node": "^18.19.0 || >=20.16.0" diff --git a/yarn.lock b/yarn.lock index cca742a..604e3c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -382,23 +382,23 @@ __metadata: languageName: node linkType: hard -"@langchain/core@npm:^0.3.42": - version: 0.3.57 - resolution: "@langchain/core@npm:0.3.57" +"@langchain/core@npm:^0.3.59": + version: 0.3.59 + resolution: "@langchain/core@npm:0.3.59" dependencies: "@cfworker/json-schema": ^4.0.2 ansi-styles: ^5.0.0 camelcase: 6 decamelize: 1.2.0 js-tiktoken: ^1.0.12 - langsmith: ^0.3.29 + langsmith: ^0.3.33 mustache: ^4.2.0 p-queue: ^6.6.2 p-retry: 4 uuid: ^10.0.0 - zod: ^3.22.4 + zod: ^3.25.32 zod-to-json-schema: ^3.22.3 - checksum: 5a497553209a3fe0c2a31b23c9586f586ea8b0785cb437a0b7140c308be80f0caa4397c45a4d7f0a1b7056f3509b03663f6c714217b75c20cce0a2df4fb3c105 + checksum: 7ad68340baaa45dbdb94393345b23680fb57633aea3a3f766a96329b8521acd54197f68faa6ee8c12249d8bd5737f5cb37cc508df62dbfe4bf00b20af1cef8fa languageName: node linkType: hard @@ -409,7 +409,7 @@ __metadata: "@babel/code-frame": ^7.26.2 "@hono/node-server": ^1.12.0 "@hono/zod-validator": ^0.2.2 - "@langchain/core": ^0.3.42 + "@langchain/core": ^0.3.59 "@langchain/langgraph": ^0.2.57 "@langchain/langgraph-checkpoint": ~0.0.16 "@langchain/langgraph-sdk": ^0.0.77 @@ -427,7 +427,7 @@ __metadata: exit-hook: ^4.0.0 hono: ^4.5.4 jose: ^6.0.10 - langsmith: ^0.2.15 + langsmith: ^0.3.33 open: ^10.1.0 postgres: ^3.4.5 prettier: ^3.3.3 @@ -442,7 +442,7 @@ __metadata: winston-console-format: ^1.0.8 zod: ^3.23.8 peerDependencies: - "@langchain/core": ^0.3.42 + "@langchain/core": ^0.3.59 "@langchain/langgraph": ^0.2.57 || ^0.3.0 "@langchain/langgraph-checkpoint": ~0.0.16 "@langchain/langgraph-sdk": ~0.0.70 @@ -2228,9 +2228,9 @@ __metadata: languageName: node linkType: hard -"langsmith@npm:^0.3.29": - version: 0.3.29 - resolution: "langsmith@npm:0.3.29" +"langsmith@npm:^0.3.33": + version: 0.3.33 + resolution: "langsmith@npm:0.3.33" dependencies: "@types/uuid": ^10.0.0 chalk: ^4.1.2 @@ -2244,7 +2244,7 @@ __metadata: peerDependenciesMeta: openai: optional: true - checksum: 5e714752d40bd90525436d2d977ed0e750031f946dbc6c5549a1d7ceb5546b48dfcc23a1fb1b758f18d954fe53e6089b7ca600c60f2f72d854aa24d5ff0a41fa + checksum: 45970dbc711d3c84b1603d26291b9164ca6daf6d802f151af6c3ccdbfb84068be390366dbb15319a158ccf50e7e9f161c55abe84bce2730f93962888b33e6269 languageName: node linkType: hard @@ -3807,9 +3807,9 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.22.4, zod@npm:^3.23.8": - version: 3.25.20 - resolution: "zod@npm:3.25.20" - checksum: fce59e8727a1403b52158ea3b92f3cec23556dc014174ccabe49910fb4d59f0031df3a687a5941885dd26dc5d263ef976c5c07099e07b68c208f0049ef9f05a5 +"zod@npm:^3.23.8, zod@npm:^3.25.32": + version: 3.25.67 + resolution: "zod@npm:3.25.67" + checksum: 56ab904d33b1cd00041ce64ae05b0628fcbfeb7e707fa31cd498a97b540135e4dfe685200c9c62aea307695ee132870b4bc34f035228ea728aa75cc96a4954cb languageName: node linkType: hard