# wetqv/snapmatch architecture

> Architecture diagram of the GitHub repository wetqv/snapmatch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-07-31). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/wetqv/snapmatch
- Repository: https://github.com/wetqv/snapmatch

## Overview

#### Purpose and entry points
SnapMatch is a local desktop control plane for a Telegram AI bot. It combines bot operation, model routing, MCP tool use, voice transcription, persistent message history, and a secretary workflow. `main.py` is the application entry point; it starts the PyQt6 administration UI and bot/server lifecycle. Configuration is loaded from `config/settings.py`, with a user-created local `config.json`.

#### Desktop administration and lifecycle
The PyQt6 GUI is the primary operator interface, centered on `gui/admin_dashboard.py` and the modular admin panel under `gui/admin_panel/`. It exposes settings, user management, message history, voice settings, secretary controls, MCP configuration, and server start/stop control. `gui/admin_panel/server_control.py` forms the important boundary between UI actions and bot runtime state.

#### Telegram ingestion and command surface
Telegram updates enter through handler modules in `bot/handlers/`, separating commands, menus, regular messages, and stateful interactions:
- `bot/handlers/command_handlers.py`
- `bot/handlers/message_handlers.py`
- `bot/handlers/menu_handlers.py`

Handlers delegate rather than directly implementing model/database logic. Queue and active-task management (`bot/handlers/queue_manager.py`, `bot/handlers/active_tasks_registry.py`) protect the runtime from concurrent or long-running user requests.

#### AI request pipeline and model providers
The main response path is service-oriented: incoming text/media is normalized, context is assembled, a model request is built, and a selected configured model is invoked. Core stages are represented by:
- `bot/handlers/services/message_processor.py`
- `bot/handlers/services/request_processor.py`
- `bot/handlers/services/model_request_builder.py`
- `bot/handlers/services/model_client_manager.py`

Configured model backends include OpenAI-compatible endpoints, OpenRouter, Groq, and local compatible services. Prompt/context boundaries are managed in `prompt_manager.py` and `context_manager.py`, allowing user/history context to be isolated from provider-client behavior.

#### MCP tool integration
MCP is an explicit tool-execution subsystem rather than ad hoc model output handling. `bot/handlers/services/mcp_registry.py` registers/discovers servers and tools, `mcp_runtime.py` executes them, and `mcp_permissions.py` applies access controls. MCP configuration and persistence are surfaced through:
- `bot/handlers/services/mcp_runtime.py`
- `bot/handlers/services/mcp_permissions.py`
- `utils/database/mcp_db.py`
- `gui/admin_panel/mcp_tab.py`

The included `examples/mcp/simple_snapmatch_mcp.py` defines the expected external MCP-server integration model.

#### Secretary and deferred-response workflow
Secretary mode is a separate intake, debounce, queue-policy, and response pipeline for incoming communications. Its orchestration spans:
- `bot/handlers/secretary_runtime.py`
- `bot/handlers/services/secretary_intake.py`
- `bot/handlers/services/secretary_queue_policy.py`
- `bot/handlers/services/secretary_response.py`

This separates assistant-style direct replies from managed/deferred secretary processing, with durable secretary data in `utils/database/secretary_db.py`.

#### Persistence, media, and local services
All operational data is local: database access is centralized through `utils/database/database_manager.py`, with specialized stores for users, messages, MCP, and secretary state. `utils/encryption.py` protects sensitive local material. Voice handling in `utils/voice_processor.py` integrates Vosk, OpenAI Whisper, or Groq; packaged deployments may use FFmpeg. Image and rich Telegram output processing are isolated in `bot/handlers/services/image_processor.py` and `rich_message_sender.py`.

#### Packaging and deployment
The application is packaged as a desktop executable, not deployed as a hosted web service. PyInstaller uses `snapmatch.spec`; Windows installer construction uses `SnapMatch_Installer.iss`. Linux Debian packaging is driven by `packaging/linux/build_deb.sh` and release automation by `.github/workflows/release-build.yml`.

