@skein-js/agent-protocol 0.6.3 → 0.8.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 CHANGED
@@ -101,7 +101,7 @@ Graph **state, history, and interrupt/resume are 100% LangGraph-native** via the
101
101
  ## API
102
102
 
103
103
  - **Entry points:** `createProtocolRuntime(deps, options?)` → `{ service, handlers, worker }`;
104
- `createProtocolService` / `buildProtocolService`; `createProtocolHandlers`; `createContext`;
104
+ `createProtocolService` / `createProtocolServiceFromContext`; `createProtocolHandlers`; `createContext`;
105
105
  `createRunWorker(ctx, options?)` (`RunWorkerOptions`: `maxConcurrency`, `shutdownGraceMs`).
106
106
  - **Service surface** (`runtime.service`): `assistants` (`registerGraphAssistants`, `get`, `list`,
107
107
  `search`, `schemas`), `threads` (`create`/`get`/`list`/`patch`/`delete`/`history`/`getState`),
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GraphSchema, SkeinStore, RunQueue, RunEventBus, AuthEngine, AuthUser, Metadata, Thread, ThreadSearchQuery, ThreadState, Assistant, AssistantSearchQuery, AssistantCreate, AssistantUpdate, AssistantVersionsQuery, AssistantVersion, AssistantGraph, Config, StreamMode, MultitaskStrategy, RunFrame, DefaultValues, Run, RunStatus, StorePutOptions, Item, StoreSearchQuery, SearchItem, StoreRepo } from '@skein-js/core';
1
+ import { GraphSchema, SkeinStore, RunQueue, RunEventBus, AuthEngine, AuthUser, Metadata, Thread, ThreadSearchQuery, ThreadState, Checkpoint, Assistant, AssistantSearchQuery, AssistantCreate, AssistantUpdate, AssistantVersionsQuery, AssistantVersion, AssistantGraph, Config, StreamMode, MultitaskStrategy, RunFrame, DefaultValues, Run, RunStatus, StorePutOptions, Item, StoreSearchQuery, SearchItem, StoreRepo } from '@skein-js/core';
2
2
  import { CompiledGraph, BaseCheckpointSaver, BaseStore, Item as Item$1, Operation, OperationResults } from '@langchain/langgraph';
3
3
 
4
4
  /** A factory export: called (optionally with per-run config) to produce a compiled graph. */
