@skein-js/server-kit 0.9.1 → 0.11.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/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ProtocolRuntime, ProtocolDeps, Logger, RunWorkerOptions, GraphResolver, ProtocolResponse } from '@skein-js/agent-protocol';
2
- export { CompiledGraphFactory, DEFAULT_RUN_CONCURRENCY, GraphResolver, ProtocolDeps, ResolvedGraph, RunWorkerOptions } from '@skein-js/agent-protocol';
3
- import { ModuleImporter, GraphSchemas } from '@skein-js/config';
2
+ export { CompiledGraphFactory, DEFAULT_RUN_CONCURRENCY, DEFAULT_SHUTDOWN_GRACE_MS, GraphResolver, ProtocolDeps, ResolvedGraph, RunWorkerOptions } from '@skein-js/agent-protocol';
3
+ import { ModuleImporter, LanggraphJson, GraphSchemas } from '@skein-js/config';
4
4
  import { CorsOptions } from 'cors';
5
5
  export { CorsOptions } from 'cors';
6
6
  import { MemoryStoreSnapshot } from '@skein-js/storage-memory';
@@ -33,6 +33,11 @@ interface SkeinRuntimeCommonOptions {
33
33
  * engine's execution lock — but see the head-of-line note in docs/runs-and-redis.md if your workload
34
34
  * leans on `multitask_strategy: "enqueue"`. Ignored by the invoke-only surface, which starts no
35
35
  * worker.
36
+ *
37
+ * `shutdownGraceMs` is how long `worker.stop()` lets in-flight runs finish before aborting them
38
+ * (default `DEFAULT_SHUTDOWN_GRACE_MS`); omit it and skein reads `SKEIN_SHUTDOWN_GRACE_MS`, with
39
+ * the same explicit-wins-but-still-validated rule. Whatever forces the process to exit must wait
40
+ * longer than this, or the abort step never runs — see docs/deploy.md.
36
41
  */
37
42
  worker?: RunWorkerOptions;
38
43
  }
@@ -90,6 +95,20 @@ declare function resolveProtocolRuntime(options: SkeinRuntimeOptions): Promise<R
90
95
  */
91
96
  declare function resolveRunConcurrency(explicit?: number, env?: NodeJS.ProcessEnv): number;
92
97
 
98
+ /**
99
+ * The one precedence chain for the shutdown drain window: an explicit `worker.shutdownGraceMs` wins,
100
+ * else `SKEIN_SHUTDOWN_GRACE_MS`, else {@link DEFAULT_SHUTDOWN_GRACE_MS}. The environment is read and
101
+ * validated even when `explicit` is given, so a bad value can't sit unnoticed in a deployment that
102
+ * also passes the option.
103
+ *
104
+ * Zero is allowed and means "abort in-flight runs immediately" — a legitimate choice for a fleet that
105
+ * relies on queue redelivery instead of draining.
106
+ *
107
+ * `env` is injected (defaulting to `process.env`) so callers — and tests — can resolve against an
108
+ * environment they control.
109
+ */
110
+ declare function resolveShutdownGraceMs(explicit?: number, env?: NodeJS.ProcessEnv): number;
111
+
93
112
  /** The checkpoint tuple `[checkpoint, metadata, parentId?]` with the blobs base64-encoded. */
94
113
  type SerializedCheckpointTuple = [string, string, string | undefined];
95
114
  /** `MemorySaver.storage` (thread → namespace → checkpointId → tuple) with blobs base64-encoded. */
