Skip to content

Latest commit

 

History

History
639 lines (494 loc) · 25.7 KB

File metadata and controls

639 lines (494 loc) · 25.7 KB

Python Multi-Provider Platform License CI

✨ OpenKyrozen ✨

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.

🌐 English · 简体中文 · 日本語 · 한국어


📑 Table of Contents


What is OpenKyrozen?

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.


🚀 Installation

Prerequisites

  • 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)

Option A: From source (recommended)

git clone https://github.com/EvanProgramming/OpenKyrozen.git
cd OpenKyrozen

# macOS / Linux
make install
make run

# Windows
setup.bat
run.bat

Option B: pip install from local directory

git clone https://github.com/EvanProgramming/OpenKyrozen.git
cd OpenKyrozen
pip install .

# Then run anywhere:
kyrozen          # terminal agent
kyrozen-web      # web server

Note: pip install openkyrozen from 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.


📖 Usage Guide

Terminal mode

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:

  1. Classify your request (simple / medium / complex)
  2. Choose the best model for the job
  3. Create a plan if needed
  4. Execute tools step by step
  5. Show progress in a live task panel
  6. Summarize what was done

In-chat commands

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

Web UI mode

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 openkyrozen

The web interface provides a dark-themed chat UI with real-time streaming, cost tracking, and session management.


🏗 Architecture

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
└─────────────────┘

Task complexity routing

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

Model auto-selection

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
Google gemini-2.5-flash gemini-2.5-pro
Ollama llama3.2 llama3.2

Provider management

Switch providers anytime — in chat with /provider, or via environment:

export KYROZEN_PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
python main.py

If 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.


🛠 Tools Reference

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, shrun_cmd; status, diff, loggit_status, etc.

File & System

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"

Web

Tool Description Example
search_web Internet search (Google → DDG → Wikipedia) "latest Python release"
read_webpage Fetch URL text content "https://example.com"

Git (15 tools)

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

Memory

Tool Description
search_memory Semantic search over stored knowledge
check_stored_data Memory statistics and recent facts

🧠 Dedicated Workflows

Bug fixing (6-step protocol)

When you paste an error or traceback, Kyrozen activates automatically:

  1. Reproduce — read the offending code, re-run the failing command
  2. Diagnose — parse the traceback, identify root cause
  3. Hypothesise — state the fix before making any changes
  4. Fix — apply the minimal code change
  5. Verify — re-run the failing command; loop back to step 2 if it fails
  6. 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.

Git operations (safety-first)

  • Always runs git_status first
  • Reviews git_diff before 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

Complex tasks (never stops early)

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 TaskDone markers
  • Auto-generates a summary when complete

🧬 Self-Learning System

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.

How it works

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

Memory storage

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_memory

The migration creates a .v1-backup copy and writes the v2 database under ~/.kyrozen/v2/ (or KYROZEN_DB_PATH).

v2 durable tasks and learning

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>.


🌐 Web UI & REST API

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

REST API endpoints

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 deployment

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 \
  openkyrozen

🔌 Plugin System

Create 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.


🔐 Security

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

⚙️ Configuration Reference

Environment variables

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.

Config file (~/.kyrozen_config.json)

{
  "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.


🔧 Development

# 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 push

CI/CD

GitHub 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

pip package

# Install from local directory (PyPI publishing coming soon)
pip install .                   # core + CLI
pip install .[web]              # + web UI
pip install .[all]              # + Claude + Gemini + web

📁 Project structure

OpenKyrozen/
├── 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

🙏 Standing on the Shoulders of Giants

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


📄 License

MIT License. See LICENSE for details.


Built with ❤️ for developers who want an AI that learns