@skein-js/agent-protocol 0.9.0 → 0.10.0
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 +4 -1
- package/dist/index.d.ts +27 -4
- package/dist/index.js +42 -9
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -102,7 +102,10 @@ Graph **state, history, and interrupt/resume are 100% LangGraph-native** via the
|
|
|
102
102
|
|
|
103
103
|
- **Entry points:** `createProtocolRuntime(deps, options?)` → `{ service, handlers, worker }`;
|
|
104
104
|
`createProtocolService` / `createProtocolServiceFromContext`; `createProtocolHandlers`; `createContext`;
|
|
105
|
-
`createRunWorker(ctx, options?)` (`RunWorkerOptions`: `maxConcurrency
|
|
105
|
+
`createRunWorker(ctx, options?)` (`RunWorkerOptions`: `maxConcurrency` — queued runs at once,
|
|
106
|
+
default `DEFAULT_RUN_CONCURRENCY` (10, matching the LangGraph CLI) — and `shutdownGraceMs`). The
|
|
107
|
+
adapters surface this as `worker.maxConcurrency` and also read `SKEIN_RUN_CONCURRENCY` /
|
|
108
|
+
`N_JOBS_PER_WORKER`; see [runs-and-redis.md](../../docs/runs-and-redis.md#run-concurrency).
|
|
106
109
|
- **Service surface** (`runtime.service`): `assistants` (`registerGraphAssistants`, `get`, `list`,
|
|
107
110
|
`search`, `schemas`), `threads` (`create`/`get`/`list`/`patch`/`delete`/`history`/`getState`),
|
|
108
111
|
`threadStream` (`stream` / `joinStream` / `command` — HIL resume, requires status `interrupted`),
|
package/dist/index.d.ts
CHANGED
|
@@ -436,10 +436,33 @@ interface ProtocolHandlers {
|
|
|
436
436
|
}
|
|
437
437
|
declare function createProtocolHandlers(service: ProtocolService): ProtocolHandlers;
|
|
438
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Queued runs one worker executes at once when nothing is configured. Matches the LangGraph CLI's
|
|
441
|
+
* `--n-jobs-per-worker` default, so a project moving off `langgraph dev` keeps its throughput.
|
|
442
|
+
*/
|
|
443
|
+
declare const DEFAULT_RUN_CONCURRENCY = 10;
|
|
444
|
+
/**
|
|
445
|
+
* How long `stop()` lets in-flight runs finish before aborting them. Chosen to leave room inside the
|
|
446
|
+
* tightest common stop window — a container platform typically sends SIGTERM and SIGKILLs ~10s later
|
|
447
|
+
* (Cloud Run's default; `docker stop`'s too) — for this drain *plus* the abort-and-settle step that
|
|
448
|
+
* follows it. Raise it via `SKEIN_SHUTDOWN_GRACE_MS` where the platform allows a longer window
|
|
449
|
+
* (Railway, Kubernetes' `terminationGracePeriodSeconds`, ECS `stopTimeout`); the host must also wait
|
|
450
|
+
* longer than this before forcing exit, or the abort path never runs. See docs/deploy.md.
|
|
451
|
+
*/
|
|
452
|
+
declare const DEFAULT_SHUTDOWN_GRACE_MS = 5000;
|
|
439
453
|
interface RunWorkerOptions {
|
|
440
|
-
/**
|
|
454
|
+
/**
|
|
455
|
+
* Max queued runs this worker executes at once. Default {@link DEFAULT_RUN_CONCURRENCY}.
|
|
456
|
+
* Per-thread ordering does not depend on this: `startRunExecution` serializes by `thread_id` at
|
|
457
|
+
* every value. The trade-off is head-of-line blocking — a run waiting on a busy thread's lock
|
|
458
|
+
* still holds a slot, so a burst of `multitask_strategy: "enqueue"` runs on one thread can occupy
|
|
459
|
+
* the worker. See docs/runs-and-redis.md.
|
|
460
|
+
*/
|
|
441
461
|
maxConcurrency?: number;
|
|
442
|
-
/**
|
|
462
|
+
/**
|
|
463
|
+
* How long `stop()` waits for in-flight runs before aborting them (ms). Default
|
|
464
|
+
* {@link DEFAULT_SHUTDOWN_GRACE_MS}.
|
|
465
|
+
*/
|
|
443
466
|
shutdownGraceMs?: number;
|
|
444
467
|
}
|
|
445
468
|
interface RunWorker {
|
|
@@ -452,7 +475,7 @@ declare function createRunWorker(ctx: ProtocolContext, options?: RunWorkerOption
|
|
|
452
475
|
|
|
453
476
|
/** Options for {@link createProtocolRuntime}. */
|
|
454
477
|
interface ProtocolRuntimeOptions {
|
|
455
|
-
/** Tuning for the background run worker (concurrency,
|
|
478
|
+
/** Tuning for the background run worker (max concurrency, shutdown grace period). */
|
|
456
479
|
worker?: RunWorkerOptions;
|
|
457
480
|
}
|
|
458
481
|
/** The wired engine: the service, the transport-neutral handler table, and the background worker. */
|
|
@@ -602,4 +625,4 @@ declare function toSseEvents(frames: AsyncIterable<RunFrame>, finalStatus: () =>
|
|
|
602
625
|
*/
|
|
603
626
|
declare function parseAfterSeq(lastEventId: string | undefined): number;
|
|
604
627
|
|
|
605
|
-
export { type AssistantService, type Clock, type CommandInput, type CompiledGraphFactory, type CreateAssistantInput, type CreateRunInput, type CreateThreadInput, DEFAULT_INVOKE_PREFIX, type DeleteAssistantOptions, type DrawGraphOptions, type GraphInvokeHandlerName, type GraphInvokeOptions, type GraphResolver, type GraphSchemas, type HistoryOptions, type HttpMethod, type Logger, type PatchThreadInput, type ProtocolContext, type ProtocolDeps, type ProtocolHandler, type ProtocolHandlers, type ProtocolRequest, type ProtocolResponse, type ProtocolRuntime, type ProtocolRuntimeOptions, type ProtocolService, type ResolvedGraph, type RouteBinding, type RouteMatch, type RouteMatcher, type RunService, type RunWorker, type RunWorkerOptions, SSE_HEADERS, SkeinBaseStore, type StartedStream, type StoreService, type SubgraphsOptions, type ThreadService, type ThreadStreamInput, type ThreadStreamService, buildProtocolService, copyThreadIdIntoBody, createContext, createGraphInvokeHandler, createProtocolHandlers, createProtocolRuntime, createProtocolService, createProtocolServiceFromContext, createRouteMatcher, createRunWorker, encodeFrame, encodeTerminal, foldThreadId, graphInvokeRoutes, matchSkeinRoute, parseAfterSeq, skeinRoutes, toSseEvents };
|
|
628
|
+
export { type AssistantService, type Clock, type CommandInput, type CompiledGraphFactory, type CreateAssistantInput, type CreateRunInput, type CreateThreadInput, DEFAULT_INVOKE_PREFIX, DEFAULT_RUN_CONCURRENCY, DEFAULT_SHUTDOWN_GRACE_MS, type DeleteAssistantOptions, type DrawGraphOptions, type GraphInvokeHandlerName, type GraphInvokeOptions, type GraphResolver, type GraphSchemas, type HistoryOptions, type HttpMethod, type Logger, type PatchThreadInput, type ProtocolContext, type ProtocolDeps, type ProtocolHandler, type ProtocolHandlers, type ProtocolRequest, type ProtocolResponse, type ProtocolRuntime, type ProtocolRuntimeOptions, type ProtocolService, type ResolvedGraph, type RouteBinding, type RouteMatch, type RouteMatcher, type RunService, type RunWorker, type RunWorkerOptions, SSE_HEADERS, SkeinBaseStore, type StartedStream, type StoreService, type SubgraphsOptions, type ThreadService, type ThreadStreamInput, type ThreadStreamService, buildProtocolService, copyThreadIdIntoBody, createContext, createGraphInvokeHandler, createProtocolHandlers, createProtocolRuntime, createProtocolService, createProtocolServiceFromContext, createRouteMatcher, createRunWorker, encodeFrame, encodeTerminal, foldThreadId, graphInvokeRoutes, matchSkeinRoute, parseAfterSeq, skeinRoutes, toSseEvents };
|
package/dist/index.js
CHANGED
|
@@ -2014,7 +2014,15 @@ function createAuthorizingHandlers(context, engine) {
|
|
|
2014
2014
|
import {
|
|
2015
2015
|
isTerminalRunStatus as isTerminalRunStatus6
|
|
2016
2016
|
} from "@skein-js/core";
|
|
2017
|
-
var
|
|
2017
|
+
var DEFAULT_RUN_CONCURRENCY = 10;
|
|
2018
|
+
var DEFAULT_SHUTDOWN_GRACE_MS = 5e3;
|
|
2019
|
+
function cancellableDelay(ms) {
|
|
2020
|
+
let timer;
|
|
2021
|
+
const elapsed = new Promise((resolve) => {
|
|
2022
|
+
timer = setTimeout(resolve, ms);
|
|
2023
|
+
});
|
|
2024
|
+
return { elapsed, cancel: () => clearTimeout(timer) };
|
|
2025
|
+
}
|
|
2018
2026
|
function logRunLifecycle(logger, run, status, startedAt, endedAt) {
|
|
2019
2027
|
logger.info(status === "success" ? "Background run succeeded" : `Background run ${status}`, {
|
|
2020
2028
|
run_id: run.run_id,
|
|
@@ -2028,10 +2036,16 @@ function logRunLifecycle(logger, run, status, startedAt, endedAt) {
|
|
|
2028
2036
|
}
|
|
2029
2037
|
function createRunWorker(ctx, options = {}) {
|
|
2030
2038
|
const { deps, control } = ctx;
|
|
2031
|
-
const maxConcurrency = options.maxConcurrency ??
|
|
2032
|
-
const shutdownGraceMs = options.shutdownGraceMs ??
|
|
2039
|
+
const maxConcurrency = options.maxConcurrency ?? DEFAULT_RUN_CONCURRENCY;
|
|
2040
|
+
const shutdownGraceMs = options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS;
|
|
2033
2041
|
const inFlight = /* @__PURE__ */ new Set();
|
|
2034
|
-
const
|
|
2042
|
+
const running = /* @__PURE__ */ new Set();
|
|
2043
|
+
const executeQueuedRun = (queued) => {
|
|
2044
|
+
const task = executeOne(queued);
|
|
2045
|
+
running.add(task);
|
|
2046
|
+
return task.finally(() => running.delete(task));
|
|
2047
|
+
};
|
|
2048
|
+
const executeOne = async (queued) => {
|
|
2035
2049
|
const run = await deps.store.runs.get(queued.run_id);
|
|
2036
2050
|
if (!run || isTerminalRunStatus6(run.status)) {
|
|
2037
2051
|
ctx.rollbackPlans.delete(queued.run_id);
|
|
@@ -2052,20 +2066,37 @@ function createRunWorker(ctx, options = {}) {
|
|
|
2052
2066
|
return {
|
|
2053
2067
|
start() {
|
|
2054
2068
|
if (consumer) return;
|
|
2055
|
-
consumer = deps.queue.consume(
|
|
2069
|
+
consumer = deps.queue.consume(executeQueuedRun, { concurrency: maxConcurrency });
|
|
2056
2070
|
},
|
|
2057
2071
|
async stop() {
|
|
2058
2072
|
if (!consumer) return;
|
|
2059
2073
|
const active = consumer;
|
|
2060
2074
|
consumer = void 0;
|
|
2061
2075
|
let drained = false;
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2076
|
+
let drainFailure;
|
|
2077
|
+
const graceful = active.close().then(
|
|
2078
|
+
() => {
|
|
2079
|
+
drained = true;
|
|
2080
|
+
},
|
|
2081
|
+
(error) => {
|
|
2082
|
+
drainFailure = error;
|
|
2083
|
+
}
|
|
2084
|
+
);
|
|
2085
|
+
const deadline = cancellableDelay(shutdownGraceMs);
|
|
2086
|
+
try {
|
|
2087
|
+
await Promise.race([graceful, deadline.elapsed]);
|
|
2088
|
+
} finally {
|
|
2089
|
+
deadline.cancel();
|
|
2090
|
+
}
|
|
2066
2091
|
if (!drained) {
|
|
2067
2092
|
for (const runId of inFlight) control.abort(runId, "cancel");
|
|
2068
2093
|
await graceful;
|
|
2094
|
+
await Promise.allSettled([...running]);
|
|
2095
|
+
}
|
|
2096
|
+
if (drainFailure !== void 0) {
|
|
2097
|
+
deps.logger.warn("Run queue did not close cleanly during shutdown", {
|
|
2098
|
+
error: drainFailure instanceof Error ? drainFailure.message : String(drainFailure)
|
|
2099
|
+
});
|
|
2069
2100
|
}
|
|
2070
2101
|
}
|
|
2071
2102
|
};
|
|
@@ -2315,6 +2346,8 @@ function createGraphInvokeHandler(deps, options = {}) {
|
|
|
2315
2346
|
}
|
|
2316
2347
|
export {
|
|
2317
2348
|
DEFAULT_INVOKE_PREFIX,
|
|
2349
|
+
DEFAULT_RUN_CONCURRENCY,
|
|
2350
|
+
DEFAULT_SHUTDOWN_GRACE_MS,
|
|
2318
2351
|
SSE_HEADERS,
|
|
2319
2352
|
SkeinBaseStore,
|
|
2320
2353
|
buildProtocolService,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skein-js/agent-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Framework-agnostic Agent Protocol engine for LangGraph.js — run engine, handlers, and SSE, driven entirely by injected dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Maina Wycliffe <wmmaina7@gmail.com>",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
32
32
|
"types": "./dist/index.d.ts",
|
|
33
|
-
"import": "./dist/index.js"
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"default": "./dist/index.js"
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
37
|
"files": [
|
|
@@ -44,14 +45,14 @@
|
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
47
|
"zod": "^3.25.76",
|
|
47
|
-
"@skein-js/core": "0.
|
|
48
|
+
"@skein-js/core": "0.10.0"
|
|
48
49
|
},
|
|
49
50
|
"peerDependencies": {
|
|
50
51
|
"@langchain/langgraph": "^1.4.0",
|
|
51
52
|
"@langchain/langgraph-sdk": "^1.9.0"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"@skein-js/storage-memory": "0.
|
|
55
|
+
"@skein-js/storage-memory": "0.10.0"
|
|
55
56
|
},
|
|
56
57
|
"publishConfig": {
|
|
57
58
|
"access": "public"
|