experimental-a2 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/{actor-D_54lz_1.d.ts → actor-DJi3RsNu.d.ts} +2 -2
- package/dist/{actor-D_54lz_1.d.ts.map → actor-DJi3RsNu.d.ts.map} +1 -1
- package/dist/actor-client.d.ts +1 -1
- package/dist/actor-react.d.ts +1 -1
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +1 -1
- package/dist/ai-server.d.ts +1 -1
- package/dist/ai-server.js +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/scheduler-qstash.d.ts +1 -1
- package/dist/scheduler-qstash.js +1 -1
- package/dist/scheduler-vercel.d.ts +1 -1
- package/dist/scheduler-vercel.js +1 -1
- package/dist/{server-Dkz2a84E.js → server-BeNADlCI.js} +8 -5
- package/dist/server-BeNADlCI.js.map +1 -0
- package/dist/{server-DwPrMqHB.d.ts → server-DjZZa1wr.d.ts} +8 -2
- package/dist/{server-DwPrMqHB.d.ts.map → server-DjZZa1wr.d.ts.map} +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/docs/reference/01-api.mdx +64 -1
- package/examples/playground/package.json +1 -1
- package/package.json +1 -1
- package/src/server.ts +14 -3
- package/dist/server-Dkz2a84E.js.map +0 -1
|
@@ -65,6 +65,64 @@ client exposes its `A2ClientError` subclass. See
|
|
|
65
65
|
|
|
66
66
|
## `experimental-a2/server`
|
|
67
67
|
|
|
68
|
+
### `handler(entry)`
|
|
69
|
+
|
|
70
|
+
Define handlers inline in `createServer({ handlers })` for ordinary use.
|
|
71
|
+
Use this helper when composing an existing handler.
|
|
72
|
+
|
|
73
|
+
Accepts a handler function or an object with `handler` and optional `lane` and
|
|
74
|
+
`abortOn`. Returns the object shape: a function becomes `{ handler: entry }`,
|
|
75
|
+
and an object is returned unchanged. The original function and object types
|
|
76
|
+
are preserved. Use it to compose an existing handler without branching on its
|
|
77
|
+
shape.
|
|
78
|
+
|
|
79
|
+
```ts server/composed-orders.ts
|
|
80
|
+
import * as a2 from 'experimental-a2'
|
|
81
|
+
import { createServer, handler, type HandlerContext } from 'experimental-a2/server'
|
|
82
|
+
import { z } from 'zod'
|
|
83
|
+
|
|
84
|
+
const orders = a2.contract({
|
|
85
|
+
name: 'composed-orders',
|
|
86
|
+
events: {
|
|
87
|
+
created: z.object({ shopId: z.string() }),
|
|
88
|
+
notified: z.object({ shopId: z.string() }),
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const created = handler({
|
|
93
|
+
lane: 'orders',
|
|
94
|
+
handler: async (ctx: HandlerContext<typeof orders.events, 'created'>) => {
|
|
95
|
+
return orders.batch({ type: 'notified', payload: ctx.event.payload })
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
export const ordersServer = createServer({
|
|
100
|
+
contract: orders,
|
|
101
|
+
handlers: {
|
|
102
|
+
created: {
|
|
103
|
+
...created,
|
|
104
|
+
handler: async (ctx) => {
|
|
105
|
+
const result = await created.handler(ctx)
|
|
106
|
+
// Your additional work goes here:
|
|
107
|
+
// await notifyShop(ctx.event.payload, { idempotencyKey: ctx.event.id })
|
|
108
|
+
return result
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Spreading the object preserves its `lane` and `abortOn`. Set either property
|
|
116
|
+
after the spread to override it. Changing a built-in AI handler's lane can
|
|
117
|
+
separate it from the handlers it coordinates with.
|
|
118
|
+
|
|
119
|
+
Composition runs in one handler attempt. Work after the original function
|
|
120
|
+
resolves still runs before its returned events commit. A thrown error fails
|
|
121
|
+
the composed attempt; on retry, the wrapper and original handler can run again.
|
|
122
|
+
For a new handler, annotate its context as above or pass an already typed
|
|
123
|
+
function. `handler` does not bind a handler to a contract;
|
|
124
|
+
`createServer({ handlers })` checks that it matches the contract.
|
|
125
|
+
|
|
68
126
|
### `createServer(options)`
|
|
69
127
|
|
|
70
128
|
```ts
|
|
@@ -1205,7 +1263,12 @@ it into `createServer({ handlers })` beside application handlers when you need
|
|
|
1205
1263
|
a custom assembly. The table handles input facts, generation requests, model
|
|
1206
1264
|
step completion, tool calls, approval responses, and terminal tool results.
|
|
1207
1265
|
Application handlers spread later can deliberately replace a built-in
|
|
1208
|
-
handler.
|
|
1266
|
+
handler. Use `handler` from `experimental-a2/server` to normalize an
|
|
1267
|
+
existing entry before wrapping its `handler` and spreading its execution
|
|
1268
|
+
policy. Entries in this table's type are optional; narrow an entry before
|
|
1269
|
+
passing it to `handler`.
|
|
1270
|
+
|
|
1271
|
+
A custom assembly owns its browser ingress policy. Use
|
|
1209
1272
|
`server.fetch(request, { authorize })` to reject server-authored AI event names
|
|
1210
1273
|
before they reach the server. `createAgentServer()` installs the built-in
|
|
1211
1274
|
browser allowlist automatically.
|
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -301,6 +301,17 @@ export type HandlerEntry<
|
|
|
301
301
|
handler: Handler<D, K, P>
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
type HandlerFunction = (ctx: never) => Promise<unknown>
|
|
305
|
+
|
|
306
|
+
export function handler<
|
|
307
|
+
H extends HandlerFunction | { handler: HandlerFunction },
|
|
308
|
+
>(entry: H): H extends HandlerFunction ? { handler: H } : H
|
|
309
|
+
export function handler(
|
|
310
|
+
entry: HandlerFunction | { handler: HandlerFunction },
|
|
311
|
+
): { handler: HandlerFunction } {
|
|
312
|
+
return typeof entry === 'function' ? { handler: entry } : entry
|
|
313
|
+
}
|
|
314
|
+
|
|
304
315
|
export type ServerOptions<
|
|
305
316
|
D extends EventDefs,
|
|
306
317
|
P extends PresenceDefs = Record<never, never>,
|
|
@@ -615,8 +626,8 @@ export function createServer<
|
|
|
615
626
|
`contract '${name}' has no event type '${type}' — cannot register a handler for it`,
|
|
616
627
|
)
|
|
617
628
|
}
|
|
618
|
-
const
|
|
619
|
-
if (typeof
|
|
629
|
+
const callback = typeof entry === 'function' ? entry : entry?.handler
|
|
630
|
+
if (typeof callback !== 'function') {
|
|
620
631
|
throw new TypeError(`handler for '${type}' must be a function`)
|
|
621
632
|
}
|
|
622
633
|
let abortOn: AbortMatcher | null = null
|
|
@@ -660,7 +671,7 @@ export function createServer<
|
|
|
660
671
|
)
|
|
661
672
|
}
|
|
662
673
|
handlers.set(type, {
|
|
663
|
-
handler:
|
|
674
|
+
handler: callback as Handler<D>,
|
|
664
675
|
abortOn,
|
|
665
676
|
lane: lane as Lane<D> | null,
|
|
666
677
|
})
|