Metadata-Version: 2.4
Name: eaves-ai
Version: 0.1.1
Summary: 本地化家庭语音 AI 助手（唤醒->声纹->ASR->LLM->TTS）
Author: snowhere
License: MIT
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: miniaudio>=1.59
Requires-Dist: numpy<2,>=1.24.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: openai>=1.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: pydantic<3,>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: langgraph>=0.2.0
Requires-Dist: fastapi>=0.110.0
Requires-Dist: uvicorn[standard]>=0.27.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: sse-starlette>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.3; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: pre-commit>=3.0; extra == "dev"
Provides-Extra: funasr
Requires-Dist: eaves-ai-funasr; extra == "funasr"
Provides-Extra: edge
Requires-Dist: eaves-ai-edge; extra == "edge"
Provides-Extra: silero
Requires-Dist: eaves-ai-silero; extra == "silero"
Provides-Extra: piper
Requires-Dist: eaves-ai-piper; extra == "piper"
Provides-Extra: cosyvoice
Requires-Dist: eaves-ai-cosyvoice; extra == "cosyvoice"
Provides-Extra: sherpa-kws
Requires-Dist: eaves-ai-sherpa-kws; extra == "sherpa-kws"
Provides-Extra: speaker-3d
Requires-Dist: eaves-ai-speaker-3d; extra == "speaker-3d"
Provides-Extra: bge-st
Requires-Dist: eaves-ai-bge-st; extra == "bge-st"
Provides-Extra: all-engines
Requires-Dist: eaves-ai-funasr; extra == "all-engines"
Requires-Dist: eaves-ai-edge; extra == "all-engines"
Requires-Dist: eaves-ai-silero; extra == "all-engines"
Requires-Dist: eaves-ai-piper; extra == "all-engines"
Requires-Dist: eaves-ai-cosyvoice; extra == "all-engines"
Requires-Dist: eaves-ai-sherpa-kws; extra == "all-engines"
Requires-Dist: eaves-ai-speaker-3d; extra == "all-engines"
Requires-Dist: eaves-ai-bge-st; extra == "all-engines"
Dynamic: license-file

# 屋檐 Eaves

**[English](README.en.md) | 中文**

