Personal agent assistant
Обзор
A local-first Feishu work assistant built around a file-based Skills ecosystem. EvoPaw connects to Feishu through the official channel, routes each conversation through a multi-provider , and grows new abilities through a folder of self-describing . No public webhook. No vendor lock-in. Your data stays on your box. - 🪶 Runs on a laptop, home server, or air-gapped VM — no inbound webhook required. - 🔌 Built-in claude_sdk, anthropic, dashscope, plus any OpenAI-compatible provider. - 🧰 Drop in a SKILL.md, get a new capability — PDFs, Feishu ops, web search, scheduling, investment workflows, and more. - 🧠 Bootstrap files, compressed session context, and pgvector semantic recall. - 🎙️ Feishu audio → DashScope Fun-ASR → Agent → reply. - 📡 Stream tool execution back to the chat for transparent debugging. - 📊 Prometheus metrics and JSON-line logs out of the box. Send a message to your Feishu bot — that's it.
README
EvoPaw connects to Feishu through the official WebSocket channel, routes each conversation through a multi-provider agent runtime, and grows new abilities through a folder of self-describing Skills.
No public webhook. No vendor lock-in. Your data stays on your box.
✨ Highlights
- 🪶 Local-first. Runs on a laptop, home server, or air-gapped VM — no inbound webhook required.
- 🔌 Multi-provider runtime. Built-in
claude_sdk,anthropic,dashscope, plus any OpenAI-compatible provider. - 🧰 File-based Skills. Drop in a
SKILL.md, get a new capability — PDFs, Feishu ops, web search, scheduling, investment workflows, and more. - 🧠 Three-layer memory. Bootstrap files, compressed session context, and pgvector semantic recall.
- 🎙️ Voice in, voice out. Feishu audio → DashScope Fun-ASR → Agent → reply.
- 📡 Verbose mode. Stream tool execution back to the chat for transparent debugging.
- 📊 Observable. Prometheus metrics and JSON-line logs out of the box.
🚀 Quick Start
# 1. install
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
npm install -g @anthropic-ai/claude-code # default sub-agent runtime
# 2. configure
cp config.yaml.template config.yaml # fill in Feishu app_id / app_secret
# 3. run
docker compose up -d # app + pgvector
# or, for a manual loop:
python3 -m evopaw.main
Send a message to your Feishu bot — that’s it.
🏗️ Architecture
Feishu WebSocket
│
▼
FeishuListener ──▶ Runner ──▶ Main Agent Runtime
( claude_sdk │ anthropic_messages │ openai_chat )
│
┌────────────┴────────────┐
▼ ▼
SkillDispatcher Memory runtime
├─ reference / history ├─ bootstrap files
└─ task → Sub-Agent ├─ ctx.json / raw.jsonl
└─ pgvector index
Conversations are isolated by routing key:
| Feishu context | Routing key |
|---|---|
| Direct chat | p2p:{open_id} |
| Group chat | group:{chat_id} |
| Threaded chat | thread:{chat_id}:{thread_id} |
⚙️ Configuration
Create a private runtime config (Git-ignored):
cp config.yaml.template config.yaml
Minimum Feishu block:
feishu:
app_id: "${FEISHU_APP_ID}"
app_secret: "${FEISHU_APP_SECRET}"
Environment variables
| Variable | Required when | Purpose |
|---|---|---|
FEISHU_APP_ID / FEISHU_APP_SECRET |
Always | Feishu app credentials |
ANTHROPIC_API_KEY |
Using anthropic provider |
Anthropic Messages API |
DASHSCOPE_API_KEY |
ASR enabled | DashScope Fun-ASR WebSocket |
QWEN_API_KEY |
DashScope memory roles | DashScope OpenAI-compatible chat / embeddings |
TAVILY_API_KEY |
tavily_search Skill |
Web search |
MOONSHOT_API_KEY |
Custom Moonshot provider | Example OpenAI-compatible provider |
POSTGRES_PASSWORD |
Override Docker pgvector | PostgreSQL password |
DASHSCOPE_API_KEYandQWEN_API_KEYcan hold the same DashScope key — they exist as two names because ASR and the OpenAI-compatible memory client read different env vars.
▶️ Running
Docker Compose (recommended)
docker compose up -d --build
Set memory.db_dsn to the Compose service host:
memory:
db_dsn: "postgresql://evopaw:evopaw123@evopaw-pgvector:5432/evopaw_memory"
| Service | Purpose |
|---|---|
evopaw-main |
Python app and agent runtime |
pgvector |
PostgreSQL 16 with pgvector |
Manual
docker compose -f pgvector-docker-compose.yaml up -d # optional: semantic memory
python3 -m evopaw.main
For the manual path use localhost in the DSN:
memory:
db_dsn: "postgresql://evopaw:evopaw123@localhost:5432/evopaw_memory"
Runtime endpoints
| Item | Location |
|---|---|
| Prometheus metrics | http://127.0.0.1:9100/metrics |
| Runtime logs | data/logs/evopaw.log |
| Session data | data/sessions/ |
| Context snapshots | data/ctx/ |
| Workspace data | data/workspace/ |
💬 Slash Commands
| Command | Description |
|---|---|
/new |
Start a fresh session |
/verbose on · /verbose off · /verbose |
Stream / stop / inspect tool-progress streaming |
/status |
Show current session details |
/help |
Show command help |
🛠️ Skills
The authoritative list lives in evopaw/skills/load_skills.yaml.
| Skill | Type | Purpose |
|---|---|---|
pdf / docx / pptx / xlsx |
task | Document parsing and extraction |
feishu_ops |
task | Feishu docs, sheets, bitables, messages, files |
scheduler_mgr |
task | Scheduled task management |
tavily_search |
task | Internet search via Tavily |
arxiv_search |
task | arXiv search and PDF retrieval |
web_browse |
task | Web content extraction |
history_reader |
reference | Inline paginated conversation history |
memory-save / search_memory / memory-governance |
task | Long-term memory lifecycle |
skill-creator |
task | Turn repeatable workflows into Skills |
daily-summary |
task | Daily work summaries |
investment-report / investment-review / investment-consult |
task | Investment workflows |
hk-investment-morning-report |
task | Hong Kong market morning report |
🧠 Memory
| Layer | Storage | Role |
|---|---|---|
| L1 · Bootstrap | data/workspace/*.md |
Identity, profile, operating rules, memory index |
| L2 · Context | data/ctx/*.json · *.jsonl |
Compressed session context and audit log |
| L3 · Vector | PostgreSQL + pgvector | Semantic search over historical turns |
If the database or DashScope key is unavailable, semantic memory degrades — the main Feishu flow keeps running.
🎙️ Voice Messages
Feishu audio → FeishuDownloader → SpeechRecognitionService
→ FunASRRealtimeClient → Main Agent → Feishu reply
- Audio bytes stream straight to Fun-ASR after download.
- ASR credentials stay in the main process environment.
- Long or slow clips receive an early acknowledgement before the final reply.
- Duplicate Feishu deliveries are deduped by recent
msg_id. - ASR metrics are exported through Prometheus.
Helpers:
python3 scripts/audit_audio_sample_rate.py data/workspace/sessions/
python3 scripts/calibrate_thresholds.py
🧪 Testing
python3 -m pytest # everything
python3 -m pytest tests/unit/ --cov=evopaw --cov-report=term # unit + coverage
python3 -m pytest tests/integration/ -m "not llm" # integration (no LLM)
python3 -m pytest tests/integration/test_voice_end_to_end.py # voice e2e mock
🔒 Security & Local-Only Files
Keep these on the local box — never commit:
.env,config.yamldata/,tests/logs/,workspace-init/.coverage,coverage.json,htmlcov/- Python and test caches
If a secret was ever committed, rotate it and clean Git history — don’t just delete it in a follow-up commit.
Рекомендуемые инструменты
Попробуйте другой запрос или уберите фильтр.
Установка
npx skillfish add hxdflying/evopaw