EliaAgent

A fleet of autonomous AI agents that runs your digital life 24/7.

SCHEDULED · MONITORED · SELF-HEALING · UNLIMITED TOKENS

Quick Start Platform Docker RAM License
⭐ View on GitHub ⚡ Quick Start — 2 commands

⚡ Why This Exists

One AI agent is an assistant. A fleet is an employee base. EliaAgent turns OpenCode into a self-managed fleet of autonomous subworkers — each with its own personality, workspace, schedule and memory — driven by a Python FastAPI server in Docker.

🕐 Schedules, not prompts

Every hour from 9h to 18h, weekdays only, weekends off, cron expressions — set it and forget it.

🐳 4 GB RAM ≈ thousands of sessions

The Docker runtime isolates and contains OpenCode's known memory leaks that previously caused CPU/RAM blowups.

♻️ Self-healing runs

Provider outage mid-task? The server detects it, waits a randomized delay, nudges the same session with "continue the tasks" — work resumes where it stopped.

🔁 Exponential-backoff retries

Crashed or timed-out runs retry automatically; session state survives full container nukes.

📡 Realtime everything

REST API + WebSocket events — live status, streaming logs, reasoning, tool calls.

🌍 Remote access

Built-in Cloudflare Tunnel wizard — reach your fleet from anywhere, protected by a shared auth token.

∞ Unlimited tokens

Free OpenCode Zen models + rotating residential proxies = effectively unlimited autonomous work. Rotate IP, keep working — dead proxies are health-checked and skipped automatically.

🧠 Persistent memory (codemem)

Every session feeds a per-agent SQLite memory: decisions, bug fixes, discoveries. The next run loads relevant context automatically — 3,400+ sessions indexed across the production fleet.

💡 Flagship proof: production subworkers run every day for months, writing reports and handing off state to the next shift — without a single human prompt.

🚀 Quick Start

Two commands. Prerequisites, config, Docker image, opencode server, tmux UI — all handled.

git clone https://github.com/vakandi/EliaAgent.git
cd EliaAgent/subworkers

./install_subworkers.sh    # prerequisites + config + Docker image
./start_subworkers.sh      # opencode server + Docker stack + UI in tmux

Health check:

curl http://localhost:5656/health
# {"status":"ok","timestamp":"...","uptime":...}

Then install a client to control the fleet:

🖥️

EliaTopBar

macOS menu bar — trigger, enable/disable, visual schedule picker, live log viewer per agent.

GitHub →
📱

EliaAndroidApp

Your fleet in your pocket — monitor and control agents from mobile.

GitHub →

🤖 How to Add a Subworker

The core skill of the system. Three files, zero code.

Create the agent folder

A workspace for isolated file I/O and a .enabled gate file — presence = active.

mkdir -p subworkers/<agent-id>/workspace
touch subworkers/<agent-id>/.enabled

Write PROMPT.md — the task instructions injected on every run: workspace constraint, handoff protocol (HANDOFF_NEXT_SESSION.md read at start, overwritten at end) and the mandatory <promise>DONE</promise> completion marker the server uses to detect success.

Register the personality

Create ~/.config/opencode/agents/<agent-id>.md with YAML frontmatter — name, description, model (opencode/big-pickle…), temperature, tool permissions. Below the frontmatter: persona, workflow, rules. The host OpenCode server loads it at session creation.

Declare the schedule

Add an entry to subworkers/server/app/config/subworkers.json — hours, minute, days (cron convention: [1,2,3,4,5] = weekdays only) or a cron expression. Max retries and timeout per agent. The server hot-reloads the file — no restart needed:

curl -X POST http://localhost:5656/config/reload

📄 Deep dive: SUBWORKERS_SYSTEM.md — architecture, API contract, failure modes.

🏗️ Architecture

 EliaTopBar / EliaAndroidApp / Electron UI          ← realtime clients
        │  WebSocket /ws + REST :5656
        ▼
 ┌────────────────────────────────────────────┐
 │  elia-subworker-srv (Docker, FastAPI)      │
 │  ├── APScheduler ← subworkers.json         │
 │  ├── SubworkerRunner                       │
 │  │     ├── provider-error auto-recovery    │
 │  │     ├── retries + exponential backoff   │
 │  │     └── HealthManager (auto-restart)    │
 │  └── SessionMonitor (2s polling)           │
 └──────────────┬─────────────────────────────┘
                │ HTTP (host network)
                ▼
      opencode serve :4096  (HOST process)
                │
    ┌───────────┼───────────┐
    ▼           ▼           ▼
 agent A    agent B    agent N      ← personalities + PROMPT.md
 workspace/ workspace/ workspace/  ← isolated file I/O

Run lifecycle: APScheduler fires → isolated session created → PROMPT.md sent → agent works (streamed live over WS) → completion = idle + <promise>DONE</promise> → transient errors auto-recovered → failures retried with exponential backoff → alerts via macOS beep / ntfy.sh.

🔌 API Quick Reference

Auth: shared token via ELIA_AUTH_TOKEN — send as Authorization: Bearer <token>.

MethodPathPurpose
GET/healthServer healthcheck
GET/statusAll subworkers {name, enabled, running, next_run, schedule}
PUT/status/{name}Edit config — schedule (hours/minute/days), model, variant, timeouts
POST/trigger/{name}Run now (optional {prompt, model} body)
POST/enable/{name} · /disable/{name}Toggle
GET/logs/{name}?lines=NRecent run-log lines
GET/sessions/{name}?limit=NFull session messages (reasoning, tools, text)
GET/modelsModel catalog (OpenCode Zen favorites first)
GET/POST/main-agentRead/set the MAIN agent
GET/POST/server/health · /server/restartOpenCode subprocess control
WS/wsLive events: initial_status, subworker_started, run_log, subworker_completed, subworker_error

❓ Troubleshooting

ProblemFix
Client shows DisconnectedServer URL must be http://localhost:5656 (not 8080)
Schedule didn't fireCheck entry in subworkers.json (enabled: true) then POST /config/reload
Container downcd subworkers/server && docker-compose up -d --build
OpenCode server deadPOST /server/restart or restart via launcher
Auth errors (401)Match ELIA_AUTH_TOKEN between server .env and client
Missed runs while laptop sleptHarmless — next slot fires when awake