stitchkit 0.56.0 → 0.56.2
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/README.md +12 -3
- package/dist/agent-runtime/compaction.d.ts +33 -0
- package/dist/agent-runtime/compaction.d.ts.map +1 -0
- package/dist/agent-runtime/coordinator.d.ts +24 -0
- package/dist/agent-runtime/coordinator.d.ts.map +1 -0
- package/dist/agent-runtime/events.d.ts +454 -0
- package/dist/agent-runtime/events.d.ts.map +1 -0
- package/dist/agent-runtime/history.d.ts +11 -0
- package/dist/agent-runtime/history.d.ts.map +1 -0
- package/dist/agent-runtime/managed-tools.d.ts +18 -0
- package/dist/agent-runtime/managed-tools.d.ts.map +1 -0
- package/dist/agent-runtime/models.d.ts +51 -0
- package/dist/agent-runtime/models.d.ts.map +1 -0
- package/dist/agent-runtime/observability.d.ts +134 -0
- package/dist/agent-runtime/observability.d.ts.map +1 -0
- package/dist/agent-runtime/prompt.d.ts +50 -0
- package/dist/agent-runtime/prompt.d.ts.map +1 -0
- package/dist/agent-runtime/protocol.d.ts +16 -0
- package/dist/agent-runtime/protocol.d.ts.map +1 -0
- package/dist/agent-runtime/runtime.d.ts +120 -0
- package/dist/agent-runtime/runtime.d.ts.map +1 -0
- package/dist/agent-runtime/schemas.d.ts +470 -0
- package/dist/agent-runtime/schemas.d.ts.map +1 -0
- package/dist/agent-runtime/store.d.ts +905 -0
- package/dist/agent-runtime/store.d.ts.map +1 -0
- package/dist/agent-runtime/testing.d.ts +17 -0
- package/dist/agent-runtime/testing.d.ts.map +1 -0
- package/dist/agent-runtime-openrouter.d.ts +6 -0
- package/dist/agent-runtime-openrouter.d.ts.map +1 -0
- package/dist/agent-runtime-openrouter.js +46 -0
- package/dist/agent-runtime.d.ts +13 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +1931 -0
- package/dist/cli.js +8 -5
- package/dist/index-0nc0cddp.js +178 -0
- package/dist/{index-6y759j86.js → index-1tkyng3g.js} +9 -57
- package/dist/{index-sm2tjx06.js → index-41wm56v0.js} +2 -2
- package/dist/index-6djpbnda.js +56 -0
- package/dist/{index-j3dem06f.js → index-7c0gkyvj.js} +5 -3
- package/dist/{index-n4nfa7gh.js → index-9zn9fb4e.js} +74 -10
- package/dist/{index-xy8fmh6w.js → index-f6pymtqe.js} +3 -3
- package/dist/{index-jcc611vh.js → index-gnvzyw0k.js} +2 -2
- package/dist/{index-qh4xevf5.js → index-mr617n62.js} +4 -2
- package/dist/{index-5r13htq1.js → index-ps5pxp3h.js} +1 -1
- package/dist/index-sa2mbwa7.js +336 -0
- package/dist/index-smpbdg6k.js +27 -0
- package/dist/{index-7eq9va6e.js → index-y2rb7dwx.js} +1 -27
- package/dist/{index-escqg10p.js → index-zk5zn2nh.js} +32 -334
- package/dist/internal/observability-sink.d.ts +26 -0
- package/dist/internal/observability-sink.d.ts.map +1 -0
- package/dist/node.js +6 -5
- package/dist/observability/audit.d.ts +4 -0
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/event.d.ts +5 -0
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/observability/index.js +29 -186
- package/dist/remote.js +4 -3
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +10 -8
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/index.js +11 -8
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/request-body.d.ts.map +1 -1
- package/dist/testing.js +5 -3
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/execute.d.ts +7 -0
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools.d.ts +2 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +23 -12
- package/llms-full.txt +429 -18
- package/llms.txt +1 -0
- package/package.json +16 -3
package/llms-full.txt
CHANGED
|
@@ -47,6 +47,8 @@ keeping server-only code (`Bun.serve`, the MCP SDK) out of browser bundles.
|
|
|
47
47
|
| `stitchkit/remote` | browser **and** server | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
48
48
|
| `stitchkit/files` | server (Bun or Node) | peer-free managed local-file boundary |
|
|
49
49
|
| `stitchkit/observability` | server | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
50
|
+
| `stitchkit/agent-runtime` | server | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
51
|
+
| `stitchkit/agent-runtime/openrouter` | server | isolated OpenRouter language-model adapter |
|
|
50
52
|
| `stitchkit/testing` | tests on Bun or Node | in-process generated clients over a real Fetch handler, without a TCP port |
|
|
51
53
|
| `stitchkit/react` | browser | `createCursorQuery`, `createCacheBridge` |
|
|
52
54
|
|
|
@@ -146,6 +148,8 @@ map — feature → packages:
|
|
|
146
148
|
| `createServer` (Bun) | — (uses `Bun.serve`) |
|
|
147
149
|
| `serveNode` (Node ≥ 22) | `srvx` (+ `@types/bun` dev) |
|
|
148
150
|
| MCP / agent tools (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
|
|
151
|
+
| Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
|
|
152
|
+
| OpenRouter runtime adapter (`stitchkit/agent-runtime/openrouter`) | `ai` `@openrouter/ai-sdk-provider` |
|
|
149
153
|
| MCP host/client tests | `@modelcontextprotocol/client` |
|
|
150
154
|
| MCP Apps UI widgets | `@modelcontextprotocol/ext-apps` |
|
|
151
155
|
| React data layer (`stitchkit/react`) | `@tanstack/react-query` `react-query-kit` |
|
|
@@ -989,6 +993,18 @@ createServer({
|
|
|
989
993
|
| `'pretty'` | two coloured lines per request — `→` on arrival, `←` on completion | no — a line sized for a terminal is not a record |
|
|
990
994
|
| `'json'` | one structured line per completed request | yes |
|
|
991
995
|
|
|
996
|
+
Status `499` has one framework-wide meaning: the client closed the request. It
|
|
997
|
+
is logged at `info`, not under the ordinary `4xx → warn` rule. A confirmed
|
|
998
|
+
disconnect is not sent through project `onError`, `normalizeError` or the
|
|
999
|
+
request-error recorder; an `AbortError` while the request signal is still active
|
|
1000
|
+
remains an internal failure. A runtime abort reason may be preserved by identity
|
|
1001
|
+
through at most eight cycle-safe standard `cause` links; error messages and codes
|
|
1002
|
+
are never classifiers. The same rule applies when the disconnect happens while
|
|
1003
|
+
Stitchkit is reading a JSON upload body: bounded reads race every pending stream
|
|
1004
|
+
read against the request signal and never parse a cancelled partial body. `499`
|
|
1005
|
+
is transport telemetry, not a response declared in the contract or generated
|
|
1006
|
+
OpenAPI document.
|
|
1007
|
+
|
|
992
1008
|
Unset, `format` follows `NODE_ENV`: `json` under `production`, `pretty`
|
|
993
1009
|
otherwise. That default is read **per request** — not at import, not when this
|
|
994
1010
|
package was built — so it reflects the environment your app actually runs in.
|
|
@@ -1159,7 +1175,9 @@ createServer({
|
|
|
1159
1175
|
- **`afterHandle`** — receives the handler result; return a replacement to
|
|
1160
1176
|
transform it.
|
|
1161
1177
|
- **`onError`** — receives any thrown error; return a `Response` to customise
|
|
1162
|
-
the error body. Without it, errors render through the standard envelope.
|
|
1178
|
+
the error body. Without it, errors render through the standard envelope. A
|
|
1179
|
+
confirmed client disconnect is a transport cancellation rather than an
|
|
1180
|
+
application error and deliberately bypasses this hook.
|
|
1163
1181
|
|
|
1164
1182
|
Hooks see `RuntimeContext` (loose types); handlers see `HandlerContext` (typed).
|
|
1165
1183
|
That split is deliberate — see [ADR 0003](../decisions/0003-two-context-types.md).
|
|
@@ -2822,6 +2840,10 @@ list.
|
|
|
2822
2840
|
|
|
2823
2841
|
## AI agents — `mountAgent`
|
|
2824
2842
|
|
|
2843
|
+
`mountAgent` remains the low-level path when the application owns its own model
|
|
2844
|
+
loop and conversation state. For the optional Stitchkit-owned run/history loop,
|
|
2845
|
+
see [Agent application runtime](./agent-runtime.md).
|
|
2846
|
+
|
|
2825
2847
|
`mountAgent` turns a service into a Vercel AI SDK `ToolSet`, ready for
|
|
2826
2848
|
`generateText` / `streamText`:
|
|
2827
2849
|
|
|
@@ -3326,6 +3348,288 @@ the rest of the context (`params`, `input`, anything `context` injects) is
|
|
|
3326
3348
|
identical. Write the handler once; it serves every surface.
|
|
3327
3349
|
|
|
3328
3350
|
|
|
3351
|
+
==============================================================================
|
|
3352
|
+
# Guide: Agent application runtime (docs/guide/agent-runtime.md)
|
|
3353
|
+
==============================================================================
|
|
3354
|
+
|
|
3355
|
+
---
|
|
3356
|
+
title: "Agent application runtime"
|
|
3357
|
+
description: Configure Stitchkit's optional durable history, stream loop, run coordination and managed-tool fencing.
|
|
3358
|
+
type: architecture
|
|
3359
|
+
status: active
|
|
3360
|
+
created: 2026-08-22
|
|
3361
|
+
updated: 2026-08-22
|
|
3362
|
+
---
|
|
3363
|
+
|
|
3364
|
+
# Agent application runtime
|
|
3365
|
+
|
|
3366
|
+
`stitchkit/agent-runtime` is the server-only, opinionated layer above
|
|
3367
|
+
`mountAgent`. Use it when the application wants Stitchkit to own conversation
|
|
3368
|
+
mechanics: durable acceptance, history projection, the AI SDK stream loop,
|
|
3369
|
+
checkpoints, keyed interruption, terminal commit and stable application events.
|
|
3370
|
+
|
|
3371
|
+
If the application already owns that loop, continue importing `mountAgent` from
|
|
3372
|
+
`stitchkit/tools`. Neither path depends on the other at runtime.
|
|
3373
|
+
|
|
3374
|
+
## Install
|
|
3375
|
+
|
|
3376
|
+
```sh
|
|
3377
|
+
bun add stitchkit ai zod
|
|
3378
|
+
```
|
|
3379
|
+
|
|
3380
|
+
OpenRouter is isolated so other runtime users do not resolve its package:
|
|
3381
|
+
|
|
3382
|
+
```sh
|
|
3383
|
+
bun add @openrouter/ai-sdk-provider
|
|
3384
|
+
```
|
|
3385
|
+
|
|
3386
|
+
## Minimal composition
|
|
3387
|
+
|
|
3388
|
+
```ts
|
|
3389
|
+
import { z } from 'zod'
|
|
3390
|
+
import {
|
|
3391
|
+
composeAgentPrompt,
|
|
3392
|
+
createAgentRuntime,
|
|
3393
|
+
createMemoryAgentRuntimeStore,
|
|
3394
|
+
defineAgentProtocol,
|
|
3395
|
+
defineModelRegistry,
|
|
3396
|
+
} from 'stitchkit/agent-runtime'
|
|
3397
|
+
import { openRouterProvider } from 'stitchkit/agent-runtime/openrouter'
|
|
3398
|
+
import { composeToolLifecycle, mountAgent } from 'stitchkit/tools'
|
|
3399
|
+
|
|
3400
|
+
const protocol = defineAgentProtocol({
|
|
3401
|
+
context: z.object({ userId: z.string() }),
|
|
3402
|
+
inputMetadata: z.object({}),
|
|
3403
|
+
})
|
|
3404
|
+
|
|
3405
|
+
const models = defineModelRegistry({
|
|
3406
|
+
providers: {
|
|
3407
|
+
openrouter: openRouterProvider({ apiKey: env.OPENROUTER_API_KEY }),
|
|
3408
|
+
},
|
|
3409
|
+
models: {
|
|
3410
|
+
fast: {
|
|
3411
|
+
provider: 'openrouter',
|
|
3412
|
+
modelId: 'provider/model',
|
|
3413
|
+
contextWindow: 128_000,
|
|
3414
|
+
capabilities: ['tools'],
|
|
3415
|
+
},
|
|
3416
|
+
},
|
|
3417
|
+
})
|
|
3418
|
+
|
|
3419
|
+
const prompt = composeAgentPrompt([
|
|
3420
|
+
{
|
|
3421
|
+
name: 'product',
|
|
3422
|
+
stability: 'stable',
|
|
3423
|
+
render: ({ context }) => `Help user ${context.userId}.`,
|
|
3424
|
+
},
|
|
3425
|
+
])
|
|
3426
|
+
|
|
3427
|
+
const runtime = createAgentRuntime({
|
|
3428
|
+
protocol,
|
|
3429
|
+
store: createMemoryAgentRuntimeStore(),
|
|
3430
|
+
models: { resolve: () => models.resolve('fast', ['tools']) },
|
|
3431
|
+
prompt: ({ context, signal, model }) =>
|
|
3432
|
+
prompt({
|
|
3433
|
+
context,
|
|
3434
|
+
signal,
|
|
3435
|
+
budget: {
|
|
3436
|
+
contextWindow: model.descriptor.contextWindow,
|
|
3437
|
+
reservedOutput: 8_000,
|
|
3438
|
+
toolSchemas: { provenance: 'unavailable' },
|
|
3439
|
+
attachments: { value: 0, provenance: 'measured' },
|
|
3440
|
+
providerOverhead: { provenance: 'unavailable' },
|
|
3441
|
+
},
|
|
3442
|
+
}),
|
|
3443
|
+
tools: ({ context, toolFenceLifecycle }) =>
|
|
3444
|
+
mountAgent(service, {
|
|
3445
|
+
context,
|
|
3446
|
+
lifecycle: composeToolLifecycle(authLifecycle, toolFenceLifecycle),
|
|
3447
|
+
}),
|
|
3448
|
+
runs: { inputPolicy: 'interrupt', coalescePending: true },
|
|
3449
|
+
loop: {
|
|
3450
|
+
idleTimeoutMs: 60_000,
|
|
3451
|
+
prepareStep: ({ context, steps }) => ({
|
|
3452
|
+
activeTools: steps.some((step) => step.toolCalls.length > 0)
|
|
3453
|
+
? ['lookup']
|
|
3454
|
+
: ['lookup', 'discover'],
|
|
3455
|
+
instructions: `Current account: ${context.userId}`,
|
|
3456
|
+
}),
|
|
3457
|
+
stopPolicies: [
|
|
3458
|
+
{
|
|
3459
|
+
name: 'repeated-tool-error',
|
|
3460
|
+
when: ({ steps }) => hasRepeatedToolError(steps),
|
|
3461
|
+
},
|
|
3462
|
+
],
|
|
3463
|
+
},
|
|
3464
|
+
})
|
|
3465
|
+
|
|
3466
|
+
const ticket = runtime.submit({
|
|
3467
|
+
conversationId: 'conversation-id',
|
|
3468
|
+
idempotencyKey: 'request-id',
|
|
3469
|
+
context: { userId: 'user-id' },
|
|
3470
|
+
parts: [{ type: 'text', text: 'Hello' }],
|
|
3471
|
+
})
|
|
3472
|
+
|
|
3473
|
+
await ticket.accepted
|
|
3474
|
+
const terminal = await ticket.result
|
|
3475
|
+
```
|
|
3476
|
+
|
|
3477
|
+
The in-memory store is a reference adapter and has process-local durability
|
|
3478
|
+
only. Production applications implement `AgentRuntimeStore` with their own
|
|
3479
|
+
database transaction and, when needed, distributed lease/fencing token.
|
|
3480
|
+
|
|
3481
|
+
## Durable order
|
|
3482
|
+
|
|
3483
|
+
`acceptInputAndAssignRun` is one atomic operation. It is followed by ownership
|
|
3484
|
+
acquisition, revision-checked assistant checkpoints and one terminal CAS. The
|
|
3485
|
+
process-local coordinator releases its lane only after terminal commit.
|
|
3486
|
+
|
|
3487
|
+
```text
|
|
3488
|
+
input + queued run → running → execution settled → terminal CAS → successor
|
|
3489
|
+
```
|
|
3490
|
+
|
|
3491
|
+
With `runs.coalescePending: true`, an active lane has at most one queued
|
|
3492
|
+
successor. Every later accepted input is atomically appended to that successor;
|
|
3493
|
+
its `AgentRun.inputMessageIds` records the whole batch and every input ticket
|
|
3494
|
+
resolves to the same terminal run. Coalescing never mutates the active run.
|
|
3495
|
+
|
|
3496
|
+
`AbortSignal.aborted` is only a cooperation request. A successor does not begin
|
|
3497
|
+
while the predecessor still owns managed callbacks. A hung predecessor blocks
|
|
3498
|
+
the lane in the first version.
|
|
3499
|
+
|
|
3500
|
+
Use `await runtime.interrupt({ conversationId, runId })` when the interruption
|
|
3501
|
+
must be durable: it first commits `interrupt_requested`, then aborts the local
|
|
3502
|
+
coordinator signal. `runtime.stop(key)` is the process-local signal-only escape
|
|
3503
|
+
hatch.
|
|
3504
|
+
|
|
3505
|
+
## Store operations
|
|
3506
|
+
|
|
3507
|
+
An adapter implements the aggregate `AgentRuntimeStore`, not separate message
|
|
3508
|
+
and run CRUD stores:
|
|
3509
|
+
|
|
3510
|
+
- `acceptInputAndAssignRun`
|
|
3511
|
+
- `acquireRun`
|
|
3512
|
+
- `checkpointRunAssistant`
|
|
3513
|
+
- `requestRunInterrupt`
|
|
3514
|
+
- `recoverRun`
|
|
3515
|
+
- `commitRunTerminal`
|
|
3516
|
+
- `replaceCompactedRange`
|
|
3517
|
+
- `loadSnapshot` and `scanRecoverable`
|
|
3518
|
+
|
|
3519
|
+
Every mutation carries an expected run revision or snapshot version. Input
|
|
3520
|
+
assignment additionally carries an idempotency identity. A conflict is a
|
|
3521
|
+
control outcome; stale data is never silently overwritten.
|
|
3522
|
+
|
|
3523
|
+
On startup, `scanRecoverable` returns queued/acquired records. `recoverRun`
|
|
3524
|
+
may abandon them, or requeue an already acquired run only with explicit
|
|
3525
|
+
`replaySafe: true` evidence. The framework never guesses that an external
|
|
3526
|
+
side effect is replayable. After an application reconstructs its typed context,
|
|
3527
|
+
`runtime.resume({ conversationId, runId, context })` admits that queued record
|
|
3528
|
+
through the same acquisition CAS and coordinator lane; it never creates a
|
|
3529
|
+
second input message.
|
|
3530
|
+
|
|
3531
|
+
Canonical records currently write `schemaVersion: 1`. A durable adapter owns
|
|
3532
|
+
read-time migration of older rows: migrate to the current shape at its storage
|
|
3533
|
+
boundary, validate with the exported schema, and write only the current
|
|
3534
|
+
version. Core deliberately does not guess an application's database migration
|
|
3535
|
+
or silently accept an unknown future version.
|
|
3536
|
+
|
|
3537
|
+
## Events and reconnect
|
|
3538
|
+
|
|
3539
|
+
`publish` receives event classes with different guarantees:
|
|
3540
|
+
|
|
3541
|
+
- `assistant-delta` is transient and ordered by
|
|
3542
|
+
`(runId, runtimeEpoch, sequence)`;
|
|
3543
|
+
- `assistant-checkpoint` follows a successful checkpoint CAS;
|
|
3544
|
+
- `run-state` follows durable queue/acquire/interrupt transitions;
|
|
3545
|
+
- `tool-status` is transient lifecycle presentation with JSON-safe input on
|
|
3546
|
+
start and output on completion; internal tool failures remain generic;
|
|
3547
|
+
- `terminal` follows the winning terminal CAS.
|
|
3548
|
+
|
|
3549
|
+
A named custom stop condition terminalizes with `policy_stop`; its `policyName`
|
|
3550
|
+
is persisted on the run and included in the terminal event/result. `max-steps`
|
|
3551
|
+
is the reserved built-in policy name. `loop.prepareStep` is the controlled AI
|
|
3552
|
+
SDK step boundary for changing active tools, model, instructions or messages.
|
|
3553
|
+
It cannot replace the managed tool set or bypass its lifecycle fence.
|
|
3554
|
+
|
|
3555
|
+
`loop.idleTimeoutMs` is inactivity, not total duration: the deadline resets on
|
|
3556
|
+
every model stream event. A stalled call aborts with durable reason `timeout`;
|
|
3557
|
+
user interruption and shutdown remain distinct.
|
|
3558
|
+
|
|
3559
|
+
Reconnect loads the durable snapshot. Missing transient deltas do not mean the
|
|
3560
|
+
canonical result was lost. Exactly-once external delivery requires the
|
|
3561
|
+
application's transactional outbox or stable-ID deduplication.
|
|
3562
|
+
|
|
3563
|
+
## Managed tools
|
|
3564
|
+
|
|
3565
|
+
Always compose `toolFenceLifecycle` into `mountAgent`. It checks ownership
|
|
3566
|
+
before a managed side effect and again before accepting its result. Fence loss
|
|
3567
|
+
uses an internal control signal: it stops the old loop and is not sent to the
|
|
3568
|
+
model as a tool error.
|
|
3569
|
+
|
|
3570
|
+
The framework cannot undo an already-started non-cooperative external effect.
|
|
3571
|
+
Pass the stable call/run idempotency identity into business mutations when the
|
|
3572
|
+
effect must be replay-safe.
|
|
3573
|
+
|
|
3574
|
+
## History, provider metadata and files
|
|
3575
|
+
|
|
3576
|
+
`projectAgentHistory` converts canonical engine records into provider-valid AI
|
|
3577
|
+
SDK messages and pairs tool calls/results. Provider-required metadata is kept
|
|
3578
|
+
in a versioned opaque envelope and omitted from product delivery by default.
|
|
3579
|
+
|
|
3580
|
+
`ComposedAgentPrompt.instructions` accepts the AI SDK `Instructions` contract.
|
|
3581
|
+
Use `adaptInstructions` when a provider needs metadata on the system message:
|
|
3582
|
+
|
|
3583
|
+
```ts
|
|
3584
|
+
prompt({
|
|
3585
|
+
context,
|
|
3586
|
+
signal,
|
|
3587
|
+
adaptInstructions: (content) => ({
|
|
3588
|
+
role: 'system',
|
|
3589
|
+
content,
|
|
3590
|
+
providerOptions: { openrouter: { cacheControl: { type: 'ephemeral' } } },
|
|
3591
|
+
}),
|
|
3592
|
+
})
|
|
3593
|
+
```
|
|
3594
|
+
|
|
3595
|
+
Attachments and generated files remain application-owned. The runtime only
|
|
3596
|
+
stores a reference returned by `persistGeneratedFile`; it never silently puts
|
|
3597
|
+
base64 blobs into the neutral history store.
|
|
3598
|
+
|
|
3599
|
+
To send a stored attachment back to a multimodal model, configure
|
|
3600
|
+
`history.resolveFile`. It maps the neutral file reference to AI SDK file data
|
|
3601
|
+
(URL, bytes, provider reference or text). Without a resolver the explicit
|
|
3602
|
+
`unresolvedFile` policy is `text` by default; choose `omit` or `error` when a
|
|
3603
|
+
placeholder would be incorrect.
|
|
3604
|
+
|
|
3605
|
+
## Compaction
|
|
3606
|
+
|
|
3607
|
+
`structuredCompaction` summarizes complete provider-valid turn groups outside
|
|
3608
|
+
the store lock, then calls `replaceCompactedRange` against the exact snapshot
|
|
3609
|
+
version. A concurrent input produces `conflict`; the stale summary is not
|
|
3610
|
+
applied. Summary records use the dedicated `summary` role and project to a
|
|
3611
|
+
provider system message. The consumer supplies the structured summary schema
|
|
3612
|
+
and prompt. Pass `previousSummary` for a direct call, or configure
|
|
3613
|
+
`readPreviousSummary` for runtime-managed compaction, to merge and atomically
|
|
3614
|
+
replace a leading summary on the next compaction.
|
|
3615
|
+
|
|
3616
|
+
## Observability
|
|
3617
|
+
|
|
3618
|
+
`createAgentObservability` emits a separate operator-only `AgentRunEvent`. It
|
|
3619
|
+
reuses the same bounded sink lifecycle as request/tool observability without
|
|
3620
|
+
sending new event kinds to existing request sinks. Product events omit provider
|
|
3621
|
+
causes; the operator terminal event may include `internalCause`, so its sink
|
|
3622
|
+
must use internal retention and redaction policy.
|
|
3623
|
+
|
|
3624
|
+
Usage values carry `provider-reported`, `computed`, `estimated` or
|
|
3625
|
+
`unavailable` provenance. Cost additionally carries an ISO currency code;
|
|
3626
|
+
OpenRouter-reported cost is normalized as USD. Missing values remain absent,
|
|
3627
|
+
never zero-filled.
|
|
3628
|
+
|
|
3629
|
+
In-memory sink delivery is at-most-once per execution. Stable event IDs allow
|
|
3630
|
+
consumer dedupe; cross-crash exactly-once requires a durable outbox.
|
|
3631
|
+
|
|
3632
|
+
|
|
3329
3633
|
==============================================================================
|
|
3330
3634
|
# Guide: CLI (docs/guide/cli.md)
|
|
3331
3635
|
==============================================================================
|
|
@@ -4685,22 +4989,36 @@ error round-trips without adding correlation data to the response body.
|
|
|
4685
4989
|
### Stitch codes vs your codes
|
|
4686
4990
|
|
|
4687
4991
|
A `code` is a free string — your app codes (`BOT_NOT_FOUND`, …) are yours and the
|
|
4688
|
-
core never models them (ADR 0002). But stitchkit itself emits a
|
|
4992
|
+
core never models them (ADR 0002). But stitchkit itself emits a set of its own:
|
|
4689
4993
|
`BAD_REQUEST`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `METHOD_NOT_ALLOWED`,
|
|
4690
|
-
`CONFLICT`, `RATE_LIMITED`, `VALIDATION_ERROR`, `
|
|
4994
|
+
`CONFLICT`, `RATE_LIMITED`, `VALIDATION_ERROR`, `FILE_INVALID_PATH`,
|
|
4995
|
+
`FILE_OUTSIDE_ROOT`, `FILE_NOT_FOUND`, `FILE_NOT_REGULAR`,
|
|
4996
|
+
`FILE_INSPECTION_REJECTED`, `FILE_TOO_LARGE`, `FILE_EXISTS`,
|
|
4997
|
+
`REALTIME_CONTRACT_VIOLATION`, `INTERNAL_SERVER_ERROR` — a set that grows in
|
|
4998
|
+
ordinary releases, each addition named in the changelog. They are
|
|
4691
4999
|
published as **`STITCH_ERROR_STATUS`** (the `code → status` map) and
|
|
4692
5000
|
**`StitchErrorCode`** (its `keyof`), with **`isStitchErrorCode()`** (→ ADR 0026).
|
|
4693
5001
|
|
|
4694
5002
|
If you translate stitch's framework errors into your own wire codes in an
|
|
4695
|
-
`onError` hook,
|
|
4696
|
-
|
|
5003
|
+
`onError` hook, you choose how the set's growth reaches you. Keying the map by
|
|
5004
|
+
`StitchErrorCode` makes it exhaustive, so a code stitch adds or renames becomes
|
|
5005
|
+
a compile error rather than an unfamiliar code on your wire — worth it when the
|
|
5006
|
+
envelope is a published contract, at the cost of an edit on those releases:
|
|
4697
5007
|
|
|
4698
5008
|
```ts
|
|
5009
|
+
// Exhaustive on purpose: the annotation is what turns a new stitch code into a
|
|
5010
|
+
// compile error here. Drop it (or use `satisfies` on a partial map) to let an
|
|
5011
|
+
// unmapped code travel as itself instead.
|
|
4699
5012
|
const STITCH_TO_APP: Record<StitchErrorCode, AppCode> = {
|
|
4700
5013
|
NOT_FOUND: 'NOT_FOUND', METHOD_NOT_ALLOWED: 'METHOD_NOT_ALLOWED',
|
|
4701
5014
|
BAD_REQUEST: 'VALIDATION_ERROR', VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
4702
5015
|
UNAUTHORIZED: 'UNAUTHORIZED', FORBIDDEN: 'FORBIDDEN', CONFLICT: 'CONFLICT',
|
|
4703
5016
|
RATE_LIMITED: 'RATE_LIMITED', INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
|
|
5017
|
+
REALTIME_CONTRACT_VIOLATION: 'INTERNAL_SERVER_ERROR',
|
|
5018
|
+
FILE_INVALID_PATH: 'VALIDATION_ERROR', FILE_OUTSIDE_ROOT: 'VALIDATION_ERROR',
|
|
5019
|
+
FILE_NOT_FOUND: 'NOT_FOUND', FILE_NOT_REGULAR: 'VALIDATION_ERROR',
|
|
5020
|
+
FILE_INSPECTION_REJECTED: 'VALIDATION_ERROR', FILE_TOO_LARGE: 'VALIDATION_ERROR',
|
|
5021
|
+
FILE_EXISTS: 'CONFLICT',
|
|
4704
5022
|
}
|
|
4705
5023
|
onError: (ctx, err) => {
|
|
4706
5024
|
if (AppError.is(err) && isStitchErrorCode(err.code)) {
|
|
@@ -4776,20 +5094,20 @@ codes and schemas remain application-owned; Stitchkit stays domain-free.
|
|
|
4776
5094
|
|
|
4777
5095
|
## `createErrorHook`
|
|
4778
5096
|
|
|
4779
|
-
`createErrorHook` is the code-map above, packaged — you supply
|
|
4780
|
-
|
|
5097
|
+
`createErrorHook` is the code-map above, packaged — you supply a `codeMap` and
|
|
5098
|
+
the envelope shape, it does the normalisation (including the
|
|
4781
5099
|
never-leak-an-internal-message rule for a raw throw):
|
|
4782
5100
|
|
|
4783
5101
|
```ts
|
|
4784
5102
|
const onError = createErrorHook({
|
|
5103
|
+
// Map the codes you have an opinion about; the rest travel as themselves.
|
|
4785
5104
|
codeMap: {
|
|
4786
5105
|
BAD_REQUEST: 'bad_request', VALIDATION_ERROR: 'bad_request',
|
|
4787
5106
|
UNAUTHORIZED: 'unauthenticated', FORBIDDEN: 'forbidden',
|
|
4788
5107
|
NOT_FOUND: 'not_found', METHOD_NOT_ALLOWED: 'not_found',
|
|
4789
5108
|
CONFLICT: 'conflict', RATE_LIMITED: 'rate_limited',
|
|
4790
5109
|
INTERNAL_SERVER_ERROR: 'internal',
|
|
4791
|
-
|
|
4792
|
-
} satisfies Record<StitchErrorCode, string>,
|
|
5110
|
+
},
|
|
4793
5111
|
// `ctx` is the request's RuntimeContext — read `ctx.traceId` for a
|
|
4794
5112
|
// correlation id in the envelope. Declaring it is optional.
|
|
4795
5113
|
render: (info, ctx) => ({
|
|
@@ -4802,8 +5120,24 @@ const onError = createErrorHook({
|
|
|
4802
5120
|
createServer({ services, hooks: { onError } })
|
|
4803
5121
|
```
|
|
4804
5122
|
|
|
4805
|
-
|
|
4806
|
-
|
|
5123
|
+
`codeMap` is partial: map the codes you have an opinion about. A stitchkit code
|
|
5124
|
+
you did not list travels as itself — the same thing a code you threw yourself
|
|
5125
|
+
always did. That is what keeps a code added by a future release from being a
|
|
5126
|
+
compile break for every project that translates codes at all.
|
|
5127
|
+
|
|
5128
|
+
One `satisfies` is the **opt-in** to the stricter deal:
|
|
5129
|
+
|
|
5130
|
+
```ts
|
|
5131
|
+
codeMap: { /* … every code … */ } satisfies Record<StitchErrorCode, string>,
|
|
5132
|
+
```
|
|
5133
|
+
|
|
5134
|
+
That makes the map exhaustive on your side, so a release that adds a code stops
|
|
5135
|
+
your build until you decide what the new code is called on your wire. Take it
|
|
5136
|
+
when your envelope is a published contract and a code surfacing in stitchkit's
|
|
5137
|
+
spelling would violate it; leave it off when passing one through is fine.
|
|
5138
|
+
Neither choice is silent — the changelog names every added code. For a single
|
|
5139
|
+
catch-all instead of either, decide it in `render`, where `info.code` is the
|
|
5140
|
+
resolved value.
|
|
4807
5141
|
|
|
4808
5142
|
Both `onError` and `render` may be asynchronous and receive the matched endpoint
|
|
4809
5143
|
as their final argument. The observer is awaited before rendering, so it can
|
|
@@ -4878,9 +5212,11 @@ a request context, and event projections — and you usually touch only the last
|
|
|
4878
5212
|
### createObservability
|
|
4879
5213
|
|
|
4880
5214
|
`createObservability` configures request and tool projections independently.
|
|
4881
|
-
Every completed call is normalised into one `RequestEvent`; HTTP
|
|
4882
|
-
owned directly by `createHandler`, while MCP/Agent completion uses
|
|
4883
|
-
`ToolCallHooks` runner.
|
|
5215
|
+
Every completed application call is normalised into one `RequestEvent`; HTTP
|
|
5216
|
+
completion is owned directly by `createHandler`, while MCP/Agent completion uses
|
|
5217
|
+
the canonical `ToolCallHooks` runner. Confirmed HTTP client cancellation stays
|
|
5218
|
+
in the access log by default and becomes a structured event only when the
|
|
5219
|
+
request sink opts in. There is no nested HTTP audit wrapper.
|
|
4884
5220
|
|
|
4885
5221
|
```ts
|
|
4886
5222
|
import { createObservability } from 'stitchkit/observability'
|
|
@@ -4901,6 +5237,7 @@ export const observability = createObservability({
|
|
|
4901
5237
|
request: {
|
|
4902
5238
|
write,
|
|
4903
5239
|
includePayload: false, // default: no Request.clone(), payload is null
|
|
5240
|
+
includeCancelled: false, // default: keep client closes in access logs only
|
|
4904
5241
|
filter: (event) => event.method !== 'GET',
|
|
4905
5242
|
},
|
|
4906
5243
|
tools: {
|
|
@@ -4923,6 +5260,40 @@ Each sink runs fire-and-forget and fails independently: a slow or broken request
|
|
|
4923
5260
|
sink cannot block the response, suppress operational logging or break the tool
|
|
4924
5261
|
sink.
|
|
4925
5262
|
|
|
5263
|
+
#### Client cancellation
|
|
5264
|
+
|
|
5265
|
+
A physical client close is classified only when the request's own signal is
|
|
5266
|
+
aborted and the thrown value is either an `AbortError` or contains the exact
|
|
5267
|
+
`request.signal.reason` by identity at the top level or within at most eight
|
|
5268
|
+
standard `cause` links. Cause traversal is cycle-safe. No message or error-code
|
|
5269
|
+
matching is used; active requests and unrelated/deeper causes remain application
|
|
5270
|
+
failures. The access completion is always `499/info`, without application error
|
|
5271
|
+
fields or project `onError`.
|
|
5272
|
+
|
|
5273
|
+
Structured request sinks are default-preserving: existing sinks receive no row
|
|
5274
|
+
for this outcome. Opt in when cancellation frequency belongs in the durable
|
|
5275
|
+
stream:
|
|
5276
|
+
|
|
5277
|
+
```ts
|
|
5278
|
+
const observability = createObservability({
|
|
5279
|
+
request: {
|
|
5280
|
+
includeCancelled: true,
|
|
5281
|
+
write: (event) => {
|
|
5282
|
+
if (event.outcome === 'cancelled') return recordClientClose(event)
|
|
5283
|
+
return recordApplicationRequest(event)
|
|
5284
|
+
},
|
|
5285
|
+
},
|
|
5286
|
+
})
|
|
5287
|
+
```
|
|
5288
|
+
|
|
5289
|
+
An opted-in row has `outcome: 'cancelled'`, `ok: false`, `statusCode: 499`, the
|
|
5290
|
+
ordinary identity/trace/timing fields and no `errorCode`, `errorMessage` or
|
|
5291
|
+
`errorDetail`. `ok` remains the legacy success bit: branch on `outcome` first.
|
|
5292
|
+
Cancellation rows use the same filter, capacity, diagnostics, ordering,
|
|
5293
|
+
`flush()` and `close()` machinery as every request event. MCP protocol
|
|
5294
|
+
cancellation remains represented by `event.mcp.outcome`; Agent and CLI have no
|
|
5295
|
+
generic client-disconnect signal and are not inferred from error text.
|
|
5296
|
+
|
|
4926
5297
|
The fire-and-forget work has an explicit bounded lifecycle:
|
|
4927
5298
|
|
|
4928
5299
|
```ts
|
|
@@ -5003,7 +5374,8 @@ queryable across all three:
|
|
|
5003
5374
|
| `httpMethod` | the contract verb on **tool** events (their `method` is `TOOL`) — filter reads vs writes across both surfaces with `(event.httpMethod ?? event.method) !== 'GET'` |
|
|
5004
5375
|
| `dimensions` | app-defined domain dimensions (tenant / project / entity id) — see [request context](#request-context) |
|
|
5005
5376
|
| `traceId` / `spanId` / `parentSpanId` | [W3C trace context](#trace-context) |
|
|
5006
|
-
| `
|
|
5377
|
+
| `outcome` | optional `'cancelled'` on explicitly enabled HTTP client-close rows; ordinary rows omit it |
|
|
5378
|
+
| `ok` / `statusCode` | legacy success bit plus real HTTP status, or `200`/`400` for a tool; an opted-in cancellation is `false` / `499` |
|
|
5007
5379
|
| `durationMs` / `startedAt` | timing |
|
|
5008
5380
|
| `errorCode` / `errorMessage` / `errorDetail` | failures only — `errorDetail` carries the structure the message flattens (e.g. Zod issues) |
|
|
5009
5381
|
| `payload` | sanitised tool arguments; HTTP is `null` unless request `includePayload` is enabled |
|
|
@@ -5253,6 +5625,10 @@ success and error alike — carrying the tool name, the arguments, the result, t
|
|
|
5253
5625
|
duration, the call context, the endpoint identity, and (only when the call failed
|
|
5254
5626
|
by throwing) the raw thrown value.
|
|
5255
5627
|
|
|
5628
|
+
A confirmed HTTP client disconnect is the exception to the raw-hook table: it
|
|
5629
|
+
is transport cancellation, so neither `afterHandle` nor project `onError` runs.
|
|
5630
|
+
Use the `499/info` access completion or opt-in request cancellation event above.
|
|
5631
|
+
|
|
5256
5632
|
```ts
|
|
5257
5633
|
createMcpHandler({
|
|
5258
5634
|
serverInfo, auth, services,
|
|
@@ -7526,6 +7902,38 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
7526
7902
|
|
|
7527
7903
|
---
|
|
7528
7904
|
|
|
7905
|
+
## `stitchkit/agent-runtime`
|
|
7906
|
+
|
|
7907
|
+
Server-only optional application runtime. See the
|
|
7908
|
+
[agent runtime guide](../guide/agent-runtime.md).
|
|
7909
|
+
|
|
7910
|
+
| Export | Kind | Summary |
|
|
7911
|
+
|--------|------|---------|
|
|
7912
|
+
| `createAgentRuntime` | function | compose durable acceptance, stream loop, checkpoints, coordination, managed tools and terminal publication |
|
|
7913
|
+
| `defineAgentProtocol` | function | declare and validate context, input metadata and canonical message parts |
|
|
7914
|
+
| `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
|
|
7915
|
+
| `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
|
|
7916
|
+
| `RecoverAgentRunSchema` | schema | explicit abandon/requeue recovery decision; acquired runs require replay-safe evidence |
|
|
7917
|
+
| `createMemoryAgentRuntimeStore` | function | process-local reference adapter, not production durability |
|
|
7918
|
+
| `projectAgentHistory` | function | asynchronously project canonical records and resolved multimodal files into provider-valid AI SDK messages |
|
|
7919
|
+
| `defineModelRegistry` | function | typed language-model descriptors, capabilities and provider construction |
|
|
7920
|
+
| `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware context budget |
|
|
7921
|
+
| `structuredCompaction` | function | summarize a provider-valid snapshot range and replace it through CAS |
|
|
7922
|
+
| `createAgentSessionCoordinator` | function | strict process-local queue/interrupt lifecycle |
|
|
7923
|
+
| `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
|
|
7924
|
+
| `AgentRuntimePrepareStep` | _type_ | per-run controlled step callback with typed domain context and managed run signal/fence |
|
|
7925
|
+
| `AgentHistoryProjectionOptions` | _type_ | storage-neutral file resolver and explicit unresolved-file behavior |
|
|
7926
|
+
| `createAgentToolFenceLifecycle` | function | pre-effect and post-effect run ownership fence for `mountAgent` |
|
|
7927
|
+
| `AgentRuntimeEventSchema` | schema | transient delta, durable checkpoint/run-state/tool and terminal event union |
|
|
7928
|
+
| `createAgentObservability` | function | separate agent-run sink over the shared bounded observability lifecycle |
|
|
7929
|
+
|
|
7930
|
+
## `stitchkit/agent-runtime/openrouter`
|
|
7931
|
+
|
|
7932
|
+
| Export | Kind | Summary |
|
|
7933
|
+
|--------|------|---------|
|
|
7934
|
+
| `openRouterProvider` | function | isolated `@openrouter/ai-sdk-provider` language-model factory |
|
|
7935
|
+
| `OpenRouterProviderSettings` | _type_ | official provider settings accepted by the factory |
|
|
7936
|
+
|
|
7529
7937
|
## `stitchkit/observability`
|
|
7530
7938
|
|
|
7531
7939
|
Server-only. The audit layer one level above the raw hooks — W3C trace context,
|
|
@@ -7537,7 +7945,7 @@ audit event. See the [Observability guide](../guide/observability.md).
|
|
|
7537
7945
|
| Export | Kind | Summary |
|
|
7538
7946
|
|--------|------|---------|
|
|
7539
7947
|
| `createObservability` | function | configure framework-owned request completion and canonical tool event sinks — [guide](../guide/observability.md#createobservability) |
|
|
7540
|
-
| `RequestEvent` | _type_ | the normalised audit event handed to the sink |
|
|
7948
|
+
| `RequestEvent` | _type_ | the normalised audit event handed to the sink; opt-in HTTP cancellation rows carry `outcome: 'cancelled'` |
|
|
7541
7949
|
| `ObservabilityConfig` | _type_ | independent request and tool sink configuration |
|
|
7542
7950
|
| `Observability` | _type_ | `{ request?, toolCall, getStatus(), flush(), close() }` with bounded sink lifecycle |
|
|
7543
7951
|
| `ObservabilitySinkStatus` | _type_ | immutable counters for one bounded request/tool sink |
|
|
@@ -7545,11 +7953,11 @@ audit event. See the [Observability guide](../guide/observability.md).
|
|
|
7545
7953
|
| `ObservabilityDrainReport` | _type_ | final closed/drained snapshot plus duration |
|
|
7546
7954
|
| `ObservabilitySinkStatusSchema` / `ObservabilityStatusSchema` / `ObservabilityDrainReportSchema` | schema | runtime schemas for status/report integration boundaries |
|
|
7547
7955
|
| `RequestEventSinkConfig` | _type_ | `write`, filter/sanitisation, `maxPending`, `onSinkError` and `onDrop` |
|
|
7548
|
-
| `RequestObservabilityConfig` | _type_ | request sink plus opt-in payload capture |
|
|
7956
|
+
| `RequestObservabilityConfig` | _type_ | request sink plus opt-in payload capture and default-off `includeCancelled` rows |
|
|
7549
7957
|
| `SinkDropReason` | _type_ | `'capacity' \| 'closed'` |
|
|
7550
7958
|
| `SinkError` | _type_ | isolated sink/projection failure and optional event |
|
|
7551
7959
|
| `SinkDrop` | _type_ | rejected event, reason and current pending count |
|
|
7552
|
-
| `HttpRequestCompletion` | _type_ | the single framework-owned HTTP outcome projected to logging and request events |
|
|
7960
|
+
| `HttpRequestCompletion` | _type_ | the single framework-owned HTTP outcome, including optional neutral cancellation, projected to logging and request events |
|
|
7553
7961
|
| `HttpRequestObserver` | _type_ | server-facing projection consumed by `HandlerConfig.observability` |
|
|
7554
7962
|
|
|
7555
7963
|
### Request context
|
|
@@ -7699,6 +8107,9 @@ payload.
|
|
|
7699
8107
|
| `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
|
|
7700
8108
|
| `ToolExtend` | _type_ | extra-args extension for `mountMcp` / `mountAgent` |
|
|
7701
8109
|
| `ToolLifecycle` | _type_ | `beforeHandle` / `afterHandle` gate for tool calls — [guide](../guide/mcp-and-agents.md#guarding-tools--lifecycle) |
|
|
8110
|
+
| `ToolExecutionControlReason` | _type_ | internal managed-execution stop reason: stale run or requested interruption |
|
|
8111
|
+
| `ToolExecutionControlError` | class | control-flow error used to unwind a superseded managed tool call without presenting it as a model-facing tool failure |
|
|
8112
|
+
| `isToolExecutionControlError` | function | narrow an unknown thrown value to the managed execution control error |
|
|
7702
8113
|
| `ToolOperation` | _type_ | executable path-free operation shape shared by contract and framework-native runners |
|
|
7703
8114
|
| `ToolCallHooks` | _type_ | object-shaped `beforeToolCall` / `afterToolCall` / `onToolError` observability hooks; the raw thrown value reaches the last two as `error` ([guide](../guide/observability.md#the-cause-behind-a-failed-tool-call)) |
|
|
7704
8115
|
| `BeforeToolCallOptions` | _type_ | `{ toolName, args, context, endpoint }` passed before execution |
|
package/llms.txt
CHANGED
|
@@ -10,6 +10,7 @@ Build with stitchkit: define a contract once, then `implement` it and serve it (
|
|
|
10
10
|
- [HTTP server](https://github.com/max-listov/stitchkit/blob/master/docs/guide/server.md): createServer/createHandler, implement, lifecycle hooks, raw routes + raw-response endpoints + helpers, scopePrefixes, serveFile, primitives
|
|
11
11
|
- [Typed client](https://github.com/max-listov/stitchkit/blob/master/docs/guide/client.md): createClient/createHttpClient, the typed call surface, scoped clients, SSE
|
|
12
12
|
- [MCP & agents](https://github.com/max-listov/stitchkit/blob/master/docs/guide/mcp-and-agents.md): contracts as MCP tools (createMcpHandler) and AI-agent tools (mountAgent); tool lifecycle, extend, identity
|
|
13
|
+
- [Agent application runtime](https://github.com/max-listov/stitchkit/blob/master/docs/guide/agent-runtime.md): optional durable history, prompt/model composition, stream loop, coordination, fencing and events
|
|
13
14
|
- [CLI](https://github.com/max-listov/stitchkit/blob/master/docs/guide/cli.md): contracts as a command-line program
|
|
14
15
|
- [Realtime](https://github.com/max-listov/stitchkit/blob/master/docs/guide/realtime.md): Socket.IO server/client wrappers, handshake auth, the cache bridge, a raw WebSocket lane
|
|
15
16
|
- [Auth & errors](https://github.com/max-listov/stitchkit/blob/master/docs/guide/auth-and-errors.md): scopes, createAuthHook, JWT/cookies, the AppError model, the stitch error-code registry
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stitchkit",
|
|
3
|
-
"version": "0.56.
|
|
3
|
+
"version": "0.56.2",
|
|
4
4
|
"description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -76,6 +76,14 @@
|
|
|
76
76
|
"types": "./dist/observability/index.d.ts",
|
|
77
77
|
"import": "./dist/observability/index.js"
|
|
78
78
|
},
|
|
79
|
+
"./agent-runtime": {
|
|
80
|
+
"types": "./dist/agent-runtime.d.ts",
|
|
81
|
+
"import": "./dist/agent-runtime.js"
|
|
82
|
+
},
|
|
83
|
+
"./agent-runtime/openrouter": {
|
|
84
|
+
"types": "./dist/agent-runtime-openrouter.d.ts",
|
|
85
|
+
"import": "./dist/agent-runtime-openrouter.js"
|
|
86
|
+
},
|
|
79
87
|
"./testing": {
|
|
80
88
|
"types": "./dist/testing.d.ts",
|
|
81
89
|
"import": "./dist/testing.js"
|
|
@@ -95,7 +103,7 @@
|
|
|
95
103
|
"scripts": {
|
|
96
104
|
"check": "bun x tsc --noEmit",
|
|
97
105
|
"build:browser": "bun build src/index.ts src/react.ts src/contract/index.ts --outdir dist --target node --packages external --splitting --root src",
|
|
98
|
-
"build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts --outdir dist --target node --packages external --splitting --root src",
|
|
106
|
+
"build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-openrouter.ts --outdir dist --target node --packages external --splitting --root src",
|
|
99
107
|
"build:js": "bun run build:browser && bun run build:server",
|
|
100
108
|
"build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
101
109
|
"build": "rm -rf dist && bun run build:js && bun run build:types && bun scripts/check-browser-clean.mjs && bun scripts/check-env-live.mjs && bun scripts/check-public-types.mjs",
|
|
@@ -110,6 +118,7 @@
|
|
|
110
118
|
"peerDependencies": {
|
|
111
119
|
"@modelcontextprotocol/ext-apps": "^1.7.2",
|
|
112
120
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
121
|
+
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
113
122
|
"@types/bun": "^1.3.14",
|
|
114
123
|
"@socket.io/bun-engine": "^0.1.1",
|
|
115
124
|
"@socket.io/component-emitter": "^3.1.2",
|
|
@@ -132,6 +141,9 @@
|
|
|
132
141
|
"@modelcontextprotocol/server": {
|
|
133
142
|
"optional": true
|
|
134
143
|
},
|
|
144
|
+
"@openrouter/ai-sdk-provider": {
|
|
145
|
+
"optional": true
|
|
146
|
+
},
|
|
135
147
|
"@socket.io/bun-engine": {
|
|
136
148
|
"optional": true
|
|
137
149
|
},
|
|
@@ -164,9 +176,10 @@
|
|
|
164
176
|
"ky": "^2.0.2"
|
|
165
177
|
},
|
|
166
178
|
"devDependencies": {
|
|
167
|
-
"@modelcontextprotocol/ext-apps": "^1.7.5",
|
|
168
179
|
"@modelcontextprotocol/client": "^2.0.0",
|
|
180
|
+
"@modelcontextprotocol/ext-apps": "^1.7.5",
|
|
169
181
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
182
|
+
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
170
183
|
"@socket.io/bun-engine": "^0.1.1",
|
|
171
184
|
"@socket.io/component-emitter": "^3.1.2",
|
|
172
185
|
"@tanstack/react-query": "5.101.4",
|