stitchkit 0.106.1 → 0.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/darwin-native.cjs +16 -4
- package/dist/agent-runtime/deferred-tool-types.d.ts +6 -27
- package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/browser.js +2 -3
- package/dist/entrypoints/agent-runtime/coding-tools.js +6 -8
- package/dist/entrypoints/agent-runtime/harness.js +7 -11
- package/dist/entrypoints/agent-runtime/realtime.js +2 -3
- package/dist/entrypoints/agent-runtime/sandbox.js +6 -8
- package/dist/entrypoints/agent-runtime.d.ts +2 -1
- package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime.js +20 -23
- package/dist/entrypoints/application/diagnostic-journal.js +3 -3
- package/dist/entrypoints/application/directory-inbox.js +8 -9
- package/dist/entrypoints/application/grammy.js +3 -3
- package/dist/entrypoints/application.js +7 -8
- package/dist/entrypoints/cli/publish.js +10 -11
- package/dist/entrypoints/cli.js +12 -16
- package/dist/entrypoints/contract.js +1 -1
- package/dist/entrypoints/files/packaging.d.ts +1 -1
- package/dist/entrypoints/files/packaging.d.ts.map +1 -1
- package/dist/entrypoints/files/packaging.js +99 -47
- package/dist/entrypoints/files.js +16 -16
- package/dist/entrypoints/index.js +41 -41
- package/dist/entrypoints/node.js +27 -29
- package/dist/entrypoints/observability.js +10 -12
- package/dist/entrypoints/process.js +2 -2
- package/dist/entrypoints/react.js +3 -4
- package/dist/entrypoints/remote.js +8 -9
- package/dist/entrypoints/server.js +48 -51
- package/dist/entrypoints/telegram/html.js +3 -3
- package/dist/entrypoints/telegram/screens.js +5 -5
- package/dist/entrypoints/telegram.js +9 -10
- package/dist/entrypoints/testing.js +8 -11
- package/dist/entrypoints/tools/connections.js +11 -11
- package/dist/entrypoints/tools/invoker.js +5 -9
- package/dist/entrypoints/tools/mcp.js +8 -14
- package/dist/entrypoints/tools.js +19 -25
- package/dist/entrypoints/tracking.js +3 -3
- package/dist/files/native-packaging-layout.d.ts +6 -2
- package/dist/files/native-packaging-layout.d.ts.map +1 -1
- package/dist/files/native-packaging.d.ts +45 -10
- package/dist/files/native-packaging.d.ts.map +1 -1
- package/dist/{index-v5ee8ath.js → index-1h2zv8rx.js} +10 -40
- package/dist/index-2kbysk9s.js +42 -0
- package/dist/{index-wbhdzxar.js → index-2s6fpehp.js} +5 -5
- package/dist/{index-4vsby8n8.js → index-4f37d3bg.js} +1 -1
- package/dist/{index-ksfagmyz.js → index-4qh90tyw.js} +8 -8
- package/dist/{index-yvfk3y36.js → index-636mggad.js} +4 -3
- package/dist/{index-f199nfq5.js → index-6y9t2fwz.js} +7 -7
- package/dist/{index-azx12jgv.js → index-7r74re56.js} +1 -1
- package/dist/{index-w8etpm8j.js → index-9j2atjte.js} +1 -1
- package/dist/{index-dsnjzb62.js → index-bnf8s6v3.js} +1 -1
- package/dist/{index-pz3y6b6g.js → index-cx2nh595.js} +3 -3
- package/dist/{index-2k91mewf.js → index-dm2fv45z.js} +9 -9
- package/dist/{index-9bskshe3.js → index-dwf0gymy.js} +10 -10
- package/dist/{index-qaqbdm7s.js → index-h7qms8f9.js} +8 -8
- package/dist/{index-drs41arz.js → index-ktjmgq9p.js} +1 -1
- package/dist/{index-1ptj98e0.js → index-mbf4h8kp.js} +2 -2
- package/dist/{index-916yh4e2.js → index-mep4sb48.js} +14 -14
- package/dist/{index-wdy68sh6.js → index-njs9gvrh.js} +17 -17
- package/dist/{index-sj28htvf.js → index-pvh3z03x.js} +1 -1
- package/dist/{index-r393tnfp.js → index-q6crhe1n.js} +4 -4
- package/dist/{index-z23rfxhj.js → index-xmgjtkvr.js} +1 -1
- package/dist/{index-gr5g3xfw.js → index-yz8x0hbx.js} +1 -1
- package/dist/{index-gxm9rc97.js → index-zrtrjkbf.js} +1 -1
- package/dist/{index-1pwwan01.js → index-zsqt5q98.js} +5 -5
- package/dist/internal/darwin-binding-error.d.ts +9 -1
- package/dist/internal/darwin-binding-error.d.ts.map +1 -1
- package/dist/internal/darwin-binding.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts +0 -7
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/runtime-tool-declaration.d.ts +11 -0
- package/dist/tools/runtime-tool-declaration.d.ts.map +1 -1
- package/dist/tools/runtime-tool.d.ts +2 -3
- package/dist/tools/runtime-tool.d.ts.map +1 -1
- package/llms/files-packaging.txt +10 -6
- package/llms/process.txt +57 -15
- package/llms/stitchkit.txt +3 -3
- package/llms/{upgrading-0.37.0-0.53.0.txt → upgrading-0.37.0-0.58.0.txt} +209 -3
- package/llms/{upgrading-0.55.0-0.68.0.txt → upgrading-0.59.0-0.71.0.txt} +149 -209
- package/llms/{upgrading-0.69.0-0.95.0.txt → upgrading-0.72.0-0.97.0.txt} +76 -149
- package/llms/{upgrading-0.96.0-0.106.0.txt → upgrading-0.98.0-0.107.0.txt} +56 -83
- package/llms/upgrading.txt +4 -4
- package/llms-full.txt +123 -31
- package/llms.txt +6 -6
- package/package.json +2 -1
- package/dist/{index-cazts87s.js → index-07dcf2yn.js} +3 -3
- package/dist/{index-n1nszyk0.js → index-7jvwrjqa.js} +3 -3
- package/dist/{index-cmzvhhtd.js → index-85qve8mq.js} +3 -3
- package/dist/{index-rpzewktb.js → index-fynr93w4.js} +3 -3
- package/dist/{index-37asdw3a.js → index-k7qdkh3n.js} +3 -3
- package/dist/{index-x7w1z6pf.js → index-q4hjtyye.js} +4 -4
- package/dist/{index-7n68nmc6.js → index-y3nemndz.js} +3 -3
- package/dist/{index-12zsej7b.js → index-y70v24cw.js} +3 -3
- package/dist/{index-pzb63z66.js → index-ykdcnq1f.js} +3 -3
|
@@ -1,14 +1,160 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.59.0 → 0.71.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.59.0 → 0.71.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.59.0 → 0.71.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.71.0
|
|
13
|
+
|
|
14
|
+
The Agent coding tools. Two of the three changes are visible to the compiler;
|
|
15
|
+
the third is the one to read carefully, because nothing will point at it.
|
|
16
|
+
|
|
17
|
+
### If you implement `authorize`
|
|
18
|
+
|
|
19
|
+
The operation union gained `edit`, `list` and `glob` and lost `patch`. An
|
|
20
|
+
exhaustive matcher stops compiling and the compiler shows you every arm. **A
|
|
21
|
+
matcher with a default branch does not**, and that is the dangerous case:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// before — and after this upgrade, silently wrong in both directions
|
|
25
|
+
if (request.operation === 'patch') return reviewPatch(request)
|
|
26
|
+
return true // now also authorizes edit, list and glob
|
|
27
|
+
// …or: return false // now also kills edit_file
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// after
|
|
32
|
+
switch (request.operation) {
|
|
33
|
+
case 'edit': return reviewEdit(request) // the old `patch` payload, unchanged
|
|
34
|
+
case 'list':
|
|
35
|
+
case 'glob': return true // or your own policy
|
|
36
|
+
// …existing read / write / search / shell / artifact-read arms
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`write` gained `createsDirectories` — the workspace-relative directories the
|
|
41
|
+
call would create, outermost first, reported **before** anything is created. A
|
|
42
|
+
host that wants to refuse implicit directory creation now can.
|
|
43
|
+
|
|
44
|
+
### If you call `apply_patch`
|
|
45
|
+
|
|
46
|
+
It is `edit_file`, and it is one call:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// before
|
|
50
|
+
const read = await readFile({ path })
|
|
51
|
+
await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: true })
|
|
52
|
+
await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: false })
|
|
53
|
+
|
|
54
|
+
// after
|
|
55
|
+
await editFile({ path, oldText, newText })
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`expectedSha256` is optional and still refuses a stale base with `CONFLICT` when
|
|
59
|
+
you pass it; `edit_file` returns the resulting `sha256`, so a chain of edits
|
|
60
|
+
never needs to re-read. If you key an approval policy or a UI label on the string
|
|
61
|
+
`apply_patch`, update the key — nothing will fail loudly.
|
|
62
|
+
|
|
63
|
+
### If you match on `INTERNAL_SERVER_ERROR` from a coding tool
|
|
64
|
+
|
|
65
|
+
Ordinary outcomes no longer arrive that way. A missing file is `NOT_FOUND`, an
|
|
66
|
+
existing file without `overwrite` is `CONFLICT`, an ambiguous snippet is
|
|
67
|
+
`CONFLICT` with the occurrence count, a path outside the root is `FORBIDDEN`.
|
|
68
|
+
Code that treated any coding-tool failure as an internal fault will now see
|
|
69
|
+
codes it did not before; code that showed the model an empty error now has a
|
|
70
|
+
sentence and a `hint` to show it. Host-level causes are unchanged and still
|
|
71
|
+
scrubbed.
|
|
72
|
+
|
|
73
|
+
### If you write files into new directories
|
|
74
|
+
|
|
75
|
+
Nothing to change: `write_file` creates missing parents inside the root. Read
|
|
76
|
+
`createdDirectories` in the result if you want to notice a typo — a path that
|
|
77
|
+
was a failure before is now a successful write into a new tree.
|
|
78
|
+
|
|
79
|
+
### If you want a step to know its context budget
|
|
80
|
+
|
|
81
|
+
Opt in by reading it; nothing is injected for you:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
loop: {
|
|
85
|
+
prepareStep: ({ contextUsage }) => {
|
|
86
|
+
const used = contextUsage?.usedTokens
|
|
87
|
+
if (used?.provenance === 'unavailable') return {} // no step has landed yet
|
|
88
|
+
const fraction = (used?.value ?? 0) / (contextUsage?.contextWindow ?? 1)
|
|
89
|
+
// …render it wherever you put it
|
|
90
|
+
return {}
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Put it at the **tail** of the conversation rather than in the system
|
|
96
|
+
instructions unless you have a reason: changing the system prompt on every step
|
|
97
|
+
invalidates the provider's prefix cache for the whole conversation, and on a long
|
|
98
|
+
run that is a multiple of the input cost.
|
|
99
|
+
|
|
100
|
+
## Released migration: 0.70.0
|
|
101
|
+
|
|
102
|
+
### Descriptor-backed Agent filesystem containment
|
|
103
|
+
|
|
104
|
+
Built-in coding file/search tools and `createAgentHarnessFileResources` now require a runtime
|
|
105
|
+
that can address an opened directory descriptor: Linux `/proc/self/fd`, or the packaged macOS
|
|
106
|
+
Node-API backend added in 0.70.1. This is what keeps a mutable parent rename or outside-symlink replacement from changing
|
|
107
|
+
the authorized target between validation and the actual effect.
|
|
108
|
+
|
|
109
|
+
No call-site change is needed on those platforms. The 0.70.0 notes incorrectly inferred macOS and
|
|
110
|
+
FreeBSD support from `/dev/fd`; macOS is restored by 0.70.1 and FreeBSD remains unsupported. On
|
|
111
|
+
Windows or another platform without that
|
|
112
|
+
boundary, move the built-in filesystem operations to a supported worker or replace them with
|
|
113
|
+
application-owned tools backed by an equivalent native handle API. They fail closed rather than
|
|
114
|
+
falling back to path spelling. `run_command` remains separately available under its explicit
|
|
115
|
+
executable alias and authorization policy; this change does not claim an executable sandbox.
|
|
116
|
+
|
|
117
|
+
## Released migration: 0.69.0
|
|
118
|
+
|
|
119
|
+
### Direct coding-tool operation names
|
|
120
|
+
|
|
121
|
+
`createAgentCodingTools` no longer prefixes durable operation identity with `coding_`, and the
|
|
122
|
+
unguarded exact-string edit tool is gone. Update approval maps, presenters and tests together:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// before
|
|
126
|
+
{ coding_read_file: 'approved', coding_search: 'approved', coding_patch_file: 'user-approval' }
|
|
127
|
+
|
|
128
|
+
// after
|
|
129
|
+
{ read_file: 'approved', search_files: 'approved', apply_patch: 'user-approval' }
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The full mapping is `coding_read_file → read_file`, `coding_write_file → write_file`,
|
|
133
|
+
`coding_search → search_files`, `coding_patch_file → apply_patch`, `coding_shell → run_command`,
|
|
134
|
+
`coding_read_artifact → read_output` and `harness_read_resource → read_resource`. Replace
|
|
135
|
+
`coding_edit_file` with `read_file` followed by guarded `apply_patch`; `read_file` now returns the
|
|
136
|
+
required SHA-256. If the host declares no executable aliases, expect `run_command` to be absent.
|
|
137
|
+
|
|
138
|
+
### Durable Agent approval message variants
|
|
139
|
+
|
|
140
|
+
If a renderer, store adapter or export pipeline exhaustively switches over
|
|
141
|
+
`AgentMessage.role`, add the `tool` branch. If it switches over
|
|
142
|
+
`AgentMessagePart.type`, add `tool-approval-request` and `tool-approval-response`.
|
|
143
|
+
They are durable provider-continuation evidence: preserve them in storage and provider history;
|
|
144
|
+
a UI may render them as approval state or intentionally omit their visual row.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
// before
|
|
148
|
+
const unreachable: never = message.role
|
|
149
|
+
|
|
150
|
+
// after
|
|
151
|
+
if (message.role === 'tool') renderToolContinuation(message.parts)
|
|
152
|
+
else renderExistingRole(message)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
No data migration is needed. The schema still accepts all earlier records, and applications that
|
|
156
|
+
do not exhaustively branch over these unions compile unchanged.
|
|
157
|
+
|
|
12
158
|
## Released migration: 0.68.0
|
|
13
159
|
|
|
14
160
|
### Make Unix transport selection explicit outside Bun
|
|
@@ -994,209 +1140,3 @@ createAgentRuntimeStore({
|
|
|
994
1140
|
`runAgentStoreConformance()` against the migrated adapter before switching production traffic.
|
|
995
1141
|
If an application implements `AgentRuntimeStore` directly, its duplicate result must also include
|
|
996
1142
|
the canonical `run` and the retained `assistant` for a terminal run.
|
|
997
|
-
|
|
998
|
-
## Released migration: 0.58.0
|
|
999
|
-
|
|
1000
|
-
### The default history projection rejects invalid chronology
|
|
1001
|
-
|
|
1002
|
-
`projectAgentHistory` no longer forwards records a provider contract cannot
|
|
1003
|
-
accept. A completed assistant record before the first user message, and an
|
|
1004
|
-
assistant record whose tool calls have no matching results, are omitted with an
|
|
1005
|
-
inspectable decision instead of being sent upstream:
|
|
1006
|
-
|
|
1007
|
-
```ts
|
|
1008
|
-
// before — a leading assistant record was forwarded as-is
|
|
1009
|
-
projectAgentHistory(messages)
|
|
1010
|
-
// after — opt in explicitly, and only where the provider contract permits it
|
|
1011
|
-
projectAgentHistory(messages, { leadingAssistant: 'allow' })
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
Two consequences the changelog does not spell out. First, the projection can now
|
|
1015
|
-
return **fewer** messages than the history holds, so any assertion or metric
|
|
1016
|
-
that compared projected length against stored length will move; read the
|
|
1017
|
-
detailed projection instead — it reports what was omitted and why, which is the
|
|
1018
|
-
supported way to see the difference. Second, the omission is silent to the
|
|
1019
|
-
provider but not to you: if a conversation suddenly loses its leading context,
|
|
1020
|
-
the decision record is where that shows up, not the transcript.
|
|
1021
|
-
|
|
1022
|
-
### Operator events redact `internalCause` by default
|
|
1023
|
-
|
|
1024
|
-
Raw provider and tool failures no longer travel in operator events unless the
|
|
1025
|
-
sink asks for them:
|
|
1026
|
-
|
|
1027
|
-
```ts
|
|
1028
|
-
// before — internalCause was present
|
|
1029
|
-
createAgentObservability({ write })
|
|
1030
|
-
// after — an explicit operator-only opt-in
|
|
1031
|
-
createAgentObservability({ write, includeInternalCause: true })
|
|
1032
|
-
```
|
|
1033
|
-
|
|
1034
|
-
The consequence to check before upgrading: any dashboard, alert or log
|
|
1035
|
-
processor keyed on `internalCause` goes blind the moment you upgrade, and it
|
|
1036
|
-
goes blind quietly — the field is absent, not empty. Set the flag on the
|
|
1037
|
-
operator sink you own. Product delivery stays redacted regardless of the flag;
|
|
1038
|
-
this option cannot widen what reaches a user.
|
|
1039
|
-
|
|
1040
|
-
## Released migration: 0.57.0
|
|
1041
|
-
|
|
1042
|
-
### Duplicate admission results carry the complete identity
|
|
1043
|
-
|
|
1044
|
-
Custom `AgentRuntimeStore` adapters must persist and return the input and
|
|
1045
|
-
assistant identities associated with an idempotency key:
|
|
1046
|
-
|
|
1047
|
-
```ts
|
|
1048
|
-
// before
|
|
1049
|
-
return { outcome: 'duplicate', runId, snapshot }
|
|
1050
|
-
|
|
1051
|
-
// after
|
|
1052
|
-
return { outcome: 'duplicate', input, inputMessageId, runId, assistantMessageId, snapshot }
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
Prefer replacing the custom aggregate reducer with `createAgentRuntimeStore()`;
|
|
1056
|
-
its admission record and transaction driver implement this contract
|
|
1057
|
-
automatically. Historical note: 0.59.0 reshaped this driver again, so an adapter
|
|
1058
|
-
crossing both versions should read that section first and migrate once.
|
|
1059
|
-
|
|
1060
|
-
### `AgentRuntimeEvent` adds a post-commit `admission` variant
|
|
1061
|
-
|
|
1062
|
-
Add it to any exhaustive publisher switch. Its `assistant` is either the pending
|
|
1063
|
-
placeholder for a new assignment or the canonical persisted assistant for a
|
|
1064
|
-
duplicate:
|
|
1065
|
-
|
|
1066
|
-
```ts
|
|
1067
|
-
case 'admission':
|
|
1068
|
-
await persistProductProjection(event.input, event.run, event.assistant)
|
|
1069
|
-
break
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
The consequence for an exhaustive switch written without a `default` branch is a
|
|
1073
|
-
compile error, which is the point. The consequence for a switch that *has* a
|
|
1074
|
-
`default` is worse and silent: post-commit admissions fall into it and are
|
|
1075
|
-
projected as an unknown event. Grep for publisher switches before upgrading.
|
|
1076
|
-
|
|
1077
|
-
## Released migration: 0.56.0
|
|
1078
|
-
|
|
1079
|
-
### Surface manifests are version 2
|
|
1080
|
-
|
|
1081
|
-
`operation.tools` could not describe a role-selected MCP surface, a different
|
|
1082
|
-
Agent or CLI selection, or an advertised `extend` schema, so projections moved
|
|
1083
|
-
out of the canonical operation:
|
|
1084
|
-
|
|
1085
|
-
```ts
|
|
1086
|
-
// before
|
|
1087
|
-
manifest.operations[0].tools.MCP
|
|
1088
|
-
// after
|
|
1089
|
-
manifest.toolSurfaces.find((s) => s.transport === 'MCP' && s.surface === null)?.tools
|
|
1090
|
-
|
|
1091
|
-
// before
|
|
1092
|
-
buildSurfaceManifest({ mcpSurfaces: { admin: { services, extend } } })
|
|
1093
|
-
// after
|
|
1094
|
-
buildSurfaceManifest({ mcpSurfaces: { admin: { services } }, mcpPreparation: { extend } })
|
|
1095
|
-
```
|
|
1096
|
-
|
|
1097
|
-
A committed snapshot is regenerated once, deliberately: `manifestVersion` is
|
|
1098
|
-
`2`, and `ConformanceTransport` gained `REALTIME`, so any exhaustive
|
|
1099
|
-
`Record<ConformanceTransport, …>` must handle it.
|
|
1100
|
-
|
|
1101
|
-
### `FILE_*` codes joined the error registry
|
|
1102
|
-
|
|
1103
|
-
`StitchErrorCode` gained `FILE_INVALID_PATH`, `FILE_OUTSIDE_ROOT`,
|
|
1104
|
-
`FILE_NOT_FOUND`, `FILE_NOT_REGULAR`, `FILE_INSPECTION_REJECTED`,
|
|
1105
|
-
`FILE_TOO_LARGE` and `FILE_EXISTS`. Only exhaustive maps break:
|
|
1106
|
-
|
|
1107
|
-
```ts
|
|
1108
|
-
// before — compiled while the registry had no file codes
|
|
1109
|
-
const copy: Record<StitchErrorCode, string> = { …, RATE_LIMITED: '…' }
|
|
1110
|
-
// after — add the seven managed-file codes (or use Partial<Record<…>>)
|
|
1111
|
-
```
|
|
1112
|
-
|
|
1113
|
-
Unexpected IO stays scrubbed as `INTERNAL_SERVER_ERROR`: the new codes are the
|
|
1114
|
-
caller-safe ones only.
|
|
1115
|
-
|
|
1116
|
-
### `ScopedAuthHook` is nominal
|
|
1117
|
-
|
|
1118
|
-
A hand-written function shaped like an auth hook is no longer assignable —
|
|
1119
|
-
identity now comes from the factory, so scope ownership and the inferred
|
|
1120
|
-
context cannot drift apart:
|
|
1121
|
-
|
|
1122
|
-
```ts
|
|
1123
|
-
// before — a structural stand-in
|
|
1124
|
-
const auth: ScopedAuthHook<Scopes> = async (ctx, endpoint) => { … }
|
|
1125
|
-
// after — create it, then compose domains
|
|
1126
|
-
const auth = createAuthHook({ resolve, rules })
|
|
1127
|
-
const composed = composeAuthHooks({ hooks: [auth, billingAuth], defaultScope: 'public' })
|
|
1128
|
-
```
|
|
1129
|
-
|
|
1130
|
-
### Managed-file inspectors also run on reads
|
|
1131
|
-
|
|
1132
|
-
An inspector is no longer write-only, and it has a finite default deadline
|
|
1133
|
-
(15 s). Make it read-aware and idempotent — a read carries no
|
|
1134
|
-
`declaredMediaType`:
|
|
1135
|
-
|
|
1136
|
-
```ts
|
|
1137
|
-
// before
|
|
1138
|
-
inspect: ({ declaredMediaType }) => inspectDeclaredType(declaredMediaType!)
|
|
1139
|
-
// after
|
|
1140
|
-
inspect: ({ prefix, declaredMediaType, signal }) =>
|
|
1141
|
-
inspectBytes(prefix, { declaredMediaType, signal })
|
|
1142
|
-
```
|
|
1143
|
-
|
|
1144
|
-
Set `inspectionTimeoutMs` explicitly when 15 seconds is the wrong budget.
|
|
1145
|
-
|
|
1146
|
-
### Direct async-operation binding needs a wire-stable ID
|
|
1147
|
-
|
|
1148
|
-
A direct binding reuses the start output as the follow-up wire input, so the ID
|
|
1149
|
-
schema must parse to itself (`z.input` equals `z.output`, no transform,
|
|
1150
|
-
coercion, default or overwrite). Anything else is parsed twice:
|
|
1151
|
-
|
|
1152
|
-
```ts
|
|
1153
|
-
// before — a transform silently ran on start and again on every follow-up
|
|
1154
|
-
defineAsyncOperationContract({ binding: 'direct', id: z.string().transform(Number) })
|
|
1155
|
-
// after — keep the wire shape, adapt explicitly
|
|
1156
|
-
defineAsyncOperationContract({
|
|
1157
|
-
binding: 'adapted',
|
|
1158
|
-
id,
|
|
1159
|
-
adapters: { idFromStart, inputFor },
|
|
1160
|
-
})
|
|
1161
|
-
```
|
|
1162
|
-
|
|
1163
|
-
## Released migration: 0.55.0
|
|
1164
|
-
|
|
1165
|
-
### Peer-free `implementRemote`
|
|
1166
|
-
|
|
1167
|
-
`implementRemote` now has one canonical, optional-peer-free owner. This keeps
|
|
1168
|
-
MCP SDK and AI SDK modules out of CLI bundles that only proxy HTTP calls:
|
|
1169
|
-
|
|
1170
|
-
```ts
|
|
1171
|
-
// before
|
|
1172
|
-
import { implementRemote } from 'stitchkit/tools'
|
|
1173
|
-
// after
|
|
1174
|
-
import { implementRemote } from 'stitchkit/remote'
|
|
1175
|
-
```
|
|
1176
|
-
|
|
1177
|
-
### Managed file boundary and strict auth returns
|
|
1178
|
-
|
|
1179
|
-
Create one boundary during application bootstrap and pass the capability, never
|
|
1180
|
-
a per-call directory or host path:
|
|
1181
|
-
|
|
1182
|
-
```ts
|
|
1183
|
-
import { createManagedFileBoundary } from 'stitchkit/files'
|
|
1184
|
-
|
|
1185
|
-
const files = await createManagedFileBoundary({ root: '/srv/app-files' })
|
|
1186
|
-
|
|
1187
|
-
// before
|
|
1188
|
-
defineDownloadTool({ defaultDir: '/srv/app-files', resolveUrl, ...common })
|
|
1189
|
-
defineUploadTool({ upload: (path) => provider.uploadFile(path), ...common })
|
|
1190
|
-
defineViewFileTool({ baseDir: '/srv/app-files', ...common })
|
|
1191
|
-
|
|
1192
|
-
// after
|
|
1193
|
-
defineDownloadTool({ files, resolveUrl, ...common })
|
|
1194
|
-
defineUploadTool({ files, upload: ({ bytes }) => provider.upload(bytes), ...common })
|
|
1195
|
-
defineViewFileTool({ files, ...common })
|
|
1196
|
-
```
|
|
1197
|
-
|
|
1198
|
-
Downloaded `path` is now relative to the boundary and MIME metadata is named
|
|
1199
|
-
`mediaType`. Update raw `mountDownload`/`mountUpload`/`mountViewFile` configs the
|
|
1200
|
-
same way. Auth predicates must explicitly return `true`, `false`, or a plain
|
|
1201
|
-
object of context fields; replace accidental `undefined` fallthroughs with the
|
|
1202
|
-
intended boolean.
|
|
@@ -1,14 +1,87 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.72.0 → 0.97.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.72.0 → 0.97.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.72.0 → 0.97.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.97.0
|
|
13
|
+
|
|
14
|
+
### schedule delivery
|
|
15
|
+
|
|
16
|
+
**Who must act:** consumers of `createAgentScheduleService`, exhaustive switches on
|
|
17
|
+
`AgentSchedule.state`, and operators opening existing agent-runtime SQLite stores.
|
|
18
|
+
|
|
19
|
+
- Stop old scheduler processes and back up SQLite before startup. The store migrates
|
|
20
|
+
transactionally to v4; old binaries cannot open it. Rollback uses the backup.
|
|
21
|
+
- Handle `failed` as a terminal schedule state. To refuse future delivery (including
|
|
22
|
+
recurring delivery), return `{ status: 'terminal', reason: 'destination closed' }`.
|
|
23
|
+
The occurrence remains unadvanced; `schedule/failed` carries `terminal: true`.
|
|
24
|
+
- A throw or `{ status: 'retry', reason: 'temporarily unavailable' }` retries the same
|
|
25
|
+
key after 1, 2, 4, 8, 16, 32, then 60 seconds. `nextAt` remains the original due time;
|
|
26
|
+
`retryAt`, `attempts` and `lastError` expose retry diagnostics. Success clears them.
|
|
27
|
+
- Resolve `void` only after durable consumer admission. Honor the supplied `signal`:
|
|
28
|
+
dispatch has a 30-second deadline and a 60-second lease. Durable deduplication by
|
|
29
|
+
`idempotencyKey` is required even after abort or crash; do not implement sleeps in dispatch.
|
|
30
|
+
- Stale/cancelled attempts emit no `schedule/fired` or `schedule/late`. Observe the
|
|
31
|
+
cancellation event instead of relying on a synthetic cancelled firing.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// before
|
|
35
|
+
async function dispatch(request) {
|
|
36
|
+
if (await destinationClosed(request.conversationId)) throw new Error('closed')
|
|
37
|
+
await admit(request)
|
|
38
|
+
}
|
|
39
|
+
// after: use this callback as createAgentScheduleService({ dispatch, ... })
|
|
40
|
+
async function dispatch(request) {
|
|
41
|
+
if (await destinationClosed(request.conversationId)) {
|
|
42
|
+
return { status: 'terminal', reason: 'destination closed' }
|
|
43
|
+
}
|
|
44
|
+
await admit({ ...request, signal: request.signal }) // durably deduplicates idempotencyKey
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Released migration: 0.96.0
|
|
49
|
+
|
|
50
|
+
### resource-context-admission
|
|
51
|
+
|
|
52
|
+
One breaking change in `stitchkit/application`: `ManagedResourceContext` gains a
|
|
53
|
+
required `admission`. Every context the kernel hands a resource already carries
|
|
54
|
+
it; only a context built by hand needs it.
|
|
55
|
+
|
|
56
|
+
1. **Give a hand-built resource context an `admission`.** **Who must act:** a
|
|
57
|
+
project whose tests call a resource's phase directly with a context object
|
|
58
|
+
they wrote themselves (`resource.close?.({ applicationId, signal, … })`).
|
|
59
|
+
The type checker names each one:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// before
|
|
63
|
+
await resource.close?.({ applicationId: 'test', signal, now, reportHealth, use })
|
|
64
|
+
// after
|
|
65
|
+
await resource.close?.({
|
|
66
|
+
applicationId: 'test',
|
|
67
|
+
signal,
|
|
68
|
+
now,
|
|
69
|
+
reportHealth,
|
|
70
|
+
use,
|
|
71
|
+
admission: { acquire: () => null, acquireWhenAccepting: () => new Promise(() => {}) },
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
A test that needs real admission starts the resource inside
|
|
76
|
+
`createApplication` instead.
|
|
77
|
+
|
|
78
|
+
2. **Nothing to do for grammY polling, but know what changed.** **Who must
|
|
79
|
+
act:** nobody. `grammyPollingResource` now admits updates by batch: it does
|
|
80
|
+
not fetch while the application is not accepting, and finishes the batch in
|
|
81
|
+
hand before `bot.stop()`. A project that wrote its own `getUpdates`
|
|
82
|
+
transformer for this (waiting on `app.admission` before returning a batch)
|
|
83
|
+
deletes it; keeping both waits twice and is harmless.
|
|
84
|
+
|
|
12
85
|
## Released migration: 0.95.0
|
|
13
86
|
|
|
14
87
|
One breaking change in `stitchkit/application`: the process lifecycle ledger
|
|
@@ -1003,149 +1076,3 @@ const snapshot: CreditWindowSnapshot = { state: 'open', capacityBytes: 100, /*
|
|
|
1003
1076
|
// after
|
|
1004
1077
|
const snapshot: CreditWindowSnapshot = { state: 'open', capacityBytes: 100, /* … */ waiting: 0 }
|
|
1005
1078
|
```
|
|
1006
|
-
|
|
1007
|
-
## Released migration: 0.71.0
|
|
1008
|
-
|
|
1009
|
-
The Agent coding tools. Two of the three changes are visible to the compiler;
|
|
1010
|
-
the third is the one to read carefully, because nothing will point at it.
|
|
1011
|
-
|
|
1012
|
-
### If you implement `authorize`
|
|
1013
|
-
|
|
1014
|
-
The operation union gained `edit`, `list` and `glob` and lost `patch`. An
|
|
1015
|
-
exhaustive matcher stops compiling and the compiler shows you every arm. **A
|
|
1016
|
-
matcher with a default branch does not**, and that is the dangerous case:
|
|
1017
|
-
|
|
1018
|
-
```ts
|
|
1019
|
-
// before — and after this upgrade, silently wrong in both directions
|
|
1020
|
-
if (request.operation === 'patch') return reviewPatch(request)
|
|
1021
|
-
return true // now also authorizes edit, list and glob
|
|
1022
|
-
// …or: return false // now also kills edit_file
|
|
1023
|
-
```
|
|
1024
|
-
|
|
1025
|
-
```ts
|
|
1026
|
-
// after
|
|
1027
|
-
switch (request.operation) {
|
|
1028
|
-
case 'edit': return reviewEdit(request) // the old `patch` payload, unchanged
|
|
1029
|
-
case 'list':
|
|
1030
|
-
case 'glob': return true // or your own policy
|
|
1031
|
-
// …existing read / write / search / shell / artifact-read arms
|
|
1032
|
-
}
|
|
1033
|
-
```
|
|
1034
|
-
|
|
1035
|
-
`write` gained `createsDirectories` — the workspace-relative directories the
|
|
1036
|
-
call would create, outermost first, reported **before** anything is created. A
|
|
1037
|
-
host that wants to refuse implicit directory creation now can.
|
|
1038
|
-
|
|
1039
|
-
### If you call `apply_patch`
|
|
1040
|
-
|
|
1041
|
-
It is `edit_file`, and it is one call:
|
|
1042
|
-
|
|
1043
|
-
```ts
|
|
1044
|
-
// before
|
|
1045
|
-
const read = await readFile({ path })
|
|
1046
|
-
await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: true })
|
|
1047
|
-
await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: false })
|
|
1048
|
-
|
|
1049
|
-
// after
|
|
1050
|
-
await editFile({ path, oldText, newText })
|
|
1051
|
-
```
|
|
1052
|
-
|
|
1053
|
-
`expectedSha256` is optional and still refuses a stale base with `CONFLICT` when
|
|
1054
|
-
you pass it; `edit_file` returns the resulting `sha256`, so a chain of edits
|
|
1055
|
-
never needs to re-read. If you key an approval policy or a UI label on the string
|
|
1056
|
-
`apply_patch`, update the key — nothing will fail loudly.
|
|
1057
|
-
|
|
1058
|
-
### If you match on `INTERNAL_SERVER_ERROR` from a coding tool
|
|
1059
|
-
|
|
1060
|
-
Ordinary outcomes no longer arrive that way. A missing file is `NOT_FOUND`, an
|
|
1061
|
-
existing file without `overwrite` is `CONFLICT`, an ambiguous snippet is
|
|
1062
|
-
`CONFLICT` with the occurrence count, a path outside the root is `FORBIDDEN`.
|
|
1063
|
-
Code that treated any coding-tool failure as an internal fault will now see
|
|
1064
|
-
codes it did not before; code that showed the model an empty error now has a
|
|
1065
|
-
sentence and a `hint` to show it. Host-level causes are unchanged and still
|
|
1066
|
-
scrubbed.
|
|
1067
|
-
|
|
1068
|
-
### If you write files into new directories
|
|
1069
|
-
|
|
1070
|
-
Nothing to change: `write_file` creates missing parents inside the root. Read
|
|
1071
|
-
`createdDirectories` in the result if you want to notice a typo — a path that
|
|
1072
|
-
was a failure before is now a successful write into a new tree.
|
|
1073
|
-
|
|
1074
|
-
### If you want a step to know its context budget
|
|
1075
|
-
|
|
1076
|
-
Opt in by reading it; nothing is injected for you:
|
|
1077
|
-
|
|
1078
|
-
```ts
|
|
1079
|
-
loop: {
|
|
1080
|
-
prepareStep: ({ contextUsage }) => {
|
|
1081
|
-
const used = contextUsage?.usedTokens
|
|
1082
|
-
if (used?.provenance === 'unavailable') return {} // no step has landed yet
|
|
1083
|
-
const fraction = (used?.value ?? 0) / (contextUsage?.contextWindow ?? 1)
|
|
1084
|
-
// …render it wherever you put it
|
|
1085
|
-
return {}
|
|
1086
|
-
},
|
|
1087
|
-
}
|
|
1088
|
-
```
|
|
1089
|
-
|
|
1090
|
-
Put it at the **tail** of the conversation rather than in the system
|
|
1091
|
-
instructions unless you have a reason: changing the system prompt on every step
|
|
1092
|
-
invalidates the provider's prefix cache for the whole conversation, and on a long
|
|
1093
|
-
run that is a multiple of the input cost.
|
|
1094
|
-
|
|
1095
|
-
## Released migration: 0.70.0
|
|
1096
|
-
|
|
1097
|
-
### Descriptor-backed Agent filesystem containment
|
|
1098
|
-
|
|
1099
|
-
Built-in coding file/search tools and `createAgentHarnessFileResources` now require a runtime
|
|
1100
|
-
that can address an opened directory descriptor: Linux `/proc/self/fd`, or the packaged macOS
|
|
1101
|
-
Node-API backend added in 0.70.1. This is what keeps a mutable parent rename or outside-symlink replacement from changing
|
|
1102
|
-
the authorized target between validation and the actual effect.
|
|
1103
|
-
|
|
1104
|
-
No call-site change is needed on those platforms. The 0.70.0 notes incorrectly inferred macOS and
|
|
1105
|
-
FreeBSD support from `/dev/fd`; macOS is restored by 0.70.1 and FreeBSD remains unsupported. On
|
|
1106
|
-
Windows or another platform without that
|
|
1107
|
-
boundary, move the built-in filesystem operations to a supported worker or replace them with
|
|
1108
|
-
application-owned tools backed by an equivalent native handle API. They fail closed rather than
|
|
1109
|
-
falling back to path spelling. `run_command` remains separately available under its explicit
|
|
1110
|
-
executable alias and authorization policy; this change does not claim an executable sandbox.
|
|
1111
|
-
|
|
1112
|
-
## Released migration: 0.69.0
|
|
1113
|
-
|
|
1114
|
-
### Direct coding-tool operation names
|
|
1115
|
-
|
|
1116
|
-
`createAgentCodingTools` no longer prefixes durable operation identity with `coding_`, and the
|
|
1117
|
-
unguarded exact-string edit tool is gone. Update approval maps, presenters and tests together:
|
|
1118
|
-
|
|
1119
|
-
```ts
|
|
1120
|
-
// before
|
|
1121
|
-
{ coding_read_file: 'approved', coding_search: 'approved', coding_patch_file: 'user-approval' }
|
|
1122
|
-
|
|
1123
|
-
// after
|
|
1124
|
-
{ read_file: 'approved', search_files: 'approved', apply_patch: 'user-approval' }
|
|
1125
|
-
```
|
|
1126
|
-
|
|
1127
|
-
The full mapping is `coding_read_file → read_file`, `coding_write_file → write_file`,
|
|
1128
|
-
`coding_search → search_files`, `coding_patch_file → apply_patch`, `coding_shell → run_command`,
|
|
1129
|
-
`coding_read_artifact → read_output` and `harness_read_resource → read_resource`. Replace
|
|
1130
|
-
`coding_edit_file` with `read_file` followed by guarded `apply_patch`; `read_file` now returns the
|
|
1131
|
-
required SHA-256. If the host declares no executable aliases, expect `run_command` to be absent.
|
|
1132
|
-
|
|
1133
|
-
### Durable Agent approval message variants
|
|
1134
|
-
|
|
1135
|
-
If a renderer, store adapter or export pipeline exhaustively switches over
|
|
1136
|
-
`AgentMessage.role`, add the `tool` branch. If it switches over
|
|
1137
|
-
`AgentMessagePart.type`, add `tool-approval-request` and `tool-approval-response`.
|
|
1138
|
-
They are durable provider-continuation evidence: preserve them in storage and provider history;
|
|
1139
|
-
a UI may render them as approval state or intentionally omit their visual row.
|
|
1140
|
-
|
|
1141
|
-
```ts
|
|
1142
|
-
// before
|
|
1143
|
-
const unreachable: never = message.role
|
|
1144
|
-
|
|
1145
|
-
// after
|
|
1146
|
-
if (message.role === 'tool') renderToolContinuation(message.parts)
|
|
1147
|
-
else renderExistingRole(message)
|
|
1148
|
-
```
|
|
1149
|
-
|
|
1150
|
-
No data migration is needed. The schema still accepts all earlier records, and applications that
|
|
1151
|
-
do not exhaustively branch over these unions compile unchanged.
|