Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/stable-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"agents": patch
---

`agents/lifecycle` is no longer experimental, and neither are the `Scheduler` (`agents/schedules`), `State` (`agents/state`), `WebSockets` (`agents/websockets`) and `MCPClientManager` (`agents/mcp/client`) capabilities. Their `@experimental` tags are removed. The Cap'n Web WebSocket transport, `Queue`, `Tasks`, `Streams`, `Sessions`, `RoutedAgents` and `Browser` stay experimental. See [Lifecycle](https://github.com/cloudflare/agents/blob/main/docs/agents/lifecycle.md).
176 changes: 99 additions & 77 deletions docs/agents/index.md

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions docs/agents/lifecycle.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Durable Object lifecycle

> **Experimental.** Everything exported from `agents/lifecycle` — and the
> capabilities built on it, including `Scheduler` — may change between
> releases while the composition surface stabilizes.
`agents/lifecycle` is stable. Most capabilities built on it are still
experimental; each capability's page says which.

`agents/lifecycle` lets reusable durable capabilities work in both `Agent` and a
plain Cloudflare Durable Object. It uses composition: your class extends the
Expand Down
5 changes: 2 additions & 3 deletions docs/agents/queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ survives the object leaving memory.

## Queue Lifecycle capability

> **Experimental.** The `Queue` capability and the `agents/lifecycle` surface
> it builds on may change between releases. Agent's established queue methods
> (`this.queue()` and friends) are stable.
> **Experimental.** The `Queue` capability may change between releases.
> Agent's queue methods (`this.queue()` and friends) are stable.

