stitchkit 0.111.3 → 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 +16 -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/entrypoints/cli.js +1 -1
- package/dist/entrypoints/tools.js +1 -1
- package/dist/{index-5as18gs2.js → index-a0vj9edp.js} +1 -1
- package/dist/{index-jprxv2an.js → index-bd7spznx.js} +14 -1
- package/dist/tools/cli/args.d.ts.map +1 -1
- package/dist/tools/cli/help.d.ts.map +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/cli.2.txt +1 -1
- package/llms/cli.txt +10 -1
- package/llms/stitchkit.txt +3 -3
- package/llms/{upgrading-0.101.0-0.111.0.txt → upgrading-0.103.0-0.112.0.txt} +34 -63
- package/llms/{upgrading-0.61.0-0.73.0.txt → upgrading-0.61.0-0.74.0.txt} +64 -3
- package/llms/{upgrading-0.74.0-0.100.0.txt → upgrading-0.75.0-0.102.0.txt} +63 -64
- package/llms/upgrading.txt +3 -3
- package/llms-full.txt +111 -5
- package/llms.txt +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,22 @@ 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
|
+
|
|
25
|
+
## [0.112.0] - 2026-10-24
|
|
26
|
+
|
|
27
|
+
### ⚠️ Breaking changes
|
|
28
|
+
|
|
29
|
+
**Who must act:** scripts that combine named array options with bare positional arguments without an explicit `positionals` policy must name the scalar fields or declare their destinations. Flag-only calls and explicitly declared positional policies need no migration.
|
|
30
|
+
|
|
31
|
+
- `stitchkit/cli` — **array options require named arguments or an explicit positional policy.** Without a declared `positionals` policy, a named array option together with any bare positional is now a usage error before dispatch. Schema-order inference could mistake the array's remaining elements for unrelated optional fields and execute a different call. Before: `app resolve --references alpha.md beta.md gamma.md` could assign `beta.md` and `gamma.md` to other fields. After: `app resolve --references alpha.md --references beta.md --references gamma.md`, or `app resolve --references:='["alpha.md","beta.md","gamma.md"]'`. Name scalar fields with flags too, or declare their exact positional policy. Command help describes one element per option; only a declared trailing positional array is variadic. See [ADR 0268](docs/decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md) and the [migration](docs/guide/upgrading.md).
|
|
32
|
+
**Affects:** `stitchkit/cli` createCli, parseCliArgs
|
|
33
|
+
|
|
18
34
|
## [0.111.3] - 2026-10-20
|
|
19
35
|
|
|
20
36
|
### Fixed
|
|
@@ -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";
|
package/dist/entrypoints/cli.js
CHANGED
|
@@ -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
|
|
@@ -1102,6 +1102,12 @@ function resolveCliView(flags, ascending) {
|
|
|
1102
1102
|
// src/tools/cli/args.ts
|
|
1103
1103
|
function buildToolArgs(tokens, fields, fieldFor, declaredPositionals, allowUnknown) {
|
|
1104
1104
|
const { flags, jsonFields, literalBooleanFlags, positionals } = tokens;
|
|
1105
|
+
if (declaredPositionals === undefined && positionals.length > 0) {
|
|
1106
|
+
const arrayFlag = [...flags.keys()].find((key) => fieldFor(key)?.kind === "array");
|
|
1107
|
+
if (arrayFlag !== undefined) {
|
|
1108
|
+
throw new CliArgumentError2(`--${arrayFlag} cannot be combined with automatic positional arguments. Repeat --${arrayFlag} for each element or use --${arrayFlag}:=JSON; name other fields with flags, or declare a positional policy.`);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1105
1111
|
const toolArgs = {};
|
|
1106
1112
|
const fillable = declaredPositionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...declaredPositionals];
|
|
1107
1113
|
const variadicTail = declaredPositionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
|
|
@@ -1660,7 +1666,7 @@ function typeLabel(schema) {
|
|
|
1660
1666
|
if (Array.isArray(schema.enum))
|
|
1661
1667
|
return schema.enum.join("|");
|
|
1662
1668
|
if (schema.type === "array")
|
|
1663
|
-
return "value
|
|
1669
|
+
return "value";
|
|
1664
1670
|
if (typeof schema.type === "string")
|
|
1665
1671
|
return schema.type;
|
|
1666
1672
|
return "value";
|
|
@@ -1822,6 +1828,13 @@ function renderCommandHelp(name, command, descriptor, applicationOptions = []) {
|
|
|
1822
1828
|
if (flag !== undefined) {
|
|
1823
1829
|
lines.push("", `A boolean flag is on alone or takes true/false: --${flag}, --${flag} false, --no-${flag}`);
|
|
1824
1830
|
}
|
|
1831
|
+
const arrays = [...kinds].filter(([, info]) => info.kind === "array");
|
|
1832
|
+
for (const [field] of arrays) {
|
|
1833
|
+
lines.push("", `Repeat --${field} <value> for each element, or assign the whole array with --${field}:=JSON.`);
|
|
1834
|
+
}
|
|
1835
|
+
if (arrays.length > 0 && descriptor.positionals === undefined) {
|
|
1836
|
+
lines.push("Array options cannot be combined with automatic positional arguments; name other fields with flags.");
|
|
1837
|
+
}
|
|
1825
1838
|
lines.push("", ...jsonValueHelp(fields), "");
|
|
1826
1839
|
}
|
|
1827
1840
|
const applicationLines = applicationOptionLines(applicationOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,aAAa,CAAC;AAMjE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,aAAa,CAAC;AAMjE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;AAwHD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAC7B,MAAM,GAAE;IACN,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,GACL,aAAa,CAsBf;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,GAC9B,qBAAqB,CAyDvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAkIvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAsCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAkIvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAsCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,CAyER"}
|
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/cli.2.txt
CHANGED
|
@@ -281,7 +281,7 @@ SDK nor the `ai` peer.
|
|
|
281
281
|
|--------|------|---------|
|
|
282
282
|
| `createCli` | function | build and run a CLI from contracts — [guide](../guide/cli.md) |
|
|
283
283
|
| `defineCliCommand` | function | define one Zod-typed CLI-only executable command with optional validated-result presentation/exit policy |
|
|
284
|
-
| `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical (advanced) |
|
|
284
|
+
| `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical; named array options together with bare positionals require an explicit `positionals` policy (advanced) |
|
|
285
285
|
| `routeCliArgv` | function | select the command out of argv without duplicating the global-option grammar (advanced) |
|
|
286
286
|
| `extractCliGlobalOptions` | function | lift the application's own global options out of argv before routing (advanced) |
|
|
287
287
|
| `coerceJsonArgs` | function | the second half of `parseCliArgs` — parse array/object values a consumer sends itself, including discovered MCP object guards restored from JSON Schema, without the `stitchkit/tools` barrel |
|
package/llms/cli.txt
CHANGED
|
@@ -247,6 +247,15 @@ string, the schema says what it should be:
|
|
|
247
247
|
| `z.record(z.string(), z.unknown())` | `--data '{"code":"007"}'` or `--data.code=007` → `"007"` |
|
|
248
248
|
| `.optional()` / `.default()` | not required |
|
|
249
249
|
|
|
250
|
+
An array option takes **one value per occurrence**, never a bare list after the flag.
|
|
251
|
+
Repeat it (`--tag a --tag b`) or assign the whole array (`--tag:='["a","b"]'`).
|
|
252
|
+
Without an explicit command `positionals` policy, combining any named array option
|
|
253
|
+
with bare positionals is refused before dispatch: schema-order inference could otherwise
|
|
254
|
+
assign the remaining array elements to unrelated fields. This includes short aliases,
|
|
255
|
+
dotted array leaves, whole-array JSON and tokens after `--`, regardless of token order.
|
|
256
|
+
Name the scalar fields too, or declare their exact positional destinations. An explicitly
|
|
257
|
+
declared trailing positional array is the variadic form described below.
|
|
258
|
+
|
|
250
259
|
Use the inline `:=` form to assign a whole JSON value without scalar coercion:
|
|
251
260
|
|
|
252
261
|
```bash
|
|
@@ -522,7 +531,7 @@ Declared aliases render beside their canonical options, for example
|
|
|
522
531
|
|
|
523
532
|
The argument table and `Application options:` show bounds from their JSON Schema,
|
|
524
533
|
for example `<integer> [>=1, <=50]`, `<string> [length >=1, length <=12]`, and
|
|
525
|
-
`<value
|
|
534
|
+
`<value> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
|
|
526
535
|
and `<=` include the endpoint; a zero limit is displayed too. Only limits the
|
|
527
536
|
schema declares are shown: the safe-integer range every `z.int()` carries is the
|
|
528
537
|
type, not a bound, so a bare integer prints `<integer>`, `.min(1)` prints `>=1` and
|
package/llms/stitchkit.txt
CHANGED
|
@@ -85,12 +85,12 @@ own, recorded as an ADR.
|
|
|
85
85
|
| `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
|
|
86
86
|
| `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
|
|
87
87
|
| `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
|
|
88
|
-
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the
|
|
88
|
+
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the 57 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
89
89
|
| `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
|
|
90
90
|
| `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
91
91
|
| `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
|
|
92
92
|
| `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
|
|
93
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the
|
|
93
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
94
94
|
| `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
|
|
95
95
|
| `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
|
|
96
96
|
| `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
|
|
@@ -102,7 +102,7 @@ own, recorded as an ADR.
|
|
|
102
102
|
| `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
|
|
103
103
|
| `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
|
|
104
104
|
| `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
|
|
105
|
-
| `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the
|
|
105
|
+
| `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
|
|
106
106
|
| `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
|
|
107
107
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
108
108
|
| `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
|
|
@@ -1,14 +1,45 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.103.0 → 0.112.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.112.0
|
|
13
|
+
|
|
14
|
+
**Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
|
|
15
|
+
|
|
16
|
+
An array flag consumes one value. Automatic schema-order positionals cannot distinguish additional array elements from values intended for unrelated fields, so the combination is refused before any handler or stdin read. The rule is independent of token order, includes aliases, dotted array leaves and whole-array JSON, and `--` does not bypass it. See [ADR 0268](../decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md).
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
# before: the last two words could populate unrelated fields
|
|
20
|
+
app resolve --references alpha.md beta.md gamma.md
|
|
21
|
+
# after: repeat the option or assign the whole array
|
|
22
|
+
app resolve --references alpha.md --references beta.md --references gamma.md
|
|
23
|
+
app resolve --references:='["alpha.md","beta.md","gamma.md"]'
|
|
24
|
+
|
|
25
|
+
# before: even an intended scalar positional has an implicit destination
|
|
26
|
+
app resolve project-one --references alpha.md
|
|
27
|
+
# after: name it
|
|
28
|
+
app resolve --projectId project-one --references alpha.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Applications that intend positional syntax declare its destinations on the available command:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
createCli({ ...config, positionals: { resolve: ['projectId'] } })
|
|
35
|
+
// app resolve project-one --references alpha.md
|
|
36
|
+
|
|
37
|
+
createCli({ ...config, positionals: { resolve: ['references'] } })
|
|
38
|
+
// app resolve alpha.md beta.md gamma.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
A declared trailing array accepts all remaining positional elements. Giving that same field both a flag and positional elements remains an error. An empty policy accepts flags only. Policies still target exact available command names: a partial dynamic catalogue needs no policy for an unavailable command to enforce this admission rule.
|
|
42
|
+
|
|
12
43
|
## Released migration: 0.111.0
|
|
13
44
|
|
|
14
45
|
**Who must act:** applications whose raw routes call `parseBody` on JSON larger than 1 MiB, and applications whose OAuth clients send `/register` or `/token` bodies larger than 64 KiB.
|
|
@@ -874,63 +905,3 @@ For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
|
|
|
874
905
|
from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
|
|
875
906
|
missing files, permissions and unsafe paths still throw. See the
|
|
876
907
|
[journal guide](application-kernel.md#bounded-local-diagnostic-journal).
|
|
877
|
-
|
|
878
|
-
## Released migration: 0.102.0
|
|
879
|
-
|
|
880
|
-
### `view_file` receives an array, not an array encoded as text
|
|
881
|
-
|
|
882
|
-
**Who must act:** callers sending `paths` as a JSON-encoded array string, or
|
|
883
|
-
matching the former media-extension refusal for that input. Managed MCP,
|
|
884
|
-
Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
|
|
885
|
-
reports an input-validation error. Correct single paths and arrays need no change.
|
|
886
|
-
|
|
887
|
-
```ts
|
|
888
|
-
// Before
|
|
889
|
-
{ paths: '["image.png"]' }
|
|
890
|
-
// After
|
|
891
|
-
{ paths: ['image.png'] }
|
|
892
|
-
// One file may also be a string
|
|
893
|
-
{ paths: 'image.png' }
|
|
894
|
-
```
|
|
895
|
-
|
|
896
|
-
The same rule applies to an array element containing another encoded array.
|
|
897
|
-
Do not change generic string-union coercion: path strings remain strings.
|
|
898
|
-
A legitimate filename such as `[preview].PNG` is still accepted. Local
|
|
899
|
-
unsupported-extension errors now include the caller's path and extension;
|
|
900
|
-
match the error code rather than the former generic message.
|
|
901
|
-
|
|
902
|
-
## Released migration: 0.101.0
|
|
903
|
-
|
|
904
|
-
### `TelegramInitDataUser` is `TelegramUser`
|
|
905
|
-
|
|
906
|
-
**Who must act:** code that names the type `TelegramInitDataUser` from
|
|
907
|
-
`stitchkit/telegram`. The record is the same; its name now says it is any
|
|
908
|
-
Telegram user, since `parseTelegramUser(ctx.from)` returns it for a Bot API user
|
|
909
|
-
too.
|
|
910
|
-
|
|
911
|
-
```ts
|
|
912
|
-
// Before
|
|
913
|
-
import type { TelegramInitDataUser } from 'stitchkit/telegram'
|
|
914
|
-
function ensureAccount(user: TelegramInitDataUser) {}
|
|
915
|
-
// After
|
|
916
|
-
import type { TelegramUser } from 'stitchkit/telegram'
|
|
917
|
-
function ensureAccount(user: TelegramUser) {}
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
### `TELEGRAM_BOT_TOKEN_PATTERN` matches the secret half only
|
|
921
|
-
|
|
922
|
-
**Who must act:** code that uses `TELEGRAM_BOT_TOKEN_PATTERN` to find or cut a
|
|
923
|
-
whole token. It now matches what follows `<bot id>:`, so a masking replace keeps
|
|
924
|
-
the bot's id — `123456:[redacted]`. Masking needs nothing any more: `redact` and
|
|
925
|
-
every logger on it mask bot tokens by shape; remove the pattern from
|
|
926
|
-
`sensitiveUrlPatterns`, and use `redactTelegramBotToken(text)` for a string of
|
|
927
|
-
your own.
|
|
928
|
-
|
|
929
|
-
```ts
|
|
930
|
-
// Before
|
|
931
|
-
createJsonLogger({ sensitiveUrlPatterns: [TELEGRAM_BOT_TOKEN_PATTERN] })
|
|
932
|
-
text.replace(new RegExp(TELEGRAM_BOT_TOKEN_PATTERN.source, 'g'), '[redacted]')
|
|
933
|
-
// After
|
|
934
|
-
createJsonLogger({})
|
|
935
|
-
redactTelegramBotToken(text)
|
|
936
|
-
```
|
|
@@ -1,14 +1,75 @@
|
|
|
1
|
-
# Upgrading 0.61.0 → 0.
|
|
1
|
+
# Upgrading 0.61.0 → 0.74.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.61.0 → 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.61.0 → 0.
|
|
9
|
+
# Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.74.0
|
|
13
|
+
|
|
14
|
+
One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
|
|
15
|
+
planning the request, before anything was sent. A server refusal is unchanged.
|
|
16
|
+
|
|
17
|
+
### If you match on the text of a client-side refusal
|
|
18
|
+
|
|
19
|
+
A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
|
|
20
|
+
invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
|
|
21
|
+
arrive as an `ApiError` in the same shape a server validation failure uses.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// before
|
|
25
|
+
catch (e) {
|
|
26
|
+
if (/Missing path param/.test(e.message)) …
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// after
|
|
30
|
+
catch (e) {
|
|
31
|
+
if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
|
|
32
|
+
}
|
|
33
|
+
// e.details.issues[0].path === 'id'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`status` is what separates the two worlds, and it is not new — `0` has always meant *this never
|
|
37
|
+
reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
|
|
38
|
+
|
|
39
|
+
| | `code` | `status` |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| the client refused your arguments | `VALIDATION_ERROR` | `0` |
|
|
42
|
+
| the server refused your arguments | `VALIDATION_ERROR` | `400` |
|
|
43
|
+
|
|
44
|
+
`details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
|
|
45
|
+
and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
|
|
46
|
+
`stitchkit/server`.
|
|
47
|
+
|
|
48
|
+
### If you are on `createHttpClient` and your call site relied on a synchronous throw
|
|
49
|
+
|
|
50
|
+
This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
|
|
51
|
+
**synchronously** on the Ky-backed client — before the call returned a promise — so
|
|
52
|
+
`api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
|
|
53
|
+
client rejected normally. They now reject on both.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// before, on createHttpClient only
|
|
57
|
+
try {
|
|
58
|
+
api.upload({}) // threw here
|
|
59
|
+
} catch (e) { … }
|
|
60
|
+
|
|
61
|
+
// after, on both transports
|
|
62
|
+
await api.upload({}).catch(handler)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
|
|
66
|
+
longer catches anything — which was already true on the other transport.
|
|
67
|
+
|
|
68
|
+
Not a migration, but worth knowing: a missing multipart file used to be reported as
|
|
69
|
+
`UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
|
|
70
|
+
where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
|
|
71
|
+
validation stays on the server.
|
|
72
|
+
|
|
12
73
|
## Released migration: 0.73.0
|
|
13
74
|
|
|
14
75
|
Two breaking changes. Nothing you send to a server changed, and only one of these
|
|
@@ -1,14 +1,74 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.75.0 → 0.102.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.102.0
|
|
13
|
+
|
|
14
|
+
### `view_file` receives an array, not an array encoded as text
|
|
15
|
+
|
|
16
|
+
**Who must act:** callers sending `paths` as a JSON-encoded array string, or
|
|
17
|
+
matching the former media-extension refusal for that input. Managed MCP,
|
|
18
|
+
Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
|
|
19
|
+
reports an input-validation error. Correct single paths and arrays need no change.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Before
|
|
23
|
+
{ paths: '["image.png"]' }
|
|
24
|
+
// After
|
|
25
|
+
{ paths: ['image.png'] }
|
|
26
|
+
// One file may also be a string
|
|
27
|
+
{ paths: 'image.png' }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The same rule applies to an array element containing another encoded array.
|
|
31
|
+
Do not change generic string-union coercion: path strings remain strings.
|
|
32
|
+
A legitimate filename such as `[preview].PNG` is still accepted. Local
|
|
33
|
+
unsupported-extension errors now include the caller's path and extension;
|
|
34
|
+
match the error code rather than the former generic message.
|
|
35
|
+
|
|
36
|
+
## Released migration: 0.101.0
|
|
37
|
+
|
|
38
|
+
### `TelegramInitDataUser` is `TelegramUser`
|
|
39
|
+
|
|
40
|
+
**Who must act:** code that names the type `TelegramInitDataUser` from
|
|
41
|
+
`stitchkit/telegram`. The record is the same; its name now says it is any
|
|
42
|
+
Telegram user, since `parseTelegramUser(ctx.from)` returns it for a Bot API user
|
|
43
|
+
too.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// Before
|
|
47
|
+
import type { TelegramInitDataUser } from 'stitchkit/telegram'
|
|
48
|
+
function ensureAccount(user: TelegramInitDataUser) {}
|
|
49
|
+
// After
|
|
50
|
+
import type { TelegramUser } from 'stitchkit/telegram'
|
|
51
|
+
function ensureAccount(user: TelegramUser) {}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### `TELEGRAM_BOT_TOKEN_PATTERN` matches the secret half only
|
|
55
|
+
|
|
56
|
+
**Who must act:** code that uses `TELEGRAM_BOT_TOKEN_PATTERN` to find or cut a
|
|
57
|
+
whole token. It now matches what follows `<bot id>:`, so a masking replace keeps
|
|
58
|
+
the bot's id — `123456:[redacted]`. Masking needs nothing any more: `redact` and
|
|
59
|
+
every logger on it mask bot tokens by shape; remove the pattern from
|
|
60
|
+
`sensitiveUrlPatterns`, and use `redactTelegramBotToken(text)` for a string of
|
|
61
|
+
your own.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// Before
|
|
65
|
+
createJsonLogger({ sensitiveUrlPatterns: [TELEGRAM_BOT_TOKEN_PATTERN] })
|
|
66
|
+
text.replace(new RegExp(TELEGRAM_BOT_TOKEN_PATTERN.source, 'g'), '[redacted]')
|
|
67
|
+
// After
|
|
68
|
+
createJsonLogger({})
|
|
69
|
+
redactTelegramBotToken(text)
|
|
70
|
+
```
|
|
71
|
+
|
|
12
72
|
## Released migration: 0.100.0
|
|
13
73
|
|
|
14
74
|
### watch capacity and session/live/delivery adoption
|
|
@@ -1026,64 +1086,3 @@ schema.
|
|
|
1026
1086
|
`stitchkit/live`, the watch hub, the keyspace and the trust fence are all
|
|
1027
1087
|
additive. Adopt them when you want them; the guide is
|
|
1028
1088
|
[Live data](./live.md).
|
|
1029
|
-
|
|
1030
|
-
## Released migration: 0.74.0
|
|
1031
|
-
|
|
1032
|
-
One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
|
|
1033
|
-
planning the request, before anything was sent. A server refusal is unchanged.
|
|
1034
|
-
|
|
1035
|
-
### If you match on the text of a client-side refusal
|
|
1036
|
-
|
|
1037
|
-
A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
|
|
1038
|
-
invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
|
|
1039
|
-
arrive as an `ApiError` in the same shape a server validation failure uses.
|
|
1040
|
-
|
|
1041
|
-
```ts
|
|
1042
|
-
// before
|
|
1043
|
-
catch (e) {
|
|
1044
|
-
if (/Missing path param/.test(e.message)) …
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
// after
|
|
1048
|
-
catch (e) {
|
|
1049
|
-
if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
|
|
1050
|
-
}
|
|
1051
|
-
// e.details.issues[0].path === 'id'
|
|
1052
|
-
```
|
|
1053
|
-
|
|
1054
|
-
`status` is what separates the two worlds, and it is not new — `0` has always meant *this never
|
|
1055
|
-
reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
|
|
1056
|
-
|
|
1057
|
-
| | `code` | `status` |
|
|
1058
|
-
|---|---|---|
|
|
1059
|
-
| the client refused your arguments | `VALIDATION_ERROR` | `0` |
|
|
1060
|
-
| the server refused your arguments | `VALIDATION_ERROR` | `400` |
|
|
1061
|
-
|
|
1062
|
-
`details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
|
|
1063
|
-
and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
|
|
1064
|
-
`stitchkit/server`.
|
|
1065
|
-
|
|
1066
|
-
### If you are on `createHttpClient` and your call site relied on a synchronous throw
|
|
1067
|
-
|
|
1068
|
-
This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
|
|
1069
|
-
**synchronously** on the Ky-backed client — before the call returned a promise — so
|
|
1070
|
-
`api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
|
|
1071
|
-
client rejected normally. They now reject on both.
|
|
1072
|
-
|
|
1073
|
-
```ts
|
|
1074
|
-
// before, on createHttpClient only
|
|
1075
|
-
try {
|
|
1076
|
-
api.upload({}) // threw here
|
|
1077
|
-
} catch (e) { … }
|
|
1078
|
-
|
|
1079
|
-
// after, on both transports
|
|
1080
|
-
await api.upload({}).catch(handler)
|
|
1081
|
-
```
|
|
1082
|
-
|
|
1083
|
-
A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
|
|
1084
|
-
longer catches anything — which was already true on the other transport.
|
|
1085
|
-
|
|
1086
|
-
Not a migration, but worth knowing: a missing multipart file used to be reported as
|
|
1087
|
-
`UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
|
|
1088
|
-
where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
|
|
1089
|
-
validation stays on the server.
|
package/llms/upgrading.txt
CHANGED
|
@@ -11,9 +11,9 @@ Contains: Guide: Upgrading, general (docs/guide/upgrading.md)
|
|
|
11
11
|
|
|
12
12
|
Load this slice, then every range slice between your installed version and the target:
|
|
13
13
|
|
|
14
|
-
- 0.
|
|
15
|
-
- 0.
|
|
16
|
-
- 0.61.0 → 0.
|
|
14
|
+
- 0.103.0 → 0.112.0: `llms/upgrading-0.103.0-0.112.0.txt`
|
|
15
|
+
- 0.75.0 → 0.102.0: `llms/upgrading-0.75.0-0.102.0.txt`
|
|
16
|
+
- 0.61.0 → 0.74.0: `llms/upgrading-0.61.0-0.74.0.txt`
|
|
17
17
|
- 0.44.0 → 0.60.0: `llms/upgrading-0.44.0-0.60.0.txt`
|
|
18
18
|
- 0.37.0 → 0.37.0: `llms/upgrading-0.37.0.txt`
|
|
19
19
|
|
package/llms-full.txt
CHANGED
|
@@ -77,12 +77,12 @@ own, recorded as an ADR.
|
|
|
77
77
|
| `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
|
|
78
78
|
| `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
|
|
79
79
|
| `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
|
|
80
|
-
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the
|
|
80
|
+
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the 57 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
81
81
|
| `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
|
|
82
82
|
| `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
83
83
|
| `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
|
|
84
84
|
| `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
|
|
85
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the
|
|
85
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
86
86
|
| `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
|
|
87
87
|
| `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
|
|
88
88
|
| `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
|
|
@@ -94,7 +94,7 @@ own, recorded as an ADR.
|
|
|
94
94
|
| `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
|
|
95
95
|
| `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
|
|
96
96
|
| `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
|
|
97
|
-
| `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the
|
|
97
|
+
| `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
|
|
98
98
|
| `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
|
|
99
99
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
100
100
|
| `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
|
|
@@ -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
|
|
@@ -9941,6 +9997,15 @@ string, the schema says what it should be:
|
|
|
9941
9997
|
| `z.record(z.string(), z.unknown())` | `--data '{"code":"007"}'` or `--data.code=007` → `"007"` |
|
|
9942
9998
|
| `.optional()` / `.default()` | not required |
|
|
9943
9999
|
|
|
10000
|
+
An array option takes **one value per occurrence**, never a bare list after the flag.
|
|
10001
|
+
Repeat it (`--tag a --tag b`) or assign the whole array (`--tag:='["a","b"]'`).
|
|
10002
|
+
Without an explicit command `positionals` policy, combining any named array option
|
|
10003
|
+
with bare positionals is refused before dispatch: schema-order inference could otherwise
|
|
10004
|
+
assign the remaining array elements to unrelated fields. This includes short aliases,
|
|
10005
|
+
dotted array leaves, whole-array JSON and tokens after `--`, regardless of token order.
|
|
10006
|
+
Name the scalar fields too, or declare their exact positional destinations. An explicitly
|
|
10007
|
+
declared trailing positional array is the variadic form described below.
|
|
10008
|
+
|
|
9944
10009
|
Use the inline `:=` form to assign a whole JSON value without scalar coercion:
|
|
9945
10010
|
|
|
9946
10011
|
```bash
|
|
@@ -10216,7 +10281,7 @@ Declared aliases render beside their canonical options, for example
|
|
|
10216
10281
|
|
|
10217
10282
|
The argument table and `Application options:` show bounds from their JSON Schema,
|
|
10218
10283
|
for example `<integer> [>=1, <=50]`, `<string> [length >=1, length <=12]`, and
|
|
10219
|
-
`<value
|
|
10284
|
+
`<value> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
|
|
10220
10285
|
and `<=` include the endpoint; a zero limit is displayed too. Only limits the
|
|
10221
10286
|
schema declares are shown: the safe-integer range every `z.int()` carries is the
|
|
10222
10287
|
type, not a bound, so a bare integer prints `<integer>`, `.min(1)` prints `>=1` and
|
|
@@ -16193,6 +16258,37 @@ analytics policy belong to the application.
|
|
|
16193
16258
|
|
|
16194
16259
|
# Upgrading stitchkit
|
|
16195
16260
|
|
|
16261
|
+
## Released migration: 0.112.0
|
|
16262
|
+
|
|
16263
|
+
**Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
|
|
16264
|
+
|
|
16265
|
+
An array flag consumes one value. Automatic schema-order positionals cannot distinguish additional array elements from values intended for unrelated fields, so the combination is refused before any handler or stdin read. The rule is independent of token order, includes aliases, dotted array leaves and whole-array JSON, and `--` does not bypass it. See [ADR 0268](../decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md).
|
|
16266
|
+
|
|
16267
|
+
```sh
|
|
16268
|
+
# before: the last two words could populate unrelated fields
|
|
16269
|
+
app resolve --references alpha.md beta.md gamma.md
|
|
16270
|
+
# after: repeat the option or assign the whole array
|
|
16271
|
+
app resolve --references alpha.md --references beta.md --references gamma.md
|
|
16272
|
+
app resolve --references:='["alpha.md","beta.md","gamma.md"]'
|
|
16273
|
+
|
|
16274
|
+
# before: even an intended scalar positional has an implicit destination
|
|
16275
|
+
app resolve project-one --references alpha.md
|
|
16276
|
+
# after: name it
|
|
16277
|
+
app resolve --projectId project-one --references alpha.md
|
|
16278
|
+
```
|
|
16279
|
+
|
|
16280
|
+
Applications that intend positional syntax declare its destinations on the available command:
|
|
16281
|
+
|
|
16282
|
+
```ts
|
|
16283
|
+
createCli({ ...config, positionals: { resolve: ['projectId'] } })
|
|
16284
|
+
// app resolve project-one --references alpha.md
|
|
16285
|
+
|
|
16286
|
+
createCli({ ...config, positionals: { resolve: ['references'] } })
|
|
16287
|
+
// app resolve alpha.md beta.md gamma.md
|
|
16288
|
+
```
|
|
16289
|
+
|
|
16290
|
+
A declared trailing array accepts all remaining positional elements. Giving that same field both a flag and positional elements remains an error. An empty policy accepts flags only. Policies still target exact available command names: a partial dynamic catalogue needs no policy for an unavailable command to enforce this admission rule.
|
|
16291
|
+
|
|
16196
16292
|
## Released migration: 0.111.0
|
|
16197
16293
|
|
|
16198
16294
|
**Who must act:** applications whose raw routes call `parseBody` on JSON larger than 1 MiB, and applications whose OAuth clients send `/register` or `/token` bodies larger than 64 KiB.
|
|
@@ -22248,6 +22344,16 @@ projection, budgeting and structured compaction; `isAssistantHistoryEvidence` ap
|
|
|
22248
22344
|
compatibility default omits it. Approval message schemas are
|
|
22249
22345
|
`AgentToolApprovalRequestPartSchema` and `AgentToolApprovalResponsePartSchema`.
|
|
22250
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
|
+
|
|
22251
22357
|
Model exports are `AgentLanguageModelProvider`, `AgentModelCapability`,
|
|
22252
22358
|
`AgentModelCapabilitySchema`, `AgentModelDescriptor`,
|
|
22253
22359
|
`AgentModelDescriptorSchema`, `AgentModelRegistry`, `AgentModelRegistryConfig`,
|
|
@@ -23410,7 +23516,7 @@ SDK nor the `ai` peer.
|
|
|
23410
23516
|
|--------|------|---------|
|
|
23411
23517
|
| `createCli` | function | build and run a CLI from contracts — [guide](../guide/cli.md) |
|
|
23412
23518
|
| `defineCliCommand` | function | define one Zod-typed CLI-only executable command with optional validated-result presentation/exit policy |
|
|
23413
|
-
| `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical (advanced) |
|
|
23519
|
+
| `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical; named array options together with bare positionals require an explicit `positionals` policy (advanced) |
|
|
23414
23520
|
| `routeCliArgv` | function | select the command out of argv without duplicating the global-option grammar (advanced) |
|
|
23415
23521
|
| `extractCliGlobalOptions` | function | lift the application's own global options out of argv before routing (advanced) |
|
|
23416
23522
|
| `coerceJsonArgs` | function | the second half of `parseCliArgs` — parse array/object values a consumer sends itself, including discovered MCP object guards restored from JSON Schema, without the `stitchkit/tools` barrel |
|
package/llms.txt
CHANGED
|
@@ -18,14 +18,14 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
18
18
|
- **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
|
|
19
19
|
- **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
|
|
20
20
|
- **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.8 KB
|
|
21
|
-
- **stitchkit/cli**: [llms/cli.txt](llms/cli.txt)
|
|
21
|
+
- **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 45.3 KB → [llms/cli.2.txt](llms/cli.2.txt) 21.4 KB
|
|
22
22
|
- **stitchkit/cli/publish**: [llms/cli-publish.txt](llms/cli-publish.txt) 1.5 KB
|
|
23
23
|
- **stitchkit/remote**: [llms/remote.txt](llms/remote.txt) 1.0 KB
|
|
24
24
|
- **stitchkit/contract**: [llms/contract.txt](llms/contract.txt) 31.9 KB
|
|
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
|
|
@@ -64,9 +64,9 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
64
64
|
|
|
65
65
|
## Upgrading slices
|
|
66
66
|
- **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 12.7 KB
|
|
67
|
-
- **Upgrading 0.
|
|
68
|
-
- **Upgrading 0.
|
|
69
|
-
- **Upgrading 0.61.0 → 0.
|
|
67
|
+
- **Upgrading 0.103.0 → 0.112.0**: [llms/upgrading-0.103.0-0.112.0.txt](llms/upgrading-0.103.0-0.112.0.txt) 46.6 KB
|
|
68
|
+
- **Upgrading 0.75.0 → 0.102.0**: [llms/upgrading-0.75.0-0.102.0.txt](llms/upgrading-0.75.0-0.102.0.txt) 44.8 KB
|
|
69
|
+
- **Upgrading 0.61.0 → 0.74.0**: [llms/upgrading-0.61.0-0.74.0.txt](llms/upgrading-0.61.0-0.74.0.txt) 43.5 KB
|
|
70
70
|
- **Upgrading 0.44.0 → 0.60.0**: [llms/upgrading-0.44.0-0.60.0.txt](llms/upgrading-0.44.0-0.60.0.txt) 43.9 KB
|
|
71
71
|
- **Upgrading 0.37.0 → 0.37.0**: [llms/upgrading-0.37.0.txt](llms/upgrading-0.37.0.txt) 6.2 KB
|
|
72
72
|
|
package/package.json
CHANGED