stitchkit 0.62.0 → 0.64.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.
@@ -99,6 +99,7 @@ var AgentRunStateSchema = z.enum([
99
99
  "completed",
100
100
  "interrupted",
101
101
  "superseded",
102
+ "absorbed",
102
103
  "failed",
103
104
  "cancelled",
104
105
  "abandoned"
@@ -106,6 +107,7 @@ var AgentRunStateSchema = z.enum([
106
107
  var AgentTerminalReasonSchema = z.enum([
107
108
  "success",
108
109
  "policy_stop",
110
+ "provider_stop",
109
111
  "interrupted",
110
112
  "superseded",
111
113
  "cancelled",
@@ -115,6 +117,23 @@ var AgentTerminalReasonSchema = z.enum([
115
117
  "tool_failure",
116
118
  "abandoned"
117
119
  ]);
120
+ var AgentUsageValueSchema = z.object({
121
+ value: z.number().nonnegative().optional(),
122
+ provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
123
+ });
124
+ var AgentCostValueSchema = z.object({
125
+ value: z.number().nonnegative().optional(),
126
+ currency: z.string().length(3).optional(),
127
+ provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
128
+ });
129
+ var AgentUsageSchema = z.object({
130
+ inputTokens: AgentUsageValueSchema,
131
+ outputTokens: AgentUsageValueSchema,
132
+ reasoningTokens: AgentUsageValueSchema.optional(),
133
+ cacheReadTokens: AgentUsageValueSchema.optional(),
134
+ cacheWriteTokens: AgentUsageValueSchema.optional(),
135
+ cost: AgentCostValueSchema.optional()
136
+ });
118
137
  var AgentRunSchema = z.object({
119
138
  schemaVersion: z.literal(1),
120
139
  id: AgentRecordIdSchema,
@@ -127,6 +146,8 @@ var AgentRunSchema = z.object({
127
146
  fencingToken: AgentRecordVersionSchema.optional(),
128
147
  terminalReason: AgentTerminalReasonSchema.optional(),
129
148
  terminalPolicyName: z.string().min(1).optional(),
149
+ absorbedIntoRunId: AgentRecordIdSchema.optional(),
150
+ usage: AgentUsageSchema.optional(),
130
151
  createdAt: AgentTimestampSchema,
131
152
  updatedAt: AgentTimestampSchema
132
153
  });
@@ -137,23 +158,6 @@ var AgentSnapshotSchema = z.object({
137
158
  messages: z.array(AgentMessageSchema),
138
159
  runs: z.array(AgentRunSchema)
139
160
  });
140
- var AgentUsageValueSchema = z.object({
141
- value: z.number().nonnegative().optional(),
142
- provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
143
- });
144
- var AgentCostValueSchema = z.object({
145
- value: z.number().nonnegative().optional(),
146
- currency: z.string().length(3).optional(),
147
- provenance: z.enum(["provider-reported", "computed", "estimated", "unavailable"])
148
- });
149
- var AgentUsageSchema = z.object({
150
- inputTokens: AgentUsageValueSchema,
151
- outputTokens: AgentUsageValueSchema,
152
- reasoningTokens: AgentUsageValueSchema.optional(),
153
- cacheReadTokens: AgentUsageValueSchema.optional(),
154
- cacheWriteTokens: AgentUsageValueSchema.optional(),
155
- cost: AgentCostValueSchema.optional()
156
- });
157
161
  var AgentRunMetricsSchema = z.object({
158
162
  partial: z.boolean(),
159
163
  usage: AgentUsageSchema.optional(),
@@ -161,4 +165,4 @@ var AgentRunMetricsSchema = z.object({
161
165
  ttftMs: z.number().nonnegative().optional()
162
166
  });
163
167
 
164
- export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, AgentRunSchema, AgentSnapshotSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunMetricsSchema };
168
+ export { AgentRecordIdSchema, AgentRecordVersionSchema, AgentTimestampSchema, AgentJsonObjectSchema, AgentProviderEnvelopeSchema, AgentTextPartSchema, AgentReasoningPartSchema, AgentFilePartSchema, AgentSourcePartSchema, AgentToolCallPartSchema, AgentToolResultPartSchema, AgentOpaquePartSchema, AgentControlPartSchema, AgentMessagePartSchema, AgentMessageRoleSchema, AgentMessageStatusSchema, AgentMessageSchema, AgentAssistantPlaceholderSchema, AgentRunStateSchema, AgentTerminalReasonSchema, AgentUsageValueSchema, AgentCostValueSchema, AgentUsageSchema, AgentRunSchema, AgentSnapshotSchema, AgentRunMetricsSchema };
@@ -1 +1 @@
1
- {"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/D;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CAmRf"}
1
+ {"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/D;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CA4Sf"}
package/dist/testing.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AgentMessageSchema,
3
3
  AgentRunSchema
4
- } from "./index-58vkx74h.js";
4
+ } from "./index-b1k33127.js";
5
5
  import {
6
6
  createApplication
7
7
  } from "./index-eabpd4tb.js";
@@ -283,12 +283,20 @@ async function runAgentStoreConformance(config) {
283
283
  parts: [{ type: "text", text: "checkpoint" }],
284
284
  createdAt: "2026-08-22T00:00:00.000Z",
285
285
  updatedAt: "2026-08-22T00:00:01.000Z"
286
- })
286
+ }),
287
+ usage: {
288
+ inputTokens: { value: 1000, provenance: "provider-reported" },
289
+ outputTokens: { value: 100, provenance: "provider-reported" },
290
+ cost: { value: 0.25, currency: "USD", provenance: "provider-reported" }
291
+ }
287
292
  });
288
293
  requireOutcome(checkpoint, "applied");
289
294
  const checkpointedRun = checkpoint.snapshot.runs.find((run) => run.id === running.id);
290
295
  if (!checkpointedRun)
291
296
  throw new Error("Checkpointed run disappeared");
297
+ if (checkpointedRun.usage?.cost?.value !== 0.25) {
298
+ throw new Error("Checkpoint did not persist the run usage it was given");
299
+ }
292
300
  const terminalAssistant = AgentMessageSchema.parse({
293
301
  schemaVersion: 1,
294
302
  id: running.assistantMessageId,
@@ -307,7 +315,12 @@ async function runAgentStoreConformance(config) {
307
315
  expectedRevision: checkpointedRun.revision,
308
316
  ownerId: "conformance-owner",
309
317
  assistant: terminalAssistant,
310
- reason: "success"
318
+ reason: "success",
319
+ usage: {
320
+ inputTokens: { value: 3000, provenance: "computed" },
321
+ outputTokens: { value: 300, provenance: "computed" },
322
+ cost: { value: 1.5, currency: "USD", provenance: "computed" }
323
+ }
311
324
  }),
312
325
  store.commitRunTerminal({
313
326
  conversationId,
@@ -315,7 +328,12 @@ async function runAgentStoreConformance(config) {
315
328
  expectedRevision: checkpointedRun.revision,
316
329
  ownerId: "conformance-owner",
317
330
  assistant: terminalAssistant,
318
- reason: "success"
331
+ reason: "success",
332
+ usage: {
333
+ inputTokens: { value: 3000, provenance: "computed" },
334
+ outputTokens: { value: 300, provenance: "computed" },
335
+ cost: { value: 1.5, currency: "USD", provenance: "computed" }
336
+ }
319
337
  })
320
338
  ]);
321
339
  const terminalOutcomes = terminalResults.map((result) => result.outcome).sort();
@@ -326,6 +344,10 @@ async function runAgentStoreConformance(config) {
326
344
  if (terminalApplied?.outcome !== "applied") {
327
345
  throw new Error("Terminal race produced no applied result");
328
346
  }
347
+ const settledRun = terminalApplied.snapshot.runs.find((run) => run.id === running.id);
348
+ if (settledRun?.usage?.cost?.value !== 1.5) {
349
+ throw new Error("Terminal commit did not persist the run usage it was given");
350
+ }
329
351
  const compactedTerminal = await store.replaceCompactedRange({
330
352
  conversationId,
331
353
  expectedVersion: terminalApplied.snapshot.version,
package/llms-full.txt CHANGED
@@ -58,7 +58,7 @@ own, recorded as an ADR.
58
58
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the store and managed-resource conformance kits |
59
59
  | `stitchkit/declaration` | build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
60
60
  | `stitchkit/react` | browser | stable | `createCursorQuery`, `createCacheBridge` |
61
- | `stitchkit/agent-runtime` | server | evolving | optional durable conversation/run loop, history, models, prompts, fencing and events |
61
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 7 of the 9 minors since 0.56.2, most recently 0.64.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
62
62
  | `stitchkit/agent-runtime/openrouter` | server | evolving | isolated OpenRouter language-model adapter |
63
63
  | `stitchkit/application` | server | evolving | managed resource graph, readiness, admission, schedules and bounded shutdown |
64
64
  | `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
@@ -3682,7 +3682,7 @@ the fourth row below is a behaviour it deliberately does not offer yet:
3682
3682
  | `queue` (default) | finishes first | kept |
3683
3683
  | `interrupt` | ends | kept, and marked as cut off |
3684
3684
  | `supersede` | ends | discarded from the prompt, kept in the record |
3685
- | _inject_ | continues | — not supported; see below |
3685
+ | `inject` | continues | kept it takes the new input at a step boundary |
3686
3686
 
3687
3687
  `interrupt` and `supersede` differ in exactly one thing, and the question that
3688
3688
  picks between them is **not** "was the run interrupted" but **"did anyone see
@@ -3766,15 +3766,37 @@ const { decisions } = await projectAgentHistoryDetailed(snapshot.messages)
3766
3766
  process-local escape hatch chooses the reason, so a caller that knows the answer
3767
3767
  was never delivered can discard it without a newer input arriving.
3768
3768
 
3769
- ### The one that is not supported
3770
-
3771
- **inject** hand the input to the loop between tool calls and let the run
3772
- continue has no primitive. `loop.prepareStep` passes the AI SDK return type
3773
- through, so an application *can* append messages between steps, but nothing
3774
- hands `prepareStep` the pending inputs and nothing attaches an absorbed input to
3775
- the running run's `inputMessageIds`. A run that answered two messages would
3776
- carry a durable record claiming it answered one. It is reachable by hand, not
3777
- supported.
3769
+ ### The one that ends nothing
3770
+
3771
+ **`inject`** hands the input to the loop between tool calls and lets the run keep
3772
+ going. It is right when the input *refines* rather than redirects — a correction
3773
+ arriving while a multi-step task is halfway through, where discarding the
3774
+ finished steps would be pure loss.
3775
+
3776
+ It queues like `queue`, and a run already in flight takes it on at its next step
3777
+ boundary. That ordering is the whole design: the tempting shape, attaching a new
3778
+ input straight to a running run, has a loss case with no honest answer, because
3779
+ the run may terminate before the loop reaches a boundary and the input would then
3780
+ be recorded as answered by a turn that never saw it. Queue first and absorb
3781
+ opportunistically, and the fallback is simply that the successor runs — the
3782
+ behaviour every other policy already has.
3783
+
3784
+ When a run does absorb one:
3785
+
3786
+ - both inputs land in the answering run's `inputMessageIds`, so the durable
3787
+ record matches what the model was actually asked;
3788
+ - both submissions' tickets resolve to the same terminal result;
3789
+ - the absorbed run is marked `absorbed` with `absorbedIntoRunId` pointing at the
3790
+ run that answered. It is kept, not deleted — its admission receipt still points
3791
+ at it, so a duplicate submission has to resolve to something. It leaves the
3792
+ conversation snapshot, because a snapshot carries active runs plus those a
3793
+ message references and an absorbed run never wrote an assistant message;
3794
+ - the next provider call carries the re-projected history. An application's own
3795
+ `prepareStep` wins if it sets `messages` itself — it is the one that knows why.
3796
+
3797
+ A step boundary is the only place this can happen: the provider is between calls,
3798
+ so the next request can carry the new message. A single-step run never reaches
3799
+ one, and its successor simply runs next.
3778
3800
 
3779
3801
  With `runs.coalescePending: true`, an active lane has at most one queued
3780
3802
  successor. Every later accepted input is atomically appended to that successor;
@@ -4028,6 +4050,35 @@ Usage is **not durable**. It reaches you on the operator and delivery event
4028
4050
  streams and in `AgentRuntimeResult.metrics`, and stitchkit writes no spend to the
4029
4051
  store — where a figure lives afterwards is the application's (→ ADR 0002).
4030
4052
 
4053
+ ### Reconciling with the provider's own accounting
4054
+
4055
+ Whether a provider bills for a call that was aborted mid-flight cannot be known
4056
+ inside the process: the authoritative number arrives later, from the provider's
4057
+ accounting. **stitchkit does not accept it back** (→ ADR 0110) — a terminal run
4058
+ is an absorbing state, and a write that reached it through the conversation
4059
+ aggregate could conflict a concurrent compaction into discarding a summary it had
4060
+ just paid a model to produce.
4061
+
4062
+ The join is yours, and `runId` is the key:
4063
+
4064
+ ```ts
4065
+ // when the run terminates — write what the runtime observed
4066
+ await ledger.record({
4067
+ runId: terminal.run.id,
4068
+ conversationId: terminal.run.conversationId,
4069
+ costUsd: terminal.metrics?.usage?.cost?.value ?? null, // null when `unavailable`
4070
+ provenance: terminal.metrics?.usage?.cost?.provenance ?? 'unavailable',
4071
+ })
4072
+
4073
+ // later — the provider's accounting names the same generation
4074
+ await ledger.reconcile({ runId, costUsd: billed, provenance: 'provider-reported' })
4075
+ ```
4076
+
4077
+ Record the row even when the figure is `unavailable`: that row is the evidence
4078
+ that a run happened and cost something nobody has counted yet, and it is what the
4079
+ provider's later figure attaches to. A run with no row is a run you cannot
4080
+ reconcile.
4081
+
4031
4082
  The sink deduplicates stable event IDs by default. Cross-crash exactly-once still requires a durable
4032
4083
  outbox.
4033
4084
 
@@ -7712,6 +7763,24 @@ additive** — adopting it changes nothing in your code. (See
7712
7763
  So upgrading is: read the `### ⚠️ Breaking changes` of every version *above* your
7713
7764
  current one *up to* your target, and apply each snippet.
7714
7765
 
7766
+ ## Before you bump, if you implement an agent store
7767
+
7768
+ One step, and it is mechanical. If your project has an `AgentRuntimeStore` — a
7769
+ Prisma adapter, an in-memory one, anything — run the conformance kit against it
7770
+ **on the version you are leaving**, then again after the bump:
7771
+
7772
+ ```ts
7773
+ import { runAgentStoreConformance } from 'stitchkit/testing'
7774
+
7775
+ await runAgentStoreConformance({ store: yourStore, conversationId: 'conformance' })
7776
+ ```
7777
+
7778
+ Green before and red after tells you the contract grew and where, in one run,
7779
+ instead of one failure at a time in production. Green both times means the
7780
+ upgrade owes you nothing on that surface — which is the usual answer if you
7781
+ implement `AgentRuntimeStoreDriver` and compose the aggregate with
7782
+ `createAgentRuntimeStore(driver)`, the supported shape (→ ADR 0111).
7783
+
7715
7784
  ## Flow (agent or human)
7716
7785
 
7717
7786
  1. **Find the current version.** In the consumer: the resolved `stitchkit` in
@@ -7750,6 +7819,114 @@ current one *up to* your target, and apply each snippet.
7750
7819
  runtime): bootstrap the server, one HTTP request, and any feature you rely on
7751
7820
  (Socket.IO connect, an MCP tool call, a multipart upload, …).
7752
7821
 
7822
+ ## Released migration: 0.64.0
7823
+
7824
+ Two changes, and only one of them can break a build. Nothing was removed.
7825
+
7826
+ ### An event that says which kind it is
7827
+
7828
+ ### Narrow `AgentRunEvent` on `type`
7829
+
7830
+ ```ts
7831
+ // before
7832
+ for (const event of events) record(event.usage?.cost?.value ?? 0)
7833
+
7834
+ // after — and the compiler will point at every site
7835
+ for (const event of events) {
7836
+ if (event.type !== 'run-terminal') continue
7837
+ record(event.usage.cost.value ?? null) // `usage` is present; unknown says so
7838
+ }
7839
+ ```
7840
+
7841
+ `step` is now required on `step-finished`, `terminalReason` on `run-terminal`,
7842
+ and `usage` on both. `queueWaitMs` exists only on `run-started`. Nothing was
7843
+ removed — the fields that were optional because a *different* kind of event
7844
+ lacked them are now simply on the kinds that have them.
7845
+
7846
+ Import `AgentRunTerminalEventSchema` (or the sibling schemas) if you construct
7847
+ events in tests.
7848
+
7849
+ ### If you implement `AgentRuntimeStore` directly, move to the driver
7850
+
7851
+ Not urgent and nothing breaks today — but the aggregate is no longer the
7852
+ supported target, so its future growth will not be announced as breaking
7853
+ (→ ADR 0111). The supported shape is one line:
7854
+
7855
+ ```ts
7856
+ const driver: AgentRuntimeStoreDriver<TransactionClient> = { /* six primitives */ }
7857
+ export const store = createAgentRuntimeStore(driver)
7858
+ ```
7859
+
7860
+ Run `runAgentStoreConformance` against your adapter before and after any bump —
7861
+ see *Before you bump, if you implement an agent store* above.
7862
+
7863
+ ## Released migration: 0.63.0
7864
+
7865
+ Four changes to what a running system reports and how an input reaches a run
7866
+ in flight. Nothing moves an export except one added store member, and only an
7867
+ application implementing `AgentRuntimeStore` directly has to touch code.
7868
+
7869
+ ### A spend figure that survives, and an input that joins
7870
+
7871
+ ### `AgentRuntimeStore` has a ninth member
7872
+
7873
+ Only if you implement the aggregate interface directly — an adapter built on
7874
+ `AgentRuntimeStoreDriver` needs no change, and the public conformance kit covers
7875
+ the new operation.
7876
+
7877
+ ```ts
7878
+ // after
7879
+ absorbQueuedRun(input: AbsorbQueuedRun): Promise<AgentStoreMutationResult>
7880
+ ```
7881
+
7882
+ It moves a queued successor's inputs into the run already answering, in one
7883
+ mutation, and marks the successor `absorbed`. Two run records change in one
7884
+ transaction — if your driver persists them one at a time, persist both.
7885
+
7886
+ ### A provider failure says so
7887
+
7888
+ ```ts
7889
+ // before — an upstream error arrived as a policy stop with no policy
7890
+ if (terminal.reason === 'policy_stop') retryLater()
7891
+
7892
+ // after
7893
+ if (terminal.reason === 'provider_failure') retryLater()
7894
+ if (terminal.reason === 'provider_stop') { /* a length cap or content filter */ }
7895
+ ```
7896
+
7897
+ `policy_stop` now always carries the `policyName` that caused it. If you switch
7898
+ exhaustively on `AgentTerminalReason` or `AgentRunState`, add `'provider_stop'`
7899
+ and `'absorbed'`.
7900
+
7901
+ ### `partial` changed meaning
7902
+
7903
+ It used to tell you which event kind you were holding. It now tells you whether
7904
+ the figure beside it is a confirmed total:
7905
+
7906
+ ```ts
7907
+ // after — true when the provider never reported the run finished
7908
+ if (metrics.partial) treatAsFloor(metrics.usage)
7909
+ ```
7910
+
7911
+ Terminal events for runs that were superseded, interrupted, timed out or failed
7912
+ before the provider finished now report `partial: true` where they reported
7913
+ `false`.
7914
+
7915
+ ### Checkpoint metrics are a running total
7916
+
7917
+ ```ts
7918
+ // wrong, and now wrong by more than it used to be
7919
+ const spent = checkpoints.reduce((total, c) => total + (c.metrics.usage?.cost?.value ?? 0), 0)
7920
+ // right
7921
+ const spent = checkpoints.at(-1)?.metrics.usage?.cost?.value
7922
+ ```
7923
+
7924
+ ### You can read a run's spend back from the store
7925
+
7926
+ `AgentRun.usage` is written at every checkpoint and with the terminal record, so
7927
+ a dropped observability event no longer loses the number, and a process that dies
7928
+ mid-stream leaves behind what it had already spent.
7929
+
7753
7930
  ## Released migration: 0.62.0
7754
7931
 
7755
7932
  Two groups of behaviour changes. Nothing moves an export — the surface is
@@ -10237,7 +10414,8 @@ Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `AgentRec
10237
10414
  Store command/result exports are `AcceptInputAndAssignRun`, `AcceptInputAndAssignRunSchema`,
10238
10415
  `AcquireAgentRun`, `AcquireAgentRunSchema`, `CheckpointRunAssistant`,
10239
10416
  `CheckpointRunAssistantSchema`, `CommitRunTerminal`, `CommitRunTerminalSchema`,
10240
- `RequestRunInterrupt`, `RequestRunInterruptSchema`, `RecoverAgentRun`, `ReplaceCompactedRange`,
10417
+ `RequestRunInterrupt`, `RequestRunInterruptSchema`, `AbsorbQueuedRun`, `AbsorbQueuedRunSchema`,
10418
+ `RecoverAgentRun`, `ReplaceCompactedRange`,
10241
10419
  `ReplaceCompactedRangeSchema`, `AgentStoreMutationResult`, `AgentStoreMutationResultSchema`,
10242
10420
  `AgentStoreAppliedSchema`, `AgentStoreConflictSchema`, `AgentStoreDuplicateSchema`,
10243
10421
  `AgentStoreNotFoundSchema`, `AgentAdmissionReceipt`, `AgentAdmissionReceiptSchema`,
@@ -10272,6 +10450,8 @@ snapshot reload; the bounded sink isolates transport failure and supports a type
10272
10450
 
10273
10451
  Managed effects and operator telemetry additionally export `AgentToolFenceConfig`,
10274
10452
  `AgentToolFenceContext`, `AgentObservability`, `AgentRunEvent`, `AgentRunEventSchema`,
10453
+ `AgentRunStartedEvent`, `AgentRunStartedEventSchema`, `AgentStepFinishedEvent`,
10454
+ `AgentStepFinishedEventSchema`, `AgentRunTerminalEvent`, `AgentRunTerminalEventSchema`,
10275
10455
  `AgentRunSinkConfig`, `AgentRunSinkDrop` and `AgentRunSinkError`. A monotonic run `fencingToken`
10276
10456
  may accompany checkpoint/terminal writes and tool context; internal causes are redacted unless an
10277
10457
  operator-only observability sink explicitly opts in.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.62.0",
3
+ "version": "0.64.0",
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",