agents
Version:
A home for your AI agents
199 lines (197 loc) • 8.2 kB
TypeScript
import {
r as CapabilityWebSocketUpgradeContext,
s as LifecycleCapability,
x as Connection
} from "./capability-runner-BiVUtjqC.js";
import {
i as WebSocketsOptions,
n as WebSocketHandlers,
r as WebSocketMessage
} from "./options-CiIsJHXR.js";
//#region src/websockets/websockets.d.ts
/**
* Opt-in WebSocket support for Lifecycle Objects.
*
* Lifecycle itself does not model WebSockets — hosts that want them
* install this capability, which owns the connection subsystem end to
* end: it claims upgrades, dispatches `onConnect`/`onMessage`/`onClose`
* inside the host invocation boundary, reciprocates close handshakes,
* and answers `getConnections()`/`getConnection()`.
*
* ```ts
* class Room extends DurableObject<Env> {
* readonly webSockets = new WebSockets({
* handlers: {
* onConnect: (connection) => connection.send("welcome"),
* onMessage: (connection, message) => { ... }
* },
* callables: new RoomCallables()
* });
* readonly lifecycle = Lifecycle.install(this).use(this.webSockets);
* }
* ```
*
* Connections arrive on one of two wires, chosen by the client:
*
* - **cf-websocket** (default): accepted with the Hibernation API. Idle
* clients stay connected while the Durable Object leaves memory.
* - **capnweb** (`?__agents_transport=capnweb`): protocol frames through
* one pipe method on a Cap'n Web session whose root also carries the
* host's callables natively. Non-hibernating — the object stays pinned
* while the connection is open.
*
* Both wires dispatch the same handlers and appear in `getConnections()`.
* On both, the capability speaks the Agent protocol a plain host needs
* for `useAgent` and `AgentClient`: it sends the identity frame on
* connect, and it serves `callables` — as `rpc` JSON frames on the
* WebSocket wire, and natively on the Cap'n Web session root, where an
* `RpcTarget` result becomes a live stub and calls pipeline. `call()`
* and `stub` work against a plain Durable Object exactly as against an
* `Agent`. Pass a `State` capability as `state` and the hook's
* `state`/`setState` work too: the current value is pushed on connect
* 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.
*/
declare class WebSockets extends LifecycleCapability {
#private;
/** Claims every upgrade, so Lifecycle dispatches it after all others. */
readonly claims = "catch-all";
constructor(options?: WebSocketsOptions);
/**
* Claim every upgrade, never declining: a Cap'n Web transport upgrade
* becomes a session, everything else a tracked hibernating connection,
* whether or not handlers or callables are configured. Handlers only add
* behavior on connect, message, close, and error.
*/
onWebSocketUpgrade({
request
}: CapabilityWebSocketUpgradeContext): Promise<Response>;
/** Dispatch a platform message wake for a capability-owned socket. */
onWebSocketMessage(
ws: WebSocket,
message: WebSocketMessage
): Promise<boolean>;
/** Dispatch and reciprocate a close wake for an owned socket. */
onWebSocketClose(
ws: WebSocket,
code: number,
reason: string,
wasClean: boolean
): Promise<boolean>;
/** Dispatch an error wake for an owned socket. */
onWebSocketError(ws: WebSocket, error: unknown): Promise<boolean>;
/**
* Close every owned connection during explicit host destruction. The
* capability owns its sockets' lifetimes, so it also owns tearing
* them down.
*/
dispose(): void;
/**
* Add handlers for another component sharing these connections, such as
* a protocol of its own. They run before the configured handlers, and
* their `onMessage` can claim a message by returning true.
*/
use(handlers: WebSocketHandlers): void;
/** Open connections on either wire, optionally by tag. */
getConnections<TState = unknown>(
tag?: string
): IterableIterator<Connection<TState>>;
/** One connection on either wire, by id. */
getConnection<TState = unknown>(id: string): Connection<TState> | undefined;
/**
* Send the connect sequence: the identity frame, then the current state
* when one is stored. The identity carries `stateFollows` in that case,
* so clients resolve `ready` only once the state has landed. Nothing is
* sent to a no-protocol connection. Identity defaults as for
* `sendIdentity()`.
*/
sendConnectFrames(
connection: Connection,
identity?: {
name: string;
agent: string;
}
): void;
/**
* Send the identity frame alone, unless the connection is no-protocol.
* Clients resolve `ready` on it, so a host that also pushes state on
* connect should use `sendConnectFrames()`. The defaults are the Durable
* Object's routed name and host class; a host whose public identity
* differs — an `Agent` facet, whose routed name is an internal encoding
* of its logical name — passes its own.
*/
sendIdentity(
connection: Connection,
identity?: {
name: string;
agent: string;
}
): void;
/**
* Send the current state to one connection, unless nothing is stored
* or the connection is no-protocol. Reading the state may seed the
* initial value; see `#connecting`.
*/
sendState(connection: Connection): void;
/**
* Apply a parsed `cf_agent_state` frame from a client. A readonly
* connection is refused; a change the host's validator rejects is
* logged in full server-side and answered with a generic
* `cf_agent_state_error`. Broadcasting the accepted change is the state
* owner's call, through its `onChanged` hook. Callers that drive the
* protocol themselves call this inside their own invocation context;
* the capability's automatic path does so via `runInHostContext`.
*
* @returns Whether the frame was a state frame (handled either way).
*/
applyStateFrame(connection: Connection, frame: unknown): boolean;
/**
* Push the current state to every protocol-enabled connection except
* the one a change came from, which already has the value it sent.
* Wire a `State`'s `onChanged` to this.
*/
broadcastState(except?: Connection | "server"): void;
/** Whether the connection may update host state over the wire. */
isReadonly(connection: Connection): boolean;
/** Mark a connection readonly, or writable again. */
setReadonly(connection: Connection, readonly?: boolean): void;
/** Whether protocol text frames reach the connection. */
isProtocolEnabled(connection: Connection): boolean;
/** Enable or suppress protocol text frames for a connection. */
setProtocolEnabled(connection: Connection, enabled: boolean): void;
}
//#endregion
//#region src/websockets/connection-flags.d.ts
/**
* Internal per-connection flags, stored inside the connection's own state
* under `_cf_`-prefixed keys so they ride the hibernation attachment (or a
* bridged connection's synced state) and survive a wake. The state wrapper
* installed by {@link ensureConnectionWrapped} hides them from
* `connection.state` and preserves them across user `setState` calls.
*
* Owned by the WebSockets capability; `Agent` and framework mixins reach it
* through the capability or, for their own keys, through
* {@link registerInternalConnectionKeys}.
*/
/** A readonly connection may not update host state. */
declare const CF_READONLY_KEY = "_cf_readonly";
/**
* A no-protocol connection receives no protocol text frames (identity,
* state sync, MCP servers) — neither on connect nor via broadcasts.
*/
declare const CF_NO_PROTOCOL_KEY = "_cf_no_protocol";
/**
* Register additional `_cf_`-prefixed keys a host or mixin stores in
* connection state, so they are hidden from `connection.state` and kept
* across user `setState` calls like the capability's own flags.
*/
declare function registerInternalConnectionKeys(...keys: string[]): void;
//#endregion
export {
WebSockets as i,
CF_READONLY_KEY as n,
registerInternalConnectionKeys as r,
CF_NO_PROTOCOL_KEY as t
};
//# sourceMappingURL=index-CBt8oRJt.d.ts.map