`Queue` is a reusable Lifecycle capability. A plain Lifecycle Object can
install it without extending `Agent`:
Expand Down
8 changes: 2 additions & 6 deletions docs/agents/scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ Under the hood, scheduling uses [Durable Object alarms](https://developers.cloud

## Scheduler Lifecycle primitive

> **Experimental.** The `Scheduler` primitive and the `agents/lifecycle`
> surface it builds on may change between releases. Agent's established
> scheduling methods (`this.schedule()` and friends) are stable.

`Scheduler` is a reusable Lifecycle capability. A plain Lifecycle Object can
install it without extending `Agent`:

Expand Down Expand Up @@ -836,8 +832,8 @@ When using this schema with OpenAI models via the AI SDK, you must pass `provide

## API Reference

Two surfaces share these semantics: the experimental `Scheduler` primitive
(`agents/schedules`, methods on the scheduler instance) and the stable `Agent`
Two surfaces share these semantics: the `Scheduler` capability
(`agents/schedules`, methods on the scheduler instance) and the `Agent`
methods (on the Agent class, delegating to `this.scheduler`).

### Scheduler primitive
Expand Down
8 changes: 2 additions & 6 deletions packages/agents/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,6 @@ export class Agent<
> extends DurableObject<Env> {
/**
* Runtime lifecycle and reusable durable capabilities for this Agent.
*
* @experimental The API surface may change before stabilizing.
*/
readonly lifecycle = Lifecycle.install<Env, Props>(this, {
maxAlarmMemoryLimitStrikes: this._resolvedOptions.maxAlarmMemoryLimitStrikes
Expand Down Expand Up @@ -1321,10 +1319,8 @@ export class Agent<

/**
* Durable scheduling capability installed into this Agent's Lifecycle.
*
* @experimental The API surface may change before stabilizing. Agent's
* schedule()/scheduleEvery()/getScheduleById()/listSchedules()/
* cancelSchedule() methods are the stable surface.
* Agent's schedule()/scheduleEvery()/getScheduleById()/listSchedules()/
* cancelSchedule() methods delegate to it.
*/
readonly scheduler: Scheduler;

Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/lifecycle/capability-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ export type MemoryLimitContext = {
* - `onRoute` is addressed to one capability by its id; `onJob` is
* addressed by the due job's owning capability, with Lifecycle owning
* the queue and the one physical alarm.
*
* @experimental The API surface may change before stabilizing.
*/
export interface DurableObjectCapability<Props extends object = object> {
/**
Expand Down
4 changes: 0 additions & 4 deletions packages/agents/src/lifecycle/capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ export type LifecycleSockets = {

/**
* Standard services granted to every installed Lifecycle capability.
*
* @experimental The API surface may change before stabilizing.
*/
export type LifecycleServices = {
/** The host's Durable Object name; see `Lifecycle.name`. */
Expand Down Expand Up @@ -130,8 +128,6 @@ const installedServices = new WeakMap<object, LifecycleServices>();

/**
* Base class for capabilities that consume standard Lifecycle services.
*
* @experimental The API surface may change before stabilizing.
*/
export abstract class LifecycleCapability<Props extends object = object> {
readonly capabilityId: string;
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/lifecycle/current-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import type { LifecycleJobContext, LifecycleJobOutcome } from "./job-queue";
*
* Pass a more specific Lifecycle Object type to {@link getCurrentAgent} when
* shared host code needs APIs implemented by a particular object.
*
* @experimental The API surface may change before stabilizing.
*/
export interface LifecycleObject<
Env extends object = Cloudflare.Env,
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/lifecycle/durable-object-lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ export type LifecycleOptions = {
* Construct this as an instance field on a class that directly extends
* `DurableObject`, then call {@link Lifecycle.installHandlers}
* from that class's constructor.
*
* @experimental The API surface may change before stabilizing.
*/
/** The dispatch hooks a catch-all can monopolize; uniqueness is per hook. */
const CATCH_ALL_HOOKS = ["onRequest", "onWebSocketUpgrade"] as const;
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/lifecycle/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/**
* Durable Object lifecycle composition.
*
* @experimental Every export here may change before stabilizing.
*/
export {
LifecycleCapability,
Expand Down
3 changes: 1 addition & 2 deletions packages/agents/src/mcp/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,7 @@ export type MCPServerFilter = {

/**
* A Durable Object capability that persists and aggregates MCP client
* connections. Installing it directly on a Lifecycle (outside `agent.mcp`)
* is experimental: that capability surface may change before stabilizing.
* connections. Install it on any Lifecycle, or use `agent.mcp` on an Agent.
*/
export class MCPClientManager extends LifecycleCapability {
public mcpConnections: Record<string, MCPClientConnection> = {};
Expand Down
6 changes: 2 additions & 4 deletions packages/agents/src/schedules/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/**
* Persistent scheduling for Lifecycle Objects.
*
* @experimental The Scheduler surface (`Scheduler`, `SchedulerOptions`, and
* the callback-map types) may change before stabilizing. `Schedule`,
* `ScheduleCriteria`, and `ScheduleOptions` are shared with Agent's stable
* scheduling methods.
* `Schedule`, `ScheduleCriteria`, and `ScheduleOptions` are shared with
* Agent's scheduling methods.
*/
export { Scheduler } from "./scheduler";
export type { SchedulerEventType, SchedulerOptions } from "./options";
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/schedules/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export type SchedulerEventType =

/**
* Optional callbacks and policy for a Scheduler capability.
*
* @experimental The API surface may change before stabilizing.
*/
export interface SchedulerOptions<
Handlers extends SchedulerHandlers = SchedulerCallbacks
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/schedules/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ function isSchedulerJobPayload(value: unknown): value is SchedulerJobPayload {
* Lifecycle job queue; Lifecycle owns the physical alarm and the alarm
* event loop, and Scheduler runs registered callbacks through Lifecycle's
* host invocation boundary when its jobs come due.
*
* @experimental The API surface may change before stabilizing.
*/
export class Scheduler<
Handlers extends SchedulerHandlers = SchedulerCallbacks
Expand Down
6 changes: 0 additions & 6 deletions packages/agents/src/schedules/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ export type Schedule<T = string> = {
/**
* Constraint for a Scheduler's registered callback map: named handlers
* receiving the parsed payload and the schedule that fired.
*
* @experimental The API surface may change before stabilizing.
*/
export type SchedulerHandlers = Record<
string,
Expand All @@ -67,8 +65,6 @@ export type SchedulerHandlers = Record<
* must be registered or supplied by a composition-root resolver (the
* aperture behind Agent's name-based scheduling API); a bare Scheduler
* rejects it otherwise.
*
* @experimental The API surface may change before stabilizing.
*/
export type SchedulerCallbacks = Record<
string,
Expand All @@ -77,8 +73,6 @@ export type SchedulerCallbacks = Record<

/**
* The payload type a registered scheduler callback accepts.
*
* @experimental The API surface may change before stabilizing.
*/
export type SchedulerPayload<Handler> = Handler extends (
payload: infer Payload,
Expand Down
4 changes: 0 additions & 4 deletions packages/agents/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export type StateChangeSource = Connection | "server";
* Options for a {@link State} capability. Validation and the post-change hook
* stay on the host, which passes them in; the capability owns storage and
* change ordering.
*
* @experimental The API surface may change before stabilizing.
*/
export interface StateOptions<T = unknown> {
/** Seeded on first access when nothing is stored. `undefined` seeds nothing. */
Expand Down Expand Up @@ -66,8 +64,6 @@ const DEFAULT_STATE = {} as unknown;
* validated persistence. Install the instance with `Lifecycle.use()`. State
* validation and the post-change notification hook stay on the host, which
* injects both callbacks. This capability never touches connections.
*
* @experimental The API surface may change before stabilizing.
*/
export class State<T = unknown> extends LifecycleCapability {
#state = DEFAULT_STATE as T;
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/websockets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
* Opt-in WebSocket support for Lifecycle Objects: hibernating and Cap'n
* Web connections plus the Agent identity and `rpc` frame protocol,
* owned entirely by the capability.
*
* @experimental The WebSockets surface may change before stabilizing.
Comment on lines -5 to -6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Cap'n Web stability boundary is unclear

Cap'n Web remains experimental, but the stable WebSockets documentation presents both transports together without marking the exception. Its exported transport helpers also lack an experimental annotation. Mark the exception where users encounter the transport.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

*/
export { WebSockets } from "./websockets";
export {
Expand Down
4 changes: 0 additions & 4 deletions packages/agents/src/websockets/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export type WebSocketMessage = WSMessage;
* Connection handlers for the WebSockets capability. Handlers run inside
* the host invocation boundary with the live connection in ambient
* context (`getCurrentAgent().connection`).
*
* @experimental The API surface may change before stabilizing.
*/
export type WebSocketHandlers = {
/** Handle a newly accepted hibernating WebSocket connection. */
Expand Down Expand Up @@ -51,8 +49,6 @@ export type WebSocketHandlers = {

/**
* Configuration for the WebSockets capability.
*
* @experimental The API surface may change before stabilizing.
*/
export interface WebSocketsOptions {
/**
Expand Down
2 changes: 0 additions & 2 deletions packages/agents/src/websockets/websockets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ function isRpcRequest(value: unknown): value is RpcRequest {
* and client updates are validated and applied; the state owner
* broadcasts changes with `broadcastState()`. Per-connection readonly
* and no-protocol flags live here as well, for every host.
*
* @experimental The API surface may change before stabilizing.
*/
export class WebSockets extends LifecycleCapability {
/** Claims every upgrade, so Lifecycle dispatches it after all others. */
Expand Down
Loading