Agent Selma is a simplified, educational reimplementation of the OpenClaw project.
The primary goal is to deconstruct and understand the underlying architecture of autonomous agents by rebuilding them from scratch using Python. By stripping away complexity, Selma serves as a clean baseline for learning how agentic components interact.
Warning
This is a toy project for learning purposes only. Selma is not hardened for production use. There are no security audits, no SLA guarantees, and no guarantees of stability or correctness. Do not use this in any production or commercial environment. Use at your own risk.
| Component | Library |
|---|---|
| Language | Python 3.13+ |
| LLM API | Ollama (local) or any OpenAI-compatible API |
| Agent Framework | Pydantic AI — see why it wasn't used |
| Gateway | FastAPI + Uvicorn |
| Dashboard | Streamlit |
| Telegram Channel | python-telegram-bot |
| Tracing | OpenTelemetry + Arize Phoenix |
| Web tools | Playwright, Trafilatura, DDGS |
| Inspiration | OpenClaw / PI-Agent |
Prerequisites: uv must be installed. If you don't have it yet:
pip install uvgit clone https://github.com/YOUR_USERNAME/agent-selma.git
cd agent-selma
uv syncOllama (for local models) — download and install from ollama.com, then pull a model:
ollama pull llama3.2 # recommended default (~2 GB)
ollama pull qwen2.5:14b # more capable, requires ~9 GB RAMOllama runs as a background service automatically after installation. Verify it is running:
ollama listFor the browser tool (Playwright), install Chromium once:
uv run playwright install chromiumRun the setup script once to create the .selma/ directory, generate a default selma.json, and deploy skills and templates into the workspace:
uv run setup.pyThe script is safe to re-run — it never overwrites existing files.
The generated .selma/selma.json contains all available options with their defaults. The most important setting is the model:
"model": {
"model": "ollama/llama3.1",
...
}Use the format "provider/model-name", e.g.:
"ollama/llama3.1"— local Ollama instance (default)"openai/gpt-4o"— OpenAI API (requiresOPENAI_API_KEYin.env)"anthropic/claude-sonnet-4-6"— Anthropic API (requiresANTHROPIC_API_KEYin.env)
If the Telegram channel is enabled, add the bot token to a .env file in the project root:
TELEGRAM_TOKEN=...The WebChat channel needs no additional credentials.
Start the gateway (FastAPI) and the dashboard (Streamlit) together:
./start.sh # macOS / Linux
start.bat # WindowsOr start them individually:
uv run gateway.py # REST API on http://localhost:8000
uv run streamlit run dashboard.pyTo restart only the gateway (e.g. after a code change):
./restart_gateway.sh # macOS / Linux
restart_gateway.bat # WindowsThe Streamlit dashboard (dashboard.py) is the primary web interface for chatting with Selma.
Start it together with the gateway via ./start.sh, or standalone:
uv run streamlit run dashboard.pyThe dashboard opens automatically in the browser at http://localhost:8501.
Features:
- Streaming chat — responses appear word-by-word as Selma generates them; active tool calls are shown inline while the agent works.
- Session continuity — each browser tab gets its own user ID, so multiple sessions run independently against the same gateway.
- Settings dialog — click ⚙️ in the sidebar to view or live-edit
.selma/selma.jsondirectly from the UI, with JSON validation before saving.
When channels.webchat.enabled is true, the gateway exposes a REST endpoint that any web client can use to chat with Selma.
Set channels.telegram.enabled to true and provide TELEGRAM_TOKEN in .env. The bot listens to direct messages and group mentions (@BotName).
Skills extend Selma's behaviour without touching core code. Each skill lives in its own folder:
skills/
<skill-name>/
SKILL.md ← definition (YAML frontmatter + Markdown instructions)
Minimal SKILL.md:
---
name: my-skill
description: "One sentence describing when to trigger this skill."
user-invocable: true
---
# My Skill
## When to use
...
## Steps
1. ...Built-in skills: summarize, web-research, blogwatcher, healthcheck.
Selma uses OpenTelemetry to emit spans for every agent run and records all LLM calls via the OpenInference instrumentation. The traces are collected and visualised by Arize Phoenix — an open-source LLM observability tool that runs entirely locally.
Installation — Phoenix is already listed as a dependency and is installed automatically by uv sync. No separate account or cloud service is needed.
Starting the collector:
Phoenix is started automatically by start.sh / start.bat together with the gateway and dashboard. The UI is available at http://localhost:6006, logs go to phoenix.log.
To start Phoenix standalone (e.g. for debugging without the full stack):
./start_otel.sh # macOS / Linux
start_otel.bat # WindowsIn the Phoenix UI you can inspect:
- every agent run as a trace with individual spans
- LLM input/output messages and token counts
- tool calls and their results
- Python log records attached to their span
Tracing is opt-in: if Phoenix is not running, Selma operates normally with a no-op tracer — nothing breaks.
Scripts marked pytest are discovered and run by pytest. The others are standalone scripts that must be run directly — they require a running Ollama instance and a configured .selma/selma.json.
| Script | How to run | What it tests |
|---|---|---|
test_unit_heartbeat.py |
pytest | Heartbeat scheduling unit tests |
test_unit_memory.py |
pytest | Memory index and search unit tests |
test_agent.py |
direct | Basic agent call without session persistence |
test_agent_session.py |
direct | AgentSession event subscription (streaming) |
test_agent_session_chat.py |
direct | Interactive CLI chat with spinner, /info, /reset_session |
test_agent_session_continue.py |
direct | Resuming an existing session |
test_bootstrap_chat.py |
direct | Bootstrap flow (first-run system prompt) |
test_function_call.py |
direct | Tool / function-call round-trip for all Ollama models |
test_runtime.py |
direct | Full agent runtime integration |
test_skills.py |
direct | Skills snapshot loading and hashing |
test_webchat.py |
direct | WebChat streaming end-to-end (direct function call) |
test_webchat_http.py |
direct | WebChat streaming end-to-end via HTTP gateway |
Run the pytest suite:
uv run pytestRun a standalone script:
uv run test_agent.pyagentselma-game — Play an Agent in an OpenClaw-like Architecture.
A browser-based game (self-contained HTML5, no build step) inspired by the C64 classic Elevator Action: you play Agent Selma, collect context documents from behind locked doors across eight floors, query a chat model and deliver the answers to the drones on the roof. Along the way the mechanics teach the same concepts this repository implements — context window management, debugging, channel routing and prompt-injection defense.
Version 1.0 — feature-complete first release (June 2026).
Important
No Contributions Yet: At this stage, I am not accepting Pull Requests or changes. I am focusing on the initial build to establish the core learning path.
Communication: Feel free to reach out with questions or thoughts! However, please understand that due to time constraints, I may not be able to respond to every message personally.
