Skip to content

Commit 91652a0

Browse files
feat: add durable v2 memory learning and tasks
1 parent 831a732 commit 91652a0

12 files changed

Lines changed: 1311 additions & 372 deletions

Makefile

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Use a known-stable Python version (3.14 has import deadlocks with openai)
44
PYTHON := python3.12
5+
VENV_PYTHON := $(if $(wildcard venv/bin/python),./venv/bin/python,$(PYTHON))
56

67
# Detect Windows (native cmd) and redirect to .bat files
78
ifeq ($(OS),Windows_NT)
@@ -18,11 +19,11 @@ install:
1819

1920
run:
2021
@command -v $(PYTHON) >/dev/null 2>&1 || { echo "Error: venv requires $(PYTHON). Run 'make install' with $(PYTHON) installed."; exit 1; }
21-
. venv/bin/activate && python main.py
22+
$(VENV_PYTHON) main.py
2223

2324
web:
2425
@command -v $(PYTHON) >/dev/null 2>&1 || { echo "Error: venv requires $(PYTHON)."; exit 1; }
25-
. venv/bin/activate && pip install fastapi uvicorn -q && python server.py
26+
$(VENV_PYTHON) -m pip install fastapi uvicorn -q && $(VENV_PYTHON) server.py
2627

2728
debug:
2829
@command -v $(PYTHON) >/dev/null 2>&1 || { echo "Error: venv requires $(PYTHON). Run 'make install' first."; exit 1; }
@@ -44,23 +45,21 @@ clean:
4445

4546
# Syntax check
4647
lint:
47-
. venv/bin/activate && python -c "compile(open('main.py').read(), 'main.py', 'exec'); print('main.py OK')"
48-
. venv/bin/activate && python -c "compile(open('tools.py').read(), 'tools.py', 'exec'); print('tools.py OK')"
49-
. venv/bin/activate && python -c "compile(open('memory.py').read(), 'memory.py', 'exec'); print('memory.py OK')"
48+
$(VENV_PYTHON) -m compileall -q main.py server.py tools.py memory.py event_store.py task_engine.py learning_engine.py migration.py
49+
@echo "Python syntax OK."
5050
@echo "All files pass syntax check."
5151

5252
# Unit tests
5353
test:
54-
. venv/bin/activate && pip install fastapi uvicorn -q && python -m unittest discover -s tests -p 'test_*.py' -v
54+
$(VENV_PYTHON) -m unittest discover -s tests -p 'test_*.py' -v
5555

5656
# Quick verification
5757
check:
5858
@echo "Checking Python syntax..."
59-
@./venv/bin/python -c "compile(open('main.py').read(), 'main.py', 'exec'); print(' main.py: OK')"
60-
@./venv/bin/python -c "compile(open('tools.py').read(), 'tools.py', 'exec'); print(' tools.py: OK')"
61-
@./venv/bin/python -c "compile(open('memory.py').read(), 'memory.py', 'exec'); print(' memory.py: OK')"
59+
@$(VENV_PYTHON) -m py_compile main.py server.py tools.py memory.py event_store.py task_engine.py learning_engine.py migration.py
60+
@echo " Python modules: OK"
6261
@echo "Checking git tools..."
63-
@./venv/bin/python -c "from tools import AVAILABLE_TOOLS; git = [k for k in AVAILABLE_TOOLS if k.startswith('git_')]; print(f' {len(git)} git tools, {len(AVAILABLE_TOOLS)} total tools')"
62+
@$(VENV_PYTHON) -c "from tools import AVAILABLE_TOOLS; git = [k for k in AVAILABLE_TOOLS if k.startswith('git_')]; print(f' {len(git)} git tools, {len(AVAILABLE_TOOLS)} total tools')"
6463
@echo "All checks passed."
6564

6665
# Git helpers

README.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
OpenKyrozen is a **self-learning AI agent** that runs in your terminal. Unlike a typical chatbot, it:
6161

