Skip to main content

Loopy

Agent workflows that run when your data changes.

open source · agent neutral · code-first

PyPI version Python versions Downloads License: Apache-2.0


Loopy is an open-source, agent-neutral framework for authoring agent automations. Workflows, skills, and sensors live in your repo as Markdown and code, so they version, diff, and review like the rest of your codebase. There is no canvas to click together: loopy compile builds the workflow DAG straight from those files.

Installation

uv tool install loopy-computer   # puts `loopy` on your PATH

Tip: Working from a checkout of this repo? uv tool install . from the repo root installs your local source. Prefer not to install at all? Prefix commands with uv run (e.g. uv run loopy compile).

Quickstart

loopy init my-project            # interactive wizard: scaffold, credentials, webhooks
cd my-project

loopy compile --check            # is the project valid?
loopy doctor                     # is it runnable? (names anything still missing)
loopy trigger --json             # fire one run end-to-end, full record on stdout

loopy run --in-process .         # dev server: compiles, hosts sensors, records every run
loopy admin                      # in another terminal → http://127.0.0.1:9000

A project is a directory, and its credentials live inside it: secrets/base.env (the sandbox environment) and loopy.env (control-plane credentials), both gitignored. loopy init sets all of this up and finishes by running the same checks as loopy doctor, so you know exactly what's left before a first run.

Why Loopy?

  • Files, not canvases. Workflows are Markdown files with YAML frontmatter; the DAG is compiled from on:/after: edges. Everything versions, diffs, and reviews like the rest of your codebase.
  • Agent-neutral. Every agent names its harness, the runner that drives it. Claude Code, OpenAI Codex, and OpenCode ship today, and the harness registry is built to take more. Mix them in one manifest: route triage to one harness and a fixer to another, and swap a step's harness or model without touching its prose.
  • Typed contracts. Events and step outputs are typed field maps (JSON Schema under the hood, validated at runtime by pydantic and code-generated into loopy.events for your typechecker).
  • Sandboxed execution. Every agent runs in a declared sandbox (local, docker, or daytona) with an explicit image, environment, and cloned repos. The sandbox inherits nothing from your shell.
  • Budgets and limits. Per-step budget: (wall clock, spend), plus registry-level caps for a whole workflow or an entire event cascade.
  • Built to be driven by agents. loopy docs prints the full authoring reference as markdown straight from the CLI, and every check is exit-code-clean, so a coding agent can drive the whole authoring cycle headlessly.
  • Observability included. Runs are recorded to a durable store; loopy admin serves a dashboard of run timelines, emitted events, outputs, and failures, locally or against a hosted control plane, bearer-token-gated end to end.

How it works

A workflow is a directory of steps. Exactly one entry step carries on: (a registered event, or a built-in cron("<expr>") trigger); every other step carries after: <step> and consumes its predecessors' outputs. A step is one Markdown file:

---
after:  fix                 # or `on: <RegisteredEvent>` for the one entry step
agent:  Reviewer            # from registry.yml
output: { verdict: enum[pass, fail], notes: str }   # structured outputs, typed
budget: { wall_clock: 20, spend: { usd: 4 } }
---
The agent's objective, in prose; reads {{ event.* }} and {{ fix.diff }} (an output of `fix`).

The reusable entities (Agents, Sandboxes, and Events) are defined once in registry.yml and referenced by name:

defaults:
  agent: { sandbox: default, model: claude-sonnet-4-6, harness: claude-code }

sandboxes:
  default:
    provider: daytona
    image: { debian_slim: "3.12", apt: [git], workdir: /home/loopy, user: loopy }
    env_file: secrets/base.env       # gitignored; injected as the sandbox's env
    repos: [octocat/Hello-World]     # cloned into the workspace, git auth injected

agents:
  Investigator: { skills: [triage, repro-authoring] }            # inherits defaults
  Fixer:        { model: claude-opus-4-8, skills: [testing] }
  Scout:        { model: gpt-5, harness: codex, skills: [triage] }

events:
  Incident: { source: enum[sentry, linear, datadog], issue_id: str, title: str, link: url }
  WorkItem: { link: url, description: str }

A project lays out like this:

my-project/
  registry.yml        # reused, Capitalized entities: Agents · Sandboxes · Events
  workflows/          # each subdirectory is one single-entry workflow
    triage/    investigate.md                          # on: Incident → WorkItem
    resolve/   arbitrate.md · fix.md · review.md · ship.md
  skills/             # reusable agent skills, referenced by name from registry.yml
    triage/    SKILL.md
  sensors/            # the event-publish layer: code that emits registered events
    sensors.py

