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.
- package/dist/agent-runtime/compaction.d.ts +14 -1
- package/dist/agent-runtime/compaction.d.ts.map +1 -1
- package/dist/agent-runtime/coordinator.d.ts +8 -2
- package/dist/agent-runtime/coordinator.d.ts.map +1 -1
- package/dist/agent-runtime/events.d.ts +124 -0
- package/dist/agent-runtime/events.d.ts.map +1 -1
- package/dist/agent-runtime/observability.d.ts +333 -12
- package/dist/agent-runtime/observability.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts +4 -0
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schemas.d.ts +199 -77
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +180 -0
- package/dist/agent-runtime/store-driver.d.ts.map +1 -1
- package/dist/agent-runtime/store.d.ts +556 -0
- package/dist/agent-runtime/store.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-commit.d.ts +33 -3
- package/dist/agent-runtime/terminal-commit.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-status.d.ts.map +1 -1
- package/dist/agent-runtime.d.ts +2 -2
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +184 -29
- package/dist/{index-58vkx74h.js → index-b1k33127.js} +22 -18
- package/dist/testing/agent-store-conformance.d.ts.map +1 -1
- package/dist/testing.js +26 -4
- package/llms-full.txt +192 -12
- package/package.json +1 -1
|
@@ -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,
|
|
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,
|
|
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-
|
|
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
|
-
|
|
|
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
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
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`, `
|
|
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