npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-sdk-cloudflare-workflow-harness

v0.1.2

Published

Run an @ai-sdk/harness agent as a durable workflow on Cloudflare Workflows.

Readme

AI SDK - Cloudflare Workflow Harness

This package is experimental.

Drive an AI SDK HarnessAgent turn as a durable workflow on Cloudflare Workflows, dividing it into time slices or semantic agent steps. Each slice is a step.do.

The agent runs its work (Claude Code, Codex) in a sandbox; the workflow orchestrates that turn durably. The turn state machine, step.do checkpointing, resume across slices, and reattachment to a still running sandbox are verified on the live Cloudflare Workflows runtime.

Runtime. The agent's orchestrator runs in the Worker and drives the agent's process in the sandbox, so the orchestrator, its adapter, and its sandbox provider must run in workerd. Today the shipping @ai-sdk/harness-claude-code and Codex adapters read their bundled bridge assets from the filesystem and connect over the ws package, and the local, docker, and bridge sandbox providers rely on host process or Node APIs. None of those run in workerd yet, so Claude Code and Codex on Cloudflare Workflows are not yet possible. The durable plumbing is ready for a workerd-compatible agent and sandbox provider.

This is the Cloudflare counterpart to @ai-sdk/workflow-harness. That package runs on Vercel's Workflow DevKit; this one runs on the Cloudflare Workflows engine (WorkflowEntrypoint, step.do) instead. The turn state machine is the same, so the two read alike. There is no dependency on the workflow DevKit.

Each slice runs in its own step.do and returns a serializable state object, which Cloudflare Workflows persists as the durable checkpoint between steps. Time slices let a long turn checkpoint and reattach to the still-running sandbox. Semantic steps persist after each agent step, typically by configuring the agent with stopWhen: isStepCount(1).

This package ships plain helpers; you own the thin WorkflowEntrypoint. Keep the agent, its sandbox provider, and other Node-heavy dependencies out of any code path that has to stay lightweight by importing the agent inside the step body.

Setup

npm i ai-sdk-cloudflare-workflow-harness @ai-sdk/harness

Requires a Workers project with Workflows enabled, and a workerd-compatible HarnessAgent (see the runtime note above). The agent's sandbox provider must also run in workerd; host-process providers like ai-sdk-sandbox-local and the docker CLI provider do not.

Usage

agent.ts:

import { HarnessAgent } from '@ai-sdk/harness/agent';
import { claudeCode } from '@ai-sdk/harness-claude-code';

export function createAgent(env: Env) {
  return new HarnessAgent({
    harness: claudeCode,
    sandbox: createSandbox(env), // your sandbox provider
  });
}

agent-workflow.ts:

import {
  WorkflowEntrypoint,
  type WorkflowEvent,
  type WorkflowStep,
} from 'cloudflare:workers';
import {
  runHarnessWorkflow,
  durableObjectResumeStore,
  nullWritable,
  type HarnessWorkflowInput,
} from 'ai-sdk-cloudflare-workflow-harness';

export class AgentWorkflow extends WorkflowEntrypoint<Env, HarnessWorkflowInput> {
  async run(event: WorkflowEvent<HarnessWorkflowInput>, step: WorkflowStep) {
    const { createAgent } = await import('./agent');

    return runHarnessWorkflow({
      agent: createAgent(this.env),
      input: event.payload, // { sessionId, prompt, resumeFrom? }
      step,
      writable: nullWritable(), // or a DO WebSocket / SSE sink
      store: durableObjectResumeStore(this.env.SESSIONS.get(id).storage),
    });
  }
}

wrangler.toml:

[[workflows]]
name = "agent"
binding = "AGENT_WORKFLOW"
class_name = "AgentWorkflow"

Start a run from a fetch handler with env.AGENT_WORKFLOW.create({ params }), reusing the conversation id as sessionId so each user turn resumes the same warm session.

Driving the loop yourself

runHarnessWorkflow is the loop. To control each step, call the lower-level helpers and continue while the status is ready_for_next_step:

import {
  createHarnessWorkflowState,
  finalizeHarnessWorkflow,
  runHarnessAgentStep,
} from 'ai-sdk-cloudflare-workflow-harness';

let state = createHarnessWorkflowState(event.payload);
let i = 0;
do {
  const current = state;
  state = await step.do(`agent:${i++}`, () =>
    runHarnessAgentStep({ agent, state: current, writable }),
  );
} while (state.status === 'ready_for_next_step');
return finalizeHarnessWorkflow(state);

Use runHarnessAgentStep for semantic steps (configure the agent with stopWhen: isStepCount(1)) or runHarnessAgentTimeSlice for wall-clock slices.

Resume across turns

Within one run, step.do return values carry state between steps. A ResumeStore is what lets a later run, a new user turn, reattach to the same warm conversation. It is the Cloudflare stand-in for the DevKit's implicit persistence.

import { durableObjectResumeStore, kvResumeStore } from 'ai-sdk-cloudflare-workflow-harness';

const store = durableObjectResumeStore(this.env.SESSIONS.get(id).storage);
// or
const store = kvResumeStore(this.env.SESSIONS_KV);

Pass it to runHarnessWorkflow and it loads the coordinate before the turn and saves the next one after. ResumeStore is a three-method interface (load, save, clear); implement it over any backend.

Options

runHarnessWorkflow takes agent, input, step, and writable. The rest are optional:

  • store persist and reattach the warm session across turns.
  • timeSliceSeconds wall-clock budget per slice. Defaults to 750.
  • destroyOnFinish release the sandbox when the turn finishes. Defaults to false, so the next turn resumes.
  • stepConfig override the step.do retry and timeout for each slice.

License

Apache-2.0

Portions derived from @ai-sdk/workflow-harness (Apache-2.0).