Metadata-Version: 2.5
Name: pygenius-ai
Version: 0.3.17
Summary: Production-grade Python code generation system with AST-aware context, layered defense, and multi-agent orchestration
Project-URL: Homepage, https://github.com/pygenius/pygenius
Project-URL: Repository, https://github.com/pygenius/pygenius
Project-URL: Changelog, https://github.com/pygenius/pygenius/blob/main/CHANGELOG.md
Author: PyGenius Team
License: MIT
License-File: LICENSE
Keywords: agent,ast,code-generation,llm,mcp,multi-agent,python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: chromadb<1,>=0.5
Requires-Dist: click<9,>=8.1
Requires-Dist: docker<8,>=7.0
Requires-Dist: gitpython<4,>=3.1
Requires-Dist: httpx<1,>=0.27
Requires-Dist: opentelemetry-api<2,>=1.25
Requires-Dist: opentelemetry-sdk<2,>=1.25
Requires-Dist: pydantic-settings<3,>=2.3
Requires-Dist: pydantic<3,>=2.7
Requires-Dist: rich<14,>=13.7
Requires-Dist: structlog<25,>=24.2
Requires-Dist: tenacity<9,>=8.3
Provides-Extra: dev
Requires-Dist: mypy<2,>=1.10; extra == 'dev'
Requires-Dist: pip-audit<3,>=2.7; extra == 'dev'
Requires-Dist: pyright<2,>=1.1; extra == 'dev'
Requires-Dist: pytest-asyncio<1,>=0.23; extra == 'dev'
Requires-Dist: pytest-cov<6,>=5.0; extra == 'dev'
Requires-Dist: pytest<9,>=8.2; extra == 'dev'
Requires-Dist: ruff<1,>=0.5; extra == 'dev'
Provides-Extra: vec
Requires-Dist: chromadb<1,>=0.5; extra == 'vec'
Requires-Dist: sentence-transformers<4,>=3.0; extra == 'vec'
Description-Content-Type: text/markdown

# PyGenius

> Production-grade Python code generation system with AST-aware context,
> layered defense, multi-agent orchestration, and pluggable LLM providers.

## 状态

