Vercel Workflow `world-restate` Adapter
Status
proposed
Context
Vercel’s Workflow DevKit (useworkflow.dev) provides a durable workflow SDK with event-sourced runs, type-safe steps, hooks/webhooks, DurableAgent, trace viewer, and encryption. The SDK is substrate-agnostic through the World interface — implementations exist for local filesystem, Postgres, and Vercel Cloud.
joelclaw has a proven Restate + Redis + Typesense runtime (ADR-0207/0217/0230) with a custom dagOrchestrator for wave-based DAG execution. This works but lacks:
- Event-sourced run history (we have OTEL events but not a formal event log)
- Type-safe workflow definitions (our DAG nodes are config-driven, not code-defined)
- DurableAgent support (for agent loops with client-side tool pausing)
- Built-in observability (trace viewer, encryption-aware o11y)
- A standards-based workflow model that other tools can integrate with
Building a world-restate adapter gives us Vercel’s SDK ergonomics on our proven substrate.
Decision
Core principle: Bridge, don’t replace
Implement the Vercel Workflow World interface on top of joelclaw’s existing Restate + Redis + Typesense infrastructure. Keep the custom dagOrchestrator for config-driven parallel DAG patterns. Use Workflow SDK for code-defined sequential/branching workflows and DurableAgent.
World interface mapping
| World Component | Interface | joelclaw Implementation |
|---|---|---|
| Storage.runs | get/list | Restate virtual objects (execution state) + Typesense (queryable index) |
| Storage.steps | get/list | Restate step memoization + OTEL events |
| Storage.events | create/list | Redis streams (append-only log) + Typesense (search) |
| Storage.hooks | get/getByToken/list | Redis hash keys (token lookup) + Typesense (audit) |
| Queue | queue/createQueueHandler | Restate service invocations via ingress API |
| Streamer | write/close/readFromStream | Redis pub/sub (real-time) + Redis streams (durability) |
Package structure
packages/world-restate/
├── src/
│ ├── index.ts # World implementation
│ ├── storage.ts # Event log + entity materialization
│ ├── queue.ts # World queue → Restate invocation bridge
│ ├── streamer.ts # Dual-path streaming
│ └── types.ts # Shared types
├── __tests__/
└── package.json # depends on @workflow/core, @restatedev/restate-sdk, ioredisDual execution model
| Pattern | Engine | When to use |
|---|---|---|
| Config-driven DAG (waves, parallel, dependency graph) | dagOrchestrator (existing) | Complex multi-node pipelines dispatched by the workload planner |
| Code-defined workflow (sequential steps, sleep, hooks) | Workflow SDK via world-restate | Type-safe agent workflows, DurableAgent loops, webhook-driven flows |
| One-shot inference/shell | dagWorker handlers (existing) | Simple single-step tasks |
Implementation Plan
Phase 1: Storage adapter
- Implement event log on Redis streams (
joelclaw:workflow:events:{runId}) - Materialize run/step/hook entities from events into Restate virtual objects
- Index into Typesense for list/search queries
- Pass Vercel’s E2E test suite
Phase 2: Queue adapter
- Translate
queue()calls into Restate service invocations - Map
createQueueHandler()to Restate service handler registration - Preserve retry policies and idempotency
Phase 3: Streamer adapter
- Redis pub/sub for low-latency write/read
- Redis streams as durable backing store
- Stream lifecycle tied to workflow run terminal states
Phase 4: Integration + DurableAgent
- Wire world-restate into joelclaw workload system
- Enable DurableAgent workflows (agent loops with client-side tool pausing)
- Connect to existing pi/codex execution in the k8s agent image
Phase 5: Observability
- Wire Workflow SDK trace events into joelclaw OTEL pipeline
- Connect to existing Typesense otel_events collection
- Optionally: self-host Workflow DevKit web UI for trace viewing
Consequences
Positive
- Standards-based workflow model compatible with Vercel ecosystem
- DurableAgent support for sophisticated agent loops
- Event-sourced run history with formal replay capability
- Type-safe workflow definitions instead of config-driven JSON
- Built-in trace viewer and observability
- Community-tested E2E test suite validates the adapter
- Can publish as open-source
world-restatepackage
Negative
- Two workflow execution models to maintain (dagOrchestrator + Workflow SDK)
- Event log adds storage requirements (Redis streams + Typesense)
- Vercel SDK is beta (0.x) — API may change
- Additional dependency surface (@workflow/core)
Risks
- State consistency between Restate execution and event log materialization
- Queue semantics mismatch between World expectations and Restate’s deterministic execution
- Vercel SDK may evolve in directions incompatible with self-hosted patterns
- Workflow SDK’s sequential step model may not map well to our wave-based parallelism
Research Source
This ADR was researched through the joelclaw Restate DAG pipeline (dogfood):
- 3-stage chained workflow: analyze-world-interface → map-dagworker → draft-adr
- Executed via
dagOrchestratorwithinferhandler (pi → Claude Sonnet) - Total pipeline time: ~46s
- Full research outputs preserved in session transcript
References
- Vercel Workflow DevKit — Building a World
- world-local reference impl
- world-postgres reference impl
- ADR-0207: Restate Durable Execution Engine
- ADR-0217: Agent-First Event-Driven Workflows
- ADR-0230: Firecracker MicroVM Agent Sandboxes