Main entry points: [`bot/handlers/services/request_processor.py`](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/request_processor.py) (Request processor), [`gui/admin_dashboard.py`](https://github.com/wetqv/snapmatch/blob/main/gui/admin_dashboard.py) (Admin dashboard), [`bot/handlers/message_handlers.py`](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/message_handlers.py) (Telegram handlers), [`bot/handlers/queue_manager.py`](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/queue_manager.py) (Request queue)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop control plane"]
  node_main["Application entry point<br/>Python bootstrap<br/>[main.py]"]
  node_settings["Settings loader<br/>configuration<br/>[settings.py]"]
  node_dashboard["Admin dashboard<br/>PyQt6 UI<br/>[admin_dashboard.py]"]
  node_server_control["Server control<br/>UI-runtime boundary<br/>[server_control.py]"]
end

subgraph group_runtime["Telegram runtime"]
  node_telegram_handlers["Telegram handlers<br/>update routing"]
  node_queue["Request queue<br/>concurrency control<br/>[queue_manager.py]"]
  node_active_tasks["Active task registry<br/>task tracking"]
  node_secretary_runtime["Secretary workflow<br/>deferred-response orchestration"]
end

subgraph group_ai["AI and tools"]
  node_message_processor["Message processor<br/>normalization"]
  node_request_processor["Request processor<br/>orchestrator"]
  node_model_request["Model request builder<br/>request construction"]
  node_context_prompt["Prompt and context<br/>context boundary"]
  node_model_clients{{"Model client manager<br/>provider routing"}}
  node_mcp_registry["MCP registry<br/>tool discovery<br/>[mcp_registry.py]"]
  node_mcp_runtime{{"MCP runtime<br/>tool execution<br/>[mcp_runtime.py]"}}
end

subgraph group_local["Local data and media"]
  node_database[("Database manager<br/>local persistence")]
  node_mcp_store[("MCP store<br/>tool persistence<br/>[mcp_db.py]")]
  node_secretary_store[("Secretary store<br/>workflow persistence<br/>[secretary_db.py]")]
  node_media["Voice and rich media<br/>media processing<br/>[voice_processor.py]"]
end

subgraph group_distribution["Packaging"]
  node_release["Desktop packaging<br/>release pipeline<br/>[snapmatch.spec]"]
end

node_main -->|"loads"| node_settings
node_main -->|"starts"| node_dashboard
node_dashboard -->|"hosts"| node_server_control
node_server_control -->|"controls lifecycle"| node_telegram_handlers
node_telegram_handlers -->|"queues requests"| node_queue
node_queue -->|"tracks"| node_active_tasks
node_queue -->|"dispatches"| node_message_processor
node_telegram_handlers -->|"routes secretary mode"| node_secretary_runtime
node_message_processor -->|"processes media"| node_media
node_message_processor -->|"normalized input"| node_request_processor
node_request_processor -->|"assembles context"| node_context_prompt
node_request_processor -->|"builds"| node_model_request
node_model_request -->|"invokes"| node_model_clients
node_request_processor -->|"uses tools"| node_mcp_runtime
node_mcp_registry -->|"provides tools"| node_mcp_runtime
node_mcp_runtime -->|"uses configuration"| node_mcp_store
node_dashboard -->|"administers"| node_mcp_store
node_request_processor -->|"reads history"| node_database
node_secretary_runtime -->|"persists workflow"| node_secretary_store
node_dashboard -->|"manages local data"| node_database
node_release -.->|"packages"| node_main

click node_main "https://github.com/wetqv/snapmatch/blob/main/main.py"
click node_settings "https://github.com/wetqv/snapmatch/blob/main/config/settings.py"
click node_dashboard "https://github.com/wetqv/snapmatch/blob/main/gui/admin_dashboard.py"
click node_server_control "https://github.com/wetqv/snapmatch/blob/main/gui/admin_panel/server_control.py"
click node_telegram_handlers "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/message_handlers.py"
click node_queue "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/queue_manager.py"
click node_active_tasks "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/active_tasks_registry.py"
click node_message_processor "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/message_processor.py"
click node_request_processor "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/request_processor.py"
click node_model_request "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/model_request_builder.py"
click node_model_clients "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/model_client_manager.py"
click node_mcp_registry "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/mcp_registry.py"
click node_mcp_runtime "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/mcp_runtime.py"
click node_secretary_runtime "https://github.com/wetqv/snapmatch/blob/main/bot/handlers/secretary_runtime.py"
click node_database "https://github.com/wetqv/snapmatch/blob/main/utils/database/database_manager.py"
click node_mcp_store "https://github.com/wetqv/snapmatch/blob/main/utils/database/mcp_db.py"
click node_secretary_store "https://github.com/wetqv/snapmatch/blob/main/utils/database/secretary_db.py"
click node_media "https://github.com/wetqv/snapmatch/blob/main/utils/voice_processor.py"
click node_release "https://github.com/wetqv/snapmatch/blob/main/snapmatch.spec"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_settings,node_dashboard,node_server_control toneBlue
class node_telegram_handlers,node_queue,node_active_tasks,node_secretary_runtime toneAmber
class node_message_processor,node_request_processor,node_model_request,node_context_prompt,node_model_clients,node_mcp_registry,node_mcp_runtime toneMint
class node_database,node_mcp_store,node_secretary_store,node_media toneRose
class node_release toneIndigo
```

## Components

### Desktop control plane

- [Application entry point](https://github.com/wetqv/snapmatch/blob/main/main.py): Python bootstrap · Starts the PyQt administration UI and bot lifecycle. · `main.py`
- [Settings loader](https://github.com/wetqv/snapmatch/blob/main/config/settings.py): configuration · Loads settings and user-created local config.json. · `config/settings.py`
- [Admin dashboard](https://github.com/wetqv/snapmatch/blob/main/gui/admin_dashboard.py): PyQt6 UI · Operator interface for settings, users, history, tools, and runtime controls. · `gui/admin_dashboard.py`
- [Server control](https://github.com/wetqv/snapmatch/blob/main/gui/admin_panel/server_control.py): UI-runtime boundary · Maps UI start and stop actions to bot runtime state. · `gui/admin_panel/server_control.py`

### Telegram runtime

- [Telegram handlers](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/message_handlers.py): update routing · Command, menu, and message handlers delegate incoming updates. · `bot/handlers/message_handlers.py`
- [Request queue](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/queue_manager.py): concurrency control · Protects the runtime from concurrent and long-running requests. · `bot/handlers/queue_manager.py`
- [Active task registry](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/active_tasks_registry.py): task tracking · `bot/handlers/active_tasks_registry.py`
- [Secretary workflow](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/secretary_runtime.py): deferred-response orchestration · Runs separate intake, debounce, queue policy, and response processing. · `bot/handlers/secretary_runtime.py`

### AI and tools

- [Message processor](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/message_processor.py): normalization · Normalizes incoming text and media for processing. · `bot/handlers/services/message_processor.py`
- [Request processor](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/request_processor.py): orchestrator · Assembles context and routes requests through the AI pipeline. · `bot/handlers/services/request_processor.py`
- [Model request builder](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/model_request_builder.py): request construction · `bot/handlers/services/model_request_builder.py`
- **Prompt and context**: context boundary · Isolates user and history context from provider clients.
- [Model client manager](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/model_client_manager.py): provider routing · Selects configured OpenAI-compatible, OpenRouter, Groq, or local providers. · `bot/handlers/services/model_client_manager.py`
- [MCP registry](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/mcp_registry.py): tool discovery · Registers MCP servers and tools. · `bot/handlers/services/mcp_registry.py`
- [MCP runtime](https://github.com/wetqv/snapmatch/blob/main/bot/handlers/services/mcp_runtime.py): tool execution · Executes discovered tools under access controls. · `bot/handlers/services/mcp_runtime.py`

### Local data and media

- [Database manager](https://github.com/wetqv/snapmatch/blob/main/utils/database/database_manager.py): local persistence · Central access point for users, messages, MCP, and secretary stores. · `utils/database/database_manager.py`
- [MCP store](https://github.com/wetqv/snapmatch/blob/main/utils/database/mcp_db.py): tool persistence · `utils/database/mcp_db.py`
- [Secretary store](https://github.com/wetqv/snapmatch/blob/main/utils/database/secretary_db.py): workflow persistence · `utils/database/secretary_db.py`
- [Voice and rich media](https://github.com/wetqv/snapmatch/blob/main/utils/voice_processor.py): media processing · Transcribes voice and processes images and rich Telegram output. · `utils/voice_processor.py`

### Packaging

- [Desktop packaging](https://github.com/wetqv/snapmatch/blob/main/snapmatch.spec): release pipeline · Builds executable, Windows installer, and Linux Debian packages. · `snapmatch.spec`

## Connections

- Application entry point → Settings loader: loads
- Application entry point → Admin dashboard: starts
- Admin dashboard → Server control: hosts
- Server control → Telegram handlers: controls lifecycle
- Telegram handlers → Request queue: queues requests
- Request queue → Active task registry: tracks
- Request queue → Message processor: dispatches
- Telegram handlers → Secretary workflow: routes secretary mode
- Message processor → Voice and rich media: processes media
- Message processor → Request processor: normalized input
- Request processor → Prompt and context: assembles context
- Request processor → Model request builder: builds
- Model request builder → Model client manager: invokes
- Request processor → MCP runtime: uses tools
- MCP registry → MCP runtime: provides tools
- MCP runtime → MCP store: uses configuration
- Admin dashboard → MCP store: administers
- Request processor → Database manager: reads history
- Secretary workflow → Secretary store: persists workflow
- Admin dashboard → Database manager: manages local data
- Desktop packaging → Application entry point: packages