@@ -116,6 +135,13 @@ interface InMemoryRuntimeConfig {
116
135
  /** Load `langgraph.json`, wiring fresh in-memory drivers and reading its `http.cors` for the adapter. */
117
136
  declare function loadInMemoryRuntime(configPath: string, importModule?: ModuleImporter, staticSchemas?: Record<string, GraphSchemas>): Promise<InMemoryRuntimeConfig>;
118
137
  interface ReloadableInMemoryRuntime extends InMemoryRuntimeConfig {
138
+ /**
139
+ * The parsed `langgraph.json`, so a caller that needs a block this runtime doesn't act on itself
140
+ * (`telemetry`, say) can read it without a second `loadConfig` — which would re-import every graph.
141
+ */
142
+ config: LanggraphJson;
143
+ /** Directory holding `langgraph.json`, for resolving paths declared relative to it. */
144
+ configDir: string;
119
145
  /**
120
146
  * Re-read the config and swap in freshly imported graphs, keeping the same drivers. Because the
121
147
  * run engine calls `graphs.load()` per run (it never caches the compiled graph itself), the next
@@ -134,7 +160,14 @@ interface ReloadableInMemoryRuntime extends InMemoryRuntimeConfig {
134
160
  * dev` pairs this with vite's watcher (clear vite's cache, then `reloadGraphs()` — no server
135
161
  * restart, no lost state) and with on-disk JSON persistence across restarts.
136
162
  */
137
- declare function loadReloadableInMemoryRuntime(configPath: string, importModule?: ModuleImporter, staticSchemas?: Record<string, GraphSchemas>): Promise<ReloadableInMemoryRuntime>;
163
+ declare function loadReloadableInMemoryRuntime(configPath: string, importModule?: ModuleImporter, staticSchemas?: Record<string, GraphSchemas>,
164
+ /**
165
+ * Extra deps to build in, for a caller that acts on a config block this runtime doesn't itself
166
+ * read (`telemetry`). Merged **into** the constructed `deps`, so every consumer sees the same
167
+ * object — patching the returned `deps` afterwards would miss anything that already snapshotted it
168
+ * (`resolveDeps` spreads, it doesn't alias).
169
+ */
170
+ extraDeps?: Partial<Omit<ProtocolDeps, "graphs">>): Promise<ReloadableInMemoryRuntime>;
138
171
 
139
172
  type AnyCompiledGraph = CompiledGraph<any>;
140
173
  /**
@@ -259,4 +292,4 @@ declare function sendNodeError(error: unknown, res: ServerResponse, logger?: Log
259
292
  */
260
293
  declare function stripBasePath(pathname: string, basePath: string): string | null;
261
294
 
262
- export { type CorsSetting, type DevStateCounts, type DevStateSnapshot, type EmbeddableGraph, type InMemoryRuntimeConfig, type LanggraphCorsConfig, type ReloadableInMemoryRuntime, type ResolvedProtocolRuntime, type ResolvedRuntimeDeps, type SkeinRuntimeCommonOptions, type SkeinRuntimeOptions, allowedOrigin, applyNodeCors, corsFromHttpConfig, corsPreflightHeaders, corsResponseHeaders, createInMemoryDeps, describeSnapshot, embedInMemoryGraphs, graphMapToResolver, joinList, loadInMemoryRuntime, loadReloadableInMemoryRuntime, loadSnapshotIntoStore, normalizeEmbeddableGraphs, readLanggraphDevState, resolveProtocolRuntime, resolveRunConcurrency, resolveRuntimeDeps, sendNodeError, sendNodePreflight, sendNodeResponse, stripBasePath, toCorsOptions };
295
+ export { type CorsSetting, type DevStateCounts, type DevStateSnapshot, type EmbeddableGraph, type InMemoryRuntimeConfig, type LanggraphCorsConfig, type ReloadableInMemoryRuntime, type ResolvedProtocolRuntime, type ResolvedRuntimeDeps, type SkeinRuntimeCommonOptions, type SkeinRuntimeOptions, allowedOrigin, applyNodeCors, corsFromHttpConfig, corsPreflightHeaders, corsResponseHeaders, createInMemoryDeps, describeSnapshot, embedInMemoryGraphs, graphMapToResolver, joinList, loadInMemoryRuntime, loadReloadableInMemoryRuntime, loadSnapshotIntoStore, normalizeEmbeddableGraphs, readLanggraphDevState, resolveProtocolRuntime, resolveRunConcurrency, resolveRuntimeDeps, resolveShutdownGraceMs, sendNodeError, sendNodePreflight, sendNodeResponse, stripBasePath, toCorsOptions };
package/dist/index.js CHANGED
@@ -153,7 +153,7 @@ async function loadInMemoryRuntime(configPath, importModule, staticSchemas) {
153
153
  cors: corsFromHttpConfig(config.http)
154
154
  };
155
155
  }
156
- async function loadReloadableInMemoryRuntime(configPath, importModule, staticSchemas) {
156
+ async function loadReloadableInMemoryRuntime(configPath, importModule, staticSchemas, extraDeps) {
157
157
  const first = await loadConfig({ configPath, importModule, staticSchemas });
158
158
  let current = first.graphs;
159
159
  const graphs = {
@@ -169,11 +169,14 @@ async function loadReloadableInMemoryRuntime(configPath, importModule, staticSch
169
169
  queue: new MemoryRunQueue2(),
170
170
  bus: new MemoryRunEventBus2(),
171
171
  checkpointer,
172
- auth: await loadAuthEngine(first.config.auth, { configDir: first.configDir, importModule })
172
+ auth: await loadAuthEngine(first.config.auth, { configDir: first.configDir, importModule }),
173
+ ...extraDeps
173
174
  };
174
175
  return {
175
176
  deps,
176
177
  cors: corsFromHttpConfig(first.config.http),
178
+ config: first.config,
179
+ configDir: first.configDir,
177
180
  reloadGraphs: async () => {
178
181
  current = (await loadConfig({ configPath, importModule, staticSchemas })).graphs;
179
182
  },
@@ -214,6 +217,30 @@ function resolveRunConcurrency(explicit, env = process.env) {
214
217
  return requirePositiveInteger("worker.maxConcurrency", explicit);
215
218
  }
216
219
 
220
+ // src/shutdown-grace.ts
221
+ import { DEFAULT_SHUTDOWN_GRACE_MS } from "@skein-js/agent-protocol";
222
+ import { SkeinConfigError as SkeinConfigError2 } from "@skein-js/config";
223
+ var SHUTDOWN_GRACE_ENV_VAR = "SKEIN_SHUTDOWN_GRACE_MS";
224
+ function requireNonNegativeInteger(source, raw) {
225
+ const parsed = Number(raw);
226
+ if (!Number.isInteger(parsed) || parsed < 0) {
227
+ throw new SkeinConfigError2(
228
+ `${source} must be a non-negative integer in milliseconds (got "${String(raw)}").`
229
+ );
230
+ }
231
+ return parsed;
232
+ }
233
+ function shutdownGraceFromEnv(env) {
234
+ const raw = env[SHUTDOWN_GRACE_ENV_VAR];
235
+ if (raw === void 0 || raw.trim() === "") return void 0;
236
+ return requireNonNegativeInteger(SHUTDOWN_GRACE_ENV_VAR, raw);
237
+ }
238
+ function resolveShutdownGraceMs(explicit, env = process.env) {
239
+ const fromEnv = shutdownGraceFromEnv(env);
240
+ if (explicit === void 0) return fromEnv ?? DEFAULT_SHUTDOWN_GRACE_MS;
241
+ return requireNonNegativeInteger("worker.shutdownGraceMs", explicit);
242
+ }
243
+
217
244
  // src/resolve-runtime.ts
218
245
  async function resolveRuntimeDeps(options) {
219
246
  if (options.deps) return { deps: options.deps };
@@ -225,7 +252,8 @@ async function resolveProtocolRuntime(options) {
225
252
  const runtime = createProtocolRuntime(deps, {
226
253
  worker: {
227
254
  ...options.worker,
228
- maxConcurrency: resolveRunConcurrency(options.worker?.maxConcurrency)
255
+ maxConcurrency: resolveRunConcurrency(options.worker?.maxConcurrency),
256
+ shutdownGraceMs: resolveShutdownGraceMs(options.worker?.shutdownGraceMs)
229
257
  }
230
258
  });
231
259
  await runtime.service.assistants.registerGraphAssistants();
@@ -244,6 +272,7 @@ async function resolveProtocolRuntime(options) {
244
272
 
245
273
  // src/index.ts
246
274
  import { DEFAULT_RUN_CONCURRENCY as DEFAULT_RUN_CONCURRENCY2 } from "@skein-js/agent-protocol";
275
+ import { DEFAULT_SHUTDOWN_GRACE_MS as DEFAULT_SHUTDOWN_GRACE_MS2 } from "@skein-js/agent-protocol";
247
276
 
248
277
  // src/langgraph-import.ts
249
278
  import { readFile } from "fs/promises";
@@ -685,6 +714,7 @@ function stripBasePath(pathname, basePath) {
685
714
  }
686
715
  export {
687
716
  DEFAULT_RUN_CONCURRENCY2 as DEFAULT_RUN_CONCURRENCY,
717
+ DEFAULT_SHUTDOWN_GRACE_MS2 as DEFAULT_SHUTDOWN_GRACE_MS,
688
718
  allowedOrigin,
689
719
  applyNodeCors,
690
720
  corsFromHttpConfig,
@@ -703,6 +733,7 @@ export {
703
733
  resolveProtocolRuntime,
704
734
  resolveRunConcurrency,
705
735
  resolveRuntimeDeps,
736
+ resolveShutdownGraceMs,
706
737
  sendNodeError,
707
738
  sendNodePreflight,
708
739
  sendNodeResponse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skein-js/server-kit",
3
- "version": "0.9.1",
3
+ "version": "0.11.1",
4
4
  "description": "Shared, framework-agnostic building blocks for skein-js HTTP adapters — in-memory dev runtime, LangGraph dev-state import, and langgraph.json CORS mapping.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Maina Wycliffe <wmmaina7@gmail.com>",
@@ -27,7 +27,8 @@
27
27
  "exports": {
28
28
  ".": {
29
29
  "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js"
30
+ "import": "./dist/index.js",
31
+ "default": "./dist/index.js"
31
32
  }
32
33
  },
33
34
  "files": [
@@ -43,10 +44,10 @@
43
44
  "cors": "^2.8.5",
44
45
  "superjson": "^2.2.6",
45
46
  "zod": "^3.25.76",
46
- "@skein-js/agent-protocol": "0.9.1",
47
- "@skein-js/core": "0.9.1",
48
- "@skein-js/storage-memory": "0.9.1",
49
- "@skein-js/config": "0.9.1"
47
+ "@skein-js/agent-protocol": "0.11.1",
48
+ "@skein-js/config": "0.11.1",
49
+ "@skein-js/core": "0.11.1",
50
+ "@skein-js/storage-memory": "0.11.1"
50
51
  },
51
52
  "peerDependencies": {
52
53
  "@langchain/langgraph": "^1.4.0"