Self‑learning AI Agent — DeepSeek · OpenAI · Claude · Gemini · Ollama
A terminal-native, fully autonomous AI agent that learns from every interaction,
operates your filesystem, manages git, fixes bugs, and improves itself over time.
- What is OpenKyrozen?
- 🚀 Installation
- 📖 Usage Guide
- 🏗 Architecture
- 🛠 Tools Reference
- 🧠 Dedicated Workflows
- 🧬 Self-Learning System
- 🌐 Web UI & REST API
- 🔌 Plugin System
- 🔐 Security
- ⚙️ Configuration Reference
- 🔧 Development
- 📁 Project Structure
- 🙏 Standing on the Shoulders of Giants
- 📄 License
OpenKyrozen is a self-learning AI agent that runs in your terminal. Unlike a typical chatbot, it:
- Uses 26 built-in tools — read/write files, execute shell commands, search the web, manage git repositories
- Learns continuously — background learning creates evidence-backed proposals and only promotes repeated or validated improvements
- Works with any LLM — DeepSeek, OpenAI, Claude, Gemini, or local Ollama models
- Runs on any OS — macOS, Linux, and Windows (with automatic terminal capability detection)
- Has a Web UI — browser-based chat interface with REST API for integration
Think of it as an AI teammate that gets smarter every time you use it.
- Python 3.12 or 3.13 (Python 3.14+ has a known import issue with the OpenAI SDK)
- An API key from any supported provider:
| Provider | Get a key | Cost |
|---|---|---|
| DeepSeek | platform.deepseek.com | ~$0.27/M input tokens |
| OpenAI | platform.openai.com | ~$2.50/M input tokens |
| Anthropic (Claude) | console.anthropic.com | ~$3.00/M input tokens |
| Google (Gemini) | aistudio.google.com | ~$0.15/M input tokens |
| Ollama | ollama.com | Free (runs locally) |
git clone https://github.com/EvanProgramming/OpenKyrozen.git
cd OpenKyrozen
# macOS / Linux
make install
make run
# Windows
setup.bat
run.batgit clone https://github.com/EvanProgramming/OpenKyrozen.git
cd OpenKyrozen
pip install .
# Then run anywhere:
kyrozen # terminal agent
kyrozen-web # web serverNote:
pip install openkyrozenfrom PyPI is coming soon. For now, install from the local directory or clone the repo.
On first launch, you'll be prompted for an API key. The agent auto-detects your provider and saves the encrypted key to ~/.kyrozen_config.json.
Once launched, you'll see the banner and a You: prompt. Type naturally — the agent understands plain English (and Chinese, Japanese, Korean).
You: read the README and tell me what this project does
You: create a new Python file called hello.py that prints "Hello World"
You: search the web for the latest Python release date
You: fix the bug in main.py around line 200
You: commit all changes with a good message
Kyrozen will:
- Classify your request (simple / medium / complex)
- Choose the best model for the job
- Create a plan if needed
- Execute tools step by step
- Show progress in a live task panel
- Summarize what was done
| Command | What it does |
|---|---|
/quit or /exit |
Exit the agent |
/provider |
Switch to a different LLM provider (interactive menu) |
/api_key |
Change your API key |
/learn |
Immediately scan project files into memory |
/forget |
Show recent learnings; /forget keyword to delete bad learnings |
/update |
Pull the latest version from git |
/self-learning |
Toggle individual self-learning features on/off |
python server.py --port 8000
# Open http://localhost:8000
# For LAN or container access, set a token and bind explicitly:
KYROZEN_SERVER_TOKEN=change-me python server.py --host 0.0.0.0 --port 8000
# Or via Docker:
docker build -t openkyrozen .
docker run -p 8000:8000 -e DEEPSEEK_API_KEY=sk-... -e KYROZEN_SERVER_TOKEN=change-me openkyrozenThe web interface provides a dark-themed chat UI with real-time streaming, cost tracking, and session management.
User Input
│
▼
┌─────────────────┐
│ Task Classifier │──► simple / medium / complex
└────────┬────────┘
│
▼
┌─────────────────┐
│ Model Selector │──► deepseek-chat / deepseek-reasoner / gpt-4o / claude / gemini / llama
└────────┬────────┘
│
▼
┌─────────────────┐
│ LLM Provider │──► 5 backends with automatic fallback chain
└────────┬────────┘
│ Response + tool calls
▼
┌─────────────────┐
│ Tool Executor │──► 26 built-in tools (file I/O, shell, git, web, memory)
└────────┬────────┘
│ Tool results fed back to LLM
│ (up to 50 tool-call rounds per turn)
▼
┌─────────────────┐
│ Response │──► User sees answer + task summary
└────────┬────────┘
│
▼
┌─────────────────┐
│ Self-Learning │──► Background: extract facts, score memories, build knowledge graph
└─────────────────┘
Kyrozen automatically classifies every request and adapts its behavior:
| Level | Example triggers | Agent behavior |
|---|---|---|
| Simple | "hi", "what is Python", "thanks" | Direct reply, zero planning overhead |
| Medium | "list files and read README" | Creates a numbered Plan, executes tools sequentially |
| Complex | "audit this repo", "fix the bug and commit", "build a web app" | Full Plan → TaskList → progress tracking → never stops early |
The agent picks different models for simple vs complex tasks. You can override these:
export KYROZEN_MODEL_SIMPLE=deepseek-chat
export KYROZEN_MODEL_COMPLEX=deepseek-reasoner| Provider | Simple tasks (default) | Complex tasks (default) |
|---|---|---|
| DeepSeek | deepseek-chat |
deepseek-reasoner |
| OpenAI | gpt-4o |
gpt-4o |
| Anthropic | claude-sonnet-4-20250514 |
claude-sonnet-4-20250514 |
gemini-2.5-flash |
gemini-2.5-pro |
|
| Ollama | llama3.2 |
llama3.2 |
Switch providers anytime — in chat with /provider, or via environment:
export KYROZEN_PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
python main.pyIf the primary provider fails, Kyrozen automatically falls back through a chain (e.g., DeepSeek → OpenAI → Claude). Rate-limit errors (HTTP 429) trigger exponential backoff with jitter.
All 26 tools accept a plain-string args field in a JSON action block:
{"action": "read_file", "args": "README.md"}Short aliases work too — bash, cmd, sh → run_cmd; status, diff, log → git_status, etc.
| Tool | Description | Example |
|---|---|---|
read_file |
Read file contents | "README.md" |
write_file |
Create or overwrite a file | "path|content" |
list_dir |
List directory contents | "." |
list_tree |
Recursive directory tree | "src/" |
find_files |
Glob-based file search | "*.py|." |
run_cmd |
Execute shell command | "python --version" |
| Tool | Description | Example |
|---|---|---|
search_web |
Internet search (Google → DDG → Wikipedia) | "latest Python release" |
read_webpage |
Fetch URL text content | "https://example.com" |
| Tool | What it does |
|---|---|
git_status |
Show working tree status |
git_diff |
Unstaged / staged / between-commit diffs |
git_log |
Commit history (--oneline --decorate) |
git_branch |
List / create / delete branches |
git_add |
Stage files for commit |
git_commit |
Commit with message |
git_push / git_pull |
Remote sync |
git_checkout |
Switch branches or restore files |
git_stash |
Stash / pop / list working changes |
git_reset |
Reset HEAD (--soft safe, --hard warns) |
git_show |
Inspect a commit with --stat |
git_remote |
List / add / remove remotes |
git_clone |
Clone a repository |
analyze_remote_repo |
Clone + read all files → structured summary |
| Tool | Description |
|---|---|
search_memory |
Semantic search over stored knowledge |
check_stored_data |
Memory statistics and recent facts |
When you paste an error or traceback, Kyrozen activates automatically:
- Reproduce — read the offending code, re-run the failing command
- Diagnose — parse the traceback, identify root cause
- Hypothesise — state the fix before making any changes
- Fix — apply the minimal code change
- Verify — re-run the failing command; loop back to step 2 if it fails
- Explain — tell you what was wrong, what changed, and why
After the fix, Kyrozen tracks the outcome. If you say "thanks, that works" it records a success. If you say "still broken" it records a failure and triggers deeper analysis.
- Always runs
git_statusfirst - Reviews
git_diffbefore committing - Uses conventional commit prefixes:
fix:,feat:,refactor:,chore: - Never force-pushes without explicit request
- Stashes uncommitted changes before switching branches
- Warns before
git reset --hard
For multi-step work (refactors, project generators, codebase audits):
- Breaks down the request into verifiable subtasks
- Creates a numbered Plan
- Builds a JSON TaskList mapped to each plan step
- Tracks progress with
TaskDonemarkers - Auto-generates a summary when complete
The v2 learning engine is autonomous but evidence-gated. It records observations, creates candidate proposals, checks repeated evidence or validation results, activates a versioned improvement, and records rollback information. Autonomous learning never grants a new permission merely because a memory contains an instruction.
When idle, Kyrozen runs a bounded learning cycle. File scans are incremental, background work has a concurrency limit, and failures are recorded as events instead of being silently discarded. Most features can be toggled on/off with /self-learning.
| # | Feature | What it learns |
|---|---|---|
| 1 | Conversation learning | Extracts facts, preferences, and patterns from chat |
| 2 | Project file scanning | Reads every .py file into memory for context |
| 3 | Stale entry aging | Removes facts about files that no longer exist |
| 4 | Tool auto-debug | Analyzes tool failures, finds root causes |
| 5 | Memory consolidation | Deduplicates and summarizes stored facts |
| 6 | Tool review | Suggests under-used tools for removal |
| 7 | Targeted inquiry | Finds undocumented functions and infers their purpose |
| 8 | Idle reflection | After complex tasks, reflects on what went well |
| 9 | Strategy distillation | When token usage is high, distills efficiency tips |
| 10 | New tech auto-patch | Queries the web when you mention unknown libraries |
| 11 | Skill invention | Creates reusable skill templates from past successes |
| 12 | Context compression | Summarizes old turns when context exceeds 30K chars |
| 13 | Fix verification | Tracks bug-fix success rate over time |
| 14 | Dynamic tool creation | DefineTool: syntax lets the agent build new tools |
| 15 | User preference model | Detects your coding style, preferred language, verbosity |
| 16 | Autonomous inspection | Checks for outdated packages, code smells, gitignore gaps |
| 17 | Memory importance scoring | Rates entries 0-10; high-score entries get priority |
| 18 | Knowledge graph | Builds entity→relationship maps from stored facts |
| 19 | Skill composition | Chains multiple learned skills into workflows |
| 20 | Bad learning rollback | /forget command to remove incorrect learnings |
OpenKyrozen v2 uses SQLite as the source of truth (~/.kyrozen/v2/openkyrozen.sqlite3) and ChromaDB as a rebuildable semantic index. Memories have a kind, scope, confidence, source events, and lifecycle status. Workspaces and sessions are isolated, raw observations are marked as data, and /forget removes records by durable ID. If ChromaDB is unavailable, SQLite keeps durable keyword retrieval.
Import an existing v1 store without deleting it:
python main.py migrate v1 ./chroma_memoryThe migration creates a .v1-backup copy and writes the v2 database under ~/.kyrozen/v2/ (or KYROZEN_DB_PATH).
Tasks persist across process restarts and use pending, running, succeeded, failed, blocked, and cancelled states. TaskDone is only a completion request; a successful tool result, test, file check, or explicit confirmation must provide evidence before a task can succeed.
Learning proposals are visible with /learning status, explainable with /learning explain <proposal_id>, and reversible with /learning rollback <proposal_id>.
pip install fastapi uvicorn
python server.py --port 8000
# Open http://localhost:8000
# For LAN or container access, set a token and bind explicitly:
KYROZEN_SERVER_TOKEN=change-me python server.py --host 0.0.0.0 --port 8000| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Dark-themed chat web UI |
POST |
/api/chat |
Send a message, get JSON response |
POST |
/api/chat/stream |
SSE streaming chat |
GET |
/api/memory?q=keyword |
Search stored memories |
GET |
/api/v2/memory?q=keyword |
Structured memory search with provenance and scope |
GET/POST |
/api/v2/tasks |
Durable task listing and creation |
GET |
/api/v2/learning |
Learning proposal status |
POST |
/api/v2/learning/{id}/rollback |
Roll back an activated proposal |
GET |
/api/v2/events |
Auditable runtime, task, session, and learning events |
GET/POST |
/api/v2/schedules |
Durable interval and one-shot Gateway jobs |
POST |
/api/v2/schedules/{id}/disable |
Disable a scheduled job |
GET |
/api/v2/skills |
List installed candidate/active skills |
POST |
/api/v2/skills/install |
Install and validate a local SKILL.md package |
POST |
/api/v2/skills/{id}/activate |
Activate a validated skill |
POST |
/api/v2/skills/{id}/rollback |
Roll back a skill |
GET |
/api/v2/sessions |
List durable sessions |
GET |
/api/v2/sessions/{id} |
Resume/read a session context |
GET |
/api/v2/agents |
List specialised sub-agent profiles |
POST |
/api/v2/agents/run |
Run a sub-agent with isolated memory and capabilities |
Browser tools (browser_open, browser_snapshot, browser_click, browser_type, and
browser_close) use an isolated profile and are available after
pip install 'openkyrozen[browser]' && playwright install chromium. Private and
loopback destinations are blocked unless KYROZEN_BROWSER_ALLOW_PRIVATE=1 is set.
| GET | /api/cost | Token usage and cost summary |
| GET | /api/health | Provider status + memory count |
| GET | /api/voice/speak?text=... | Text-to-speech via system TTS |
| POST | /api/voice/transcribe | Speech-to-text (passthrough) |
| POST | /api/webhooks/register | Register a webhook URL |
| GET | /api/webhooks | List registered webhooks |
| POST | /api/webhooks/test | Fire a test webhook |
| POST | /mcp | Model Context Protocol (JSON-RPC 2.0) |
API and MCP routes allow direct loopback access without a token. Any
non-loopback deployment must set KYROZEN_SERVER_TOKEN and send it as
Authorization: Bearer <token> or X-Kyrozen-Token. Web/MCP use the rich
workspace profile by default; choose full explicitly for irreversible reset
and dynamic tools. Authentication, capability tokens, and command safety checks
still apply.
docker build -t openkyrozen .
docker run -p 8000:8000 \
-e DEEPSEEK_API_KEY=sk-your-key \
-e KYROZEN_SERVER_TOKEN=change-me \
-v kyrozen-data:/root/.kyrozen/v2 \
openkyrozenCreate a .py file in plugins/ with a register() function:
# plugins/my_plugin.py
class MyPlugin:
def on_startup(self, agent=None, **kwargs):
print("Plugin loaded!")
def on_turn_start(self, user_input, **kwargs):
print(f"User said: {user_input[:50]}")
def on_tool_execute(self, action, args, result, **kwargs):
print(f"Tool {action}({args[:30]}) → {result[:30]}")
def register():
return MyPlugin()Available hooks: on_startup, on_turn_start, on_turn_end, on_tool_execute.
See plugins/turn_logger.py for a working example.
| Feature | What it protects |
|---|---|
| Dangerous command filter | Blocks rm -rf, mkfs, fork bombs, Windows destructive commands |
| API key encryption | Fernet encryption with a random per-install secret; config and secret files use 0600 permissions |
| Prompt injection protection | Filters known patterns in CLI, API, and MCP messages |
| Workspace boundary | File and directory tools reject paths outside the active workspace |
| API authentication | Non-loopback API/MCP access requires KYROZEN_SERVER_TOKEN |
| Capability profiles | Local CLI keeps the full agent toolset; Web/MCP default to rich workspace access, while full explicitly enables irreversible Git reset and dynamic tools |
| Git safety | Never force-pushes; CLI confirms high-impact Git actions and records the decision |
| Audit logging | All chat/API events logged to kyrozen_audit.log with timestamps |
| Python version guard | Refuses to start on Python 3.14+ |
| Tool failure memory | Remembers past failures and avoids repeating them |
| Variable | Description | Default |
|---|---|---|
KYROZEN_PROVIDER |
LLM provider | deepseek |
DEEPSEEK_API_KEY |
DeepSeek API key | — |
OPENAI_API_KEY |
OpenAI API key | — |
ANTHROPIC_API_KEY |
Anthropic API key | — |
GEMINI_API_KEY |
Google Gemini API key | — |
KYROZEN_API_KEY |
Universal API key (overrides provider-specific) | — |
KYROZEN_MODEL_SIMPLE |
Model for simple/medium tasks | Provider default |
KYROZEN_MODEL_COMPLEX |
Model for complex tasks | Provider default |
KYROZEN_BASE_URL |
Custom API base URL | Provider default |
KYROZEN_EXECUTION_SURFACE |
Execution surface (cli or web) |
cli |
KYROZEN_ALLOW_DYNAMIC_TOOLS |
Allow LLM-generated Python tools (1/true) |
CLI: enabled; Web/MCP: disabled |
KYROZEN_APPROVAL_MODE |
CLI confirmation mode for high-impact Git actions (dangerous/never) |
dangerous |
KYROZEN_WEB_CAPABILITIES |
Web chat capabilities: readonly, workspace, or full |
workspace |
KYROZEN_MCP_CAPABILITIES |
MCP capabilities: readonly, workspace, or full |
workspace |
The local CLI is intentionally a high-permission agent, similar to Codex or OpenClaw: it can read and write the active workspace, run shell commands, use the network, and operate Git. The Web and MCP surfaces expose the same rich workspace profile by default, but keep irreversible git_reset and LLM-generated Python tools behind the explicit full/KYROZEN_ALLOW_DYNAMIC_TOOLS=1 opt-in. Authentication and the command safety filter still apply.
{
"provider": "deepseek",
"api_key": "<encrypted>",
"model_simple": "deepseek-chat",
"model_complex": "deepseek-reasoner",
"encrypted": true,
"encryption": "fernet"
}The file is auto-managed. Use /provider or /api_key in-chat to update it interactively.
# Quick verification
make check
# Syntax lint only
make lint
# Debug mode (format-error traps)
make debug
# First-time API key setup
make init
# Rebuild venv after Python version change
make reinstall
# Launch web server
make web
# Git helpers
make git-status
make git-log
make commit msg='feat: description'
make pushGitHub Actions automatically runs on every push and PR:
- Syntax check across Python 3.12 and 3.13
- Tool inventory validation
- Provider import check
- Docker build verification
# Install from local directory (PyPI publishing coming soon)
pip install . # core + CLI
pip install .[web] # + web UI
pip install .[all] # + Claude + Gemini + webOpenKyrozen/
├── main.py # Core agent loop, self-learning, chat turn logic
├── tools.py # 26 built-in tools (file, shell, git, web)
├── providers.py # Multi-LLM abstraction (5 providers + fallback)
├── memory.py # ChromaDB-backed vector memory
├── server.py # FastAPI web server + REST API + chat UI
├── pyproject.toml # pip package configuration
├── Dockerfile # Docker image definition
├── Makefile # Build automation (macOS/Linux)
├── setup.bat / run.bat # Windows batch scripts
├── plugins/ # Plugin directory (hook-based)
├── prompts/ # Prompt templates (role, instructions, examples)
├── chroma_memory/ # ChromaDB persistent storage (auto-created)
└── .github/workflows/ # CI/CD pipeline
OpenKyrozen is built on top of incredible open-source work. We're grateful to every maintainer and contributor who made these projects possible.
| Project | Repo | What we use it for |
|---|---|---|
| Aider | paul-gauthier/aider | Inspired our multi-turn agent loop, tool-calling patterns, and git-safety conventions |
| CodeWhale | deepseek-ai/codewhale | Agent runtime architecture, sub-agent delegation, and verification discipline |
| Chroma | chroma-core/chroma | Vector database powering our long-term memory and semantic recall |
| FastAPI | fastapi/fastapi | Web server, REST API, and real-time streaming endpoints |
| Rich | Textualize/rich | Terminal UI — panels, progress bars, syntax highlighting, and live displays |
| OpenAI Python | openai/openai-python | Unified API client for DeepSeek, OpenAI, and Ollama providers |
| Uvicorn | encode/uvicorn | ASGI server for production web deployments |
| googlesearch-python | Nv7-GitHub/googlesearch | Web search fallback when DuckDuckGo is unavailable |
"If I have seen further, it is by standing on the shoulders of giants." — Isaac Newton
MIT License. See LICENSE for details.
Built with ❤️ for developers who want an AI that learns