experimental-a2 0.20.0 → 0.22.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 +55 -0
- package/README.md +1 -1
- package/dist/{actor-C7b-1arn.d.ts → actor-CqibLgjQ.d.ts} +15 -7
- package/dist/actor-CqibLgjQ.d.ts.map +1 -0
- package/dist/actor-client.d.ts +1 -1
- package/dist/actor-client.js +2 -2
- package/dist/actor-react.d.ts +3 -3
- package/dist/actor-react.js +5 -5
- package/dist/{actor-shared-t7w8xIKP.js → actor-shared-DFET5q16.js} +3 -3
- package/dist/actor-shared-DFET5q16.js.map +1 -0
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +54 -43
- package/dist/actor.js.map +1 -1
- package/dist/{ai-Cz3hqVhk.d.ts → ai-DAu77CDr.d.ts} +8 -8
- package/dist/{ai-Cz3hqVhk.d.ts.map → ai-DAu77CDr.d.ts.map} +1 -1
- package/dist/{ai-mMiWul1T.js → ai-EEfKyc-z.js} +9 -9
- package/dist/ai-EEfKyc-z.js.map +1 -0
- package/dist/ai-client.d.ts +2 -2
- package/dist/ai-client.js +2 -2
- package/dist/ai-fx.d.ts +4 -2
- package/dist/ai-fx.d.ts.map +1 -1
- package/dist/ai-fx.js +214 -67
- package/dist/ai-fx.js.map +1 -1
- package/dist/{ai-harness-CV6rXbB3.d.ts → ai-harness-DTjkAr2T.d.ts} +2 -2
- package/dist/{ai-harness-CV6rXbB3.d.ts.map → ai-harness-DTjkAr2T.d.ts.map} +1 -1
- package/dist/{ai-harness-Clbg5ei7.js → ai-harness-dQeJaR1t.js} +7 -3
- package/dist/ai-harness-dQeJaR1t.js.map +1 -0
- package/dist/ai-pi.d.ts +1 -1
- package/dist/ai-pi.js +3 -3
- package/dist/ai-pi.js.map +1 -1
- package/dist/ai-react.d.ts +5 -5
- package/dist/ai-react.js +2 -2
- package/dist/ai-server.d.ts +14 -17
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +86 -73
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +2 -2
- package/dist/{client-BhHLoNKF.js → client-BQS4i_V9.js} +29 -6
- package/dist/client-BQS4i_V9.js.map +1 -0
- package/dist/{client-h_DKFAjj.d.ts → client-CUMbS_38.d.ts} +3 -3
- package/dist/{client-h_DKFAjj.d.ts.map → client-CUMbS_38.d.ts.map} +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/{contract-BYKASlCV.js → contract-CWukt01d.js} +2 -2
- package/dist/contract-CWukt01d.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/{initial-snapshot-Bx-c0pDP.d.ts → initial-snapshot-D3Lve43o.d.ts} +4 -4
- package/dist/initial-snapshot-D3Lve43o.d.ts.map +1 -0
- package/dist/{internal-CscSY7K_.js → internal-CvsrprnU.js} +40 -16
- package/dist/internal-CvsrprnU.js.map +1 -0
- package/dist/otel.d.ts +1 -1
- package/dist/otel.js +1 -1
- package/dist/otel.js.map +1 -1
- package/dist/{react-BBXgHWFc.d.ts → react-BoHvC3v9.d.ts} +4 -4
- package/dist/{react-BBXgHWFc.d.ts.map → react-BoHvC3v9.d.ts.map} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{reducer-CqA59Q6U.d.ts → reducer-CYPHsSmd.d.ts} +2 -2
- package/dist/{reducer-CqA59Q6U.d.ts.map → reducer-CYPHsSmd.d.ts.map} +1 -1
- package/dist/{reducer-BAXc8JyF.js → reducer-CjmvZSAb.js} +2 -2
- package/dist/{reducer-BAXc8JyF.js.map → reducer-CjmvZSAb.js.map} +1 -1
- package/dist/runtime-consumer-CIeL33wj.js +12 -0
- package/dist/runtime-consumer-CIeL33wj.js.map +1 -0
- package/dist/scheduler-qstash.d.ts +2 -2
- package/dist/scheduler-qstash.js +3 -3
- package/dist/scheduler-task-X1SToDjP.js.map +1 -1
- package/dist/scheduler-vercel.d.ts +2 -2
- package/dist/scheduler-vercel.js +3 -3
- package/dist/scheduler-vercel.js.map +1 -1
- package/dist/{server-qyb5aJJG.js → server-DtFrWxi3.js} +412 -116
- package/dist/server-DtFrWxi3.js.map +1 -0
- package/dist/{server-DYAATFuT.d.ts → server-qgez0Xny.d.ts} +108 -41
- package/dist/server-qgez0Xny.d.ts.map +1 -0
- package/dist/server.browser.js +1 -1
- package/dist/server.browser.js.map +1 -1
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/{session-clear-C-QwTXV1.d.ts → session-clear-D1PFe7xl.d.ts} +2 -2
- package/dist/session-clear-D1PFe7xl.d.ts.map +1 -0
- package/dist/{session-clear-DGI4jTQ5.js → session-clear-wHd5GCpZ.js} +5 -4
- package/dist/session-clear-wHd5GCpZ.js.map +1 -0
- package/dist/store-D0MhBvg6.d.ts +532 -0
- package/dist/store-D0MhBvg6.d.ts.map +1 -0
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-codec-DwrWlgQx.js +65 -0
- package/dist/store-codec-DwrWlgQx.js.map +1 -0
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-memory.d.ts.map +1 -1
- package/dist/store-memory.js +406 -225
- package/dist/store-memory.js.map +1 -1
- package/dist/{store-polling-7WJV0YWP.js → store-polling-BZt2Rf3D.js} +2 -2
- package/dist/{store-polling-7WJV0YWP.js.map → store-polling-BZt2Rf3D.js.map} +1 -1
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-postgres.d.ts.map +1 -1
- package/dist/store-postgres.js +1598 -587
- package/dist/store-postgres.js.map +1 -1
- package/dist/store-presence-polling-JuAy2Ck2.js +111 -0
- package/dist/store-presence-polling-JuAy2Ck2.js.map +1 -0
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.js +4 -4
- package/dist/store-redis-notify-CsJw_hfD.js +3060 -0
- package/dist/store-redis-notify-CsJw_hfD.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.d.ts.map +1 -1
- package/dist/store-redis.js +4 -5
- package/dist/store-redis.js.map +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/store-sqlite.d.ts.map +1 -1
- package/dist/store-sqlite.js +527 -299
- package/dist/store-sqlite.js.map +1 -1
- package/dist/stream-buffer-DrTyiIuo.js +57 -0
- package/dist/stream-buffer-DrTyiIuo.js.map +1 -0
- package/dist/{telemetry-Cyfqo6Qt.d.ts → telemetry-CWwsh-Gx.d.ts} +3 -3
- package/dist/telemetry-CWwsh-Gx.d.ts.map +1 -0
- package/dist/{wire-BKxH1vbP.js → wire-CV-Z7wz-.js} +6 -5
- package/dist/wire-CV-Z7wz-.js.map +1 -0
- package/docs/01-quickstart.mdx +21 -15
- package/docs/02-examples.mdx +1 -1
- package/docs/actors/01-introduction.mdx +13 -2
- package/docs/actors/02-concurrency.mdx +1 -1
- package/docs/agents/01-introduction.mdx +1 -1
- package/docs/agents/02-tools.mdx +12 -11
- package/docs/agents/03-conversations.mdx +36 -25
- package/docs/agents/04-harnesses.mdx +14 -7
- package/docs/client/03-presence.mdx +18 -14
- package/docs/contract/01-events.mdx +2 -2
- package/docs/contract/02-state.mdx +18 -14
- package/docs/contract/03-sessions.mdx +32 -25
- package/docs/index.mdx +29 -24
- package/docs/reference/01-core.mdx +7 -6
- package/docs/reference/02-server.mdx +250 -191
- package/docs/reference/04-ai.mdx +33 -23
- package/docs/reference/05-telemetry.mdx +27 -13
- package/docs/reference/06-errors.mdx +25 -19
- package/docs/reference/meta.ts +1 -1
- package/docs/schedulers/01-overview.mdx +8 -8
- package/docs/schedulers/02-vercel-queues.mdx +2 -2
- package/docs/schedulers/03-qstash.mdx +4 -4
- package/docs/server/01-consumers.mdx +418 -0
- package/docs/server/02-timers.mdx +31 -21
- package/docs/server/03-cancellation.mdx +52 -44
- package/docs/server/04-routes.mdx +4 -1
- package/docs/server/05-sql-projections.mdx +391 -0
- package/docs/server/06-guarantees.mdx +61 -51
- package/docs/stores/01-overview.mdx +3 -3
- package/docs/stores/02-redis.mdx +24 -10
- package/docs/stores/03-redis-http.mdx +8 -6
- package/docs/stores/04-postgres.mdx +65 -14
- package/docs/stores/05-sqlite.mdx +5 -3
- package/docs/upgrades/01-overview.mdx +31 -0
- package/docs/upgrades/78-0-22.mdx +115 -0
- package/docs/upgrades/79-0-21.mdx +165 -0
- package/docs/upgrades/80-0-20.mdx +43 -0
- package/docs/upgrades/81-0-19.mdx +33 -0
- package/docs/upgrades/82-0-18.mdx +33 -0
- package/docs/upgrades/83-0-17.mdx +69 -0
- package/docs/upgrades/meta.ts +3 -0
- package/examples/playground/DEPLOY.md +39 -7
- package/examples/playground/app/a0/chat.test.tsx +2 -2
- package/examples/playground/app/a0/sandbox-log.ts +17 -15
- package/examples/playground/app/a0/sandbox.ts +58 -13
- package/examples/playground/app/a0/server.ts +4 -4
- package/examples/playground/app/a2slack/a2slack.css +1067 -0
- package/examples/playground/app/a2slack/c/[channel]/page.tsx +20 -0
- package/examples/playground/app/a2slack/consumers/agent.ts +63 -0
- package/examples/playground/app/a2slack/consumers/feed.ts +164 -0
- package/examples/playground/app/a2slack/consumers/notify.ts +116 -0
- package/examples/playground/app/a2slack/consumers/search.ts +37 -0
- package/examples/playground/app/a2slack/consumers/triage.ts +31 -0
- package/examples/playground/app/a2slack/consumers/welcome.ts +25 -0
- package/examples/playground/app/a2slack/db/a2.ts +209 -0
- package/examples/playground/app/a2slack/db/index.ts +73 -0
- package/examples/playground/app/a2slack/db/migrations/0000_extensions.sql +4 -0
- package/examples/playground/app/a2slack/db/migrations/0001_workspace.sql +74 -0
- package/examples/playground/app/a2slack/db/migrations/0002_a2.sql +215 -0
- package/examples/playground/app/a2slack/db/migrations/0003_a2_batch.sql +67 -0
- package/examples/playground/app/a2slack/db/migrations/0004_a2_session_event_ids.sql +2 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0000_snapshot.json +18 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0001_snapshot.json +500 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0002_snapshot.json +1159 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0003_snapshot.json +1159 -0
- package/examples/playground/app/a2slack/db/migrations/meta/0004_snapshot.json +1165 -0
- package/examples/playground/app/a2slack/db/migrations/meta/_journal.json +41 -0
- package/examples/playground/app/a2slack/db/queries.ts +263 -0
- package/examples/playground/app/a2slack/db/schema.ts +145 -0
- package/examples/playground/app/a2slack/drills/a2slack.drill.ts +708 -0
- package/examples/playground/app/a2slack/drills/harness.ts +244 -0
- package/examples/playground/app/a2slack/events/route.ts +36 -0
- package/examples/playground/app/a2slack/identity.ts +44 -0
- package/examples/playground/app/a2slack/inbox/route.ts +8 -0
- package/examples/playground/app/a2slack/lag/data/route.ts +8 -0
- package/examples/playground/app/a2slack/lag/page.tsx +101 -0
- package/examples/playground/app/a2slack/lag.ts +73 -0
- package/examples/playground/app/a2slack/layout.tsx +43 -0
- package/examples/playground/app/a2slack/messages/route.ts +17 -0
- package/examples/playground/app/a2slack/model.test.ts +208 -0
- package/examples/playground/app/a2slack/model.ts +369 -0
- package/examples/playground/app/a2slack/models.test.ts +72 -0
- package/examples/playground/app/a2slack/page.tsx +10 -0
- package/examples/playground/app/a2slack/scheduler/route.ts +5 -0
- package/examples/playground/app/a2slack/search/route.ts +40 -0
- package/examples/playground/app/a2slack/search-index.ts +108 -0
- package/examples/playground/app/a2slack/server.test.ts +315 -0
- package/examples/playground/app/a2slack/server.ts +55 -0
- package/examples/playground/app/a2slack/sessions.ts +50 -0
- package/examples/playground/app/a2slack/thread/route.ts +8 -0
- package/examples/playground/app/a2slack/ui/ChannelView.tsx +87 -0
- package/examples/playground/app/a2slack/ui/Composer.tsx +117 -0
- package/examples/playground/app/a2slack/ui/DotsShadow.tsx +42 -0
- package/examples/playground/app/a2slack/ui/Feed.tsx +157 -0
- package/examples/playground/app/a2slack/ui/InboxContext.tsx +63 -0
- package/examples/playground/app/a2slack/ui/InboxView.tsx +82 -0
- package/examples/playground/app/a2slack/ui/Menu.tsx +128 -0
- package/examples/playground/app/a2slack/ui/MessageRow.tsx +314 -0
- package/examples/playground/app/a2slack/ui/NameGate.tsx +35 -0
- package/examples/playground/app/a2slack/ui/SearchContext.tsx +146 -0
- package/examples/playground/app/a2slack/ui/SearchResults.tsx +97 -0
- package/examples/playground/app/a2slack/ui/Shell.tsx +34 -0
- package/examples/playground/app/a2slack/ui/Sidebar.tsx +199 -0
- package/examples/playground/app/a2slack/ui/ThreadPanel.tsx +134 -0
- package/examples/playground/app/a2slack/ui/useInbox.ts +71 -0
- package/examples/playground/app/agent/server.ts +3 -3
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +1 -1
- package/examples/playground/app/chat/server.ts +45 -35
- package/examples/playground/app/components/demo-icons.tsx +7 -0
- package/examples/playground/app/components/demos.tsx +7 -0
- package/examples/playground/app/orders/[orderId]/order-client.tsx +2 -2
- package/examples/playground/app/orders/page.tsx +1 -1
- package/examples/playground/app/orders/server.ts +49 -30
- package/examples/playground/app/recovery/[recoveryId]/recovery-client.tsx +14 -15
- package/examples/playground/app/recovery/page.tsx +4 -4
- package/examples/playground/app/recovery/server.ts +23 -32
- package/examples/playground/drizzle.config.ts +14 -0
- package/examples/playground/lib/store.ts +1 -1
- package/examples/playground/next.config.ts +6 -1
- package/examples/playground/package.json +12 -1
- package/examples/playground/scripts/migrate.mjs +31 -0
- package/examples/playground/vercel.json +9 -0
- package/examples/playground/vitest.drills.config.ts +32 -0
- package/package.json +5 -2
- package/sql/postgres/drizzle-schema.ts +209 -0
- package/sql/postgres/schema.sql +227 -67
- package/src/actor-shared.ts +10 -2
- package/src/actor.ts +101 -71
- package/src/ai-agent.ts +162 -111
- package/src/ai-control-server.ts +8 -8
- package/src/ai-fx.ts +324 -82
- package/src/ai-harness.ts +17 -2
- package/src/ai-pi.ts +2 -2
- package/src/ai-server.ts +2 -2
- package/src/ai.ts +7 -7
- package/src/client.ts +19 -2
- package/src/contract.ts +1 -1
- package/src/deterministic-id.ts +27 -4
- package/src/errors.ts +8 -5
- package/src/idempotent-replay.ts +0 -1
- package/src/index.ts +1 -1
- package/src/internal.ts +57 -16
- package/src/otel.ts +1 -1
- package/src/postgres-schema.ts +98 -57
- package/src/presence-recovery.ts +18 -11
- package/src/presence-tombstones.ts +52 -0
- package/src/push-envelope.ts +20 -0
- package/src/runtime-consumer.ts +10 -0
- package/src/scheduler-task.ts +2 -2
- package/src/scheduler-vercel.ts +1 -1
- package/src/server.browser.ts +1 -1
- package/src/server.ts +819 -218
- package/src/session-socket.ts +1 -1
- package/src/store-codec.ts +66 -0
- package/src/store-memory.ts +604 -286
- package/src/store-postgres.ts +2006 -857
- package/src/store-presence-polling.ts +59 -34
- package/src/store-redis-core.ts +1961 -1333
- package/src/store-redis-notify.ts +76 -26
- package/src/store-redis.ts +2 -3
- package/src/store-sqlite.ts +915 -516
- package/src/store.ts +241 -102
- package/src/telemetry.ts +2 -1
- package/src/wire.ts +1 -0
- package/dist/actor-C7b-1arn.d.ts.map +0 -1
- package/dist/actor-shared-t7w8xIKP.js.map +0 -1
- package/dist/ai-harness-Clbg5ei7.js.map +0 -1
- package/dist/ai-mMiWul1T.js.map +0 -1
- package/dist/client-BhHLoNKF.js.map +0 -1
- package/dist/contract-BYKASlCV.js.map +0 -1
- package/dist/idempotent-replay-JdgMQRRm.js +0 -21
- package/dist/idempotent-replay-JdgMQRRm.js.map +0 -1
- package/dist/initial-snapshot-Bx-c0pDP.d.ts.map +0 -1
- package/dist/internal-CscSY7K_.js.map +0 -1
- package/dist/server-DYAATFuT.d.ts.map +0 -1
- package/dist/server-qyb5aJJG.js.map +0 -1
- package/dist/session-clear-C-QwTXV1.d.ts.map +0 -1
- package/dist/session-clear-DGI4jTQ5.js.map +0 -1
- package/dist/store-CyLUy86v.d.ts +0 -404
- package/dist/store-CyLUy86v.d.ts.map +0 -1
- package/dist/store-codec-DTG0Ftek.js +0 -10
- package/dist/store-codec-DTG0Ftek.js.map +0 -1
- package/dist/store-presence-polling-B1ixeqIS.js +0 -94
- package/dist/store-presence-polling-B1ixeqIS.js.map +0 -1
- package/dist/store-redis-notify-CM0AfLY0.js +0 -2544
- package/dist/store-redis-notify-CM0AfLY0.js.map +0 -1
- package/dist/stream-buffer-Cx7AAPGq.js +0 -23
- package/dist/stream-buffer-Cx7AAPGq.js.map +0 -1
- package/dist/telemetry-Cyfqo6Qt.d.ts.map +0 -1
- package/dist/wire-BKxH1vbP.js.map +0 -1
- package/docs/server/01-handlers.mdx +0 -227
package/src/ai-agent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The server-only implementation of the experimental-a2/ai protocol:
|
|
3
|
-
*
|
|
2
|
+
* The server-only implementation of the experimental-a2/ai protocol: its
|
|
3
|
+
* consumers and `agent()`, its assembly as an ordinary A2 server.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// oxlint-disable no-await-in-loop -- stream chunks and durable appends are
|
|
@@ -75,14 +75,17 @@ import type {
|
|
|
75
75
|
import { A2Error } from './errors.ts'
|
|
76
76
|
import {
|
|
77
77
|
consumeSchedulerSendFailure,
|
|
78
|
+
drainSettledHooks,
|
|
78
79
|
failedPreviousAttempt,
|
|
79
80
|
installAmbientToolScopeStorage,
|
|
80
81
|
type AmbientToolScope,
|
|
81
82
|
} from './internal.ts'
|
|
83
|
+
import { runtimeConsumer } from './runtime-consumer.ts'
|
|
82
84
|
import {
|
|
83
85
|
createServer,
|
|
84
86
|
type A2Server,
|
|
85
|
-
type
|
|
87
|
+
type Consumer,
|
|
88
|
+
type ConsumerContext,
|
|
86
89
|
type ServerOptions,
|
|
87
90
|
} from './server.ts'
|
|
88
91
|
import {
|
|
@@ -191,7 +194,7 @@ export type AgentResolverContext<
|
|
|
191
194
|
* in the checkpoint the generation already reads, so it costs no I/O.
|
|
192
195
|
*/
|
|
193
196
|
state: X
|
|
194
|
-
session: Pick<
|
|
197
|
+
session: Pick<ConsumerContext<D>['session'], 'state'>
|
|
195
198
|
signal: AbortSignal
|
|
196
199
|
}
|
|
197
200
|
|
|
@@ -239,7 +242,7 @@ export type CompactionOptions<
|
|
|
239
242
|
|
|
240
243
|
export type AgentGenerationSettings<T extends ToolSet> = AISDKStepSettings<T>
|
|
241
244
|
|
|
242
|
-
export type
|
|
245
|
+
export type ConsumersOptions<
|
|
243
246
|
M extends UIMessage,
|
|
244
247
|
D extends AIEventDefs<M> & EventDefs,
|
|
245
248
|
T extends ToolSet = ToolSet,
|
|
@@ -344,27 +347,24 @@ type AgentServerOptions<
|
|
|
344
347
|
T extends ToolSet,
|
|
345
348
|
X extends object = Record<never, never>,
|
|
346
349
|
H extends string = string,
|
|
350
|
+
C extends readonly unknown[] = readonly Consumer<D>[],
|
|
347
351
|
> = AgentModelOptions<M, D, T, X, H> &
|
|
348
|
-
Omit<
|
|
349
|
-
ServerOptions<D, Record<never, never>, Reducer<D, S>>,
|
|
350
|
-
'contract' | 'handlers'
|
|
351
|
-
> & {
|
|
352
|
-
/** Handlers for application events. */
|
|
353
|
-
handlers?: ServerOptions<D, Record<never, never>, Reducer<D, S>>['handlers']
|
|
354
|
-
}
|
|
352
|
+
Omit<ServerOptions<D, Record<never, never>, Reducer<D, S>, C>, 'contract'>
|
|
355
353
|
|
|
356
354
|
export type AgentOptions<
|
|
357
355
|
M extends UIMessage,
|
|
358
356
|
E extends EventDefs,
|
|
359
357
|
T extends ToolSet,
|
|
360
358
|
H extends string = string,
|
|
359
|
+
C extends readonly unknown[] = readonly Consumer<AIEventDefs<M> & E>[],
|
|
361
360
|
> = AgentServerOptions<
|
|
362
361
|
NoInfer<M>,
|
|
363
362
|
AIEventDefs<NoInfer<M>> & E,
|
|
364
363
|
AIState<NoInfer<M>>,
|
|
365
364
|
T,
|
|
366
365
|
Record<never, never>,
|
|
367
|
-
H
|
|
366
|
+
H,
|
|
367
|
+
C
|
|
368
368
|
> & {
|
|
369
369
|
/** Identity: prefixes storage keys and queue messages. */
|
|
370
370
|
name: string
|
|
@@ -384,7 +384,8 @@ export type AgentFromContractOptions<
|
|
|
384
384
|
Name extends string = string,
|
|
385
385
|
X extends object = Record<never, never>,
|
|
386
386
|
H extends string = string,
|
|
387
|
-
|
|
387
|
+
C extends readonly unknown[] = readonly Consumer<D>[],
|
|
388
|
+
> = AgentServerOptions<AIMessageOf<D>, D, S, T, X, H, C> & {
|
|
388
389
|
/**
|
|
389
390
|
* A shared `agentContract()`. Its application state reaches every resolver
|
|
390
391
|
* as `state`; a fully custom contract is core A2, served by `createServer()`.
|
|
@@ -480,8 +481,8 @@ const toolScopeStorage = installAmbientToolScopeStorage(
|
|
|
480
481
|
() => new AsyncLocalStorage<AmbientToolScope>(),
|
|
481
482
|
)
|
|
482
483
|
|
|
483
|
-
/** Run `fn` with `ctx` as the ambient tool
|
|
484
|
-
export function
|
|
484
|
+
/** Run `fn` with `ctx` as the ambient tool consumer context, for direct tool tests. */
|
|
485
|
+
export function runWithConsumerContext<D extends AgentToolEventDefs, R>(
|
|
485
486
|
ctx: AgentToolContext<D>,
|
|
486
487
|
fn: () => R,
|
|
487
488
|
): R {
|
|
@@ -683,7 +684,7 @@ async function* consumeGeneration(options: {
|
|
|
683
684
|
const reader = options.source.stream.getReader()
|
|
684
685
|
// The next read starts before a batch is yielded, and the consumer may
|
|
685
686
|
// take a while to ask again: a stream that fails meanwhile must not leave
|
|
686
|
-
// that read rejected with
|
|
687
|
+
// that read rejected with nothing to catch it, which ends the process.
|
|
687
688
|
const readAhead = (): Promise<StreamRead<UIMessageChunk>> => {
|
|
688
689
|
const read = reader.read()
|
|
689
690
|
read.catch(() => {})
|
|
@@ -1232,14 +1233,12 @@ const assertNoLoopOptions = (options: { harness?: { type: string } }): void => {
|
|
|
1232
1233
|
}
|
|
1233
1234
|
}
|
|
1234
1235
|
|
|
1235
|
-
export function
|
|
1236
|
+
export function createConsumers<
|
|
1236
1237
|
M extends UIMessage,
|
|
1237
1238
|
D extends AIEventDefs<M> & EventDefs,
|
|
1238
1239
|
T extends ToolSet = ToolSet,
|
|
1239
1240
|
X extends object = Record<never, never>,
|
|
1240
|
-
>(
|
|
1241
|
-
options: HandlersOptions<M, D, T, X>,
|
|
1242
|
-
): NonNullable<ServerOptions<D>['handlers']> {
|
|
1241
|
+
>(options: ConsumersOptions<M, D, T, X>): Consumer<D>[] {
|
|
1243
1242
|
if (options.model === undefined) {
|
|
1244
1243
|
throw new TypeError('agent requires model')
|
|
1245
1244
|
}
|
|
@@ -1349,7 +1348,7 @@ export function createHandlers<
|
|
|
1349
1348
|
contract: options.contract,
|
|
1350
1349
|
})
|
|
1351
1350
|
const readContext = async (
|
|
1352
|
-
session:
|
|
1351
|
+
session: ConsumerContext<D>['session'],
|
|
1353
1352
|
through: number | 'latest',
|
|
1354
1353
|
) => {
|
|
1355
1354
|
const snapshot = await session.state(contextReducer, { through })
|
|
@@ -1390,7 +1389,7 @@ export function createHandlers<
|
|
|
1390
1389
|
) => unknown
|
|
1391
1390
|
}
|
|
1392
1391
|
|
|
1393
|
-
type
|
|
1392
|
+
type ToolConsumerContext = ConsumerContext<D, 'ai.tool.execution.requested'>
|
|
1394
1393
|
|
|
1395
1394
|
const resultEvent = async (
|
|
1396
1395
|
call: ToolCalledPayload,
|
|
@@ -1435,7 +1434,7 @@ export function createHandlers<
|
|
|
1435
1434
|
}) as AppendInput<D>
|
|
1436
1435
|
|
|
1437
1436
|
const promptMessages = (input: {
|
|
1438
|
-
ctx:
|
|
1437
|
+
ctx: ToolConsumerContext
|
|
1439
1438
|
call: ToolCalledPayload
|
|
1440
1439
|
generation: GenerationStartedPayload
|
|
1441
1440
|
}): Promise<ModelMessage[]> => {
|
|
@@ -1485,7 +1484,7 @@ export function createHandlers<
|
|
|
1485
1484
|
}
|
|
1486
1485
|
|
|
1487
1486
|
const toolExecutionFailure = async (
|
|
1488
|
-
ctx:
|
|
1487
|
+
ctx: ToolConsumerContext,
|
|
1489
1488
|
call: ToolCalledPayload,
|
|
1490
1489
|
error: unknown,
|
|
1491
1490
|
): Promise<AppendInput<D> | void> => {
|
|
@@ -1498,7 +1497,7 @@ export function createHandlers<
|
|
|
1498
1497
|
}
|
|
1499
1498
|
|
|
1500
1499
|
const runToolExecution = async (
|
|
1501
|
-
ctx:
|
|
1500
|
+
ctx: ToolConsumerContext,
|
|
1502
1501
|
call: ToolCalledPayload,
|
|
1503
1502
|
execute: NonNullable<RuntimeTool['execute']>,
|
|
1504
1503
|
messages: ModelMessage[],
|
|
@@ -1575,7 +1574,7 @@ export function createHandlers<
|
|
|
1575
1574
|
}
|
|
1576
1575
|
|
|
1577
1576
|
const executeTool = async (input: {
|
|
1578
|
-
ctx:
|
|
1577
|
+
ctx: ToolConsumerContext
|
|
1579
1578
|
call: ToolCalledPayload
|
|
1580
1579
|
generation: GenerationStartedPayload
|
|
1581
1580
|
}): Promise<AppendInput<D> | void> => {
|
|
@@ -1629,7 +1628,7 @@ export function createHandlers<
|
|
|
1629
1628
|
}
|
|
1630
1629
|
|
|
1631
1630
|
const handleToolExecution = async (
|
|
1632
|
-
ctx:
|
|
1631
|
+
ctx: ToolConsumerContext,
|
|
1633
1632
|
): Promise<AppendInput<D>> => {
|
|
1634
1633
|
try {
|
|
1635
1634
|
const state = (
|
|
@@ -1666,7 +1665,7 @@ export function createHandlers<
|
|
|
1666
1665
|
}
|
|
1667
1666
|
|
|
1668
1667
|
const generationHandler = async (
|
|
1669
|
-
ctx:
|
|
1668
|
+
ctx: ConsumerContext<D, 'ai.generation.requested'>,
|
|
1670
1669
|
): Promise<void | AppendInput<D> | readonly AppendInput<D>[]> => {
|
|
1671
1670
|
if (checkAbort(ctx.signal)) return
|
|
1672
1671
|
const requestId = ctx.event.id
|
|
@@ -2150,6 +2149,7 @@ export function createHandlers<
|
|
|
2150
2149
|
const source =
|
|
2151
2150
|
harness !== undefined
|
|
2152
2151
|
? await harness.step({
|
|
2152
|
+
scope: states,
|
|
2153
2153
|
agentName: options.contract.name,
|
|
2154
2154
|
sessionId: ctx.event.sessionId,
|
|
2155
2155
|
requestIndex: ctx.event.index,
|
|
@@ -2315,23 +2315,41 @@ export function createHandlers<
|
|
|
2315
2315
|
}
|
|
2316
2316
|
}
|
|
2317
2317
|
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2318
|
+
const contract = options.contract as unknown as Contract<
|
|
2319
|
+
D,
|
|
2320
|
+
Record<never, never>,
|
|
2321
|
+
undefined
|
|
2322
|
+
>
|
|
2323
|
+
const { toolLane } = options
|
|
2324
|
+
type Of<K extends string> = ContractEvent<D, K & keyof D & string>
|
|
2325
|
+
type Generation = Of<'ai.generation.requested'>
|
|
2326
|
+
type ToolCall = Of<'ai.tool.execution.requested'>
|
|
2327
|
+
return [
|
|
2328
|
+
runtimeConsumer({
|
|
2329
|
+
contract,
|
|
2330
|
+
name: 'a2.ai.metadata',
|
|
2331
|
+
types: ['ai.model.metadata.requested'],
|
|
2332
|
+
}).run(async (ctx) => {
|
|
2333
|
+
const limits = await readModelLimits({
|
|
2334
|
+
modelId: ctx.event.payload.modelId,
|
|
2335
|
+
signal: ctx.signal,
|
|
2336
|
+
})
|
|
2337
|
+
ctx.signal.throwIfAborted()
|
|
2338
|
+
return {
|
|
2339
|
+
type: 'ai.model.metadata.resolved',
|
|
2340
|
+
id: await aiEventId('a2.ai.model.metadata.resolved', ctx.event.id),
|
|
2341
|
+
payload: { modelId: ctx.event.payload.modelId, limits },
|
|
2342
|
+
} as AppendInput<D>
|
|
2343
|
+
}),
|
|
2344
|
+
// One lane for every control event: commands, work reports, and closes
|
|
2345
|
+
// apply one at a time. Its lane function also rejects a bad command at
|
|
2346
|
+
// append, before anything is written.
|
|
2347
|
+
runtimeConsumer({
|
|
2348
|
+
contract,
|
|
2349
|
+
name: 'a2.ai.control',
|
|
2350
|
+
types: ['ai.control.requested', 'ai.work.reported', 'ai.session.closed'],
|
|
2334
2351
|
lane: ({ event }) => {
|
|
2352
|
+
if (event.type !== 'ai.control.requested') return 'a2.ai.control'
|
|
2335
2353
|
const command = event.payload as ControlCommand<M>
|
|
2336
2354
|
if (event.id === '')
|
|
2337
2355
|
throw new A2Error(
|
|
@@ -2353,17 +2371,25 @@ export function createHandlers<
|
|
|
2353
2371
|
)
|
|
2354
2372
|
return 'a2.ai.control'
|
|
2355
2373
|
},
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
lane: 'a2.ai.model',
|
|
2374
|
+
}).run(controlHandler as never),
|
|
2375
|
+
runtimeConsumer({
|
|
2376
|
+
contract,
|
|
2377
|
+
name: 'a2.ai.model',
|
|
2378
|
+
types: ['ai.generation.requested'],
|
|
2379
|
+
lane: () => 'a2.ai.model',
|
|
2380
|
+
// The contract is generic here, so the map's keys widen to string and
|
|
2381
|
+
// each predicate names its own event types.
|
|
2362
2382
|
abortOn: {
|
|
2363
|
-
'ai.control.requested': (
|
|
2383
|
+
'ai.control.requested': (
|
|
2384
|
+
event: Of<'ai.control.requested'>,
|
|
2385
|
+
trigger: Generation,
|
|
2386
|
+
) =>
|
|
2364
2387
|
event.payload.action === 'stop' &&
|
|
2365
2388
|
event.payload.turnId === trigger.payload.control?.turnId,
|
|
2366
|
-
'ai.control.committed': (
|
|
2389
|
+
'ai.control.committed': (
|
|
2390
|
+
event: Of<'ai.control.committed'>,
|
|
2391
|
+
trigger: Generation,
|
|
2392
|
+
) => {
|
|
2367
2393
|
const active = (event.payload as ControlCommit).view
|
|
2368
2394
|
return (
|
|
2369
2395
|
active?.turnId !== trigger.payload.control?.turnId ||
|
|
@@ -2371,39 +2397,50 @@ export function createHandlers<
|
|
|
2371
2397
|
)
|
|
2372
2398
|
},
|
|
2373
2399
|
'ai.session.closed': true,
|
|
2374
|
-
},
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
+
} as never,
|
|
2401
|
+
}).run((ctx) =>
|
|
2402
|
+
telemetry.span(
|
|
2403
|
+
'a2.ai.generate',
|
|
2404
|
+
{
|
|
2405
|
+
'a2.contract': options.contract.name,
|
|
2406
|
+
'a2.session_id': ctx.event.sessionId,
|
|
2407
|
+
'a2.ai.generate.request_id': ctx.event.id,
|
|
2408
|
+
'a2.ai.generate.attempt': ctx.attempt,
|
|
2409
|
+
},
|
|
2410
|
+
async () => {
|
|
2411
|
+
try {
|
|
2412
|
+
return control.settled({
|
|
2413
|
+
ctx,
|
|
2414
|
+
events: await generationHandler(ctx),
|
|
2415
|
+
})
|
|
2416
|
+
} catch (error) {
|
|
2417
|
+
if (control.cancelled({ error, signal: ctx.signal }))
|
|
2418
|
+
return control.settled({ ctx, events: undefined })
|
|
2419
|
+
throw error
|
|
2420
|
+
}
|
|
2421
|
+
},
|
|
2422
|
+
),
|
|
2423
|
+
),
|
|
2424
|
+
runtimeConsumer({
|
|
2425
|
+
contract,
|
|
2426
|
+
name: 'a2.ai.tools',
|
|
2427
|
+
types: ['ai.tool.execution.requested'],
|
|
2428
|
+
...(toolLane === undefined ? {} : { lane: () => toolLane }),
|
|
2400
2429
|
abortOn: {
|
|
2401
|
-
'ai.control.requested': (
|
|
2430
|
+
'ai.control.requested': (
|
|
2431
|
+
event: Of<'ai.control.requested'>,
|
|
2432
|
+
trigger: ToolCall,
|
|
2433
|
+
) =>
|
|
2402
2434
|
event.payload.action === 'stop' &&
|
|
2403
2435
|
event.payload.turnId === trigger.payload.turnId,
|
|
2404
|
-
'ai.generation.failed': (
|
|
2405
|
-
event
|
|
2406
|
-
|
|
2436
|
+
'ai.generation.failed': (
|
|
2437
|
+
event: Of<'ai.generation.failed'>,
|
|
2438
|
+
trigger: ToolCall,
|
|
2439
|
+
) => event.payload.generationId === trigger.payload.call.generationId,
|
|
2440
|
+
'ai.control.committed': (
|
|
2441
|
+
event: Of<'ai.control.committed'>,
|
|
2442
|
+
trigger: ToolCall,
|
|
2443
|
+
) => {
|
|
2407
2444
|
const active = (event.payload as ControlCommit).view
|
|
2408
2445
|
return (
|
|
2409
2446
|
active?.turnId !== trigger.payload.turnId ||
|
|
@@ -2411,26 +2448,26 @@ export function createHandlers<
|
|
|
2411
2448
|
)
|
|
2412
2449
|
},
|
|
2413
2450
|
'ai.session.closed': true,
|
|
2414
|
-
},
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2451
|
+
} as never,
|
|
2452
|
+
}).run((ctx) =>
|
|
2453
|
+
telemetry.span(
|
|
2454
|
+
'a2.ai.tool',
|
|
2455
|
+
{
|
|
2456
|
+
'a2.contract': options.contract.name,
|
|
2457
|
+
'a2.session_id': ctx.event.sessionId,
|
|
2458
|
+
'a2.ai.tool.request_id': ctx.event.payload.call.requestId,
|
|
2459
|
+
'a2.ai.tool.call_id': ctx.event.payload.call.toolCallId,
|
|
2460
|
+
'a2.ai.tool.name': ctx.event.payload.call.toolName,
|
|
2461
|
+
'a2.ai.tool.attempt': ctx.attempt,
|
|
2462
|
+
},
|
|
2463
|
+
() => handleToolExecution(ctx),
|
|
2464
|
+
),
|
|
2465
|
+
),
|
|
2466
|
+
] as Consumer<D>[]
|
|
2430
2467
|
}
|
|
2431
2468
|
|
|
2432
2469
|
/**
|
|
2433
|
-
* Serve an AI agent: the built-in protocol, its
|
|
2470
|
+
* Serve an AI agent: the built-in protocol, its consumers, and A2's store,
|
|
2434
2471
|
* scheduler, and telemetry, as one ordinary A2 server. Pass `name` for the
|
|
2435
2472
|
* built-in protocol, or a shared `agentContract()` when clients fold
|
|
2436
2473
|
* application state.
|
|
@@ -2440,8 +2477,9 @@ export function agent<
|
|
|
2440
2477
|
M extends UIMessage = UIMessage,
|
|
2441
2478
|
E extends EventDefs = Record<never, never>,
|
|
2442
2479
|
H extends string = never,
|
|
2480
|
+
const C extends readonly unknown[] = readonly Consumer<AIEventDefs<M> & E>[],
|
|
2443
2481
|
>(
|
|
2444
|
-
options: AgentOptions<M, E, T, H>,
|
|
2482
|
+
options: AgentOptions<M, E, T, H, C>,
|
|
2445
2483
|
): Agent<AIEventDefs<M> & E, AIState<M>, typeof AI_STATE_REDUCER>
|
|
2446
2484
|
export function agent<
|
|
2447
2485
|
D extends AIEventDefs<AIMessageOf<D>> & EventDefs,
|
|
@@ -2450,7 +2488,8 @@ export function agent<
|
|
|
2450
2488
|
Name extends string = string,
|
|
2451
2489
|
X extends object = Record<never, never>,
|
|
2452
2490
|
H extends string = never,
|
|
2453
|
-
|
|
2491
|
+
const C extends readonly unknown[] = readonly Consumer<D>[],
|
|
2492
|
+
>(options: AgentFromContractOptions<D, S, T, Name, X, H, C>): Agent<D, S, Name>
|
|
2454
2493
|
export function agent(
|
|
2455
2494
|
options:
|
|
2456
2495
|
| AgentOptions<UIMessage, EventDefs, ToolSet>
|
|
@@ -2458,6 +2497,12 @@ export function agent(
|
|
|
2458
2497
|
): Agent<AIEventDefs & EventDefs, AIState> {
|
|
2459
2498
|
type D = AIEventDefs & EventDefs
|
|
2460
2499
|
assertNoLoopOptions(options)
|
|
2500
|
+
if (
|
|
2501
|
+
options.toolLane !== undefined &&
|
|
2502
|
+
(typeof options.toolLane !== 'string' || options.toolLane.length === 0)
|
|
2503
|
+
) {
|
|
2504
|
+
throw new TypeError('toolLane must be a non-empty string')
|
|
2505
|
+
}
|
|
2461
2506
|
const {
|
|
2462
2507
|
model,
|
|
2463
2508
|
tools,
|
|
@@ -2467,13 +2512,12 @@ export function agent(
|
|
|
2467
2512
|
toolRecovery,
|
|
2468
2513
|
progress,
|
|
2469
2514
|
toolLane,
|
|
2470
|
-
handlers,
|
|
2471
2515
|
...rest
|
|
2472
2516
|
} = options
|
|
2473
2517
|
let contract: Contract<D, Record<never, never>, Reducer<D, AIState>>
|
|
2474
2518
|
let serverOptions: Omit<
|
|
2475
2519
|
ServerOptions<D, Record<never, never>, Reducer<D, AIState>>,
|
|
2476
|
-
'contract'
|
|
2520
|
+
'contract'
|
|
2477
2521
|
>
|
|
2478
2522
|
if ('contract' in rest) {
|
|
2479
2523
|
const { contract: shared, ...remaining } = rest
|
|
@@ -2493,7 +2537,7 @@ export function agent(
|
|
|
2493
2537
|
serverOptions = remaining
|
|
2494
2538
|
}
|
|
2495
2539
|
const states = harnessStates()
|
|
2496
|
-
const builtIns =
|
|
2540
|
+
const builtIns = createConsumers<UIMessage, D>({
|
|
2497
2541
|
contract,
|
|
2498
2542
|
model,
|
|
2499
2543
|
harnessStates: states,
|
|
@@ -2507,17 +2551,24 @@ export function agent(
|
|
|
2507
2551
|
...(toolRecovery === undefined ? {} : { toolRecovery }),
|
|
2508
2552
|
...(progress === undefined ? {} : { progress }),
|
|
2509
2553
|
...(toolLane === undefined ? {} : { toolLane }),
|
|
2510
|
-
} as
|
|
2511
|
-
for (const type of Object.keys(handlers ?? {})) {
|
|
2512
|
-
if (Object.hasOwn(builtIns, type))
|
|
2513
|
-
throw new TypeError(`agent handles '${type}' itself`)
|
|
2514
|
-
}
|
|
2554
|
+
} as ConsumersOptions<UIMessage, D>)
|
|
2515
2555
|
const server = createServer({
|
|
2516
2556
|
...serverOptions,
|
|
2517
2557
|
contract,
|
|
2518
|
-
|
|
2558
|
+
consumers: [...builtIns, ...(serverOptions.consumers ?? [])],
|
|
2519
2559
|
})
|
|
2520
2560
|
registerHarnessStates(server, states)
|
|
2561
|
+
const driver =
|
|
2562
|
+
harness === undefined || harness.type === 'ai-sdk'
|
|
2563
|
+
? undefined
|
|
2564
|
+
: harnessDriver(harness)
|
|
2565
|
+
const release = driver?.release
|
|
2566
|
+
// What a harness kept for a session's next step goes once nothing is left
|
|
2567
|
+
// to run for the session here.
|
|
2568
|
+
if (release !== undefined)
|
|
2569
|
+
drainSettledHooks.set(server, (sessionId) =>
|
|
2570
|
+
release({ scope: states, sessionId }),
|
|
2571
|
+
)
|
|
2521
2572
|
const applicationEvents = 'contract' in rest
|
|
2522
2573
|
setServerFetchHooks(server, {
|
|
2523
2574
|
validateIngress: (context) =>
|
package/src/ai-control-server.ts
CHANGED
|
@@ -31,7 +31,7 @@ import type {
|
|
|
31
31
|
ContractEvent,
|
|
32
32
|
EventDefs,
|
|
33
33
|
} from './contract.ts'
|
|
34
|
-
import type {
|
|
34
|
+
import type { ConsumerContext } from './server.ts'
|
|
35
35
|
import type { Reducer } from './reducer.ts'
|
|
36
36
|
import type { AICoordinatorState, CoordinatorCall } from './ai-coordinator.ts'
|
|
37
37
|
import { validateSync } from './validate.ts'
|
|
@@ -56,18 +56,18 @@ export type AIControlRuntime<
|
|
|
56
56
|
D extends AIEventDefs<M> & EventDefs,
|
|
57
57
|
> = {
|
|
58
58
|
handler(
|
|
59
|
-
ctx:
|
|
59
|
+
ctx: ConsumerContext<
|
|
60
60
|
D,
|
|
61
61
|
'ai.control.requested' | 'ai.work.reported' | 'ai.session.closed'
|
|
62
62
|
>,
|
|
63
63
|
): Promise<AppendInput<D>[]>
|
|
64
64
|
append(options: {
|
|
65
|
-
ctx:
|
|
65
|
+
ctx: ConsumerContext<D>
|
|
66
66
|
name: string
|
|
67
67
|
events: AppendInput<D>[]
|
|
68
68
|
}): Promise<ContractEvent<D>[]>
|
|
69
69
|
settled(options: {
|
|
70
|
-
ctx:
|
|
70
|
+
ctx: ConsumerContext<D>
|
|
71
71
|
events: void | AppendInput<D> | readonly AppendInput<D>[]
|
|
72
72
|
}): Promise<AppendInput<D>>
|
|
73
73
|
cancelled(options: { error: unknown; signal: AbortSignal }): boolean
|
|
@@ -117,7 +117,7 @@ export const createControlRuntime = <
|
|
|
117
117
|
const coordinator = aiCoordinatorReducer(options.contract)
|
|
118
118
|
|
|
119
119
|
const handler = async (
|
|
120
|
-
ctx:
|
|
120
|
+
ctx: ConsumerContext<
|
|
121
121
|
D,
|
|
122
122
|
'ai.control.requested' | 'ai.work.reported' | 'ai.session.closed'
|
|
123
123
|
>,
|
|
@@ -761,7 +761,7 @@ export const createControlRuntime = <
|
|
|
761
761
|
settled,
|
|
762
762
|
name,
|
|
763
763
|
}: {
|
|
764
|
-
ctx:
|
|
764
|
+
ctx: ConsumerContext<D>
|
|
765
765
|
events: readonly AppendInput<D>[]
|
|
766
766
|
settled: boolean
|
|
767
767
|
name: string
|
|
@@ -828,7 +828,7 @@ export const createControlRuntime = <
|
|
|
828
828
|
name,
|
|
829
829
|
events,
|
|
830
830
|
}: {
|
|
831
|
-
ctx:
|
|
831
|
+
ctx: ConsumerContext<D>
|
|
832
832
|
name: string
|
|
833
833
|
events: AppendInput<D>[]
|
|
834
834
|
}): Promise<ContractEvent<D>[]> => {
|
|
@@ -896,7 +896,7 @@ export const createControlRuntime = <
|
|
|
896
896
|
ctx,
|
|
897
897
|
events,
|
|
898
898
|
}: {
|
|
899
|
-
ctx:
|
|
899
|
+
ctx: ConsumerContext<D>
|
|
900
900
|
events: void | AppendInput<D> | readonly AppendInput<D>[]
|
|
901
901
|
}): Promise<AppendInput<D>> =>
|
|
902
902
|
report({
|