Skip to main content

OpenLoom: a lightweight agent task harness — schedule, monitor, and verify AI coding tasks.

Project description

OpenLoom

CI PyPI

Don't trust the agent's word — trust the file system.

OpenLoom is a webhook-driven task harness for OpenCode. It gives OpenCode a JSON task API, a session monitor, webhook fan-out, a web dashboard, and a file-inbox storage runner — so you can dispatch work from anywhere, even a phone.

OpenLoom does not replace OpenCode. It fills the gaps in its HTTP API.

Install

Requires Python 3.11+ and a running OpenCode server.

uv tool install openloom

That's it. Server deps, python-docx, requests — all bundled. No --with, no [extras].

Quick start

1. Start OpenCode

opencode serve

2. Configure (optional)

Defaults work out of the box with a local OpenCode on port 4096. For custom setups:

openloom init

This writes ~/.openloom/config.yaml. Edit it, or use env vars:

export OPENLOOM_OPENCODE_URL=http://127.0.0.1:4096
export OPENLOOM_OPENCODE_USERNAME=opencode
export OPENLOOM_OPENCODE_PASSWORD=your-password

3. Start OpenLoom

openloom serve

Web dashboard at http://127.0.0.1:8967. Verbose logging: openloom serve -v.

Webhook API

Dispatch a task from any HTTP client, CI pipeline, or messaging bot:

curl -X POST http://127.0.0.1:8967/api/tasks \
  -H "Content-Type: application/json" \
  -d '{"name": "fix-typo", "workspace": "/path/to/project", "goal": "Fix the typo in README.md"}'

Endpoints:

Method Path Description
POST /api/tasks Create and dispatch a task
GET /api/tasks List all tasks
GET /api/tasks/{id} Get task status
POST /api/tasks/{id}/abort Abort a stuck session
DELETE /api/tasks/{id} Delete a task
GET /api/tasks/{id}/events SSE stream of task events

Task payload

{
  "name": "unique-task-name",
  "workspace": "/absolute/path/to/project",
  "goal": "Natural-language instruction for OpenCode"
}

Webhook notifications

OpenLoom fires webhooks on task lifecycle changes. Configure in config.yaml:

bus:
  webhook_url: https://your-service.com/hooks/openloom
  webhook_secret: "shared-secret"

Event payload:

{
  "event": "TASK_UPDATED",
  "task_name": "fix-typo",
  "task_id": "abc123",
  "status": "completed",
  "timestamp": 1719676800,
  "timestamp_iso": "2024-06-29T12:00:00+00:00",
  "recent_activity": [...]
}

Storage Runner

Drop files into an inbox directory and OpenLoom dispatches them as tasks automatically.

Setup

Add a storage level to config.yaml:

levels:
  storage:
    path: ./inbox           # directory to watch
    poll_interval_s: 5      # check every 5 seconds
    class: myapp.MyConnector  # optional connector class

Supported formats

Extension Format
.yaml / .yml Task spec (name, workspace, goal)
.md Markdown — first heading as name, body as goal
.txt Plain text
.docx Word documents (auto-detected)

Connectors

Storage connectors fetch task files from external sources. A connector is a Python class with a download(path) -> bytes | None method. Put it in ./connectors/:

# connectors/mysource.py
import requests
from openloom.levels.storage.base import Connector

class MyConnector(Connector):
    def __init__(self):
        self._session = requests.Session()
        self._session.proxies = {"http": None, "https": None}  # bypass system proxy

    def download(self, path: str) -> bytes | None:
        url = f"https://my-server/files/{path}"
        r = self._session.get(url, timeout=30)
        r.raise_for_status()
        return r.content

Configure in config.yaml:

levels:
  storage:
    class: mysource.MyConnector

Dashboard

openloom serve serves a Svelte dashboard at http://127.0.0.1:8967:

  • Dashboard — live task overview
  • Tasks — create, browse, abort, delete tasks
  • Activity — event stream with session messages
  • Session drawer — inspect OpenCode sessions in real time

Configuration

Run openloom init for a starter ~/.openloom/config.yaml. Key sections:

opencode_url: "http://127.0.0.1:4096"
server:
  port: 8967
bus:
  webhook_url: ""
  webhook_secret: ""
levels:
  storage:
    path: ./inbox
    poll_interval_s: 5

Full reference: docs/configuration.md.

Requirements

  • Python 3.11+
  • OpenCode running with HTTP API enabled

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openloom-0.17.0.tar.gz (678.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openloom-0.17.0-py3-none-any.whl (667.6 kB view details)

Uploaded Python 3

File details

Details for the file openloom-0.17.0.tar.gz.

File metadata

  • Download URL: openloom-0.17.0.tar.gz
  • Upload date:
  • Size: 678.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openloom-0.17.0.tar.gz
Algorithm Hash digest
SHA256 465d26b08efb4c98b7b31a6f80ac88a0702085c0174b20370504af04f42a0521
MD5 350daf404b5f74950406d6cf6f03fe38
BLAKE2b-256 dbedf882d9e6c94dc5cac91903ccc20950642fb50929b3fe8adcdb037592a00b

See more details on using hashes here.

Provenance

The following attestation bundles were made for openloom-0.17.0.tar.gz:

Publisher: release.yml on atbeta/openloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openloom-0.17.0-py3-none-any.whl.

File metadata

  • Download URL: openloom-0.17.0-py3-none-any.whl
  • Upload date:
  • Size: 667.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openloom-0.17.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cfe0a155d1fb5e3f43a339cc5244e3e860ef397d0cf49fc3f449cc47b7627a1f
MD5 12d240416c62cf4aef9e1665edcdf5ff
BLAKE2b-256 0462273cc8088736256b793efd2942cae99465b2eb1609fa51532b7bb5ff5d1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for openloom-0.17.0-py3-none-any.whl:

Publisher: release.yml on atbeta/openloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page