Files
dotfiles/dot_claude/skills/agents-sdk/references/workflows.md
T
Prad NukalaandClaude Fable 5 20891f3910 config(git,claude,ssh): templated gitconfig; claude settings/commands/hooks/skills; ssh config
gitconfig: name/email from chezmoi data, gh credential helper by PATH
lookup (portable to darwin). claude: no credentials, history, projects,
sessions, or plugin caches. ssh config as private_ (0600).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 14:53:46 -04:00

3.8 KiB

Workflows Integration

Fetch https://developers.cloudflare.com/agents/api-reference/run-workflows/ for complete documentation.

Overview

Agents handle real-time communication; Workflows handle durable execution. Together they enable:

  • Long-running background tasks with automatic retries
  • Human-in-the-loop approval flows
  • Multi-step pipelines that survive failures
Use Case Recommendation
Chat/messaging Agent only
Quick API calls (<30s) Agent only
Background processing (<30s) Agent queue()
Long-running tasks (>30s) Agent + Workflow
Human approval flows Agent + Workflow

AgentWorkflow Base Class

import { AgentWorkflow } from "agents/workflows";
import type { AgentWorkflowEvent, AgentWorkflowStep } from "agents/workflows";

type TaskParams = { taskId: string; data: string };

export class ProcessingWorkflow extends AgentWorkflow<MyAgent, TaskParams> {
  async run(event: AgentWorkflowEvent<TaskParams>, step: AgentWorkflowStep) {
    const params = event.payload;

    // Durable step - retries on failure
    const result = await step.do("process", async () => {
      return processData(params.data);
    });

    // Non-durable: progress reporting
    await this.reportProgress({ step: "process", percent: 0.5 });

    // Non-durable: broadcast to connected clients
    this.broadcastToClients({ type: "update", taskId: params.taskId });

    // Durable: merge state via step
    await step.mergeAgentState({ lastProcessed: params.taskId });

    // Durable: report completion
    await step.reportComplete(result);

    return result;
  }
}

Wrangler Configuration

{
  "workflows": [
    { "name": "processing-workflow", "binding": "PROCESSING_WORKFLOW", "class_name": "ProcessingWorkflow" }
  ],
  "durable_objects": {
    "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }]
}

Agent Methods for Workflows

// Start a workflow
const instance = await this.runWorkflow("ProcessingWorkflow", { taskId: "123", data: "..." });

// Send event to waiting workflow
await this.sendWorkflowEvent("ProcessingWorkflow", workflowId, { type: "approve" });

// Query workflows
const workflow = await this.getWorkflow(workflowId);
const workflows = await this.getWorkflows({ status: "running" });

// Control workflows
await this.approveWorkflow(workflowId);
await this.rejectWorkflow(workflowId);
await this.terminateWorkflow(workflowId);
await this.pauseWorkflow(workflowId);
await this.resumeWorkflow(workflowId);

// Delete workflows
await this.deleteWorkflow(workflowId);
await this.deleteWorkflows({ status: "complete", before: new Date(...) });

Lifecycle Callbacks

export class MyAgent extends Agent<Env, State> {
  async onWorkflowProgress(workflowName: string, workflowId: string, progress: unknown) {
    // Workflow reported progress via this.reportProgress()
    this.broadcast({ type: "progress", workflowId, progress });
  }

  async onWorkflowComplete(workflowName: string, workflowId: string, result?: unknown) {
    // Workflow finished successfully
  }

  async onWorkflowError(workflowName: string, workflowId: string, error: Error) {
    // Workflow failed
  }

  async onWorkflowEvent(workflowName: string, workflowId: string, event: unknown) {
    // Workflow received an event via sendWorkflowEvent()
  }
}

Human-in-the-Loop

// In workflow: wait for approval
const approved = await step.waitForEvent<{ approved: boolean }>("approval", {
  timeout: "7d"
});

if (!approved.approved) {
  throw new Error("Rejected");
}

// From agent: approve or reject
await this.approveWorkflow(workflowId);  // Sends { approved: true }
await this.rejectWorkflow(workflowId);   // Sends { approved: false }