Your AI workforce, orchestrated.
A visual workflow engine that turns ChatGPT, Claude, and Gemini into coordinated AI employees —
each with real browser sessions, custom roles, and chained task pipelines.
No API keys. No fine-tuning. No vendor lock-in.
Just your existing AI subscriptions, working together.
- The Problem
- What Reception Does
- Who It's For
- How It Works — User Perspective
- Architecture Overview
- Deep Dive — How Everything Works
- Tech Stack
- Getting Started
- Troubleshooting
- Hosting & Deployment
- Roadmap
Everyone's talking about AI employees. But nobody knows how to actually build them.
Companies are drowning in AI tools. Every team has a ChatGPT bookmark, a Claude tab, maybe a Gemini subscription. But these tools sit in isolation — they don't talk to each other, they don't build on each other's work, and they certainly don't function like a coordinated team.
The industry has a fundamental gap:
| What companies have | What companies need |
|---|---|
| Individual AI chatbots | A coordinated AI workforce |
| One-shot prompts | Multi-step, chained pipelines |
| Manual copy-paste between tools | Automatic routing of outputs to inputs |
| AI working amongst humans | AI working with humans |
| Expensive API integrations | Zero-config, subscription-based access |
There's also a deeper philosophical problem: we're building AI to work amongst us — as separate tools we switch between — rather than with us — as team members that collaborate, specialize, and build on each other's work. The difference is everything. A company doesn't hire five generalists and hand each one the same unrelated task. A company hires specialists, defines roles, and chains their outputs into a pipeline. That's what Reception does for AI.
And it's not just enterprise. Solo developers lose hours copy-pasting between Claude for architecture, ChatGPT for implementation, and Gemini for research. There's no reason a single person shouldn't be able to build an automated pipeline that does all of that in one click.
Reception is a visual workflow orchestrator — think n8n or Zapier, but where every node is an AI agent running in a real browser session.
You build a graph. Each node is a named AI employee with a specific role (defined by a system prompt) powered by your choice of service (ChatGPT, Claude, or Gemini). You connect the nodes. You type a single prompt. Reception handles everything else — spawning browsers, sending tasks, routing outputs from one agent to the next, and delivering the final result.
-
🏗️ Visual Workflow Builder — Drag-and-drop node graph editor. Create agents, connect them, define the flow. It's as intuitive as drawing a diagram on a whiteboard.
-
🤖 Multi-Model AI Orchestration — Mix and match ChatGPT, Claude, and Gemini in a single workflow. Use Claude for planning, ChatGPT for code, and Gemini for review — in one pipeline.
-
🖥️ Real Browser Sessions — Not APIs. Playwright opens actual Microsoft Edge windows, uses your logged-in sessions, and interacts with the real web UI. No API keys, no token limits, no monthly API bills.
-
🔗 Automatic Output Routing — The output of each node is automatically fed as the input to the next. Multi-parent nodes aggregate outputs from all predecessors. Zero manual copy-paste.
-
📋 System Prompts as Role Definitions — Each agent gets a system prompt that defines who it is. "You are a senior architect." "You are a QA engineer who finds bugs." "You are a technical writer." This turns generic chatbots into specialized workers.
-
💾 Workflow Persistence — Save, load, and manage workflows from a sidebar. Build a pipeline once, reuse it forever.
-
📊 Real-Time Activity Logging — Live timestamped logs of every action: agent spin-up, prompt delivery, response capture, errors. Full visibility into what's happening under the hood.
-
🔄 Live Status Indicators — Every node shows its current state (idle → initializing → ready → running → done/error) with color-coded indicators and pulse animations.
-
👁️ Output Preview Mode — Toggle output mode to see each agent's response directly on the canvas, transforming the workflow graph into a readable results dashboard.
-
🔐 Persistent Login Sessions — Log in to each AI service once. Playwright saves your session to a persistent browser profile. You never log in again.
| Persona | Use Case |
|---|---|
| Startups & SMBs | Build an AI team without hiring. Create a "Product Manager → Developer → Code Reviewer" pipeline for instant feature development. |
| Solo Developers | Stop copy-pasting between three AI tabs. Build a research → plan → implement → test pipeline and run it with one click. |
| Agency Teams | Chain a "Strategist → Copywriter → Editor → SEO Optimizer" workflow. Feed in a topic, get publish-ready content. |
| Engineering Managers | Manage your AI employees from a single visual dashboard. See who's doing what, what the output is, and where the pipeline breaks. |
| Ops & Automation Teams | Build repeatable, saveable automation pipelines. Think Zapier, but every step is an AI that thinks. |
| Content Creators | Automate the entire creation pipeline: ideation → drafting → editing → formatting → SEO. One prompt in, finished article out. |
Click + Add agent to create nodes on the canvas. Each node represents an AI employee. Click a node to configure it:
- Name — Give it a role title (e.g., "Architect", "Developer", "Reviewer").
- Service — Choose which AI powers it: Claude, ChatGPT, or Gemini.
- System Prompt — Define its role and behavior. This is the most important part — it turns a generic chatbot into a specialized worker.
Drag from one node's right handle to another node's left handle to create a connection. The output of the source node becomes the input of the target node. You can build linear chains, fan-out patterns (one node feeds many), or fan-in patterns (many nodes feed one).
Click ▶ Run workflow, enter your initial prompt (sent to the first node — the one with no incoming connections), and watch. Reception will:
- Spawn a real browser for every agent
- Wait for each browser to be fully loaded and ready
- Execute nodes in topological order (respecting dependencies)
- Send each agent its system prompt + task input as a single combined message
- Capture the full response
- Route the response to the next node(s) in the pipeline
- Display the final output when the last node completes
Toggle the output mode button (bottom-left ◉) to see every agent's response directly on the canvas. Open the Activity panel at the bottom for timestamped logs. Click any node to see its full output in the config panel.
Open the sidebar (☰), name your workflow, and save it. Load it back anytime with a single click.
┌─────────────────────────────────────────────────────────────────────┐
│ FRONTEND (React + React Flow + Vite) │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ ┌─────────┐ ┌─────────┐ │
│ │ App.jsx │ │AgentNode │ │ConfigPanel │ │ Sidebar │ │useWork- │ │
│ │ (layout) │ │(node UI) │ │(right cfg) │ │(left) │ │flow.js │ │
│ └──────────┘ └──────────┘ └────────────┘ └─────────┘ └─────────┘ │
│ │ REST + WebSocket (port 3001) │
├───────┼─────────────────────────────────────────────────────────────┤
│ BACKEND (Node.js + Express + WebSocket) │
│ ┌──────────┐ ┌────────────────┐ ┌──────────────┐ │
│ │server.js │ │orchestrator.js │ │agentManager │ │
│ │(API + │ │(topological │ │.js (process │ │
│ │ routes) │ │ sort + exec) │ │ lifecycle) │ │
│ └──────────┘ └────────────────┘ └──────┬───────┘ │
│ │ child_process.spawn │
├─────────────────────────────────────────┼───────────────────────────┤
│ AGENTS (Python + Playwright) │ │
│ ┌────────────────┐ ┌───────────┐ ┌─────┴──────┐ │
│ │chatgpt_agent.py│ │claude_ │ │gemini_ │ │
│ │ │ │agent.py │ │agent.py │ │
│ └───────┬────────┘ └─────┬─────┘ └─────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌────────────┐ ┌────────────────┐ │
│ │ chatgpt.com │ │ claude.ai │ │gemini.google │ │
│ │ (browser) │ │ (browser) │ │.com (browser) │ │
│ └──────────────┘ └────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Data flows in one direction:
- User draws a workflow graph and clicks Run
- Frontend serializes the graph and POSTs it to the backend
- Backend Orchestrator performs a topological sort to determine execution order
- Agent Manager spawns Python child processes (one per node)
- Python Agents launch real Edge browser windows via Playwright
- Agents type prompts into the real AI web interfaces, wait for responses, and return them
- Outputs are routed node-to-node until the pipeline completes
- WebSocket pushes live status updates back to the frontend throughout
Stack: React 18 · React Flow 11 · Vite 5 · Vanilla CSS
The frontend is a single-page application built with React and Vite. It has zero CSS frameworks — all styling is done in a single App.css file (800+ lines) implementing a dark-mode-first design system with IBM Plex Sans/Mono typography.
| File | Purpose |
|---|---|
App.jsx |
Root layout. Holds the React Flow canvas, toolbar, modals (Run & Output), activity log panel, and manages all top-level state. Registers WebSocket event handlers to update node statuses in real time. |
AgentNode.jsx |
Custom React Flow node component. Renders agent name, AI service badge, system prompt preview, status indicator (with pulse animation for running state), and output preview. Has a dual-mode renderer: normal view vs. output view (when output toggle is active). |
ConfigPanel.jsx |
Right-side configuration sidebar. Appears when a node is selected. Lets users set the agent name, choose the AI service from a dropdown, write a system prompt in a monospace textarea, and view the last output. Changes are applied on click. |
Sidebar.jsx |
Collapsible left sidebar with a rail + panel pattern. Two tabs: Workflows (save/load/delete workflows) and Settings (AI account login management — open a browser to log in to each service). |
useWorkflow.js |
Custom React hook encapsulating all WebSocket and REST API communication. Manages connection state, auto-reconnects on disconnect (2-second backoff), and exposes runWorkflow, stopWorkflow, saveWorkflow, and loadWorkflows functions. Uses a handlersRef pattern to allow dynamic event handler registration without resubscribing. |
React Flow provides the draggable, zoomable canvas with connection handles. Each agent is rendered as a custom agentNode type. Edges are created by dragging between handles. The graph state (nodes + edges) is managed by React Flow's useNodesState and useEdgesState hooks. When a workflow runs, WebSocket events update each node's data.status and data.output fields, causing React to re-render the nodes with live status indicators.
Stack: Node.js · Express 4 · WebSocket (ws) · UUID · Nodemon
The backend is a stateful HTTP + WebSocket server. It is intentionally not a stateless REST API — it holds active agent processes in memory, manages their lifecycles, and broadcasts real-time events.
| File | Purpose |
|---|---|
server.js |
Entry point. Sets up Express, WebSocket server, and all REST endpoints. Handles workflow CRUD (save/load/delete to workflows.json), workflow execution (POST /api/run and POST /api/stop), health checks, and login session management (POST /api/login/:service). Broadcasts agent events to all connected WebSocket clients. |
orchestrator.js |
The execution engine. Takes a workflow graph and an initial prompt, then: (1) builds adjacency lists from edges, (2) performs Kahn's Algorithm (topological sort) to determine safe execution order, (3) detects cycles (and rejects them), (4) spawns all agents (browsers) in parallel, (5) executes nodes in topological order, combining system prompt + task input into a single message, (6) routes outputs between nodes (single parent = direct pass, multiple parents = labeled aggregation). |
agentManager.js |
Process lifecycle manager. Extends EventEmitter. Spawns Python child processes via child_process.spawn, monitors their stdout for the READY signal again, and for base64-encoded responses terminated by @@END_OF_RESPONSE@@. Handles per-agent timeouts (120s for initialization, 180s per prompt), decodes base64 payloads, and cleans up on process exit. |
workflows.json |
Flat-file JSON database storing saved workflows. Each entry has an id, name, workflow (nodes + edges), and updatedAt timestamp. No external database required. |
The orchestrator is the brain of the system. Here's the exact execution flow:
1. Receive workflow graph (nodes[] + edges[]) + initialPrompt
2. Build adjacency structures:
- outgoing{nodeId → [targetIds]} — who does this node feed?
- incoming{nodeId → count} — how many nodes feed into this one?
3. Topological sort (Kahn's Algorithm):
- Start with all nodes that have 0 incoming edges (entry points)
- Process queue: for each node, decrement incoming count of its targets
- If any target reaches 0 incoming, add it to the queue
- If sorted order ≠ total nodes → CYCLE DETECTED → abort
4. Spawn all agents:
- For each node, spawn the Python agent for its service
- Wait for READY signal from each
- Broadcast "initializing" → "ready" status per node
5. Execute in topological order:
- For each node:
a. Determine input:
- No parents → use initialPrompt
- One parent → use parent's output directly
- Multiple parents → aggregate: "[ParentName]:\n{output}\n---\n[ParentName]:\n{output}"
b. Combine: "[System Instructions]\n{systemPrompt}\n\n[Task]\n{taskInput}"
c. Send to agent via stdin
d. Wait for base64 response + @@END_OF_RESPONSE@@
e. Store output, broadcast status + output to frontend
6. Broadcast workflow:complete with the last node's output
Stack: Python 3.10+ · Playwright (sync API) · Microsoft Edge · Base64
The agents are the interface between Reception and the actual AI services. Each agent is a standalone Python script that automates a real browser window.
| Browser Automation (Reception's approach) | API Integration (traditional approach) |
|---|---|
| Uses your existing subscription | Requires separate API billing |
| No per-token costs | $0.01–$0.06 per 1K tokens |
| No API key management | API keys per service |
| Uses the full web UI with all features | API may lag behind web features |
| Visually inspect what's happening | Black box |
| No rate limit concerns (within normal usage) | Strict rate limits |
All three agents (ChatGPT, Claude, Gemini) follow the same stdio protocol:
Node.js Python Agent
│ │
│ spawn("python", ["agent.py"]) │
│─────────────────────────────────▶│
│ │ Launch Edge browser
│ │ Navigate to AI service
│ │ Wait for input element
│ "READY\n" │
│◀─────────────────────────────────│
│ │
│ "prompt text here\n" │
│─────────────────────────────────▶│
│ │ Type into input field
│ │ Press Enter / Click Send
│ │ Wait for stop button → hidden
│ │ Scrape response text
│ "base64(response)\n" │
│◀─────────────────────────────────│
│ "@@END_OF_RESPONSE@@\n" │
│◀─────────────────────────────────│
│ │
│ (repeat for next prompt) │
Base64 encoding is used to prevent multi-line responses from corrupting the line-based protocol. The @@END_OF_RESPONSE@@ sentinel ensures the Node.js process knows exactly when a response is complete.
chatgpt_agent.py
- Navigates to
chatgpt.com/?model=gpt-4o - Locates the prompt input via
#prompt-textarea - Uses
.fill()+Enterkey to submit - Waits for
button[data-testid='stop-button']to appear then disappear (streaming complete) - Scrapes the last
[data-message-author-role='assistant']element
claude_agent.py
- Navigates to
claude.ai/new - Locates Claude's
contenteditablediv - Clears it via
innerHTML = '', then types with 10ms delay - Clicks the send button via
aria-label="Send message" - Waits for stop button (
aria-label="Stop Response") to appear then disappear - Scrapes from
.font-claude-messageor[data-is-streaming]
gemini_agent.py
- Navigates to
gemini.google.com/app - Locates Google's custom
<rich-textarea>element - Selects all (
Ctrl+A), types with 10ms delay, pressesEnter - Waits for "Stop generating" button to appear then disappear
- Scrapes from
<model-response>or.model-response-text
All agents share these resilience features:
- Retry logic — 3 attempts to launch the browser with 2-second backoff
- Lock file cleanup — removes stale
SingletonLock/SingletonSocketfiles that prevent Edge from relaunching - Persistent profiles — session data saved to
profiles/{service}/so you only log in once - Anti-detection flags —
--disable-blink-features=AutomationControlledto avoid bot detection - Graceful error handling — timeouts, closed browser detection, and error messages are all properly emitted
Reception uses two communication channels:
For stateless, request/response operations:
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/api/health |
Server health check |
POST |
/api/run |
Start a workflow (sends graph + initial prompt) |
POST |
/api/stop |
Stop the running workflow and kill all agents |
GET |
/api/workflows |
List all saved workflows |
POST |
/api/workflows |
Save a new workflow |
PUT |
/api/workflows/:id |
Update an existing workflow |
DELETE |
/api/workflows/:id |
Delete a workflow |
POST |
/api/login/:service |
Open a browser for manual login |
POST |
/api/login/:service/close |
Close a login browser |
GET |
/api/login/status |
Check which login sessions are open |
For live, push-based updates during workflow execution:
| Event | Direction | Payload | Purpose |
|---|---|---|---|
connected |
Server → Client | { status } |
Initial handshake, tells client if a workflow is running |
workflow:start |
Server → Client | { timestamp } |
Workflow execution has begun |
node:status |
Server → Client | { nodeId, status } |
Node state changed (idle/initializing/ready/running/done/error) |
node:output |
Server → Client | { nodeId, output } |
Node produced output |
workflow:log |
Server → Client | { message } |
General log message |
agent:log |
Server → Client | { agentId, level, message } |
Agent-level log (stderr output) |
agent:ready |
Server → Client | { agentId } |
Agent browser is ready |
workflow:complete |
Server → Client | { finalOutput, timestamp } |
Workflow finished successfully |
workflow:error |
Server → Client | { message } |
Workflow encountered an error |
workflow:stopped |
Server → Client | {} |
Workflow was manually stopped |
login:ready |
Server → Client | { service } |
Login browser is ready |
login:log |
Server → Client | { service, message } |
Login session log |
login:closed |
Server → Client | { service } |
Login browser was closed |
| Layer | Technology | Why |
|---|---|---|
| Frontend Framework | React 18 | Component-based UI, rich ecosystem, excellent state management with hooks |
| Canvas / Graph Editor | React Flow 11 | Purpose-built for node-based editors — draggable nodes, edge routing, zoom/pan, custom node types |
| Build Tool | Vite 5 | Instant HMR, fast cold starts, significantly faster than Webpack or CRA |
| CSS | Vanilla CSS | Full control over the dark-mode design system without framework overhead. 800+ lines of hand-crafted styles. |
| Typography | IBM Plex Sans + IBM Plex Mono | Clean, professional font pairing. Sans for UI, Mono for code/logs. |
| Backend Runtime | Node.js | Async I/O is perfect for managing multiple long-running child processes. Same language as frontend. |
| HTTP Server | Express 4 | Lightweight, standard, minimal boilerplate |
| WebSocket | ws 8 | Low-level WebSocket library. No Socket.IO overhead — we don't need rooms or namespaces. |
| Unique IDs | uuid 9 | RFC4122 UUIDs for workflow storage without needing a database with auto-increment |
| Dev Server | Nodemon 3 | Auto-restart on backend file changes |
| Process Orchestration | concurrently | Run frontend + backend dev servers from a single npm run dev command |
| Browser Automation | Playwright (Python) | Superior auto-wait, persistent profiles, Edge channel support, cleaner sync API than Selenium or Puppeteer |
| Browser | Microsoft Edge | Chromium-based, less likely to be flagged as automation than raw Chromium |
| Data persistence | JSON flat file | Zero-dependency storage. No database to install, configure, or maintain. |
- Node.js 18+ and npm
- Python 3.10+
- Microsoft Edge (Playwright uses it for persistent browser profiles)
git clone https://github.com/your-username/reception.git
cd reception
# Install root dependencies (concurrently)
npm install
# Install frontend + backend dependencies
npm run install:allpip install playwright pyautogui
playwright install msedgenpm run devThis starts both servers concurrently:
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:3001/api |
| WebSocket | ws://localhost:3001 |
The first time you use a service (ChatGPT, Claude, or Gemini), you need to log in once:
- Open the sidebar (☰ icon) → Settings tab
- Click Login next to the service you want to use
- A real Edge browser window will open — log in manually
- Your session is saved to
backend/profiles/{service}/ - Close the login window — you won't need to log in again
| Problem | Cause | Fix |
|---|---|---|
| "backend offline" in the UI | Backend server not running | Run npm run dev from the project root, or cd backend && npm run dev separately |
| Agent never becomes ready | Browser opened but needs login, or page didn't load | Check the Edge window. Log in if prompted. The agent waits indefinitely for the input element to appear. |
| Agent returns an error | CSS selectors broke (AI services update their UIs) | Open the agent script in agents/, inspect the live page with DevTools, and update the selectors. |
| CAPTCHA or rate limiting | AI service detected automation | Open the visible Edge window, solve the CAPTCHA manually, and the agent will resume automatically. |
| "Failed to launch browser" | Stale lock files from a previous crash | The agents auto-clear lock files on startup. If it persists, manually delete files in backend/profiles/{service}/SingletonLock*. |
| WebSocket keeps reconnecting | Backend crashed or port conflict | Check the backend terminal for errors. Ensure port 3001 is not in use by another process. |
Because Reception uses real browser windows, hosting options are limited to environments that support desktop GUI applications.
The primary intended deployment. Uses your local Edge installation and saves sessions to your hard drive. No configuration needed beyond the setup steps above.
Feasible with extra setup. On Linux, you'll need Xvfb (virtual framebuffer) to run Playwright in headful mode — headless mode triggers Cloudflare/CAPTCHA blocks on AI services. You must VNC/RDP into the server at least once to perform initial logins.
Not possible. These environments don't support persistent file systems (profiles would be wiped), kill long-running processes, and can't run full desktop browsers. Playwright would also be instantly detected as a bot without proper display drivers.
- Conditional branching — Route outputs to different nodes based on content analysis
- Loop nodes — Repeat a sub-pipeline until a condition is met
- Parallel execution — Run independent branches simultaneously instead of sequentially
- File I/O nodes — Read from and write to local files as pipeline inputs/outputs
- Template variables — Insert dynamic values (
{{date}},{{filename}}) into system prompts - Workflow sharing — Export/import workflows as portable JSON files
- Execution history — Log and replay past workflow runs
- More AI services — Perplexity, Mistral Le Chat, Grok, and more
- Headless mode — Optional headless execution for services that don't block it
- Multi-user support — Separate profiles and workflows per user for team deployments
Reception — Stop switching tabs. Start building teams.
Built with frustration at the current state of AI integration. And a lot of Playwright.