@skein-js/agent-protocol 0.9.1 → 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/dist/index.d.ts CHANGED
@@ -441,6 +441,15 @@ declare function createProtocolHandlers(service: ProtocolService): ProtocolHandl
441
441
  * `--n-jobs-per-worker` default, so a project moving off `langgraph dev` keeps its throughput.
442
442
  */
443
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;
444
453
  interface RunWorkerOptions {
445
454
  /**
446
455
  * Max queued runs this worker executes at once. Default {@link DEFAULT_RUN_CONCURRENCY}.
@@ -450,7 +459,10 @@ interface RunWorkerOptions {
450
459
  * the worker. See docs/runs-and-redis.md.
451
460
  */
452
461
  maxConcurrency?: number;
453
- /** How long `stop()` waits for in-flight runs before aborting them (ms). Default 5000. */
462
+ /**
463
+ * How long `stop()` waits for in-flight runs before aborting them (ms). Default
464
+ * {@link DEFAULT_SHUTDOWN_GRACE_MS}.
465
+ */
454
466
  shutdownGraceMs?: number;
455
467
  }
456
468
  interface RunWorker {
@@ -613,4 +625,4 @@ declare function toSseEvents(frames: AsyncIterable<RunFrame>, finalStatus: () =>
613
625
  */
614
626
  declare function parseAfterSeq(lastEventId: string | undefined): number;
615
627
 
616
- export { type AssistantService, type Clock, type CommandInput, type CompiledGraphFactory, type CreateAssistantInput, type CreateRunInput, type CreateThreadInput, DEFAULT_INVOKE_PREFIX, DEFAULT_RUN_CONCURRENCY, 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
@@ -2015,7 +2015,14 @@ import {
2015
2015
  isTerminalRunStatus as isTerminalRunStatus6
2016
2016
  } from "@skein-js/core";
2017
2017
  var DEFAULT_RUN_CONCURRENCY = 10;
2018
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
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
+ }
2019
2026
  function logRunLifecycle(logger, run, status, startedAt, endedAt) {
2020
2027
  logger.info(status === "success" ? "Background run succeeded" : `Background run ${status}`, {
2021
2028
  run_id: run.run_id,
@@ -2030,9 +2037,15 @@ function logRunLifecycle(logger, run, status, startedAt, endedAt) {
2030
2037
  function createRunWorker(ctx, options = {}) {
2031
2038
  const { deps, control } = ctx;
2032
2039
  const maxConcurrency = options.maxConcurrency ?? DEFAULT_RUN_CONCURRENCY;
2033
- const shutdownGraceMs = options.shutdownGraceMs ?? 5e3;
2040
+ const shutdownGraceMs = options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS;
2034
2041
  const inFlight = /* @__PURE__ */ new Set();
2035
- const process = async (queued) => {
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) => {
2036
2049
  const run = await deps.store.runs.get(queued.run_id);
2037
2050
  if (!run || isTerminalRunStatus6(run.status)) {
2038
2051
  ctx.rollbackPlans.delete(queued.run_id);
@@ -2053,20 +2066,37 @@ function createRunWorker(ctx, options = {}) {
2053
2066
  return {
2054
2067
  start() {
2055
2068
  if (consumer) return;
2056
- consumer = deps.queue.consume(process, { concurrency: maxConcurrency });
2069
+ consumer = deps.queue.consume(executeQueuedRun, { concurrency: maxConcurrency });
2057
2070
  },
2058
2071
  async stop() {
2059
2072
  if (!consumer) return;
2060
2073
  const active = consumer;
2061
2074
  consumer = void 0;
2062
2075
  let drained = false;
2063
- const graceful = active.close().then(() => {
2064
- drained = true;
2065
- });
2066
- await Promise.race([graceful, sleep(shutdownGraceMs)]);
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
+ }
2067
2091
  if (!drained) {
2068
2092
  for (const runId of inFlight) control.abort(runId, "cancel");
2069
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
+ });
2070
2100
  }
2071
2101
  }
2072
2102
  };
@@ -2317,6 +2347,7 @@ function createGraphInvokeHandler(deps, options = {}) {
2317
2347
  export {
2318
2348
  DEFAULT_INVOKE_PREFIX,
2319
2349
  DEFAULT_RUN_CONCURRENCY,
2350
+ DEFAULT_SHUTDOWN_GRACE_MS,
2320
2351
  SSE_HEADERS,
2321
2352
  SkeinBaseStore,
2322
2353
  buildProtocolService,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skein-js/agent-protocol",
3
- "version": "0.9.1",
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.9.1"
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.9.1"
55
+ "@skein-js/storage-memory": "0.10.0"
55
56
  },
56
57
  "publishConfig": {
57
58
  "access": "public"