Bantz won't be a helper; he will be your Host. Your computer will become his studio, and your tasks will give the "entertainment." He won't just execute code; he will "pull strings" behind the scenes with a smile that you can hear through the text.
Python
19
584 commits
updated Oct 17, 2026
Bantz is a local-first AI assistant that runs on your Linux machine and acts as a personal butler — it has a voice, remembers things across sessions, runs scheduled jobs overnight, controls your desktop, reads your email, and talks to you like a person who's known you long enough to be useful. It is also a small multi-agent system: the brain can hand tasks to specialist sub-agents (researcher, developer, reviewer) that run on their own small local models, serialized through a single LLM lane so a modest machine never runs two local inferences at once. The primary interface is the Operations Center desktop app (bantz --ui), with a bantz CLI alongside it. Everything is local by default. Nothing phones home unless you configure it to.
Screenshots and screen recordings live in bantz-demo/.
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
GIF walkthroughs:
The Brain (core/brain.py) sits at the center. Every request — typed, spoken, or sent via Telegram — goes through the same pipeline:
Input (Terminal / Voice / Telegram)
│
▼
Translation Layer core/translation_layer.py
│ MarianMT Turkish↔English bridge; all internal processing in English
│
▼
Memory Injector core/memory_injector.py
│ Injects: recent messages, desktop context, persona state, location
│
▼
OmniMemoryManager memory/omni_memory.py
│ Parallel asyncio recall — Graph (35%) + Vector (40%) + Deep (25%)
│ 400-token budget, entity-based re-ranking, zero sequential waiting
│
▼
Routing Engine core/routing_engine.py + core/intent.py
│ quick_route(): hardware controls (TTS stop, wake word, ducking)
│ cot_route(): Chain-of-Thought LLM routing — tool selection + risk
│
▼
Executor / Planner agent/executor.py + agent/planner.py
│ Plan-and-Solve multi-step execution with $REF variable binding
│ Step failure → circuit breaker, optional replan
│
▼
Finalizer core/finalizer.py
│ Butler persona enforcement, hallucination checks, error honesty
│
▼
Memory persistence MemPalace (ChromaDB + SQLite KG)
core/memory.py (session log, SQLite WAL)
Supporting systems run alongside the main loop:
llm/lane.py) — the single choke point for every agent/workflow/background LLM call: one local inference at a time, interactive chat gets priority, and Ollama keep_alive is managed per model class (conversation model stays warm 30 min, agent side-models unload after 5)agent/agent_manager.py + agent/sub_agent.py) — spawns ephemeral specialist sub-agents (researcher / developer / reviewer) with per-role small models (BANTZ_AGENT_MODELS), tool whitelists, concurrency caps, and timeouts; the brain routes suitable requests to them first-class (route="agent")agent/job_scheduler.py) — persistent SQLAlchemy job store, nightly maintenance/reflection/overnight email pollagent/ghost_loop.py) — wake word → VAD capture → STT → brain dispatch; started automatically by the daemon when voice is enabledagent/affinity_engine.py) — cumulative score [-100, 100] drives persona tiercore/event_bus.py) — decoupled pub/sub between brain, UI, voice, agents; delegation/job/workflow outcomes flow here with correlation IDscore/gps_server.py) — local HTTP server receiving phone location updatesConversation and memory
Voice pipeline (end-to-end: say the wake word → speak → Bantz answers out loud)
Scheduling and automation
Desktop and computer control
External integrations
Personality and adaptation
Security and permissions
BantzContext: safe / moderate / destructivey before executionDESTRUCTIVE_COMMANDS frozenset in tools/shell.py — rm -rf, mkfs, dd, etc.Infrastructure
.env, all aliasedInterfaces
bantz --ui. Six pages, all live over a local WebSocket (:8765):
bantz CLI as a secondary interface: bantz --once "query" for a single query, bantz --daemon for headless/systemd operation, bantz --doctor for health checksWeb intelligence (via the bundled bantz-web pipeline at vendor/bantz-web)
web_search — quick web lookup (under ~60s), tiered SearXNG → DuckDuckGo fallbackweb_research — deep, multi-source research producing a structured report; runs async with live progress streamed to the Broadcast Channel and a cancel controlweb_news — news pipeline: fetch + extract + summarize current headlines for a topicAnomaly Watch
Multi-agent
BANTZ_AGENT_MODELS (default gemma3:4b) so delegation doesn't evict your conversation modeldelegate_taskMulti-step workflows
$REF_STEP_N variable binding between stepsi18n
Wake word: requires a Porcupine access key from Picovoice (free). Without it the wake listener logs a warning and stays off while the rest of the voice stack (TTS/STT) keeps working. A fully local openWakeWord engine with a custom "Bantz" model — no external account at all — is the next planned replacement (epic #563).
VLM / vision analysis: runs locally by default via Ollama (BANTZ_VLM_BACKEND=ollama). Bantz uses a built-in multimodal path — the same local model that handles chat also reads the screen (e.g. gemma4:e4b-it-qat), with moondream as a lightweight fallback. A remote VLM endpoint (BANTZ_VLM_BACKEND=remote + BANTZ_VLM_ENDPOINT, e.g. a Jetson/Colab box) is optional for offloading.
Mood history display: bantz --mood-history prints a stub message. Mood data is recorded in SQLite but there's no display command since the Textual TUI was removed.
Observer: background log analysis via a small Ollama model (default qwen2.5:0.5b) — implemented but disabled by default (BANTZ_OBSERVER_ENABLED=false). Adds latency on low-end hardware.
RL engine: the old Q-learning engine was replaced by the Affinity Engine. The BANTZ_RL_ENABLED flag exists and gates the intervention/proactive systems, but the underlying RL training loop is no longer active.
Proactive interventions: implemented in agent/interventions.py, gated behind BANTZ_RL_ENABLED. Off by default. Not well-tested in the current build.
Autonomy confirmation: the Settings "Autonomy" dial is enforced on the single-tool path and on agent delegations (low = ask first), but the multi-step PlanExecutor does not yet check it per step — destructive shell commands there still gate only on their own DESTRUCTIVE_COMMANDS confirm.
Roadmap: Bantz is mid-way through becoming a fuller multi-agent system — a mail agent over a local mbsync/notmuch mail store (works offline), an event-driven "jury" agent that watches job failures and anomalies and files verdicts, loop agents on schedules, WhatsApp/Telegram awareness via a desktop-notification listener, and an Agents panel in the Operations Center. The full plan lives in epic #563.
web_research is Ollama-bound: deep research runs many local model calls, so on a memory-constrained machine the model can stall mid-run; it falls back gracefully but a full report needs a healthy Ollama.
Requirements: Python 3.11+, git, Ollama running locally
curl -fsSL https://raw.githubusercontent.com/miclaldogan/bantzv2/main/install.sh | bash
Checks Python and git, clones the repo to ~/.local/share/bantz/src, installs the package, fixes your PATH if needed, runs an interactive wizard to write your .env, and finishes with bantz --doctor.
git clone https://github.com/miclaldogan/bantzv2.git
cd bantzv2
pip install -e ".[dev]"
cp .env.example .env # then edit with your values
bantz --doctor
Voice pipeline (all optional — install only what you need):
pip install pvporcupine pyaudio webrtcvad # wake word + capture
pip install faster-whisper # STT
# Piper TTS: install binary from https://github.com/rhasspy/piper/releases
# put 'piper' in PATH, download a voice model .onnx file
MemPalace memory:
pip install mempalace
Google integrations:
# Create an OAuth 2.0 client in Google Cloud Console (Desktop app type)
# Download credentials.json to ~/.local/share/bantz/
bantz --setup google gmail
bantz --setup google classroom
Telegram:
bantz --setup telegram
Create a .env file in your working directory (or ~/.local/share/bantz/.env). Minimum working config:
# gemma4:e4b-it-qat is recommended: one multimodal model (~4B active / ~7.5B
# resident) serves chat, routing, finalizing AND screen vision — leanest on
# memory-constrained machines. Any Ollama chat model works (e.g. llama3.1:8b).
BANTZ_OLLAMA_MODEL=gemma4:e4b-it-qat
BANTZ_OLLAMA_BASE_URL=http://localhost:11434
# Optional: route through a separate smaller model. Empty (default) = routing
# uses BANTZ_OLLAMA_MODEL; an uninstalled model also falls back to it.
BANTZ_OLLAMA_ROUTING_MODEL=
# Conversation provider: ollama (local, default) | claude | gemini | openai
# Switchable live from Settings → Conversation Provider (persists to .env).
BANTZ_LLM_PROVIDER=ollama
# Multi-agent: sub-agents on their own small models, serialized through the
# LLM lane (interactive chat always has priority over agent traffic).
BANTZ_MULTI_AGENT_ENABLED=true
BANTZ_AGENT_MODELS={"researcher":"gemma3:4b","developer":"gemma3:4b","reviewer":"gemma3:4b"}
# Model residency: conversation model stays warm; agent models unload fast.
BANTZ_OLLAMA_KEEP_ALIVE=30m
BANTZ_OLLAMA_BG_KEEP_ALIVE=5m
# Claude / Anthropic
BANTZ_ANTHROPIC_API_KEY=your_key_here
BANTZ_ANTHROPIC_MODEL=claude-sonnet-4-6
# Gemini
BANTZ_GEMINI_API_KEY=your_key_here
BANTZ_GEMINI_MODEL=gemini-2.0-flash
# OpenAI
BANTZ_OPENAI_API_KEY=your_key_here
BANTZ_OPENAI_MODEL=gpt-4o-mini
# Voice (wake word)
BANTZ_PORCUPINE_ACCESS_KEY=your_picovoice_key
# Primary language (default Turkish)
BANTZ_LANGUAGE=tr
# Memory
BANTZ_MEMPALACE_ENABLED=true
Full reference in src/bantz/config.py — every field has a comment.
bantz --setup profile # name, timezone, city — stored in SQLite
bantz --setup places # named GPS locations (home, office, etc.)
bantz --setup schedule # weekly timetable
bantz --setup google gmail # Google OAuth for Gmail
bantz --setup google classroom # Google OAuth for Classroom
bantz --setup telegram # Telegram bot token
bantz --setup systemd # install + enable systemd user service
bantz --setup systemd --check # show service status, PID, memory, uptime
# Operations Center — the Tauri desktop UI (starts the daemon if not running)
bantz --ui
# Headless daemon — APScheduler drives all background jobs (UI connects to this)
bantz --daemon
# Single query from the CLI, no UI
bantz --once "what's on my calendar today?"
# System health check
bantz --doctor
# Show running config (secrets masked)
bantz --config
Scheduled job management:
bantz --jobs # list all APScheduler jobs
bantz --run-job nightly_maintenance # trigger any job immediately
bantz --maintenance # run maintenance workflow now
bantz --reflect # run reflection now
bantz --reflections # view last 10 reflections
bantz --overnight-poll # run one overnight poll cycle
Systemd service (recommended for daemon mode):
bantz --setup systemd
# writes ~/.config/systemd/user/bantz.service
# enables linger, enables and starts the service
systemctl --user status bantz
journalctl --user -u bantz -f
src/bantz/
├── __main__.py entry point, CLI argument routing
├── config.py pydantic-settings, ~70 env vars
├── cli/
│ └── setup.py all setup wizards and --doctor diagnostics
├── core/
│ ├── brain.py central orchestrator
│ ├── routing_engine.py quick_route + plan-and-solve dispatch
│ ├── intent.py CoT LLM routing (cot_route)
│ ├── finalizer.py butler persona + hallucination check
│ ├── memory_injector.py context assembly before LLM call
│ ├── prompt_builder.py system prompt composition
│ └── workflow.py inline multi-tool workflow detection
├── memory/
│ ├── bridge.py MemPalace adapter (replaces 8 old modules)
│ └── omni_memory.py parallel hybrid recall orchestrator
├── agent/
│ ├── executor.py plan-and-solve step runner
│ ├── planner.py LLM plan generator
│ ├── job_scheduler.py APScheduler wrapper
│ ├── affinity_engine.py bonding score + persona tier
│ ├── ghost_loop.py wake→capture→STT→dispatch cycle
│ ├── wake_word.py Porcupine always-on listener
│ ├── voice_capture.py WebRTC VAD recording
│ ├── stt.py faster-whisper transcription
│ ├── tts.py Piper + aplay synthesis
│ ├── audio_ducker.py system volume control during speech
│ ├── ambient.py environment sound classifier
│ ├── observer.py background log analysis
│ ├── notifier.py desktop notifications
│ ├── interventions.py proactive suggestion queue
│ └── workflows/ nightly maintenance, reflection, overnight poll
├── data/
│ ├── layer.py DataLayer singleton, unified store init
│ ├── sqlite_store.py profile, places, schedule, session, KV stores
│ └── connection_pool.py WAL-mode thread-safe SQLite pool
├── interface/
│ ├── ws_server.py WebSocket server (:8765) — backend for the desktop UI
│ └── live_ui.py legacy CLI status view
├── integrations/
│ └── telegram_bot.py Telegram remote access bot
├── tools/ 31 registered tools (shell, gmail, calendar, ...)
├── llm/
│ ├── router.py provider selector (ollama | claude | gemini | openai)
│ ├── ollama.py local Ollama client (default)
│ ├── anthropic_client.py Claude / Anthropic client
│ ├── gemini.py Gemini client
│ └── openai_client.py OpenAI client
├── personality/
│ ├── persona.py system prompt persona layer
│ ├── bonding.py interaction scoring
│ └── greeting.py morning briefing generation
├── auth/ Google OAuth2 PKCE flow
└── i18n/
└── bridge.py MarianMT translation bridge
pytest # full suite
pytest tests/core/ # core modules only
pytest --cov=bantz # coverage report (target: 65%)
The test suite passes on Python 3.11 and 3.12 (the Tests CI workflow is required green before any PR merges to main).
Core (always installed):
ollama — local LLM server (separate binary install, not pip)httpx — async HTTP for Ollama and Geminipydantic-settings — config from envrich — terminal UIaioconsole — async terminal inputapscheduler + sqlalchemy — persistent job schedulingpsutil — system stats (CPU/RAM/VRAM/DISK)python-telegram-bot — Telegram integrationmempalace — ChromaDB + KG memory stackOptional (install as needed):
pvporcupine, pyaudio — wake word detectionwebrtcvad — voice activity detectionfaster-whisper — local STTpiper (binary) — local TTStransformers, torch, sentencepiece — MarianMT translation (pip install -e ".[translation]")pymupdf, python-docx — document reading (pip install -e ".[docs]")pyautogui, pynput — desktop automation (pip install -e ".[automation]")Bantz won't be a helper; he will be your Host. Your computer will become his studio, and your tasks will give the "entertainment." He won't just execute code; he will "pull strings" behind the scenes with a smile that you can hear through the text.
Python
19
584 commits
updated Oct 17, 2026
Bantz is a local-first AI assistant that runs on your Linux machine and acts as a personal butler — it has a voice, remembers things across sessions, runs scheduled jobs overnight, controls your desktop, reads your email, and talks to you like a person who's known you long enough to be useful. It is also a small multi-agent system: the brain can hand tasks to specialist sub-agents (researcher, developer, reviewer) that run on their own small local models, serialized through a single LLM lane so a modest machine never runs two local inferences at once. The primary interface is the Operations Center desktop app (bantz --ui), with a bantz CLI alongside it. Everything is local by default. Nothing phones home unless you configure it to.
Screenshots and screen recordings live in bantz-demo/.
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
GIF walkthroughs:
The Brain (core/brain.py) sits at the center. Every request — typed, spoken, or sent via Telegram — goes through the same pipeline:
Input (Terminal / Voice / Telegram)
│
▼
Translation Layer core/translation_layer.py
│ MarianMT Turkish↔English bridge; all internal processing in English
│
▼
Memory Injector core/memory_injector.py
│ Injects: recent messages, desktop context, persona state, location
│
▼
OmniMemoryManager memory/omni_memory.py
│ Parallel asyncio recall — Graph (35%) + Vector (40%) + Deep (25%)
│ 400-token budget, entity-based re-ranking, zero sequential waiting
│
▼
Routing Engine core/routing_engine.py + core/intent.py
│ quick_route(): hardware controls (TTS stop, wake word, ducking)
│ cot_route(): Chain-of-Thought LLM routing — tool selection + risk
│
▼
Executor / Planner agent/executor.py + agent/planner.py
│ Plan-and-Solve multi-step execution with $REF variable binding
│ Step failure → circuit breaker, optional replan
│
▼
Finalizer core/finalizer.py
│ Butler persona enforcement, hallucination checks, error honesty
│
▼
Memory persistence MemPalace (ChromaDB + SQLite KG)
core/memory.py (session log, SQLite WAL)
Supporting systems run alongside the main loop:
llm/lane.py) — the single choke point for every agent/workflow/background LLM call: one local inference at a time, interactive chat gets priority, and Ollama keep_alive is managed per model class (conversation model stays warm 30 min, agent side-models unload after 5)agent/agent_manager.py + agent/sub_agent.py) — spawns ephemeral specialist sub-agents (researcher / developer / reviewer) with per-role small models (BANTZ_AGENT_MODELS), tool whitelists, concurrency caps, and timeouts; the brain routes suitable requests to them first-class (route="agent")agent/job_scheduler.py) — persistent SQLAlchemy job store, nightly maintenance/reflection/overnight email pollagent/ghost_loop.py) — wake word → VAD capture → STT → brain dispatch; started automatically by the daemon when voice is enabledagent/affinity_engine.py) — cumulative score [-100, 100] drives persona tiercore/event_bus.py) — decoupled pub/sub between brain, UI, voice, agents; delegation/job/workflow outcomes flow here with correlation IDscore/gps_server.py) — local HTTP server receiving phone location updatesConversation and memory
Voice pipeline (end-to-end: say the wake word → speak → Bantz answers out loud)
Scheduling and automation
Desktop and computer control
External integrations
Personality and adaptation
Security and permissions
BantzContext: safe / moderate / destructivey before executionDESTRUCTIVE_COMMANDS frozenset in tools/shell.py — rm -rf, mkfs, dd, etc.Infrastructure
.env, all aliasedInterfaces
bantz --ui. Six pages, all live over a local WebSocket (:8765):
bantz CLI as a secondary interface: bantz --once "query" for a single query, bantz --daemon for headless/systemd operation, bantz --doctor for health checksWeb intelligence (via the bundled bantz-web pipeline at vendor/bantz-web)
web_search — quick web lookup (under ~60s), tiered SearXNG → DuckDuckGo fallbackweb_research — deep, multi-source research producing a structured report; runs async with live progress streamed to the Broadcast Channel and a cancel controlweb_news — news pipeline: fetch + extract + summarize current headlines for a topicAnomaly Watch
Multi-agent
BANTZ_AGENT_MODELS (default gemma3:4b) so delegation doesn't evict your conversation modeldelegate_taskMulti-step workflows
$REF_STEP_N variable binding between stepsi18n
Wake word: requires a Porcupine access key from Picovoice (free). Without it the wake listener logs a warning and stays off while the rest of the voice stack (TTS/STT) keeps working. A fully local openWakeWord engine with a custom "Bantz" model — no external account at all — is the next planned replacement (epic #563).
VLM / vision analysis: runs locally by default via Ollama (BANTZ_VLM_BACKEND=ollama). Bantz uses a built-in multimodal path — the same local model that handles chat also reads the screen (e.g. gemma4:e4b-it-qat), with moondream as a lightweight fallback. A remote VLM endpoint (BANTZ_VLM_BACKEND=remote + BANTZ_VLM_ENDPOINT, e.g. a Jetson/Colab box) is optional for offloading.
Mood history display: bantz --mood-history prints a stub message. Mood data is recorded in SQLite but there's no display command since the Textual TUI was removed.
Observer: background log analysis via a small Ollama model (default qwen2.5:0.5b) — implemented but disabled by default (BANTZ_OBSERVER_ENABLED=false). Adds latency on low-end hardware.
RL engine: the old Q-learning engine was replaced by the Affinity Engine. The BANTZ_RL_ENABLED flag exists and gates the intervention/proactive systems, but the underlying RL training loop is no longer active.
Proactive interventions: implemented in agent/interventions.py, gated behind BANTZ_RL_ENABLED. Off by default. Not well-tested in the current build.
Autonomy confirmation: the Settings "Autonomy" dial is enforced on the single-tool path and on agent delegations (low = ask first), but the multi-step PlanExecutor does not yet check it per step — destructive shell commands there still gate only on their own DESTRUCTIVE_COMMANDS confirm.
Roadmap: Bantz is mid-way through becoming a fuller multi-agent system — a mail agent over a local mbsync/notmuch mail store (works offline), an event-driven "jury" agent that watches job failures and anomalies and files verdicts, loop agents on schedules, WhatsApp/Telegram awareness via a desktop-notification listener, and an Agents panel in the Operations Center. The full plan lives in epic #563.
web_research is Ollama-bound: deep research runs many local model calls, so on a memory-constrained machine the model can stall mid-run; it falls back gracefully but a full report needs a healthy Ollama.
Requirements: Python 3.11+, git, Ollama running locally
curl -fsSL https://raw.githubusercontent.com/miclaldogan/bantzv2/main/install.sh | bash
Checks Python and git, clones the repo to ~/.local/share/bantz/src, installs the package, fixes your PATH if needed, runs an interactive wizard to write your .env, and finishes with bantz --doctor.
git clone https://github.com/miclaldogan/bantzv2.git
cd bantzv2
pip install -e ".[dev]"
cp .env.example .env # then edit with your values
bantz --doctor
Voice pipeline (all optional — install only what you need):
pip install pvporcupine pyaudio webrtcvad # wake word + capture
pip install faster-whisper # STT
# Piper TTS: install binary from https://github.com/rhasspy/piper/releases
# put 'piper' in PATH, download a voice model .onnx file
MemPalace memory:
pip install mempalace
Google integrations:
# Create an OAuth 2.0 client in Google Cloud Console (Desktop app type)
# Download credentials.json to ~/.local/share/bantz/
bantz --setup google gmail
bantz --setup google classroom
Telegram:
bantz --setup telegram
Create a .env file in your working directory (or ~/.local/share/bantz/.env). Minimum working config:
# gemma4:e4b-it-qat is recommended: one multimodal model (~4B active / ~7.5B
# resident) serves chat, routing, finalizing AND screen vision — leanest on
# memory-constrained machines. Any Ollama chat model works (e.g. llama3.1:8b).
BANTZ_OLLAMA_MODEL=gemma4:e4b-it-qat
BANTZ_OLLAMA_BASE_URL=http://localhost:11434
# Optional: route through a separate smaller model. Empty (default) = routing
# uses BANTZ_OLLAMA_MODEL; an uninstalled model also falls back to it.
BANTZ_OLLAMA_ROUTING_MODEL=
# Conversation provider: ollama (local, default) | claude | gemini | openai
# Switchable live from Settings → Conversation Provider (persists to .env).
BANTZ_LLM_PROVIDER=ollama
# Multi-agent: sub-agents on their own small models, serialized through the
# LLM lane (interactive chat always has priority over agent traffic).
BANTZ_MULTI_AGENT_ENABLED=true
BANTZ_AGENT_MODELS={"researcher":"gemma3:4b","developer":"gemma3:4b","reviewer":"gemma3:4b"}
# Model residency: conversation model stays warm; agent models unload fast.
BANTZ_OLLAMA_KEEP_ALIVE=30m
BANTZ_OLLAMA_BG_KEEP_ALIVE=5m
# Claude / Anthropic
BANTZ_ANTHROPIC_API_KEY=your_key_here
BANTZ_ANTHROPIC_MODEL=claude-sonnet-4-6
# Gemini
BANTZ_GEMINI_API_KEY=your_key_here
BANTZ_GEMINI_MODEL=gemini-2.0-flash
# OpenAI
BANTZ_OPENAI_API_KEY=your_key_here
BANTZ_OPENAI_MODEL=gpt-4o-mini
# Voice (wake word)
BANTZ_PORCUPINE_ACCESS_KEY=your_picovoice_key
# Primary language (default Turkish)
BANTZ_LANGUAGE=tr
# Memory
BANTZ_MEMPALACE_ENABLED=true
Full reference in src/bantz/config.py — every field has a comment.
bantz --setup profile # name, timezone, city — stored in SQLite
bantz --setup places # named GPS locations (home, office, etc.)
bantz --setup schedule # weekly timetable
bantz --setup google gmail # Google OAuth for Gmail
bantz --setup google classroom # Google OAuth for Classroom
bantz --setup telegram # Telegram bot token
bantz --setup systemd # install + enable systemd user service
bantz --setup systemd --check # show service status, PID, memory, uptime
# Operations Center — the Tauri desktop UI (starts the daemon if not running)
bantz --ui
# Headless daemon — APScheduler drives all background jobs (UI connects to this)
bantz --daemon
# Single query from the CLI, no UI
bantz --once "what's on my calendar today?"
# System health check
bantz --doctor
# Show running config (secrets masked)
bantz --config
Scheduled job management:
bantz --jobs # list all APScheduler jobs
bantz --run-job nightly_maintenance # trigger any job immediately
bantz --maintenance # run maintenance workflow now
bantz --reflect # run reflection now
bantz --reflections # view last 10 reflections
bantz --overnight-poll # run one overnight poll cycle
Systemd service (recommended for daemon mode):
bantz --setup systemd
# writes ~/.config/systemd/user/bantz.service
# enables linger, enables and starts the service
systemctl --user status bantz
journalctl --user -u bantz -f
src/bantz/
├── __main__.py entry point, CLI argument routing
├── config.py pydantic-settings, ~70 env vars
├── cli/
│ └── setup.py all setup wizards and --doctor diagnostics
├── core/
│ ├── brain.py central orchestrator
│ ├── routing_engine.py quick_route + plan-and-solve dispatch
│ ├── intent.py CoT LLM routing (cot_route)
│ ├── finalizer.py butler persona + hallucination check
│ ├── memory_injector.py context assembly before LLM call
│ ├── prompt_builder.py system prompt composition
│ └── workflow.py inline multi-tool workflow detection
├── memory/
│ ├── bridge.py MemPalace adapter (replaces 8 old modules)
│ └── omni_memory.py parallel hybrid recall orchestrator
├── agent/
│ ├── executor.py plan-and-solve step runner
│ ├── planner.py LLM plan generator
│ ├── job_scheduler.py APScheduler wrapper
│ ├── affinity_engine.py bonding score + persona tier
│ ├── ghost_loop.py wake→capture→STT→dispatch cycle
│ ├── wake_word.py Porcupine always-on listener
│ ├── voice_capture.py WebRTC VAD recording
│ ├── stt.py faster-whisper transcription
│ ├── tts.py Piper + aplay synthesis
│ ├── audio_ducker.py system volume control during speech
│ ├── ambient.py environment sound classifier
│ ├── observer.py background log analysis
│ ├── notifier.py desktop notifications
│ ├── interventions.py proactive suggestion queue
│ └── workflows/ nightly maintenance, reflection, overnight poll
├── data/
│ ├── layer.py DataLayer singleton, unified store init
│ ├── sqlite_store.py profile, places, schedule, session, KV stores
│ └── connection_pool.py WAL-mode thread-safe SQLite pool
├── interface/
│ ├── ws_server.py WebSocket server (:8765) — backend for the desktop UI
│ └── live_ui.py legacy CLI status view
├── integrations/
│ └── telegram_bot.py Telegram remote access bot
├── tools/ 31 registered tools (shell, gmail, calendar, ...)
├── llm/
│ ├── router.py provider selector (ollama | claude | gemini | openai)
│ ├── ollama.py local Ollama client (default)
│ ├── anthropic_client.py Claude / Anthropic client
│ ├── gemini.py Gemini client
│ └── openai_client.py OpenAI client
├── personality/
│ ├── persona.py system prompt persona layer
│ ├── bonding.py interaction scoring
│ └── greeting.py morning briefing generation
├── auth/ Google OAuth2 PKCE flow
└── i18n/
└── bridge.py MarianMT translation bridge
pytest # full suite
pytest tests/core/ # core modules only
pytest --cov=bantz # coverage report (target: 65%)
The test suite passes on Python 3.11 and 3.12 (the Tests CI workflow is required green before any PR merges to main).
Core (always installed):
ollama — local LLM server (separate binary install, not pip)httpx — async HTTP for Ollama and Geminipydantic-settings — config from envrich — terminal UIaioconsole — async terminal inputapscheduler + sqlalchemy — persistent job schedulingpsutil — system stats (CPU/RAM/VRAM/DISK)python-telegram-bot — Telegram integrationmempalace — ChromaDB + KG memory stackOptional (install as needed):
pvporcupine, pyaudio — wake word detectionwebrtcvad — voice activity detectionfaster-whisper — local STTpiper (binary) — local TTStransformers, torch, sentencepiece — MarianMT translation (pip install -e ".[translation]")pymupdf, python-docx — document reading (pip install -e ".[docs]")pyautogui, pynput — desktop automation (pip install -e ".[automation]")