Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions libs/langgraph-api/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module.exports = {
extends: [
"airbnb-base",
"eslint:recommended",
"prettier",
"plugin:@typescript-eslint/recommended",
],
parserOptions: {
ecmaVersion: 12,
parser: "@typescript-eslint/parser",
project: "./tsconfig.json",
sourceType: "module",
},
plugins: ["@typescript-eslint", "no-instanceof"],
ignorePatterns: [
".eslintrc.cjs",
"scripts",
"node_modules",
"dist",
"dist-cjs",
"*.js",
"*.cjs",
"*.d.ts",
],
rules: {
"no-process-env": 2,
"no-instanceof/no-instanceof": 2,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-shadow": 0,
"@typescript-eslint/no-empty-interface": 0,
"@typescript-eslint/no-use-before-define": ["error", "nofunc"],
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"arrow-body-style": 0,
camelcase: 0,
"class-methods-use-this": 0,
"import/extensions": [2, "ignorePackages"],
"import/no-extraneous-dependencies": [
"error",
{ devDependencies: ["**/*.test.ts"] },
],
"import/no-unresolved": 0,
"import/prefer-default-export": 0,
"keyword-spacing": "error",
"max-classes-per-file": 0,
"max-len": 0,
"no-await-in-loop": 0,
"no-bitwise": 0,
"no-console": 0,
"no-empty-function": 0,
"no-restricted-syntax": 0,
"no-shadow": 0,
"no-continue": 0,
"no-void": 0,
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"no-useless-constructor": 0,
"no-return-await": 0,
"consistent-return": 0,
"no-else-return": 0,
"func-names": 0,
"no-lonely-if": 0,
"prefer-rest-params": 0,
"new-cap": ["error", { properties: false, capIsNew: false }],
},
};
11 changes: 11 additions & 0 deletions libs/langgraph-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
"build": "yarn turbo:command build:internal --filter=@langchain/langgraph-api",
"build:internal": "yarn clean && node scripts/build.mjs",
"dev": "tsx ./tests/utils.server.mts --dev",
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js,.mts,.mjs src/",
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts src/*.js src/**/*.js src/*.mts src/**/*.mts src/*.mjs src/**/*.mjs",
"lint": "yarn lint:eslint && yarn lint:dpdm",
"lint:fix": "yarn lint:eslint --fix && yarn lint:dpdm",
"prepack": "yarn run build",
"typecheck": "tsc --noEmit",
"test": "vitest run",
Expand Down Expand Up @@ -93,6 +97,13 @@
"@types/react-dom": "^19.0.3",
"@types/semver": "^7.7.0",
"@types/uuid": "^10.0.0",
"dpdm": "^3.12.0",
"eslint": "^8.33.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-no-instanceof": "^1.0.1",
"eslint-plugin-prettier": "^4.2.1",
"jose": "^6.0.10",
"postgres": "^3.4.5",
"prettier": "^2.8.3",
Expand Down
3 changes: 2 additions & 1 deletion libs/langgraph-api/src/api/assistants.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import { Hono } from "hono";
import { v4 as uuid } from "uuid";
import { z } from "zod";

import { HTTPException } from "hono/http-exception";
import {
getAssistantId,
getCachedStaticGraphSchema,
getGraph,
} from "../graph/load.mjs";
import { getRuntimeGraphSchema } from "../graph/parser/index.mjs";

import { HTTPException } from "hono/http-exception";
import * as schemas from "../schemas.mjs";
import { Assistants } from "../storage/ops.mjs";

const api = new Hono();

