stitchkit 0.62.0 → 0.63.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 +2 -0
- 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 +1 -1
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +152 -21
- 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 +130 -11
- package/package.json +1 -1
package/llms-full.txt
CHANGED
|
@@ -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
|
|
|
@@ -7750,6 +7801,73 @@ current one *up to* your target, and apply each snippet.
|
|
|
7750
7801
|
runtime): bootstrap the server, one HTTP request, and any feature you rely on
|
|
7751
7802
|
(Socket.IO connect, an MCP tool call, a multipart upload, …).
|
|
7752
7803
|
|
|
7804
|
+
## Released migration: 0.63.0
|
|
7805
|
+
|
|
7806
|
+
Four changes to what a running system reports and how an input reaches a run
|
|
7807
|
+
in flight. Nothing moves an export except one added store member, and only an
|
|
7808
|
+
application implementing `AgentRuntimeStore` directly has to touch code.
|
|
7809
|
+
|
|
7810
|
+
### A spend figure that survives, and an input that joins
|
|
7811
|
+
|
|
7812
|
+
### `AgentRuntimeStore` has a ninth member
|
|
7813
|
+
|
|
7814
|
+
Only if you implement the aggregate interface directly — an adapter built on
|
|
7815
|
+
`AgentRuntimeStoreDriver` needs no change, and the public conformance kit covers
|
|
7816
|
+
the new operation.
|
|
7817
|
+
|
|
7818
|
+
```ts
|
|
7819
|
+
// after
|
|
7820
|
+
absorbQueuedRun(input: AbsorbQueuedRun): Promise<AgentStoreMutationResult>
|
|
7821
|
+
```
|
|
7822
|
+
|
|
7823
|
+
It moves a queued successor's inputs into the run already answering, in one
|
|
7824
|
+
mutation, and marks the successor `absorbed`. Two run records change in one
|
|
7825
|
+
transaction — if your driver persists them one at a time, persist both.
|
|
7826
|
+
|
|
7827
|
+
### A provider failure says so
|
|
7828
|
+
|
|
7829
|
+
```ts
|
|
7830
|
+
// before — an upstream error arrived as a policy stop with no policy
|
|
7831
|
+
if (terminal.reason === 'policy_stop') retryLater()
|
|
7832
|
+
|
|
7833
|
+
// after
|
|
7834
|
+
if (terminal.reason === 'provider_failure') retryLater()
|
|
7835
|
+
if (terminal.reason === 'provider_stop') { /* a length cap or content filter */ }
|
|
7836
|
+
```
|
|
7837
|
+
|
|
7838
|
+
`policy_stop` now always carries the `policyName` that caused it. If you switch
|
|
7839
|
+
exhaustively on `AgentTerminalReason` or `AgentRunState`, add `'provider_stop'`
|
|
7840
|
+
and `'absorbed'`.
|
|
7841
|
+
|
|
7842
|
+
### `partial` changed meaning
|
|
7843
|
+
|
|
7844
|
+
It used to tell you which event kind you were holding. It now tells you whether
|
|
7845
|
+
the figure beside it is a confirmed total:
|
|
7846
|
+
|
|
7847
|
+
```ts
|
|
7848
|
+
// after — true when the provider never reported the run finished
|
|
7849
|
+
if (metrics.partial) treatAsFloor(metrics.usage)
|
|
7850
|
+
```
|
|
7851
|
+
|
|
7852
|
+
Terminal events for runs that were superseded, interrupted, timed out or failed
|
|
7853
|
+
before the provider finished now report `partial: true` where they reported
|
|
7854
|
+
`false`.
|
|
7855
|
+
|
|
7856
|
+
### Checkpoint metrics are a running total
|
|
7857
|
+
|
|
7858
|
+
```ts
|
|
7859
|
+
// wrong, and now wrong by more than it used to be
|
|
7860
|
+
const spent = checkpoints.reduce((total, c) => total + (c.metrics.usage?.cost?.value ?? 0), 0)
|
|
7861
|
+
// right
|
|
7862
|
+
const spent = checkpoints.at(-1)?.metrics.usage?.cost?.value
|
|
7863
|
+
```
|
|
7864
|
+
|
|
7865
|
+
### You can read a run's spend back from the store
|
|
7866
|
+
|
|
7867
|
+
`AgentRun.usage` is written at every checkpoint and with the terminal record, so
|
|
7868
|
+
a dropped observability event no longer loses the number, and a process that dies
|
|
7869
|
+
mid-stream leaves behind what it had already spent.
|
|
7870
|
+
|
|
7753
7871
|
## Released migration: 0.62.0
|
|
7754
7872
|
|
|
7755
7873
|
Two groups of behaviour changes. Nothing moves an export — the surface is
|
|
@@ -10237,7 +10355,8 @@ Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `AgentRec
|
|
|
10237
10355
|
Store command/result exports are `AcceptInputAndAssignRun`, `AcceptInputAndAssignRunSchema`,
|
|
10238
10356
|
`AcquireAgentRun`, `AcquireAgentRunSchema`, `CheckpointRunAssistant`,
|
|
10239
10357
|
`CheckpointRunAssistantSchema`, `CommitRunTerminal`, `CommitRunTerminalSchema`,
|
|
10240
|
-
`RequestRunInterrupt`, `RequestRunInterruptSchema`, `
|
|
10358
|
+
`RequestRunInterrupt`, `RequestRunInterruptSchema`, `AbsorbQueuedRun`, `AbsorbQueuedRunSchema`,
|
|
10359
|
+
`RecoverAgentRun`, `ReplaceCompactedRange`,
|
|
10241
10360
|
`ReplaceCompactedRangeSchema`, `AgentStoreMutationResult`, `AgentStoreMutationResultSchema`,
|
|
10242
10361
|
`AgentStoreAppliedSchema`, `AgentStoreConflictSchema`, `AgentStoreDuplicateSchema`,
|
|
10243
10362
|
`AgentStoreNotFoundSchema`, `AgentAdmissionReceipt`, `AgentAdmissionReceiptSchema`,
|
package/package.json
CHANGED