Skip to content

Commit 87bf1ee

Browse files
committed
[Agents] Add changelog for Agents SDK v0.7.0
1 parent 3ff29f0 commit 87bf1ee

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
title: "Agents SDK v0.7.0: Observability rewrite, keepAlive, and waitForMcpConnections"
3+
description: "Agents SDK v0.7.0 replaces the old console.log-based observability with diagnostics_channel events across 7 named channels, adds keepAlive() to prevent idle eviction during long-running work, and introduces waitForMcpConnections to guarantee MCP tools are ready before chat handlers run."
4+
products:
5+
- agents
6+
- workers
7+
date: 2026-03-02
8+
---
9+
10+
import { TypeScriptExample } from "~/components";
11+
12+
The latest release of the [Agents SDK](https://github.com/cloudflare/agents) rewrites observability from scratch with `diagnostics_channel`, adds `keepAlive()` to prevent Durable Object eviction during long-running work, and introduces `waitForMcpConnections` so MCP tools are always available when `onChatMessage` runs.
13+
14+
## Observability rewrite
15+
16+
The previous observability system used `console.log()` with a custom `Observability.emit()` interface. v0.7.0 replaces it with structured events published to [diagnostics channels](/workers/runtime-apis/nodejs/diagnostics-channel/) — silent by default, zero overhead when nobody is listening.
17+
18+
Every event has a `type`, `payload`, and `timestamp`. Events are routed to seven named channels:
19+
20+
| Channel | Event types |
21+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22+
| `agents:state` | `state:update` |
23+
| `agents:rpc` | `rpc`, `rpc:error` |
24+
| `agents:message` | `message:request`, `message:response`, `message:clear`, `message:cancel`, `message:error`, `tool:result`, `tool:approval` |
25+
| `agents:schedule` | `schedule:create`, `schedule:execute`, `schedule:cancel`, `schedule:retry`, `schedule:error`, `queue:retry`, `queue:error` |
26+
| `agents:lifecycle` | `connect`, `destroy` |
27+
| `agents:workflow` | `workflow:start`, `workflow:event`, `workflow:approved`, `workflow:rejected`, `workflow:terminated`, `workflow:paused`, `workflow:resumed`, `workflow:restarted` |
28+
| `agents:mcp` | `mcp:client:preconnect`, `mcp:client:connect`, `mcp:client:authorize`, `mcp:client:discover` |
29+
30+
Use the typed `subscribe()` helper from `agents/observability` for type-safe access:
31+
32+
<TypeScriptExample>
33+
34+
```ts
35+
import { subscribe } from "agents/observability";
36+
37+
const unsub = subscribe("rpc", (event) => {
38+
if (event.type === "rpc") {
39+
console.log(`RPC call: ${event.payload.method}`);
40+
}
41+
if (event.type === "rpc:error") {
42+
console.error(
43+
`RPC failed: ${event.payload.method} — ${event.payload.error}`,
44+
);
45+
}
46+
});
47+
48+
// Clean up when done
49+
unsub();
50+
```
51+
52+
</TypeScriptExample>
53+
54+
In production, all diagnostics channel messages are automatically forwarded to [Tail Workers](/workers/observability/tail-workers/) — no subscription code needed in the agent itself:
55+
56+
<TypeScriptExample>
57+
58+
```ts
59+
export default {
60+
async tail(events) {
61+
for (const event of events) {
62+
for (const msg of event.diagnosticsChannelEvents) {
63+
// msg.channel is "agents:rpc", "agents:workflow", etc.
64+
console.log(msg.timestamp, msg.channel, msg.message);
65+
}
66+
}
67+
},
68+
};
69+
```
70+
71+
</TypeScriptExample>
72+
73+
The custom `Observability` override interface is still supported for users who need to filter or forward events to external services.
74+
75+
For the full event reference, refer to the [Observability documentation](/agents/api-reference/observability/).
76+
77+
## `keepAlive()` and `keepAliveWhile()`
78+
79+
Durable Objects are evicted after a period of inactivity (typically 70-140 seconds with no incoming requests, WebSocket messages, or alarms). During long-running operations — streaming LLM responses, waiting on external APIs, running multi-step computations — the agent can be evicted mid-flight.
80+
81+
`keepAlive()` prevents this by creating a 30-second heartbeat schedule. The alarm firing resets the inactivity timer. Returns a disposer function that cancels the heartbeat when called.
82+
83+
<TypeScriptExample>
84+
85+
```ts
86+
const dispose = await this.keepAlive();
87+
try {
88+
const result = await longRunningComputation();
89+
await sendResults(result);
90+
} finally {
91+
dispose();
92+
}
93+
```
94+
95+
</TypeScriptExample>
96+
97+
`keepAliveWhile()` wraps an async function with automatic cleanup — the heartbeat starts before the function runs and stops when it completes:
98+
99+
<TypeScriptExample>
100+
101+
```ts
102+
const result = await this.keepAliveWhile(async () => {
103+
const data = await longRunningComputation();
104+
return data;
105+
});
106+
```
107+
108+
</TypeScriptExample>
109+
110+
Key details:
111+
112+
- **Multiple concurrent callers** — Each `keepAlive()` call returns an independent disposer. Disposing one does not affect others.
113+
- **AIChatAgent built-in**`AIChatAgent` automatically calls `keepAlive()` during streaming responses. You do not need to add it yourself.
114+
- **Uses the scheduling system** — The heartbeat does not conflict with your own schedules. It shows up in `getSchedules()` if you need to inspect it.
115+
116+
:::note
117+
`keepAlive()` is marked `@experimental` and may change between releases.
118+
:::
119+
120+
For the full API reference and when-to-use guidance, refer to [Schedule tasks — Keeping the agent alive](/agents/api-reference/schedule-tasks/#keeping-the-agent-alive).
121+
122+
## `waitForMcpConnections`
123+
124+
`AIChatAgent` now waits for MCP server connections to settle before calling `onChatMessage`. This ensures `this.mcp.getAITools()` returns the full set of tools, especially after Durable Object hibernation when connections are being restored in the background.
125+
126+
<TypeScriptExample>
127+
128+
```ts
129+
export class ChatAgent extends AIChatAgent {
130+
// Default — waits up to 10 seconds
131+
// waitForMcpConnections = { timeout: 10_000 };
132+
133+
// Wait forever
134+
waitForMcpConnections = true;
135+
136+
// Disable waiting
137+
waitForMcpConnections = false;
138+
}
139+
```
140+
141+
</TypeScriptExample>
142+
143+
| Value | Behavior |
144+
| --------------------- | --------------------------------------------- |
145+
| `{ timeout: 10_000 }` | Wait up to 10 seconds (default) |
146+
| `{ timeout: N }` | Wait up to `N` milliseconds |
147+
| `true` | Wait indefinitely until all connections ready |
148+
| `false` | Do not wait (old behavior before 0.2.0) |
149+
150+
For lower-level control, call `this.mcp.waitForConnections()` directly inside `onChatMessage` instead.
151+
152+
## Other improvements
153+
154+
- **MCP deduplication by name and URL**`addMcpServer` with HTTP transport now deduplicates on both server name and URL. Calling it with the same name but a different URL creates a new connection. URLs are normalized before comparison (trailing slashes, default ports, hostname case).
155+
- **`callbackHost` optional for non-OAuth servers**`addMcpServer` no longer requires `callbackHost` when connecting to MCP servers that do not use OAuth.
156+
- **MCP URL security** — Server URLs are validated before connection to prevent SSRF. Private IP ranges, loopback addresses, link-local addresses, and cloud metadata endpoints are blocked.
157+
- **Custom denial messages**`addToolOutput` now supports `state: "output-error"` with `errorText` for custom denial messages in human-in-the-loop tool approval flows.
158+
- **`requestId` in chat options**`onChatMessage` options now include a `requestId` for logging and correlating events.
159+
160+
### Upgrade
161+
162+
To update to the latest version:
163+
164+
```sh
165+
npm i agents@latest @cloudflare/ai-chat@latest
166+
```

0 commit comments

Comments
 (0)