const RunnableConfigSchema = z.object({
Expand Down
12 changes: 6 additions & 6 deletions libs/langgraph-api/src/api/meta.mts
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ try {
}

// read env variable
const env = process.env;
const {env} = process;

api.get("/info", (c) => {
const langsmithApiKey = env["LANGSMITH_API_KEY"] || env["LANGCHAIN_API_KEY"];
const langsmithApiKey = env.LANGSMITH_API_KEY || env.LANGCHAIN_API_KEY;

const langsmithTracing = (() => {
if (langsmithApiKey) {
// Check if any tracing variable is explicitly set to "false"
const tracingVars = [
env["LANGCHAIN_TRACING_V2"],
env["LANGCHAIN_TRACING"],
env["LANGSMITH_TRACING_V2"],
env["LANGSMITH_TRACING"],
env.LANGCHAIN_TRACING_V2,
env.LANGCHAIN_TRACING,
env.LANGSMITH_TRACING_V2,
env.LANGSMITH_TRACING,
];

// Return true unless explicitly disabled
Expand Down
6 changes: 3 additions & 3 deletions libs/langgraph-api/src/api/runs.mts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ const createValidRun = async (
if (auth) {
userId = auth.user.identity ?? auth.user.id;
config.configurable ??= {};
config.configurable["langgraph_auth_user"] = auth.user;
config.configurable["langgraph_auth_user_id"] = userId;
config.configurable["langgraph_auth_permissions"] = auth.scopes;
config.configurable.langgraph_auth_user = auth.user;
config.configurable.langgraph_auth_user_id = userId;
config.configurable.langgraph_auth_permissions = auth.scopes;
}

let feedbackKeys =
Expand Down
12 changes: 6 additions & 6 deletions libs/langgraph-api/src/api/store.mts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import * as schemas from "../schemas.mjs";
import { HTTPException } from "hono/http-exception";
import { store as storageStore } from "../storage/store.mjs";
import type { Item } from "@langchain/langgraph";
import * as schemas from "../schemas.mjs";
import { store as storageStore } from "../storage/store.mjs";
import { handleAuthEvent } from "../auth/custom.mjs";

const api = new Hono();
Expand All @@ -17,8 +17,8 @@ const validateNamespace = (namespace: string[]) => {
if (!label || label.includes(".")) {
throw new HTTPException(422, {
message:
"Namespace labels cannot be empty or contain periods. Received: " +
namespace.join("."),
`Namespace labels cannot be empty or contain periods. Received: ${
namespace.join(".")}`,
});
}
}
Expand Down Expand Up @@ -136,8 +136,8 @@ api.get(
key: payload.key,
});

const key = payload.key;
const namespace = payload.namespace;
const {key} = payload;
const {namespace} = payload;
return c.json(mapItemsToApi(await storageStore.get(namespace, key)));
}
);
Expand Down
2 changes: 1 addition & 1 deletion libs/langgraph-api/src/cli/entrypoint.mts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { asyncExitHook } from "exit-hook";
import * as process from "node:process";
import { Client as LangSmithClient } from "langsmith";
import { startServer, StartServerSchema } from "../server.mjs";
import { connectToServer } from "./utils/ipc/client.mjs";
import { Client as LangSmithClient } from "langsmith";
import { logger } from "../logging.mjs";

logger.info(`Starting server...`);
Expand Down
2 changes: 1 addition & 1 deletion libs/langgraph-api/src/command.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface RunCommand {
}

export const getLangGraphCommand = (command: RunCommand) => {
let goto =
const goto =
command.goto != null && !Array.isArray(command.goto)
? [command.goto]
: command.goto;
Expand Down
16 changes: 7 additions & 9 deletions libs/langgraph-api/src/experimental/embed.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import { streamSSE } from "hono/streaming";
import { RunnableConfig } from "@langchain/core/runnables";
import { v4 as uuidv4 } from "uuid";

import { z } from "zod";
import type { Metadata, Run } from "../storage/ops.mjs";
import * as schemas from "../schemas.mjs";

import { z } from "zod";
import { streamState } from "../stream.mjs";
import { serialiseAsDict, serializeError } from "../utils/serde.mjs";
import { getDisconnectAbortSignal, jsonExtra } from "../utils/hono.mjs";
Expand Down Expand Up @@ -62,11 +62,10 @@ function createStubRun(
: undefined;

if (streamMode == null || streamMode.length === 0) streamMode = ["values"];
const config = Object.assign(
{},
payload.config ?? {},
{
configurable: {
const config = {

...payload.config ?? {},
configurable: {
run_id: runId,
thread_id: threadId,
graph_id: payload.assistant_id,
Expand All @@ -81,9 +80,8 @@ function createStubRun(
}
: null),
},
},
{ metadata: payload.metadata ?? {} }
);
metadata: payload.metadata ?? {}
};

return {
run_id: runId,
Expand Down
2 changes: 1 addition & 1 deletion libs/langgraph-api/src/graph/load.mts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { z } from "zod";

import * as uuid from "uuid";
import { Assistants } from "../storage/ops.mjs";
import type {
BaseCheckpointSaver,
BaseStore,
CompiledGraph,
LangGraphRunnableConfig,
} from "@langchain/langgraph";
import { HTTPException } from "hono/http-exception";
import { Assistants } from "../storage/ops.mjs";
import { type CompiledGraphFactory, resolveGraph } from "./load.utils.mjs";
import type { GraphSchema, GraphSpec } from "./parser/index.mjs";
import { getStaticGraphSchema } from "./parser/index.mjs";
Expand Down
22 changes: 13 additions & 9 deletions libs/langgraph-api/src/graph/parser/parser.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import * as ts from "typescript";
import * as vfs from "@typescript/vfs";
import * as path from "node:path";
import dedent from "dedent";
import { buildGenerator } from "./schema/types.mjs";
import { fileURLToPath } from "node:url";
import type { JSONSchema7 } from "json-schema";
import { buildGenerator } from "./schema/types.mjs";

interface GraphSchema {
state: JSONSchema7 | undefined;
Expand All @@ -29,11 +29,15 @@ const INFER_TEMPLATE_PATH = path.resolve(

export class SubgraphExtractor {
protected program: ts.Program;

protected checker: ts.TypeChecker;

protected sourceFile: ts.SourceFile;

protected inferFile: ts.SourceFile;

protected anyPregelType: ts.Type;

protected anyGraphType: ts.Type;

protected strict: boolean;
Expand All @@ -56,11 +60,11 @@ export class SubgraphExtractor {
}

private findTypeByName = (needle: string) => {
let result: ts.Type | undefined = undefined;
let result: ts.Type | undefined;

const visit = (node: ts.Node) => {
if (ts.isTypeAliasDeclaration(node)) {
const symbol = (node as any).symbol;
const {symbol} = (node as any);

if (symbol != null) {
const name = this.checker
Expand All @@ -81,7 +85,7 @@ export class SubgraphExtractor {
root: ts.Node,
predicate: (node: ts.Node) => boolean
): ts.Node | undefined => {
let result: ts.Node | undefined = undefined;
let result: ts.Node | undefined;

const visit = (node: ts.Node) => {
if (predicate(node)) {
Expand Down Expand Up @@ -158,7 +162,7 @@ export class SubgraphExtractor {
}

acc.push({
namespace: namespace,
namespace,
node: nodeName,
subgraph: variables[0],
});
Expand Down Expand Up @@ -585,10 +589,10 @@ export class SubgraphExtractor {
const allDiagnostics = ts.getPreEmitDiagnostics(extract);
for (const diagnostic of allDiagnostics) {
let message =
ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n") + "\n";
`${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n") }\n`;

if (diagnostic.file) {
const fileName = diagnostic.file.fileName;
const {fileName} = diagnostic.file;
const { line, character } = ts.getLineAndCharacterOfPosition(
diagnostic.file,
diagnostic.start!
Expand All @@ -602,7 +606,7 @@ export class SubgraphExtractor {

const schemaGenerator = buildGenerator(extract);
const trySymbol = (symbol: string) => {
let schema: JSONSchema7 | undefined = undefined;
let schema: JSONSchema7 | undefined;
try {
schema = schemaGenerator?.getSchemaForSymbol(symbol) ?? undefined;
} catch (e) {
Expand All @@ -614,7 +618,7 @@ export class SubgraphExtractor {

if (schema == null) return undefined;

const definitions = schema.definitions;
const {definitions} = schema;
if (definitions == null) return schema;

const toReplace = Object.keys(definitions).flatMap((key) => {
Expand Down
Loading