Skip to content

Repository files navigation

Multi-Agent Task Automation Platform

Type a high-level goal in plain English — "research my top 3 competitors and draft an outreach email" — and the system:

  1. Decomposes it into a dependency graph of subtasks (a DAG, not a list)
  2. Assigns each subtask to a specialized AI agent (Research / Calendar / Email)
  3. Executes them with real tools (Tavily web search, Google Calendar, Gmail) through a dependency-aware job queue
  4. Streams progress live — you watch the graph's nodes flip queued → running → done
  5. Pauses for approval before anything leaves the sandbox (creating a calendar event, creating a Gmail draft — email is never auto-sent)
  6. Replans dynamically — after each subtask completes, the orchestrator re-evaluates the remaining plan and can add or cancel tasks
  7. Synthesizes a final report when everything settles

Architecture

┌──────────────────────┐        HTTP + SSE         ┌──────────────────────────────┐
│  apps/web (Next.js)  │◄─────────────────────────►│  apps/server (Fastify)       │
│  - goal input        │                           │  - auth (cookie sessions)    │
│  - live task graph   │                           │  - REST: goals / artifacts   │
│  - activity feed     │                           │  - SSE relay (Redis pub/sub) │
│  - approval modal    │                           └──────────┬───────────────────┘
└──────────────────────┘                                      │
                                                   BullMQ jobs│ + pub/sub
                                                              ▼
                            ┌─────────────────────────────────────────────────────┐
                            │  Workers (same process, split-ready)                │
                            │                                                     │
                            │  plan queue ──► Orchestrator (Claude Opus 4.8)      │
                            │                 goal → task DAG → Postgres          │
                            │                                                     │
                            │  task queue ──► dispatch by agent type:             │
                            │    Research Agent ── web_search (Tavily)            │
                            │    Calendar Agent ── list events, PROPOSE events    │
                            │    Email Agent ───── draft emails (never sends)     │
                            │                                                     │
                            │  Execution engine:                                  │
                            │   - enqueue tasks whose deps are all done           │
                            │   - after each completion: replan check (≤3/goal)   │
                            │   - external effects pause in awaiting_approval     │
                            │   - all settled → Writer Agent → final report       │
                            └───────────┬───────────────────────┬─────────────────┘
                                        │                       │
                                 ┌──────▼──────┐         ┌──────▼──────┐
                                 │  Postgres   │         │   Redis     │
                                 │  (Neon)     │         │  (Upstash)  │
                                 │ users/goals │         │ BullMQ jobs │
                                 │ tasks/tool_ │         │ + pub/sub   │
                                 │ calls/artif.│         │ for SSE     │
                                 └─────────────┘         └─────────────┘

Key design points

  • Custom DAG state machine, not a framework. Tasks live in Postgres with a depends_on array. The engine enqueues any pending task whose dependencies are all done, using atomic status transitions (UPDATE … WHERE status='pending') so concurrent workers never double-execute.
  • Real replanning. After every completed task the orchestrator (an LLM call with structured output) reviews the remaining graph and may add or cancel tasks — capped at 3 replans per goal, and cancellations cascade to dependents.
  • Human-in-the-loop as a hard boundary. Agents can only propose external effects. Proposals persist as artifacts in pending_approval; the owning task parks in awaiting_approval; the Google API call happens only inside the approval endpoint, after an explicit user decision. Gmail integration can only create drafts — there is no code path that sends email.
  • Every tool call is logged to the tool_calls table (input, output, error flag, mock flag).
  • Live UX via SSE. Workers publish events to Redis pub/sub; the API relays them per-goal over Server-Sent Events; the frontend reduces them into the task graph, activity feed, and approval modal.
  • Mock fallbacks. Tavily and Google integrations fall back to clearly-labeled mock data when their credentials are absent, so the whole pipeline is demoable with just an Anthropic key.

Repository layout

apps/server        Fastify API + BullMQ workers + orchestrator + agents
apps/web           Next.js App Router frontend
packages/shared    Types shared between the two (DTOs, SSE event union)

Setup

Prerequisites: Node 20+, and free accounts for Neon (Postgres) and Upstash (Redis).

npm install

# 1. Configure the server
cp apps/server/.env.example apps/server/.env
#    - DATABASE_URL: Neon connection string
#    - REDIS_URL:    Upstash *TCP* URL (rediss://default:...@xxx.upstash.io:6379)
#    - ANTHROPIC_API_KEY
#    - optional: TAVILY_API_KEY, GOOGLE_CLIENT_ID/SECRET/REFRESH_TOKEN

# 2. Configure the web app
cp apps/web/.env.local.example apps/web/.env.local

# 3. Create the database tables
npm run db:push

# 4. Run both apps (web on :3000, API on :4000)
npm run dev

Register an account at http://localhost:3000/register, submit a goal, and watch the graph.

Google integration (optional)

Create an OAuth client in Google Cloud Console, enable the Calendar and Gmail APIs, and obtain a refresh token authorized for https://www.googleapis.com/auth/calendar and https://www.googleapis.com/auth/gmail.compose (the OAuth Playground is the quickest way). Put the client ID, secret, and refresh token in apps/server/.env. Without them, calendar/email actions are simulated and labeled as mock.

v1 uses a single server-configured Google identity. The upgrade path to per-user OAuth is a google_accounts table keyed by user + a standard OAuth redirect flow; every call site already goes through src/tools/google.ts.

Data model

Table Purpose
users email/password auth
sessions cookie session tokens
goals the original prompt, status, final summary, replan counter
tasks subtasks: agent, status, depends_on[], result
tool_calls log of every tool invocation (input/output, error + mock flags)
artifacts outputs: email drafts, proposed events, final summaries + approval state

Task lifecycle: pending → queued → running → (awaiting_approval →) done | failed | cancelled

Deployment

  • Frontend: Vercel (apps/web, set NEXT_PUBLIC_API_URL)
  • Backend: Render or Railway (apps/server, npm start); point DATABASE_URL/REDIS_URL at the same Neon/Upstash instances and set WEB_ORIGIN to the Vercel URL
  • The workers run inside the API process; to scale, move startWorkers() (one call site in src/index.ts) into a dedicated worker service.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages