Skip to content

Repository files navigation

Agentic Workflow Platform

An internal platform for running AI agent workflows (Claude and OpenAI) that can be triggered by schedule, webhook, or API call — with support for pausing a workflow to wait for human input before it completes, and automatic failover across an ordered list of models if a provider is temporarily unavailable.

Full design rationale: docs/superpowers/specs/2026-07-17-agentic-workflow-platform-design.md. Original implementation plan: docs/superpowers/plans/2026-07-17-agentic-workflow-platform.md.

Features

  • Multi-provider failover — each workflow declares an ordered list of {provider, model} preferences; a transient failure (rate limit, 5xx, timeout, network error) automatically falls over to the next preference, while a logical failure (bad request, auth, content policy) fails the workflow outright rather than retrying blindly.
  • Durable pause/resume — a workflow can pause to wait for a human decision. Pause state is persisted to Postgres and survives a restart of the worker process; resuming is race-guarded so two simultaneous resume attempts on the same run can't both succeed.
  • Three trigger types — cron schedule, signed webhook, or a direct authenticated API call, all normalized into the same internal event.
  • Minimal resume UI — a session-authenticated internal web page listing paused runs, with a form to submit the input needed to resume one.

Requirements

  • Bun 1.3+
  • A Postgres instance (for the durable run-state tables)
  • A self-hosted Inngest server (for orchestration)
  • Claude and/or OpenAI API credentials
  • Podman (for the container-based deployment described below)

Getting started

bun install
cp .env.example .env   # fill in provider keys, secrets, and connection info

Load the database schema into your Postgres instance:

psql -d <your-database> -f src/db/schema.sql

Run the two services (each is a separate process/container in production — see Deployment):

bun run src/worker/main.ts   # Inngest functions: runs and orchestrates workflows
bun run src/http/main.ts     # HTTP service: webhook/API triggers, resume API, resume UI

The HTTP service also needs a running Inngest server pointed at the worker's /api/inngest endpoint — see deploy/podman-compose.yml for the exact self-hosting configuration (Inngest does not auto-discover apps; it needs explicit registration).

Development

bun run test        # full test suite (see note below on why not `bun test`)
bun run typecheck    # tsc --noEmit
bun test path/to/file.test.ts   # a single test file

bun run test runs bun test --isolate, which is required — several test files replace shared modules with mock.module(), and that replacement leaks across test files sharing one process unless each file runs in its own isolated global environment.

Tests under src/db/ and src/worker/runLeg.e2e.test.ts need a real Postgres reachable via APP_POSTGRES_URL, with src/db/schema.sql loaded:

initdb -D /path/to/pgdata -U postgres --auth=trust
pg_ctl -D /path/to/pgdata -o "-p 5433" start
createdb -p 5433 -U postgres test
psql -p 5433 -U postgres -d test -f src/db/schema.sql
APP_POSTGRES_URL=postgres://postgres@localhost:5433/test bun run test

Project layout

Path Responsibility
src/adapter/ Provider-agnostic agent runner (runAgent()) wrapping the Claude Agent SDK and OpenAI Agents SDK, with ordered-preference failover
src/db/ Postgres-backed durable state for workflow runs, the audit-log event stream, and resume-UI sessions
src/worker/ Inngest functions — the per-"leg" workflow executor and workflow registry
src/http/ Webhook/API trigger routes, the resume API, and the session-authenticated resume UI
deploy/ Dockerfiles and a Podman Compose file for a four-container deployment (Inngest server, worker, HTTP service, application Postgres)

Deployment

cd deploy
podman-compose up --build

This brings up four containers: the Inngest server, the worker, the HTTP service, and a dedicated application Postgres (kept separate from Inngest's own internal storage). See the Dockerfiles and podman-compose.yml for the exact environment variables each service needs.

Known limitations

  • The HTTP trigger and resume routes commit their Postgres state change before sending the corresponding Inngest event; if that send fails, the run is left in place with no automatic reconciliation. See "Known Issues / Follow-ups" in the design spec.
  • Live deployment (Podman) and real provider API calls have not been exercised end-to-end outside of unit/integration tests with mocked SDK responses — see the design spec and plan documents for what remains to be manually verified.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages