From f876f65d665c5fcae1e076dfe1df3158510ce90b Mon Sep 17 00:00:00 2001 From: katereznykova Date: Mon, 21 Jul 2025 12:21:09 +0100 Subject: [PATCH 01/11] agents sdk changelog --- ...7-21-agents-queue-email-context-update.mdx | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx new file mode 100644 index 000000000000000..52632e749065b0f --- /dev/null +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -0,0 +1,142 @@ +--- +title: Agents SDK now supports task queues, email handling, and context-wrapped methods +description: The latest release adds .queue(), email support, and automatic context for custom methods +products: + - agents + - workers + - workflows +date: 2025-07-21 +--- + +The latest releases of [@cloudflare/agents] (https://github.com/cloudflare/agents) brings three powerful improvements that make building and scaling agents even easier. You now get: + +### Lightweight .queue for fast task deferral + +You can use .queue() to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. +Here's a full example using .queue() inside a tool, with batching and concurrency control: + +```ts +const queueMessage = tool({ + description: "Queue a message to be processed by the agent", + parameters: z.object({ + message: z.string().describe("The message to process"), + priority: z + .enum(["low", "normal", "high"]) + .default("normal") + .describe("Priority level for the message"), + }), + execute: async ({ message, priority = "normal" }) => { + const { agent } = getCurrentAgent(); + + if (!agent) { + return "Error: Agent not available"; + } + + try { + // Create a batch of 100 messages + const batchNumbers = Array.from({ length: 100 }, (_, i) => i + 1); + + const taskIds = await pMap( + batchNumbers, + async (i) => { + return agent.queue("processMessage", { + message: `${message} (batch ${i}/100)`, + priority, + }); + }, + { concurrency: 6 }, // Run up to 6 queues in parallel + ); + + return `Queued 100 messages. Example Task IDs: ${taskIds.slice(0, 5).join(", ")}...`; + } catch (error) { + console.error("Error queueing message", error); + return `Error queueing message: ${error}`; + } + }, +}); +``` + +Notes: + +- this uses pMap to handle concurrent queuing with a limit (concurrency: 6). +- each .queue() call returns a task ID you can track. +- works seamlessly thanks to automatic context wrapping + +Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale. + +### New email adaptor + +Want to build an AI agent that can receive and respond to emails automatically? With the new email adaptor and onEmail lifecycle method, now you can. + +```ts +export class EmailAgent extends Agent { + initialState = { + emailCount: 0, + emails: [], + autoReplyEnabled: true, + lastUpdated: new Date(), + }; + + async onEmail(email: AgentEmail) { + const raw = await email.getRaw(); + const parsed = await PostalMime.parse(raw); + + this.setState({ + ...this.state, + emailCount: this.state.emailCount + 1, + emails: [ + ...this.state.emails.slice(-9), + { + from: parsed.from?.address ?? email.from, + subject: parsed.subject ?? "No Subject", + text: parsed.text, + html: parsed.html, + to: email.to, + timestamp: new Date(), + messageId: parsed.messageId, + }, + ], + lastUpdated: new Date(), + }); + + if (this.state.autoReplyEnabled && !this.isAutoReply(parsed)) { + await this.replyToEmail(email, { + fromName: "Email Agent", + body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, + }); + } + } +} +``` + +You route incoming mail like this: + +```ts +export default { + async email(email, env) { + await routeAgentEmail(email, env, { + resolver: createAddressBasedEmailResolver("EmailAgent"), + }); + }, +}; +``` + +You can find a full example [here] (cloudflare/agents/examples/email-agent) + +### Automatic context wrapping for custom methods + +Defining custom methods on your agent is now even safer and cleaner. This means getCurrentAgent(), getCurrentRequest(), and getCurrentConnection() are now reliably accessible from anywhere in your agent — not just inside onRequest. + +```ts +export class MyAgent extends Agent { + async suggestReply(ctx, { message }) { + // getCurrentAgent() now works! + return generateText({ + prompt: `Suggest a reply to: "${message}"`, + tools: [replyWithEmoji], + }); + } +} +``` + +Try it out and tell us what you build! From 7d108176daf6c5fafb000b041ebe7a9eb730248b Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 13:27:00 +0100 Subject: [PATCH 02/11] simplify examples Co-authored-by: Sunil Pai --- ...7-21-agents-queue-email-context-update.mdx | 51 ++++--------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index 52632e749065b0f..f7d9e337096caa1 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -13,48 +13,19 @@ The latest releases of [@cloudflare/agents] (https://github.com/cloudflare/agent ### Lightweight .queue for fast task deferral You can use .queue() to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. -Here's a full example using .queue() inside a tool, with batching and concurrency control: ```ts -const queueMessage = tool({ - description: "Queue a message to be processed by the agent", - parameters: z.object({ - message: z.string().describe("The message to process"), - priority: z - .enum(["low", "normal", "high"]) - .default("normal") - .describe("Priority level for the message"), - }), - execute: async ({ message, priority = "normal" }) => { - const { agent } = getCurrentAgent(); - - if (!agent) { - return "Error: Agent not available"; - } - - try { - // Create a batch of 100 messages - const batchNumbers = Array.from({ length: 100 }, (_, i) => i + 1); - - const taskIds = await pMap( - batchNumbers, - async (i) => { - return agent.queue("processMessage", { - message: `${message} (batch ${i}/100)`, - priority, - }); - }, - { concurrency: 6 }, // Run up to 6 queues in parallel - ); - - return `Queued 100 messages. Example Task IDs: ${taskIds.slice(0, 5).join(", ")}...`; - } catch (error) { - console.error("Error queueing message", error); - return `Error queueing message: ${error}`; - } - }, -}); -``` +class MyAgent extends Agent{ + doSomethingExpensive(payload){ + // a long running process that you want to run in the background + } + + queueSomething(){ + await this.queue('doSomethingExpensive', somePayload); // this will NOT block further execution, and runs in the background + await this.queue('doSomethingExpensive', someOtherPayload); // the callback will NOT run until the previous callback is complete + // ... call as many times as you want + } +} Notes: From ca349c20b005e36a5dbe37d2cbf01d3f6426fe28 Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 13:27:10 +0100 Subject: [PATCH 03/11] simplify examples Co-authored-by: Sunil Pai --- .../2025-07-21-agents-queue-email-context-update.mdx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index f7d9e337096caa1..f66bc8bdf0917f6 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -96,18 +96,20 @@ You can find a full example [here] (cloudflare/agents/examples/email-agent) ### Automatic context wrapping for custom methods -Defining custom methods on your agent is now even safer and cleaner. This means getCurrentAgent(), getCurrentRequest(), and getCurrentConnection() are now reliably accessible from anywhere in your agent — not just inside onRequest. +Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but not just works out of the box. + + ```ts -export class MyAgent extends Agent { +export class MyAgent extends Agent { async suggestReply(ctx, { message }) { - // getCurrentAgent() now works! + // getCurrentAgent() now correctly works, even when called inside an RPC method + const { agent } = getCurrentAgent()!; return generateText({ - prompt: `Suggest a reply to: "${message}"`, + prompt: `Suggest a reply to: "${message}" from "${agent.name}"`, tools: [replyWithEmoji], }); } } -``` Try it out and tell us what you build! From 68fc25f382c877965d7bbeb8340dcd1d2ee714f2 Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 13:27:19 +0100 Subject: [PATCH 04/11] simplify examples Co-authored-by: Sunil Pai --- .../agents/2025-07-21-agents-queue-email-context-update.mdx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index f66bc8bdf0917f6..2097944a30eb3f5 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -27,11 +27,6 @@ class MyAgent extends Agent{ } } -Notes: - -- this uses pMap to handle concurrent queuing with a limit (concurrency: 6). -- each .queue() call returns a task ID you can track. -- works seamlessly thanks to automatic context wrapping Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale. From 22c6436bf0b3307ff29bc95bbec5184ca31138af Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 13:28:23 +0100 Subject: [PATCH 05/11] simplify examples Co-authored-by: Sunil Pai --- ...7-21-agents-queue-email-context-update.mdx | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index 2097944a30eb3f5..d2b2b036be99b4b 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -35,42 +35,19 @@ Want to try it yourself? Just define a method like processMessage in your agent, Want to build an AI agent that can receive and respond to emails automatically? With the new email adaptor and onEmail lifecycle method, now you can. ```ts -export class EmailAgent extends Agent { - initialState = { - emailCount: 0, - emails: [], - autoReplyEnabled: true, - lastUpdated: new Date(), - }; - +export class EmailAgent extends Agent { async onEmail(email: AgentEmail) { const raw = await email.getRaw(); const parsed = await PostalMime.parse(raw); - this.setState({ - ...this.state, - emailCount: this.state.emailCount + 1, - emails: [ - ...this.state.emails.slice(-9), - { - from: parsed.from?.address ?? email.from, - subject: parsed.subject ?? "No Subject", - text: parsed.text, - html: parsed.html, - to: email.to, - timestamp: new Date(), - messageId: parsed.messageId, - }, - ], - lastUpdated: new Date(), + // create a response based on the email contents + // and then send a reply + + await this.replyToEmail(email, { + fromName: "Email Agent", + body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, }); - if (this.state.autoReplyEnabled && !this.isAutoReply(parsed)) { - await this.replyToEmail(email, { - fromName: "Email Agent", - body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, - }); - } } } ``` From a6563a09ebb578d9b907c2c7ed3d2a1cd7805f09 Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 13:28:31 +0100 Subject: [PATCH 06/11] Update src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx Co-authored-by: Sunil Pai --- .../agents/2025-07-21-agents-queue-email-context-update.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index d2b2b036be99b4b..673e056d13df09e 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -64,7 +64,7 @@ export default { }; ``` -You can find a full example [here] (cloudflare/agents/examples/email-agent) +You can find a full example [here](https://github.com/cloudflare/agents/tree/main/examples/email-agent). ### Automatic context wrapping for custom methods From 8f805faea71c96127388b035fe9c58184f27c010 Mon Sep 17 00:00:00 2001 From: katereznykova Date: Mon, 21 Jul 2025 13:40:01 +0100 Subject: [PATCH 07/11] fixed trailing --- ...7-21-agents-queue-email-context-update.mdx | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index 673e056d13df09e..eb9b3053cdc4a12 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -15,18 +15,18 @@ The latest releases of [@cloudflare/agents] (https://github.com/cloudflare/agent You can use .queue() to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. ```ts -class MyAgent extends Agent{ - doSomethingExpensive(payload){ - // a long running process that you want to run in the background - } - - queueSomething(){ - await this.queue('doSomethingExpensive', somePayload); // this will NOT block further execution, and runs in the background - await this.queue('doSomethingExpensive', someOtherPayload); // the callback will NOT run until the previous callback is complete - // ... call as many times as you want - } -} +class MyAgent extends Agent { + doSomethingExpensive(payload) { + // a long running process that you want to run in the background + } + queueSomething() { + await this.queue("doSomethingExpensive", somePayload); // this will NOT block further execution, and runs in the background + await this.queue("doSomethingExpensive", someOtherPayload); // the callback will NOT run until the previous callback is complete + // ... call as many times as you want + } +} +``` Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale. @@ -41,13 +41,12 @@ export class EmailAgent extends Agent { const parsed = await PostalMime.parse(raw); // create a response based on the email contents - // and then send a reply - - await this.replyToEmail(email, { + // and then send a reply + + await this.replyToEmail(email, { fromName: "Email Agent", body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, }); - } } ``` @@ -68,20 +67,19 @@ You can find a full example [here](https://github.com/cloudflare/agents/tree/mai ### Automatic context wrapping for custom methods -Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but not just works out of the box. - - +Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but not just works out of the box. ```ts export class MyAgent extends Agent { async suggestReply(ctx, { message }) { - // getCurrentAgent() now correctly works, even when called inside an RPC method - const { agent } = getCurrentAgent()!; + // getCurrentAgent() now correctly works, even when called inside an RPC method + const { agent } = getCurrentAgent()!; return generateText({ prompt: `Suggest a reply to: "${message}" from "${agent.name}"`, tools: [replyWithEmoji], }); } } +``` Try it out and tell us what you build! From 179ecd590c0e2a129bb761ecded11b9f472c676c Mon Sep 17 00:00:00 2001 From: katereznykova Date: Mon, 21 Jul 2025 13:52:51 +0100 Subject: [PATCH 08/11] small fixes and typos --- .../2025-07-21-agents-queue-email-context-update.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index eb9b3053cdc4a12..196f82c050b208a 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -12,7 +12,7 @@ The latest releases of [@cloudflare/agents] (https://github.com/cloudflare/agent ### Lightweight .queue for fast task deferral -You can use .queue() to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. +You can use `.queue()` to enqueue background work — ideal for tasks like processing user messages, sending notifications etc. ```ts class MyAgent extends Agent { @@ -30,9 +30,9 @@ class MyAgent extends Agent { Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale. -### New email adaptor +### New email adapter -Want to build an AI agent that can receive and respond to emails automatically? With the new email adaptor and onEmail lifecycle method, now you can. +Want to build an AI agent that can receive and respond to emails automatically? With the new email adapter and onEmail lifecycle method, now you can. ```ts export class EmailAgent extends Agent { @@ -67,11 +67,11 @@ You can find a full example [here](https://github.com/cloudflare/agents/tree/mai ### Automatic context wrapping for custom methods -Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but not just works out of the box. +Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but now just works out of the box. ```ts export class MyAgent extends Agent { - async suggestReply(ctx, { message }) { + async suggestReply(message) { // getCurrentAgent() now correctly works, even when called inside an RPC method const { agent } = getCurrentAgent()!; return generateText({ From daf9d82c36296670ea388cac271c81b7ad37b467 Mon Sep 17 00:00:00 2001 From: whoiskatrin Date: Mon, 21 Jul 2025 14:47:18 +0100 Subject: [PATCH 09/11] fix hyperlink Co-authored-by: Sunil Pai --- .../agents/2025-07-21-agents-queue-email-context-update.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index 196f82c050b208a..a969c2adacc2628 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -8,7 +8,7 @@ products: date: 2025-07-21 --- -The latest releases of [@cloudflare/agents] (https://github.com/cloudflare/agents) brings three powerful improvements that make building and scaling agents even easier. You now get: +The latest releases of [@cloudflare/agents](https://github.com/cloudflare/agents) brings three powerful improvements that make building and scaling agents even easier. You now get: ### Lightweight .queue for fast task deferral From c6a6781d812b6b222979f10fbf1c3f0719a1ef58 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Mon, 21 Jul 2025 16:46:00 +0100 Subject: [PATCH 10/11] Update 2025-07-21-agents-queue-email-context-update.mdx --- ...7-21-agents-queue-email-context-update.mdx | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index a969c2adacc2628..da84a8154258aad 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -16,15 +16,15 @@ You can use `.queue()` to enqueue background work — ideal for tasks like proce ```ts class MyAgent extends Agent { - doSomethingExpensive(payload) { - // a long running process that you want to run in the background - } - - queueSomething() { - await this.queue("doSomethingExpensive", somePayload); // this will NOT block further execution, and runs in the background - await this.queue("doSomethingExpensive", someOtherPayload); // the callback will NOT run until the previous callback is complete - // ... call as many times as you want - } + doSomethingExpensive(payload) { + // a long running process that you want to run in the background + } + + queueSomething() { + await this.queue("doSomethingExpensive", somePayload); // this will NOT block further execution, and runs in the background + await this.queue("doSomethingExpensive", someOtherPayload); // the callback will NOT run until the previous callback is complete + // ... call as many times as you want + } } ``` @@ -36,18 +36,18 @@ Want to build an AI agent that can receive and respond to emails automatically? ```ts export class EmailAgent extends Agent { - async onEmail(email: AgentEmail) { - const raw = await email.getRaw(); - const parsed = await PostalMime.parse(raw); - - // create a response based on the email contents - // and then send a reply - - await this.replyToEmail(email, { - fromName: "Email Agent", - body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, - }); - } + async onEmail(email: AgentEmail) { + const raw = await email.getRaw(); + const parsed = await PostalMime.parse(raw); + + // create a response based on the email contents + // and then send a reply + + await this.replyToEmail(email, { + fromName: "Email Agent", + body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`, + }); + } } ``` @@ -55,11 +55,11 @@ You route incoming mail like this: ```ts export default { - async email(email, env) { - await routeAgentEmail(email, env, { - resolver: createAddressBasedEmailResolver("EmailAgent"), - }); - }, + async email(email, env) { + await routeAgentEmail(email, env, { + resolver: createAddressBasedEmailResolver("EmailAgent"), + }); + }, }; ``` @@ -71,14 +71,14 @@ Custom methods are now automatically wrapped with the agent's context, so callin ```ts export class MyAgent extends Agent { - async suggestReply(message) { - // getCurrentAgent() now correctly works, even when called inside an RPC method - const { agent } = getCurrentAgent()!; - return generateText({ - prompt: `Suggest a reply to: "${message}" from "${agent.name}"`, - tools: [replyWithEmoji], - }); - } + async suggestReply(message) { + // getCurrentAgent() now correctly works, even when called inside an RPC method + const { agent } = getCurrentAgent()!; + return generateText({ + prompt: `Suggest a reply to: "${message}" from "${agent.name}"`, + tools: [replyWithEmoji], + }); + } } ``` From 3f5e6b69e4ebd8191ed83ba23441f7cf8888e8f3 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Mon, 21 Jul 2025 16:46:26 +0100 Subject: [PATCH 11/11] Update 2025-07-21-agents-queue-email-context-update.mdx --- .../agents/2025-07-21-agents-queue-email-context-update.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx index da84a8154258aad..5ccd67e97f943fb 100644 --- a/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx +++ b/src/content/changelog/agents/2025-07-21-agents-queue-email-context-update.mdx @@ -4,7 +4,6 @@ description: The latest release adds .queue(), email support, and automatic cont products: - agents - workers - - workflows date: 2025-07-21 ---