@@ -184,6 +184,17 @@ interface PatchThreadInput {
184
184
  interface HistoryOptions {
185
185
  limit?: number;
186
186
  }
187
+ /** Body of `POST /threads/{id}/state` — a time-travel update that forks a new checkpoint. */
188
+ interface UpdateStateInput {
189
+ /** New state to write. `null`/`undefined` re-points `next` without changing values. */
190
+ values?: unknown;
191
+ /** Attribute the update as though this node produced `values` (sets up which node runs next). */
192
+ as_node?: string;
193
+ /** The checkpoint to fork from; omitted updates the thread tip. */
194
+ checkpoint_id?: string;
195
+ /** Full checkpoint pointer to fork from (alternative to `checkpoint_id`). */
196
+ checkpoint?: Record<string, unknown>;
197
+ }
187
198
  interface ThreadService {
188
199
  create(input?: CreateThreadInput): Promise<Thread>;
189
200
  get(threadId: string): Promise<Thread>;
@@ -197,6 +208,15 @@ interface ThreadService {
197
208
  history(threadId: string, options?: HistoryOptions): Promise<ThreadState[]>;
198
209
  /** The thread's current state snapshot — `GET /threads/{id}/state`, what `useStream` hydrates from. */
199
210
  getState(threadId: string): Promise<ThreadState>;
211
+ /** State at a specific checkpoint (time travel) — `GET /threads/{id}/state/{checkpoint_id}`. */
212
+ getStateAt(threadId: string, checkpointId: string): Promise<ThreadState>;
213
+ /**
214
+ * Update (fork) thread state at a checkpoint — `POST /threads/{id}/state`. Writes a new checkpoint
215
+ * via `graph.updateState`, mirrors it onto the thread row, and returns the new checkpoint pointer.
216
+ */
217
+ updateState(threadId: string, input: UpdateStateInput): Promise<{
218
+ checkpoint: Checkpoint;
219
+ }>;
200
220
  }
201
221
 
202
222
  /** `POST /assistants` — create input plus LangGraph's `if_exists` conflict policy. */
@@ -266,6 +286,8 @@ interface CreateRunInput {
266
286
  interrupt_after?: string[] | "*";
267
287
  /** Absolute `http(s)` URL POSTed with the settled run once it reaches a terminal status. */
268
288
  webhook?: string;
289
+ /** Time travel: fork this run from a prior checkpoint instead of the thread tip (server-validated). */
290
+ checkpoint_id?: string;
269
291
  }
270
292
  /** A started streaming run: its id, plus the live frame iterable to serialize as SSE. */
271
293
  interface StartedStream {
@@ -331,10 +353,16 @@ interface ProtocolService {
331
353
  store: StoreService;
332
354
  }
333
355
  /** Assemble the service over an existing context (used by the runtime to share the context). */
334
- declare function buildProtocolService(ctx: ProtocolContext): ProtocolService;
356
+ declare function createProtocolServiceFromContext(ctx: ProtocolContext): ProtocolService;
335
357
  /** Build the service with its own context. Use {@link createProtocolRuntime} when you also run a
336
358
  * background worker in the same process, so cancellation is shared. */
337
359
  declare function createProtocolService(deps: ProtocolDeps): ProtocolService;
360
+ /**
361
+ * @deprecated Renamed to {@link createProtocolServiceFromContext} — it builds the service over an
362
+ * existing `ProtocolContext` (vs {@link createProtocolService}, which takes `deps` and makes its own).
363
+ * Kept for back-compat; slated for removal in a future major.
364
+ */
365
+ declare const buildProtocolService: typeof createProtocolServiceFromContext;
338
366
 
339
367
  /** A normalized request an adapter maps its framework request onto. */
340
368
  interface ProtocolRequest {
@@ -381,6 +409,8 @@ interface ProtocolHandlers {
381
409
  deleteThread: ProtocolHandler;
382
410
  getThreadHistory: ProtocolHandler;
383
411
  getThreadState: ProtocolHandler;
412
+ getThreadStateAtCheckpoint: ProtocolHandler;
413
+ updateThreadState: ProtocolHandler;
384
414
  createWaitRun: ProtocolHandler;
385
415
  createStreamRun: ProtocolHandler;
386
416
  createBackgroundRun: ProtocolHandler;
@@ -414,12 +444,18 @@ interface RunWorker {
414
444
  }
415
445
  declare function createRunWorker(ctx: ProtocolContext, options?: RunWorkerOptions): RunWorker;
416
446
 
447
+ /** Options for {@link createProtocolRuntime}. */
417
448
  interface ProtocolRuntimeOptions {
449
+ /** Tuning for the background run worker (concurrency, poll interval). */
418
450
  worker?: RunWorkerOptions;
419
451
  }
452
+ /** The wired engine: the service, the transport-neutral handler table, and the background worker. */
420
453
  interface ProtocolRuntime {
454
+ /** High-level operations over assistants / threads / runs / store (used to seed assistants). */
421
455
  service: ProtocolService;
456
+ /** The transport-neutral HTTP handler table an adapter dispatches requests into. */
422
457
  handlers: ProtocolHandlers;
458
+ /** The background worker that drains the run queue; `start()` it after seeding assistants. */
423
459
  worker: RunWorker;
424
460
  }
425
461
  /**
@@ -448,9 +484,14 @@ declare const skeinRoutes: readonly RouteBinding[];
448
484
  /**
449
485
  * Copy the path `thread_id` into an object body so a stateless run handler runs on the right thread.
450
486
  * A no-op when there is no `thread_id` param. Used by every adapter for the `foldThreadIdIntoBody`
451
- * routes, so the folding rule lives in one place.
487
+ * routes, so this rule lives in one place.
488
+ */
489
+ declare function copyThreadIdIntoBody(request: ProtocolRequest): ProtocolRequest;
490
+ /**
491
+ * @deprecated Renamed to {@link copyThreadIdIntoBody} — it copies the path `thread_id` into the
492
+ * request body. Kept for back-compat; slated for removal in a future major.
452
493
  */
453
- declare function foldThreadId(request: ProtocolRequest): ProtocolRequest;
494
+ declare const foldThreadId: typeof copyThreadIdIntoBody;
454
495
  /** A resolved route: the matched binding plus the path params extracted from the URL. */
455
496
  interface RouteMatch {
456
497
  binding: RouteBinding;
@@ -518,4 +559,4 @@ declare function toSseEvents(frames: AsyncIterable<RunFrame>, finalStatus: () =>
518
559
  */
519
560
  declare function parseAfterSeq(lastEventId: string | undefined): number;
520
561
 
521
- export { type AssistantService, type Clock, type CommandInput, type CompiledGraphFactory, type CreateAssistantInput, type CreateRunInput, type CreateThreadInput, type DeleteAssistantOptions, type DrawGraphOptions, 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 RunService, type RunWorker, type RunWorkerOptions, SSE_HEADERS, SkeinBaseStore, type StartedStream, type StoreService, type SubgraphsOptions, type ThreadService, type ThreadStreamInput, type ThreadStreamService, buildProtocolService, createContext, createProtocolHandlers, createProtocolRuntime, createProtocolService, createRunWorker, encodeFrame, encodeTerminal, foldThreadId, matchSkeinRoute, parseAfterSeq, skeinRoutes, toSseEvents };
562
+ export { type AssistantService, type Clock, type CommandInput, type CompiledGraphFactory, type CreateAssistantInput, type CreateRunInput, type CreateThreadInput, type DeleteAssistantOptions, type DrawGraphOptions, 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 RunService, type RunWorker, type RunWorkerOptions, SSE_HEADERS, SkeinBaseStore, type StartedStream, type StoreService, type SubgraphsOptions, type ThreadService, type ThreadStreamInput, type ThreadStreamService, buildProtocolService, copyThreadIdIntoBody, createContext, createProtocolHandlers, createProtocolRuntime, createProtocolService, createProtocolServiceFromContext, createRunWorker, encodeFrame, encodeTerminal, foldThreadId, matchSkeinRoute, parseAfterSeq, skeinRoutes, toSseEvents };
package/dist/index.js CHANGED
@@ -64,6 +64,11 @@ var streamModeSchema = z.union([z.string(), z.array(z.string())]);
64
64
  var configSchema = z.record(z.unknown());
65
65
  var multitaskStrategySchema = z.enum(["reject", "interrupt", "rollback", "enqueue"]);
66
66
  var interruptWhenSchema = z.union([z.array(z.string()), z.literal("*")]);
67
+ var checkpointSchema = z.object({
68
+ checkpoint_id: z.string().optional(),
69
+ checkpoint_ns: z.string().nullish(),
70
+ checkpoint_map: z.record(z.unknown()).nullish()
71
+ });
67
72
  var runCreateSchema = z.object({
68
73
  assistant_id: z.string().min(1),
69
74
  thread_id: z.string().min(1).optional(),
@@ -77,7 +82,21 @@ var runCreateSchema = z.object({
77
82
  interrupt_before: interruptWhenSchema.optional(),
78
83
  interrupt_after: interruptWhenSchema.optional(),
79
84
  /** Run-completion webhook: an absolute `http(s)` URL POSTed the settled run when it finishes. */
80
- webhook: z.string().url().optional()
85
+ webhook: z.string().url().optional(),
86
+ /** Time travel: fork this run from a prior checkpoint instead of the thread tip. */
87
+ checkpoint_id: z.string().optional(),
88
+ /** Time travel: full checkpoint pointer to fork from (its `checkpoint_id` is what matters). */
89
+ checkpoint: checkpointSchema.optional()
90
+ }).passthrough();
91
+ var threadStateUpdateSchema = z.object({
92
+ /** New state to write. `null` re-points `next` without changing values; an array is a bulk write. */
93
+ values: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).nullish(),
94
+ /** Attribute the update as though this node produced `values` (sets up which node runs next). */
95
+ as_node: z.string().optional(),
96
+ /** The checkpoint to fork from; omitted updates the thread tip. */
97
+ checkpoint_id: z.string().optional(),
98
+ /** Full checkpoint pointer to fork from (alternative to `checkpoint_id`). */
99
+ checkpoint: checkpointSchema.nullish()
81
100
  }).passthrough();
82
101
  var threadStreamSchema = z.object({
83
102
  assistant_id: z.string().min(1),
@@ -321,6 +340,23 @@ function createProtocolHandlers(service) {
321
340
  return json(await service.threads.history(requireParam(req.params, "thread_id"), options));
322
341
  },
323
342
  getThreadState: async (req) => json(await service.threads.getState(requireParam(req.params, "thread_id"))),
343
+ getThreadStateAtCheckpoint: async (req) => json(
344
+ await service.threads.getStateAt(
345
+ requireParam(req.params, "thread_id"),
346
+ requireParam(req.params, "checkpoint_id")
347
+ )
348
+ ),
349
+ updateThreadState: async (req) => {
350
+ const body = parse(threadStateUpdateSchema, req.body ?? {});
351
+ return json(
352
+ await service.threads.updateState(requireParam(req.params, "thread_id"), {
353
+ values: body.values,
354
+ as_node: body.as_node,
355
+ checkpoint_id: body.checkpoint_id,
356
+ checkpoint: body.checkpoint ?? void 0
357
+ })
358
+ );
359
+ },
324
360
  // --- runs ---------------------------------------------------------------------------------
325
361
  createWaitRun: async (req) => json(await service.runs.createWait(parse(runCreateSchema, req.body))),
326
362
  createStreamRun: async (req) => {
@@ -990,10 +1026,15 @@ function toFactoryConfigurable(kwargs) {
990
1026
  }
991
1027
  function toGraphCallOptions(kwargs, threadId, signal) {
992
1028
  const options = {
993
- // Drop server-owned keys from the client's configurable, force this thread's id, then stamp the
994
- // authenticated caller so the graph can authorize off `configurable.langgraph_auth_user`.
1029
+ // Drop server-owned keys from the client's configurable, force this thread's id, add the
1030
+ // server-owned time-travel fork target (if any) *after* sanitizing so the client can never spoof
1031
+ // it, then stamp the authenticated caller so the graph can authorize off `langgraph_auth_user`.
995
1032
  configurable: withAuthUser(
996
- { ...sanitizeConfigurable(kwargs.config?.configurable), thread_id: threadId },
1033
+ {
1034
+ ...sanitizeConfigurable(kwargs.config?.configurable),
1035
+ thread_id: threadId,
1036
+ ...kwargs.checkpoint_id !== void 0 ? { checkpoint_id: kwargs.checkpoint_id } : {}
1037
+ },
997
1038
  kwargs.auth_user,
998
1039
  kwargs.auth_scopes
999
1040
  ),
@@ -1334,6 +1375,7 @@ function toKwargs(input, authUser, authScopes) {
1334
1375
  if (input.interrupt_before !== void 0) kwargs.interrupt_before = input.interrupt_before;
1335
1376
  if (input.interrupt_after !== void 0) kwargs.interrupt_after = input.interrupt_after;
1336
1377
  if (input.webhook !== void 0) kwargs.webhook = input.webhook;
1378
+ if (input.checkpoint_id !== void 0) kwargs.checkpoint_id = input.checkpoint_id;
1337
1379
  if (authUser !== void 0) {
1338
1380
  kwargs.auth_user = authUser;
1339
1381
  if (authScopes !== void 0) kwargs.auth_scopes = authScopes;
@@ -1554,13 +1596,13 @@ function createThreadService(ctx) {
1554
1596
  if (!thread) throw SkeinHttpError7.notFound(`Thread "${threadId}" not found.`);
1555
1597
  return thread;
1556
1598
  };
1557
- const readHistory = async (threadId, options) => {
1599
+ const loadThreadGraph = async (threadId) => {
1558
1600
  await requireThread(threadId);
1559
1601
  const runs = await deps.store.runs.listByThread(threadId);
1560
1602
  const latest = [...runs].sort((a, b) => b.created_at.localeCompare(a.created_at))[0];
1561
- if (!latest) return [];
1603
+ if (!latest) return void 0;
1562
1604
  const assistant = await deps.store.assistants.get(latest.assistant_id);
1563
- if (!assistant) return [];
1605
+ if (!assistant) return void 0;
1564
1606
  const resolved = await deps.graphs.load(assistant.graph_id);
1565
1607
  let graph;
1566
1608
  if (typeof resolved === "function") {
@@ -1570,6 +1612,11 @@ function createThreadService(ctx) {
1570
1612
  graph = resolved;
1571
1613
  }
1572
1614
  graph.checkpointer = deps.checkpointer;
1615
+ return graph;
1616
+ };
1617
+ const readHistory = async (threadId, options) => {
1618
+ const graph = await loadThreadGraph(threadId);
1619
+ if (!graph) return [];
1573
1620
  const states = [];
1574
1621
  const limit = options?.limit;
1575
1622
  for await (const snapshot of graph.getStateHistory({
@@ -1626,6 +1673,45 @@ function createThreadService(ctx) {
1626
1673
  async getState(threadId) {
1627
1674
  const [current] = await readHistory(threadId, { limit: 1 });
1628
1675
  return current ?? emptyThreadState(threadId);
1676
+ },
1677
+ async getStateAt(threadId, checkpointId) {
1678
+ const graph = await loadThreadGraph(threadId);
1679
+ if (!graph) return emptyThreadState(threadId);
1680
+ const snapshot = await graph.getState({
1681
+ configurable: { thread_id: threadId, checkpoint_ns: "", checkpoint_id: checkpointId }
1682
+ });
1683
+ return snapshotToThreadState(snapshot);
1684
+ },
1685
+ async updateState(threadId, input) {
1686
+ const graph = await loadThreadGraph(threadId);
1687
+ if (!graph) {
1688
+ throw SkeinHttpError7.unprocessable(`Thread "${threadId}" has no graph to update state on.`);
1689
+ }
1690
+ if (await deps.store.runs.hasActiveRun(threadId)) {
1691
+ throw SkeinHttpError7.conflict(
1692
+ `Thread "${threadId}" is busy; wait for its active run to finish before updating state.`
1693
+ );
1694
+ }
1695
+ const configurable = {
1696
+ checkpoint_ns: "",
1697
+ ...input.checkpoint ?? {},
1698
+ ...input.checkpoint_id !== void 0 ? { checkpoint_id: input.checkpoint_id } : {},
1699
+ thread_id: threadId
1700
+ };
1701
+ const nextConfig = await graph.updateState({ configurable }, input.values, input.as_node);
1702
+ const snapshot = await graph.getState({ configurable: { thread_id: threadId } });
1703
+ await deps.store.threads.update(
1704
+ threadId,
1705
+ snapshotToThreadUpdate(snapshot, runStatusForSnapshot(snapshot))
1706
+ );
1707
+ const next = nextConfig.configurable ?? {};
1708
+ const checkpoint = {
1709
+ thread_id: threadId,
1710
+ checkpoint_ns: next["checkpoint_ns"] ?? "",
1711
+ checkpoint_id: next["checkpoint_id"],
1712
+ checkpoint_map: next["checkpoint_map"]
1713
+ };
1714
+ return { checkpoint };
1629
1715
  }
1630
1716
  };
1631
1717
  }
@@ -1692,7 +1778,7 @@ function createThreadStreamService(ctx, runs) {
1692
1778
  }
1693
1779
 
1694
1780
  // src/service.ts
1695
- function buildProtocolService(ctx) {
1781
+ function createProtocolServiceFromContext(ctx) {
1696
1782
  const runs = createRunService(ctx);
1697
1783
  const threads = createThreadService(ctx);
1698
1784
  return {
@@ -1707,8 +1793,9 @@ function buildProtocolService(ctx) {
1707
1793
  };
1708
1794
  }
1709
1795
  function createProtocolService(deps) {
1710
- return buildProtocolService(createContext(deps));
1796
+ return createProtocolServiceFromContext(createContext(deps));
1711
1797
  }
1798
+ var buildProtocolService = createProtocolServiceFromContext;
1712
1799
 
1713
1800
  // src/auth/auth-scoped-store.ts
1714
1801
  import {
@@ -1827,9 +1914,12 @@ var ROUTE_AUTHZ = {
1827
1914
  copyThread: { resource: "threads", action: "create" },
1828
1915
  getThread: { resource: "threads", action: "read" },
1829
1916
  getThreadState: { resource: "threads", action: "read" },
1917
+ getThreadStateAtCheckpoint: { resource: "threads", action: "read" },
1830
1918
  getThreadHistory: { resource: "threads", action: "read" },
1831
1919
  listThreads: { resource: "threads", action: "search" },
1832
1920
  patchThread: { resource: "threads", action: "update" },
1921
+ // Time-travel state update forks a checkpoint — a write, so read-only principals can't fork.
1922
+ updateThreadState: { resource: "threads", action: "update" },
1833
1923
  deleteThread: { resource: "threads", action: "delete" },
1834
1924
  // runs (authorized through the owning thread)
1835
1925
  createWaitRun: { resource: "threads", action: "create_run" },
@@ -1878,7 +1968,7 @@ var STUDIO_USER = {
1878
1968
  permissions: []
1879
1969
  };
1880
1970
  function createAuthorizingHandlers(context, engine) {
1881
- const baseHandlers = createProtocolHandlers(buildProtocolService(context));
1971
+ const baseHandlers = createProtocolHandlers(createProtocolServiceFromContext(context));
1882
1972
  const names = Object.keys(ROUTE_AUTHZ);
1883
1973
  const resolveAuthContext = async (req) => {
1884
1974
  if (!engine.studioAuthDisabled && req.headers["x-auth-scheme"] === "langsmith") {
@@ -1907,7 +1997,7 @@ function createAuthorizingHandlers(context, engine) {
1907
1997
  store: createAuthScopedStore(context.deps.store, engine, filters, route.resource)
1908
1998
  } : context.deps
1909
1999
  };
1910
- return createProtocolHandlers(buildProtocolService(requestContext))[name](req);
2000
+ return createProtocolHandlers(createProtocolServiceFromContext(requestContext))[name](req);
1911
2001
  };
1912
2002
  }
1913
2003
  return wrapped;
@@ -1977,7 +2067,7 @@ function createRunWorker(ctx, options = {}) {
1977
2067
  // src/runtime.ts
1978
2068
  function createProtocolRuntime(deps, options = {}) {
1979
2069
  const context = createContext(deps);
1980
- const service = buildProtocolService(context);
2070
+ const service = createProtocolServiceFromContext(context);
1981
2071
  const handlers = deps.auth ? createAuthorizingHandlers(context, deps.auth) : createProtocolHandlers(service);
1982
2072
  return {
1983
2073
  service,
@@ -2017,6 +2107,12 @@ var skeinRoutes = [
2017
2107
  { method: "patch", path: "/threads/:thread_id", handler: "patchThread" },
2018
2108
  { method: "delete", path: "/threads/:thread_id", handler: "deleteThread" },
2019
2109
  { method: "get", path: "/threads/:thread_id/state", handler: "getThreadState" },
2110
+ { method: "post", path: "/threads/:thread_id/state", handler: "updateThreadState" },
2111
+ {
2112
+ method: "get",
2113
+ path: "/threads/:thread_id/state/:checkpoint_id",
2114
+ handler: "getThreadStateAtCheckpoint"
2115
+ },
2020
2116
  { method: "post", path: "/threads/:thread_id/history", handler: "getThreadHistory" },
2021
2117
  // runs — the stateless handlers are reused on the thread-scoped path with the id folded in
2022
2118
  { method: "post", path: "/runs/wait", handler: "createWaitRun" },
@@ -2051,12 +2147,13 @@ var skeinRoutes = [
2051
2147
  { method: "post", path: "/store/items/search", handler: "searchStoreItems" },
2052
2148
  { method: "post", path: "/store/namespaces", handler: "listStoreNamespaces" }
2053
2149
  ];
2054
- function foldThreadId(request) {
2150
+ function copyThreadIdIntoBody(request) {
2055
2151
  const threadId = request.params["thread_id"];
2056
2152
  if (threadId === void 0) return request;
2057
2153
  const base = typeof request.body === "object" && request.body !== null && !Array.isArray(request.body) ? request.body : {};
2058
2154
  return { ...request, body: { ...base, thread_id: threadId } };
2059
2155
  }
2156
+ var foldThreadId = copyThreadIdIntoBody;
2060
2157
  var compiledRoutes = skeinRoutes.map((binding) => ({
2061
2158
  binding,
2062
2159
  regex: new RegExp(`^${binding.path.replace(/:(\w+)/g, "(?<$1>[^/]+)")}$`)
@@ -2085,10 +2182,12 @@ export {
2085
2182
  SSE_HEADERS,
2086
2183
  SkeinBaseStore,
2087
2184
  buildProtocolService,
2185
+ copyThreadIdIntoBody,
2088
2186
  createContext,
2089
2187
  createProtocolHandlers,
2090
2188
  createProtocolRuntime,
2091
2189
  createProtocolService,
2190
+ createProtocolServiceFromContext,
2092
2191
  createRunWorker,
2093
2192
  encodeFrame,
2094
2193
  encodeTerminal,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skein-js/agent-protocol",
3
- "version": "0.6.3",
3
+ "version": "0.8.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>",
@@ -44,14 +44,14 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "zod": "^3.25.76",
47
- "@skein-js/core": "0.6.3"
47
+ "@skein-js/core": "0.8.0"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@langchain/langgraph": "^1.4.0",
51
51
  "@langchain/langgraph-sdk": "^1.9.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@skein-js/storage-memory": "0.6.3"
54
+ "@skein-js/storage-memory": "0.8.0"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public"