[![Tests](https://img.shields.io/badge/tests-1578%20passed%20(%E2%80%BE3min)-brightgreen)]()
[![Coverage](https://img.shields.io/badge/coverage-99%25-green)]()
[![E2E Score](https://img.shields.io/badge/E2E%20score-100%2F100-brightgreen)]()
[![Ruff](https://img.shields.io/badge/ruff-passing-brightgreen)]()
[![Mypy](https://img.shields.io/badge/mypy-passing%20(52%20files)-brightgreen)]()
[![Python](https://img.shields.io/badge/python-3.12%2B-blue)]()

## 设计原则

1. **AST 先行** — 用 `ast` 模块做精准上下文提取，绝不全文塞入 LLM
2. **分层防线** — Ruff → pyright → mypy → pytest，快速反馈优先
3. **Plan 驱动** — Python 约定强，先规划再执行
4. **异步感知** — Python 异步生态有坑，记忆必须沉淀经验
5. **沙箱隔离** — 代码执行必须在 Docker 内
6. **版本锁定** — 所有依赖 `==` 指定版本
7. **测试即验证** — Debug 优先跑测试，不靠肉眼看
8. **渐进上下文** — L1 签名 → L2 依赖链 → L3 全文，按需加载
9. **Provider 无关** — LLM 调用走抽象层，OpenAI/DeepSeek/Mock 都能插

## 项目结构

```
pygenius/
├── pyproject.toml                  # 项目配置 + ruff/mypy 规则
├── README.md
├── sandbox/Dockerfile              # Docker 沙箱镜像
├── examples/
│   └── demo_mock.py                # 端到端 demo（无需 API key）
├── src/pygenius/
│   ├── main.py                     # CLI 入口 (click)
│   ├── llm/                        # 🆕 LLM Provider 抽象层
│   │   ├── base.py                 #   LLMProvider 抽象类 + 数据模型
│   │   ├── mock.py                 #   MockLLMProvider（测试用）
│   │   ├── openai_provider.py      #   OpenAI 兼容后端
│   │   └── router.py               #   🆕 LLMRouter 多 provider 路由
│   ├── agents/                     # 多智能体
│   │   ├── base.py                 #   基类
│   │   ├── planner.py              #   Plan-and-Solve 架构师
│   │   ├── coder.py                #   ReAct 码农循环（LLM 驱动）
│   │   └── reviewer.py             #   Reflection 审查专家
│   ├── orchestrator/
│   │   └── orchestrator.py         # 协调器（项目经理）
│   ├── context/                    # AST 上下文
│   │   ├── extractor.py            #   L1/L2/L3 提取 + 缓存
│   │   ├── dependency.py           #   跨模块依赖图
│   │   └── assembler.py            #   上下文组装（预算+降级）
│   ├── memory/                     # 三层记忆
│   │   ├── short_term.py           #   会话记忆 + 反思触发
│   │   ├── long_term.py            #   持久记忆（TTL+冲突）
│   │   └── vector.py               #   向量记忆（ChromaDB）
│   ├── budget/                     # Token 预算
│   │   └── token_budget.py         #   全局+任务+Agent 三层限额
│   ├── events/
│   │   └── event_bus.py            # 事件总线（观察者模式）
│   ├── sandbox/
│   │   └── docker_sandbox.py       # Docker 沙箱
│   ├── tools/                      # 工具链
│   │   ├── file_ops.py             #   文件操作（路径穿越防护）
│   │   ├── command.py              #   命令执行（白名单）
│   │   ├── linter.py               #   ruff→pyright→mypy 分层
│   │   ├── tester.py               #   pytest + coverage
│   │   ├── quality_checker.py      #   AST 代码质量检查 🆕
│   │   ├── package_manager.py      #   pip/uv 安装 + pip-audit
│   │   ├── ast_engine.py           #   AST 分析工具
│   │   ├── git_ops.py              #   Git 操作
│   │   ├── security.py             #   命令分类 + 密钥扫描
│   │   └── registry.py             #   工具注册中心
│   ├── config/settings.py          # pydantic-settings 配置
│   └── models/                     # Pydantic 数据模型
│       ├── messages.py             #   Agent 消息
│       ├── tasks.py                #   任务模型
│       └── context.py              #   上下文模型
└── tests/                          # 1116 个测试
    ├── conftest.py
    ├── test_llm.py                 # 🆕 LLM provider 测试 (18)
    ├── test_coder.py               # 🆕 Coder ReAct 测试 (25)
    ├── test_coder_robustness.py    # 🆕 Coder 鲁棒性测试 (41)
    ├── test_coder_actions.py       # 🆕 Coder 动作执行测试 (15)
    ├── test_reviewer.py            # 🆕 Reviewer 测试 (10)
    ├── test_reviewer_quality.py    # 🆕 Reviewer 质量检查测试 (10)
    ├── test_orchestrator.py        # 🆕 Orchestrator 测试 (9)
    ├── test_orchestrator_edge_cases.py # 🆕 Orchestrator 边界测试 (14)
    ├── test_dependency.py          # 🆕 依赖图测试 (6)
    ├── test_dependency_comprehensive.py # 🆕 依赖图全面测试 (24)
    ├── test_command.py             # 🆕 命令执行测试 (13)
    ├── test_command_edge_cases.py  # 🆕 命令执行边界测试 (7)
    ├── test_linter.py              # 🆕 Linter 测试 (9)
    ├── test_linter_comprehensive.py # 🆕 Linter 解析边界测试 (12)
    ├── test_linter_edge_cases.py   # 🆕 Linter 边界测试 (5)
    ├── test_linter_fallback.py     # 🆕 Linter fallback 测试 (3)
    ├── test_linter_resolution.py   # 🆕 Linter 命令解析测试 (12)
    ├── test_tester.py              # 🆕 TestRunner 测试 (7)
    ├── test_tester_comprehensive.py # 🆕 TestRunner 全面测试 (8)
    ├── test_config.py              # 🆕 配置测试 (8)
    ├── test_ast_engine.py          # AST 引擎 (10)
    ├── test_ast_engine_comprehensive.py # 🆕 AST 引擎异常测试 (13)
    ├── test_ast_engine_edge_cases.py # 🆕 AST 引擎边界测试 (2)
    ├── test_context.py             # 上下文组装 (5)
    ├── test_assembler_comprehensive.py # 🆕 上下文组装全面测试 (19)
    ├── test_context_comprehensive.py # 🆕 上下文模块全面测试 (36)
    ├── test_tools.py               # 文件/安全 (15)
    ├── test_file_ops_comprehensive.py # 🆕 文件操作全面测试 (10)
    ├── test_memory.py              # 记忆系统 (12)
    ├── test_short_term_comprehensive.py # 🆕 STM 全面测试 (11)
    ├── test_long_term_comprehensive.py # 🆕 LTM 全面测试 (63，含去重/衰减/压实)
    ├── test_budget.py              # Token 预算 (7)
    ├── test_agents.py              # Planner/Plan (8)
    ├── test_base_agent.py          # 🆕 BaseAgent 基础设施测试 (11)
    ├── test_planner_comprehensive.py # 🆕 Planner 全面测试 (52)
    ├── test_events.py              # 事件总线 (5)
    ├── test_quality_checker.py     # 🆕 代码质量检查测试 (24)
    ├── test_codegen_mock_expansion.py # 🆕 多项目类型测试 (26)
    ├── test_main_helpers.py        # 🆕 CLI helper 全面测试 (27)
    ├── test_llm_base_helpers.py    # 🆕 LLM base + FakeClock 测试 (6)
    ├── test_llm_mock_extras.py     # 🆕 MockLLMProvider 扩展测试 (3)
    ├── test_vector_memory.py       # 🆕 向量记忆测试 (19)
    ├── test_openai_provider_extras.py # 🆕 OpenAI provider retry+embed 测试 (12)
    ├── test_git_ops_safety.py      # 🆕 Git hard_reset 安全测试 (3)
    ├── test_quality_checker_edge_cases.py # 🆕 质量检查边界测试 (6)
    ├── test_docker_sandbox_mocked.py # 🆕 Docker sandbox mock 测试 (25)
    ├── test_assembler_edge_cases.py # 🆕 上下文组装边界测试 (7)
    ├── test_command_docker_mocked.py # 🆕 Command Docker mock 测试 (10)
    ├── test_coder_parse_edge_cases.py # 🆕 Coder 解析边界测试 (9)
    ├── test_multi_turn_interaction.py # 🆕 多轮交互端到端测试 (5)
    ├── test_cli_callback_interaction.py # 🆕 CLI 回调交互测试 (7)
    ├── test_orchestrator_multi_turn.py # 🆕 Orchestrator 多轮路径测试 (4)
    ├── test_main_verbose.py           # 🆕 CLI verbose traceback 测试 (7)
    ├── test_parallelism_report.py     # 🆕 冲突可视化报告测试 (27)
    ├── test_ltm_maintenance.py        # 🆕 LTM 自动维护钩子测试 (17)
    ├── test_ltm_maintenance_surface.py # 🆕 LTM 维护表面接线测试 (19)
    ├── test_packaging.py              # 🆕 打包发布测试 (12)
    ├── test_assembler_remaining.py    # 🆕 上下文组装剩余分支测试 (2)
    ├── test_tool_calling.py           # 🆕 原生 tool calling 测试 (30)
    ├── test_openai_streaming.py       # 🆕 OpenAI streaming SSE 测试 (7)
    ├── test_openai_provider.py        # 🆕 OpenAI chat/embed/retry 测试 (30)
    ├── test_search_replace.py          # 🆕 search_replace 工具测试 (19)
    └── test_web_ops.py                # 🆕 web_search/fetch_url 工具测试 (37)
```

## 快速开始

### 运行测试

```bash
# 安装
python -m venv .venv
.venv/bin/pip install -e ".[dev]"

# 跑测试
.venv/bin/python -m pytest tests/ -v

# 跑覆盖率
.venv/bin/python -m pytest tests/ --cov=pygenius --cov-report=term

# 代码检查
.venv/bin/ruff check src/ tests/
.venv/bin/ruff format src/ tests/
```

### 端到端 Demo

```bash
# 无需 API key — 用 MockLLMProvider 跑通完整流程
.venv/bin/python examples/demo_mock.py
```

输出示例：
```
📋 === Step 1: Planning ===
   Project: user
   Tech stack: {'framework': 'FastAPI', 'database': 'PostgreSQL'}
   Subtasks: 7

🔧 === Step 2: Execute T1 (Initialize project) ===
   Status: completed
   Iterations: 2
   ✅ Created: pyproject.toml

🔍 === Step 3: Review ===
   Approved: True ✅
   Score: 100.0

📊 === Step 4: Final Status ===
   Tokens used: 14,424 / 500,000
   LLM calls: 3
   ReAct steps: 2
```

### 接入真实 LLM

```python
from pygenius.llm.openai_provider import OpenAICompatibleProvider
from pygenius.orchestrator.orchestrator import Orchestrator
import os

# DeepSeek
provider = OpenAICompatibleProvider(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com/v1",
    default_model="deepseek-chat",
)

orch = Orchestrator(project_dir="./my_project", llm=provider)
result = orch.execute("Create a FastAPI REST API for a todo app")
```

## LLM Provider 抽象

所有 Agent 通过 `LLMProvider` 接口调用 LLM，可插拔：

| Provider | 用途 | 网络 |
|---|---|---|
| `MockLLMProvider` | 测试、demo、CI | 否 |
| `OpenAICompatibleProvider` | 生产环境（OpenAI / DeepSeek / Together / vLLM / Ollama） | 是 |
| `LLMRouter` | 🆕 多 provider 路由 + 自动 fallback + 成本统计 | 取决于子 provider |

Mock provider 支持：
- **Scripted** — 按顺序返回预设响应
- **Rule-based** — 子串匹配返回响应
- **Regex** — 正则匹配返回响应
- **fail_after** — N 次后失败（重试测试）
- **call_log** — 完整调用记录（断言用）

### LLMRouter 多 provider 路由

按任务复杂度自动分流到不同模型，降低成本同时维持质量：

```python
from pygenius.llm import LLMRouter, OpenAICompatibleProvider

strong = OpenAICompatibleProvider(default_model="gpt-4o")          # 规划/重构
balanced = OpenAICompatibleProvider(default_model="gpt-4o-mini")  # 日常编码
fast = OpenAICompatibleProvider(default_model="gpt-4o-nano")     # 简单编辑

router = LLMRouter(
    strong=strong,
    balanced=balanced,
    fast=fast,
    enable_fallback=True,  # 主 provider 失败自动切换
)

orch = Orchestrator(project_dir="./my_project", llm=router)
```

路由策略（基于关键词分类复杂度）：
- **high**（architect/design/refactor/security/performance/...）→ strong
- **medium**（默认编码任务）→ balanced
- **low**（rename/typo/format/comment/...）→ fast
- **tool calling** → 必须用 strong/balanced（fast 不支持）

特性：
- 自动 fallback：primary 失败 → 备用 provider 接管
- 成本统计：每个 provider 单独累计 calls/failures/tokens
- `route()` 方法可预测路由决策（不调用 LLM）
- 透明：实现 `LLMProvider` 接口，agents 无感知

## 三层记忆

| 层 | 实现 | 用途 | 持久化 |
|---|---|---|---|
| 短期 | `ShortTermMemory` | 当前会话的 AST 索引、错误日志、连续失败计数 | 否 |
| 长期 | `LongTermMemory` | 跨会话的最佳实践、bug 教训、版本陷阱 | JSON 文件 |
| 向量 | `VectorMemory` | ChromaDB 语义检索历史代码模式 | ChromaDB |

长期记忆的特性：
- TTL 和淘汰机制
- 置信度评分 + **时间衰减**（`decay()`：每闲置一个半衰期置信度减半，低于阈值自动剪枝；human 来源免疫；get/search/合并刷新存活时钟）
- **重复观察自动合并**（`add()` 三级判定：精确重复 → 置信度强化合并；近似重复（Jaccard≥0.8 或包含率≥0.95，标点/大小写不敏感）→ 合并标签并集；version_scope 特化 → 旧条目弃用+新条目插入）——不再静默覆盖、不再堆积近似重复
- `merge_duplicates()`：存量库一次性压实（旧格式数据迁移）
- 版本范围限定
- 冲突检测（新条目自动 deprecate 旧条目）

## Token 预算

防止失控烧钱：
- 全局预算上限（默认 50 万 token）
- 单任务上限（默认 5 万）
- 单 Agent 上限（默认 20 万）
- 按 task/agent/model 多维度追踪

## Coder ReAct 引擎

Coder 是核心代码生成 agent，使用 ReAct 范式（Thought → Action → Observation 循环）：

**可用 Actions**：
- `write_file` — 创建/覆盖文件，写完自动跑 ruff format
- `edit_file` — 精确替换文件中的文本片段
- `read_file` — 读取已有文件内容（LLM 可主动探索项目）
- `list_dir` — 列出目录内容（LLM 可了解项目结构）
- `run_linter` — 调用 ruff / pyright / mypy 检查代码
- `run_tests` — 运行 pytest 并解析结果
- `ask_user` — LLM 在遇到歧义时主动向用户提问
- `done` — 声明任务完成

**健壮性设计**：
- **格式容错解析**：支持 ```json 代码块包裹、大小写混用、非标准 JSON 的 lenient fallback
- **重试机制**：LLM 返回不可解析时，最多重试 2 次，附带修正提示
- **自动格式化**：写完 `.py` 文件后自动跑 `ruff format`，保证代码风格一致
- **Python 最佳实践内置**：SYSTEM_PROMPT 包含 PEP 484/257、pathlib、async、pydantic 等规范
- **丰富 Observation**：每个 action 的返回观察包含文件路径、行数、错误位置等可操作细节
- **LTM Pattern Recall**：每个任务开始前从长期记忆查询相关 pattern，注入 prompt
- **定向测试**：`run_tests` 支持 `file_paths` 参数，只跑特定测试文件
- **🆕 多 tool_calls 串行执行**：当 LLM 一次返回多个 tool_calls（OpenAI/Anthropic 并行 tool use），Coder 串行执行全部调用（避免文件竞态），单 tool_call 走原路径保持向后兼容。任一 call 是 "done" → 立即结束；任一 call 异常 → 累积错误继续执行剩余。
- **🆕 多轮 ReAct messages 累积**：`_react_step_native` 在 task 内持有 `_native_messages` 持久对话，跨迭代累积 assistant/tool 消息。LLM 能看到之前所有 tool_calls 和 observations（含 `tool_call_id` 关联），真正实现多轮对话式 ReAct。task 切换时自动清空。
- **🆕 messages 滑动窗口**：`max_conversation_length` 配置项（默认 50，0=无限）控制 `_native_messages` 长度。超过阈值时丢弃最旧的 (assistant, tool*) 回合，但始终保留 system+user 头部，并维护 OpenAI tool-message 协议不变式（每个 tool message 必须紧跟在带 matching tool_calls 的 assistant 之后）。
- **🆕 文本 ReAct 模式 messages 累积**：`_react_step_text` 也持有 `_text_messages` 持久对话（对齐 native 模式）。LLM 响应后追加 assistant message，action 执行后追加 user message（`Observation: ...`）。文本模式与 native 模式共享 `_trim_messages` 截断逻辑。
- **🆕 自定义 tier 关键词**：`LLMRouter` 接受 `complex_keywords` / `simple_keywords` 参数，让用户根据自己领域（ML、数据工程、DevOps 等）定制路由策略。自定义关键词**替换**默认（非合并）；用 `default_complex_keywords() + (...)` 扩展默认。`classify_complexity` 也接受相同参数作为模块级函数。
- **🆕 复杂度评分可视化**：`LLMRouter.route_explain(messages, tools)` 返回详细路由决策解释，包含 `matched_complex_keywords` / `matched_simple_keywords` / `msg_count` / `has_tools` / `reason`（人类可读字符串）。用于调试为什么某个任务被路由到 strong/balanced/fast，以及优化关键词配置。
- **🆕 Router 健康检查面板**：`LLMRouter.health_report()` 返回所有 provider 的健康状态 + tier + model，包含 `healthy_count` / `all_healthy` / `primary_healthy` 汇总字段。用于一次性诊断 provider 故障和 fallback 状态。
- **🆕 运行时关键词更新**：`LLMRouter.set_complex_keywords()` / `set_simple_keywords()` / `reset_keywords()` 让用户在不重建 router 的情况下动态调整路由关键词。用于 A/B 测试关键词配置或根据实际路由效果优化关键词。
- **🆕 截断时保留摘要消息**：`_trim_messages` 在丢弃旧消息时，自动在 system message 中追加一个 `[Context: N earlier messages were trimmed...]` 摘要说明，让 LLM 知道有历史被丢弃，避免突然失忆。摘要不累积（每次 trim 时先切掉旧摘要再追加新摘要），不新增消息（保持现有 len 和协议不变式）。
- **🆕 ReAct 历史持久化**：`CoderAgent.save_state(path)` / `load_state(path)` 把 `_native_messages` 和 `_text_messages` 序列化为 JSON 文件，支持跨 session 恢复对话状态。基于 pydantic 的 `model_dump()` / `model_validate()`，完整保留 tool_calls、name 等字段。
- **🆕 Router 配置持久化**：`LLMRouter.save_config(path)` / `load_config(path)` 把自定义关键词配置保存为 JSON 文件，支持跨 session 复现路由行为。`None` 关键词（用模块默认）保存为 JSON `null`，加载时恢复为 `None`。用于 A/B 测试配置存档、版本控制关键词配置。
- **🔧 修复 LLMMessage._id 字段**：把 `_id`（单下划线开头，pydantic v2 当作私有字段，不能通过 `__init__`/`model_validate`/`__setattr__` 设置）改为 `tool_call_id`（不带下划线）。修复后 CoderAgent 创建的 tool message 的 `tool_call_id` 能正确设置（不再是 None），`save_state`/`load_state` 也能正确 round-trip。
- **🆕 Orchestrator 状态快照增强**：`get_status()` 方法增强为返回完整的流水线状态快照。原有字段（project_dir / plan_progress / total_iterations / token_budget / stm_snapshot）保持不变，新增 4 个字段：`coder_state`（对话消息计数 + react 历史长度 + max_conversation_length）、`provider_info`（单 provider 显示 name+model，LLMRouter 显示 health_report）、`recent_errors`（最近 3 条 STM 错误）、`reflection_count`（LTM 反射条目数）。用于调试、监控长运行、checkpoint 前状态检查。
- **🆕 Reviewer review 历史与统计**：`ReviewerAgent` 新增 `_review_history` 追踪每次 `review()` 调用的结果摘要（approved / score / findings_count / coverage）。新增 `get_review_stats()` 方法返回聚合统计：`total_reviews`、`approval_rate`、`average_score`、`max_score`/`min_score`、`latest_score`、`average_findings`、`average_coverage`、`score_trend`（时间序列）。用于跟踪质量趋势、对比迭代效果。
- **🆕 Reviewer 历史持久化**：`ReviewerAgent.save_review_history(path)` / `load_review_history(path)` 把 `_review_history` 序列化为 JSON 文件，支持跨 session 恢复质量统计。用于归档 metrics、对比不同分支/运行的质量趋势、在 Reviewer 实例间转移历史。与 Coder 的 `save_state`/`load_state` 模式一致。
- **🆕 Orchestrator 统一 checkpoint/restore**：`Orchestrator.save_checkpoint(path)` / `load_checkpoint(path)` 把整个流水线状态（Coder 对话 + Reviewer 历史 + LLMRouter 配置 + total_iterations）保存为目录，包含 `manifest.json` 记录哪些组件被保存。用于 checkpoint 长运行、跨 session 恢复、在 Orchestrator 实例间转移状态。整合了持久化三件套（Coder save_state + LLMRouter save_config + Reviewer save_review_history）。
- **🆕 Planner plan 历史与统计**：`PlannerAgent` 新增 `_plan_history` 追踪每次 `create_plan()` 调用的结果摘要（project_name / subtask_count / python_version / tech_stack）。新增 `get_plan_stats()` 方法返回聚合统计：`total_plans`、`average_subtask_count`、`latest_project`、`latest_subtask_count`、`python_versions`（版本分布）、`tech_stack_frequency`（技术栈频次）、`subtask_trend`（时间序列）。用于跟踪规划活动、分析技术栈分布。
- **🆕 Planner 历史持久化**：`PlannerAgent.save_plan_history(path)` / `load_plan_history(path)` 把 `_plan_history` 序列化为 JSON 文件，支持跨 session 恢复规划统计。Orchestrator 的 `save_checkpoint`/`load_checkpoint` 已整合 Planner，checkpoint 目录现在包含 `plan_history.json`。持久化五件套完成：Coder + LLMRouter + Reviewer + Planner + Orchestrator 统一 checkpoint。
- **🆕 Orchestrator 自动 checkpoint**：`Orchestrator` 构造器新增 `checkpoint_interval`（默认 0 = 禁用）和 `checkpoint_dir`（默认 `{project_dir}/.checkpoints/`）参数。`execute()` 循环中每隔 N 次迭代自动调用 `save_checkpoint()`，保存到 `checkpoint_{N}/` 目录。checkpoint 失败不会崩溃，emit `auto_checkpoint_failed` 事件。成功时 emit `auto_checkpoint_saved` 事件。用于长运行任务的自动断点恢复。
- **🆕 LTM 自动维护钩子**：`Orchestrator` 构造器新增 `ltm_maintenance_interval`（默认 0 = 禁用，语义同 checkpoint_interval）、`ltm_decay_half_life_days`（默认 30）、`ltm_decay_min_confidence`（默认 0.1）三个参数。`execute()` / `execute_parallel()` 循环中每隔 N 次迭代自动运行 `_maintain_ltm()`——`ltm.decay()`（按 last_used 半衰期衰减 + 低于阈值剪枝）+ `ltm.merge_duplicates()`（存量压实），`_finalize_project()` 收尾时再补一次（捕获编码阶段新增的 reflection，即使 interval 从未对齐）。成功 emit `ltm_maintained`（`{pruned, merged, iteration}`），失败 emit `ltm_maintenance_failed`，永不崩溃主管线。让 LTM 在长运行中自洁，无需人工调用 decay/merge。
- **🆕 LTM 维护全表面接线**：`PyGeniusSettings.ltm_maintenance_interval`（默认 0，支持 env `PYGENIUS_LTM_MAINTENANCE_INTERVAL` / toml 配置）→ CLI `generate --ltm-maintenance-interval N`（显式传参覆盖 settings，未传回落 settings，启用时打印 mode line）→ MCP `generate` 工具 schema 新增 `ltm_maintenance_interval` 参数（per-call 覆盖 `MCPServer(ltm_maintenance_interval=...)` 的 server 级默认，缺省不顶掉 server 默认；非整数/负数返回 text_error）。`pygenius mcp` 启动时把 settings 值传给 MCPServer。第六十三轮的钩子从此从三个用户可达面都能开启。
- **🆕 memory stats 闭环健康度**：`top_recalled` 榜（按 use_count 排序前 5——「真正在用的知识」）+ `never_recalled` 计数（写入了但从未被召回——写读失配指标）；全部 never 时 rich 输出直接警告「recall keywords may mismatch stored content (learning loop idle)」；`--json` 双字段稳定 schema（空库 `[]`/0）。
- **🆕 recurring 教训自修正（闭环反馈环）**：Reviewer 发现的 recurring finding（注入了教训还是犯错）现在会反向降对应教训的置信度——`LTM.record_mismatch()`（-0.1/次，floor 0.1，每 review 每条只降一次，不 bump use_count）+ `lesson_mismatch` 事件（lesson_id / new_confidence）；连续失配把教训压到 0.5 召回线以下，表述失配的教训自然退出召回池，等待更好的 re-reflection 取代。闭环从「观测」走向「自我修正」：写读失配有代价了。**第七十四轮自愈环收口**：失配把教训压过 0.5 召回线时自动触发 `LTM.rewrite_lesson`——旧条目 deprecated（`deprecated_by` 指向后继，与去重链同款语义），后继携带失配谱系（"reworded after N mismatches"）、confidence 0.6（召回线上方的观察窗口）进入下一轮召回池，`lesson_rewritten` 事件可观测；刻意绕过 `add()` 去重（重写是演化替换不是重复）。检测 → 惩罚 → 淘汰 → 重写 → 重试，五步全自动。**第一百一十六轮机器环**：memory_export MCP tool——机器分享循环的出口半边：返回 import 兼容 JSON（正是 memory_import 的输入格式）；report resource 给人读、export tool 给 agent 交换：A export → entries → B import，同 lesson 到达即 reinforce 永不重复；deprecated 血脉不出门、白名单字段、category 排序稳定 diff；只读零写盘。与 88 轮 CLI export --json 同一 export_lessons_json 单一真源。七→八 tools，AI-to-AI 分享循环成完整双向闭环。**第一百一十五轮回环**：memory_import MCP tool——分享循环的摄取半边上 MCP：read report resource → pass entries → import（与 87 轮 CLI 同一 import_lessons 单一真源）；三层去重=reinforce 永不重复；malformed 跳过不致命；dry_run 预览不落盘。六→七 tools，与 memory/report resource 配对成完整闭环。**第一百一十四轮分享环**：pygenius://memory/report 资源——可分享学习循环全报告（统计/账本/谱系/journal 回放）上 MCP；与 CLI 同一渲染单一真源（86 轮 render_memory_export）；只读不写盘，客户端自存；空项目=合法文档。registry 9→10。**第一百一十三轮手术刀**：memory_fix MCP tool——doctor 对的行动半边上 MCP：resource 诊断（108）→ tool 治愈（content-rot 清除+journal；结构问题留手修）；dry_run 不变更；CLI（110）与 MCP 自愈等价。六 tools。**第一百一十二轮回放**：pygenius://memory/events 资源——学习循环审计时间线上 MCP（add/reinforce/mismatch/rewrite/import/deprecate/evict/purge/decay 九类全记）；memory 资源看状态、events 看「怎么到的这」——110 的 lesson_purged 审计有了归处；最新 100 条+by_type 直方图；缺 journal=空流不报错。registry 8→9。**第一百一十一轮孪生**：pygenius checkpoints 命令——106 轮 MCP 资源的 CLI 孪生（反向缺口收口：MCP 有、CLI 无）；扫描逻辑提 Orchestrator.list_checkpoints() 单一真源（CLI --json 与 resource 字节同构）；此前 CLI 问「有哪些检查点」的答案是 ls .checkpoints。**第一百一十轮合环**：memory doctor --fix/--dry-run——检测→诊断→处方→抓药闭环：--fix 清除内容腐烂（空白/双胎输出条目——无可保留故 removal 非 deprecation；engine 层新 purge() API 每删一条 journal lesson_purged 可审计），结构腐烂不动留手修；--dry-run 只报告不变更；修复后 exit code 反映剩余。**第一百零九轮处方**：doctor issues 附机器可读 remediation——engine 层（health_check）每条 issue 增 {action: manual|rewrite, hint}，CLI/MCP/CI 同源路由：内容腐烂（空白/双胎输出）→ memory rewrite，结构腐烂（悬链/孤儿/越界/负数）→ 手改 store；CLI 逐条渲染提示行——自愈闭环缺的另一半。**第一百零八轮体检**：pygenius://memory/doctor 资源——六类结构腐烂检测上 MCP 面（healthy/issue_count/by_check/issues 全量），CLI 退出码门禁映射为 healthy 布尔；stats（账本）+ doctor（审计）CLI 双子星（84 轮起）在 MCP 面对称成双。registry 7→8。**第一百零七轮回路**：resume MCP tool——复活键上 MCP 面（无参取最新/指定 checkpoint、已完成跳过、逐任务 progress 流）；resource 问诊（resumable 字段）+ tool 复活的闭环成对。五 tools。**第一百零六轮问诊**：pygenius://checkpoints 资源升级 resume 元数据——iterations/completed_tasks（manifest）、project_name/tasks_done/total（plan）、resumable 判定（= resume 命令的复活条件）；撕裂 manifest 按字段降级不炸资源——按按钮前先知道哪个键能按。**第一百零五轮复活键**：pygenius resume——引擎早有 resume_from_checkpoint（加载 coder/reviewer/plan 状态续跑 pending 子任务）但零调用方：中断的 generate 留下 checkpoint 却无路可回。现在有按钮：无参取最新 checkpoint_N、路径指定；已完成任务自动跳过；续跑 review 落同一历史流（source=generate，96 轮）——中断的故事一条时间线讲完。**第一百零四轮镜像**：pygenius://reviews + //trends MCP 资源——94-98 轮建的 review 流与聚合视图镜像到 MCP（Claude Desktop 可读）；trends 聚合提 _build_trends_report 单一真源（命令与资源同源，memory stats 同哲学）；registry 5→7。**第一百零三轮收口**：mcp make_orchestrator 两构造点读全局 settings——最后的裸构造消失，101/102/103 三轮接线覆盖全部构造点（CLI 三+mcp 二）：一个 settings 源、一个落点、零劈叉。**第一百零二轮归一**：orchestrator LTM 接线（ltm_storage_path 参数，CLI 传 settings 值）——自定义 PYGENIUS_LONG_TERM_MEMORY_PATH 曾把「流水线落的 store」与「memory 命令读的 store」劈成两个落点，现在一条路径管两端；journal 跟随 store 同根。**第一百零一轮除锈**：vector_memory_path 接线进 Orchestrator（默认巧合→真生效），event_log_path/verbose_events 移除（journal 与 store 同根是设计，非可配路径）——config check 死字段警告清零，声明=事实。**第一百轮对齐**：config check——show 显示真相、check 给真相打分（stream split/orphan root 双 issue 检测 exit 1 可 gate；十进百的审计顺带揪出三个死字段 event_log_path/vector_memory_path/verbose_events——声明却零消费者）。**第九十九轮配置**：config show——生效配置一屏（十组值/env 覆盖来源/路径真解析+存在性），secret 永不打印；顺带修正 docstring 谎报的 pyproject.toml 配置源（从未实现）。**第九十八轮鸟瞰**：pygenius trends——三流（reviews/events/store）聚合一屏决策视图：质量段含半分趋势判定（rising/falling/flat），学习环按事件类型计数，store 快照；--since 双 journal 同窗、--json 全聚合。**第九十七轮过滤**：reviews --since/--source（与 events 同语法，_parse_since 提共享；source 分流单跑审计与流水线终审）。**第九十六轮汇流**：generate 流程的 review（初审+fix 复审）汇入同一 reviews.jsonl，source 标 generate/cli，回放显 gen 标——单一历史流答两个问题（单跑审计多少分/流水线交付了什么）。**第九十五轮败绩**：review_failed 事件——崩掉的 review 也入历史（错误单行化+截断 120）；reviews 失败行内联、均值排除并注明、全败史显示 no completed reviews。0.3.6 三条满。**第九十四轮评审史**：`pygenius reviews`——review 分数从「跑完即弃」变跨 run 历史（.pygenius/reviews.jsonl，与 memory journal 同款 append-only/滚动上限，不同流）；`review` 落盘、`reviews` 回放（均值趋势）；换主题首条（memory 九连终结）。**第九十三轮窗口**：`memory events --since 7d`——时间窗过滤（30m/24h/7d，与 --type/--tail AND 组合）；age 标签成熟化（>2d 显天数、>30d 显日历日期）。0.3.6 首条。**第九十二轮审计**：`memory diff a.json b.json`——对比两份 export 快照（导入前→导入后），+added/-removed/~changed 逐字段前后值（pin 翻转可见）；键=(content,category) 与 import 对账同款——**diff 和 import 对「同一条 lesson」达成一致**。0.3.5 三条满。**第九十一轮详情**：`memory show ID`——全文不截断+全字段+双向 rewrite 血统（search→show→pin/deprecate 闭环）；**档案语义**：看≠用，新 `peek()` 零副作用读（含 deprecated、不动时钟——浏览不污染 use_count/排行榜）。**第九十轮检索**：`memory search` 升级——旧存根变全量契约（--category/--tags/--min-confidence/--limit/--json、id 展示直通 pin、📌 标记）；「search 即 recall」副作用显性化（命中刷 last_used/use_count——decay 生存环由 CLI 驱动）。0.3.5 首条。**第八十九轮钉住**：`memory pin/unpin ID`——人手 decay 豁免（钉住条目 confidence 不衰减不剪枝；journaled；stats/report 可见 📌）；export --json 携带 pinned、import 新条目落地预钉（reinforce 不动本地钉——本地主权）。0.3.4 三条攒满。**第八十八轮机读导出**：`memory export --json`——markdown 报告的机器可读对偶：active-only（deprecated 族谱不出门）+ 字段白名单（usage/mismatch/溯源是进口方自己的事）+ category 排序稳定 diff；`A: export --json → B: import --file` 项目间机器级搬运闭环，自灌 reinforce 永不重复。**第八十七轮导入**：`pygenius memory import --file lessons.json [--dry-run]`——lessons 跨项目可移植的入口半环：每条走 add() 咽喉过三层去重（已存在的 reinforce 不重复；新条盖 `imported` 溯源章；malformed 跳过不致命）；dry-run 预演合并不落盘。与 86 轮 export 合成分享闭环。**第八十六轮导出**：`pygenius memory export [--out FILE] [--stdout]`——学环全量报告（markdown）：账本（stats）+ 体检（doctor）+ 历史（events journal）+ **rewrite 族谱**（root → __rw1 → … 演化链，独家视图）；导出两次 diff 即学环演进；纯读。**第八十五轮回放**：`pygenius memory events [--tail N] [--type X] [--json]`——学习环事件 journal（JSONL 落 store 旁，滚动千行上限）回放：added/reinforced/mismatched/rewritten/deprecated/evicted/decayed/compacted 八类状态转移全程可溯；journal 失败不致命（观测永不打断主环）。**第八十四轮体检**：`pygenius memory doctor [--json]`——六类结构腐烂探测器（悬挂淘汰链/孤儿重写头/置信越界/负失配/空内容/Mock 污染指纹），退出码可做 CI 门禁；核心在 `LongTermMemory.health_check()`（只读）。**第八十一轮手动干预**：`pygenius memory rewrite LESSON_ID [--dry-run] [--finding-type X]`——账本看到失配教训可立即重写（引擎与自动环共享单一真源）；离线降级确定性重写。**第八十一轮防污染**：Mock provider（`MockLLMProvider`/`CodeGenMock`）永不作为反思真源——77 轮离线污染漏洞修复。**第七十八轮账本**：`memory stats` 三表面（CLI rich / `--json` / MCP `pygenius://memory/stats` resource）新增负反馈账本——`mismatched_active`（带失配历史的活跃教训数）+ `total_mismatches`（活跃条目失配信号总量）；deprecated 条目不计（其历史由 successor 继承）。**第七十六轮反思升级**：重写优先走 LLM 反思路径（`ReviewerAgent(llm=...)` 可选注入；有界 prompt——旧表述 + 失配次数 + finding 类型 → 一句可执行的祈使句，max_tokens 120、token 预算记账），LLM 不可用/失败/超预算/输出不可用时自动降级为确定性谱系重写——自愈环从不依赖模型可达；`lesson_rewritten` 事件新增 `rewriter` 字段（"llm" | "deterministic"），successor 的 `source` 记录来源（`llm_reflection` / `re_reflection`）。**第七十七轮接电**：orchestrator 把共享 provider 传给 reviewer、`pygenius review` 子命令与 `generate` 同源构建 provider——反思路径在真实运行中上电（此前只在测试注入 mock 时触发）。
- **🆕 Reviewer 端学习闭环**：`review()` 评审前召回相关 LTM 知识（任务标题/描述为查询，全类目，best-effort 容错）——`ReviewResult.lessons_considered` 暴露本次评审参考过的教训；findings 与历史教训 tags 匹配（反思写入存 `[error_tool, root_cause]`）时标 `recurring: true` + `matched_lesson` 并 emit `ltm_lesson_hit`/`ltm_lessons_recalled` 事件（保守确定性匹配，v1 只标注不改评分——评审吃历史经验，可观测）。
- **🆕 LTM 学习闭环收口**：Coder 任务 prompt 的知识召回从「仅 pattern 类」扩展为**全类目检索**（`bug_lesson` / `best_practice` / `convention` / `gotcha` / `pattern`）——反思写入的失败教训从此回流进后续任务 prompt（同类错误只犯一次）。召回即使用：`search()` 刷新 `use_count`/`last_used`，被频繁召回的知识在 `decay()` 下存活更久（用进废退）。
- **🆕 memory stats / decay / merge 子命令**：`pygenius memory stats`——维护报告（总条数/弃用数、分类分布、平均置信度、陈旧条目数（闲置 >30 天）+ decay 建议提示、store 文件大小；空库优雅降级）；`pygenius memory decay [--half-life-days 30] [--min-confidence 0.1]`——手动衰减（orchestrator 自动钩子的手动孪生；source=human 豁免）；`pygenius memory merge`——手动压实存量近似重复（绕过 add() 写时去重的旧数据）。配套修复：TestMemoryCommands 全类 autouse chdir 隔离——旧测试三年每次全量回归都向 repo 本地运行时库写 `source=cli` 测试条目（LTM 路径 cwd 相对），已隔离并清理历史残留 3 条。
- **🆕 Checkpoint 恢复执行**：`Orchestrator.resume_from_checkpoint(path)` 从 checkpoint 目录恢复全部状态（Coder 对话 + Reviewer 历史 + Planner 历史 + Router 配置 + ProjectPlan + completed_tasks + total_iterations），然后跳过已完成的 subtask，从断点继续执行核心循环。plan 中的 subtask status 标记哪些已完成，`get_next_task()` 自动跳过 COMPLETED 状态的 task。emit `project_resumed` 事件。用于崩溃恢复、跨 session 续运行。核心循环提取为 `_run_execution_loop()` 共享方法，`execute()` 和 `resume_from_checkpoint()` 都调用它。
- **🆕 依赖图并行性分析**：`ProjectPlan.get_parallel_batches(pending_only=False)` 把 subtask 依赖图分解为可并行的"波次"（DAG level structure）——同批次任务相互独立可并发执行。`pending_only=True` 时只分析剩余 PENDING 任务（COMPLETED 依赖视为已满足，语义与 `get_next_task()` 一致）。`Orchestrator.analyze_parallelism(pending_only=False)` 返回完整统计：批次列表、波数（并行深度）、最大批次宽度（最大并行度）、serial/parallel 迭代数、理论加速比（work/span 模型）、不可解析任务（依赖环或未知依赖）。用于评估计划的可并行化程度、发现过度串行化的计划，为后续真正的并行执行打地基。
- **🆕 同波文件冲突守卫**：`ProjectPlan.get_file_conflicts(pending_only=False)` 检测同一波次内多个任务写同一文件（`files_to_create` ∪ `files_to_modify`）的竞态，返回 `{batch_index, file, task_ids}` 列表；跨波共享文件（依赖顺序保证）不算冲突。`get_parallel_batches(conflict_free=True)` 在波次分解基础上做贪心文件认领——同波任务文件不相交，冲突任务推迟到下一波（声明序优先，每波至少放置一个任务，保证终止）。`analyze_parallelism()` 相应扩展 `file_conflicts` / `num_file_conflicts` / `safe_batches` / `safe_num_batches` / `safe_estimated_speedup` 字段：理想加速比 vs 无竞态安全加速比（如 4 任务两对冲突：ideal 4.0x → safe 2.0x）。这是真并行执行的前置守卫。
- **🆕 Wave-based 真并行执行**：`Orchestrator.execute_parallel(requirement, max_workers=4)` 与 `execute()` 同管线（plan → 波次执行 → 评审），但任务按冲突安全波次并发执行——每轮取"依赖就绪 + 互不文件冲突"的 PENDING 任务集（复用 `get_parallel_batches(pending_only=True, conflict_free=True)[0]`），波内用 `ThreadPoolExecutor` 并发、波间串行汇合。并行安全设计：每个并行任务持有独立 `CoderAgent`（独立 ReAct 会话状态，`_make_task_coder()` 工厂复用全部 orchestrator 依赖）；git checkpoint、依赖图更新、completed_tasks 记账、reflection、交互式 retry/skip/abort 决策全部在主线程波汇合后按声明序处理（确定性）；线程崩溃隔离（异常 → task FAILED + `task_thread_error` 事件，波继续）；单任务波 inline 走共享 coder（与串行路径行为一致，零线程开销）。emit `wave_started` / `wave_completed` 事件。串行循环重构共享 `_plan_and_init()` + `_process_task_result()` + `_finalize_project()`，串行/并行行为等价。
- **🆕 CLI 并行集成**：`pygenius generate --parallel/-p [--max-workers N]` 从命令行启用波次并行执行（默认 4 worker，`IntRange(min=1)` 校验）；`pygenius analyze "requirement"` 并行性 dry-run 预览——创建计划后报告任务数/波数/最大波宽、理想 vs 安全加速比（含文件冲突时黄色警告并列出 wave/文件/任务明细）、冲突安全波次表、不可解析任务（依赖环）。用于在真正执行前评估 `--parallel` 是否值得。
- **🆕 MCP 服务器**：`pygenius mcp` 启动 Model Context Protocol stdio 服务器（newline-delimited JSON-RPC 2.0），把 PyGenius 暴露为 MCP 工具供 Claude Desktop 等 MCP 客户端调用。三层设计：`mcp/protocol.py` 纯协议层（解析/校验/响应构建，零 I/O）；`mcp/tools.py` 工具注册表（`plan` / `analyze` / `generate` / `memory_search` 四个工具带 JSON Schema，handler 永不抛异常——失败转 tool-level `isError` 结果；`memory_search` 查询 LTM 教训/pattern，召回即 bump use_count——客户端搜索也在参与「用进废退」）；`mcp/server.py` 服务器核心（`handle_message()` I/O-free 可测 + `serve()` stdio 循环）。协议合规：initialize 握手（capabilities + serverInfo + 协议版本回显）、notifications/initialized 无响应、握手前请求拒绝 `-32002 ServerNotInitialized`、未知方法 `-32601`、坏 JSON `-32700`、工具异常隔离（crash → isError，服务器不死）。CLI 支持 `PYGENIUS_PROJECT_DIR` 环境变量配置项目目录（Claude Desktop 集成友好）。
- **🆕 MCP Resources + Prompts**：MCP 三大能力补齐第二块。**Resources**（`resources/list` + `resources/read`，`pygenius://` URI）——只读暴露项目状态：`pygenius://status`（Python 文件数/git 仓库/checkpoint 数/memory 条目数汇总 JSON）、`pygenius://files`（排除 .git/.venv/__pycache__ 的文件树）、`pygenius://checkpoints`（checkpoint 目录列表 + 各自文件）、`pygenius://memory`（Reviewer 记录的经验教训 JSON）、`pygenius://memory/stats`（学习闭环健康度——top-recalled 榜 + never_recalled 计数 + 类目分布，0.2.1 健康指标的 MCP 订阅视图）。**Prompts**（`prompts/list` + `prompts/get`）——参数化模板引导 LLM 客户端：`generate-project`（requirement 必填 + parallel 可选，指示调用 generate 工具）、`analyze-parallelism`（requirement 必填，指示先分析再决策）、`code-review`（focus 可选，结构化评审指南）。错误处理：未知 URI/prompt 名 → `-32602` 带 `data.known` 提示；必填参数缺失/空白 → `-32602`；handler crash → `-32603` 隔离；`ProtocolError` 扩展 `data` 字段透传结构化错误详情。
- **🆕 MCP Progress 流式 + 动态工具集**：MCP 路线图 Round 3。**进度流**——客户端在 `tools/call` 请求带 `_meta.progressToken`，服务端在 generate 执行期间持续推送 `notifications/progress`（每完成一个任务一条 `done/total` 通知 + 最终 `project completed`），复用 orchestrator event bus 的 coder 级 `task_completed` 事件（串行/并行波次两种模式都精确触发），最终响应正常返回。**动态工具集**——`register_tool()` / `unregister_tool()` 运行时增删工具并广播 `notifications/tools/list_changed`，capabilities 声明 `tools.listChanged: true`；**ping** 方法返回空结果（健康检查）。`handle_message()` 扩展 `notify` 回调参数（I/O-free 核心可测），serve() 把进度通知写往 stdout（先于最终响应）。

## Planner 框架感知

Planner 根据技术栈自动定制子任务：

| 框架 | T5 文件 | T6 测试描述 |
|---|---|---|
| FastAPI | `src/app/main.py` + `routers/` | httpx AsyncClient fixtures |
| Flask | `src/app/__init__.py` | Flask test client |
| Django | `src/app/models.py` + `views.py` | Django test suite |
| 通用 | `src/app/main.py` | pytest 通用 |

所有子任务都包含明确的 acceptance criteria（ruff/mypy/pytest 通过标准）。

## Orchestrator 容错

Orchestrator 管理整个 Plan → Execute → Review 流水线：

- **任务重试**：任务因 `max_iterations` 失败时，自动重试 1 次（清空错误计数），仍失败才标记 FAILED
- **Reflection 处理**：Coder 触发 reflection 时，Reviewer 分析根因，Orchestrator 可回滚到指定 checkpoint 或新增依赖修复任务
- **预算保护**：全局 token 预算耗尽或迭代次数超限时优雅停止
- **Git checkpoint**：每个成功的任务自动创建 git commit，支持 granular rollback
- **进度传递**：每个子任务执行时，前序已完成任务的信息（task_id、文件列表）注入 prompt，避免重复创建文件
- **Reviewer 反馈循环**：Review 失败且用户选择 FIX 时，自动按 finding 分类创建修复任务，执行后重新 Review
- **AST 代码质量检查**：Reviewer 使用 `QualityChecker` 执行 6 项加权评审标准 — 类型完整性、错误处理、资源管理、代码风格、测试覆盖率、安全性 🆕
- **增量依赖图更新**：任务完成后自动将新文件加入 DependencyGraph，后续任务能解析到这些模块的 import
- **Layered Defense 集成**：Coder 在 LLM 发出 "done" 前自动运行分层防御（ruff → format → pyright → mypy → pytest），不通过则阻止完成
- **文件覆盖检测**：write_file 返回 `overwritten` 标志，observation 中显示警告，LLM 知道文件被覆盖

## 人工交互（Human-in-the-Loop）

PyGenius 支持在关键决策点引入人工审批，通过可插拔的 `InteractionCallback` 协议：

**4 个交互点**：
1. **计划审批** — Planner 生成计划后，用户确认后才执行
2. **任务失败** — 用户选择 retry / skip / abort
3. **Review 失败** — 用户选择 fix / accept / abort
4. **LLM 提问** — Coder 的 `ask_user` action，LLM 在遇到歧义时主动提问

**3 种实现**：
| 实现 | 用途 | 行为 |
|---|---|---|
| `AutoApproveCallback` | 测试/CI（默认） | 自动批准一切，重试一次后跳过 |
| `CLICallback` | 终端交互 | rich 渲染 + click 输入 |
| 自定义 | Web/API 集成 | 实现 Protocol 即可 |

**CLI 用法**：
```bash
# 非交互（默认，自动执行）
pygenius generate "Create a FastAPI app"

# 交互模式（人工审批）
pygenius generate "Create a FastAPI app" --interactive
# 或简写
pygenius generate "Create a FastAPI app" -i
```

**代码集成**：
```python
from pygenius.interaction import CLICallback
from pygenius.orchestrator import Orchestrator

orch = Orchestrator(
    project_dir="./my_project",
    llm=llm,
    interaction=CLICallback(),  # 启用交互
)
result = orch.execute("Create a FastAPI app")
```

## 安全

- 命令三档分类：`auto` / `approval` / `deny`
- 路径穿越防护（`file_ops` 校验所有路径）
- 密钥扫描（PASSWORD / API_KEY / PRIVATE_KEY 等模式）
- Docker 沙箱：非 root 用户、网络隔离、内存/CPU/PID 限制、只读文件系统
- ChromaDB 遥测默认关闭

## CLI 用法

```bash
# 初始化项目结构
pygenius init

# 生成项目计划（dry-run，不执行）
pygenius plan "Create a FastAPI user registration system with PostgreSQL"

# 并行性预览（波次 + 加速比 + 文件冲突，不执行）
pygenius analyze "Create a FastAPI user registration system with PostgreSQL"

# 同上，但输出机器可读 JSON（CI / jq 友好）
pygenius analyze --json "Create a FastAPI user registration system" | jq .estimated_speedup

# 冲突可视化报告：任务清单/波次布局/C-M 冲突矩阵/延迟代价（含传递性）/建议，落盘 Markdown
pygenius analyze "Create a FastAPI todo app" --report parallelism-report.md

# 并行波次执行（冲突安全，任务并发）
pygenius --mock generate --parallel "Create a simple Python CLI tool"
pygenius --mock generate -p --max-workers 8 "Create a simple Python CLI tool"

# MCP 服务器（Claude Desktop 等客户端通过 stdio 调用）
pygenius mcp --project-dir /path/to/projects
# Claude Desktop 配置（claude_desktop_config.json）：
# {"mcpServers": {"pygenius": {"command": "pygenius", "args": ["mcp"],
#   "env": {"PYGENIUS_PROJECT_DIR": "/path/to/projects"}}}}

# 离线测试模式（无需 API key）
pygenius --mock generate "Create a simple Python CLI tool"

# 使用真实 LLM 生成（需设置 OPENAI_API_KEY 或 LLM_API_KEY）
pygenius --model deepseek-chat generate "Build a REST API with SQLite"

# 查看项目状态
pygenius status

# 对当前项目做完整审查
pygenius review

# 管理长期记忆
pygenius memory list
pygenius memory search "sqlalchemy"
pygenius memory add "Always use AsyncSession for async SQLAlchemy" \
    --category pattern --tags "sqlalchemy,async"
pygenius memory stats   # 统计 + 维护报告（分类分布/平均置信度/陈旧条目数/文件大小）
pygenius memory decay   # 手动衰减：置信度按闲置天数半衰，低于阈值剪枝
pygenius memory merge   # 手动压实：合并近似重复条目（老条目胜出，置信度提升，tags 并集）
pygenius memory stats --json | jq .average_confidence  # CI/脚本用机器可读输出（三个子命令都支持 --json）

# Docker 沙箱管理
pygenius sandbox check    # 检查是否可用
pygenius sandbox build    # 构建沙箱镜像
pygenius sandbox run "pytest"  # 在沙箱中执行命令
```

## 测试覆盖

```
1681+ passed (1-2 skipped) in ~4 min   # 全量（含打包 12 + 冲突报告 27 + LTM 维护 17 + 表面接线 19 + memory 子命令 11 + JSON 输出 10）
1686 passed           in ~35 min   # 内环：pytest -m "not e2e"（跳过 16 个全管线 E2E；含嵌套 coverage 子进程测试，非历史快环）
All ruff checks passed!
mypy: no issues found in 59 source files ✅
E2E Score: 100/100 ✅
```

**测试工作流**：
- 日常迭代：`pytest -m "not e2e"`（快速内环）
- 提交前 / 每晚：`pytest`（全量，~3.3 分钟）
- `e2e` marker = 跑完整 generate 管线的测试（16 个，每个 ~8.6s）

**发布就绪**：hatchling 构建 sdist + wheel（twine check PASSED）；PEP 561 `py.typed`；干净 venv 安装 wheel 后 CLI / MCP 服务器 / analyze --json / generate E2E / `--report` / memory --json 全部冒烟通过。版本里程碑 git tag `v0.1.0` / `v0.1.1` / `v0.2.0` / `v0.2.1` / `v0.3.0`（0.1.1：冲突可视化报告 + LTM 去重/衰减/压实；0.2.0：LTM 全生命周期——自动维护钩子 + 三表面接线 + memory stats/decay/merge CLI + `--json` 遥测输出；0.2.1：学习闭环三连——Coder 全类目召回 + Reviewer 教训标注/recurring + stats 健康度指标；0.3.0：闭环可观测与自愈——MCP 记忆可观测（stats resource + memory_search tool）+ recurring 教训自修正（失配降置信）+ 自愈环重写（淘汰教训的确定性后继 + lineage 演化链））。`pygenius.__version__` 与 pyproject 版本锁步（0.1.1 曾 desync，已有打包测试守卫）。

关键模块覆盖率（**99% total**，新增 112 行全覆盖）：
- `tools/file_ops.py`: **100%**（+search_replace 多块替换方法）
- `tools/web_ops.py`: **99%** 🆕（+web_search + fetch_url + SSRF 防护）
- `agents/coder.py`: **99%**（+search_replace + web_search + fetch_url actions + tool schema）
- `llm/base.py`: **93%**（+ToolCall 模型、chat_with_tools、chat_stream fallback）
- `llm/mock.py`: **100%**（+tool_call_responses 脚本模式）
- `llm/openai_provider.py`: **99%**（+原生 function calling + SSE streaming 全分支覆盖）
- `llm/codegen_mock.py`: **97%**
- `budget/`: 100%
- `config/`: 98-100%
- `models/`: 92-100%
- `context/extractor.py`: **99%**
- `context/assembler.py`: **94%**
- `context/dependency.py`: **96%**
- `events/event_bus.py`: **100%**
- `memory/cache.py`: **100%**
- `memory/long_term.py`: **98%**
- `memory/short_term.py`: **97%**
- `memory/vector.py`: **100%**
- `sandbox/docker_sandbox.py`: **100%**
- `interaction/`: **100%** (base + auto + CLI) 🆕（CLI callback 达到 100%）
- `tools/security.py`: 96%
- `tools/package_manager.py`: **97%**
- `tools/registry.py`: **98%**
- `tools/git_ops.py`: **100%**
- `tools/ast_engine.py`: **100%**
- `tools/file_ops.py`: **97%**
- `tools/linter.py`: **94%**
- `tools/command.py`: **100%** 🆕（+31%，mock Docker client 全面测试）
- `tools/tester.py`: **100%**
- `tools/quality_checker.py`: **97%**
- `agents/base.py`: **100%**
- `agents/reviewer.py`: **99%**
- `agents/coder.py`: **99%** 🆕（+1%，edit_file/list_dir/run_linter 异常路径测试）
- `agents/planner.py`: **100%**
- `orchestrator/`: **98%**
- `main.py` (CLI): **99%** 🆕（+2%，verbose traceback + version constraints 测试）

剩余 1% 为各模块零散防御性分支——`linter.py` 163-177 行（mypy 旧版单 JSON 对象解析路径，实际不可达的死代码）及少量需特定异常组合才能触发的分支。

## 技术栈

| 层级 | 选型 |
|---|---|
| 推理模型 | DeepSeek-R1 / Claude 3.7 Thinking / GPT-4o（可插拔） |
| LLM 接口 | OpenAI 兼容 Chat Completions |
| 格式+Lint | Ruff |
| 类型检查 | pyright + mypy --strict |
| 测试 | pytest + pytest-asyncio + httpx |
| 覆盖率 | pytest-cov |
| 包管理 | uv（极速）/ pip |
| 沙箱 | Docker |
| 向量库 | ChromaDB |
| AST 解析 | Python `ast` 模块 |
| Git 操作 | GitPython |
| 配置管理 | pydantic-settings |

## License

MIT
