# Butler Project Memory

## 项目基本信息
- 路径: `/root/projects/butler`
- 性质: 个人 AI 助理系统（健康追踪 + 桌面自动化 + Slack Bot）
- 迁移自: macOS `/Users/lili/workspace/butler` → 当前 Linux 服务器

## 当前 LLM 配置
- 通过 OpenRouter 访问 Gemini: `GEMINI_BASE_URL=https://openrouter.ai/api`
- 当前模型: `google/gemini-3-flash-preview`
- 配置文件: `.gemini.current.env`（`.env` 通过 `GEMINI_CONFIG_PATH` 指向它）
- `TOOL_MODE=all` → Health Bot 加载全部工具

## Bot 架构
- **Health Bot**: `slack_bot/main.py` - 健康数据查询/记录/分析
- **Shell Bot**: `slack_bot/shell_main.py` - 系统管理，**默认禁用**
  - 需在 `.env` 设置 `SHELL_BOT_ENABLED=true` 才能启动（2026-03-02 添加的守卫）
  - 这台机器**不启用** Shell Bot
- Bot 管理: `python scripts/bot_manager.py {start|stop|status}`

## 数据存储
- Garmin 数据: `data/health/` (SQLite + JSON, SQLite 已开启 WAL 模式)
- 手动日志: `data/health/manual_logs/`
- Obsidian Vault: `/root/vault/obsidian_vault/obsidian/obsidian/`

## 已完成的关键任务 (Week 1 P0)
- 敏感信息日志泄露修复 ✅
- Shell 命令黑名单 ✅
- 环境变量验证 ✅
- Garmin API 重试机制 ✅
- SQLite WAL 优化 ✅
- 迁移至 Linux 服务器 ✅
- 数据库路径迁移修复 ✅（9374 条记录从 /Users/lili/workspace/bulter/ 更新为 /root/projects/butler/）
- Feature 3.1 健康周报自动生成 ✅

## 数据库路径迁移说明
迁移时 health.db 的 daily_metrics_index 保留了旧 Mac 路径（/Users/lili/workspace/bulter/ 含拼写错误），
已通过 SQL REPLACE 修复全部路径。备份：data/health/health.db.bak_20260302

## 健康数据字段名（实际 JSON）
- sleep: sleep_score, total_sleep_seconds, date
- heart_rate: resting_heart_rate, min_heart_rate, max_heart_rate
- hrv: hrv_value, baseline_hrv, status
- body_battery: charged, drained, timeline（无 highest_value/lowest_value，从 timeline 推导）
- steps: total_steps, total_distance_meters, step_goal
- spo2: raw_data.averageSpO2, raw_data.lowestSpO2（注意大写 O！直接字段因历史 bug 为 None）
  - garmin_client.fetch_spo2() 已修正 key 名（averageSpO2/lowestSpO2/spO2ValueDescriptorsDTOList）
  - 分析函数已加 raw_data fallback，旧存储文件仍可读取

## Garmin Lifestyle Logging（2026-03-02 新增）
- Pydantic 模型: health/models/daily_metrics.py LifestyleLoggingData
- 存储路径: data/health/daily_metrics/lifestyle_logging/
- 解析逻辑: garmin_client.fetch_lifestyle_logging()；logStatus=YES 才算已记录；无记录返回 None
- 测试文件: tests/test_lifestyle_logging.py（8 个测试全通过）
- engine.py get_dataframe() 已接入 gl_* 前缀列（酒精/咖啡因/饮食/轻运动/断食）

## 分析能力（health_read.py）
- 原有: rhr, hrv, sleep, stress, steps 的趋势分析 + compare_groups/analyze_driver
- 新增 8 个: spo2, respiration, hydration, floors, body_battery, intensity_minutes, weight, lifestyle_logging
- 路由在 get_aggregated_analysis() 函数内

## Feature 3.1: 健康周报
- 报告生成器: health/analytics/weekly_report.py (WeeklyReportGenerator)
- Cron 脚本: scripts/weekly_report.py（每周一 11:00）
- 需要 .env 设置: SLACK_REPORT_CHANNEL=C0XXXXXXXXX
- 活动数据用 query.get_activities_range() 而非 get_metric_range("activities",...)

## Feature 3.2: 第二大脑 RAG 系统（2026-03-03 新增）
- 新文件: slack_bot/obsidian/embeddings.py（EmbeddingProvider ABC + Qwen/SentenceTransformer 两个后端）
- 新文件: slack_bot/obsidian/vector_store.py（ChromaVectorStore + split_md_by_headers）
- 新文件: slack_bot/obsidian/note_ingester.py（NoteIngester + ExtractedNote）
- 修改: slack_bot/obsidian/generators.py（BaseGenerator 加 vector_store 参数 + _semantic_search）
- 修改: slack_bot/obsidian/dispatcher.py（MODE_NOTE + VALID_MODES + ChromaVectorStore 初始化）
- 新脚本: scripts/init_vault_indexer.py（批量洗盘 CLI，--path + --reset，python-frontmatter + tqdm）
- requirements.txt 新增: chromadb>=0.5.0, tavily-python>=0.3.0, python-frontmatter>=1.0.0, tqdm>=4.66.0, sentence-transformers>=3.0.0
- .env 需新增: EMBEDDING_BACKEND(local/cloud), TAVILY_API_KEY
- ChromaDB 数据目录: DATA_DIR/vector_db；切换 backend 前需 --reset（维度不同）
- vault 新笔记路径: OBSIDIAN_VAULT_PATH/notes/<date>_<slug>.md（含 YAML frontmatter，tags: auto_ingested）

## 归档
- `tag20260215/` - 旧归档（不改动）
- `tag20260302/` - 2026-03-02 迁移后快照

## 用户偏好
- 不在这台机器上启用 Shell Bot
- 只修改文档，不随意改动代码
- 文档更新后再开始新功能开发