6262
- **Uses 26 built-in tools** — read/write files, execute shell commands, search the web, manage git repositories
63-
- **Learns continuously**20 self-learning features run in the background, extracting facts, inventing skills, and improving strategies
63+
- **Learns continuously**background learning creates evidence-backed proposals and only promotes repeated or validated improvements
6464
- **Works with any LLM** — DeepSeek, OpenAI, Claude, Gemini, or local Ollama models
6565
- **Runs on any OS** — macOS, Linux, and Windows (with automatic terminal capability detection)
6666
- **Has a Web UI** — browser-based chat interface with REST API for integration
@@ -341,11 +341,11 @@ For multi-step work (refactors, project generators, codebase audits):
341341

342342
## 🧬 Self-Learning System
343343

344-
This is what makes Kyrozen different. **20 self-learning features** run continuously in the background — no manual saving needed. The agent gets smarter the longer you use it.
344+
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.
345345

346346
### How it works
347347

348-
Every 30 seconds (when you're idle), Kyrozen runs a learning cycle. Most features can be toggled on/off with `/self-learning`; the remaining nine run automatically in the background.
348+
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`.
349349

350350
| # | Feature | What it learns |
351351
|---|---------|---------------|
@@ -372,7 +372,21 @@ Every 30 seconds (when you're idle), Kyrozen runs a learning cycle. Most feature
372372

373373
### Memory storage
374374

375-
Long-term memory uses **ChromaDB** (vector database, stored in `chroma_memory/`). Falls back to in-memory storage if ChromaDB is unavailable. Memories are semantically searchable — the agent can recall relevant facts from weeks ago.
375+
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.
376+
377+
Import an existing v1 store without deleting it:
378+
379+
```bash
380+
python main.py migrate v1 ./chroma_memory
381+
```
382+
383+
The migration creates a `.v1-backup` copy and writes the v2 database under `~/.kyrozen/v2/` (or `KYROZEN_DB_PATH`).
384+
385+
### v2 durable tasks and learning
386+
387+
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.
388+
389+
Learning proposals are visible with `/learning status`, explainable with `/learning explain <proposal_id>`, and reversible with `/learning rollback <proposal_id>`.
376390

377391
---
378392

@@ -395,6 +409,11 @@ KYROZEN_SERVER_TOKEN=change-me python server.py --host 0.0.0.0 --port 8000
395409
| `POST` | `/api/chat` | Send a message, get JSON response |
396410
| `POST` | `/api/chat/stream` | SSE streaming chat |
397411
| `GET` | `/api/memory?q=keyword` | Search stored memories |
412+
| `GET` | `/api/v2/memory?q=keyword` | Structured memory search with provenance and scope |
413+
| `GET/POST` | `/api/v2/tasks` | Durable task listing and creation |
414+
| `GET` | `/api/v2/learning` | Learning proposal status |
415+
| `POST` | `/api/v2/learning/{id}/rollback` | Roll back an activated proposal |
416+
| `GET` | `/api/v2/events` | Auditable runtime, task, session, and learning events |
398417
| `GET` | `/api/cost` | Token usage and cost summary |
399418
| `GET` | `/api/health` | Provider status + memory count |
400419
| `GET` | `/api/voice/speak?text=...` | Text-to-speech via system TTS |

README.zh-CN.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,11 @@ python main.py
341341

342342
## 🧬 自学习系统
343343

344-
这是 Kyrozen 与众不同的地方。**20 项自学习功能**在后台持续运行——无需手动保存。使用时间越长,智能体就越聪明
344+
这是 Kyrozen 与众不同的地方。v2 的自学习是自动的,但必须经过证据门控:系统先记录观察,再生成候选提案,经过重复证据或验证后才激活,并保留回滚信息。记忆中的文字永远不能自动授予新权限
345345

346346
### 工作原理
347347

348-
每 30 秒(当你空闲时),Kyrozen 运行一个学习周期。大部分功能可以通过 `/self-learning` 开关;其余九项在后台自动运行
348+
空闲时 Kyrozen 运行有界的学习周期。项目扫描采用增量方式,后台任务有并发限制,失败会记录为事件而不会静默丢弃。大部分功能可以通过 `/self-learning` 开关。
349349

350350
| # | 功能 | 学习内容 |
351351
|---|------|---------|
@@ -372,7 +372,17 @@ python main.py
372372

373373
### 记忆存储
374374

375-
长期记忆使用 **ChromaDB**(向量数据库,存储在 `chroma_memory/`)。如果 ChromaDB 不可用则回退到内存存储。记忆支持语义搜索——智能体可以回忆起几周前的相关事实。
375+
OpenKyrozen v2 使用 **SQLite 作为事实主库**`~/.kyrozen/v2/openkyrozen.sqlite3`),ChromaDB 只作为可重建的语义索引。记忆包含类型、作用域、置信度、来源事件和生命周期状态;workspace 与 session 相互隔离。即使 ChromaDB 不可用,SQLite 仍会提供持久化关键词检索。
376+
377+
导入旧版 Chroma 记忆而不删除原数据:
378+
379+
```bash
380+
python main.py migrate v1 ./chroma_memory
381+
```
382+
383+
该命令会创建 `.v1-backup` 备份,并将 v2 数据写入 `~/.kyrozen/v2/`(也可通过 `KYROZEN_DB_PATH` 指定)。
384+
385+
任务会跨重启保存。`TaskDone` 只是完成请求,只有工具结果、测试、文件检查或明确确认提供证据后,任务才会进入成功状态。可使用 `/learning status``/learning explain <proposal_id>``/learning rollback <proposal_id>` 管理学习提案。
376386

377387
---
378388

@@ -395,6 +405,11 @@ KYROZEN_SERVER_TOKEN=change-me python server.py --host 0.0.0.0 --port 8000
395405
| `POST` | `/api/chat` | 发送消息,获取 JSON 响应 |
396406
| `POST` | `/api/chat/stream` | SSE 流式聊天 |
397407
| `GET` | `/api/memory?q=关键词` | 搜索已存储的记忆 |
408+
| `GET` | `/api/v2/memory?q=关键词` | 返回带来源、置信度和作用域的结构化记忆 |
409+
| `GET/POST` | `/api/v2/tasks` | 持久化任务查询与创建 |
410+
| `GET` | `/api/v2/learning` | 查看学习提案 |
411+
| `POST` | `/api/v2/learning/{id}/rollback` | 回滚已激活的学习提案 |
412+
| `GET` | `/api/v2/events` | 查看运行时、会话、任务和学习审计事件 |
398413
| `GET` | `/api/cost` | Token 用量和费用摘要 |
399414
| `GET` | `/api/health` | 服务商状态 + 记忆计数 |
400415
| `GET` | `/api/voice/speak?text=...` | 通过系统 TTS 进行文本转语音 |
@@ -406,8 +421,8 @@ KYROZEN_SERVER_TOKEN=change-me python server.py --host 0.0.0.0 --port 8000
406421

407422
API 和 MCP 路由在本机回环访问时可以不使用令牌;任何非本机部署都必须
408423
设置 `KYROZEN_SERVER_TOKEN`,并通过 `Authorization: Bearer <token>`
409-
`X-Kyrozen-Token` 发送。MCP 的写文件、Shell、Git 修改和远程克隆工具默认
410-
关闭;只有在可信环境中才应显式设置 `KYROZEN_MCP_ALLOW_DANGEROUS=1`
424+
`X-Kyrozen-Token` 发送。MCP/Web 默认使用 `workspace` 能力,`full` 才会开放
425+
不可逆 Git reset 和动态 Python 工具;高影响 Git 操作仍受确认模式保护
411426

412427
### Docker 部署
413428

0 commit comments

Comments
 (0)