stitchkit 0.112.0 → 0.112.1
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 +7 -0
- package/dist/agent-runtime/history.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/harness.js +1 -1
- package/dist/entrypoints/agent-runtime.js +1 -1
- package/dist/{index-5as18gs2.js → index-a0vj9edp.js} +1 -1
- package/llms/agent-runtime.2.txt +57 -103
- package/llms/agent-runtime.3.txt +117 -1
- package/llms/agent-runtime.txt +1 -1
- package/llms-full.txt +66 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,13 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
|
|
|
15
15
|
|
|
16
16
|
## [Unreleased]
|
|
17
17
|
|
|
18
|
+
## [0.112.1] - 2026-10-25
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- `stitchkit/agent-runtime` — an empty or control-only failed assistant now retains its non-success marker when explicitly included with `evidencePolicy.failedAssistant: 'assistant-marked'`. The default still omits failed evidence. The compaction guide explains the existing failed-prefix recovery policy, status-aware summarization, and why a closed tool exchange cannot settle an external effect. → ADR 0269
|
|
23
|
+
**Affects:** `stitchkit/agent-runtime` projectAgentHistory, projectAgentHistoryDetailed
|
|
24
|
+
|
|
18
25
|
## [0.112.0] - 2026-10-24
|
|
19
26
|
|
|
20
27
|
### ⚠️ Breaking changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAsB,MAAM,IAAI,CAAC;AAO1E,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAyB,MAAM,WAAW,CAAC;AACvF,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,mBAAmB,CAAC;AAE3B,KAAK,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEzC,MAAM,WAAW,6BAA6B;IAC5C,cAAc,CAAC,EAAE,0BAA0B,CAAC;IAC5C,WAAW,CAAC,CACV,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EACjD,OAAO,EAAE,YAAY,GACpB,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,GAAG,aAAa,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,MAAM,EACF,WAAW,GACX,iBAAiB,GACjB,OAAO,GACP,mBAAmB,GACnB,sBAAsB,GACtB,aAAa,GACb,YAAY,CAAC;IACjB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC,SAAS,EAAE,SAAS,8BAA8B,EAAE,CAAC;IACrD;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAsB,MAAM,IAAI,CAAC;AAO1E,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAyB,MAAM,WAAW,CAAC;AACvF,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,mBAAmB,CAAC;AAE3B,KAAK,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEzC,MAAM,WAAW,6BAA6B;IAC5C,cAAc,CAAC,EAAE,0BAA0B,CAAC;IAC5C,WAAW,CAAC,CACV,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EACjD,OAAO,EAAE,YAAY,GACpB,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,GAAG,aAAa,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,MAAM,EACF,WAAW,GACX,iBAAiB,GACjB,OAAO,GACP,mBAAmB,GACnB,sBAAsB,GACtB,aAAa,GACb,YAAY,CAAC;IACjB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC,SAAS,EAAE,SAAS,8BAA8B,EAAE,CAAC;IACrD;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AA2MD,wEAAwE;AACxE,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,4BAA4B,CAAC,CA4GvC;AAED,4EAA4E;AAC5E,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzB"}
|
|
@@ -5,7 +5,7 @@ import"../../index-8kzct1d6.js";
|
|
|
5
5
|
import {
|
|
6
6
|
composeAgentPrompt2,
|
|
7
7
|
createAgentRuntime2
|
|
8
|
-
} from "../../index-
|
|
8
|
+
} from "../../index-a0vj9edp.js";
|
|
9
9
|
import"../../index-qaet40b2.js";
|
|
10
10
|
import"../../index-mnkk1ffz.js";
|
|
11
11
|
import"../../index-fynr93w4.js";
|
|
@@ -490,7 +490,7 @@ function assistantMessages(message, marker) {
|
|
|
490
490
|
rendered.add("tool-approval-response");
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
|
-
if (marker && (messages.length > 0 || content.length > 0)) {
|
|
493
|
+
if (marker === "failed" || marker && (messages.length > 0 || content.length > 0)) {
|
|
494
494
|
append("assistant", {
|
|
495
495
|
type: "text",
|
|
496
496
|
text: marker === "interrupted" ? INTERRUPTION_NOTE : FAILURE_NOTE
|
package/llms/agent-runtime.2.txt
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Parts of this slice:
|
|
8
8
|
- `llms/agent-runtime.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
9
9
|
- `llms/agent-runtime.2.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
10
|
-
- `llms/agent-runtime.3.txt`: API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
10
|
+
- `llms/agent-runtime.3.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md) · API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
11
11
|
|
|
12
12
|
==============================================================================
|
|
13
13
|
# Guide: Agent application runtime (docs/guide/agent-runtime.md) (continued)
|
|
@@ -615,6 +615,62 @@ replace a leading summary on the next compaction.
|
|
|
615
615
|
Set `maxAttempts` to allow bounded conflict recovery. Every retry reloads the snapshot, reselects the
|
|
616
616
|
eligible range and recomputes the summary; the stale summary is never retried.
|
|
617
617
|
|
|
618
|
+
### Recovering a prefix after a failed turn
|
|
619
|
+
|
|
620
|
+
The default evidence policy omits failed assistants. A failed turn therefore stops the
|
|
621
|
+
compactable prefix, including completed turns after it. A terminal failure is not an
|
|
622
|
+
unanswered tool call, but opting its partial evidence into a summary is an explicit host
|
|
623
|
+
decision. Use the existing `evidencePolicy: { failedAssistant: 'assistant-marked' }` on
|
|
624
|
+
`structuredCompaction` (or `selectCompactableHistory`) when that evidence is wanted.
|
|
625
|
+
The same policy belongs on the summarizer's history projection and on any corresponding
|
|
626
|
+
token-budget selection. Stored statuses remain unchanged.
|
|
627
|
+
|
|
628
|
+
The summarizer receives **raw** `eligibleMessages`, not provider messages and not an
|
|
629
|
+
automatic failure marker. Project them with the same policy before sending them to a
|
|
630
|
+
model, and preserve failed outcomes in the application's structured summary and prompt:
|
|
631
|
+
|
|
632
|
+
```ts
|
|
633
|
+
const evidencePolicy: AgentHistoryEvidencePolicy = {
|
|
634
|
+
failedAssistant: 'assistant-marked',
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Inside structuredCompaction({ evidencePolicy, ... }).summarize:
|
|
638
|
+
const projected = await projectAgentHistoryDetailed(eligibleMessages, {
|
|
639
|
+
evidencePolicy,
|
|
640
|
+
incompleteToolTurn: 'error',
|
|
641
|
+
})
|
|
642
|
+
const failedMessageIds = eligibleMessages
|
|
643
|
+
.filter(message => message.role === 'assistant' && message.status === 'failed')
|
|
644
|
+
.map(message => message.id)
|
|
645
|
+
// Pass projected.messages, projected.system and failedMessageIds to the host's
|
|
646
|
+
// summarizer. Its schema/prompt must retain failures and uncertain effects as
|
|
647
|
+
// such, merge previousSummary, and never describe partial output as success.
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
An opted-in failed assistant projects an explicit non-success marker even when it has
|
|
651
|
+
no text or only control parts. A dangling call, unresolved approval, invalid result
|
|
652
|
+
chronology or a user input with no assistant remains a barrier under either policy.
|
|
653
|
+
Raw whole-turn completeness does not guarantee that every record can be projected:
|
|
654
|
+
for example, a call and its result split across records may be rejected by the projector.
|
|
655
|
+
`incompleteToolTurn: 'error'` makes that rejection stop summarization; the original history
|
|
656
|
+
stays canonical. A host with such records must use a status-aware summarizer that explicitly
|
|
657
|
+
represents every relevant record, or retain the range. Do not silently summarize an omitted
|
|
658
|
+
exchange, filter the failed record out of the replacement range, rewrite its status or skip
|
|
659
|
+
over an incomplete turn. The replacement remains one contiguous prefix under snapshot CAS.
|
|
660
|
+
|
|
661
|
+
Provider chronology and external effect authority answer different questions (ADR 0269).
|
|
662
|
+
A matching `tool-result` with `outcome: 'error'` and an application code such as `UNKNOWN`
|
|
663
|
+
closes the provider exchange; it does **not** prove the external effect failed or succeeded.
|
|
664
|
+
Compaction changes the model-history projection, not the canonical event journal or the
|
|
665
|
+
retained terminal admission receipt. The `durability/effect` intent, accepted proof and
|
|
666
|
+
uncertain outcome remain available after compaction and archive restore. A reconstructed
|
|
667
|
+
`createLocalStepDurability` using the original `(conversationId, runId, effectName)` returns
|
|
668
|
+
the accepted proof, reconciles a bare intent, or returns `uncertain` without calling `run`
|
|
669
|
+
again. It does not deduplicate a new run or a newly named effect. Standalone effect callers
|
|
670
|
+
still own the exclusive execution lease; sharing a ledger is not an atomic claim.
|
|
671
|
+
An application-owned receipt outside that journal retains its own recovery rules and must
|
|
672
|
+
not be discarded because a history turn became compactable.
|
|
673
|
+
|
|
618
674
|
### Compacting without the store
|
|
619
675
|
|
|
620
676
|
The *selection* inside compaction needs no store, no version and no runtime, so
|
|
@@ -772,105 +828,3 @@ first mutation**, so an adapter whose runtime rows reference an application-owne
|
|
|
772
828
|
can provision those parents; the optional `cleanup(context)` removes them again, and runs once
|
|
773
829
|
whether the scenario passed or failed. A factory that owns no fixture state ignores the argument and
|
|
774
830
|
keeps working unchanged.
|
|
775
|
-
|
|
776
|
-
## Plain completions and shared invocation receipts
|
|
777
|
-
|
|
778
|
-
Use `createModelInvocationLedger` from `stitchkit/agent-runtime` when a direct text
|
|
779
|
-
completion and an agent must share causal provider evidence. It uses the existing
|
|
780
|
-
runtime store, not a second database. The completion path sends exactly one user
|
|
781
|
-
prompt, no framework instructions and no tools. It never starts an agent loop.
|
|
782
|
-
|
|
783
|
-
```ts
|
|
784
|
-
import { createModelInvocationLedger } from 'stitchkit/agent-runtime';
|
|
785
|
-
|
|
786
|
-
const invocations = createModelInvocationLedger({
|
|
787
|
-
store, // the same AgentRuntimeStore object passed to createAgentRuntime
|
|
788
|
-
models, // an existing defineModelRegistry result
|
|
789
|
-
payloadKey, // 32 bytes from the host's secret store; retain separately from archives
|
|
790
|
-
authorize: async ({ context, conversationId, action, trace }) => {
|
|
791
|
-
const session = await authenticate(context);
|
|
792
|
-
await authorizeConversation(session, conversationId, action, trace);
|
|
793
|
-
return { subject: session.subject }; // verified identity, never a body field
|
|
794
|
-
},
|
|
795
|
-
});
|
|
796
|
-
|
|
797
|
-
const completion = await invocations.complete({
|
|
798
|
-
conversationId: 'evaluation-42',
|
|
799
|
-
idempotencyKey: 'summary-case-3',
|
|
800
|
-
trace: {
|
|
801
|
-
operationId: 'summary-42', purpose: 'summarize', project: 'example',
|
|
802
|
-
parent: { traceId: 'trace-42' }, experiment: 'evaluation', case: 'case-3',
|
|
803
|
-
},
|
|
804
|
-
prompt: 'Summarize these supplied facts.',
|
|
805
|
-
models: ['primary', 'fallback'], // registry keys; repeat a key for an explicit retry
|
|
806
|
-
settings: { maxOutputTokens: 500 },
|
|
807
|
-
timeoutMs: 30_000,
|
|
808
|
-
}, authenticatedContext);
|
|
809
|
-
|
|
810
|
-
// Add to the existing createAgentRuntime configuration:
|
|
811
|
-
const receiptConfig = {
|
|
812
|
-
ledger: invocations,
|
|
813
|
-
trace: ({ run }) => ({
|
|
814
|
-
operationId: run.id, purpose: 'assistant-turn', project: 'example',
|
|
815
|
-
}),
|
|
816
|
-
};
|
|
817
|
-
// createAgentRuntime({ ...existingConfig, invocations: receiptConfig });
|
|
818
|
-
|
|
819
|
-
const page = await invocations.read({
|
|
820
|
-
conversationId: 'evaluation-42', limit: 100,
|
|
821
|
-
}, authenticatedContext);
|
|
822
|
-
// Continue with fromSeq: page.nextSeq while it is defined.
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
`complete` returns `invocationId`, `outcome` and, on success, `text`. `duplicate`
|
|
826
|
-
returns the existing ID without provider execution or replaying plaintext. Changed
|
|
827
|
-
input, trace or caller under the same key is a conflict. Model attempts are explicit
|
|
828
|
-
and bounded to eight; SDK retries are disabled. Only provider failures trigger the
|
|
829
|
-
next attempt. Abort, audit refusal and configuration errors do not. An admitted call
|
|
830
|
-
whose process died stays claimed: inspect the receipt before choosing a new key.
|
|
831
|
-
|
|
832
|
-
The agent retains its existing prompt, tools and loop. Both modes produce
|
|
833
|
-
`invocation/started`, `provider/request`, `provider/response` and
|
|
834
|
-
`invocation/finished` records through `read`. Each attempt has its own ID; response
|
|
835
|
-
usage is counted once and keeps `unavailable` distinct from measured zero. Requested
|
|
836
|
-
registry selection, sent adapter identity and effective provider identity are
|
|
837
|
-
separate. Effective identity is null when not reported. A gateway's hidden retries
|
|
838
|
-
are not visible as additional attempts.
|
|
839
|
-
|
|
840
|
-
`currentModelInvocationAttempt()` returns the causal context inside a provider's
|
|
841
|
-
`fetch` callback or streamed read. Use it to join a host transport audit to
|
|
842
|
-
`operationId`, `invocationId`, `attemptId`, optional `runId` and `step`.
|
|
843
|
-
`onAttempt` is an awaited admission hook; a rejected hook prevents the provider call.
|
|
844
|
-
SDK payload hashes are not represented as hashes of HTTP wire bytes.
|
|
845
|
-
|
|
846
|
-
Prompts and output are AES-256-GCM payload artifacts. `read` returns references and
|
|
847
|
-
hashes; `readPayload({ conversationId, artifactId }, context)` separately authorizes
|
|
848
|
-
`read-payload` and checks authentication tags and hashes. `payloadKey` must be 32
|
|
849
|
-
bytes and is copied at construction. Keep it outside the event store/backups; retain
|
|
850
|
-
the appropriate key when restoring an archive. `maxPayloadBytes` defaults to 4 MiB
|
|
851
|
-
(range 1 KiB–64 MiB). Streaming output evidence keeps parts up to half of it; past
|
|
852
|
-
that the evidence carries `truncated: { parts, sha256 }` over the whole stream, and
|
|
853
|
-
the answer itself is never cut. A receipt that cannot be written never changes an
|
|
854
|
-
outcome: `complete()` returns it with `receiptError` beside it, and a succeeded
|
|
855
|
-
answer keeps its `text`. Request headers
|
|
856
|
-
are excluded. Protect existing agent history independently: enabling receipts does
|
|
857
|
-
not encrypt its ordinary conversation records.
|
|
858
|
-
|
|
859
|
-
The built-in memory and SQLite stores implement `appendEventOnce`. Custom stores
|
|
860
|
-
must implement its once-only check and append atomically, returning the original
|
|
861
|
-
event on a duplicate key scoped by conversation and kind. A factory without this
|
|
862
|
-
capability refuses receipt setup. The driver-backed implementation finds the keyed
|
|
863
|
-
event by its identity through the driver's optional `events.find` — one index probe
|
|
864
|
-
in SQLite — so admission costs the same on a long conversation as on a new one; a
|
|
865
|
-
custom driver without `find` falls back to paging the log in one transaction.
|
|
866
|
-
`store.findEventOnce({ conversationId, kind, key })` reads the same event back.
|
|
867
|
-
Invocation payload artifacts are keyed by their artifact id the same way.
|
|
868
|
-
|
|
869
|
-
### Migration from direct SDK completions
|
|
870
|
-
|
|
871
|
-
**Who must act:** applications opting into shared completion/agent receipts.
|
|
872
|
-
Replace the direct `generateText` call with `invocations.complete`, configure host
|
|
873
|
-
authorization and a retained payload key, and pass the same ledger in the agent's
|
|
874
|
-
`invocations` option. Use the returned invocation ID and the paginated `read` method
|
|
875
|
-
for receipt queries; do not import runtime internals. Available since 0.100.0;
|
|
876
|
-
existing runtime configurations need no migration.
|
package/llms/agent-runtime.3.txt
CHANGED
|
@@ -6,7 +6,113 @@
|
|
|
6
6
|
Parts of this slice:
|
|
7
7
|
- `llms/agent-runtime.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
8
8
|
- `llms/agent-runtime.2.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
9
|
-
- `llms/agent-runtime.3.txt`: API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
9
|
+
- `llms/agent-runtime.3.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md) · API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
10
|
+
|
|
11
|
+
==============================================================================
|
|
12
|
+
# Guide: Agent application runtime (docs/guide/agent-runtime.md) (continued)
|
|
13
|
+
==============================================================================
|
|
14
|
+
|
|
15
|
+
## Plain completions and shared invocation receipts
|
|
16
|
+
|
|
17
|
+
Use `createModelInvocationLedger` from `stitchkit/agent-runtime` when a direct text
|
|
18
|
+
completion and an agent must share causal provider evidence. It uses the existing
|
|
19
|
+
runtime store, not a second database. The completion path sends exactly one user
|
|
20
|
+
prompt, no framework instructions and no tools. It never starts an agent loop.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createModelInvocationLedger } from 'stitchkit/agent-runtime';
|
|
24
|
+
|
|
25
|
+
const invocations = createModelInvocationLedger({
|
|
26
|
+
store, // the same AgentRuntimeStore object passed to createAgentRuntime
|
|
27
|
+
models, // an existing defineModelRegistry result
|
|
28
|
+
payloadKey, // 32 bytes from the host's secret store; retain separately from archives
|
|
29
|
+
authorize: async ({ context, conversationId, action, trace }) => {
|
|
30
|
+
const session = await authenticate(context);
|
|
31
|
+
await authorizeConversation(session, conversationId, action, trace);
|
|
32
|
+
return { subject: session.subject }; // verified identity, never a body field
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const completion = await invocations.complete({
|
|
37
|
+
conversationId: 'evaluation-42',
|
|
38
|
+
idempotencyKey: 'summary-case-3',
|
|
39
|
+
trace: {
|
|
40
|
+
operationId: 'summary-42', purpose: 'summarize', project: 'example',
|
|
41
|
+
parent: { traceId: 'trace-42' }, experiment: 'evaluation', case: 'case-3',
|
|
42
|
+
},
|
|
43
|
+
prompt: 'Summarize these supplied facts.',
|
|
44
|
+
models: ['primary', 'fallback'], // registry keys; repeat a key for an explicit retry
|
|
45
|
+
settings: { maxOutputTokens: 500 },
|
|
46
|
+
timeoutMs: 30_000,
|
|
47
|
+
}, authenticatedContext);
|
|
48
|
+
|
|
49
|
+
// Add to the existing createAgentRuntime configuration:
|
|
50
|
+
const receiptConfig = {
|
|
51
|
+
ledger: invocations,
|
|
52
|
+
trace: ({ run }) => ({
|
|
53
|
+
operationId: run.id, purpose: 'assistant-turn', project: 'example',
|
|
54
|
+
}),
|
|
55
|
+
};
|
|
56
|
+
// createAgentRuntime({ ...existingConfig, invocations: receiptConfig });
|
|
57
|
+
|
|
58
|
+
const page = await invocations.read({
|
|
59
|
+
conversationId: 'evaluation-42', limit: 100,
|
|
60
|
+
}, authenticatedContext);
|
|
61
|
+
// Continue with fromSeq: page.nextSeq while it is defined.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`complete` returns `invocationId`, `outcome` and, on success, `text`. `duplicate`
|
|
65
|
+
returns the existing ID without provider execution or replaying plaintext. Changed
|
|
66
|
+
input, trace or caller under the same key is a conflict. Model attempts are explicit
|
|
67
|
+
and bounded to eight; SDK retries are disabled. Only provider failures trigger the
|
|
68
|
+
next attempt. Abort, audit refusal and configuration errors do not. An admitted call
|
|
69
|
+
whose process died stays claimed: inspect the receipt before choosing a new key.
|
|
70
|
+
|
|
71
|
+
The agent retains its existing prompt, tools and loop. Both modes produce
|
|
72
|
+
`invocation/started`, `provider/request`, `provider/response` and
|
|
73
|
+
`invocation/finished` records through `read`. Each attempt has its own ID; response
|
|
74
|
+
usage is counted once and keeps `unavailable` distinct from measured zero. Requested
|
|
75
|
+
registry selection, sent adapter identity and effective provider identity are
|
|
76
|
+
separate. Effective identity is null when not reported. A gateway's hidden retries
|
|
77
|
+
are not visible as additional attempts.
|
|
78
|
+
|
|
79
|
+
`currentModelInvocationAttempt()` returns the causal context inside a provider's
|
|
80
|
+
`fetch` callback or streamed read. Use it to join a host transport audit to
|
|
81
|
+
`operationId`, `invocationId`, `attemptId`, optional `runId` and `step`.
|
|
82
|
+
`onAttempt` is an awaited admission hook; a rejected hook prevents the provider call.
|
|
83
|
+
SDK payload hashes are not represented as hashes of HTTP wire bytes.
|
|
84
|
+
|
|
85
|
+
Prompts and output are AES-256-GCM payload artifacts. `read` returns references and
|
|
86
|
+
hashes; `readPayload({ conversationId, artifactId }, context)` separately authorizes
|
|
87
|
+
`read-payload` and checks authentication tags and hashes. `payloadKey` must be 32
|
|
88
|
+
bytes and is copied at construction. Keep it outside the event store/backups; retain
|
|
89
|
+
the appropriate key when restoring an archive. `maxPayloadBytes` defaults to 4 MiB
|
|
90
|
+
(range 1 KiB–64 MiB). Streaming output evidence keeps parts up to half of it; past
|
|
91
|
+
that the evidence carries `truncated: { parts, sha256 }` over the whole stream, and
|
|
92
|
+
the answer itself is never cut. A receipt that cannot be written never changes an
|
|
93
|
+
outcome: `complete()` returns it with `receiptError` beside it, and a succeeded
|
|
94
|
+
answer keeps its `text`. Request headers
|
|
95
|
+
are excluded. Protect existing agent history independently: enabling receipts does
|
|
96
|
+
not encrypt its ordinary conversation records.
|
|
97
|
+
|
|
98
|
+
The built-in memory and SQLite stores implement `appendEventOnce`. Custom stores
|
|
99
|
+
must implement its once-only check and append atomically, returning the original
|
|
100
|
+
event on a duplicate key scoped by conversation and kind. A factory without this
|
|
101
|
+
capability refuses receipt setup. The driver-backed implementation finds the keyed
|
|
102
|
+
event by its identity through the driver's optional `events.find` — one index probe
|
|
103
|
+
in SQLite — so admission costs the same on a long conversation as on a new one; a
|
|
104
|
+
custom driver without `find` falls back to paging the log in one transaction.
|
|
105
|
+
`store.findEventOnce({ conversationId, kind, key })` reads the same event back.
|
|
106
|
+
Invocation payload artifacts are keyed by their artifact id the same way.
|
|
107
|
+
|
|
108
|
+
### Migration from direct SDK completions
|
|
109
|
+
|
|
110
|
+
**Who must act:** applications opting into shared completion/agent receipts.
|
|
111
|
+
Replace the direct `generateText` call with `invocations.complete`, configure host
|
|
112
|
+
authorization and a retained payload key, and pass the same ledger in the agent's
|
|
113
|
+
`invocations` option. Use the returned invocation ID and the paginated `read` method
|
|
114
|
+
for receipt queries; do not import runtime internals. Available since 0.100.0;
|
|
115
|
+
existing runtime configurations need no migration.
|
|
10
116
|
|
|
11
117
|
==============================================================================
|
|
12
118
|
# API reference: `stitchkit/agent-runtime` (docs/api/reference.md)
|
|
@@ -244,6 +350,16 @@ projection, budgeting and structured compaction; `isAssistantHistoryEvidence` ap
|
|
|
244
350
|
compatibility default omits it. Approval message schemas are
|
|
245
351
|
`AgentToolApprovalRequestPartSchema` and `AgentToolApprovalResponsePartSchema`.
|
|
246
352
|
|
|
353
|
+
With `failedAssistant: 'assistant-marked'`, `selectCompactableHistory` and
|
|
354
|
+
`structuredCompaction` admit a failed prefix only when the entire turn's tool chronology
|
|
355
|
+
is complete. `eligibleMessages` stays raw: the summarizer must use the same policy in
|
|
356
|
+
`projectAgentHistoryDetailed` and preserve non-success/uncertain outcomes in its summary.
|
|
357
|
+
Even an empty opted-in failed assistant carries a non-success marker in that projection.
|
|
358
|
+
Use `incompleteToolTurn: 'error'` to refuse a range the projector cannot represent.
|
|
359
|
+
Compaction never deletes canonical effect events or the retained terminal receipt;
|
|
360
|
+
chronological completeness does not settle an external effect. See the
|
|
361
|
+
[failed-prefix recovery contract](../guide/agent-runtime.md#recovering-a-prefix-after-a-failed-turn).
|
|
362
|
+
|
|
247
363
|
Model exports are `AgentLanguageModelProvider`, `AgentModelCapability`,
|
|
248
364
|
`AgentModelCapabilitySchema`, `AgentModelDescriptor`,
|
|
249
365
|
`AgentModelDescriptorSchema`, `AgentModelRegistry`, `AgentModelRegistryConfig`,
|
package/llms/agent-runtime.txt
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Parts of this slice:
|
|
8
8
|
- `llms/agent-runtime.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
9
9
|
- `llms/agent-runtime.2.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
10
|
-
- `llms/agent-runtime.3.txt`: API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
10
|
+
- `llms/agent-runtime.3.txt`: Guide: Agent application runtime (docs/guide/agent-runtime.md) · API reference: `stitchkit/agent-runtime` (docs/api/reference.md) · API reference: `stitchkit-tui` (docs/api/reference.md)
|
|
11
11
|
|
|
12
12
|
==============================================================================
|
|
13
13
|
# Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
package/llms-full.txt
CHANGED
|
@@ -6706,6 +6706,62 @@ replace a leading summary on the next compaction.
|
|
|
6706
6706
|
Set `maxAttempts` to allow bounded conflict recovery. Every retry reloads the snapshot, reselects the
|
|
6707
6707
|
eligible range and recomputes the summary; the stale summary is never retried.
|
|
6708
6708
|
|
|
6709
|
+
### Recovering a prefix after a failed turn
|
|
6710
|
+
|
|
6711
|
+
The default evidence policy omits failed assistants. A failed turn therefore stops the
|
|
6712
|
+
compactable prefix, including completed turns after it. A terminal failure is not an
|
|
6713
|
+
unanswered tool call, but opting its partial evidence into a summary is an explicit host
|
|
6714
|
+
decision. Use the existing `evidencePolicy: { failedAssistant: 'assistant-marked' }` on
|
|
6715
|
+
`structuredCompaction` (or `selectCompactableHistory`) when that evidence is wanted.
|
|
6716
|
+
The same policy belongs on the summarizer's history projection and on any corresponding
|
|
6717
|
+
token-budget selection. Stored statuses remain unchanged.
|
|
6718
|
+
|
|
6719
|
+
The summarizer receives **raw** `eligibleMessages`, not provider messages and not an
|
|
6720
|
+
automatic failure marker. Project them with the same policy before sending them to a
|
|
6721
|
+
model, and preserve failed outcomes in the application's structured summary and prompt:
|
|
6722
|
+
|
|
6723
|
+
```ts
|
|
6724
|
+
const evidencePolicy: AgentHistoryEvidencePolicy = {
|
|
6725
|
+
failedAssistant: 'assistant-marked',
|
|
6726
|
+
}
|
|
6727
|
+
|
|
6728
|
+
// Inside structuredCompaction({ evidencePolicy, ... }).summarize:
|
|
6729
|
+
const projected = await projectAgentHistoryDetailed(eligibleMessages, {
|
|
6730
|
+
evidencePolicy,
|
|
6731
|
+
incompleteToolTurn: 'error',
|
|
6732
|
+
})
|
|
6733
|
+
const failedMessageIds = eligibleMessages
|
|
6734
|
+
.filter(message => message.role === 'assistant' && message.status === 'failed')
|
|
6735
|
+
.map(message => message.id)
|
|
6736
|
+
// Pass projected.messages, projected.system and failedMessageIds to the host's
|
|
6737
|
+
// summarizer. Its schema/prompt must retain failures and uncertain effects as
|
|
6738
|
+
// such, merge previousSummary, and never describe partial output as success.
|
|
6739
|
+
```
|
|
6740
|
+
|
|
6741
|
+
An opted-in failed assistant projects an explicit non-success marker even when it has
|
|
6742
|
+
no text or only control parts. A dangling call, unresolved approval, invalid result
|
|
6743
|
+
chronology or a user input with no assistant remains a barrier under either policy.
|
|
6744
|
+
Raw whole-turn completeness does not guarantee that every record can be projected:
|
|
6745
|
+
for example, a call and its result split across records may be rejected by the projector.
|
|
6746
|
+
`incompleteToolTurn: 'error'` makes that rejection stop summarization; the original history
|
|
6747
|
+
stays canonical. A host with such records must use a status-aware summarizer that explicitly
|
|
6748
|
+
represents every relevant record, or retain the range. Do not silently summarize an omitted
|
|
6749
|
+
exchange, filter the failed record out of the replacement range, rewrite its status or skip
|
|
6750
|
+
over an incomplete turn. The replacement remains one contiguous prefix under snapshot CAS.
|
|
6751
|
+
|
|
6752
|
+
Provider chronology and external effect authority answer different questions (ADR 0269).
|
|
6753
|
+
A matching `tool-result` with `outcome: 'error'` and an application code such as `UNKNOWN`
|
|
6754
|
+
closes the provider exchange; it does **not** prove the external effect failed or succeeded.
|
|
6755
|
+
Compaction changes the model-history projection, not the canonical event journal or the
|
|
6756
|
+
retained terminal admission receipt. The `durability/effect` intent, accepted proof and
|
|
6757
|
+
uncertain outcome remain available after compaction and archive restore. A reconstructed
|
|
6758
|
+
`createLocalStepDurability` using the original `(conversationId, runId, effectName)` returns
|
|
6759
|
+
the accepted proof, reconciles a bare intent, or returns `uncertain` without calling `run`
|
|
6760
|
+
again. It does not deduplicate a new run or a newly named effect. Standalone effect callers
|
|
6761
|
+
still own the exclusive execution lease; sharing a ledger is not an atomic claim.
|
|
6762
|
+
An application-owned receipt outside that journal retains its own recovery rules and must
|
|
6763
|
+
not be discarded because a history turn became compactable.
|
|
6764
|
+
|
|
6709
6765
|
### Compacting without the store
|
|
6710
6766
|
|
|
6711
6767
|
The *selection* inside compaction needs no store, no version and no runtime, so
|
|
@@ -22288,6 +22344,16 @@ projection, budgeting and structured compaction; `isAssistantHistoryEvidence` ap
|
|
|
22288
22344
|
compatibility default omits it. Approval message schemas are
|
|
22289
22345
|
`AgentToolApprovalRequestPartSchema` and `AgentToolApprovalResponsePartSchema`.
|
|
22290
22346
|
|
|
22347
|
+
With `failedAssistant: 'assistant-marked'`, `selectCompactableHistory` and
|
|
22348
|
+
`structuredCompaction` admit a failed prefix only when the entire turn's tool chronology
|
|
22349
|
+
is complete. `eligibleMessages` stays raw: the summarizer must use the same policy in
|
|
22350
|
+
`projectAgentHistoryDetailed` and preserve non-success/uncertain outcomes in its summary.
|
|
22351
|
+
Even an empty opted-in failed assistant carries a non-success marker in that projection.
|
|
22352
|
+
Use `incompleteToolTurn: 'error'` to refuse a range the projector cannot represent.
|
|
22353
|
+
Compaction never deletes canonical effect events or the retained terminal receipt;
|
|
22354
|
+
chronological completeness does not settle an external effect. See the
|
|
22355
|
+
[failed-prefix recovery contract](../guide/agent-runtime.md#recovering-a-prefix-after-a-failed-turn).
|
|
22356
|
+
|
|
22291
22357
|
Model exports are `AgentLanguageModelProvider`, `AgentModelCapability`,
|
|
22292
22358
|
`AgentModelCapabilitySchema`, `AgentModelDescriptor`,
|
|
22293
22359
|
`AgentModelDescriptorSchema`, `AgentModelRegistry`, `AgentModelRegistryConfig`,
|
package/llms.txt
CHANGED
|
@@ -25,7 +25,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
25
25
|
- **stitchkit/primitives**: [llms/primitives.txt](llms/primitives.txt) 11.7 KB
|
|
26
26
|
- **stitchkit/server**: [llms/server.txt](llms/server.txt) 44.2 KB → [llms/server.2.txt](llms/server.2.txt) 20.5 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.3 KB → [llms/server.5.txt](llms/server.5.txt) 22.9 KB
|
|
27
27
|
- **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 46.9 KB
|
|
28
|
-
- **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 42.7 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt)
|
|
28
|
+
- **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 42.7 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 44.8 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 42.1 KB
|
|
29
29
|
- **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
|
|
30
30
|
- **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 11.0 KB
|
|
31
31
|
- **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt) 5.0 KB
|
package/package.json
CHANGED