@langchain/langgraph-cli 1.1.8 → 1.1.10
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.
- package/dist/cli/build.mjs +52 -0
- package/dist/cli/cli.mjs +13 -0
- package/dist/cli/cloudflare.mjs +172 -0
- package/dist/cli/dev.mjs +143 -0
- package/dist/cli/dev.python.mjs +129 -0
- package/dist/cli/docker.mjs +114 -0
- package/dist/cli/new.mjs +13 -0
- package/dist/cli/sysinfo.mjs +63 -0
- package/dist/cli/up.mjs +139 -0
- package/dist/cli/utils/analytics.mjs +39 -0
- package/dist/cli/utils/builder.mjs +7 -0
- package/dist/cli/utils/ipc/server.mjs +93 -0
- package/dist/cli/utils/ipc/utils/get-pipe-path.mjs +29 -0
- package/dist/cli/utils/ipc/utils/temporary-directory.mjs +40 -0
- package/dist/cli/utils/project.mjs +18 -0
- package/dist/cli/utils/stream.mjs +90 -0
- package/dist/cli/utils/version.mjs +13 -0
- package/dist/docker/compose.mjs +185 -0
- package/dist/docker/docker.mjs +390 -0
- package/dist/docker/shell.mjs +62 -0
- package/dist/utils/config.mjs +104 -0
- package/dist/utils/logging.mjs +96 -0
- package/package.json +17 -17
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
import { extname } from "node:path";
|
|
3
|
+
const GraphPathSchema = z.string().refine((i) => i.includes(":"), {
|
|
4
|
+
message: "Import string must be in format '<file>:<export>'",
|
|
5
|
+
});
|
|
6
|
+
const BaseConfigSchema = z.object({
|
|
7
|
+
docker_compose_file: z.string().optional(),
|
|
8
|
+
dockerfile_lines: z.array(z.string()).default([]),
|
|
9
|
+
graphs: z.record(z.union([
|
|
10
|
+
GraphPathSchema,
|
|
11
|
+
z.object({
|
|
12
|
+
path: GraphPathSchema,
|
|
13
|
+
description: z.string().optional(),
|
|
14
|
+
}),
|
|
15
|
+
])),
|
|
16
|
+
ui: z.record(z.string()).optional(),
|
|
17
|
+
ui_config: z.object({ shared: z.array(z.string()).optional() }).optional(),
|
|
18
|
+
_INTERNAL_docker_tag: z.string().optional(),
|
|
19
|
+
env: z
|
|
20
|
+
.union([z.array(z.string()), z.record(z.string()), z.string()])
|
|
21
|
+
.default({}),
|
|
22
|
+
store: z
|
|
23
|
+
.object({
|
|
24
|
+
index: z
|
|
25
|
+
.object({
|
|
26
|
+
dims: z.number().optional(),
|
|
27
|
+
embed: z.string().optional(),
|
|
28
|
+
fields: z.array(z.string()).optional(),
|
|
29
|
+
})
|
|
30
|
+
.optional(),
|
|
31
|
+
})
|
|
32
|
+
.optional(),
|
|
33
|
+
auth: z
|
|
34
|
+
.object({
|
|
35
|
+
path: z.string().optional(),
|
|
36
|
+
disable_studio_auth: z.boolean().default(false),
|
|
37
|
+
})
|
|
38
|
+
.optional(),
|
|
39
|
+
http: z
|
|
40
|
+
.object({
|
|
41
|
+
app: z.string().optional(),
|
|
42
|
+
disable_assistants: z.boolean().default(false),
|
|
43
|
+
disable_threads: z.boolean().default(false),
|
|
44
|
+
disable_runs: z.boolean().default(false),
|
|
45
|
+
disable_store: z.boolean().default(false),
|
|
46
|
+
disable_meta: z.boolean().default(false),
|
|
47
|
+
cors: z
|
|
48
|
+
.object({
|
|
49
|
+
allow_origins: z.array(z.string()).optional(),
|
|
50
|
+
allow_methods: z.array(z.string()).optional(),
|
|
51
|
+
allow_headers: z.array(z.string()).optional(),
|
|
52
|
+
allow_credentials: z.boolean().optional(),
|
|
53
|
+
allow_origin_regex: z.string().optional(),
|
|
54
|
+
expose_headers: z.array(z.string()).optional(),
|
|
55
|
+
max_age: z.number().optional(),
|
|
56
|
+
})
|
|
57
|
+
.optional(),
|
|
58
|
+
})
|
|
59
|
+
.optional(),
|
|
60
|
+
});
|
|
61
|
+
const DEFAULT_PYTHON_VERSION = "3.11";
|
|
62
|
+
const DEFAULT_NODE_VERSION = "20";
|
|
63
|
+
const PYTHON_EXTENSIONS = [".py", ".pyx", ".pyd", ".pyi"];
|
|
64
|
+
const PythonVersionSchema = z.union([z.literal("3.11"), z.literal("3.12")]);
|
|
65
|
+
const NodeVersionSchema = z.union([z.literal("20"), z.literal("22")]);
|
|
66
|
+
const PythonConfigSchema = BaseConfigSchema.merge(z.object({
|
|
67
|
+
pip_config_file: z.string().optional(),
|
|
68
|
+
dependencies: z
|
|
69
|
+
.array(z.string())
|
|
70
|
+
.nonempty("You need to specify at least one dependency"),
|
|
71
|
+
})).merge(z.object({
|
|
72
|
+
python_version: PythonVersionSchema.default(DEFAULT_PYTHON_VERSION),
|
|
73
|
+
node_version: NodeVersionSchema.optional(),
|
|
74
|
+
}));
|
|
75
|
+
const NodeConfigSchema = BaseConfigSchema.merge(z.object({ node_version: NodeVersionSchema.default(DEFAULT_NODE_VERSION) }));
|
|
76
|
+
const ConfigSchema = z.union([NodeConfigSchema, PythonConfigSchema]);
|
|
77
|
+
// TODO: implement this in Python CLI
|
|
78
|
+
export const getConfig = (config) => {
|
|
79
|
+
let input = typeof config === "string" ? JSON.parse(config) : config;
|
|
80
|
+
const { graphs } = BaseConfigSchema.parse(input);
|
|
81
|
+
const isPython = Object.values(graphs).map((graphDef) => {
|
|
82
|
+
const importStr = typeof graphDef === "string" ? graphDef : graphDef.path;
|
|
83
|
+
return PYTHON_EXTENSIONS.includes(extname(importStr.split(":")[0]));
|
|
84
|
+
});
|
|
85
|
+
const somePython = isPython.some((i) => i);
|
|
86
|
+
const someNode = !isPython.every((i) => i);
|
|
87
|
+
const node_version = someNode
|
|
88
|
+
? input.node_version || DEFAULT_NODE_VERSION
|
|
89
|
+
: undefined;
|
|
90
|
+
const python_version = somePython
|
|
91
|
+
? input.python_version || (someNode ? "3.12" : DEFAULT_PYTHON_VERSION)
|
|
92
|
+
: undefined;
|
|
93
|
+
if (node_version && python_version && python_version !== "3.12") {
|
|
94
|
+
throw new Error("Only Python 3.12 is supported with Node.js");
|
|
95
|
+
}
|
|
96
|
+
input = { ...input, node_version, python_version };
|
|
97
|
+
if (!input.node_version)
|
|
98
|
+
delete input.node_version;
|
|
99
|
+
if (!input.python_version)
|
|
100
|
+
delete input.python_version;
|
|
101
|
+
if (python_version)
|
|
102
|
+
return PythonConfigSchema.parse(input);
|
|
103
|
+
return NodeConfigSchema.parse(input);
|
|
104
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createLogger, format, transports } from "winston";
|
|
2
|
+
import { consoleFormat } from "winston-console-format";
|
|
3
|
+
import { parse as stacktraceParser } from "stacktrace-parser";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { codeFrameColumns } from "@babel/code-frame";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
const LOG_JSON = process.env.LOG_JSON === "true";
|
|
8
|
+
const LOG_LEVEL = process.env.LOG_LEVEL || "debug";
|
|
9
|
+
export const logger = createLogger({
|
|
10
|
+
level: LOG_LEVEL,
|
|
11
|
+
format: format.combine(format.errors({ stack: true }), format.timestamp(), format.json(), ...(!LOG_JSON
|
|
12
|
+
? [
|
|
13
|
+
format.colorize({ all: true }),
|
|
14
|
+
format.padLevels(),
|
|
15
|
+
consoleFormat({
|
|
16
|
+
showMeta: true,
|
|
17
|
+
metaStrip: ["timestamp"],
|
|
18
|
+
inspectOptions: {
|
|
19
|
+
depth: Infinity,
|
|
20
|
+
colors: true,
|
|
21
|
+
maxArrayLength: Infinity,
|
|
22
|
+
breakLength: 120,
|
|
23
|
+
compact: Infinity,
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
]
|
|
27
|
+
: [
|
|
28
|
+
format.printf((info) => {
|
|
29
|
+
const { timestamp, level, message, ...rest } = info;
|
|
30
|
+
let event;
|
|
31
|
+
if (typeof message === "string") {
|
|
32
|
+
event = message;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
event = JSON.stringify(message);
|
|
36
|
+
}
|
|
37
|
+
if (rest.stack) {
|
|
38
|
+
rest.message = event;
|
|
39
|
+
event = rest.stack;
|
|
40
|
+
}
|
|
41
|
+
return JSON.stringify({ timestamp, level, event, ...rest });
|
|
42
|
+
}),
|
|
43
|
+
])),
|
|
44
|
+
transports: [new transports.Console()],
|
|
45
|
+
});
|
|
46
|
+
const formatStack = (stack) => {
|
|
47
|
+
if (!stack)
|
|
48
|
+
return stack;
|
|
49
|
+
const [firstFile] = stacktraceParser(stack).filter((item) => !item.file?.split(path.sep).includes("node_modules") &&
|
|
50
|
+
!item.file?.startsWith("node:"));
|
|
51
|
+
if (firstFile?.file && firstFile?.lineNumber) {
|
|
52
|
+
try {
|
|
53
|
+
const filePath = firstFile.file;
|
|
54
|
+
const line = firstFile.lineNumber;
|
|
55
|
+
const column = firstFile.column ?? 0;
|
|
56
|
+
const messageLines = stack.split("\n");
|
|
57
|
+
const spliceIndex = messageLines.findIndex((i) => i.includes(filePath));
|
|
58
|
+
const padding = " ".repeat(Math.max(0, messageLines[spliceIndex].indexOf("at")));
|
|
59
|
+
const highlightCode = process.stdout.isTTY;
|
|
60
|
+
let codeFrame = codeFrameColumns(readFileSync(filePath, "utf-8"), { start: { line, column } }, { highlightCode });
|
|
61
|
+
codeFrame = codeFrame
|
|
62
|
+
.split("\n")
|
|
63
|
+
.map((i) => padding + i + "\x1b[0m")
|
|
64
|
+
.join("\n");
|
|
65
|
+
if (highlightCode) {
|
|
66
|
+
codeFrame = "\x1b[36m" + codeFrame + "\x1b[31m";
|
|
67
|
+
}
|
|
68
|
+
// insert codeframe after the line but dont lose the stack
|
|
69
|
+
return [
|
|
70
|
+
...messageLines.slice(0, spliceIndex + 1),
|
|
71
|
+
codeFrame,
|
|
72
|
+
...messageLines.slice(spliceIndex + 1),
|
|
73
|
+
].join("\n");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// pass
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return stack;
|
|
80
|
+
};
|
|
81
|
+
export const logError = (error, options) => {
|
|
82
|
+
let message;
|
|
83
|
+
let context = options?.context;
|
|
84
|
+
if (error instanceof Error) {
|
|
85
|
+
message = formatStack(error.stack) || error.message;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
message = String(error);
|
|
89
|
+
context = { ...context, error };
|
|
90
|
+
}
|
|
91
|
+
if (options?.prefix != null)
|
|
92
|
+
message = `${options.prefix}:\n${message}`;
|
|
93
|
+
logger.error(message, ...(context != null ? [context] : []));
|
|
94
|
+
};
|
|
95
|
+
process.on("uncaughtException", (error) => logError(error));
|
|
96
|
+
process.on("unhandledRejection", (error) => logError(error));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^18.19.0 || >=20.16.0"
|
|
@@ -19,25 +19,11 @@
|
|
|
19
19
|
"url": "git+ssh://git@github.com/langchain-ai/langgraphjs.git",
|
|
20
20
|
"directory": "libs/langgraph-cli"
|
|
21
21
|
},
|
|
22
|
-
"scripts": {
|
|
23
|
-
"clean": "rm -rf dist/ .turbo/",
|
|
24
|
-
"build": "yarn turbo:command build:internal --filter=@langchain/langgraph-cli",
|
|
25
|
-
"build:internal": "yarn clean && node scripts/build.mjs",
|
|
26
|
-
"prepublish": "yarn build",
|
|
27
|
-
"typecheck": "tsc --noEmit",
|
|
28
|
-
"cli": "tsx src/cli/cli.mts",
|
|
29
|
-
"cli:watch": "tsx watch src/cli/cli.mts",
|
|
30
|
-
"test": "vitest run",
|
|
31
|
-
"format": "prettier --write .",
|
|
32
|
-
"format:check": "prettier --check ."
|
|
33
|
-
},
|
|
34
22
|
"dependencies": {
|
|
35
23
|
"@babel/code-frame": "^7.26.2",
|
|
36
24
|
"@commander-js/extra-typings": "^13.0.0",
|
|
37
|
-
"@langchain/langgraph-api": "workspace:*",
|
|
38
25
|
"chokidar": "^4.0.3",
|
|
39
26
|
"commander": "^13.0.0",
|
|
40
|
-
"create-langgraph": "workspace:*",
|
|
41
27
|
"dedent": "^1.5.3",
|
|
42
28
|
"dotenv": "^16.4.7",
|
|
43
29
|
"execa": "^9.5.2",
|
|
@@ -51,7 +37,9 @@
|
|
|
51
37
|
"winston": "^3.17.0",
|
|
52
38
|
"winston-console-format": "^1.0.8",
|
|
53
39
|
"yaml": "^2.7.0",
|
|
54
|
-
"zod": "^3.25.76 || ^4"
|
|
40
|
+
"zod": "^3.25.76 || ^4",
|
|
41
|
+
"@langchain/langgraph-api": "1.1.10",
|
|
42
|
+
"create-langgraph": "1.1.5"
|
|
55
43
|
},
|
|
56
44
|
"devDependencies": {
|
|
57
45
|
"@types/babel__code-frame": "^7.0.6",
|
|
@@ -60,5 +48,17 @@
|
|
|
60
48
|
"tsx": "^4.19.3",
|
|
61
49
|
"typescript": "^4.9.5 || ^5.4.5",
|
|
62
50
|
"vitest": "^3.2.4"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"clean": "rm -rf dist/ .turbo/",
|
|
54
|
+
"build": "pnpm turbo build:internal --filter=@langchain/langgraph-cli",
|
|
55
|
+
"build:internal": "pnpm clean && node scripts/build.mjs",
|
|
56
|
+
"prepublish": "pnpm build",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"cli": "tsx src/cli/cli.mts",
|
|
59
|
+
"cli:watch": "tsx watch src/cli/cli.mts",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"format": "prettier --write .",
|
|
62
|
+
"format:check": "prettier --check ."
|
|
63
63
|
}
|
|
64
|
-
}
|
|
64
|
+
}
|