stitchkit 0.85.1 → 0.85.2

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/CHANGELOG.md CHANGED
@@ -15,6 +15,24 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.85.2] — 2026-09-08
19
+
20
+ ### Fixed
21
+
22
+ - **An asynchronous store no longer fails a run before the provider is
23
+ called.** The assistant checkpoint and the model-request admission are two
24
+ owned mutations of one run, written by two independent schedules — the stream
25
+ consumer and the SDK's model middleware — and each named the revision it read
26
+ before its own `await`. Where the store answered on a later tick (a worker, a
27
+ socket, a real database) the second write named a spent revision, the losing
28
+ compare-and-set threw out of `wrapStream`, and the run ended
29
+ `provider_failure` with zero provider calls; frequent checkpoints
30
+ (`checkpointEveryEvents: 1`) made it reliable. Owned mutations of a run now
31
+ take their turn in one per-run queue and read the revision inside that turn.
32
+ Independent runs are unaffected — the queue is per run — and fencing,
33
+ cancellation and checkpoint durability are unchanged. Proven on the packed
34
+ tarball by a consumer-lane fixture, not only in-repo. → ADR 0174 (amended).
35
+
18
36
  ## [0.85.1] — 2026-09-07
19
37
 
20
38
  ### Fixed
@@ -1 +1 @@
1
- {"version":3,"file":"run-execution.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/run-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AAMZ,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,UAAU,CAAC;AAEvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAI1D,OAAO,KAAK,EAAqB,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAavE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAKL,KAAK,QAAQ,EAOd,MAAM,WAAW,CAAC;AAuCnB,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB,CAAC,OAAO,EAAE,KAAK,SAAS,OAAO;IACrE,MAAM,EAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,IAAI,MAAM,CAAC;IACrB,GAAG,IAAI,IAAI,CAAC;IACZ,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,KAAK,SAAS,OAAO,EAC9D,YAAY,EAAE,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,WAcb;IACtC,WAAW,EAAE,QAAQ,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,UAAU,CAAC,IAAI,IAAI,CAAC;CACrB,KAAG,OAAO,CAAC,kBAAkB,CAAC,CAoiChC"}
1
+ {"version":3,"file":"run-execution.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/run-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AAMZ,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,UAAU,CAAC;AAEvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAK1D,OAAO,KAAK,EAAqB,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAavE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAKL,KAAK,QAAQ,EAOd,MAAM,WAAW,CAAC;AAuCnB,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB,CAAC,OAAO,EAAE,KAAK,SAAS,OAAO;IACrE,MAAM,EAAE,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,IAAI,MAAM,CAAC;IACrB,GAAG,IAAI,IAAI,CAAC;IACZ,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,KAAK,SAAS,OAAO,EAC9D,YAAY,EAAE,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,WAcb;IACtC,WAAW,EAAE,QAAQ,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,UAAU,CAAC,IAAI,IAAI,CAAC;CACrB,KAAG,OAAO,CAAC,kBAAkB,CAAC,CA8iChC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Owned mutations of one run, applied one at a time.
3
+ *
4
+ * Every owned mutation is a compare-and-set against the run's current revision,
5
+ * and the revision it must name is the one the previous mutation produced.
6
+ * Reading that revision and writing it back are therefore safe apart only while
7
+ * nothing else can write in between — which stops being true the moment a store
8
+ * returns a promise that yields. With an asynchronous store the assistant
9
+ * checkpoint and the model-request admission both name the revision they read
10
+ * before their own `await`, the later write is rejected as a conflict, and the
11
+ * run fails without the provider ever having been called.
12
+ *
13
+ * The terminal commit answers the same hazard with a bounded retry, which suits
14
+ * it: committing a terminal twice is a duplicate the store recognises. It does
15
+ * not suit these two — a retried operation write would publish a second
16
+ * lifecycle event for one provider call — so they take their turn instead.
17
+ */
18
+ export type RunMutationQueue = <T>(mutation: () => Promise<T>) => Promise<T>;
19
+ /** A queue of owned mutations for one run. */
20
+ export declare function createRunMutationQueue(): RunMutationQueue;
21
+ //# sourceMappingURL=run-mutation-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-mutation-queue.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/run-mutation-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7E,8CAA8C;AAC9C,wBAAgB,sBAAsB,IAAI,gBAAgB,CAgBzD"}
@@ -1,5 +1,6 @@
1
1
  import { type LanguageModel } from 'ai';
2
2
  import type { AgentRuntimeEvent } from './event-schema.js';
3
+ import type { RunMutationQueue } from './run-mutation-queue.js';
3
4
  import { type AgentRun, type AgentSnapshot } from './schemas.js';
4
5
  import type { AgentRuntimeStore } from './store.js';
5
6
  type TerminalOperationPhase = 'completed' | 'failed' | 'cancelled';
@@ -10,6 +11,8 @@ export interface AgentRunOperationLifecycleConfig {
10
11
  acceptSnapshot(snapshot: AgentSnapshot): void;
11
12
  publish(event: AgentRuntimeEvent): Promise<void>;
12
13
  now(): Date;
14
+ /** The order every owned mutation of this run takes its turn in. */
15
+ serialize: RunMutationQueue;
13
16
  }
14
17
  /** One durable latest-operation state machine for an executing run. */
15
18
  export declare function createAgentRunOperationLifecycle(config: AgentRunOperationLifecycleConfig): {
@@ -1 +1 @@
1
- {"version":3,"file":"run-operation-lifecycle.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/run-operation-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,IAAI,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EACL,KAAK,QAAQ,EAGb,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGjD,KAAK,sBAAsB,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEnE,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,IAAI,QAAQ,CAAC;IACvB,cAAc,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,GAAG,IAAI,IAAI,CAAC;CACb;AAED,uEAAuE;AACvE,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,gCAAgC;IA4CrF,gBAAgB,SAAS,MAAM,GAAG,IAAI;IAGhC,YAAY,QACT,aAAa,QACd,MAAM,kBACI,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC;IAgCzB,cAAc,OAAO,MAAM,GAAG,IAAI;IAQlC,mBAAmB,QAAQ,OAAO,GAAG,IAAI;IAIzC,eAAe,cAAc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,MAAM,QAAQ,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;EAavD"}
1
+ {"version":3,"file":"run-operation-lifecycle.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/run-operation-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,IAAI,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EACL,KAAK,QAAQ,EAGb,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGjD,KAAK,sBAAsB,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEnE,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,IAAI,QAAQ,CAAC;IACvB,cAAc,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,GAAG,IAAI,IAAI,CAAC;IACZ,oEAAoE;IACpE,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AAED,uEAAuE;AACvE,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,gCAAgC;IA+CrF,gBAAgB,SAAS,MAAM,GAAG,IAAI;IAGhC,YAAY,QACT,aAAa,QACd,MAAM,kBACI,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC;IAgCzB,cAAc,OAAO,MAAM,GAAG,IAAI;IAQlC,mBAAmB,QAAQ,OAAO,GAAG,IAAI;IAIzC,eAAe,cAAc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,MAAM,QAAQ,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;EAavD"}
@@ -2,7 +2,7 @@ import {
2
2
  composeAgentPrompt,
3
3
  createAgentRuntime,
4
4
  createAgentRuntimeEventSink
5
- } from "./index-jpp7jd1p.js";
5
+ } from "./index-2jg7b11j.js";
6
6
  import {
7
7
  AgentModelDescriptorSchema
8
8
  } from "./index-tg3m2ec5.js";
@@ -49,7 +49,7 @@ import {
49
49
  registerDeferredToolRepair,
50
50
  repairedSearchCall,
51
51
  selectAgentHistory
52
- } from "./index-jpp7jd1p.js";
52
+ } from "./index-2jg7b11j.js";
53
53
  import {
54
54
  AgentModelCapabilitySchema,
55
55
  AgentModelCatalogEntrySchema,
@@ -934,6 +934,20 @@ function repairedSearchCall(toolCall, searchName) {
934
934
  };
935
935
  }
