Skip to content

Workflow Integration Enhancements#825

Merged
threepointone merged 3 commits into
mainfrom
workflows-enhancements
Feb 1, 2026
Merged

Workflow Integration Enhancements#825
threepointone merged 3 commits into
mainfrom
workflows-enhancements

Conversation

@threepointone

Copy link
Copy Markdown
Contributor

Summary

This PR adds several improvements to the Cloudflare Workflows integration for Agents:

  • Fix tracking table updates - Workflow callbacks now properly update the cf_agents_workflows tracking table in real-time (fixes Workflow Tracking Table Not Updated by AgentWorkflow Callbacks #821)
  • Workflow control methods - Add terminateWorkflow(), pauseWorkflow(), resumeWorkflow(), and restartWorkflow() for managing workflow lifecycle
  • Cursor-based pagination - getWorkflows() now returns paginated results with total count and nextCursor for efficient querying of large workflow lists
  • Enhanced workflows demo - Multi-workflow support with real-time updates, pagination UI, and workflow control buttons

Changes

Core SDK (packages/agents)

  • onWorkflowCallback() now updates the tracking table when receiving progress/complete/error callbacks
  • Added terminateWorkflow(workflowId) - Terminate a running workflow
  • Added pauseWorkflow(workflowId) - Pause a running workflow
  • Added resumeWorkflow(workflowId) - Resume a paused workflow
  • Added restartWorkflow(workflowId, options?) - Restart a workflow from the beginning
  • Updated getWorkflows() to return WorkflowPage with cursor-based pagination: typescript type WorkflowPage = { workflows: WorkflowInfo[]; total: number; nextCursor: string | null; };
  • Added observability events: workflow:terminated, workflow:paused, workflow:resumed, workflow:restarted

Workflows Demo (examples/workflows)

  • Support for triggering and managing multiple concurrent workflows
  • Real-time progress updates via WebSocket broadcasts
  • Pagination with "Load More" functionality (page size of 5)
  • Workflow control buttons: Pause, Resume, Restart, Terminate
  • Approve/Reject for human-in-the-loop workflows
  • Dark mode UI with Cloudflare orange accents
  • Persisted UI state for waitingForApproval status via metadata.uiState

Documentation (docs/workflows.md)

Tests

  • Added tests for tracking table updates from callbacks
  • Added tests for pagination (cursor, total, nextCursor)
  • Added tests for orderBy (asc/desc)
  • Added tests for workflow control method error cases

Notes to Reviewers

  1. Local dev limitation: The workflow control methods (terminate, pause, resume, restart) don't work in local dev with wrangler dev due to Miniflare limitations. They work when deployed to Cloudflare. Error messages point users to workflows: terminate(), pause(), resume(), and restart() workflow methods not supported in local development #823 for tracking.

  2. Waiting status workaround: When a workflow calls waitForEvent(), Cloudflare's API still reports status as "running". We work around this by persisting waitingForApproval in metadata.uiState. I've reached out to the Workflows team about exposing a native "waiting" status - this would let us remove the workaround. Tracking here Track upstream: Workflows API "waiting for event" status #824

  3. Pagination cursor encoding: Cursors encode createdAt timestamp in seconds (matching SQLite storage) to avoid off-by-one errors when paginating.

  4. Breaking change (pre-release): getWorkflows() now returns WorkflowPage instead of WorkflowInfo[]. Since workflows haven't shipped yet, this is fine.

  5. Demo architecture: The demo uses client-side pagination state with server-side broadcasts for real-time updates. Each client manages its own loaded pages while receiving live updates for any workflow changes.

## Summary

This PR adds several improvements to the Cloudflare Workflows integration for Agents:

- **Fix tracking table updates** - Workflow callbacks now properly update the `cf_agents_workflows` tracking table in real-time (fixes #821)
- **Workflow control methods** - Add `terminateWorkflow()`, `pauseWorkflow()`, `resumeWorkflow()`, and `restartWorkflow()` for managing workflow lifecycle
- **Cursor-based pagination** - `getWorkflows()` now returns paginated results with `total` count and `nextCursor` for efficient querying of large workflow lists
- **Enhanced workflows demo** - Multi-workflow support with real-time updates, pagination UI, and workflow control buttons

## Changes

### Core SDK (`packages/agents`)

- `onWorkflowCallback()` now updates the tracking table when receiving progress/complete/error callbacks
- Added `terminateWorkflow(workflowId)` - Terminate a running workflow
- Added `pauseWorkflow(workflowId)` - Pause a running workflow
- Added `resumeWorkflow(workflowId)` - Resume a paused workflow
- Added `restartWorkflow(workflowId, options?)` - Restart a workflow from the beginning
- Updated `getWorkflows()` to return `WorkflowPage` with cursor-based pagination:
  ```typescript
  type WorkflowPage = {
    workflows: WorkflowInfo[];
    total: number;
    nextCursor: string | null;
  };
  ```
- Added observability events: `workflow:terminated`, `workflow:paused`, `workflow:resumed`, `workflow:restarted`

### Workflows Demo (`examples/workflows`)

- Support for triggering and managing multiple concurrent workflows
- Real-time progress updates via WebSocket broadcasts
- Pagination with "Load More" functionality (page size of 5)
- Workflow control buttons: Pause, Resume, Restart, Terminate
- Approve/Reject for human-in-the-loop workflows
- Dark mode UI with Cloudflare orange accents
- Persisted UI state for `waitingForApproval` status via `metadata.uiState`

### Documentation (`docs/workflows.md`)

- Added API reference for new workflow control methods
- Added pagination examples for `getWorkflows()`
- Documented local dev limitations with link to #823

### Tests

- Added tests for tracking table updates from callbacks
- Added tests for pagination (cursor, total, nextCursor)
- Added tests for orderBy (asc/desc)
- Added tests for workflow control method error cases

## Notes to Reviewers

1. **Local dev limitation**: The workflow control methods (`terminate`, `pause`, `resume`, `restart`) don't work in local dev with `wrangler dev` due to Miniflare limitations. They work when deployed to Cloudflare. Error messages point users to #823 for tracking.

2. **Waiting status workaround**: When a workflow calls `waitForEvent()`, Cloudflare's API still reports status as "running". We work around this by persisting `waitingForApproval` in `metadata.uiState`. I've reached out to the Workflows team about exposing a native "waiting" status - this would let us remove the workaround. Tracking here #824

3. **Pagination cursor encoding**: Cursors encode `createdAt` timestamp in seconds (matching SQLite storage) to avoid off-by-one errors when paginating.

4. **Breaking change (pre-release)**: `getWorkflows()` now returns `WorkflowPage` instead of `WorkflowInfo[]`. Since workflows haven't shipped yet, this is fine.

5. **Demo architecture**: The demo uses client-side pagination state with server-side broadcasts for real-time updates. Each client manages its own loaded pages while receiving live updates for any workflow changes.
@changeset-bot

changeset-bot Bot commented Feb 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0ab5f6f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agents Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Feb 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/agents@825

commit: 0ab5f6f

@claude

This comment was marked as resolved.

Clear persisted UI state on workflow restart, add robust pagination cursor parsing with descriptive errors, and protect workflow status updates from race-condition overwrites.

Details:
- examples/workflows/src/server.ts: Call clearUIState(workflowId) before restarting a workflow to ensure UI state is reset.
- packages/agents/src/index.ts: Wrap atob/JSON parsing in try/catch and validate cursor structure, throwing a clear "Invalid pagination cursor" error for malformed input. Add WHERE ... AND status NOT IN ('terminated', 'paused') to UPDATE queries for "complete" and "error" callbacks to avoid overwriting terminal states.
- packages/agents/src/tests/worker.ts: Add restartWorkflowWithOptions helper to forward restart options (used in tests).
- packages/agents/src/tests/workflow.test.ts: Add tests to (a) check acceptance of resetTracking option / note on preserving timestamps, and (b) assert descriptive errors are thrown for malformed or structurally invalid pagination cursors.

These changes improve robustness against corrupted pagination cursors and race conditions, and ensure UI state is cleared when restarting workflows.
Remove the separate pre-count and early-return when deleting workflows, and return the actual number of rows deleted from the SQL cursor (cursor.rowsWritten). This avoids an extra COUNT query and provides an accurate deletion result.
agents-git-bot Bot pushed a commit to cloudflare/cloudflare-docs that referenced this pull request Feb 1, 2026
This update comprehensively documents the new Workflow Integration features added in cloudflare/agents#825:

- New AgentWorkflow base class for tight Agent-Workflow integration
- Workflow tracking in Agent SQLite database with cf_agents_workflows table
- Lifecycle callbacks: onWorkflowProgress, onWorkflowComplete, onWorkflowError, onWorkflowEvent
- New workflow control methods: terminateWorkflow, pauseWorkflow, resumeWorkflow, restartWorkflow
- Cursor-based pagination for getWorkflows() with WorkflowPage return type
- Bidirectional communication patterns (Workflow ↔ Agent)
- State synchronization via step.updateAgentState and step.mergeAgentState
- Human-in-the-loop approval flow with waitForApproval helper
- Comprehensive patterns and examples for common use cases

Breaking change: getWorkflows() now returns WorkflowPage instead of array (pre-release).

Note: Workflow control methods not yet supported in local dev - work when deployed.

Related: cloudflare/agents#825, cloudflare/agents#823
@threepointone

Copy link
Copy Markdown
Contributor Author

I addressed all valid claude code feedback

@threepointone
threepointone merged commit 0c3c9bb into main Feb 1, 2026
5 checks passed
@threepointone
threepointone deleted the workflows-enhancements branch February 1, 2026 21:09
@github-actions github-actions Bot mentioned this pull request Feb 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Workflow Tracking Table Not Updated by AgentWorkflow Callbacks

1 participant