docs: correct Agents SDK guidance - #32762
Conversation
Review
👉 Fix in your agent 👈Fix the following review findings in PR #32762 (https://github.com/cloudflare/cloudflare-docs/pull/32762).
Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g. the fix requires disproportionate effort for minimal benefit,
or the finding is factually incorrect), explain why
- If you need clarification before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order
After triaging, follow this order:
1. Post a comment on this PR for any findings you are skipping, with the finding ID and your reasoning.
2. Then commit the fixes for the legitimate findings.
The comment must come before the commit — the bot reads PR comments when a new
push triggers a review, so skip comments posted after the push will be missed.
---
## Code Review
### Warnings (1)
#### CR-6d2017216f6a · Unvalidated JSON.parse
- **File:** `src/content/docs/agents/communication-channels/webhooks/index.mdx` line 40
- **Issue:** All three changed payload-parsing sites (lines 40, 95, and 189) call JSON.parse on raw external body text without a try/catch. A malformed payload will throw an unhandled exception and surface as a 500 instead of a controlled 400.
- **Fix:** Wrap each JSON.parse in a try/catch block and return new Response('Invalid payload', { status: 400 }) when parsing fails.
Code ReviewThis code review is in beta and may not always be helpful — use your judgment. Warnings (1)
ConventionsNo convention issues found. Style Guide ReviewNo style-guide issues found. CommandsOnly codeowners can run commands. Post a comment with the command to trigger it.
|
| ```sh | ||
| npm install @cloudflare/ai-chat agents ai workers-ai-provider | ||
| ``` | ||
| <PackageManagers pkg="@cloudflare/ai-chat agents ai @ai-sdk/react workers-ai-provider" /> |
There was a problem hiding this comment.
The example imports React helpers, so the install command needs this package.
| import { Agent, callable, type StreamingResponse } from "agents"; | ||
|
|
||
| class MyAgent extends Agent { | ||
| @callable({ streaming: true }) |
There was a problem hiding this comment.
This now matches the streaming API the SDK actually exposes.
|
|
||
| if ( | ||
| !(await this.verifySignature(body, signature, this.env.WEBHOOK_SECRET)) | ||
| !(await verifyGitHubWebhook( |
There was a problem hiding this comment.
This file now shows a complete, working GitHub webhook flow instead of several disconnected examples:
- It accepts only
POSTrequests and checks GitHub'sX-Hub-Signature-256against the raw body before parsing any JSON. - It uses
crypto.subtle.verify()and rejects malformed signatures instead of comparing hand-built signature strings. - It chooses the Agent from the signed
repository.full_namevalue, rather than trusting an unsigned URL segment or header. - It uses GitHub's real event and signature headers and reuses the same verification helper throughout the page.
- It makes clear that Slack, Stripe, and other providers need their own checks, and that routing should only use data returned after those checks pass.
as a whole, these changes make the examples usable as they've been written (and prevent forged webhook data from selecting or reaching an Agent).
| }; | ||
|
|
||
| export class ProjectManager extends Agent<ProjectState> { | ||
| export class ProjectManager extends Agent<Env, ProjectState> { |
There was a problem hiding this comment.
The Agent type expects the environment first and state second.
| [vars] | ||
| EMAIL_SECRET = "change-me-in-production" | ||
| ``` | ||
| 1. Store the signing key as a Wrangler secret. Do not put it in `vars` or commit it to source control: |
There was a problem hiding this comment.
The signing key is a secret, so it should not live in committed configuration.
| ### RPC and Callable Methods | ||
|
|
||
| `agents` takes Durable Objects RPC one step further by implementing RPC through WebSockets, so clients can call methods on the Agent directly. To make a method callable through WebSocket, use the `@callable()` decorator. Methods can return a serializable value or a stream (when using `@callable({ stream: true })`). | ||
| `agents` takes Durable Objects RPC one step further by implementing RPC through WebSockets, so clients can call methods on the Agent directly. To make a method callable through WebSocket, use the `@callable()` decorator. Methods can return a serializable value or a stream (when using `@callable({ streaming: true })`). |
There was a problem hiding this comment.
The SDK calls this option streaming; using stream does not work.
| "staging": { | ||
| "name": "my-agent-staging", | ||
| "durable_objects": { | ||
| "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }], |
There was a problem hiding this comment.
Named Wrangler environments do not inherit Durable Object bindings, so each one needs its own copy.
| ### Cross origin | ||
|
|
||
| Cookies do not help across origins. Pass credentials in the URL query, then verify on the server. | ||
| Cross-origin cookie behavior depends on the cookie's domain and `SameSite` attributes, whether the two origins are same-site, and browser third-party cookie policy. If you cannot rely on a cookie, pass a short-lived credential in the URL query and verify it on the server. |
There was a problem hiding this comment.
Cookies are not always blocked across origins, so this explains when they work and when a short-lived token is needed.
|
This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:
|
Summary
Correct outdated Agents SDK examples and security guidance.
Documentation checklist