936
936
 
937
+ // src/agent-runtime/run-mutation-queue.ts
938
+ function createRunMutationQueue() {
939
+ let tail = Promise.resolve();
940
+ return (mutation) => {
941
+ const result = tail.then(mutation, mutation);
942
+ tail = result.then(() => {
943
+ return;
944
+ }, () => {
945
+ return;
946
+ });
947
+ return result;
948
+ };
949
+ }
950
+
937
951
  // src/agent-runtime/run-operation-lifecycle.ts
938
952
  import { wrapLanguageModel } from "ai";
939
953
 
@@ -1084,7 +1098,7 @@ function createAgentRunOperationLifecycle(config) {
1084
1098
  let providerCallId;
1085
1099
  let checkpointedStep = -1;
1086
1100
  const checkpointWaiters = new Map;
1087
- const record = async (operation) => {
1101
+ const record = (operation) => config.serialize(async () => {
1088
1102
  const current = config.currentRun();
1089
1103
  const snapshot = appliedSnapshot(await config.store.recordRunOperation({
1090
1104
  conversationId: current.conversationId,
@@ -1106,7 +1120,7 @@ function createAgentRunOperationLifecycle(config) {
1106
1120
  operation,
1107
1121
  emittedAt: config.now().toISOString()
1108
1122
  });
1109
- };
1123
+ });
1110
1124
  const startModelRequest = (callId, step) => record(AgentRunOperationSchema.parse({
1111
1125
  operationId: `${callId}:${step}`,
1112
1126
  kind: "model-request",
@@ -1314,9 +1328,11 @@ function createRunExecutor(dependencies) {
1314
1328
  let terminalPolicyName;
1315
1329
  const idleDeadline = createIdleDeadline(input.signal, idleTimeoutMs);
1316
1330
  const executionSignal = idleDeadline.signal;
1331
+ const serialize = createRunMutationQueue();
1317
1332
  const operationLifecycle = createAgentRunOperationLifecycle({
1318
1333
  store: config.store,
1319
1334
  runtimeEpoch,
1335
+ serialize,
1320
1336
  currentRun: () => run,
1321
1337
  acceptSnapshot: (next) => {
1322
1338
  snapshot = next;
@@ -1347,7 +1363,7 @@ function createRunExecutor(dependencies) {
1347
1363
  ...provider && { provider }
1348
1364
  }));
1349
1365
  };
1350
- const checkpoint = async () => {
1366
+ const checkpoint = () => serialize(async () => {
1351
1367
  assistant = AgentMessageSchema.parse({
1352
1368
  ...assistant,
1353
1369
  parts,
@@ -1380,7 +1396,7 @@ function createRunExecutor(dependencies) {
1380
1396
  metrics: checkpointMetrics,
1381
1397
  emittedAt: now().toISOString()
1382
1398
  });
1383
- };
1399
+ });
1384
1400
  try {
1385
1401
  if (config.history?.compact) {
1386
1402
  await operationLifecycle.startCompaction(generateId());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.85.1",
3
+ "version": "0.85.2",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",