ouro-agents
A Python package for running long-lived autonomous agents on the Ouro platform. An agent process owns a workspace on disk, talks to Ouro through MCP, maintains its own memory, and runs in several modes — interactive chat, one-shot tasks, scheduled heartbeats, and a multi-cycle planning loop tied to Ouro quests.
Highlights
- Multiple run modes — chat, autonomous, heartbeat, plan, review. Each mode has a declarative profile controlling prompt framing, tool access, and lifecycle.
- Subagents — built-in
research,planner,executor,writer,developerprofiles, plus a paralleldelegatetool for fan-out work. Custom profiles can be dropped intoworkspace/subagents/. - Three-layer memory — vector memory (mem0 + Chroma) for curated
facts, working memory (
MEMORY.mdand daily logs) maintained by the agent itself, and conversation history for chat continuity. - Doc store — local markdown mirrored to Ouro posts, scoped per-team.
- Planning loop — generates plan cycles tied to Ouro quests, drives them across heartbeats, incorporates comment feedback through review heartbeats.
- Scheduler — heartbeat, consolidation, refinement, plus user-defined recurring tasks (cron or interval).
- Refinement & cleanup — periodic LLM-driven rewrites of working
memory based on a typed change-set queue, plus deterministic cleanup
for
asset.deletedwebhooks. - OpenRouter integration — prompt caching for Anthropic models, per-mode and per-subagent reasoning effort, multi-model setups.
Install
pip install ouro-agents
Python 3.10+ is required.
Quickstart
Create a standalone agent project:
ouro-agents init my-agent
cd my-agent
python -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
# edit .env and agent.json, then:
ouro-agents build-sandbox
ouro-agents --config agent.json chat
The generated repository owns the agent's identity, skills, curated memory,
coils, and service code. Runtime data and secrets are ignored. Its
pyproject.toml pins the same released ouro-agents package an external user
installs; no checkout of this repository is required.
Harness-owned databases and run state live under agent.data_dir (generated
as ~/ouro-data/<name>), outside the repository.
Run a one-shot task:
ouro-agents --config agent.json run "What teams am I on?"
Or start the long-running server (heartbeats + webhook receiver):
ouro-agents --config agent.json serve
The full walkthrough is in docs/getting-started.md.
Documentation
Full docs live in docs/. A few starting points:
- Concepts overview — how the agent loop, modes, subagents, memory, and planning fit together.
- Configuration reference — every field in
config.json. - CLI reference — every subcommand and flag.
- Run modes — chat, autonomous, heartbeat, plan, review.
- Subagents — built-in profiles, custom profiles,
the
delegatetool. - Memory model — vector memory, doc store, working memory, reflection.
- Workspace layout — what every directory is for.
- Planning — the plan / review cycle.
- HTTP API & webhooks —
/run,/health, event routing. - Glossary — recurring terms.
CLI cheatsheet
ouro-agents init my-agent # scaffold a standalone agent repo
ouro-agents --config agent.json serve # FastAPI server + scheduler
ouro-agents --config agent.json run "Summarize today's activity"
ouro-agents --config agent.json chat # interactive REPL
ouro-agents --config agent.json heartbeat # one heartbeat tick
ouro-agents --config agent.json plan ["goal"] # force a planning heartbeat
ouro-agents --config agent.json review # force a review heartbeat
Add -v for verbose output or --debug-md to capture a full run trace
(see the CLI reference).
HTTP API
While ouro-agents serve is running:
# Threaded conversation-style chat
curl -X POST http://localhost:8000/run \
-H "Content-Type: application/json" \
-d '{"task":"Hi, can you help me post a dataset?","session_id":"demo-user-1"}'
# Same session reuses the same conversation id automatically
curl -X POST http://localhost:8000/run \
-H "Content-Type: application/json" \
-d '{"task":"Use the Machine Learning team","session_id":"demo-user-1"}'
# Health
curl http://localhost:8000/health
The server also accepts Ouro webhook events at server.webhook_path
(default /events). See docs/http-api.md and
docs/events.md.
Workspace
The agent reads and writes everything under agent.workspace (default
./workspace):
workspace/
├── SOUL.md # required: identity, values, operating rules
├── NOTES.md # optional: ambient notes
├── MEMORY.md # curated cross-team memory
├── conversations/ # per-conversation transcripts ({id}.jsonl)
├── shared/logs/ # period logs (daily/weekly/biweekly)
├── teams/<id>/ # team memory, logs/, plans, doc registry
├── memory/ # mem0 + Chroma store (opaque)
├── skills/ # workspace skill overrides
└── subagents/ # custom SubAgentProfile files
See docs/workspace.md.
Configuration at a glance
Minimal config.json shape (full reference in
docs/configuration.md):
{
"agent": {
"name": "hermes",
"org_id": "00000000-0000-0000-0000-000000000000",
"workspace": "./workspace"
},
"models": {
"strong": {
"id": "anthropic/claude-4.6-sonnet",
"reasoning": { "effort": "medium" }
},
"light": {
"id": "google/gemini-2.5-flash",
"reasoning": { "effort": "none" }
}
},
"modes": {
"run": { "max_steps": 60 },
"chat": { "max_steps": 40 },
"planning": { "enabled": true, "cadence": "4h" },
"heartbeat": {
"enabled": true,
"every": "1h",
"active_hours": { "start": "09:00", "end": "17:00", "timezone": "America/Chicago" }
}
},
"subagents": {
"research": { "max_steps": 30 }
},
"memory": {
"provider": "mem0",
"path": "./workspace/protected/memory",
"embedder": "openai/text-embedding-3-small"
},
"mcp_servers": [
{
"name": "ouro",
"transport": "stdio",
"command": "/path/to/python",
"args": ["-m", "ouro_mcp.server"],
"env": { "OURO_API_KEY": "${OURO_API_KEY}", "OURO_BASE_URL": "${OURO_BASE_URL}" }
}
],
"prompt_caching": { "enabled": true, "ttl": "5m" }
}
models.strong / models.light (and optional mid) are the preferred way
to pick models — the harness assigns them by role. Explicit
subagents.<name>.model / modes.*.model overrides still win. See the docs
for everything else.
Development
Tests are in tests/:
pytest
Linting:
ruff check .
The package layout:
ouro_agents/
├── agent.py # OuroAgent orchestrator
├── cli/ # Typer CLI entry point (serve/run/chat/...)
├── server.py # FastAPI + webhook routing
├── config.py # Pydantic config models + loader
├── modes/ # mode profiles + heartbeat + planning
├── subagents/ # SubAgentProfile + runner + built-in prompts
├── memory/ # vector memory + doc store + reflection
├── refinement/ # change-set queue + LLM-driven rewrites
├── cleanup/ # deterministic asset.deleted handler
├── skills/ # built-in markdown skills
├── tools/ # built-in tools (delegate, run_python, etc.)
├── tui/ # team / plan pickers
└── utils/ # streaming, callbacks, conversation helpers
Browse docs/ for a guided tour.
License
See the repository root for license terms.
Release files for ouro-agents 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ouro_agents-0.1.5.tar.gz | 682.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ouro_agents-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / ouro_agents-0.1.5.tar.gz
| Download URL | ouro_agents-0.1.5.tar.gz |
|---|---|
| Size | 682.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4badd49b5e2c53aadbf0608763f82ecccc08db008d2cffc3c26b0dc5be27e2b
|
|
BLAKE2b-256 checksum How to use checksums |
9f67addd527c23de4586d8a8af48362cfd7e1dc4269b79c671f3a8f4a83afcfc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|
Release files / ouro_agents-0.1.5-py3-none-any.whl
| Download URL | ouro_agents-0.1.5-py3-none-any.whl |
|---|---|
| Size | 551.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5acbb44212cd4e361b0dea61d3d52956c26801bf3ff1396ce723daaa747dd71
|
|
BLAKE2b-256 checksum How to use checksums |
786bc62c13134ab11e2a29a3ccfb0ddc4298e425a1ac625916ab6b1a720ea69a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|