Skip to content

@helix-agents/runtime-cloudflare

Cloudflare Workflows runtime for edge deployment. Durable execution using Cloudflare Workers, D1, and Durable Objects.

Installation

bash
npm install @helix-agents/runtime-cloudflare

AgentRegistry

Maps agent type names to configurations.

typescript
import { AgentRegistry } from '@helix-agents/runtime-cloudflare';

const registry = new AgentRegistry();
registry.register(MyAgent);
registry.register(SubAgent);

// Use default global registry
import { defaultAgentRegistry } from '@helix-agents/runtime-cloudflare';

CloudflareAgentExecutor

Executor that starts and manages Cloudflare Workflows.

typescript
import { CloudflareAgentExecutor } from '@helix-agents/runtime-cloudflare';

const executor = new CloudflareAgentExecutor({
  workflowBinding, // AgentWorkflowBinding from env
  stateStore, // StateStore (D1StateStore)
  streamManager, // StreamManager (DurableObjectStreamManager)
  logger, // Optional
});

// Execute agent
const handle = await executor.execute(MyAgent, {
  message: 'Hello',
  state: { userId: 'user-123' },
});

// Get existing handle
const handle = await executor.getHandle(MyAgent, 'run-123');

AgentExecutionHandle

typescript
// Run ID and stream ID
handle.runId;
handle.streamId;

// Stream events
const stream = await handle.stream();
for await (const chunk of stream) {
  // Process chunk
}

// Wait for result
const result = await handle.result();

// Abort execution
await handle.abort('User cancelled');

runAgentWorkflow

Core workflow function for Cloudflare Workflows.

typescript
import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
import { runAgentWorkflow, AgentRegistry } from '@helix-agents/runtime-cloudflare';
import { createCloudflareStore } from '@helix-agents/store-cloudflare';
import { VercelAIAdapter } from '@helix-agents/llm-vercel';

export class AgentWorkflow extends WorkflowEntrypoint<Env, AgentWorkflowInput> {
  async run(event: WorkflowEvent<AgentWorkflowInput>, step: WorkflowStep) {
    const { stateStore, streamManager } = createCloudflareStore({
      db: this.env.AGENT_DB,
      streams: this.env.STREAMS,
    });

    return runAgentWorkflow(event, step, {
      stateStore,
      streamManager,
      llmAdapter: new VercelAIAdapter(),
      registry,
      workflowBinding: this.env.AGENT_WORKFLOW,
    });
  }
}

AgentSteps

Step implementations for workflow execution.

typescript
import { AgentSteps } from '@helix-agents/runtime-cloudflare';

const steps = new AgentSteps({
  stateStore,
  streamManager,
  llmAdapter,
  registry,
});

// Use in workflow
await steps.initializeAgentState(step, input);
await steps.executeAgentStep(step, input);
await steps.executeToolCall(step, toolCall);

createWorkflowRunner

Alternative factory for creating workflow runners.

typescript
import { createWorkflowRunner } from '@helix-agents/runtime-cloudflare';

const runner = createWorkflowRunner({
  stateStore,
  streamManager,
  llmAdapter,
  registry,
  workflowBinding,
});

// Use in workflow
return runner.run(event, step);

Binding Types

Types for Cloudflare bindings.

typescript
import type {
  AgentWorkflowBinding,
  WorkflowBinding,
  WorkflowInstance,
  WorkflowStatus,
  WorkflowDependencies,
  WorkflowOptions,
} from '@helix-agents/runtime-cloudflare';

// Define your environment
interface Env {
  AGENT_DB: D1Database;
  STREAMS: DurableObjectNamespace;
  AGENT_WORKFLOW: AgentWorkflowBinding;
  OPENAI_API_KEY: string;
}

DTOs

Type-safe schemas for workflow inputs/outputs.

typescript
import {
  // Workflow DTOs
  AgentWorkflowInputSchema,
  AgentWorkflowResultSchema,
  type AgentWorkflowInput,
  type AgentWorkflowResult,

  // Step DTOs
  InitializeAgentInputSchema,
  ExecuteAgentStepInputSchema,
  ExecuteToolCallInputSchema,
  ToolCallResultSchema,

  // Sub-agent DTOs
  RegisterSubAgentsInputSchema,
  RecordSubAgentResultInputSchema,
  MarkAgentFailedInputSchema,

  // Stream DTOs
  EndAgentStreamInputSchema,
  FailAgentStreamInputSchema,
} from '@helix-agents/runtime-cloudflare';

Workflow Types

typescript
import type {
  WorkflowStep,
  WorkflowEvent,
  WorkflowDuration,
  WorkflowRetryConfig,
  WorkflowStepConfig,
  WaitForEventOptions,
  WaitForEventResult,
  SubAgentCompletionEvent,
} from '@helix-agents/runtime-cloudflare';

Utilities

pollUntil

Poll until a condition is met.

typescript
import { pollUntil } from '@helix-agents/runtime-cloudflare';

const result = await pollUntil({
  check: async () => {
    const status = await getStatus();
    if (status === 'done') {
      return { done: true, value: status };
    }
    return { done: false };
  },
  interval: 1000,
  timeout: 60000,
});

Complete Example

wrangler.toml

toml
name = "my-agent-worker"
main = "src/worker.ts"
compatibility_date = "2024-12-01"
compatibility_flags = ["nodejs_compat"]

[[d1_databases]]
binding = "AGENT_DB"
database_name = "agents-db"
database_id = "xxx"

[[durable_objects.bindings]]
name = "STREAMS"
class_name = "StreamDurableObject"

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

[[migrations]]
tag = "v1"
new_sqlite_classes = ["StreamDurableObject"]

worker.ts

typescript
import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
import {
  runAgentWorkflow,
  AgentRegistry,
  CloudflareAgentExecutor,
  type AgentWorkflowInput,
} from '@helix-agents/runtime-cloudflare';
import { createCloudflareStore, StreamDurableObject } from '@helix-agents/store-cloudflare';
import { VercelAIAdapter } from '@helix-agents/llm-vercel';
import { MyAgent } from './agent.js';

// Re-export Durable Object
export { StreamDurableObject };

// Registry
const registry = new AgentRegistry();
registry.register(MyAgent);

// Workflow
export class AgentWorkflow extends WorkflowEntrypoint<Env, AgentWorkflowInput> {
  async run(event: WorkflowEvent<AgentWorkflowInput>, step: WorkflowStep) {
    const { stateStore, streamManager } = createCloudflareStore({
      db: this.env.AGENT_DB,
      streams: this.env.STREAMS,
    });

    return runAgentWorkflow(event, step, {
      stateStore,
      streamManager,
      llmAdapter: new VercelAIAdapter(),
      registry,
      workflowBinding: this.env.AGENT_WORKFLOW,
    });
  }
}

// HTTP handler
export default {
  async fetch(request: Request, env: Env) {
    const { stateStore, streamManager } = createCloudflareStore({
      db: env.AGENT_DB,
      streams: env.STREAMS,
    });

    const executor = new CloudflareAgentExecutor({
      workflowBinding: env.AGENT_WORKFLOW,
      stateStore,
      streamManager,
    });

    // POST /agent/run
    if (request.method === 'POST') {
      const { message } = await request.json();
      const handle = await executor.execute(MyAgent, { message });
      return Response.json({ runId: handle.runId });
    }

    return Response.json({ error: 'Not found' }, { status: 404 });
  },
};

interface Env {
  AGENT_DB: D1Database;
  STREAMS: DurableObjectNamespace;
  AGENT_WORKFLOW: AgentWorkflowBinding;
}

See Also

Released under the MIT License.