@callable() to expose them to external clients like browsers, mobile apps, or other services.
Overview
When to Use @callable
The
@callable() decorator is specifically for WebSocket-based RPC from external clients. When calling from within the same Worker or another agent, use standard Durable Object RPC directly.
TypeScript Configuration
The@callable() decorator requires TypeScript’s decorator support. Set "target" to "ES2021" or later in your tsconfig.json:
tsconfig.json
Basic Usage
Defining Callable Methods
Add the@callable() decorator to any method you want to expose:
Calling from the Client
There are two ways to call methods from the client:stub proxy provides better ergonomics and TypeScript support.
Method Signatures
Serializable Types
Arguments and return values must be JSON-serializable:Async Methods
Both sync and async methods work:Void Methods
Methods that don’t return a value:Streaming Responses
For methods that produce data over time (like AI text generation), use streaming:Defining a Streaming Method
Consuming Streams on the Client
StreamingResponse API
(chunk: unknown) => void
Send a chunk to the client
(finalChunk?: unknown) => void
End the stream, optionally with a final value
(message: string) => void
Send an error to the client and close the stream
TypeScript Integration
Typed Client Calls
Pass your agent class as a type parameter for full type safety:Excluding Non-Callable Methods
If you have methods that aren’t decorated with@callable(), you can exclude them from the type:
Error Handling
Throwing Errors in Callable Methods
Errors thrown in callable methods are propagated to the client:Client-Side Error Handling
Streaming Error Handling
For streaming methods, use theonError callback:
stream.error() to gracefully send an error mid-stream:
Connection Errors
If the WebSocket connection closes while RPC calls are pending, they automatically reject with a “Connection closed” error:Retrying After Reconnection
PartySocket automatically reconnects after disconnection. To retry a failed call after reconnection, awaitagent.ready before retrying:
Only retry idempotent operations. If the server received the request but the connection dropped before the response arrived, retrying could cause duplicate execution.
When NOT to Use @callable
Worker-to-Agent Calls
When calling an agent from the same Worker (e.g., in yourfetch handler), use Durable Object RPC directly:
Agent-to-Agent Calls
When one agent needs to call another:Why the Distinction?
DO RPC is more efficient for internal calls since it doesn’t go through WebSocket serialization. The
@callable decorator adds the necessary WebSocket RPC handling for external clients.
API Reference
@callable(metadata?) Decorator
Marks a method as callable from external clients.CallableMetadata Type
string
Optional description of what the method does
boolean
Whether the method supports streaming responses
Client Methods
(method, args?, options?) => Promise
Call a method by name
Proxy
Typed method calls
CallOptions Type
number
Timeout in milliseconds. Rejects if call doesn’t complete in time.
object
Streaming options
onChunk?: (chunk: unknown) => voidonDone?: (finalChunk: unknown) => voidonError?: (error: string) => void