0.17
Redis stores need a fresh key prefix, and agents are served with agent().
Redis: a fresh keyPrefix
import { redis } from 'experimental-a2/store-redis'
export const store = redis({
url: process.env.REDIS_URL,
// a prefix no earlier release wrote under:
keyPrefix: 'a2-017',
})Both Redis stores change how they keep event ids and per-event metadata: one
key per event id instead of one shared hash, and metadata in hashes of 1,000
events. 0.17 no longer reads the shared id hash, and earlier releases can't
see what 0.17 writes, so on a shared prefix a retry on either side can append
a duplicate event, re-run work, or stall a lane. Switch to a fresh keyPrefix
when you upgrade, and don't roll back to an earlier release on a prefix 0.17
has written. Vercel Queues keeps running recovery and scheduled work on the
deployment that published it for up to seven days, so earlier deployments keep
touching their sessions after you upgrade.
Before you clear sessions
0.17 adds session.clear(). Upgrade
every instance before you clear any session: an earlier release ignores the
clear and can run cleared events in the new lifetime. Upgrade every scheduler
route before you schedule clears, and don't roll back while clear tasks are
pending.
Vercel Queues
vercelQueues({ scheduledAppends }) is replaced by
deploymentId?: string | null: leave it out to deliver to the current
deployment, pass a deployment ID to target one, or pass null for
deploymentless delivery. It applies to every task, recovery included, so
null makes recovery deploymentless too, unlike 'deploymentless' did.
Changing it doesn't move tasks already queued. A custom QueueTransport.send
no longer takes a fourth routing argument. See
Deployments.
Agents
| Before | 0.17 |
|---|---|
createAgentServer({ agent: definition, ... }) | agent({ name, ... }), or agent({ contract, ... }) with a shared contract |
agent() from experimental-a2/ai | agentContract() |
createReducer(), reducerName | agentContract({ reducer }) |
createHandlers(), authorizeAgentIngress | removed: pass handlers and events to agent() |
handlerContext(agent) | handlerContext(), or handlerContext(contract) |
request in generate and messageMetadata | event |
requestId | event.id |
responseMessageId | event.payload.responseMessageId |
agent({ contract })takes only anagentContract(). Any other contract throws. A fully custom contract is core A2, served bycreateServer().- Upgrade clients with the server. A client from before 0.17 ignores the new shape of streamed progress, so a response's output doesn't appear in it until it reloads.
- Custom telemetry recorders must accept the new span names: core claim
and commit spans, and
a2.ai.*.
0.21 later renames handlers to consumers and handlerContext() to
consumerContext(); see 0.21.