---
title: Agents SDK v0.3.7: Workflows integration, synchronous state, and scheduleEvery()
description: The Agents SDK v0.3.7 introduces first-class Cloudflare Workflows integration, synchronous setState() with validation hooks, fixed-interval scheduling with scheduleEvery(), and callable system improvements.
image: https://developers.cloudflare.com/changelog-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/changelog/llms.txt  
> Use this file to discover all available pages before exploring further. 

[Skip to content](#%5Ftop) 

# Changelog

New updates and improvements at Cloudflare.

[ Subscribe to RSS ](https://developers.cloudflare.com/changelog/rss/index.xml) [ View RSS feeds ](https://developers.cloudflare.com/fundamentals/new-features/available-rss-feeds/) 

![hero image](https://developers.cloudflare.com/_astro/hero.CVYJHPAd_26AMqX.svg) 

[ ← Back to all posts ](https://developers.cloudflare.com/changelog/) 

## Agents SDK v0.3.7: Workflows integration, synchronous state, and scheduleEvery()

Feb 03, 2026 

[ Agents ](https://developers.cloudflare.com/agents/)[ Workflows ](https://developers.cloudflare.com/workflows/) 

The latest release of the [Agents SDK ↗](https://github.com/cloudflare/agents) brings first-class support for [Cloudflare Workflows](https://developers.cloudflare.com/workflows/), synchronous state management, and new scheduling capabilities.

#### Cloudflare Workflows integration

Agents excel at real-time communication and state management. Workflows excel at durable execution. Together, they enable powerful patterns where Agents handle WebSocket connections while Workflows handle long-running tasks, retries, and human-in-the-loop flows.

Use the new `AgentWorkflow` class to define workflows with typed access to your Agent:

* [  JavaScript ](#tab-panel-2711)
* [  TypeScript ](#tab-panel-2712)

JavaScript

```
import { AgentWorkflow } from "agents/workflows";
export class ProcessingWorkflow extends AgentWorkflow {  async run(event, step) {    // Call Agent methods via RPC    await this.agent.updateStatus(event.payload.taskId, "processing");
    // Non-durable: progress reporting to clients    await this.reportProgress({ step: "process", percent: 0.5 });    this.broadcastToClients({ type: "update", taskId: event.payload.taskId });
    // Durable via step: idempotent, won't repeat on retry    await step.mergeAgentState({ taskProgress: 0.5 });
    const result = await step.do("process", async () => {      return processData(event.payload.data);    });
    await step.reportComplete(result);    return result;  }}
```

TypeScript

```
import { AgentWorkflow } from "agents/workflows";import type { AgentWorkflowEvent, AgentWorkflowStep } from "agents/workflows";
export class ProcessingWorkflow extends AgentWorkflow<MyAgent, TaskParams> {  async run(event: AgentWorkflowEvent<TaskParams>, step: AgentWorkflowStep) {    // Call Agent methods via RPC    await this.agent.updateStatus(event.payload.taskId, "processing");
    // Non-durable: progress reporting to clients    await this.reportProgress({ step: "process", percent: 0.5 });    this.broadcastToClients({ type: "update", taskId: event.payload.taskId });
    // Durable via step: idempotent, won't repeat on retry    await step.mergeAgentState({ taskProgress: 0.5 });
    const result = await step.do("process", async () => {      return processData(event.payload.data);    });
    await step.reportComplete(result);    return result;  }}
```

Start workflows from your Agent with `runWorkflow()` and handle lifecycle events:

* [  JavaScript ](#tab-panel-2713)
* [  TypeScript ](#tab-panel-2714)

JavaScript

```
export class MyAgent extends Agent {  async startTask(taskId, data) {    const instanceId = await this.runWorkflow("PROCESSING_WORKFLOW", {      taskId,      data,    });    return { instanceId };  }
  async onWorkflowProgress(workflowName, instanceId, progress) {    this.broadcast(JSON.stringify({ type: "progress", progress }));  }
  async onWorkflowComplete(workflowName, instanceId, result) {    console.log(`Workflow ${instanceId} completed`);  }
  async onWorkflowError(workflowName, instanceId, error) {    console.error(`Workflow ${instanceId} failed:`, error);  }}
```

TypeScript

```
export class MyAgent extends Agent {  async startTask(taskId: string, data: string) {    const instanceId = await this.runWorkflow("PROCESSING_WORKFLOW", {      taskId,      data,    });    return { instanceId };  }
  async onWorkflowProgress(    workflowName: string,    instanceId: string,    progress: unknown,  ) {    this.broadcast(JSON.stringify({ type: "progress", progress }));  }
  async onWorkflowComplete(    workflowName: string,    instanceId: string,    result?: unknown,  ) {    console.log(`Workflow ${instanceId} completed`);  }
  async onWorkflowError(    workflowName: string,    instanceId: string,    error: unknown,  ) {    console.error(`Workflow ${instanceId} failed:`, error);  }}
```

Key workflow methods on your Agent:

* `runWorkflow(workflowName, params, options?)` — Start a workflow with optional metadata
* `getWorkflow(workflowId)` / `getWorkflows(criteria?)` — Query workflows with cursor-based pagination
* `approveWorkflow(workflowId)` / `rejectWorkflow(workflowId)` — Human-in-the-loop approval flows
* `pauseWorkflow()`, `resumeWorkflow()`, `terminateWorkflow()` — Workflow control

#### Synchronous setState()

State updates are now synchronous with a new `validateStateChange()` validation hook:

* [  JavaScript ](#tab-panel-2705)
* [  TypeScript ](#tab-panel-2706)

JavaScript

```
export class MyAgent extends Agent {  validateStateChange(oldState, newState) {    // Return false to reject the change    if (newState.count < 0) return false;    // Return modified state to transform    return { ...newState, lastUpdated: Date.now() };  }}
```

TypeScript

```
export class MyAgent extends Agent<Env, State> {  validateStateChange(oldState: State, newState: State): State | false {    // Return false to reject the change    if (newState.count < 0) return false;    // Return modified state to transform    return { ...newState, lastUpdated: Date.now() };  }}
```

#### scheduleEvery() for recurring tasks

The new `scheduleEvery()` method enables fixed-interval recurring tasks with built-in overlap prevention:

* [  JavaScript ](#tab-panel-2703)
* [  TypeScript ](#tab-panel-2704)

JavaScript

```
// Run every 5 minutesawait this.scheduleEvery("syncData", 5 * 60 * 1000, { source: "api" });
```

TypeScript

```
// Run every 5 minutesawait this.scheduleEvery("syncData", 5 * 60 * 1000, { source: "api" });
```

#### Callable system improvements

* **Client-side RPC timeout** — Set timeouts on callable method invocations
* **`StreamingResponse.error(message)`** — Graceful stream error signaling
* **`getCallableMethods()`** — Introspection API for discovering callable methods
* **Connection close handling** — Pending calls are automatically rejected on disconnect

* [  JavaScript ](#tab-panel-2707)
* [  TypeScript ](#tab-panel-2708)

JavaScript

```
await agent.call("method", [args], {  timeout: 5000,  stream: { onChunk, onDone, onError },});
```

TypeScript

```
await agent.call("method", [args], {  timeout: 5000,  stream: { onChunk, onDone, onError },});
```

#### Email and routing enhancements

**Secure email reply routing** — Email replies are now secured with HMAC-SHA256 signed headers, preventing unauthorized routing of emails to agent instances.

**Routing improvements:**

* `basePath` option to bypass default URL construction for custom routing
* Server-sent identity — Agents send `name` and `agent` type on connect
* New `onIdentity` and `onIdentityChange` callbacks on the client

* [  JavaScript ](#tab-panel-2709)
* [  TypeScript ](#tab-panel-2710)

JavaScript

```
const agent = useAgent({  basePath: "user",  onIdentity: (name, agentType) => console.log(`Connected to ${name}`),});
```

TypeScript

```
const agent = useAgent({  basePath: "user",  onIdentity: (name, agentType) => console.log(`Connected to ${name}`),});
```

#### Upgrade

To update to the latest version:

Terminal window

```
npm i agents@latest
```

For the complete Workflows API reference and patterns, see [Run Workflows](https://developers.cloudflare.com/agents/runtime/execution/run-workflows/).

```json
{"@context":"https://schema.org","@type":"BlogPosting","@id":"https://developers.cloudflare.com/changelog/post/2026-02-03-agents-workflows-integration/#page","headline":"Agents SDK v0.3.7: Workflows integration, synchronous state, and scheduleEvery() · Changelog","description":"The Agents SDK v0.3.7 introduces first-class Cloudflare Workflows integration, synchronous setState() with validation hooks, fixed-interval scheduling with scheduleEvery(), and callable system improvements.","url":"https://developers.cloudflare.com/changelog/post/2026-02-03-agents-workflows-integration/","inLanguage":"en","image":"https://developers.cloudflare.com/changelog-preview.png","dateModified":"2026-02-03","datePublished":"2026-02-03","publisher":{"@type":"Organization","name":"Cloudflare","url":"https://www.cloudflare.com/"},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```