[![CI](https://github.com/snowhere/eaves/actions/workflows/ci.yml/badge.svg)](https://github.com/snowhere/eaves/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/)

> 本地化部署的家庭语音助手。唤醒 -> 声纹识别 -> ASR -> LLM -> TTS 全链路，
> 会记住家人、认得每个人的声音、一个 AI 多重身份、多设备接入。

## 为什么做这个

想做一个**部署在家里的 AI 中枢**：全家人和家里的设备，共享同一个有人格、
有记忆、认得每个人的 AI。

- **一个 AI，多重身份**：声纹认出说话人后，同一个 AI 对孩子耐心讲科普、对家长干练执行指令——行为微调，不是人格切换，底层是同一份记忆与人格。
- **记得家人说过的话**：每日对话自动提炼为长期记忆，下次说话时按语义检索注入。妈妈白天说"明天有重要会议得早睡"，晚上孩子问"妈妈怎么这么早睡"，它答得上来。
- **设备随便加，大脑只有一个**：麦克风、扬声器、旧手机、摄像头流源统一接入同一个中枢，加一个房间就多接一个设备，中枢不用动。

全部本地部署，数据不出家门。更多产品思考见 [doc/vision.md](doc/vision.md)。

## 界面预览

Web 控制台覆盖配置、监控与管理全流程（引擎切换、LLM provider、成员、记忆、提醒、设备，全部页面化操作）：

| 首页概览 | 对话历史 |
| --- | --- |
| ![首页概览](doc/images/console-home.png) | ![对话历史](doc/images/console-dialogue.png) |
| **家庭成员** | **记忆管理** |
| ![家庭成员](doc/images/console-members.png) | ![记忆管理](doc/images/console-memories.png) |
| **提醒** | **设备管理** |
| ![提醒](doc/images/console-reminders.png) | ![设备管理](doc/images/console-devices.png) |

## 快速开始

### 安装

需要 Python 3.11+。

```bash
git clone https://github.com/snowhere/eaves.git
cd eaves
pip install -e '.[dev]'                  # 主包 + 开发依赖（pytest / ruff / pre-commit）
pip install -e '.[funasr,silero,edge]'   # 按需装语音引擎 provider
```

或最小化跑通 stub 全链路（不装真实引擎）：

```bash
pip install -r requirements.txt
```

### 配置

复制出厂默认并填入 LLM key 与设备选择：

```bash
cp config/settings.yaml config/settings.local.yaml
# 编辑 settings.local.yaml：
#   llm.providers          填 API key（DeepSeek / OpenAI 兼容）
#   llm.default_provider   选默认 LLM
#   engines.*.provider     选真实引擎（funasr / silero / edge ...）
#   active_input / active_output  选麦克风 / 扬声器设备
```

首启若没有 `settings.local.yaml`，会以出厂默认（全 stub）启动并提示你去 Web 控制台配置。

### 启动

```bash
./run.sh                  # 等价于 python -m eaves.main
./run.sh --check-only     # 仅启动检查，不进对话循环
```

启动后 Web 控制台默认在 http://localhost:8000，可在控制台配置 LLM key、切换引擎
provider、下载模型、管理设备，全部复用后端 API。

### 测试

```bash
python -m pytest tests/ -q
```

## 核心特性

- **全链路语音**：唤醒词（Sherpa-ONNX）-> 声纹（3D-Speaker）-> ASR（FunASR Paraformer）-> LLM（DeepSeek / OpenAI 兼容）-> TTS（edge-tts / Piper / CosyVoice）。无真实 provider 时各引擎 stub 兜底，纯文字调试走 console `/api/debug/chat`。
- **引擎插件化**：ASR / TTS / VAD / 声纹 / 唤醒词 / Embedding 走 entry_points 发现，`pip install eaves-ai-<x>` 装即用，业务代码不知情。
- **LangGraph 对话流**：tool-use 链（非 intent 分类），LLM 自行决定调什么工具；流式 TTS 首句在 LLM 生成中即推送。
- **长期记忆**：每日笔记自动提炼入 SQLite + embedding，对话时语义检索注入；成员画像是 Markdown 文件。
- **多设备**：DeviceServer 常驻 WebSocket 底座，IO 热切换不踢设备；EchoGuard 防 TTS 自激。
- **MCP 工具**：builtin 工具 + MCP 服务汇入统一 dispatcher，家电控制走 MCP。
- **Web 控制台**：Vue 3 + Naive UI，引擎切换热重载、LLM 多 provider、设备管理、记忆查看、调试对话。

## 架构概览

```
唤醒 -> 声纹 -> ASR -> LLM -> TTS -> 扬声器
```

- **抽象接口先行**：引擎 Protocol 在 `eaves/engines/interfaces.py`，IO Protocol 在 `eaves/io/interfaces.py`，LLM Protocol 在 `eaves/llm/`。换底层实现不改业务代码。
- **Holder 正交分层**：`EnginesHolder`（引擎能力，热替换不重启 loop）+ `IOHolder`（IO 拓扑）+ `SettingsHolder`（配置热替换）+ `DeviceServer`（设备层）。
- **录音与识别解耦**：`InputSource` 编排录音 + VAD + ASR + 唤醒词，`MicCapture` 只采 PCM，ASR provider 只做 `bytes -> text`。
- **配置分层**：`config/settings.yaml`（出厂默认，进 git）+ `config/settings.local.yaml`（用户覆盖，gitignore）。

## 目录结构

```
eaves/
├── main.py              # 启动入口
├── audio/               # 录音 / 播放 / 降噪 / 分段
├── engines/             # 引擎 Protocol + stub 兜底（真实实现走 providers/）
├── llm/                 # LLM Protocol + openai / anthropic 实现
├── io/                  # InputSource / AudioOutput Protocol
├── conversation/        # LangGraph 对话流 / loop / OutputSink
├── identity/            # 声纹绑定 / 人格 / prompt 拼装
├── devices/             # 设备模型 / EchoGuard / DeviceServer
├── bridges/             # 流源桥接（direct / go2rtc）
├── tools/               # builtin 工具 + MCP
├── scheduler/           # 提醒 / 定时器
├── storage/             # SQLite + 记忆 store + 各 repository
├── workers/             # 每日笔记 / 记忆提炼 / embedding 填充 / 保留清理
├── console/             # FastAPI Web 控制台 + web_dist 前端产物
├── config/              # 配置加载 / schema / 分层
├── shared/              # 跨模块工具（音频格式 / 日志 / 注册表）
└── routing/             # 网络扬声器路由
providers/               # 8 个独立 pip 包（引擎真实实现）
web-src/                 # Vue 3 前端源码（构建到 eaves/console/web_dist/）
config/                  # settings.yaml + settings.local.yaml
data/                    # 运行时数据（gitignore）
tests/                   # 单元 + 集成测试
```

## 常见问题

- **首启全是 stub？** 没检测到 `config/settings.local.yaml` 时以出厂默认（全 stub 兜底）启动，进 Web 控制台配置后即换真实引擎。这是设计，不是 bug。
- **录音没声音 / 不识别？** 检查 `settings.local.yaml` 的 `active_input` 是否选对麦克风设备，以及系统麦克风权限。
- **LLM API key 填哪？** `config/settings.local.yaml` 的 `llm.providers.<name>.api_key`（明文存储，gitignore 不进 git）。
- **不想装某个引擎？** 不装即可，对应能力走 stub 兜底，主流程照样能跑。
- **拉 RTSP 流报 ffmpeg 缺失？** 仅 `PullInputSource`（摄像头流源）需要 ffmpeg。macOS `brew install ffmpeg`，Debian/Ubuntu `sudo apt install ffmpeg`。

## 文档

- [doc/vision.md](doc/vision.md) - 产品愿景：是什么、不是什么、典型场景与明确边界
- [doc/deploy.md](doc/deploy.md) - 部署与安装（环境要求 / 本地与云端形态 / 国内踩坑）
- [doc/configuration.md](doc/configuration.md) - 配置参考（配置分层 / 全字段说明 / 常见场景）
- [doc/architecture.md](doc/architecture.md) - 关键架构（Protocol 抽象 / Holder 分层 / 对话流 / 记忆系统）
- [doc/develop-providers.md](doc/develop-providers.md) - 引擎 Provider 开发指南
- [CHANGELOG.md](CHANGELOG.md) - 变更记录
- [CONTRIBUTING.md](CONTRIBUTING.md) - 贡献指南
- [SECURITY.md](SECURITY.md) - 安全策略
- 部分模块在 `eaves/<module>/README.md` 有职责说明

## 致谢

本项目站在以下开源项目的肩上：

- [Sherpa-ONNX](https://github.com/k2-fsa/sherpa-onnx) - 唤醒词识别
- [FunASR](https://github.com/modelscope/FunASR) - 语音识别（Paraformer）
- [3D-Speaker](https://github.com/alibaba-damo-academy/3D-Speaker) - 声纹识别（CAM++）
- [SileroVAD](https://github.com/snakers4/silero-models) - 语音活动检测
- [edge-tts](https://github.com/rany2/edge-tts) / [Piper](https://github.com/rhasspy/piper) / [CosyVoice](https://github.com/FunAudioLLM/CosyVoice) - 语音合成
- [LangGraph](https://github.com/langchain-ai/langgraph) - 对话流编排
- [FastAPI](https://fastapi.tiangolo.com/) + [Vue 3](https://vuejs.org/) + [Naive UI](https://www.naiveui.com/) - Web 控制台

## License

[MIT](LICENSE)
