stitchkit 0.89.0 → 0.90.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -0
- package/dist/agent-runtime/coding-tool-refusals.d.ts +31 -10
- package/dist/agent-runtime/coding-tool-refusals.d.ts.map +1 -1
- package/dist/agent-runtime/spill.d.ts.map +1 -1
- package/dist/agent-runtime-coding-tools.js +4 -4
- package/dist/agent-runtime-harness.js +5 -5
- package/dist/agent-runtime-sandbox.js +5 -5
- package/dist/agent-runtime.js +17 -29
- package/dist/application/watch-hub.d.ts +24 -2
- package/dist/application/watch-hub.d.ts.map +1 -1
- package/dist/application-grammy.js +1 -1
- package/dist/application.js +103 -13
- package/dist/cli.js +7 -7
- package/dist/contract/errors.d.ts +3 -0
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/index.js +2 -2
- package/dist/{index-qmgs7y68.js → index-1txvygak.js} +1 -1
- package/dist/{index-8c3a7m4g.js → index-2hrfpw2c.js} +1 -1
- package/dist/{index-7evdsyez.js → index-2hryh65w.js} +1 -1
- package/dist/index-2na0qrfn.js +214 -0
- package/dist/{index-zyvby92n.js → index-44ht2790.js} +2 -2
- package/dist/{index-27gm3d6g.js → index-6q3zjwaz.js} +2 -2
- package/dist/{index-mnm4qp0p.js → index-79hb1wyh.js} +3 -3
- package/dist/{index-apn8repm.js → index-7gqx71yd.js} +2 -2
- package/dist/{index-7601qfg1.js → index-8dph3pw6.js} +4 -4
- package/dist/{index-90d7h2cr.js → index-bg8ypxzn.js} +3 -3
- package/dist/{index-vchzar7e.js → index-db51n3xr.js} +5 -5
- package/dist/{index-hw2chdvy.js → index-f475yj00.js} +1 -1
- package/dist/{index-q3ve2d1k.js → index-gbqjt8jz.js} +3 -3
- package/dist/index-gte38nbm.js +101 -0
- package/dist/{index-cp20z0n6.js → index-j7q0xj6d.js} +7 -55
- package/dist/{index-2bxcmqkb.js → index-kazec06k.js} +1 -1
- package/dist/{index-0w9abg87.js → index-scs3f1eg.js} +3 -0
- package/dist/{index-31jw8fjq.js → index-wb15909q.js} +1 -1
- package/dist/{index-p18f59zy.js → index-z78bjcxj.js} +1 -1
- package/dist/{index-t7fkyxcr.js → index-zkcqhxx8.js} +1 -1
- package/dist/index.js +6 -6
- package/dist/live/watch-client.d.ts +2 -1
- package/dist/live/watch-client.d.ts.map +1 -1
- package/dist/live/watch-contract.d.ts +70 -4
- package/dist/live/watch-contract.d.ts.map +1 -1
- package/dist/live/watch-delta.d.ts +110 -0
- package/dist/live/watch-delta.d.ts.map +1 -0
- package/dist/live.d.ts +2 -1
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +56 -4
- package/dist/node.js +6 -6
- package/dist/observability/changes.d.ts +55 -0
- package/dist/observability/changes.d.ts.map +1 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +130 -3
- package/dist/observability/spool.d.ts +53 -0
- package/dist/observability/spool.d.ts.map +1 -0
- package/dist/primitives.js +2 -2
- package/dist/remote.js +5 -5
- package/dist/server/index.js +8 -8
- package/dist/testing.js +6 -6
- package/dist/tool-invoker.js +6 -6
- package/dist/tools.js +11 -11
- package/dist/tracking.js +2 -2
- package/llms-full.txt +156 -15
- package/package.json +1 -1
- package/dist/index-dre2ywck.js +0 -48
- package/dist/index-gskm1k5a.js +0 -50
package/llms-full.txt
CHANGED
|
@@ -48,7 +48,7 @@ own, recorded as an ADR.
|
|
|
48
48
|
|--------|--------|----------|-------|
|
|
49
49
|
| `stitchkit` | browser **and** server | stable | `defineContract`, `createClient`, `createHttpClient`, `createSocketIOClient`, `parseSSE`, the error model |
|
|
50
50
|
| `stitchkit/contract` | browser **and** server | stable | the contract layer alone — `defineContract`, errors, pagination |
|
|
51
|
-
| `stitchkit/live` | browser **and** server | evolving | `defineEvents` — topic declarations beside the operation contract
|
|
51
|
+
| `stitchkit/live` | browser **and** server | evolving | `defineEvents` — topic declarations beside the operation contract — and watched reads: `createWatchClient`, the value/difference frame and its reassembly |
|
|
52
52
|
| `stitchkit/primitives` | browser **and** server | evolving | generic values and declarations for lifecycle, access, audit, delivery and exports |
|
|
53
53
|
| `stitchkit/server` | server (Bun) | stable | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
|
|
54
54
|
| `stitchkit/node` | server (Node ≥ 22) | stable | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
|
|
@@ -64,11 +64,11 @@ own, recorded as an ADR.
|
|
|
64
64
|
| `stitchkit/tracking/server` | server (Bun or Node) | evolving | the decisions a tracking backend makes — dispositions, visit lease over an application-owned store, active intervals, presence; no database |
|
|
65
65
|
| `stitchkit/release` | browser **and** server | evolving | a page follows the release it was built for — `createReleaseMarker` on the server, `createReleaseWatcher` in the browser, the `X-Build-Id` header and a socket event between them |
|
|
66
66
|
| `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
|
|
67
|
-
| `stitchkit/observability` | server | stable<br>_redefined in 1 of the
|
|
67
|
+
| `stitchkit/observability` | server | stable<br>_redefined in 1 of the 35 minors since 0.56.2, most recently 0.83.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
68
68
|
| `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 |
|
|
69
69
|
| `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
70
70
|
| `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
|
|
71
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 20 of the
|
|
71
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 20 of the 35 minors since 0.56.2, most recently 0.89.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
72
72
|
| `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
|
|
73
73
|
| `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults and deterministic race controls |
|
|
74
74
|
| `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
|
|
@@ -78,7 +78,7 @@ own, recorded as an ADR.
|
|
|
78
78
|
| `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
|
|
79
79
|
| `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
|
|
80
80
|
| `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
|
|
81
|
-
| `stitchkit/application` | browser + server | evolving<br>_redefined in 7 of the
|
|
81
|
+
| `stitchkit/application` | browser + server | evolving<br>_redefined in 7 of the 35 minors since 0.56.2, most recently 0.83.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
|
|
82
82
|
| `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
|
|
83
83
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
84
84
|
| `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
|
|
@@ -4765,8 +4765,11 @@ authorization payload, so no directory is created before a host approves it.
|
|
|
4765
4765
|
|
|
4766
4766
|
**Every ordinary outcome is a refusal a model can act on** — a missing file is `NOT_FOUND`, an
|
|
4767
4767
|
existing file without `overwrite` is `CONFLICT`, an ambiguous snippet is `CONFLICT` carrying its
|
|
4768
|
-
occurrence count, a path outside the root is `FORBIDDEN
|
|
4768
|
+
occurrence count, a path outside the root is `FORBIDDEN`, an unknown spilled-output reference is
|
|
4769
|
+
`SPILL_REFERENCE_UNKNOWN` — each with a `hint` naming the next move.
|
|
4769
4770
|
Host-level causes stay scrubbed to `INTERNAL_SERVER_ERROR` and name nothing outside the workspace.
|
|
4771
|
+
Every refusal code is a member of `STITCH_ERROR_STATUS`, so its status survives an envelope that
|
|
4772
|
+
crosses a process boundary and is rebuilt from the wire.
|
|
4770
4773
|
→ ADR 0139
|
|
4771
4774
|
|
|
4772
4775
|
`list_directory` marks excluded directories rather than hiding them, and `glob` reports
|
|
@@ -5032,7 +5035,11 @@ chat messages.
|
|
|
5032
5035
|
`createSqliteAgentSpillStore` persists oversized output separately and records
|
|
5033
5036
|
its locator, hash and lifecycle in the ledger. `read_output` and
|
|
5034
5037
|
`search_output` re-run both locator authorization and the originating tool
|
|
5035
|
-
authorization before reading bytes.
|
|
5038
|
+
authorization before reading bytes. A reference the store does not hold is a
|
|
5039
|
+
refusal like any other — `SPILL_REFERENCE_UNKNOWN` / 404, naming the reference
|
|
5040
|
+
and pointing at the one the spilling command returned. The lookup is scoped by
|
|
5041
|
+
conversation, so a reference belonging to another conversation is absent rather
|
|
5042
|
+
than forbidden, and the refusal cannot tell a model that it exists elsewhere. `createSqliteAgentEventSearch` returns the
|
|
5036
5043
|
exact conversation and event sequence; cross-conversation results are denied
|
|
5037
5044
|
unless `authorizeConversation` approves each target.
|
|
5038
5045
|
`createAgentEventSearchTools` supplies `session_search`, `session_trace` and
|
|
@@ -8810,13 +8817,49 @@ Nothing an open can fail with escapes as a rejected promise: a disconnected
|
|
|
8810
8817
|
socket, a timeout, a refusal all arrive as `unavailable` carrying the error's own
|
|
8811
8818
|
code and message, and the next connection retries.
|
|
8812
8819
|
|
|
8820
|
+
The re-open carries what the client still holds, so a reconnection is usually
|
|
8821
|
+
cheap: the hub answers with a difference, or with nothing at all when the answer
|
|
8822
|
+
has not moved. That needs the key to still exist on the server — set `holdMs`
|
|
8823
|
+
past your reconnect delay, or the last detach releases the source and the page
|
|
8824
|
+
pays the whole value once.
|
|
8825
|
+
|
|
8826
|
+
### Large answers cross as differences
|
|
8827
|
+
|
|
8828
|
+
A frame carries the value, a **difference** to a revision this subscriber already
|
|
8829
|
+
holds, or `unchanged`. The hub chooses per subscriber and sends a difference only
|
|
8830
|
+
when it is genuinely smaller; your `value` listener sees the rebuilt value either
|
|
8831
|
+
way and needs no code for this.
|
|
8832
|
+
|
|
8833
|
+
It matters when an answer is large and moves a little: a ~75 KB list in which two
|
|
8834
|
+
timestamps change, republished every fifteen seconds, was a megabyte per
|
|
8835
|
+
subscriber per minute before and is a frame under a kilobyte now.
|
|
8836
|
+
|
|
8837
|
+
```ts
|
|
8838
|
+
createWatchHub({
|
|
8839
|
+
// Superseded values kept per key, so a difference has something to be taken
|
|
8840
|
+
// against. Default 262144. Set 0 to send whole values only.
|
|
8841
|
+
deltaMemoryBytes: 256 * 1024,
|
|
8842
|
+
holdMs: 30_000,
|
|
8843
|
+
// …
|
|
8844
|
+
});
|
|
8845
|
+
```
|
|
8846
|
+
|
|
8847
|
+
Reassembly is checked against the server's fingerprint on every frame. If a
|
|
8848
|
+
difference will not apply — a client that missed a revision, a hub that restarted
|
|
8849
|
+
— that **one key** resynchronises: your `state` listener sees `resync-required`
|
|
8850
|
+
and the whole value follows. Other keys on the same socket are untouched.
|
|
8851
|
+
|
|
8852
|
+
Both ends must come from the same major release: a client older than 0.90 reads a
|
|
8853
|
+
difference frame as a value of `undefined`.
|
|
8854
|
+
|
|
8813
8855
|
### `watch` or `createLiveStateController`?
|
|
8814
8856
|
|
|
8815
8857
|
> **If you would have written `applyEvent` as `(_, next) => next`, you want
|
|
8816
|
-
> `watch`:
|
|
8817
|
-
>
|
|
8818
|
-
>
|
|
8819
|
-
> applying both to one value is always a
|
|
8858
|
+
> `watch`: whatever crosses the wire, what your `value` listener receives is the
|
|
8859
|
+
> whole answer.** `createLiveStateController` is for a server whose *protocol* is
|
|
8860
|
+
> deltas that your code folds. `watch` may send a difference too, but it folds it
|
|
8861
|
+
> for you and hands you the value — so applying both to one value is always a
|
|
8862
|
+
> mistake.
|
|
8820
8863
|
|
|
8821
8864
|
### What it cannot promise
|
|
8822
8865
|
|
|
@@ -9495,7 +9538,10 @@ core never models them (ADR 0002). But stitchkit itself emits a set of its own:
|
|
|
9495
9538
|
`FILE_INSPECTION_REJECTED`, `FILE_TOO_LARGE`, `FILE_EXISTS`,
|
|
9496
9539
|
`REALTIME_CONTRACT_VIOLATION`, `APPLICATION_NOT_ACCEPTING`, `WAIT_TIMEOUT`,
|
|
9497
9540
|
`WAIT_FAILED`, `DOWNLOAD_NOT_FOUND`, `VIEW_HTTP_ERROR`,
|
|
9498
|
-
`OPERATION_NOT_SUCCEEDED`, `
|
|
9541
|
+
`OPERATION_NOT_SUCCEEDED`, `STREAM_ITEM_INVALID`, `STREAM_FRAME_TOO_LARGE`,
|
|
9542
|
+
`STREAM_TERMINAL_MISSING`, `STREAM_LIFETIME_EXCEEDED`,
|
|
9543
|
+
`GRAMMY_WEBHOOK_NOT_ACCEPTING`, `SANDBOX_UNAVAILABLE`, `SANDBOX_INSUFFICIENT`,
|
|
9544
|
+
`SPILL_REFERENCE_UNKNOWN`, `INTERNAL_SERVER_ERROR` — a set that grows in
|
|
9499
9545
|
ordinary releases, each addition named in the changelog. They are
|
|
9500
9546
|
published as **`STITCH_ERROR_STATUS`** (the `code → status` map) and
|
|
9501
9547
|
**`StitchErrorCode`** (its `keyof`), with **`isStitchErrorCode()`** (→ ADR 0026).
|
|
@@ -9746,9 +9792,10 @@ stitchkit answers this at two levels.
|
|
|
9746
9792
|
sanitisation and `createObservability` with independent request/tool sinks.
|
|
9747
9793
|
[Start here ↓](#the-observability-module)
|
|
9748
9794
|
|
|
9749
|
-
stitchkit still ships no logger and no audit store
|
|
9750
|
-
|
|
9751
|
-
normalised record
|
|
9795
|
+
stitchkit still ships no logger and no audit store, and auditing stays opt-in —
|
|
9796
|
+
those are the app's choice (→ ADR 0012, reaffirmed in ADR 0184). What it ships is
|
|
9797
|
+
the machinery that turns a completed call into a clean, normalised record, keeps
|
|
9798
|
+
the ones worth keeping, and does not lose them when the store is down.
|
|
9752
9799
|
|
|
9753
9800
|
## The observability module
|
|
9754
9801
|
|
|
@@ -9985,6 +10032,69 @@ queryable across all three:
|
|
|
9985
10032
|
| `resultSize` / `responseBytes` | result item count + serialised size |
|
|
9986
10033
|
| `userId` / `ipAddress` / `userAgent` | identity |
|
|
9987
10034
|
|
|
10035
|
+
### Write the calls that changed something
|
|
10036
|
+
|
|
10037
|
+
`auditChanges` is the filter most projects end up writing, shipped so they do not
|
|
10038
|
+
have to write it six ways:
|
|
10039
|
+
|
|
10040
|
+
```ts
|
|
10041
|
+
import { auditChanges, createObservability } from 'stitchkit/observability';
|
|
10042
|
+
|
|
10043
|
+
createObservability({
|
|
10044
|
+
request: { write: saveAuditRow, filter: auditChanges },
|
|
10045
|
+
tools: { write: saveAuditRow, filter: auditChanges },
|
|
10046
|
+
});
|
|
10047
|
+
```
|
|
10048
|
+
|
|
10049
|
+
It drops `GET`, `HEAD` and `OPTIONS`, keeps everything else, and keeps `401` and
|
|
10050
|
+
`403` **whatever the verb was** — a refused read is the row an audit exists to
|
|
10051
|
+
hold, and a filter that drops every `GET` drops exactly that. An unrecognised
|
|
10052
|
+
verb is kept: an extra row costs bytes, a missing one costs the answer to "who
|
|
10053
|
+
changed this", silently and only later.
|
|
10054
|
+
|
|
10055
|
+
One filter across HTTP, MCP and agent calls, because a tool call carries its
|
|
10056
|
+
contract verb in `httpMethod` while its `method` is the literal `TOOL`.
|
|
10057
|
+
|
|
10058
|
+
Narrower policy stays yours — compose it:
|
|
10059
|
+
|
|
10060
|
+
```ts
|
|
10061
|
+
filter: (event) => auditChanges(event) && event.serviceName !== 'health',
|
|
10062
|
+
```
|
|
10063
|
+
|
|
10064
|
+
### Keeping the row when the store is down
|
|
10065
|
+
|
|
10066
|
+
A sink is fire-and-forget, so an unreachable store means the event is simply
|
|
10067
|
+
gone — and a store is most likely to be unreachable during an incident, which is
|
|
10068
|
+
the window whose rows someone will later want most.
|
|
10069
|
+
|
|
10070
|
+
`createSpooledSink` writes the row to a local append-only file first, offers it
|
|
10071
|
+
to the store second, and marks it delivered third. What a previous process left
|
|
10072
|
+
unmarked is replayed:
|
|
10073
|
+
|
|
10074
|
+
```ts
|
|
10075
|
+
import { createSpooledSink } from 'stitchkit/observability';
|
|
10076
|
+
|
|
10077
|
+
const audit = createSpooledSink({
|
|
10078
|
+
path: '/var/lib/app/audit.ndjson',
|
|
10079
|
+
write: saveAuditRow,
|
|
10080
|
+
});
|
|
10081
|
+
|
|
10082
|
+
// Once, at startup, before the sink is wired — and await it.
|
|
10083
|
+
const { replayed, failed } = await audit.recover();
|
|
10084
|
+
|
|
10085
|
+
createObservability({ request: { write: audit.write, filter: auditChanges } });
|
|
10086
|
+
```
|
|
10087
|
+
|
|
10088
|
+
The guarantee is **at least once**. A crash between the store accepting a row and
|
|
10089
|
+
the file recording that it did replays the row, so **the store must be idempotent
|
|
10090
|
+
on the record key** — `event.spanId` by default, unique per call. A unique index
|
|
10091
|
+
on it turns the duplicate into a no-op; without one, replay writes the row twice.
|
|
10092
|
+
Exactly-once would need the file and the database to share a transaction. They do
|
|
10093
|
+
not.
|
|
10094
|
+
|
|
10095
|
+
One process, one path. Two processes pointed at the same file replay each other's
|
|
10096
|
+
records: harmless against an idempotent store, wasteful always.
|
|
10097
|
+
|
|
9988
10098
|
### Request context
|
|
9989
10099
|
|
|
9990
10100
|
When request observability is configured, `createHandler` establishes the
|
|
@@ -11382,6 +11492,32 @@ analytics policy belong to the application.
|
|
|
11382
11492
|
|
|
11383
11493
|
# Upgrading stitchkit
|
|
11384
11494
|
|
|
11495
|
+
## Released migration: 0.90.0
|
|
11496
|
+
|
|
11497
|
+
1. `stitchkit.watch.value` is a discriminated union on `kind` — `full`, `delta`,
|
|
11498
|
+
`unchanged` — and every frame carries `fingerprint`. **Both ends must come from
|
|
11499
|
+
the same major.** A client older than this release reads a `delta` frame as a
|
|
11500
|
+
value of `undefined`, silently; upgrade the hub and the pages that talk to it
|
|
11501
|
+
together, or set `deltaMemoryBytes: 0` on the hub until they are.
|
|
11502
|
+
|
|
11503
|
+
Applications using `createWatchClient` need no code change: it rebuilds the
|
|
11504
|
+
value and hands the listener the whole answer as before. Code that reads
|
|
11505
|
+
`WatchValueFrame.value` directly — a hand-written subscriber, a test double —
|
|
11506
|
+
narrows on `kind` first.
|
|
11507
|
+
|
|
11508
|
+
```ts
|
|
11509
|
+
// before: frame.value
|
|
11510
|
+
// after:
|
|
11511
|
+
if (frame.kind === 'full') hold(frame.value);
|
|
11512
|
+
else if (frame.kind === 'delta') hold(applyWatchDelta(held, frame.delta));
|
|
11513
|
+
// 'unchanged' leaves what you hold standing
|
|
11514
|
+
```
|
|
11515
|
+
|
|
11516
|
+
2. `AttachedWatcher.open` takes an optional third argument, `have`. A custom
|
|
11517
|
+
server binding that forwards `stitchkit.watch.open` should pass the payload's
|
|
11518
|
+
`have` through; omitting it costs a whole value on every reconnection and is
|
|
11519
|
+
otherwise harmless.
|
|
11520
|
+
|
|
11385
11521
|
## Released migration: 0.89.0
|
|
11386
11522
|
|
|
11387
11523
|
1. Custom `AgentRuntimeStore` adapters implement `seedConversationInput`; custom
|
|
@@ -15121,7 +15257,10 @@ realtime contract from `stitchkit`, and the server halves live in `stitchkit/app
|
|
|
15121
15257
|
| `watchContract` | const | the four-event realtime contract a watched read travels on |
|
|
15122
15258
|
| `WATCH_OPEN` / `WATCH_CLOSE` / `WATCH_VALUE` / `WATCH_STATE` | const | the event names of that contract |
|
|
15123
15259
|
| `WatchKey` / `WatchKeySchema` / `watchKeyString` | type / schema / function | `(service, action, arguments digest)` — the identity both ends compute the same way |
|
|
15124
|
-
| `WatchValueFrame` / `WatchValueSchema` / `WatchStateFrame` / `WatchStateSchema` | _types_ |
|
|
15260
|
+
| `WatchValueFrame` / `WatchValueSchema` / `WatchStateFrame` / `WatchStateSchema` | _types_ | one answer — `full`, `delta` or `unchanged`, with its monotonic revision and fingerprint — and a phase from `LiveStatePhase` with the read's own code and message |
|
|
15261
|
+
| `WatchHave` / `WatchHaveSchema` | type / schema | what a reconnecting subscriber already holds, offered on `open`: a revision and the fingerprint that proves it |
|
|
15262
|
+
| `WatchDelta` / `WatchDeltaSchema` / `WatchArrayOp` / `WatchArrayOpSchema` | _types_ / schemas | a structural difference over parsed JSON — objects by changed and dropped key, arrays by runs copied from the previous value |
|
|
15263
|
+
| `watchDiff` / `applyWatchDelta` / `watchDeltaWins` | functions | build a difference (`undefined` when equal), rebuild the value from one (throws rather than inventing), and whether it is actually smaller than the value |
|
|
15125
15264
|
|
|
15126
15265
|
---
|
|
15127
15266
|
|
|
@@ -16142,6 +16281,8 @@ audit event. See the [Observability guide](../guide/observability.md).
|
|
|
16142
16281
|
| Export | Kind | Summary |
|
|
16143
16282
|
|--------|------|---------|
|
|
16144
16283
|
| `createObservability` | function | configure framework-owned request completion and canonical tool event sinks — [guide](../guide/observability.md#createobservability) |
|
|
16284
|
+
| `auditChanges` | function | the sink `filter` most projects write themselves — drops `GET`/`HEAD`/`OPTIONS`, keeps `401`/`403` whatever the verb, keeps an unrecognised verb |
|
|
16285
|
+
| `createSpooledSink` / `SpooledSink` / `SpooledSinkConfig` / `SpoolRecovery` | function / _types_ | spool the row to an append-only file before the store and replay what a previous process left undelivered — at least once, keyed on `spanId` |
|
|
16145
16286
|
| `createDimensionsProjector` / `DimensionsProjector` / `DimensionsProjectorConfig` / `ProjectedDimensions` | function / _type_ | typed request/result/error attribution projected into the existing request context |
|
|
16146
16287
|
| `DimensionCollision` / `SetRequestDimensionsOptions` | _type_ | explicit overwrite, preserve or error policy for dimension keys |
|
|
16147
16288
|
| `createBoundedLogger` | function | decorate a `StitchLogger` with request context, shared sanitisation, redaction and total bounds |
|
package/package.json
CHANGED
package/dist/index-dre2ywck.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LiveStatePhaseSchema,
|
|
3
|
-
LiveStateStopReasonSchema
|
|
4
|
-
} from "./index-ywd0y6m1.js";
|
|
5
|
-
|
|
6
|
-
// src/live/watch-contract.ts
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
var WatchKeySchema = z.object({
|
|
9
|
-
service: z.string().min(1),
|
|
10
|
-
action: z.string().min(1),
|
|
11
|
-
digest: z.string().min(1)
|
|
12
|
-
}).strict().readonly();
|
|
13
|
-
var WatchOpenSchema = z.object({ key: WatchKeySchema, args: z.unknown() }).readonly();
|
|
14
|
-
var WatchAcceptedSchema = z.object({
|
|
15
|
-
accepted: z.boolean(),
|
|
16
|
-
reason: z.string().optional()
|
|
17
|
-
}).strict().readonly();
|
|
18
|
-
var WatchValueSchema = z.object({
|
|
19
|
-
key: WatchKeySchema,
|
|
20
|
-
revision: z.number().int().nonnegative(),
|
|
21
|
-
value: z.unknown()
|
|
22
|
-
}).readonly();
|
|
23
|
-
var WatchStateSchema = z.object({
|
|
24
|
-
key: WatchKeySchema,
|
|
25
|
-
phase: LiveStatePhaseSchema,
|
|
26
|
-
reason: LiveStateStopReasonSchema.optional(),
|
|
27
|
-
code: z.string().optional(),
|
|
28
|
-
message: z.string().optional()
|
|
29
|
-
}).readonly();
|
|
30
|
-
var WATCH_OPEN = "stitchkit.watch.open";
|
|
31
|
-
var WATCH_CLOSE = "stitchkit.watch.close";
|
|
32
|
-
var WATCH_VALUE = "stitchkit.watch.value";
|
|
33
|
-
var WATCH_STATE = "stitchkit.watch.state";
|
|
34
|
-
var watchContract = {
|
|
35
|
-
serverToClient: {
|
|
36
|
-
[WATCH_VALUE]: { args: z.tuple([WatchValueSchema]) },
|
|
37
|
-
[WATCH_STATE]: { args: z.tuple([WatchStateSchema]) }
|
|
38
|
-
},
|
|
39
|
-
clientToServer: {
|
|
40
|
-
[WATCH_OPEN]: { args: z.tuple([WatchOpenSchema]), ack: WatchAcceptedSchema },
|
|
41
|
-
[WATCH_CLOSE]: { args: z.tuple([z.object({ key: WatchKeySchema }).readonly()]) }
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
function watchKeyString(key) {
|
|
45
|
-
return `${key.service}/${key.action}/${key.digest}`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { WatchKeySchema, WatchValueSchema, WatchStateSchema, WATCH_OPEN, WATCH_CLOSE, WATCH_VALUE, WATCH_STATE, watchContract, watchKeyString };
|
package/dist/index-gskm1k5a.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// src/agent-runtime/sandbox.ts
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
var AgentSandboxRestrictionSchema = z.enum([
|
|
4
|
-
"network-denied",
|
|
5
|
-
"write-contained",
|
|
6
|
-
"secrets-hidden",
|
|
7
|
-
"process-contained"
|
|
8
|
-
]);
|
|
9
|
-
var AgentSandboxGradeSchema = z.discriminatedUnion("grade", [
|
|
10
|
-
z.object({ grade: z.literal("full"), restrictions: z.array(AgentSandboxRestrictionSchema) }).strict(),
|
|
11
|
-
z.object({
|
|
12
|
-
grade: z.literal("partial"),
|
|
13
|
-
restrictions: z.array(AgentSandboxRestrictionSchema),
|
|
14
|
-
gaps: z.array(AgentSandboxRestrictionSchema)
|
|
15
|
-
}).strict(),
|
|
16
|
-
z.object({ grade: z.literal("unavailable"), reason: z.string().min(1) }).strict()
|
|
17
|
-
]);
|
|
18
|
-
var probes = new WeakMap;
|
|
19
|
-
function probeAgentProcessSandbox(sandbox, options = {}) {
|
|
20
|
-
if (options.refresh)
|
|
21
|
-
probes.delete(sandbox);
|
|
22
|
-
const present = probes.get(sandbox);
|
|
23
|
-
if (present)
|
|
24
|
-
return present;
|
|
25
|
-
const pending = Promise.resolve(sandbox.probe()).then((grade) => AgentSandboxGradeSchema.parse(grade));
|
|
26
|
-
probes.set(sandbox, pending);
|
|
27
|
-
return pending;
|
|
28
|
-
}
|
|
29
|
-
function missingSandboxRestrictions(grade, required) {
|
|
30
|
-
if (grade.grade === "unavailable")
|
|
31
|
-
return required;
|
|
32
|
-
const present = new Set(grade.restrictions);
|
|
33
|
-
return required.filter((restriction) => !present.has(restriction));
|
|
34
|
-
}
|
|
35
|
-
async function recordAgentSandboxProbe(input) {
|
|
36
|
-
const grade = await probeAgentProcessSandbox(input.sandbox);
|
|
37
|
-
const missing = missingSandboxRestrictions(grade, input.required);
|
|
38
|
-
await input.store.appendEvent({
|
|
39
|
-
conversationId: input.conversationId,
|
|
40
|
-
kind: "sandbox/probed",
|
|
41
|
-
payload: {
|
|
42
|
-
result: grade,
|
|
43
|
-
required: [...input.required],
|
|
44
|
-
missing: [...missing]
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
return grade;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export { AgentSandboxRestrictionSchema, AgentSandboxGradeSchema, probeAgentProcessSandbox, missingSandboxRestrictions, recordAgentSandboxProbe };
|