Observability Rewrite with Diagnostics Channels
The observability system has been completely reimplemented using Node.js diagnostics channels, replacing the previous console.log() and custom Observability.emit() interface. The new system is silent by default with zero overhead when no subscribers are listening.
Events are structured with type, payload, and timestamp and routed to seven named channels:
agents:state— state updatesagents:rpc— RPC calls and errorsagents:message— message lifecycle and tool interactionsagents:schedule— task scheduling and queue eventsagents:lifecycle— agent connection and teardownagents:workflow— workflow state transitionsagents:mcp— MCP client operations
Use the typed subscribe() helper for type-safe event access in development, or automatically forward all diagnostics channel messages to Tail Workers in production without subscription code needed in the agent itself.
keepAlive() Prevents Durable Object Eviction
Durable Objects are evicted after 70–140 seconds of inactivity, which can interrupt long-running operations like LLM streaming or external API calls. The new keepAlive() method creates a 30-second heartbeat schedule that resets the inactivity timer.
Two usage patterns are available:
- Manual control — Call
keepAlive()and invoke the returned disposer function when complete - Automatic cleanup — Use
keepAliveWhile(asyncFn)to wrap async operations with automatic heartbeat start/stop
Key details: Multiple concurrent keepAlive() calls operate independently, AIChatAgent calls it automatically during streaming responses, and the heartbeat integrates with the existing scheduling system.
waitForMcpConnections Ensures Tool Availability
AIChatAgent now waits for MCP server connections to settle before invoking onChatMessage, ensuring this.mcp.getAITools() returns the complete tool set. This is especially important after Durable Object hibernation when connections are being restored in the background.
Configure the wait behavior with the waitForMcpConnections property: use the default { timeout: 10_000 } to wait up to 10 seconds, set true to wait indefinitely, or set false to disable waiting entirely.