Metadata-Version: 2.4
Name: heybento
Version: 0.1.0
Summary: Routing + ingress + observability hub for Claude Agent SDK agents you self-host.
Project-URL: Homepage, https://github.com/Hyra/bento
Project-URL: Repository, https://github.com/Hyra/bento
Project-URL: Issues, https://github.com/Hyra/bento/issues
Author-email: Stef van den Ham <stef@mindthecode.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agent,claude,claude-agent-sdk,cron,inbox,self-host,webhook
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.20
Requires-Dist: claude-agent-sdk>=0.2
Requires-Dist: cron-descriptor>=1.4
Requires-Dist: croniter>=2.0
Requires-Dist: cryptography>=43.0
Requires-Dist: docker>=7.0
Requires-Dist: fastapi>=0.115
Requires-Dist: gitpython>=3.1
Requires-Dist: httpx>=0.27
Requires-Dist: jinja2>=3.1
Requires-Dist: pydantic>=2.9
Requires-Dist: python-dotenv>=1.0
Requires-Dist: uvicorn[standard]>=0.32
Requires-Dist: watchfiles>=0.24
Requires-Dist: websockets>=13
Description-Content-Type: text/markdown

# 🍱 heybento

> **Claude Code gives your agent a brain. Bento gives it a heart.**

Bento is the **routing, ingress, history and lifecycle layer** for
[Claude Agent SDK](https://docs.anthropic.com/en/api/agent-sdk) agents
you self-host. Claude Code is where you write and reason about an agent.
Bento is where it actually lives — webhook URLs that don't change,
cron triggers that fire on schedule, an inbox queue with claim/retry,
sessions you can replay weeks later.

Single-tenant, self-host on your own VPS. No SaaS. See
[ADR-0002](docs/adr/0002-local-dev-tool.md) for the design.

## What Bento gives you

- **One stable ingress URL per agent.** Point Microsoft Graph, Slack,
  GitHub, whatever your webhook source is, at
  `https://bento.example.com/agents/agt_xyz/inbox/...` and never touch
  it again — whether the agent is running on your laptop, your VPS, or
  Fly.io.
- **Cron that tikt** without your agent needing to run an internal
  scheduler. The hub fires; the agent picks up the event.
- **An inbox queue**. Items wait while the agent is offline; they get
  claimed and processed when it comes back.
- **Local-dev priority**. Run `bento dev` on your laptop and the hub
  routes events to your terminal — the hosted agent (if any) is
  bypassed automatically until you quit, then it picks up the queue.
- **Sessions, events, cost.** Every run captured, replayable, with
  token + cost breakdown.
- **Encrypted secrets** (Fernet at rest), runtime config overrides
  via env vars, GitHub-connected deploys with manual ‘Deploy’ button.

## Install

```bash
pip install heybento
# or: uv tool install heybento
```

Provides one CLI: `bento`.

## Quick start: run the hub locally

```bash
bento hub             # http://localhost:8000
```

The hub is FastAPI + SQLite (`~/.bento/bento.db`). It looks for
`~/.bento/.env` on startup so you can keep your config + tokens in one
place.

## Quick start: write and run an agent

```bash
bento new melvin --project noise --description "NOISE assistant"
cd melvin
bento dev
```

`bento new` scaffolds `agent.py` + `README.md`. `bento dev` registers
the agent with the hub, opens the agent's detail page in your browser,
spawns the agent as a local subprocess and reloads it on every save.
Events from the hub flow to your terminal.

A minimal `agent.py`:

```python
import os
import bento
from claude_agent_sdk import ClaudeAgentOptions, ResultMessage

app = bento.App(name="melvin", project="noise")


@app.cron("0 9 * * 1", description="Weekly Monday review")
async def monday_review(payload: dict):
    await app.log("monday-review-start")
    # … do work, possibly call app.query(...) …
    return "done"


@app.webhook("teams", description="Inbound Teams message")
async def on_teams(payload: dict):
    options = ClaudeAgentOptions(
        system_prompt="Reply concisely.",
        max_turns=int(os.getenv("BENTO_MAX_TURNS", "3")),
        allowed_tools=[],
    )
    async for msg in app.query(prompt=payload["text"], options=options):
        if isinstance(msg, ResultMessage):
            return msg.result or ""
    return ""
```

## Deploy paths

**Bento-hosted (Docker on your VPS).** Push your agent to GitHub
(private repo is fine). In the agent's detail page → *Source*: paste
`owner/repo`, branch, click **Deploy**. Bento clones the repo into
`~/.bento/deploys/<agent_id>/` and starts a container from the
`bento-agent-runtime` image with the clone mounted read-only.

Requires `BENTO_GITHUB_TOKEN` on the hub (fine-grained PAT scoped to
the relevant repos, read-only). Token stays in the hub process, never
in any agent container.

**Anywhere else (Fly, Railway, Render, your own Kubernetes).** Bento
doesn't manage the runtime there, but the agent still talks to your
hub via HTTPS. Pin `BENTO_HUB` to your hub URL, set `BENTO_AGENT_ID`
after first registration, and you keep the ingress URL, inbox, cron,
session history, and dev-priority routing. The hub UI shows the agent
as `external` — Deploy/Restart buttons are no-ops, everything else
works.

## Environment variables

| Var | Where | Purpose |
|---|---|---|
| `BENTO_HUB` | SDK side | URL of your hub (`http://localhost:8000` locally) |
| `BENTO_DB` | hub | SQLite path (default `~/.bento/bento.db`) |
| `BENTO_DEPLOYS` | hub | git-clone root (default `~/.bento/deploys`) |
| `BENTO_GITHUB_TOKEN` | hub | PAT for cloning private repos |
| `BENTO_SECRET_KEY` | hub | Fernet key (auto-generated at `~/.bento/master.key` if absent) |
| `BENTO_AUTOSPAWN` | hub | `1` enables the supervisor's Docker spawn path (production VPS) |
| `BENTO_AGENT_ID` | SDK | Anchor re-registers to this row regardless of agent rename |

## Status

Pre-1.0. Working on agent-builder branch. Single-tenant self-host
only — no multi-tenant SaaS planned. Open-source release is on the
roadmap once the dev loop is stable enough that real-world agents are
running on it (currently dogfooded with the NOISE assistant).

## License

MIT. See [LICENSE](LICENSE).
