This repository contains the Python implementation for the Distiller CM5 project, featuring a client-server architecture based on the Model Context Protocal (MCP) for interacting with Large Language Models (LLMs).
The framework consists of several key components:
- Client (
distiller_cm5_python/client/
): Provides user interfaces (both GUI and CLI) to interact with an LLM backend via an MCP server. Includes features like optional local LLM server management, tool usage facilitation, streaming responses, voice input, and E-Ink display support. (Seeclient/README.md
for details) - LLM Server (
distiller_cm5_python/llm_server/
): A FastAPI server that wraps local LLMs (usingllama-cpp-python
) and exposes an OpenAI-compatible API endpoint for chat completions, model management, and caching. (Seellm_server/README.md
for details) - MCP Server (
distiller_cm5_python/mcp_server/
): Contains example MCP server implementations that expose specific functionalities (like Text-to-Speech or WiFi control) as tools callable by the MCP client via the protocol. (Seemcp_server/README.md
for details) - Utilities (
distiller_cm5_python/utils/
): Shared modules for configuration management (config.py
), logging (logger.py
), and custom exceptions (distiller_exception.py
). (Seeutils/README.md
for details) - SDK (
distiller_cm5_sdk
): An external, installable package containing reusable components like Whisper (ASR) and Piper (TTS) wrappers. Used by components like the client UI (client/ui/App.py
) and the talk server (mcp_server/talk_server.py
). See Pamir-AI/distiller-cm5-sdk for details.
The primary user entry point is main.py
in the project root.
-
Install
uv
(Recommended Virtual Environment and Package Manager):curl -LsSf https://astral.sh/uv/install.sh | sh source $HOME/.cargo/env # Or add uv to your PATH manually
-
Create and Activate Virtual Environment:
# Navigate to the project root directory cd /path/to/distiller-cm5-python uv venv # Creates a .venv directory source .venv/bin/activate # Or `.\.venv\Scripts\activate` on Windows
-
Install Dependencies:
# Install this project's requirements AND the external SDK uv pip install -r requirements.txt # Ensure you have a requirements.txt file uv pip install distiller-cm5-sdk # Or install from a specific source if needed # Example manual installs if requirements.txt is missing: # uv pip install fastapi uvicorn "llama-cpp-python[server]" jinja2 pydantic PyQt6 QScintilla PyOpenGL mcp nest_asyncio ... # uv pip install distiller-cm5-sdk
Note: Installing
llama-cpp-python
might require C++ build tools. Refer to its documentation. Note: InstallingPyQt6
might have specific system dependencies. Note:distiller-cm5-sdk
might have its own dependencies (likeportaudio
forPyAudio
) - refer to its README. -
Download LLM Models (for Local LLM Server): Place your desired GGUF-format models into the
distiller_cm5_python/llm_server/models/
directory. -
Download SDK Models/Executables (if needed): Refer to the distiller-cm5-sdk README for instructions on downloading necessary model files (e.g., for Whisper and Piper) or executables required by the SDK components.
-
Configuration:
- Copy
distiller_cm5_python/utils/default_config.json
tomcp_config.json
in the project root (or your working directory) and customize settings likePROVIDER_TYPE
,SERVER_URL
,MODEL_NAME
, etc. - Alternatively, set environment variables (e.g.,
export SERVER_URL=http://...
). Configuration loaded byutils/config.py
prioritizes environment variables, thenmcp_config.json
, thendefault_config.json
.
- Copy
You need an LLM backend accessible. Choose one:
-
Option A: Run the Local LLM Server:
# Make sure environment is activated python -m distiller_cm5_python.llm_server.server --model-name your_model.gguf
Ensure the
SERVER_URL
in your configuration points to this server (e.g.,http://127.0.0.1:8000
). -
Option B: Use OpenRouter or other external API: Set
PROVIDER_TYPE
toopenrouter
(or similar identifier configured inclient/mid_layer/llm_client.py
) in your configuration. EnsureOPENROUTER_API_KEY
(or equivalent environment variable) is set. TheSERVER_URL
should point to the OpenRouter API endpoint (e.g.,https://openrouter.ai/api/v1
). OpenRouter provides access to various models including OpenAI, Anthropic, Google, etc. -
Option C: Use Llama.cpp directly (Managed by Client): Set
PROVIDER_TYPE
tollama-cpp
in your configuration. Themain.py
script will attempt to start/stop allama.cpp
server automatically if one isn't detected at the configuredSERVER_URL
. This requiresllama.cpp
to be compiled and the path to itsserver
executable might need configuration (checkclient/llm_infra/llama_manager.py
and potentially config).
If you want the client to use tools provided by an MCP server (like TTS or WiFi):
# Example: Run the talk server (uses distiller_cm5_sdk for TTS)
python -m distiller_cm5_python.mcp_server.talk_server
# Or the wifi server
# python -m distiller_cm5_python.mcp_server.wifi_server
Note the path to the running server script will be needed when launching the client (--server-script
argument).
The main entry point handles launching the client.
-
Run the GUI Client:
python main.py --gui [--server-script /path/to/running/mcp_server.py] [OTHER_OPTIONS]
- The
--gui
flag is essential. - Uses
distiller_cm5_sdk
for features like voice input. - Use
--server-script
if you want to connect to a running MCP tool server (liketalk_server.py
).
- The
-
Run the CLI Client:
python main.py [--server-script /path/to/running/mcp_server.py] [OTHER_OPTIONS]
- Omit the
--gui
flag. - Use
--server-script
if needed.
- Omit the
-
Optional Llama.cpp Management: If
PROVIDER_TYPE
isllama-cpp
,main.py
will check theSERVER_URL
before starting the client. If no server is running, it will attempt to launch one (requiresllama.cpp
server binary available and configured). It will also attempt to shut down this managed server on exit.
Refer to python main.py --help
for all client launch options.