Development Setup and Conventions
Complete step-by-step guide to setting up the Familiars development environment from scratch. Covers the Python backend, the Electron frontend, environment variables, and testing red lines.
1. Repository Directory Layout
| Path | Description |
|---|---|
src/ | Python backend. bridge/ = FastAPI route layer; models/ = Agent / conversation / memory; tools/ + utils/ = tool system; base/ = configuration, GPU tiering, encryption, path alignment; storage/ = SQLite + migrations; broker/ = broker layer |
electron/ | Electron desktop app. electron/main.js = main process; electron/python.js = bridge lifecycle management; renderer/ = Vue 3 + Vite frontend |
workspace/ | Runtime data. familiars.db (SQLite), SECRET.json, agents/ (one directory per agent), manager/, marketplace_host/, .bridge_token, .bridge.port, .bridge.crt |
test/ | Full test suite (pytest). Includes bridge/, decider/, broker/, recipes/, acceptance/ |
deploy/relay/ | Standalone deployment of the broker relay (Docker + Caddy) |
main.py | CLI entry point wrapping every bridge REST endpoint |
2. Backend Environment Setup
2.1 Create a Virtual Environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows CMD
# .venv\Scripts\Activate.ps1 # Windows PowerShell2.2 Install Dependencies
Dependencies are defined in requirements.txt (151 lines, covering ML / multimedia / platform-specific packages).
# Windows (CUDA 12.6)
pip install -r requirements.txt --index-url https://download.pytorch.org/whl/cu126
# macOS (CPU/MPS)
pip install -r requirements.txt --index-url https://download.pytorch.org/whl/cpuKey notes:
torch==2.9.0+cu126/torchvision==0.24.0+cu126/torchaudio==2.9.0+cu126must be installed from the PyTorch index. A plainpip install torch==2.9.0will pull the CPU build, making local QLoRA model inference ~10× slower.onnxruntime==1.28.0(not the original 1.26.0) — 1.26.0 was compiled against NumPy 1.x; under NumPy 2.x, importing rembg raisesAttributeError: _ARRAY_API not found.- Platform-specific packages are guarded by
sys_platform:- Windows only:
uiautomation,wcferry(WeChat RPC),pycaw,comtypes,wmi,pywin32 - macOS only:
AppKit,Quartz
- Windows only:
2.3 Core Dependencies at a Glance
| Package | Purpose |
|---|---|
fastapi==0.136.1 + hypercorn[h2]>=0.16.0 | HTTP/2 + HTTPS bridge |
openai==2.36.0 | LLM API client |
torch==2.9.0+cu126 + transformers==4.57.3 + peft==0.19.1 | Local QLoRA small models (rewriter/decider/memorizer) |
sentence_transformers==5.2.2 + FlagEmbedding==1.4.0 | RAG embeddings (bge-m3) |
onnxruntime==1.28.0 + rembg (via insightface) | Digital human background removal |
faster-whisper>=1.0.0 | ASR speech recognition |
playwright==1.59.0 | Browser automation |
apscheduler==3.11.2 | Scheduled task scheduling |
cryptography==45.0.5 | HKDF key derivation + encryption |
pydantic==2.13.4 + pydantic-settings>=2.5.0 | Configuration validation |
httpx==0.28.1 | Async HTTP client |
beautifulsoup4==4.14.3 + pdfplumber==0.11.4 + python_docx==1.2.0 + openpyxl==3.1.5 | Document parsing |
paddleocr==3.5.0 + opencv_python==4.12.0.88 | OCR |
sounddevice>=0.4.6 + webrtcvad-wheels>=2.0.14 | Phone call audio loopback |
datasets==4.8.5 + trl==1.4.0 | Data generation / training pipeline |
3. Environment Variable Configuration
Configuration is centrally validated by src/base/config.py (pydantic-settings). All variables are set in the .env file.
3.1 Required Variables
| Variable | Description | Example |
|---|---|---|
BASE_URL | OpenAI-compatible API base URL | https://api.openai.com/v1 |
API_KEY | LLM API key | sk-... |
DEFAULT_MODEL | Default chat model | gpt-4o |
Missing any of these will cause the bridge to raise ValueError: Missing required environment variable(s): ... at startup.
3.2 LLM Configuration
| Variable | Default | Description |
|---|---|---|
MANAGER_MODEL | gpt-4o | Model dedicated to AssistantManager executive summaries / persona evolution |
MINI_MODEL | Qwen2.5-1.5B | Lightweight local model (rewriter/decider) |
FAST_MODEL | "" | Low-latency fast model (draft parsing, etc.); empty = fall back to DEFAULT_MODEL |
BETA | 0.3 | Cost weight in the model routing formula |
3.3 Infrastructure Tuning
| Variable | Default | Description |
|---|---|---|
TIMEOUT | 300 | HTTP request timeout (seconds) |
MAX_TURNS | 50 | Maximum number of tool-loop turns |
DIALOGUE_EXPIRE_TIME | 3600 | Dialogue expiry time (seconds) |
SLIDE_WINDOW_SIZE | 5 | Dialogue history sliding window size |
WORKSPACE_ROUTE | "" | Workspace root directory; default = cwd |
TOP_K | 5 | Number of results returned by RAG retrieval |
3.4 Embedding Model
| Variable | Default | Description |
|---|---|---|
EMBEDDING_MODEL | BAAI/bge-m3 | sentence-transformers embedding model |
BASE_ROUTE | "" | Base directory for local models / routing files |
3.5 RAG Tuning
| Variable | Default | Description |
|---|---|---|
RAG_DENSE_TOPK | 20 | Additional dense retrieval candidate count |
RAG_DATA_TOPFILES | 3 | Number of files to drill into in data mode |
RAG_DATA_TOPCHUNKS | 5 | Number of surface chunks in data mode |
RAG_CHUNK_SIZE | 800 | Target chunk size (characters) |
RAG_RERANK_MIN_SCORE | 0.0 | Rerank minimum score threshold (0 = keep all) |
RAG_REFINER_MAX_RETRIES | 3 | Refiner JSON parsing retry budget |
RAG_FILE_WEIGHT | 0.4 | File-level rerank weight α in data mode |
RAG_CHUNK_WEIGHT | 0.6 | Chunk-level rerank weight β in data mode |
RAG_RRF_K | 60 | Reciprocal Rank Fusion constant |
RAG_CACHE_DIR | "" | RAG cache directory; empty = <workspace>/.cache/rag |
RAG_FEEDBACK_WEIGHT | 0.0 | Weight of historical success rate in reranking (0 = off) |
RAG_ANN_MIN_N | 64 | Build an hnswlib ANN index once the registry reaches this size |
RAG_MULTIQUERY_N | 1 | Number of query variants combined by the local rewriter (1 = single query) |
3.6 Circuit Breaker / LLM Concurrency Control
| Variable | Default | Description |
|---|---|---|
CB_FAILURE_THRESHOLD | 5 | Consecutive failures before the circuit breaker opens |
CB_RECOVERY_SECONDS | 30.0 | Circuit breaker half-open recovery wait time (seconds) |
LLM_MAX_RETRIES | 3 | Maximum retries per LLM call |
LLM_RETRY_BASE_DELAY | 1.0 | Initial backoff delay for retries (seconds) |
LLM_RETRY_MAX_DELAY | 30.0 | Maximum backoff delay for retries (seconds) |
LLM_MAX_CONCURRENT_PER_URL | 8 | Maximum concurrent LLM calls per URL (AIMD ceiling) |
LLM_MIN_CONCURRENT_PER_URL | 1 | AIMD shrink floor |
LLM_QUEUE_WAIT_S | 120 | Maximum seconds a caller waits for gate permission |
LLM_AIMD_GROW_AFTER | 20 | AIMD target +1 after this many consecutive successes |
LLM_AIMD_SHRINK_FACTOR | 0.5 | AIMD target multiplier on timeout (0.5 = halve) |
LLM_GATE_DISABLED | false | Master switch: true = concurrency gate disabled (unlimited) |
RESPONSES_API_ENABLED | "" | Force Responses API on/off (true/false); empty = auto-detect |
RESPONSES_API_PATH | "" | Override the Responses API path (e.g. /v1/responses) |
3.7 User Preferences
| Variable | Default | Description |
|---|---|---|
need_figure | true | Whether a character portrait is needed |
need_audio | true | Whether voice is needed |
need_video | true | Whether video is needed |
need_report | true | Whether reports are needed |
intense_mode | true | Execute tasks until absolutely successful |
turbo_mode | false | Skip approvals but keep plan verification and interaction (mutually exclusive with intense_mode) |
3.8 Conversation Settings
| Variable | Default | Description |
|---|---|---|
color | blue | Agent theme color (red/blue/green/cyan/grey/yellow) |
need_initiative | true | Whether the conversation can be initiated proactively |
security_level | medium | Approval threshold (high/medium/low) |
verify_plan | false | Whether to verify the plan before execution |
skill_auto_apply | false | Auto-apply skill proposals |
3.9 Daily Monitoring
| Variable | Default | Description |
|---|---|---|
DAILY_MONITOR_MAX_TASKS | 8 | Max concurrent monitoring tasks per agent |
DAILY_MONITOR_EMBEDDING_THRESHOLD | 0.54 | Embedding cosine similarity threshold |
DAILY_MONITOR_KEYWORD_ENABLED | true | Enable keyword fast-path |
DAILY_MONITOR_MINI_CONFIRM_ENABLED | true | Enable small-model confirmation step |
DAILY_MONITOR_CLIENT_TIMEOUT | 60.0 | Browser/input client dispatch timeout (seconds) |
DAILY_MONITOR_DISABLED | false | Completely disable the daily monitoring module |
3.10 External Services / Third-Party
| Variable | Default | Description |
|---|---|---|
HUGGING_FACE_API_KEY | "" | Hugging Face API key |
DATAGEN_BASE_URL | "" | Data generation API URL |
DATAGEN_API_KEY | "" | Data generation API key |
UPDATE_URL | "" | OTA update feed URL (electron-updater generic provider); empty = disabled |
UPDATE_CHECK_INTERVAL_HOURS | 24 | Auto-update check interval (hours) |
3.11 FAMILIARS_* Runtime Flags
| Variable | Description |
|---|---|
FAMILIARS_DB_PATH | SQLite database path. Default workspace/familiars.db. Use :memory: for tests |
FAMILIARS_HTTP_INSECURE | 1 = fall back to plain HTTP + uvicorn (no HTTPS/HTTP2) |
FAMILIARS_MARKETPLACE_URL | Source URL of the marketplace index.json |
FAMILIARS_TIER*_MAX_MB | GPU tier VRAM thresholds (TIER1 ~ TIER4) |
FAMILIARS_APPROVAL_DISABLED | 1 = disable the approval gate (development; all tools execute directly) |
FAMILIARS_FRAMEWORK_DOCS_TOPK | Manager framework-docs retrieval top-K |
FAMILIARS_BROKER_ADVERTISE_URL | Broker public/LAN address (cross-machine federation) |
FAMILIARS_BROKER_BIND | Bridge bind address. 0.0.0.0 exposes across machines; empty = 127.0.0.1 |
FAMILIARS_BROKER_DIRECT_TIMEOUT | Federation direct delivery timeout (seconds), default 10.0 |
4. Frontend Environment Setup
4.1 Node.js Dependencies
cd electron
npm install4.2 Core Frontend Dependencies
| Package | Version | Purpose |
|---|---|---|
vue | ^3.5.41 | UI framework |
pinia | ^2.1.7 | State management |
@vue-flow/core | ^1.48.2 | Flow diagram editor |
@vue-flow/minimap / controls / background | companion | Flow diagram auxiliary components |
@dagrejs/dagre | ^3.0.0 | Flow diagram auto-layout |
axios | ^1.7.0 | HTTP client |
electron | ^30.0.0 | Desktop shell |
electron-builder | ^24.13.0 | Packaging (NSIS Windows / DMG macOS) |
electron-updater | ^6.8.9 | OTA auto-update |
markdown-it + katex + mermaid | - | Message rendering (Markdown / LaTeX / diagrams) |
onnxruntime-web | ^1.26.0 | In-browser ONNX inference |
@ricky0123/vad-web | ^0.0.30 | In-browser VAD (voice activity detection) |
highlight.js | ^11.11.1 | Code highlighting |
jszip | ^3.10.1 | Zip pack/unpack |
d3 | ^7.9.0 | Data visualization |
4.3 Frontend Build Scripts
{
"dev": "vite",
"build": "vite build",
"test": "vitest run",
"electron:dev": "concurrently \"vite\" \"wait-on http://localhost:5173 && electron .\"",
"electron:build": "vite build && electron-builder"
}4.4 Build Configuration
- appId:
com.familiars.desktop - productName:
Familiars - Windows: NSIS installer (not one-click; selectable install path, creates desktop/Start Menu shortcuts)
- macOS: DMG
- Update feed:
https://api.familiars.cn/_app-updates/(generic provider) - extraResources:
cover.png(app cover)
5. Starting Development
5.1 Start the Bridge (Backend)
# Recommended: hypercorn + HTTPS/HTTP2 + self-signed certificate
.venv/Scripts/python -m src.bridge.run
# Fallback: plain HTTP + uvicorn (for debugging)
FAMILIARS_HTTP_INSECURE=1 .venv/Scripts/python -m src.bridge.runThe bridge listens on 127.0.0.1:18711 (default). If the port is occupied, Electron automatically calls pickFreePort() and writes the chosen port to workspace/.bridge.port.
A self-signed certificate is auto-generated at workspace/.bridge.crt.
5.2 Start the Electron Frontend (Dev Mode)
cd electron && npm run electron:devThis starts the Vite dev server (:5173) and an Electron window at the same time, and automatically spawns the bridge process.
5.3 Driving via the CLI
python main.py --help # list command groups
python main.py agents list --pretty # list all agents
python main.py chat stream --prompt "你好" --agent-id 1 # SSE streaming chat5.4 Production Build
cd electron && npm run electron:buildOutput goes to electron/dist-electron/.
6. Testing Conventions (Red Lines)
6.1 Must Use Real SQLite
FAMILIARS_DB_PATH=:memory: pytest -qDo not mock the storage repository. Every test must run against a real SQLite database (in-memory or file-based).
6.2 Bridge Route Tests
- Restore
sys.modules: bridge routes capture module state at import time, and tests must restore it. Seetest/bridge/conftest.py. - No
importlib.reload: do not reload route modules — import-time side effects (CUDA pin, path alignment) cannot be safely replayed.
6.3 Scratch Agent Directories
Temporary agent directories belong in runs/, not workspace/agents/. At startup the bridge scans workspace/agents/ and will actually create agents from anything it finds there.
6.4 Browser Automation
Route through src/utils/browser_tools.py:familiars_cdp_port() — a single shared Chrome instance (bridge + Playwright + see-through rendering all share it).
6.5 New Logs Must Enter KNOWN_LOGS
The KNOWN_LOGS list in src/utils/framework_tools.py controls which logs the manager can see. New log files must be registered there.
7. .env Template
# ---- LLM required ----
BASE_URL=https://api.openai.com/v1
API_KEY=sk-your-key-here
DEFAULT_MODEL=gpt-4o
# ---- LLM optional ----
MANAGER_MODEL=gpt-4o
MINI_MODEL=Qwen2.5-1.5B
FAST_MODEL=
# ---- Embeddings / RAG ----
EMBEDDING_MODEL=BAAI/bge-m3
RAG_DENSE_TOPK=20
RAG_CHUNK_SIZE=800
# ---- Conversation tuning ----
MAX_TURNS=50
TIMEOUT=300
DIALOGUE_EXPIRE_TIME=3600
SLIDE_WINDOW_SIZE=5
# ---- Runtime flags ----
# FAMILIARS_DB_PATH=workspace/familiars.db
# FAMILIARS_HTTP_INSECURE=0
# FAMILIARS_APPROVAL_DISABLED=0
# FAMILIARS_MARKETPLACE_URL=https://api.familiars.cn/marketplace
# ---- Broker federation ----
# FAMILIARS_BROKER_ADVERTISE_URL=
# FAMILIARS_BROKER_BIND=127.0.0.1
# ---- User preferences ----
color=blue
intense_mode=true
security_level=medium
# ---- Daily monitoring ----
DAILY_MONITOR_MAX_TASKS=8
DAILY_MONITOR_EMBEDDING_THRESHOLD=0.54
# ---- Circuit breaker ----
CB_FAILURE_THRESHOLD=5
LLM_MAX_RETRIES=3
LLM_MAX_CONCURRENT_PER_URL=8