Skip to content

OpenProgram

Self-Programming AI Assistant. Capture, automate, and refine all your workflows.

arXiv Release License Python Platforms Build status

Getting Started · Install · Docs · API Reference · Philosophy · 中文


"The more constraints one imposes, the more one frees oneself."Igor Stravinsky, Poetics of Music

We propose Agentic Programming. An LLM is flexible; code is deterministic. Let the model run everything and you get chaos — unpredictable execution, context explosion, no output guarantees; hard-code everything and you lose the intelligence. A harness balances the two, interleaved moment to moment — Python for the flow you want fixed, the LLM for the judgement you can't script. (the full rationale →)

Contents

Install

curl -fsSL https://openprogram.io/install | sh

macOS desktop: download the unsigned DMG from GitHub Releases. Linux uses the same CLI/server runtime and the Web UI; no Linux desktop package is published. Windows native packaging is not in this release.

Platform matrix, PATH, openprogram doctor, and source-checkout install: Installation.

Quick start

The first openprogram run opens a provider setup wizard, then the terminal chat. Re-run the wizard with openprogram setup.

openprogram

Open the Web UI at http://localhost:18100:

openprogram web

Confirm with one printed reply:

openprogram --print "Introduce yourself in one sentence"

GUI Agent, Research Agent, and Wiki Agent ship with every supported release. Third-party Programs use openprogram programs install <owner>/<repo>. Details: Getting Started.

News

  • 2026-08-17 — Built-in browser: multiple panes, bookmarks, History, and Agent control of visible pages.
  • 2026-07-21 — Multi-agent: spawn sub-agents, message across sessions, file-touching branches in git worktrees.
  • 2026-06-22 — 📄 Paper accepted at the KDD 2026 Workshop on Agentic Software Engineering (arXiv:2606.15874).
  • 2026-06-07 — Installable harnesses and multi-account providers with automatic key rotation.
  • 2026-05-28 — The Web UI design system.
  • 2026-04-04 — Built-in Anthropic / OpenAI / Gemini providers.
  • 2026-04-03 — 🌱 First release: @agentic_function and the execution DAG.

Why OpenProgram?

The current OpenProgram release supports macOS and Linux installations, multiple providers, and a Web interface (desktop App or openprogram webhttp://localhost:18100). Windows native packaging is deferred for a later release decision; Windows and mobile devices can currently use the browser client against a supported remote host. The harness itself provides four mechanisms — one primitive and the three capabilities it enables.

1. Agentic Function — the primitive everything else is built on

Agentic Function — expose is shown to later functions, render_range is history context from callers, docstring is the system prompt, llm() is the model message

An agent is a Python function. You write it like any other function. The docstring is the system prompt: it tells the model what this agent does. Each argument is input for this run. A str argument is the task. In this example the task is the ticket to classify. You do not store the prompt or the JSON as separate variables. They are written as code. choices=[...] asks again until the answer is one of those words.

Here is an example, compared with the common way:

OpenProgramThe common way
@agentic_function
def triage(ticket: str, runtime=None) -> str:
    """Classify the ticket as bug / feature /
    question, then draft a reply."""
    kind = llm(                             # 🤖 LLM decides
        ticket, choices=["bug", "feature", "question"])
    if kind == "bug":                       # 🐍 you decide
        logs = search_logs(ticket)          # 🐍 plain Python
        return llm(                         # 🤖 LLM writes
            f"Reply using:\n{logs}")
    return llm("Draft a short reply.")

🤖 llm() is the model call
🐍 everything else is ordinary Python, and it runs every time

TRIAGE_PROMPT = """You are a triage
agent. Classify the ticket as bug,
feature, or question. Reply as JSON."""

TOOLS = [{"type": "function", "function": {
  "name": "triage",
  "parameters": {"type": "object",
    "properties": {"ticket": {"type": "string"}},
    "required": ["ticket"]}}}]

resp = client.chat(TRIAGE_PROMPT, tools=TOOLS)
kind = json.loads(resp)["kind"]     # hope it parses
if kind not in ("bug", "feature"):
    ...                             # and re-prompt by hand

2. DAG Context — for native multi-agent systems

DAG Context — every user, LLM, and function call is one node on a single flat DAG; each @agentic_function declares in one line what context it reads and exposes, so fork, spawn, cross-session messaging, and worktree isolation all follow

Context is an addressable node, not a per-agent buffer — so every multi-agent move is just "point at a different node set":

Want to… It's one call
Run a sub-agent on a clean context spawn_branch(...)
Send a message to another branch, get the reply message_branch(message, target=...)
Try an alternative without losing the original fork the node
Let a branch touch files safely it runs in its own git worktree

3. Agentic Workflow — for trustworthy & self-evolving agents

Agentic Workflow — Python drives the flow and code gates enforce the critical steps; a failed validation makes the model re-decide so it cannot skip checks; the agent writes and hot-loads its own @agentic_functions

A code gate can't be talked past. When the model's answer fails validation, it is sent back to re-decide — this is the real transcript:

llm  → "probably a feature request"
gate ✗ no parseable pick from ["bug", "feature", "question"]
llm  → {"call": "feature"}
gate ✓ → branch taken in Python

And it grows itself: the agent edits its own @agentic_function files with ordinary file tools → a watcher hot-loads them → the new tool is live on the next turn. No create() / fix() machinery.

4. Event Infrastructure — for proactive agents

Event Infrastructure — a unified process-wide event bus that the agent loop, auth, context, channels, and memory all emit onto; anything can subscribe by event type, and a proactive policy layer builds on top

One bus, every subsystem. The agent loop, auth, context, channels, and memory all emit the same Event(type, payload, ts) envelope, so anything can watch anything:

from openprogram.events import get_event_bus

get_event_bus().subscribe(                       # returns an unsubscribe fn
    lambda e: alert(e.payload),
    types={"context.compaction_recommended", "file.changed"},
)

A foundation, honestly labelled: the plumbing is in place and the proactive policy layer is its first intended consumer — that part is yours to build.

Citation

Using OpenProgram in your work, or building on the code? Please cite our paper — and under the AGPL, any derivative you distribute or run as a network service must itself be open-sourced under the AGPL, with attribution preserved (see License).

LLM-as-Code: Agentic Programming for Agent Harness — accepted at the KDD 2026 Workshop on Agentic Software Engineering (AgenticSE). arXiv:2606.15874

@inproceedings{qi2026llmascode,
  title     = {LLM-as-Code: Agentic Programming for Agent Harness},
  author    = {Qi, Junjia and Fu, Zichuan and Gao, Jingtong and Zhang, Wenlin and Yan, Hanyu and Wu, Xian and Zhao, Xiangyu},
  booktitle = {KDD 2026 Workshop on Agentic Software Engineering (AgenticSE)},
  year      = {2026},
  eprint    = {2606.15874},
  archivePrefix = {arXiv},
  url       = {https://arxiv.org/abs/2606.15874},
}

License

AGPL-3.0 © 2026 Fzkuji. Free to use, study, modify, and share — but any derivative you distribute or run as a network service must also be released under the AGPL, with attribution preserved.

About

Self-Programming AI Assistant. Capture, automate, and refine all your workflows.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

250 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages