Actions
Most AI frameworks give you one way to communicate with the backend:sendMessage. Your client sends a message, the server responds, and that’s the extent of your API surface. This works for chatbots but constrains everything else.
Idyllic takes a different approach. When you decorate a method with @action(), that method becomes a typed RPC endpoint. Your React application calls it as if it were a regular async function. The framework routes the call over WebSocket to your server, executes the method, and returns the result. You define whatever operations your application needs—not just “send message.”
useSystem provides:
What @action() Does
The decorator transforms a method into an RPC endpoint through several coordinated steps:- Registers the method in a callable registry so the runtime knows which methods can receive external calls
- Generates a client stub with a TypeScript signature matching your server method
- Sets up RPC handling that routes WebSocket messages to the correct method
- Broadcasts state changes to all connected clients after execution completes
- Preserves
thiscontext so your method can access fields and call other methods
@action() remain internal, invisible to clients. This lets you organize code with public actions for external requests and private helpers for implementation:
Type Safety
Idyllic extracts types from your action methods and propagates them to client code. The CLI analyzes your system classes, extracts signatures, and writes TypeScript interfaces. Your editor provides autocomplete, and TypeScript catches errors before runtime:Error Handling
When an action throws, the client’s promise rejects with the error:ActionError with structured codes:
Actions and Streaming
Actions return a single value when complete. They don’t stream their return value incrementally. For content that arrives progressively, use astream<T> field instead.
The pattern: an action initiates work and returns metadata; a stream field delivers updates:
State Updates
When an action modifies fields, changes persist and sync to all connected clients automatically:Constraints
Actions use RPC over WebSocket, which imposes constraints:- Must be async or return a Promise (RPC is inherently asynchronous)
- Arguments and returns must be JSON-serializable (no functions, class instances, circular refs)
- No overloaded signatures (use optional parameters or union types)
- Only on methods, not getters/setters
- Only on classes extending AgenticSystem
Best Practices
Keep actions focused. Each action should do one coherent thing. Split compound actions into focused pieces clients can compose. Reset streams at the start. Clear previous content before producing new output:FAQ
Can actions call other actions?
Yes. When an action calls another action within the same system, it’s a direct method call—no RPC, no serialization, no network round-trip:How do I cancel a running action?
The framework doesn’t provide built-in cancellation. For long-running operations, implement cancellation yourself using a state flag:Do actions run concurrently?
No. Durable Objects process one request at a time. Simultaneous calls queue and execute sequentially. This prevents race conditions but means long-running actions block other calls.Next: React
The useSystem hook for typed state and actions