Outputs vs. events. Within a workflow, data flows by reference along after: chains ({{ fix.diff }}); those are outputs and never touch the bus. Handoffs between workflows go through events: a step emits: a registered event, and another workflow subscribes with on:. The test: does another workflow need this value?

Sensors turn the outside world into registered events: a decorated function triggered by a poll interval or a webhook route, where returning is emitting:

from loopy import sensor
from loopy.events import Incident   # generated from registry.yml

@sensor(webhook="/hooks/sentry", emits="Incident")
def sentry_issues(req) -> Incident:
    i = req.json["data"]["issue"]
    return Incident(source="sentry", issue_id=i["id"], title=i["title"], link=i["permalink"])

Common GitHub and Sentry events are built in: a workflow can trigger on on: Github.PullRequestOpened or on: Sentry.IssueCreated with no registry entry and no sensor at all, and loopy webhooks github registers GitHub's side for you. Webhook signatures (X-Hub-Signature-256, Sentry-Hook-Signature) are verified at the edge before any sensor sees the payload.

Examples

examples/ is the cookbook. Each subdirectory is a self-contained project with its own README, grouped in examples/README.md:

Example What it shows
codefix/ The smallest runnable loop: one event, one agent that edits a checkout and opens a PR. Its README is the "run locally" quickstart. Start here.
incidents/ The canonical multi-workflow loop: triage → resolve → confirm, plus a nightly cron scan, wired by events at the workflow boundaries.
github/ The canonical webhook loop: one /hooks/github URL fans out to sensors for PR review and follow-on work.
effective-agents/ Anthropic's Building Effective Agents patterns (prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer), each as a Loopy workflow.
auto-research/ A self-driving research loop: digest → hypothesize → experiment → write up → reflect, bounded by budgets.

Documentation

The full reference ships inside the CLI, version-matched to your install and readable offline (or by an agent):

loopy docs              # the full authoring reference: workflows, registry, sensors, secrets
loopy docs deployment   # hosting the control plane: env vars, $PORT, TLS, admin auth
loopy docs errors       # the stable LOOPY-E diagnostic catalog

The verify loop is exit-code-clean (loopy compile --checkloopy doctorloopy trigger --json), so a coding agent can author and validate a project end to end. The only two commands that need a human are loopy init (interactive wizard) and loopy auth github (browser flow).

Deployment

The serve contract is deliberately provider-agnostic (a process env var, $PORT, TLS at the platform ingress, and durable run state behind the StateStore protocol), so nothing in Loopy branches on the hosting provider. One public URL is path-routed: webhook deliveries at $LOOPY_PUBLIC_URL/hooks/*, the bearer-token-gated dashboard at $LOOPY_PUBLIC_URL/admin, and an open GET /healthz for platform probes.

Concern Loopy depends on Render Fly / Railway k8s Bare VM
Secret LOOPY_ADMIN_TOKEN from env dashboard env var fly secrets / env Secret → env env / loopy.env
TLS terminated by the ingress auto auto Ingress + cert-manager nginx/caddy
Port $PORT (fallback --port) injected injected containerPort flag/env
Persistence StateStore (SQLite file) persistent disk volume PVC disk

loopy docs deployment prints the full contract; the design, guardrails, and OIDC upgrade path live in docs/design/admin-auth.md.

License

Loopy is open source under the Apache License 2.0. You're free to use, modify, and distribute it, including commercially; the license adds an express patent grant and asks that you preserve attribution and note significant changes.

Download files

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

Source Distribution

loopy_computer-0.2.0.tar.gz (584.6 kB view details)

Uploaded Source

Built Distribution

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

loopy_computer-0.2.0-py3-none-any.whl (287.7 kB view details)

Uploaded Python 3

File details

Details for the file loopy_computer-0.2.0.tar.gz.

File metadata

  • Download URL: loopy_computer-0.2.0.tar.gz
  • Upload date:
  • Size: 584.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for loopy_computer-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fa6ceae543cabae2470a0ab58d36e7c81ed986c0a3efb95730611fc0174c99e7
MD5 57f2faefa4840ce9fd40649aa8ccf8af
BLAKE2b-256 3bb5c5e327faeda8d8c26ca41be2f73a9b72d551063b4f471b063d6b36382230

See more details on using hashes here.

File details

Details for the file loopy_computer-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: loopy_computer-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 287.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for loopy_computer-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ffbe18cf4855c56160a36a60e1ebd7637b566314a1d39bfa163af1ae068de9b3
MD5 dca3fa20953a03af396f49e760fc2b2c
BLAKE2b-256 db9b87df45ceac83ae4e51ba32ec3d13f8a0cc18d879c62386b47e1c279bac3e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Supported by

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