AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Event-driven AI agent framework
Translation pending
Developer toolsPython · TypeScriptGitHub @moda-labsSelf-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
Loading the full README. The saved excerpt is shown below.
Bobi is a lightweight library for building and deploying proactive agents -
agents that don't just do work when you talk to them, but respond to real-world
events like ticket updates, incoming emails, GitHub PRs, Slack messages, or any
webhook, acting on their own when something changes. Agents coordinate, delegate,
and spin up new sub-agents on their own whenever the work calls for it.Read the full README ↗Bobi is a lightweight library for building and deploying proactive agents - agents that don't just do work when you talk to them, but respond to real-world events like ticket updates, incoming emails, GitHub PRs, Slack messages, or any webhook, acting on their own when something changes. Agents coordinate, delegate, and spin up new sub-agents on their own whenever the work calls for it.
They also get more useful the more you use them: a built-in sleep cycle distills each session into durable facts and preferences that carry into future runs, so an agent learns how you like to work and adapts its behavior over time. You extend an agent just by telling it what you want - hand it new tasks or responsibilities in plain language, or add new tools, roles, and workflows as your needs grow.
Every agent runs on Claude Code or OpenAI Codex, so it all runs on the flat-rate subscription you already pay for - no per-token API bills (API keys work too).
You define what an agent is for; the framework has no opinion. Here are a few examples of agents you can build:
eng-team agent: import it and customize it with
your own engineering methodologies and practices.personal-assistant agent, connecting to Gmail,
Google Calendar, and Google Tasks via Venn: customize it for your own routines.bobi CLI - installed from Homebrew or any Python
package manager such as uv or
pipx.node is on PATH, including when installing Bobi with Homebrew.
A companion Homebrew formula update will automate this prerequisite once it ships.You don't clone this repo to run Bobi - it's a published package. Install the CLI and go.
For a plain Python installation, use an isolated virtual environment:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install bobi
bobi --version
On a fresh install, bobi agent <name> doctor may report missing Claude Code and Node.js
20+ until those prerequisites are installed. Those warnings are actionable;
the local setup UI can start without Claude, but creating an agent requires it.
Bobi runs each agent on Claude Code (default) or OpenAI Codex. You need at least one installed and authenticated - skip this if you already have one set up.
Claude Code - if you don't have it yet:
brew install --cask claude-code # or: npm install -g @anthropic-ai/claude-code
claude
Log in with your Anthropic account (Pro, Max, or API key). See the Claude Code docs for details.
OpenAI Codex - if you don't have it yet:
brew install --cask codex # or: npm install -g @openai/codex
codex
Log in with your ChatGPT plan or an OpenAI API key. See the
Codex CLI docs for details. You'll
select Codex per agent with brain: {kind: codex} once you create one (below).
With Homebrew:
brew install moda-labs/bobi-agent/bobi
Until the companion Homebrew formula update ships, Homebrew users must install Node.js 20 or newer separately. For every install method, verify that the supported runtime is available:
node --version
Then install with uv:
uv tool install bobi
Or, from a Claude Code session:
Install bobi using https://raw.githubusercontent.com/moda-labs/bobi-agent/main/scripts/install.sh
See scripts/install.sh for what the installer does.
eng-team is the ready-to-use engineering agent that ships with Bobi - install it
to get a working team you can customize, or build your own for any domain (below).
It is preconfigured for GitHub and Slack, so bobi agents install will ask for
the required GH_TOKEN, SLACK_BOT_TOKEN, and SLACK_SIGNING_SECRET secrets
(SLACK_CHANNELS is optional). Authenticate the GitHub CLI or provide a token
with repo access, and see the Slack setup guide for the
bot token and signing secret.
# Install the ready-to-use engineering agent and start it
bobi agents install eng-team --name eng-team
bobi agent eng-team start
# Ask the manager a question (blocks until it responds)
bobi agent eng-team ask "What can I help with right now?"
# Hand it a one-off task
bobi agent eng-team subagents launch -w adhoc --role engineer --task "Fix the login bug"
Prefer a visual home for all of this? The unified web app opens as a dashboard of every agent on your machine - create a team in a guided conversation, launch it, and chat with its agents, all in the browser:
bobi app start # runs in the background; stop/restart/status manage it
Open an agent from the dashboard for its own page: a status strip
(running / stopped / not responding, with start/stop/restart), spend and
health at a glance, and one runs table folding sessions, workflow runs,
and monitor firings behind ALL / RUNNING / FAILED tabs. Click a row for a
transcript or run details; a stalled workflow run can be resumed from
there too. Composition (the agent's agent.yaml, roles, and prompts)
stays read-only on this page - edit it through bobi setup.
Prefer to design your own agent from scratch in a standalone wizard? Run:
bobi setup # go from an idea to a runnable agent, interactively
Or use your coding assistant to help you build one with the create-agent skill -
paste this into your Claude Code or Codex session:
Read https://raw.githubusercontent.com/moda-labs/bobi-agent/main/skills/create-agent.md and help me build a bobi agent
Every agent runs on Claude Code by default - you don't need to configure
anything. To run an agent on OpenAI Codex instead, add a brain block near
the top of its agent.yaml:
brain:
kind: codex # omit the block entirely for Claude Code (the default)
model: gpt-5-codex # optional: provider-specific model or alias
Make sure the matching CLI is installed and authenticated (see
Set up an agent runtime above).
For Claude-backed teams, model can be an alias such as haiku, sonnet, or
opus, or a full Claude model ID.
To run a team on local or self-hosted models, add base_url - the engine
you picked with kind then dials that gateway instead of its native vendor
endpoint. The claude engine works with any Anthropic-compatible endpoint
(LiteLLM, Ollama's Anthropic-compat API):
brain:
kind: claude
base_url: ${LLM_GATEWAY_URL} # the /v1/messages-compatible endpoint
model: qwen3:14b # gateway-native model id
If the gateway needs its own auth, put ANTHROPIC_AUTH_TOKEN in the team's
runtime .env. A proxy that accepts Claude subscription OAuth can instead use
BOBI_AUTH=subscription with no ANTHROPIC_AUTH_TOKEN; login-bootstrap
creates the subscription credentials while preserving the gateway endpoint.
See skills/create-agent.md for the details.
For an OpenAI-compatible gateway, use the codex engine instead:
brain:
kind: codex
base_url: ${LLM_GATEWAY_URL} # OpenAI-compatible /v1 endpoint
model: gpt-5.5 # gateway-native model id
wire_api: responses # optional: responses (default)
If the gateway needs auth, put BOBI_GATEWAY_API_KEY in the team's runtime
.env. Bobi references that dedicated key from Codex and never sends an ambient
real OPENAI_API_KEY to the gateway.
Current Codex builds use the Responses API for custom providers.
Bobi keeps wire_api: chat as a pass-through for deliberately pinned older
Codex builds, but bobi agent <name> doctor warns on it.
For a chat-completions-only OpenAI-compatible gateway, front it with LiteLLM so
Codex can call /v1/responses, or use kind: claude + base_url when the
backend exposes an Anthropic-compatible endpoint.
(The pre-0.46 spellings kind: gateway and kind: gateway-openai remain
accepted aliases for exactly these two configurations.)
Workflow steps can override the team default for that step:
steps:
- name: discover
agent: prospect-targeter
model: haiku
prompt: "Find companies matching the wedge..."
Don't want to edit YAML by hand? Paste this into your Claude Code or Codex session:
In my bobi agent's agent.yaml, set the brain to Codex by adding:
brain:
kind: codex
(To switch back to Claude Code, remove the brain block - Claude Code is the default.)
Out of the box an agent runs locally and handles whatever you hand it. To let it
act on outside services - opening a GitHub PR, updating a Linear ticket, posting
to Slack - it needs credentials for them. bobi agents install prompts for any
secrets the agent's agent.yaml references and writes them to run/.env (never
commit this file); you can also supply them as environment variables.
You don't run the event server yourself - bobi agent <name> start launches a
local one automatically. To receive webhooks from the public internet (Slack,
GitHub, Linear), use the Webhook ingress row in bobi setup's Connections
card. It can keep the team local-only, verify a quick tunnel such as
cloudflared/ngrok to localhost:8080, or save the URL of a durable HTTPS
event server you host yourself (BOBI_EVENT_SERVER; see
docs/SELF_HOSTED_EVENT_SERVER.md).
Setup-authored agent.yaml files reference that optional
environment variable so verified public ingress is used when present, while an
unset value leaves the automatic local event server path unchanged.
If you already run the local event server behind a Cloudflare tunnel, use the quick tunnel option; the wizard does not replace that topology, it validates and persists the tunnel URL for webhook-backed services.
To run that ingress yourself - a tunnel in front of the embedded server, a standalone event server on a box you manage, or the Cloudflare Worker variant when you need registrations and replay to survive a restart - follow docs/SELF_HOSTED_EVENT_SERVER.md.
By default you talk to an agent from the terminal (bobi agent <name> ask). To
message it from Slack instead - and have it reply and react there - generate a
Slack app and point it at your agent:
bobi create-slack-bot --app-name "Bobi"
If you built the team with bobi setup and picked Slack as its chat, the
setup completion screen walks you through this - scopes on-screen, a dedicated
channel saved for the team, and a test message to prove the wiring.
Full walkthrough: Slack setup.
bobi launches agents from your terminal - and
each agent launches its own sub-agents through the same CLI. A director can
spawn async workers, and those workers can launch bounded helpers when a
workflow calls for it. That recursion is the execution model.brain: {kind: claude|codex}, or point a
team at local models by adding a gateway endpoint with
brain: {kind: claude, base_url: ...}.doctor health check.# Launch and operate agents
bobi agent <name> start
bobi agent <name> subagents launch -w <workflow> --role <role> --task "context"
# Talk to running agents
bobi agent <name> ask "question" # blocks until response
bobi agent <name> message "update" # fire-and-forget
# Observe
bobi agent <name> status # active agents
bobi agent <name> events # recent events and decisions
bobi agent <name> events publish alert/firing --json '{"title":"x"}'
bobi agent <name> transcript show <sess> # session transcript
bobi agent <name> doctor # system health check
Full command reference: skills/bobi.md.
Bobi has a small surface area to learn:
$BOBI_HOME (default ~/.bobi)
holds every named agent: editable source in src/, the installed package in
run/package/, mutable state in run/state/, your files in run/workspace/,
and credentials in run/.env.A proactive agent is only as available as the machine it runs on. Locally, your agent works when your laptop is open; in the cloud, it works 24/7 - reacting to a PR at 2am or a support ticket on the weekend without you in the loop. That always-on shift is the real productivity unlock, and Bobi makes it one command.
Bobi publishes a reference container image so you can run an always-on agent on whatever hosts containers already - a VM, Docker on a box, Kubernetes, or your own orchestrator. Nothing about the runtime is tied to a particular cloud.
The image. ghcr.io/moda-labs/bobi:<version> is public and multi-arch. It
carries the framework, the pinned agent runtimes, and the supervisor. Run it
with --init (the container expects a real PID 1) and point it at your event
server:
docker run --init -v bobi-eng:/data \
-e BOBI_INSTANCE=eng \
-e BOBI_TEAM=eng-team \
-e BOBI_AUTH=api_key \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e BOBI_EVENT_SERVER=https://events.example.com \
ghcr.io/moda-labs/bobi:<version>
The volume at /data is the agent's identity and its only durable state -
reuse it and the agent resumes, discard it and you get a fresh agent.
docs/REFERENCE_IMAGE.md documents what the image contains, the runtime env
contract, and the TEAM_DEPS hook for baking your team's own dependencies into
a derived image. docs/SELF_HOSTED_EVENT_SERVER.md covers standing up the
event server the instance connects out to.
Managed fleets. Provisioning, GitOps reconciliation of a whole fleet, and the hosted admin control plane are part of Moda's managed/enterprise offering rather than this package - reach out via an issue or [email protected]. The mechanics below describe how a deployed instance behaves either way:
bobi agent <name> supervise) keep the agent alive
without babysitting. The supervisor's wire contract is documented in
docs/ADMIN_PROTOCOL.md, so an external control plane can monitor and drive
instances over the event bus.TEAM_DEPS hook: derive
from the published base, layer in whatever your team's tools need, and the
hook verifies its own requires gate at build time - useful for custom
runtimes, enterprise registries, or fast CI-built images.An instance needs no public ingress. It holds an outbound WebSocket to the event server and acts on events as they arrive, which is what makes it deployable behind a firewall, in a private subnet, or on a cluster with no inbound path. It works from the published image and the installed CLIs alone - no framework checkout.
Every event the bus delivers becomes input an agent acts on, and a team is code that runs with your credentials, so Bobi gates both ends. A signed trust-bubble (HMAC) controls who can publish or subscribe; proof-of-access grants control which external webhook topics you can receive, verified against an upstream credential that is never stored. The local event server is loopback-only - nothing leaves your machine until you connect a remote one - and installing a team runs its code against your credentials, so review one before installing it, like a dependency.
Full model: docs/SECURITY.md - trust boundary, credentials, the prompt-injection surface, and trusted team code. Event-bus internals: docs/EVENT_SERVER.md.
| Goal | Read |
|---|---|
| Understand how Bobi works | docs/OVERVIEW.md - the core concepts in 5 minutes |
| Go from zero to a deployed agent | docs/QUICKSTART.md - step-by-step quickstart |
| Run and operate Bobi | skills/bobi.md - full CLI reference |
| Build your own agent | skills/create-agent.md · docs/BUILDING_AGENT_TEAMS.md |
| Understand the event bus | docs/EVENT_SERVER.md — architecture, topics, security |
| Receive webhooks on your own infrastructure | docs/SELF_HOSTED_EVENT_SERVER.md — tunnel or standalone server |
| Understand the security model | docs/SECURITY.md — trust, credentials, prompt-injection |
| Connect Slack / Linear | skills/slack-setup.md · skills/linear-setup.md |
| Run Bobi in a container | docs/REFERENCE_IMAGE.md — , the published image |
git clone https://github.com/moda-labs/bobi-agent.git
cd bobi-agent
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,kb]"
pytest tests/ --ignore=tests/integration/ --ignore=tests/e2e/ --timeout=30 -q
That install is intended to match the CI Unit tests job in
.github/workflows/ci.yml. It includes the normal test tools plus
knowledge-base dependencies such as fastembed, sqlite-vec, and their numeric
stack, including numpy, because full unit-test collection imports KB modules.
Use the narrower .[dev] install for e2e-only work where the KB test surface is
not being collected.
ghcr.io/moda-labs/bobi| Control a deployment remotely | docs/ADMIN_PROTOCOL.md — the supervisor's wire contract |
| Implement or operate fine-grained usage metrics | docs/FINE_GRAINED_METRICS.md — architecture, schema, queries, smoke tests, and recovery |