skein-js 0.9.0 → 0.9.1
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/README.md +16 -9
- package/dist/index.js +40 -8
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -67,15 +67,22 @@ any layer. Public-registry builds don't need it.
|
|
|
67
67
|
|
|
68
68
|
## `skein dev` flags
|
|
69
69
|
|
|
70
|
-
| Flag
|
|
71
|
-
|
|
|
72
|
-
| `-p, --port`
|
|
73
|
-
| `--host`
|
|
74
|
-
| `--store <driver>`
|
|
75
|
-
| `--queue <driver>`
|
|
76
|
-
| `--
|
|
77
|
-
|
|
|
78
|
-
|
|
|
70
|
+
| Flag | Values | Default | Notes |
|
|
71
|
+
| ------------------------- | -------------------- | ----------- | -------------------------------------------------------------- |
|
|
72
|
+
| `-p, --port` | number | `2024` | Port to listen on. |
|
|
73
|
+
| `--host` | host | `127.0.0.1` | Interface to bind. |
|
|
74
|
+
| `--store <driver>` | `memory`, `postgres` | `memory` | `postgres` reads `POSTGRES_URI`; also selects `PostgresSaver`. |
|
|
75
|
+
| `--queue <driver>` | `memory`, `redis` | `memory` | `redis` reads `REDIS_URI` (BullMQ queue + Redis Streams bus). |
|
|
76
|
+
| `--concurrency` | number | `10` | Queued runs the background worker executes at once. |
|
|
77
|
+
| `-n, --n-jobs-per-worker` | number | `10` | LangGraph-compatible alias for `--concurrency`. |
|
|
78
|
+
| `--no-persist` | — | persists | Don't snapshot dev state to `.skein/` across restarts. |
|
|
79
|
+
| `--no-reload` | — | reloads | Disable hot reload on source change. |
|
|
80
|
+
| `-v, --verbose` | — | off | Log per-run activity (tool calls, interrupts, timing). |
|
|
81
|
+
|
|
82
|
+
`--store`, `--queue`, `--concurrency`, and `-n, --n-jobs-per-worker` are accepted by `skein start`
|
|
83
|
+
too. Concurrency also reads `SKEIN_RUN_CONCURRENCY` (or `N_JOBS_PER_WORKER`) when no flag is passed —
|
|
84
|
+
the path that reaches a container. See
|
|
85
|
+
[runs-and-redis.md](../../docs/runs-and-redis.md#run-concurrency).
|
|
79
86
|
|
|
80
87
|
`skein dev --store postgres --queue redis` is a capability the LangGraph CLI does **not** offer: it
|
|
81
88
|
lets you develop against **production-shaped** storage (durable Postgres checkpoints, pgvector
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
readLanggraphDevState
|
|
15
15
|
} from "@skein-js/express";
|
|
16
16
|
import { buildRuntime } from "@skein-js/runtime";
|
|
17
|
+
import { resolveRunConcurrency } from "@skein-js/server-kit";
|
|
17
18
|
|
|
18
19
|
// src/colors.ts
|
|
19
20
|
var colorEnabled = process.stdout.isTTY === true && process.env.NO_COLOR === void 0;
|
|
@@ -27,7 +28,7 @@ var dim = paint(2);
|
|
|
27
28
|
|
|
28
29
|
// src/banner.ts
|
|
29
30
|
function printBanner(info, logger2) {
|
|
30
|
-
const { host, port, graphIds, authPath,
|
|
31
|
+
const { host, port, graphIds, authPath, runConcurrency } = info;
|
|
31
32
|
const base = `http://${host}:${port}`;
|
|
32
33
|
console.log();
|
|
33
34
|
console.log(`${bold(green("skein"))} ${dim("\xB7 Agent Protocol dev server")}`);
|
|
@@ -37,7 +38,9 @@ function printBanner(info, logger2) {
|
|
|
37
38
|
console.log();
|
|
38
39
|
for (const id of graphIds) logger2.info(`Registering graph with id '${id}'`);
|
|
39
40
|
if (authPath) logger2.info(`Loading auth from ${authPath}`);
|
|
40
|
-
logger2.info(
|
|
41
|
+
logger2.info(
|
|
42
|
+
runConcurrency === 1 ? "Starting 1 worker" : `Starting 1 worker, up to ${runConcurrency} concurrent runs`
|
|
43
|
+
);
|
|
41
44
|
logger2.info(`Server running at ${base}`);
|
|
42
45
|
}
|
|
43
46
|
|
|
@@ -225,6 +228,7 @@ async function runDev(options) {
|
|
|
225
228
|
});
|
|
226
229
|
const port = options.portExplicit ? options.port : envPort(options.port);
|
|
227
230
|
const host = options.hostExplicit ? options.host : envHost(options.host);
|
|
231
|
+
const runConcurrency = resolveRunConcurrency(options.concurrency ?? options.nJobsPerWorker);
|
|
228
232
|
const canPersist = options.persist && runtime.snapshotState !== void 0;
|
|
229
233
|
if (options.persist && runtime.snapshotState === void 0) {
|
|
230
234
|
console.log(
|
|
@@ -263,7 +267,8 @@ async function runDev(options) {
|
|
|
263
267
|
deps: runtime.deps,
|
|
264
268
|
cors: runtime.cors,
|
|
265
269
|
warm: true,
|
|
266
|
-
logger: devLogger
|
|
270
|
+
logger: devLogger,
|
|
271
|
+
worker: { maxConcurrency: runConcurrency }
|
|
267
272
|
});
|
|
268
273
|
await server.listen(port, host);
|
|
269
274
|
} catch (error) {
|
|
@@ -278,7 +283,7 @@ async function runDev(options) {
|
|
|
278
283
|
port,
|
|
279
284
|
graphIds: runtime.deps.graphs.ids,
|
|
280
285
|
authPath: config.auth?.path,
|
|
281
|
-
|
|
286
|
+
runConcurrency
|
|
282
287
|
},
|
|
283
288
|
devLogger
|
|
284
289
|
);
|
|
@@ -925,6 +930,7 @@ import { createExpressServer as createExpressServer2 } from "@skein-js/express";
|
|
|
925
930
|
import {
|
|
926
931
|
buildRuntime as buildRuntime3
|
|
927
932
|
} from "@skein-js/runtime";
|
|
933
|
+
import { resolveRunConcurrency as resolveRunConcurrency2 } from "@skein-js/server-kit";
|
|
928
934
|
var FORCE_EXIT_MS2 = 5e3;
|
|
929
935
|
var logger = createDevLogger();
|
|
930
936
|
function readBakedSchemas(configDir) {
|
|
@@ -941,11 +947,13 @@ async function runStart(options) {
|
|
|
941
947
|
let schemas;
|
|
942
948
|
let configDir;
|
|
943
949
|
let authPath;
|
|
950
|
+
let runConcurrency;
|
|
944
951
|
try {
|
|
945
952
|
const loaded = await loadConfig5({ configPath });
|
|
946
953
|
configDir = loaded.configDir;
|
|
947
954
|
authPath = loaded.config.auth?.path;
|
|
948
955
|
await applyProjectEnv(loaded.config, configDir);
|
|
956
|
+
runConcurrency = resolveRunConcurrency2(options.concurrency ?? options.nJobsPerWorker);
|
|
949
957
|
schemas = readBakedSchemas(configDir);
|
|
950
958
|
} catch (error) {
|
|
951
959
|
console.error(`skein: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -974,7 +982,8 @@ async function runStart(options) {
|
|
|
974
982
|
deps: runtime.deps,
|
|
975
983
|
cors: runtime.cors,
|
|
976
984
|
warm: true,
|
|
977
|
-
logger
|
|
985
|
+
logger,
|
|
986
|
+
worker: { maxConcurrency: runConcurrency }
|
|
978
987
|
});
|
|
979
988
|
await server.listen(port, host);
|
|
980
989
|
} catch (error) {
|
|
@@ -983,7 +992,7 @@ async function runStart(options) {
|
|
|
983
992
|
process.exitCode = 1;
|
|
984
993
|
return;
|
|
985
994
|
}
|
|
986
|
-
printBanner({ host, port, graphIds: runtime.deps.graphs.ids, authPath,
|
|
995
|
+
printBanner({ host, port, graphIds: runtime.deps.graphs.ids, authPath, runConcurrency }, logger);
|
|
987
996
|
let shuttingDown = false;
|
|
988
997
|
const shutdown = () => {
|
|
989
998
|
if (shuttingDown) return;
|
|
@@ -1006,6 +1015,13 @@ function parsePort(value) {
|
|
|
1006
1015
|
}
|
|
1007
1016
|
return port;
|
|
1008
1017
|
}
|
|
1018
|
+
function parseConcurrency(value) {
|
|
1019
|
+
const concurrency = Number(value);
|
|
1020
|
+
if (!Number.isInteger(concurrency) || concurrency <= 0) {
|
|
1021
|
+
throw new InvalidArgumentError("Concurrency must be a positive integer.");
|
|
1022
|
+
}
|
|
1023
|
+
return concurrency;
|
|
1024
|
+
}
|
|
1009
1025
|
function parseChoice(choices) {
|
|
1010
1026
|
return (value) => {
|
|
1011
1027
|
if (!choices.includes(value)) {
|
|
@@ -1019,14 +1035,30 @@ var parseQueue = parseChoice(["memory", "redis"]);
|
|
|
1019
1035
|
var program = new Command().name("skein").description(
|
|
1020
1036
|
"Agent Protocol server for LangGraph.js \u2014 a drop-in replacement for the LangGraph CLI."
|
|
1021
1037
|
).version(version, "-v, --version");
|
|
1022
|
-
program.command("dev").description("Run the in-process dev server with hot reload (no Docker).").option("-c, --config <path>", "Path to langgraph.json", "langgraph.json").option("-p, --port <port>", "Port to bind", parsePort, 2024).option("--host <host>", "Host to bind", "127.0.0.1").option("--no-reload", "Disable hot reload").option("--no-persist", "Don't persist dev state to .skein/ between restarts").option("--store <driver>", "Store driver: memory | postgres", parseStore, "memory").option("--queue <driver>", "Queue driver: memory | redis", parseQueue, "memory").option(
|
|
1038
|
+
program.command("dev").description("Run the in-process dev server with hot reload (no Docker).").option("-c, --config <path>", "Path to langgraph.json", "langgraph.json").option("-p, --port <port>", "Port to bind", parsePort, 2024).option("--host <host>", "Host to bind", "127.0.0.1").option("--no-reload", "Disable hot reload").option("--no-persist", "Don't persist dev state to .skein/ between restarts").option("--store <driver>", "Store driver: memory | postgres", parseStore, "memory").option("--queue <driver>", "Queue driver: memory | redis", parseQueue, "memory").option(
|
|
1039
|
+
"--concurrency <count>",
|
|
1040
|
+
"Queued runs the background worker executes at once (default 10; env SKEIN_RUN_CONCURRENCY)",
|
|
1041
|
+
parseConcurrency
|
|
1042
|
+
).option(
|
|
1043
|
+
"-n, --n-jobs-per-worker <count>",
|
|
1044
|
+
"Alias for --concurrency (LangGraph CLI compatibility)",
|
|
1045
|
+
parseConcurrency
|
|
1046
|
+
).option("-v, --verbose", "Log per-run activity: start/finish, tool calls, and interrupts").action(
|
|
1023
1047
|
(options, command) => runDev({
|
|
1024
1048
|
...options,
|
|
1025
1049
|
portExplicit: command.getOptionValueSource("port") === "cli",
|
|
1026
1050
|
hostExplicit: command.getOptionValueSource("host") === "cli"
|
|
1027
1051
|
})
|
|
1028
1052
|
);
|
|
1029
|
-
program.command("start").description("Serve a pre-built .skein/build artifact (the production image entrypoint).").option("-c, --config <path>", "Path to the artifact's langgraph.json", "langgraph.json").option("-p, --port <port>", "Port to bind", parsePort, 2024).option("--host <host>", "Host to bind", "127.0.0.1").option("--store <driver>", "Store driver: memory | postgres", parseStore, "memory").option("--queue <driver>", "Queue driver: memory | redis", parseQueue, "memory").option(
|
|
1053
|
+
program.command("start").description("Serve a pre-built .skein/build artifact (the production image entrypoint).").option("-c, --config <path>", "Path to the artifact's langgraph.json", "langgraph.json").option("-p, --port <port>", "Port to bind", parsePort, 2024).option("--host <host>", "Host to bind", "127.0.0.1").option("--store <driver>", "Store driver: memory | postgres", parseStore, "memory").option("--queue <driver>", "Queue driver: memory | redis", parseQueue, "memory").option(
|
|
1054
|
+
"--concurrency <count>",
|
|
1055
|
+
"Queued runs the background worker executes at once (default 10; env SKEIN_RUN_CONCURRENCY)",
|
|
1056
|
+
parseConcurrency
|
|
1057
|
+
).option(
|
|
1058
|
+
"-n, --n-jobs-per-worker <count>",
|
|
1059
|
+
"Alias for --concurrency (LangGraph CLI compatibility)",
|
|
1060
|
+
parseConcurrency
|
|
1061
|
+
).option("-v, --verbose", "Log per-run activity: start/finish, tool calls, and interrupts").action(
|
|
1030
1062
|
(options, command) => runStart({
|
|
1031
1063
|
...options,
|
|
1032
1064
|
portExplicit: command.getOptionValueSource("port") === "cli",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skein-js",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "The skein-js CLI — a drop-in replacement for the LangGraph CLI (dev/up/build/dockerfile).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Maina Wycliffe <wmmaina7@gmail.com>",
|
|
@@ -47,10 +47,11 @@
|
|
|
47
47
|
"@commander-js/extra-typings": "~13.1.0",
|
|
48
48
|
"@langchain/langgraph-checkpoint-postgres": "^1.0.4",
|
|
49
49
|
"commander": "~13.1.0",
|
|
50
|
-
"@skein-js/core": "0.9.
|
|
51
|
-
"@skein-js/
|
|
52
|
-
"@skein-js/
|
|
53
|
-
"@skein-js/
|
|
50
|
+
"@skein-js/core": "0.9.1",
|
|
51
|
+
"@skein-js/express": "0.9.1",
|
|
52
|
+
"@skein-js/runtime": "0.9.1",
|
|
53
|
+
"@skein-js/server-kit": "0.9.1",
|
|
54
|
+
"@skein-js/config": "0.9.1"
|
|
54
55
|
},
|
|
55
56
|
"optionalDependencies": {
|
|
56
57
|
"vite": "^8.1.0"
|