stitchkit 0.67.0 → 0.68.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/dist/agent-runtime/admission-lanes.d.ts +1 -1
- package/dist/agent-runtime/compaction.d.ts +2 -2
- package/dist/agent-runtime/events.d.ts +1 -1
- package/dist/agent-runtime/history.d.ts +1 -1
- package/dist/agent-runtime/history.d.ts.map +1 -1
- package/dist/agent-runtime/injection.d.ts +1 -1
- package/dist/agent-runtime/managed-tools.d.ts +3 -3
- package/dist/agent-runtime/models.d.ts +1 -1
- package/dist/agent-runtime/observability.d.ts +1 -1
- package/dist/agent-runtime/prompt.d.ts +1 -1
- package/dist/agent-runtime/prompt.d.ts.map +1 -1
- package/dist/agent-runtime/protocol.d.ts +19 -1
- package/dist/agent-runtime/protocol.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts +5 -5
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime-internals.d.ts +1 -1
- package/dist/agent-runtime/runtime-result.d.ts +1 -1
- package/dist/agent-runtime/runtime.d.ts +14 -12
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +2 -2
- package/dist/agent-runtime/store.d.ts +2 -2
- package/dist/agent-runtime/terminal-commit.d.ts +2 -2
- package/dist/agent-runtime/terminal-status.d.ts +1 -1
- package/dist/agent-runtime-openrouter.d.ts +1 -1
- package/dist/agent-runtime.d.ts +15 -15
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +90 -30
- package/dist/application/admission.d.ts +131 -0
- package/dist/application/admission.d.ts.map +1 -0
- package/dist/application/channel.d.ts +106 -0
- package/dist/application/channel.d.ts.map +1 -0
- package/dist/application/events.d.ts +2 -2
- package/dist/application/grammy.d.ts +2 -2
- package/dist/application/graph.d.ts +1 -1
- package/dist/application/health.d.ts +1 -1
- package/dist/application/kernel.d.ts +3 -3
- package/dist/application/latest-sink.d.ts.map +1 -1
- package/dist/application/opentelemetry.d.ts +3 -3
- package/dist/application/resource.d.ts +1 -1
- package/dist/application/schedule.d.ts +1 -1
- package/dist/application/server-resource.d.ts +7 -9
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application-grammy.d.ts +1 -1
- package/dist/application-grammy.js +1 -1
- package/dist/application-opentelemetry.d.ts +1 -1
- package/dist/application-opentelemetry.js +1 -1
- package/dist/application.d.ts +11 -9
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +393 -24
- package/dist/browser/client-multipart.d.ts +1 -1
- package/dist/browser/client-url.d.ts +2 -2
- package/dist/browser/client.d.ts +4 -5
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/contract-stream.d.ts +5 -0
- package/dist/browser/contract-stream.d.ts.map +1 -0
- package/dist/browser/http.d.ts +9 -6
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts +12 -31
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/browser/stream.d.ts +5 -2
- package/dist/browser/stream.d.ts.map +1 -1
- package/dist/browser/transport.d.ts +3 -0
- package/dist/browser/transport.d.ts.map +1 -0
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +7 -7
- package/dist/contract/define.d.ts +34 -2
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors-factory.d.ts +1 -1
- package/dist/contract/errors.d.ts +4 -0
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/factory.d.ts +1 -1
- package/dist/contract/index.d.ts +7 -6
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +5 -1
- package/dist/contract/stream.d.ts +19 -0
- package/dist/contract/stream.d.ts.map +1 -0
- package/dist/files/boundary.d.ts +1 -1
- package/dist/files.d.ts +2 -2
- package/dist/{index-xxye8j3k.js → index-0w9abg87.js} +4 -0
- package/dist/{index-svqhcrrj.js → index-2ve29dzn.js} +159 -13
- package/dist/index-69m2278y.js +115 -0
- package/dist/{index-physbf4z.js → index-6wzr93cg.js} +1 -1
- package/dist/index-7etq650s.js +75 -0
- package/dist/index-9ky9hhg3.js +484 -0
- package/dist/{index-413xk7ga.js → index-cq9q73nf.js} +50 -1
- package/dist/{index-1pgeyyee.js → index-cszjsxy5.js} +25 -88
- package/dist/{index-wrhf06ak.js → index-cz32amcb.js} +8 -8
- package/dist/{index-6taryy00.js → index-dafax5md.js} +1 -1
- package/dist/index-g2j2m6vv.js +63 -0
- package/dist/{index-8mxadm34.js → index-nck3yx3y.js} +1102 -22
- package/dist/{index-y91zd0ch.js → index-pr0qsmjy.js} +3 -2
- package/dist/index-v5bayx1z.js +138 -0
- package/dist/{index-mfw1pec7.js → index-wqyrvhzz.js} +3 -3
- package/dist/{index-x8v8b7rc.js → index-zpyj7hsv.js} +330 -58
- package/dist/index.d.ts +10 -10
- package/dist/index.js +274 -109
- package/dist/internal/bounded-lines.d.ts +4 -0
- package/dist/internal/bounded-lines.d.ts.map +1 -0
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/observability-sink.d.ts +1 -1
- package/dist/node.d.ts +11 -10
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +11 -8
- package/dist/observability/audit.d.ts +5 -5
- package/dist/observability/context.d.ts +2 -2
- package/dist/observability/event.d.ts +2 -2
- package/dist/observability/index.d.ts +6 -6
- package/dist/observability/index.js +6 -7
- package/dist/react/entity-cache.d.ts +26 -1
- package/dist/react/entity-cache.d.ts.map +1 -1
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +136 -38
- package/dist/realtime/contract.d.ts +1 -1
- package/dist/realtime/index.d.ts +4 -4
- package/dist/realtime/rejection.d.ts +1 -1
- package/dist/realtime/request.d.ts +1 -1
- package/dist/realtime/socket.d.ts +2 -2
- package/dist/remote.d.ts +1 -1
- package/dist/remote.js +5 -6
- package/dist/server/bun.d.ts +3 -3
- package/dist/server/context-contribution.d.ts +1 -1
- package/dist/server/context.d.ts +4 -4
- package/dist/server/contract-stream.d.ts +5 -0
- package/dist/server/contract-stream.d.ts.map +1 -0
- package/dist/server/create.d.ts +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +3 -3
- package/dist/server/file.d.ts +1 -1
- package/dist/server/implement.d.ts +2 -2
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +31 -30
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +44 -286
- package/dist/server/lifecycle.d.ts +1 -1
- package/dist/server/logging.d.ts +1 -1
- package/dist/server/middleware/auth.d.ts +2 -2
- package/dist/server/multipart.d.ts +2 -2
- package/dist/server/node.d.ts +2 -2
- package/dist/server/openapi.d.ts +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/process-signal-common.d.ts +1 -1
- package/dist/server/process-signals.d.ts +1 -1
- package/dist/server/realtime.d.ts +4 -4
- package/dist/server/response-metadata.d.ts +1 -1
- package/dist/server/router.d.ts +1 -1
- package/dist/server/shutdown.d.ts +1 -1
- package/dist/server/socket-io-node.d.ts +3 -3
- package/dist/server/socket-io.d.ts +6 -6
- package/dist/server/stream.d.ts +3 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/streaming-route.d.ts +4 -2
- package/dist/server/streaming-route.d.ts.map +1 -1
- package/dist/server/types.d.ts +18 -8
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/unix-client-body.d.ts +4 -0
- package/dist/server/unix-client-body.d.ts.map +1 -0
- package/dist/server/unix-client-bun.d.ts +13 -0
- package/dist/server/unix-client-bun.d.ts.map +1 -0
- package/dist/server/unix-client-error.d.ts +9 -0
- package/dist/server/unix-client-error.d.ts.map +1 -0
- package/dist/server/unix-client.d.ts +25 -0
- package/dist/server/unix-client.d.ts.map +1 -0
- package/dist/testing/agent-store-conformance.d.ts +1 -1
- package/dist/testing/managed-resource-conformance-contract.d.ts +1 -1
- package/dist/testing/managed-resource-conformance-driver.d.ts +2 -2
- package/dist/testing/managed-resource-conformance-scenarios.d.ts +2 -2
- package/dist/testing/managed-resource-conformance.d.ts +2 -2
- package/dist/testing/surface-conformance.d.ts +3 -3
- package/dist/testing/surface-manifest.d.ts +5 -5
- package/dist/testing.d.ts +8 -8
- package/dist/testing.js +6 -5
- package/dist/tool-invoker.d.ts +9 -0
- package/dist/tool-invoker.d.ts.map +1 -0
- package/dist/tool-invoker.js +16 -0
- package/dist/tools/agent.d.ts +4 -4
- package/dist/tools/async-operation.d.ts +3 -3
- package/dist/tools/cli-command.d.ts +3 -3
- package/dist/tools/cli-format.d.ts +1 -1
- package/dist/tools/cli-policy.d.ts +1 -1
- package/dist/tools/cli-wait.d.ts +1 -1
- package/dist/tools/cli.d.ts +7 -7
- package/dist/tools/define-download-tool.d.ts +4 -4
- package/dist/tools/define-upload-tool.d.ts +3 -3
- package/dist/tools/define-view-file-tool.d.ts +3 -3
- package/dist/tools/define-wait-tool.d.ts +2 -2
- package/dist/tools/download-core.d.ts +2 -2
- package/dist/tools/execute.d.ts +2 -2
- package/dist/tools/flatten-join.d.ts +1 -1
- package/dist/tools/internal/surface-projector.d.ts +3 -3
- package/dist/tools/invoker.d.ts +4 -4
- package/dist/tools/lifecycle.d.ts +1 -1
- package/dist/tools/list-names.d.ts +2 -2
- package/dist/tools/managed-file-error.d.ts +1 -1
- package/dist/tools/manifest.d.ts +3 -3
- package/dist/tools/mcp-handler.d.ts +4 -4
- package/dist/tools/mcp-prepare.d.ts +8 -8
- package/dist/tools/mcp-round-policy.d.ts +1 -1
- package/dist/tools/mcp-round.d.ts +3 -3
- package/dist/tools/mcp-stdio-signals.d.ts +2 -2
- package/dist/tools/mcp-stdio.d.ts +3 -3
- package/dist/tools/mcp.d.ts +7 -7
- package/dist/tools/mount-download.d.ts +1 -1
- package/dist/tools/mount-upload.d.ts +1 -1
- package/dist/tools/mount.d.ts +5 -5
- package/dist/tools/native-definition.d.ts +2 -2
- package/dist/tools/native-mcp.d.ts +3 -3
- package/dist/tools/oauth-metadata.d.ts +1 -1
- package/dist/tools/oauth-provider.d.ts +1 -1
- package/dist/tools/presentation.d.ts +1 -1
- package/dist/tools/remote.d.ts +3 -3
- package/dist/tools/runtime-tool.d.ts +2 -2
- package/dist/tools/surface.d.ts +5 -5
- package/dist/tools/tool-logger.d.ts +1 -1
- package/dist/tools/toolkit.d.ts +7 -7
- package/dist/tools/transports.d.ts +2 -2
- package/dist/tools/upload-core.d.ts +1 -1
- package/dist/tools/view-file.d.ts +1 -1
- package/dist/tools.d.ts +42 -42
- package/dist/tools.js +27 -72
- package/llms-full.txt +506 -35
- package/package.json +8 -4
- package/dist/index-48ffdxgk.js +0 -6
- package/dist/index-pzyt11ch.js +0 -127
- package/dist/index-tvwcrx2d.js +0 -224
- package/dist/index-wd8g8z6e.js +0 -206
package/llms-full.txt
CHANGED
|
@@ -51,6 +51,7 @@ own, recorded as an ADR.
|
|
|
51
51
|
| `stitchkit/server` | server (Bun) | stable | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
|
|
52
52
|
| `stitchkit/node` | server (Node ≥ 22) | stable | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
|
|
53
53
|
| `stitchkit/tools` | server | stable | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
|
|
54
|
+
| `stitchkit/tools/invoker` | server | stable | peer-free `createToolInvoker` over the canonical contract tool runner |
|
|
54
55
|
| `stitchkit/cli` | server | stable | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
|
|
55
56
|
| `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
56
57
|
| `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
|
|
@@ -58,9 +59,9 @@ own, recorded as an ADR.
|
|
|
58
59
|
| `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the store and managed-resource conformance kits |
|
|
59
60
|
| `stitchkit/declaration` | build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
60
61
|
| `stitchkit/react` | browser | stable | `createCursorQuery`, `createCacheBridge` |
|
|
61
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 9 of the
|
|
62
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 9 of the 13 minors since 0.56.2, most recently 0.66.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
62
63
|
| `stitchkit/agent-runtime/openrouter` | server | evolving | isolated OpenRouter language-model adapter |
|
|
63
|
-
| `stitchkit/application` | server | evolving<br>_redefined in 3 of the
|
|
64
|
+
| `stitchkit/application` | server | evolving<br>_redefined in 3 of the 13 minors since 0.56.2, most recently 0.67.0_ | managed resource graph, readiness, admission, schedules and bounded shutdown |
|
|
64
65
|
| `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
|
|
65
66
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
66
67
|
|
|
@@ -159,7 +160,8 @@ map — feature → packages:
|
|
|
159
160
|
| anything (validation) | `zod` |
|
|
160
161
|
| `createServer` (Bun) | — (uses `Bun.serve`) |
|
|
161
162
|
| `serveNode` (Node ≥ 22) | `srvx` (+ `@types/bun` dev) |
|
|
162
|
-
|
|
|
163
|
+
| In-process contract tools (`stitchkit/tools/invoker`) | — |
|
|
164
|
+
| MCP / agent adapters (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
|
|
163
165
|
| Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
|
|
164
166
|
| OpenRouter runtime adapter (`stitchkit/agent-runtime/openrouter`) | `ai` `@openrouter/ai-sdk-provider` |
|
|
165
167
|
| MCP host/client tests | `@modelcontextprotocol/client` |
|
|
@@ -167,7 +169,7 @@ map — feature → packages:
|
|
|
167
169
|
| React data layer (`stitchkit/react`) | `@tanstack/react-query` `react-query-kit` |
|
|
168
170
|
| **Socket.IO server on Bun** | `socket.io` `@socket.io/bun-engine` |
|
|
169
171
|
| **Socket.IO server on Node** | `socket.io` |
|
|
170
|
-
| Socket.IO client | `socket.io-client` (
|
|
172
|
+
| Socket.IO client | `socket.io-client` (runtime peer; unrelated root declarations remain peer-free) |
|
|
171
173
|
| grammY lifecycle adapters (`stitchkit/application/grammy`) | `grammy` |
|
|
172
174
|
| OpenTelemetry gauges (`stitchkit/application/opentelemetry`) | `@opentelemetry/api` |
|
|
173
175
|
|
|
@@ -1521,6 +1523,57 @@ focused helper — not a sub-framework.
|
|
|
1521
1523
|
| `createCache()` + `cacheHeaders()` | in-memory TTL cache; `Cache-Control` builder |
|
|
1522
1524
|
| `createEventBus<EventMap>()` | typed in-process pub/sub |
|
|
1523
1525
|
|
|
1526
|
+
### Contract-first streams
|
|
1527
|
+
|
|
1528
|
+
Use an endpoint `stream` descriptor when the item schema and completion belong
|
|
1529
|
+
to the contract, rather than handing an application-owned `Response` to
|
|
1530
|
+
`rawResponse`:
|
|
1531
|
+
|
|
1532
|
+
```ts
|
|
1533
|
+
const Item = z.discriminatedUnion('kind', [
|
|
1534
|
+
z.object({ kind: z.literal('line'), text: z.string() }),
|
|
1535
|
+
z.object({ kind: z.literal('complete'), count: z.number().int() }),
|
|
1536
|
+
])
|
|
1537
|
+
|
|
1538
|
+
const reports = defineContract({ prefix: 'reports' }, {
|
|
1539
|
+
watch: {
|
|
1540
|
+
method: 'GET', path: '/:id/watch', desc: 'Watch one report',
|
|
1541
|
+
params: z.object({ id: z.string() }),
|
|
1542
|
+
stream: {
|
|
1543
|
+
item: Item,
|
|
1544
|
+
format: 'ndjson',
|
|
1545
|
+
maxFrameBytes: 64 * 1024,
|
|
1546
|
+
terminal: z.object({ kind: z.literal('complete') }).loose(),
|
|
1547
|
+
},
|
|
1548
|
+
},
|
|
1549
|
+
})
|
|
1550
|
+
|
|
1551
|
+
const service = implement(reports, {
|
|
1552
|
+
watch: async function* ({ params, signal }) {
|
|
1553
|
+
yield { kind: 'line', text: `starting ${params.id}` }
|
|
1554
|
+
if (signal.aborted) return
|
|
1555
|
+
yield { kind: 'complete', count: 1 }
|
|
1556
|
+
},
|
|
1557
|
+
})
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
The handler return is inferred as `AsyncIterable<z.output<typeof Item>>`; an
|
|
1561
|
+
invalid JavaScript producer is rejected before its value reaches the wire. Data,
|
|
1562
|
+
safe errors and normal end use a framework envelope. The default encoded frame
|
|
1563
|
+
limit is 256 KiB. `format` defaults to `ndjson`; `heartbeatMs` defaults to five
|
|
1564
|
+
seconds; `idleTimeoutSeconds` defaults to disabled; `lifetimeMs` is optional.
|
|
1565
|
+
|
|
1566
|
+
After headers, HTTP status can no longer report failure, so the stream sends a
|
|
1567
|
+
normalized code and never the raw internal exception. Normal producer completion
|
|
1568
|
+
sends an explicit `end`; when `terminal` is declared, at least one item must
|
|
1569
|
+
match it. Request abort and client iterator return abort `signal`, including a
|
|
1570
|
+
source waiting in `next()` or suspended at a yielded item.
|
|
1571
|
+
|
|
1572
|
+
Contract streams are HTTP-only and cannot declare `output`, `rawResponse`,
|
|
1573
|
+
multipart or tool exposure. They do not provide replay, cursors or durable
|
|
1574
|
+
subscriptions. Keep using `streamingRoute` for an application-owned protocol and
|
|
1575
|
+
`rawResponse` for arbitrary response bodies. → ADR 0117.
|
|
1576
|
+
|
|
1524
1577
|
### SSE streaming
|
|
1525
1578
|
|
|
1526
1579
|
`streamSSE` returns a `Response`, so its endpoint declares
|
|
@@ -1834,23 +1887,54 @@ your own `(pathname) => boolean`.
|
|
|
1834
1887
|
|
|
1835
1888
|
### Unix domain sockets
|
|
1836
1889
|
|
|
1837
|
-
The same typed client dials a local daemon's socket file
|
|
1838
|
-
([server side](server.md#local-daemon-over-a-unix-socket)):
|
|
1890
|
+
The same typed client dials a local daemon's socket file through an explicit,
|
|
1891
|
+
owned Bun/Node transport ([server side](server.md#local-daemon-over-a-unix-socket)):
|
|
1839
1892
|
|
|
1840
1893
|
```ts
|
|
1894
|
+
import { createHttpClient } from 'stitchkit'
|
|
1895
|
+
import { createUnixClientTransport } from 'stitchkit/server' // or stitchkit/node
|
|
1896
|
+
|
|
1897
|
+
const transport = createUnixClientTransport({
|
|
1898
|
+
socketPath: '/run/my-daemon.sock',
|
|
1899
|
+
maxRequestBytes: 4 * 1024 * 1024,
|
|
1900
|
+
maxResponseBytes: 16 * 1024 * 1024,
|
|
1901
|
+
})
|
|
1841
1902
|
const http = createHttpClient({
|
|
1842
|
-
baseUrl: 'http://
|
|
1843
|
-
|
|
1903
|
+
baseUrl: 'http://my-daemon', // URL/Host source; never dialled as TCP
|
|
1904
|
+
fetch: transport.fetch,
|
|
1905
|
+
retry: { limit: 0 },
|
|
1844
1906
|
})
|
|
1845
1907
|
const daemon = createClient(daemonContract, http)
|
|
1908
|
+
|
|
1909
|
+
// At application shutdown:
|
|
1910
|
+
await transport.close()
|
|
1846
1911
|
```
|
|
1847
1912
|
|
|
1848
|
-
`baseUrl` stays required
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1913
|
+
`baseUrl` stays required because it supplies the URL and `Host` header. The
|
|
1914
|
+
adapter structurally owns dispatch: relative and absolute redirects use the same
|
|
1915
|
+
socket, and a missing socket cannot fall through to that host over TCP. Defaults
|
|
1916
|
+
are 16 MiB request/response bodies, 64 KiB headers, 30 s to response headers,
|
|
1917
|
+
eight connections and five redirects.
|
|
1918
|
+
|
|
1919
|
+
`maxHeaderBytes` is enforced before exposing a response. Bun's owned parser
|
|
1920
|
+
counts the complete response head in wire bytes, including the status line and
|
|
1921
|
+
terminating blank line. Node passes the same configured integer unchanged to
|
|
1922
|
+
`http.request({ maxHeaderSize })`, so its native parser's documented header-size
|
|
1923
|
+
accounting is authoritative there. Exceeding either ceiling yields
|
|
1924
|
+
`UNIX_HEADERS_TOO_LARGE` with `delivery: 'response-received'`. A stalled body
|
|
1925
|
+
pauses its socket, and resuming preserves the exact chunked body.
|
|
1926
|
+
|
|
1927
|
+
`UnixClientTransportError` carries a stable `code` and `delivery`:
|
|
1928
|
+
`not-dispatched`, `possibly-dispatched` or `response-received`. Only the first
|
|
1929
|
+
proves that the remote operation did not begin; Stitchkit never silently retries
|
|
1930
|
+
an ambiguous write. Response consumption/cancellation belongs to the operation,
|
|
1931
|
+
and `close()` interrupts active work and destroys owned connections.
|
|
1932
|
+
|
|
1933
|
+
The legacy `createHttpClient({ unix: '/absolute/path' })` spelling remains a
|
|
1934
|
+
Bun-only convenience. On a non-Bun runtime it now refuses before dispatch
|
|
1935
|
+
instead of ignoring the selection and dialing TCP. `unix` and an injected
|
|
1936
|
+
`fetch` are mutually exclusive; use `createUnixClientTransport` for portable,
|
|
1937
|
+
explicit lifecycle ownership. → ADR 0116.
|
|
1854
1938
|
|
|
1855
1939
|
`trace: true` mints a fresh root trace per request. The stitchkit server
|
|
1856
1940
|
[continues an inbound `traceparent`](./observability.md#trace-context), so the
|
|
@@ -1954,12 +2038,58 @@ Abort and timeout do not emit `network_error` and are not retried. The same
|
|
|
1954
2038
|
options work for query, JSON, multipart and raw-response calls. Stitchkit does
|
|
1955
2039
|
not expose upload progress: Fetch has no portable upload-progress primitive.
|
|
1956
2040
|
|
|
2041
|
+
An injected transport failure is normalized to `UNKNOWN_ERROR` while its exact
|
|
2042
|
+
object remains available as `ApiError.cause`. This is how a bounded adapter can
|
|
2043
|
+
preserve facts the generic client cannot invent — for example a Unix transport's
|
|
2044
|
+
`not-dispatched`, `possibly-dispatched` or `response-received` state. Never replay
|
|
2045
|
+
an effect from `UNKNOWN_ERROR` alone; inspect the owned adapter's cause and retry
|
|
2046
|
+
only when it proves that dispatch did not happen.
|
|
2047
|
+
|
|
1957
2048
|
For an endpoint without contract arguments, pass only the options object:
|
|
1958
2049
|
|
|
1959
2050
|
```ts
|
|
1960
2051
|
await api.health.withOptions({ signal: controller.signal })
|
|
1961
2052
|
```
|
|
1962
2053
|
|
|
2054
|
+
### Injected delivery adapters
|
|
2055
|
+
|
|
2056
|
+
`ClientFetch` is the narrow composition seam for application-owned delivery.
|
|
2057
|
+
The contract still owns operation identity, request serialization and response
|
|
2058
|
+
validation; the adapter owns I/O, bounds and dispatch certainty:
|
|
2059
|
+
|
|
2060
|
+
```ts
|
|
2061
|
+
import { type ClientFetch, createClient } from 'stitchkit'
|
|
2062
|
+
|
|
2063
|
+
const delivery: ClientFetch = async (input, init) => {
|
|
2064
|
+
// Fixed deployment destination and policy are chosen here, not by caller data.
|
|
2065
|
+
return boundedFetch(input, { ...init, signal: init?.signal })
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
const query = createClient(queryContract, {
|
|
2069
|
+
baseUrl: 'https://service.internal',
|
|
2070
|
+
fetch: delivery,
|
|
2071
|
+
})
|
|
2072
|
+
const work = createClient(requestWorkContract, {
|
|
2073
|
+
baseUrl: 'https://service.internal',
|
|
2074
|
+
fetch: delivery,
|
|
2075
|
+
})
|
|
2076
|
+
```
|
|
2077
|
+
|
|
2078
|
+
The same adapter accepts unrelated contract shapes without learning their DTOs
|
|
2079
|
+
or operation inventory. `createClient` chooses method/path from the contract,
|
|
2080
|
+
serializes only the declared arguments, forwards `.withOptions(..., { signal })`
|
|
2081
|
+
and validates the response through the endpoint's output schema. A caller payload
|
|
2082
|
+
cannot replace the configured base URL or reserved operation path.
|
|
2083
|
+
|
|
2084
|
+
Contract metadata describes an effect; it does not authorize one. Authentication,
|
|
2085
|
+
scope and destination policy remain in the application/server boundary. A schema
|
|
2086
|
+
mismatch is an explicit validation failure and is not retried automatically. A
|
|
2087
|
+
timeout means the caller stopped waiting, not that the remote effect did not run.
|
|
2088
|
+
|
|
2089
|
+
Published declarations are checked from a clean tarball under both bundler and
|
|
2090
|
+
NodeNext resolution. The HTTP-only NodeNext proof uses `skipLibCheck: false` and
|
|
2091
|
+
installs no Socket.IO peer. → ADR 0120.
|
|
2092
|
+
|
|
1963
2093
|
### Many contracts at once
|
|
1964
2094
|
|
|
1965
2095
|
```ts
|
|
@@ -2096,6 +2226,7 @@ try {
|
|
|
2096
2226
|
err.details // structured details, if any
|
|
2097
2227
|
err.hint // optional hint
|
|
2098
2228
|
err.traceId // x-request-id — correlate this failure with backend logs
|
|
2229
|
+
err.cause // concrete injected transport failure, when delivery failed
|
|
2099
2230
|
}
|
|
2100
2231
|
}
|
|
2101
2232
|
```
|
|
@@ -2218,6 +2349,41 @@ sends one. The result keeps the full `react-query-kit` surface (`.getKey()`,
|
|
|
2218
2349
|
`useSuspenseInfiniteQuery`, every option). The endpoint must return the
|
|
2219
2350
|
`{ items, nextCursor }` envelope — see [Contracts → pagination](./contracts.md#pagination).
|
|
2220
2351
|
|
|
2352
|
+
## Contract-first streams
|
|
2353
|
+
|
|
2354
|
+
When an endpoint declares `stream`, `createClient` returns a schema-derived
|
|
2355
|
+
owned iterator rather than an untyped `Response`:
|
|
2356
|
+
|
|
2357
|
+
```ts
|
|
2358
|
+
const Progress = z.discriminatedUnion('kind', [
|
|
2359
|
+
z.object({ kind: z.literal('line'), text: z.string() }),
|
|
2360
|
+
z.object({ kind: z.literal('complete'), count: z.number().int() }),
|
|
2361
|
+
])
|
|
2362
|
+
|
|
2363
|
+
const contract = defineContract({ prefix: 'reports' }, {
|
|
2364
|
+
watch: {
|
|
2365
|
+
method: 'GET', path: '/:id/watch', desc: 'Watch one report',
|
|
2366
|
+
params: z.object({ id: z.string() }),
|
|
2367
|
+
stream: {
|
|
2368
|
+
item: Progress,
|
|
2369
|
+
format: 'ndjson', // default; `sse` is also supported
|
|
2370
|
+
maxFrameBytes: 64 * 1024, // default 256 KiB
|
|
2371
|
+
terminal: z.object({ kind: z.literal('complete') }).loose(),
|
|
2372
|
+
},
|
|
2373
|
+
},
|
|
2374
|
+
})
|
|
2375
|
+
|
|
2376
|
+
const stream = await createClient(contract, http).watch({ id: 'r-1' })
|
|
2377
|
+
for await (const item of stream) console.log(item) // inferred from Progress
|
|
2378
|
+
```
|
|
2379
|
+
|
|
2380
|
+
The iterator validates every frame and item. Normal completion requires the
|
|
2381
|
+
wire `end` frame and, when declared, at least one matching terminal item; EOF is
|
|
2382
|
+
`STREAM_TRUNCATED`, and a missing terminal is `STREAM_TERMINAL_MISSING`.
|
|
2383
|
+
`return()`/`break`, caller abort, producer failure and optional `lifetimeMs`
|
|
2384
|
+
converge on the request operation. See the
|
|
2385
|
+
[server half](./server.md#contract-first-streams). → ADR 0117.
|
|
2386
|
+
|
|
2221
2387
|
## SSE
|
|
2222
2388
|
|
|
2223
2389
|
For a streaming endpoint, consume the response with `parseSSE`:
|
|
@@ -2233,7 +2399,9 @@ for await (const event of parseSSE(res)) {
|
|
|
2233
2399
|
|
|
2234
2400
|
The server side is [`streamSSE`](./server.md#sse-streaming), or
|
|
2235
2401
|
[`sseRoute`](./server.md#long-lived-subscriptions) for a subscription that stays
|
|
2236
|
-
open.
|
|
2402
|
+
open. One line is bounded by `maxLineBytes` (default 1 MiB), UTF-8 is decoded
|
|
2403
|
+
strictly and malformed input throws. Supply `onParseError` only when
|
|
2404
|
+
skip-and-report is an explicit application policy.
|
|
2237
2405
|
|
|
2238
2406
|
## NDJSON
|
|
2239
2407
|
|
|
@@ -2265,8 +2433,9 @@ convenience: a long-lived stream must send something while it is idle or
|
|
|
2265
2433
|
intermediaries drop it, and an empty line is the natural pulse for this framing.
|
|
2266
2434
|
Writing the rule down on both sides is what stops it being a verbal agreement —
|
|
2267
2435
|
the server's keep-alive and the reader's skip are one decision with two
|
|
2268
|
-
implementations.
|
|
2269
|
-
|
|
2436
|
+
implementations. One line is bounded by `maxLineBytes` (default 1 MiB), UTF-8 is
|
|
2437
|
+
decoded strictly and malformed input throws. Passing `onParseError` explicitly
|
|
2438
|
+
selects tolerant skip-and-report behaviour.
|
|
2270
2439
|
|
|
2271
2440
|
|
|
2272
2441
|
==============================================================================
|
|
@@ -2356,7 +2525,7 @@ AI SDK `ToolSet` and call its transport adapter manually. Compile an in-process
|
|
|
2356
2525
|
invoker once and call the shared framework runner directly:
|
|
2357
2526
|
|
|
2358
2527
|
```ts
|
|
2359
|
-
import { createToolInvoker } from 'stitchkit/tools'
|
|
2528
|
+
import { createToolInvoker } from 'stitchkit/tools/invoker'
|
|
2360
2529
|
|
|
2361
2530
|
const invoker = createToolInvoker(services, {
|
|
2362
2531
|
transport: 'AGENT', // required exposure policy
|
|
@@ -2385,6 +2554,11 @@ recursive calls without retaining request state. Every invocation gets a fresh
|
|
|
2385
2554
|
tool-call context and runs the same extension resolution, input/output
|
|
2386
2555
|
validation, lifecycle, hooks and output-strip reporter as mounted tools.
|
|
2387
2556
|
|
|
2557
|
+
The dedicated entrypoint needs only the normal `stitchkit`/`zod` install. Use
|
|
2558
|
+
the broader `stitchkit/tools` barrel when the same program also mounts MCP or AI
|
|
2559
|
+
adapters and has installed their optional peers. Both imports reach the same
|
|
2560
|
+
runner; this is dependency isolation, not a second execution implementation.
|
|
2561
|
+
|
|
2388
2562
|
`invoke` returns the canonical discriminated `ToolResult`, not an AI SDK or MCP
|
|
2389
2563
|
presentation envelope. `invokeOrThrow` returns validated data and throws the
|
|
2390
2564
|
runner's normalized `AppError` on failure, preserving an application error's
|
|
@@ -3660,6 +3834,14 @@ const store = createAgentRuntimeStore({
|
|
|
3660
3834
|
})
|
|
3661
3835
|
```
|
|
3662
3836
|
|
|
3837
|
+
Prompt budgeting keeps reservation deficits signed. If instructions,
|
|
3838
|
+
`reservedOutput`, tool schemas, attachments and provider overhead already exceed
|
|
3839
|
+
`contextWindow`, `composeAgentPrompt` returns `contextDecision: 'oversized'`
|
|
3840
|
+
and a negative `availableHistoryTokens` even when history is empty. A `compact`
|
|
3841
|
+
policy is returned only when removing history could actually make the prompt
|
|
3842
|
+
fit. Exact equality (including a zero window with zero reservations/history)
|
|
3843
|
+
fits; any unavailable component keeps the decision `unavailable`.
|
|
3844
|
+
|
|
3663
3845
|
The same opaque `tx` reaches head, run, admission and history callbacks. The adapter maps rows
|
|
3664
3846
|
and supplies atomicity; Stitchkit owns transition validation and revision
|
|
3665
3847
|
arithmetic. The executable reference is
|
|
@@ -3987,6 +4169,24 @@ is the reserved built-in policy name. `loop.prepareStep` is the controlled AI
|
|
|
3987
4169
|
SDK step boundary for changing active tools, model, instructions or messages.
|
|
3988
4170
|
It cannot replace the managed tool set or bypass its lifecycle fence.
|
|
3989
4171
|
|
|
4172
|
+
Completion validity belongs to the protocol and is checked before the terminal
|
|
4173
|
+
CAS. Protocols that require a visible answer opt in explicitly:
|
|
4174
|
+
|
|
4175
|
+
```ts
|
|
4176
|
+
const protocol = defineAgentProtocol({
|
|
4177
|
+
context: ContextSchema,
|
|
4178
|
+
inputMetadata: InputMetadataSchema,
|
|
4179
|
+
terminalAcceptance: 'require-output',
|
|
4180
|
+
})
|
|
4181
|
+
```
|
|
4182
|
+
|
|
4183
|
+
The built-in rule accepts non-blank text, generated files, structured provider
|
|
4184
|
+
parts, and a named tool-only `policy_stop`. The default is `allow-empty` for
|
|
4185
|
+
protocols where an empty acknowledgement is meaningful. Pass a callback when
|
|
4186
|
+
the product has a narrower definition; it receives the candidate message,
|
|
4187
|
+
terminal reason and optional policy name, and runs before persistence. A false
|
|
4188
|
+
result fails the candidate instead of rewriting an already committed success.
|
|
4189
|
+
|
|
3990
4190
|
`loop.idleTimeoutMs` is inactivity, not total duration: the deadline resets on
|
|
3991
4191
|
every model stream event. A stalled call aborts with durable reason `timeout`;
|
|
3992
4192
|
user interruption and shutdown remain distinct.
|
|
@@ -4009,7 +4209,10 @@ effect must be replay-safe.
|
|
|
4009
4209
|
## History, provider metadata and files
|
|
4010
4210
|
|
|
4011
4211
|
`projectAgentHistory` converts canonical engine records into provider-valid AI
|
|
4012
|
-
SDK messages and pairs tool calls/results
|
|
4212
|
+
SDK messages and pairs tool calls/results in persisted causal order. Adjacent
|
|
4213
|
+
parallel calls stay in one assistant round and their adjacent results stay in
|
|
4214
|
+
one tool round; a dependent call after those results starts a new assistant
|
|
4215
|
+
round, and trailing final text remains after the last tool result. Provider-required metadata is kept
|
|
4013
4216
|
in a versioned opaque envelope and omitted from product delivery by default.
|
|
4014
4217
|
`projectAgentHistoryDetailed` additionally returns one inspectable decision per canonical record;
|
|
4015
4218
|
leading assistant records, crash drafts and unmatched tool chronology are never silently passed to
|
|
@@ -4246,10 +4449,12 @@ const cleanup = createManagedSchedule({
|
|
|
4246
4449
|
const http = managedServerResource({
|
|
4247
4450
|
id: 'http',
|
|
4248
4451
|
dependsOn: [database],
|
|
4249
|
-
// Called during `start`, after `database` is ready
|
|
4250
|
-
//
|
|
4251
|
-
|
|
4252
|
-
|
|
4452
|
+
// Called during `start`, after `database` is ready. The factory receives the
|
|
4453
|
+
// same declared-dependency and startup-signal context as any resource.
|
|
4454
|
+
server: (context) => {
|
|
4455
|
+
const db = context.use(database)
|
|
4456
|
+
return createServer({ port: env.PORT, services: createServices(db) })
|
|
4457
|
+
},
|
|
4253
4458
|
})
|
|
4254
4459
|
|
|
4255
4460
|
const app = createApplication({
|
|
@@ -4337,6 +4542,12 @@ Declare the dependency with the **resource**, not its id, whenever you intend to
|
|
|
4337
4542
|
read from it: that is the form `use` can type, and it keeps the declaration and
|
|
4338
4543
|
the read from drifting apart. A string still works when all you need is order.
|
|
4339
4544
|
|
|
4545
|
+
`managedServerResource` follows the same rule. Its factory receives this context
|
|
4546
|
+
during `start`, so constructing routes from a database/service/socket value does
|
|
4547
|
+
not need an outer mutable handoff or a custom `start` override. A zero-argument
|
|
4548
|
+
factory remains valid when it needs only ordering, and an already-running handle
|
|
4549
|
+
can still be passed directly. → ADR 0121.
|
|
4550
|
+
|
|
4340
4551
|
The value is published when `start` resolves and stays readable for the rest of
|
|
4341
4552
|
the application's life — from `activate` and from the shutdown phases too, where
|
|
4342
4553
|
a dependant may still need the handle it was given.
|
|
@@ -4530,6 +4741,69 @@ try {
|
|
|
4530
4741
|
`release()` is idempotent. Admission and counter increment are atomic, so work
|
|
4531
4742
|
cannot slip between the shutdown check and drain accounting.
|
|
4532
4743
|
|
|
4744
|
+
### Bounded operation admission
|
|
4745
|
+
|
|
4746
|
+
Compose `createBoundedAdmission` when accepted work also competes for a finite
|
|
4747
|
+
process-local resource:
|
|
4748
|
+
|
|
4749
|
+
```ts
|
|
4750
|
+
const generations = createBoundedAdmission({
|
|
4751
|
+
upstream: app.admission,
|
|
4752
|
+
policy: {
|
|
4753
|
+
global: { maxConcurrent: 8, rate: { limit: 120, intervalMs: 60_000 } },
|
|
4754
|
+
perKey: { maxConcurrent: 1, maxKeys: 2_000 },
|
|
4755
|
+
},
|
|
4756
|
+
})
|
|
4757
|
+
|
|
4758
|
+
await generations.run(accountId, ({ signal }) => generate({ signal }), {
|
|
4759
|
+
signal: request.signal,
|
|
4760
|
+
timeoutMs: 30_000,
|
|
4761
|
+
})
|
|
4762
|
+
```
|
|
4763
|
+
|
|
4764
|
+
Acquisition is no-queue and atomic across every configured budget. Refusal names
|
|
4765
|
+
the exact bound; only a rate refusal carries `retryAfterMs`. `maxKeys` keeps the
|
|
4766
|
+
per-key registry finite, and expired idle entries are retired.
|
|
4767
|
+
|
|
4768
|
+
The caller timeout is a wait budget, not proof that the resource stopped. It
|
|
4769
|
+
aborts the signal and settles the caller, but the lease remains active until the
|
|
4770
|
+
underlying Promise actually settles. `drain()` therefore reports real work;
|
|
4771
|
+
`force()` closes admission and reports remaining work without claiming to have
|
|
4772
|
+
terminated it. → ADR 0118.
|
|
4773
|
+
|
|
4774
|
+
### Bounded delivery and byte credit
|
|
4775
|
+
|
|
4776
|
+
`createBoundedChannel` is for one asynchronous reader when an event bus is not a
|
|
4777
|
+
queue:
|
|
4778
|
+
|
|
4779
|
+
```ts
|
|
4780
|
+
const output = createBoundedChannel<string>({
|
|
4781
|
+
policy: 'ordered',
|
|
4782
|
+
maxItems: 64,
|
|
4783
|
+
maxBytes: 256 * 1024,
|
|
4784
|
+
sizeOf: (value) => new TextEncoder().encode(value).byteLength,
|
|
4785
|
+
})
|
|
4786
|
+
|
|
4787
|
+
const progress = createBoundedChannel<{ revision: number }>({
|
|
4788
|
+
policy: 'latest',
|
|
4789
|
+
maxItems: 1,
|
|
4790
|
+
maxBytes: 128,
|
|
4791
|
+
sizeOf: () => 128,
|
|
4792
|
+
})
|
|
4793
|
+
```
|
|
4794
|
+
|
|
4795
|
+
`ordered` never overwrites accepted values; overflow is a reasoned refusal.
|
|
4796
|
+
`latest` retains exactly one pending replaceable value and reports
|
|
4797
|
+
`coalesced`. Offers never create a hidden writer queue, and only one `next()` may
|
|
4798
|
+
wait. Close chooses `drain` (default) or `discard`; abort discards; failure
|
|
4799
|
+
rejects the parked and all later reads.
|
|
4800
|
+
|
|
4801
|
+
`createCreditWindow({ capacityBytes })` is the smaller primitive for a protocol
|
|
4802
|
+
that already owns its queue but needs exact byte permission. Each credit lease
|
|
4803
|
+
replenishes once; it is flow-control credit, not a durable acknowledgement. The
|
|
4804
|
+
application snapshot sink now shares the same latest-value mechanics without
|
|
4805
|
+
changing its revision or status contract. → ADR 0119.
|
|
4806
|
+
|
|
4533
4807
|
Shutdown performs one phase barrier at a time: stop admission everywhere,
|
|
4534
4808
|
cancel future schedules, drain admitted work, then close in reverse stable
|
|
4535
4809
|
topological order. Every hook shares the same grace deadline. Forced cleanup
|
|
@@ -4804,6 +5078,56 @@ asynchronous subscriber callback racing cleanup: publish `getSnapshot()` before
|
|
|
4804
5078
|
closing the outer sink, so any older or duplicate late delivery is rejected as
|
|
4805
5079
|
stale instead of dropping the final state.
|
|
4806
5080
|
|
|
5081
|
+
## Bound a handler and a local worker with one lease policy
|
|
5082
|
+
|
|
5083
|
+
Use a bounded admission when two entry paths consume the same finite local
|
|
5084
|
+
capacity. Composing it with `application.admission` keeps readiness and shutdown
|
|
5085
|
+
as the upstream gate:
|
|
5086
|
+
|
|
5087
|
+
```ts
|
|
5088
|
+
const work = createBoundedAdmission({
|
|
5089
|
+
upstream: app.admission,
|
|
5090
|
+
policy: {
|
|
5091
|
+
global: { maxConcurrent: 4 },
|
|
5092
|
+
perKey: { maxConcurrent: 1, maxKeys: 1_000 },
|
|
5093
|
+
},
|
|
5094
|
+
})
|
|
5095
|
+
|
|
5096
|
+
const fromHttp = (key: string, signal: AbortSignal) =>
|
|
5097
|
+
work.run(key, (context) => render(context.signal), { signal, timeoutMs: 20_000 })
|
|
5098
|
+
|
|
5099
|
+
const fromWorker = (key: string) =>
|
|
5100
|
+
work.run(key, (context) => reconcile(context.signal))
|
|
5101
|
+
```
|
|
5102
|
+
|
|
5103
|
+
A timeout in `fromHttp` does not free a permit while `render` remains active.
|
|
5104
|
+
At shutdown call `work.stopAdmission()` with the other admission owners and
|
|
5105
|
+
await `work.drain(...)`; the result reports the actual remainder.
|
|
5106
|
+
|
|
5107
|
+
## Replace ad-hoc output and progress queues
|
|
5108
|
+
|
|
5109
|
+
Ordered output and replaceable progress are separate declarations:
|
|
5110
|
+
|
|
5111
|
+
```ts
|
|
5112
|
+
const lines = createBoundedChannel<string>({
|
|
5113
|
+
policy: 'ordered', maxItems: 100, maxBytes: 1_000_000,
|
|
5114
|
+
sizeOf: (line) => new TextEncoder().encode(line).byteLength,
|
|
5115
|
+
})
|
|
5116
|
+
|
|
5117
|
+
const state = createBoundedChannel<{ revision: number; percent: number }>({
|
|
5118
|
+
policy: 'latest', maxItems: 1, maxBytes: 64,
|
|
5119
|
+
sizeOf: () => 64,
|
|
5120
|
+
})
|
|
5121
|
+
|
|
5122
|
+
const lineResult = lines.offer('one durable-in-process ordering unit')
|
|
5123
|
+
const stateResult = state.offer({ revision: 2, percent: 50 })
|
|
5124
|
+
```
|
|
5125
|
+
|
|
5126
|
+
Handle `refused` from `lines` at the protocol boundary; do not turn it into
|
|
5127
|
+
implicit loss. A `coalesced` state result is expected latest-value behaviour,
|
|
5128
|
+
not evidence that an ordered event was delivered. Neither channel is durable;
|
|
5129
|
+
persist first when restart replay is required.
|
|
5130
|
+
|
|
4807
5131
|
## Handing a handle to the resources that depend on it
|
|
4808
5132
|
|
|
4809
5133
|
`dependsOn` carries ordering. To carry the object as well, return a `value` from
|
|
@@ -4846,7 +5170,10 @@ already-listening server and it adopts that one instead.
|
|
|
4846
5170
|
const http = managedServerResource({
|
|
4847
5171
|
id: 'http',
|
|
4848
5172
|
dependsOn: [database],
|
|
4849
|
-
server: () =>
|
|
5173
|
+
server: (context) => {
|
|
5174
|
+
const db = context.use(database)
|
|
5175
|
+
return createServer({ port: env.PORT, services: createServices(db) })
|
|
5176
|
+
},
|
|
4850
5177
|
})
|
|
4851
5178
|
|
|
4852
5179
|
const app = createApplication({ id: 'service', resources: [database, http] })
|
|
@@ -4857,6 +5184,11 @@ The server resource publishes its `ManagedServerHandle`, so anything that needs
|
|
|
4857
5184
|
the running server — a Socket.IO attachment, a URL to log, a probe — reads it
|
|
4858
5185
|
with `context.use(http)` rather than through a module-local.
|
|
4859
5186
|
|
|
5187
|
+
The factory itself receives `ManagedResourceContext` too. It can read only the
|
|
5188
|
+
dependencies declared on the server resource and shares the graph's startup
|
|
5189
|
+
signal. A dependency failure prevents the factory from binding; a factory
|
|
5190
|
+
rejection is rolled back without invoking the factory a second time.
|
|
5191
|
+
|
|
4860
5192
|
Do not spread this resource over your own `start` to control creation order:
|
|
4861
5193
|
that shape exists only as a workaround for the version whose `start` was empty,
|
|
4862
5194
|
and `dependsOn` now expresses the order directly. The executable recipe binds a
|
|
@@ -5770,6 +6102,36 @@ page metadata and `pageParams`; an infinite create changes only the selected
|
|
|
5770
6102
|
edge page (`createAt: 'start' | 'end'`). Creates are deduplicated across every
|
|
5771
6103
|
cached page. `updateMissing` makes an absent update explicitly skip or insert.
|
|
5772
6104
|
|
|
6105
|
+
Filtered query families can additionally declare membership per exact key and
|
|
6106
|
+
evidence-aware total reconciliation:
|
|
6107
|
+
|
|
6108
|
+
```ts
|
|
6109
|
+
list: {
|
|
6110
|
+
key: ['tickets'],
|
|
6111
|
+
shape: 'infinite-paginated',
|
|
6112
|
+
createAt: 'start',
|
|
6113
|
+
updateMissing: 'skip',
|
|
6114
|
+
membership: {
|
|
6115
|
+
evaluate: (event, queryKey) => membershipFor(event, queryKey),
|
|
6116
|
+
unknown: 'invalidate',
|
|
6117
|
+
},
|
|
6118
|
+
total: {
|
|
6119
|
+
mode: 'reconcile',
|
|
6120
|
+
unknown: 'invalidate',
|
|
6121
|
+
delta: ({ event, present, membership }) => provenDelta(event, present, membership),
|
|
6122
|
+
},
|
|
6123
|
+
}
|
|
6124
|
+
```
|
|
6125
|
+
|
|
6126
|
+
Membership is `include | exclude | unknown`. An excluded update removes an
|
|
6127
|
+
existing row; an included one follows `updateMissing`. Unknown evidence never
|
|
6128
|
+
guesses and either preserves or invalidates the exact query. The conservative
|
|
6129
|
+
total policy increments only a non-duplicate create and decrements only a
|
|
6130
|
+
delete/update whose membership is observed; unseen IDs are `unknown`. Supply
|
|
6131
|
+
`delta` only when the event itself proves a stronger transition. Every page's
|
|
6132
|
+
numeric `total` changes together while cursor metadata and `pageParams` remain
|
|
6133
|
+
unchanged.
|
|
6134
|
+
|
|
5773
6135
|
The event entity may be richer than a list row. Keep the full value in detail
|
|
5774
6136
|
cache, project it for lists, and provide the same comparator the backend uses:
|
|
5775
6137
|
|
|
@@ -5807,9 +6169,9 @@ deleted payload without guessing. The same resolved detail key drives the
|
|
|
5807
6169
|
`isFresh` echo guard. Shape checks also leave neighbouring detail caches alone
|
|
5808
6170
|
when a list key is intentionally used as a partial query-key prefix.
|
|
5809
6171
|
|
|
5810
|
-
The helper deliberately does **not** flatten pages,
|
|
5811
|
-
sort order or replace arbitrary `setQueryData` logic. Those
|
|
5812
|
-
policies;
|
|
6172
|
+
The helper deliberately does **not** flatten pages, infer filter semantics,
|
|
6173
|
+
derive a sort order or replace arbitrary `setQueryData` logic. Those remain
|
|
6174
|
+
declared application policies; Stitchkit applies their generic cache mechanics.
|
|
5813
6175
|
|
|
5814
6176
|
## Raw binary lane (Bun)
|
|
5815
6177
|
|
|
@@ -7418,6 +7780,11 @@ runtime or type-only package outside a case's budget fails with both the case id
|
|
|
7418
7780
|
and package name, so an accidental eager import cannot hide behind another
|
|
7419
7781
|
fixture's transitive dependency.
|
|
7420
7782
|
|
|
7783
|
+
That includes `stitchkit/tools/invoker`: a minimal packed consumer imports it
|
|
7784
|
+
without MCP/AI peers and executes validation, output projection and normalized
|
|
7785
|
+
errors on Bun and Node. The broader `stitchkit/tools` barrel deliberately keeps
|
|
7786
|
+
the adapter peer budget.
|
|
7787
|
+
|
|
7421
7788
|
Beside the matrix, one case is about the ARTIFACT rather than the inventory: a
|
|
7422
7789
|
program that injects the Socket.IO peer loaders is bundled and started in a
|
|
7423
7790
|
directory with no `node_modules`, under Node and under Bun with auto-install
|
|
@@ -7449,6 +7816,11 @@ const socket = await createSocketIOServer({
|
|
|
7449
7816
|
})
|
|
7450
7817
|
```
|
|
7451
7818
|
|
|
7819
|
+
The packed Next/Webpack gate compiles the browser
|
|
7820
|
+
`peers.client: () => import('socket.io-client')` loader and rejects Webpack's
|
|
7821
|
+
"request is an expression" warning. Stitchkit's runtime fallback remains lazy;
|
|
7822
|
+
its emitted import carries a count-checked ignore directive.
|
|
7823
|
+
|
|
7452
7824
|
Omit `peers` and nothing changes: the peers stay lazy and are resolved from the
|
|
7453
7825
|
machine. Both peers must be listed as dependencies of the package you bundle,
|
|
7454
7826
|
because they now genuinely are.
|
|
@@ -8038,6 +8410,56 @@ implement `AgentRuntimeStoreDriver` and compose the aggregate with
|
|
|
8038
8410
|
runtime): bootstrap the server, one HTTP request, and any feature you rely on
|
|
8039
8411
|
(Socket.IO connect, an MCP tool call, a multipart upload, …).
|
|
8040
8412
|
|
|
8413
|
+
## Released migration: 0.68.0
|
|
8414
|
+
|
|
8415
|
+
### Make Unix transport selection explicit outside Bun
|
|
8416
|
+
|
|
8417
|
+
The legacy `unix` option remains a Bun convenience, but on Node or another
|
|
8418
|
+
runtime it now fails before dispatch. Replace it with the owned adapter and close
|
|
8419
|
+
that adapter with the application:
|
|
8420
|
+
|
|
8421
|
+
```ts
|
|
8422
|
+
// before — unsafe outside Bun: an unsupported fetch could dial baseUrl over TCP
|
|
8423
|
+
const http = createHttpClient({ baseUrl, unix: '/run/service.sock' })
|
|
8424
|
+
|
|
8425
|
+
// after — Bun and Node; every dispatch and redirect stays on the socket
|
|
8426
|
+
import { createUnixClientTransport } from 'stitchkit/server' // or stitchkit/node
|
|
8427
|
+
const transport = createUnixClientTransport({ socketPath: '/run/service.sock' })
|
|
8428
|
+
const http = createHttpClient({ baseUrl, fetch: transport.fetch })
|
|
8429
|
+
// during shutdown
|
|
8430
|
+
await transport.close()
|
|
8431
|
+
```
|
|
8432
|
+
|
|
8433
|
+
Do not automatically replay `possibly-dispatched`: a timeout or connection loss
|
|
8434
|
+
after bytes left the process does not prove that a write did not happen.
|
|
8435
|
+
|
|
8436
|
+
### Choose tolerant stream parsing explicitly
|
|
8437
|
+
|
|
8438
|
+
`parseNDJSON` and `parseSSE` now throw on malformed JSON, invalid UTF-8 and an
|
|
8439
|
+
over-limit line. The default line ceiling is 1 MiB. If a feed deliberately skips
|
|
8440
|
+
bad records, retain that policy explicitly:
|
|
8441
|
+
|
|
8442
|
+
```ts
|
|
8443
|
+
// before — malformed input disappeared implicitly
|
|
8444
|
+
parseNDJSON(response)
|
|
8445
|
+
|
|
8446
|
+
// after — ordinary fail-closed path
|
|
8447
|
+
parseNDJSON(response, { maxLineBytes: 256 * 1024 })
|
|
8448
|
+
|
|
8449
|
+
// after — deliberately tolerant path
|
|
8450
|
+
parseNDJSON(response, { onParseError: (raw, error) => report(raw, error) })
|
|
8451
|
+
```
|
|
8452
|
+
|
|
8453
|
+
### Extend exhaustive framework-error handling
|
|
8454
|
+
|
|
8455
|
+
If a switch makes `StitchErrorCode` exhaustive, add
|
|
8456
|
+
`STREAM_ITEM_INVALID`, `STREAM_FRAME_TOO_LARGE`,
|
|
8457
|
+
`STREAM_TERMINAL_MISSING` and `STREAM_LIFETIME_EXCEEDED`. A partial application
|
|
8458
|
+
status map needs no change (ADR 0105).
|
|
8459
|
+
|
|
8460
|
+
The admission/channel APIs and endpoint `stream` descriptor are additive; raw
|
|
8461
|
+
responses and raw `streamingRoute` remain supported.
|
|
8462
|
+
|
|
8041
8463
|
## Released migration: 0.67.0
|
|
8042
8464
|
|
|
8043
8465
|
Three application-kernel changes. Two of them fix silent failures, so the most
|
|
@@ -10431,16 +10853,16 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
10431
10853
|
| `createUrlBuilders` | function | build one exact URL builder per contract in a registry |
|
|
10432
10854
|
| `UrlBuilderConfig` | _type_ | explicit `{ baseUrl }` source for a URL builder |
|
|
10433
10855
|
| `ClientConfig` | _type_ | config for `createClient`'s bare-fetch mode (2nd arg, no `HttpClient`) |
|
|
10434
|
-
| `ClientFetch` | _type_ | injectable Fetch-compatible transport used by framework
|
|
10856
|
+
| `ClientFetch` | _type_ | injectable Fetch-compatible transport used by framework and application-owned adapters |
|
|
10435
10857
|
| `ClientRequestOptions` | _type_ | per-call `{ signal?: AbortSignal }` passed through an endpoint callable's `.withOptions(...)`; caller abort is distinct from timeout — [guide](../guide/client.md#per-call-cancellation) |
|
|
10436
10858
|
| `ContractClientConfig` | _type_ | per-tenant / resource-scoped client config — dynamic `pathPrefix` + `stripPrefixKeys` ([guide](../guide/client.md#contractclientconfig--per-tenant--resource-scoped-clients)) |
|
|
10437
10859
|
| `contractEndpointMatchers` | function | compile exact pathname matchers for selected HTTP contract operations and expected-401 policy |
|
|
10438
10860
|
| `PathPrefixArgs` | _type_ | required string-valued keys exposed to a typed dynamic `pathPrefix` callback |
|
|
10439
10861
|
| `createHttpClient` | function | the Ky-based HTTP transport; on Next.js SSR its first attempt stays request-memoizable while every retry is a distinct transport attempt — [guide](../guide/client.md#createhttpclient) |
|
|
10440
|
-
| `ApiError` | class | a non-2xx
|
|
10862
|
+
| `ApiError` | class | a non-2xx or client failure, with `code` / `status` / `details` / `hint`, optional readonly `traceId` from `x-request-id`, and standard `cause` preserving an injected transport failure |
|
|
10441
10863
|
| `HttpClient` | _type_ | the transport interface `createClient` builds on |
|
|
10442
10864
|
| `ConfiguredHttpClient` | _type_ | a framework-created `HttpClient` carrying its readonly `baseUrl` for URL builders |
|
|
10443
|
-
| `HttpClientConfig` | _type_ | config for `createHttpClient`; retry `limit` counts retries after the initial attempt (default 2 = at most 3 GET attempts), with `statusCodes: []` by default; `
|
|
10865
|
+
| `HttpClientConfig` | _type_ | config for `createHttpClient`; retry `limit` counts retries after the initial attempt (default 2 = at most 3 GET attempts), with `statusCodes: []` by default; `fetch` installs an explicit transport and is mutually exclusive with the legacy Bun-only `unix` option — [details](../guide/client.md#createhttpclient) |
|
|
10444
10866
|
| `UnauthorizedMatcher` | _type_ | exact `(pathname) => boolean` policy accepted by `suppressUnauthorizedFor` |
|
|
10445
10867
|
| `RequestOptions` | _type_ | per-call options — params, timeout, response type |
|
|
10446
10868
|
| `HeaderProvider` | _type_ | static or per-request headers |
|
|
@@ -10458,6 +10880,8 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
10458
10880
|
| `createRetainedTopics` | function | retained last-value store for sticky events — [guide](../guide/realtime.md#sticky-events) |
|
|
10459
10881
|
| `parseSSE` | function | parse an SSE `Response` into an async generator — [guide](../guide/client.md#sse) |
|
|
10460
10882
|
| `parseNDJSON` | function | parse an NDJSON `Response`; blank keep-alive lines are skipped — [guide](../guide/client.md#ndjson) |
|
|
10883
|
+
| `ContractStreamFrameSchema` / `ContractStreamFrame` | schema / _type_ | internal-on-the-wire `data` / safe `error` / `end` envelope of a contract-first stream |
|
|
10884
|
+
| `DEFAULT_CONTRACT_STREAM_FRAME_BYTES` | const | default maximum encoded contract-stream frame: 256 KiB |
|
|
10461
10885
|
| `SocketIOClient` | _type_ | low-level client handle; `emit` reports disconnected drops and `emitWithAck` exposes the native Promise primitive used by validated `request()` |
|
|
10462
10886
|
| `SocketIOClientPeerLoaders` | _type_ | inject `socket.io-client` so a bundler can put it in a self-contained artifact |
|
|
10463
10887
|
| `SocketIOClientConfig` | _type_ | config for `createSocketIOClient` (incl. `retain`, `onConnectError`, `onDroppedEmit`) |
|
|
@@ -10533,6 +10957,7 @@ from the root `stitchkit`.
|
|
|
10533
10957
|
| `ContractDef` | _type_ | a defined contract |
|
|
10534
10958
|
| `ContractMeta` | _type_ | a contract's `prefix` + optional `scope` and `meta` (a default every endpoint shallow-merges over) |
|
|
10535
10959
|
| `EndpointDef` | _type_ | a single endpoint definition; `output` declares JSON response presence (`null` is data, `undefined` is invalid) |
|
|
10960
|
+
| `EndpointStreamDescriptor` | _type_ | HTTP-only schema-derived stream declaration: item schema, NDJSON/SSE framing, frame/lifetime/heartbeat/idle bounds and optional terminal predicate — [guide](../guide/server.md#contract-first-streams) |
|
|
10536
10961
|
| `HeadEndpointDef` | _type_ | explicit HTTP-only, bodyless `HEAD` endpoint definition |
|
|
10537
10962
|
| `EndpointResponseMeta` | _type_ | static success metadata declared by an HTTP-only typed-data endpoint |
|
|
10538
10963
|
| `ResponseMetadata` | _type_ | per-request outbound collector exposed as `ctx.response` only for a `responseMeta` endpoint |
|
|
@@ -10791,6 +11216,12 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
10791
11216
|
| `StreamingRouteOptions` | _type_ | options for `streamingRoute` / `ndjsonRoute` / `sseRoute` |
|
|
10792
11217
|
| `StreamingSourceContext` | _type_ | what a streaming source is given, including the cancellation `signal` |
|
|
10793
11218
|
| `StreamingFormat` | _type_ | `'ndjson' \| 'sse'` |
|
|
11219
|
+
| `createUnixClientTransport` | function | owned Fetch-compatible Unix-socket transport on Bun and Node; every redirect stays on the socket — [guide](../guide/client.md#unix-domain-sockets) |
|
|
11220
|
+
| `UnixClientTransportConfig` | _type_ | absolute socket path plus request/response/header/connection/redirect bounds |
|
|
11221
|
+
| `UnixClientTransport` | _type_ | `{ fetch, closed, close() }`; `close()` settles owned active work |
|
|
11222
|
+
| `UnixClientTransportError` | class | stable transport failure with `code` and dispatch certainty in `delivery` |
|
|
11223
|
+
| `UnixClientTransportErrorCode` | _type_ | finite Unix transport failure-code union |
|
|
11224
|
+
| `UnixClientDeliveryState` | _type_ | `not-dispatched \| possibly-dispatched \| response-received`; input to application retry policy, never an implicit retry |
|
|
10794
11225
|
|
|
10795
11226
|
### OpenAPI
|
|
10796
11227
|
|
|
@@ -10835,11 +11266,44 @@ cutovers are covered by the executable
|
|
|
10835
11266
|
| `ManagedResourceDependency` | _type_ | a dependency named by id or given as the resource itself — the second form is what `context.use(...)` can type |
|
|
10836
11267
|
| `ManagedResourcePublished` | _type_ | the value type `context.use(resource)` returns, recovered from that resource's own `start` |
|
|
10837
11268
|
| `ManagedResourcePublishesNoValue` | _type_ | what `context.use(...)` returns for a resource that publishes nothing — a branded refusal rather than `never`, so reading it does not silently compile |
|
|
10838
|
-
| `ManagedServerResourceConfig` | _type_ | the server or a
|
|
11269
|
+
| `ManagedServerResourceConfig` | _type_ | the server or a sync/async factory receiving `ManagedResourceContext`, plus stable ID, dependencies and shutdown policy for `managedServerResource` |
|
|
10839
11270
|
| `ManagedServerResource` | _type_ | the resource `managedServerResource` returns, whose `start` publishes the `ManagedServerHandle` |
|
|
10840
11271
|
| `ApplicationHealthHandlerOptions` / `ApplicationHealthHandlerOptionsSchema` | _type_ / schema | liveness/readiness selection and sanitized `Retry-After` policy |
|
|
10841
11272
|
| `ApplicationOperationalHandlers` / `ApplicationOperationalHandlersOptions` / `ApplicationOperationalHandlersOptionsSchema` | _type_ / schema | conventional status/readiness/liveness route surface and shared retry policy |
|
|
10842
11273
|
|
|
11274
|
+
### Bounded admission
|
|
11275
|
+
|
|
11276
|
+
| Export | Kind | Summary |
|
|
11277
|
+
|--------|------|---------|
|
|
11278
|
+
| `createBoundedAdmission` | function | process-local no-queue global/per-key concurrency and rate leases, optionally composed with application admission |
|
|
11279
|
+
| `BoundedAdmissionPolicySchema` / `BoundedAdmissionPolicy` | schema / _type_ | finite global budget and optional finite per-key budget with `maxKeys` |
|
|
11280
|
+
| `BoundedRateBudgetSchema` / `BoundedRateBudget` | schema / _type_ | `{ limit, intervalMs }` monotonic sliding-window budget |
|
|
11281
|
+
| `BoundedAdmissionStateSchema` / `BoundedAdmissionState` | schema / _type_ | `accepting \| draining \| closed` |
|
|
11282
|
+
| `BoundedAdmissionRefusalReasonSchema` / `BoundedAdmissionRefusalReason` | schema / _type_ | exact local/upstream refusal vocabulary |
|
|
11283
|
+
| `BoundedAdmissionSnapshotSchema` / `BoundedAdmissionSnapshot` | schema / _type_ | absolute active/lifetime/refusal/rate-accounting counters |
|
|
11284
|
+
| `BoundedAdmission` / `BoundedAdmissionConfig` / `BoundedAdmissionClock` | _type_ | handle, policy/upstream/clock configuration and monotonic clock seam |
|
|
11285
|
+
| `BoundedAdmissionResult` / `BoundedAdmissionLeaseResult` / `BoundedAdmissionRefusedResult` | _type_ | explicit leased-or-refused acquisition result; retry time exists only for rate bounds |
|
|
11286
|
+
| `BoundedOperationLease` | _type_ | idempotent release lease, optionally carrying its key |
|
|
11287
|
+
| `BoundedOperationRunContext` / `BoundedOperationRunOptions` | _type_ | underlying work signal and caller abort/timeout wait budget |
|
|
11288
|
+
| `BoundedAdmissionDrainOptions` / `BoundedAdmissionDrainResult` / `BoundedAdmissionForceResult` | _type_ | bounded drain inputs and honest remaining-work results |
|
|
11289
|
+
| `BoundedAdmissionRefusalError` | class | `run()` refusal with reason and optional `retryAfterMs` |
|
|
11290
|
+
| `BoundedOperationWaitError` | class | caller wait ended as `cancelled` or `timed-out`; underlying capacity remains leased until work settles |
|
|
11291
|
+
|
|
11292
|
+
### Bounded delivery
|
|
11293
|
+
|
|
11294
|
+
| Export | Kind | Summary |
|
|
11295
|
+
|--------|------|---------|
|
|
11296
|
+
| `createBoundedChannel` | function | finite single-reader async channel with explicit ordered or latest-value policy |
|
|
11297
|
+
| `BoundedChannelPolicySchema` / `BoundedChannelPolicy` | schema / _type_ | `ordered \| latest` retention policy |
|
|
11298
|
+
| `BoundedChannelStateSchema` / `BoundedChannelState` | schema / _type_ | `open \| draining \| closed \| failed` |
|
|
11299
|
+
| `BoundedChannelSnapshotSchema` / `BoundedChannelSnapshot` | schema / _type_ | exact retained count/bytes, waiter and outcome counters |
|
|
11300
|
+
| `BoundedChannel` / `BoundedChannelConfig` / `BoundedChannelCloseOptions` | _type_ | iterator/offer handle, explicit count/byte/size policy and drain/discard close mode |
|
|
11301
|
+
| `BoundedChannelOfferResult` | _type_ | `delivered`, `queued`, `coalesced`, or reasoned `refused` outcome |
|
|
11302
|
+
| `BoundedChannelReaderError` | class | refusal of a second concurrent pending `next()` |
|
|
11303
|
+
| `createCreditWindow` | function | finite byte-credit lease window with exact once-only replenishment |
|
|
11304
|
+
| `CreditWindow` / `CreditWindowSnapshot` / `CreditWindowSnapshotSchema` | _type_ / schema | byte-credit handle and absolute accounting record |
|
|
11305
|
+
| `CreditAcquireResult` / `CreditLease` | _type_ | reasoned refusal or idempotently releasable byte-credit lease |
|
|
11306
|
+
|
|
10843
11307
|
### Managed schedules
|
|
10844
11308
|
|
|
10845
11309
|
| Export | Kind | Summary |
|
|
@@ -10930,7 +11394,8 @@ Server-only optional application runtime. See the
|
|
|
10930
11394
|
| Export | Kind | Summary |
|
|
10931
11395
|
|--------|------|---------|
|
|
10932
11396
|
| `createAgentRuntime` | function | compose durable acceptance, stream loop, checkpoints, coordination, managed tools and winner-only terminal publication; reconciles same-owner terminal/interrupt/head CAS races before releasing the lane |
|
|
10933
|
-
| `defineAgentProtocol` | function | declare
|
|
11397
|
+
| `defineAgentProtocol` | function | declare context, input metadata, canonical parts and optional pre-CAS terminal acceptance (`allow-empty`, `require-output` or callback) |
|
|
11398
|
+
| `hasAgentTerminalOutput` | function | generic `require-output` predicate for non-blank text, generated files, structured provider parts and explicit tool-only policy stops |
|
|
10934
11399
|
| `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
|
|
10935
11400
|
| `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
|
|
10936
11401
|
| `createAgentRuntimeStore` | function | build the aggregate store from one coherent transaction driver; framework owns every state transition |
|
|
@@ -10943,7 +11408,7 @@ Server-only optional application runtime. See the
|
|
|
10943
11408
|
| `createMemoryAgentRuntimeStore` | function | process-local reference adapter, not production durability |
|
|
10944
11409
|
| `projectAgentHistory` | function | asynchronously project canonical records and resolved multimodal files into provider-valid AI SDK messages |
|
|
10945
11410
|
| `defineModelRegistry` | function | typed language-model descriptors, capabilities and provider construction |
|
|
10946
|
-
| `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware context budget |
|
|
11411
|
+
| `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware signed context budget; irreducible reservation deficits are `oversized`, not compactable history |
|
|
10947
11412
|
| `structuredCompaction` | function | summarize a provider-valid snapshot range and replace it through CAS |
|
|
10948
11413
|
| `createAgentSessionCoordinator` | function | strict process-local queue/interrupt/supersede lifecycle |
|
|
10949
11414
|
| `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
|
|
@@ -10972,7 +11437,8 @@ transport adapters validate the same records. Runtime composition types are `Age
|
|
|
10972
11437
|
`AgentSessionCoordinator`, `AgentCompactionContext`, `AgentCompactionResult` and
|
|
10973
11438
|
`StructuredCompactionConfig`.
|
|
10974
11439
|
|
|
10975
|
-
Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `
|
|
11440
|
+
Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `AgentTerminalAcceptance`,
|
|
11441
|
+
`AgentTerminalAcceptanceInput`, `hasAgentTerminalOutput`, `AgentRecordIdSchema`, `AgentRecordVersionSchema`,
|
|
10976
11442
|
`AgentTimestampSchema`, `AgentJsonObjectSchema`, `AgentProviderEnvelopeSchema`,
|
|
10977
11443
|
`AgentProviderEnvelope`, `AgentMessagePartSchema`, `AgentMessagePart`, `AgentTextPartSchema`,
|
|
10978
11444
|
`AgentReasoningPartSchema`, `AgentFilePartSchema`, `AgentSourcePartSchema`,
|
|
@@ -11168,7 +11634,7 @@ payload.
|
|
|
11168
11634
|
| `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
|
|
11169
11635
|
| `defineRuntimeTool` | function | define one validated pathless operation for explicit MCP, Agent and/or CLI surfaces — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
|
|
11170
11636
|
| `createRuntimeToolFactory` | function | bind shared identity and Zod-validated per-call context for runtime tools — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
|
|
11171
|
-
| `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
|
|
11637
|
+
| `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use peer-free `stitchkit/tools/invoker`, or the full `stitchkit/tools` adapter barrel — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
|
|
11172
11638
|
| `createCli` | function | a command-line program from contracts — [guide](../guide/cli.md) (also on `stitchkit/cli`) |
|
|
11173
11639
|
| `defineCliCommand` | function | define one typed CLI-only command with optional post-validation `present` and successful `exitCode` policy — [guide](../guide/cli.md#native-binary-commands) (also on `stitchkit/cli`) |
|
|
11174
11640
|
| `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
|
|
@@ -11556,6 +12022,7 @@ runtime-agnostic pieces of `stitchkit/server` and the error helpers.
|
|
|
11556
12022
|
| `serveNode` | function | build the router and start a Node HTTP server (via `srvx`) |
|
|
11557
12023
|
| `createHandler` | function | the router as a bare `(req) => Response` (same as `/server`) |
|
|
11558
12024
|
| `createSocketIOServer` | function | the typed Node Socket.IO server (`io` + `attach`; no Bun engine declarations) |
|
|
12025
|
+
| `createUnixClientTransport` | function | the same fail-closed Bun/Node Unix client adapter exported by `stitchkit/server` |
|
|
11559
12026
|
| `implement` / `createImplement` / `createScopedImplement` / `createScopedImplementRegistry` / `createMultipartStream` | function | bind a contract to typed handlers, optionally typed per endpoint scope (same as `/server`) |
|
|
11560
12027
|
| `NodeServerConfig` | _type_ | config for `serveNode` |
|
|
11561
12028
|
| `NodeServerHandle` | _type_ | managed Node handle (`url`, `port`, `runtime`, `status`, `shutdown`) |
|
|
@@ -11563,6 +12030,8 @@ runtime-agnostic pieces of `stitchkit/server` and the error helpers.
|
|
|
11563
12030
|
| `NodeSocketLifecycle` | _type_ | Bun-free Socket.IO lifecycle accepted by `serveNode` |
|
|
11564
12031
|
| `HandlerConfig` / `ServiceDef` / `RawRoute` / `RawRouteContext` | _type_ | runtime-neutral handler types; raw routes default their host server to `unknown` |
|
|
11565
12032
|
| `SocketIORequestPolicy` / `SocketIOServerConfig` / `SocketIOPeerLoaders` / `SocketIOServerHandle` | _type_ | runtime-neutral handshake policy, config, optional-peer loaders and the Bun-free Node handle with `io`, `attach` and lifecycle |
|
|
12033
|
+
| `UnixClientTransportConfig` / `UnixClientTransport` | _type_ | Unix socket bounds and owned Fetch-compatible handle |
|
|
12034
|
+
| `UnixClientTransportError` / `UnixClientTransportErrorCode` / `UnixClientDeliveryState` | class / _type_ | stable failure plus dispatch certainty; no cross-transport fallback |
|
|
11566
12035
|
| `AppError` + `appError` / `badRequest` / `unauthorized` / `forbidden` / `notFound` / `conflict` / `rateLimited` | — | error helpers (same as `/contract`) |
|
|
11567
12036
|
|
|
11568
12037
|
---
|
|
@@ -11610,6 +12079,8 @@ and `react-query-kit` peers.
|
|
|
11610
12079
|
| `createCacheBridge` | function | sync socket events into the Query cache — [guide](../guide/realtime.md#cache-bridge) |
|
|
11611
12080
|
| `createEntityCacheHandlers` | function | created/updated/deleted cache handlers for one entity — [guide](../guide/realtime.md#entity-cache-handlers) |
|
|
11612
12081
|
| `EntityCacheConfig` | _type_ | config for `createEntityCacheHandlers` |
|
|
12082
|
+
| `EntityCacheMembership` / `EntityCacheMembershipPolicy` | _type_ | per-exact-query `include | exclude | unknown` filter decision and unknown invalidation policy |
|
|
12083
|
+
| `EntityCacheTotalPolicy` / `EntityCacheTotalDeltaInput` | _type_ | evidence-aware reconciliation of numeric totals on paginated cache shapes |
|
|
11613
12084
|
| `EntityCacheHandlers` | _type_ | the `{ created, updated, deleted }` handlers it returns |
|
|
11614
12085
|
| `EntityCacheEvent` | _type_ | discriminated created/updated/deleted input for dynamic cache keys |
|
|
11615
12086
|
| `EntityCacheKey` | _type_ | static `QueryKey` or event-aware key factory |
|