"Where sabers rest, stories float, and agents run the bar."
Welcome to the Scummbar AI! This is an open-source, hands-on study repository designed to teach developers how to build, orchestrate, and maintain a complex, multi-agent conversational application using Google Agent Development Kit (ADK), Gemini, and DeepSeek, integrated directly into Telegram and REST APIs.
Instead of a dry reference manual, this documentation is structured didactically to guide you through the architectural decisions, the code design, and the modern AI-assisted workflows used to build and evolve this project.
- ๐ The Story & The Characters
- ๐ Quick Start (Run First, Learn Later)
- ๐๏ธ Architectural Blueprint & Technical Choices (ADK + Telegram)
- ๐ค AI-Assisted Development: The Pi-Agent Autopilot
The Scummbar is a legendary Caribbean pirate tavern. It is a shared multi-agent environment where AI-powered characters live, listen, and interact with patrons in real-time.
| Character | Role | Didactic Purpose | Personality Vibe |
|---|---|---|---|
| ๐บ Barnaby | Bartender | Demonstrates Tool Calling (Memory Read/Write, Text Artifact generation) and ADK Skills Auto-Discovery | Empathetic, quiet, knows every pirate's secret, mixes unforgettable custom grogs. |
| ๐ฑ Barnacle | Tavern Cat | Demonstrates Read-Only Shared Memory and Ephemeral Telegram Messaging (whispering to specific users) | Crotchety, speaks rarely, sleeps on ammo crates, dislikes loud patrons. |
| ๐ฎ Isolde | Fortune Teller | Demonstrates Independent Multi-Auth Routing and Multimodal Image Generation (native Gemini 3.1 Flash Image + Pillow PIL fallback) | Cryptic, majestic, sits in the Shadow Corner, extracts mystical tarot cards. |
| ๐งญ Balthazar | Navigator & Cartographer | Demonstrates Live RSS Feed Fetching & Pompous Comedic Translation, Sub-Agent Delegation, and Text Artifact Generation (Portolans & Charts) | Eccentric, theatrically solemn, turns political bickering and tech news into epic maritime-fantasy lore with unintentional hilarity. |
Follow these steps to get the Scummbar running on your local machine, Web UI, or Telegram group in minutes.
- Python 3.11+
- A Google Gemini API Key (from Google AI Studio) OR a Google Cloud Service Account (Vertex AI).
- A Telegram Bot Token from @BotFather (optional, for Telegram delivery).
# Clone the repository
git clone https://github.com/goldfix/ScummBarAI.git
cd ScummBarAI
# Initialize and create the virtual environment
source py_env.sh init_py
# Activate the environment
source py-env/bin/activate # or: source py_env.sh activeCopy .env.example or create a file named src/scummbar_chat/.env. This file is divided into 6 logical sections based on purpose:
# ===========================================================================
# ๐ SECTION 1: CORE GEMINI AUTHENTICATION (Chat & Compaction Auth)
# ===========================================================================
# Choose ONE of the two options (A or B) and comment out the other.
# --- OPTION A: Google AI Studio (API Key) โ Simple, no GCP project needed ---
GEMINI_API_KEY=your-api-key-here
# --- OPTION B: Vertex AI / Google Cloud (Service Account) โ GCP Enterprise ---
# GOOGLE_CLOUD_PROJECT=your-gcp-project-id
# GOOGLE_CLOUD_LOCATION=global
# GOOGLE_GENAI_USE_VERTEXAI=True
# GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/key.json
# ===========================================================================
# ๐ฌ SECTION 2: CHAT CONVERSATION (Core LLM Settings)
# ===========================================================================
# The main model used by the bots for chatting.
# You can easily switch to DeepSeek by using the "deepseek/" prefix.
# --- Example 1: Google Gemini (uses Section 1 Auth) ---
LLM_MODEL=gemini-3.6-flash
LLM_THINKING_LEVEL=medium
# --- Example 2: DeepSeek (requires Section 5 Auth) ---
# LLM_MODEL=deepseek/deepseek-v4-flash
# ===========================================================================
# ๐๏ธ SECTION 3: CONTEXT COMPACTION (Compression Settings)
# ===========================================================================
# Summarization settings (can also use DeepSeek models).
COMPACTION_MODEL=gemini-3.5-flash-lite
COMPACTION_INTERVAL=30
COMPACTION_OVERLAP=2
# ===========================================================================
# ๐ฎ SECTION 4: IMAGE GENERATION (Isolde Settings & INDEPENDENT AUTH)
# ===========================================================================
# Isolde's Tarot model and its FULLY INDEPENDENT, isolated authentication.
IMAGE_MODEL=gemini-3.1-flash-lite-image
# --- OPTION A: Google AI Studio (Dedicated API Key for Images) ---
IMAGE_GEMINI_API_KEY=your-dedicated-image-api-key-here
# --- OPTION B: Vertex AI / Google Cloud (Dedicated Service Account for Images) ---
# IMAGE_GOOGLE_CLOUD_PROJECT=another-gcp-project-id
# IMAGE_GOOGLE_CLOUD_LOCATION=europe-west1
# IMAGE_GOOGLE_GENAI_USE_VERTEXAI=True
# IMAGE_GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/another-key.json
# ===========================================================================
# ๐ง SECTION 5: DEEPSEEK PROVIDER OVERRIDES (Optional)
# ===========================================================================
DEEPSEEK_API_KEY=your-deepseek-api-key-here
DEEPSEEK_REASONING_EFFORT=high
# ===========================================================================
# ๐ก SECTION 6: TELEGRAM INTEGRATION (Optional)
# ===========================================================================
TELEGRAM_BOT_TOKEN=your-telegram-bot-token
TELEGRAM_BOT_USERNAME=your_bot_username
TELEGRAM_GROUP_LINK=https://t.me/your-group-link./start.sh # Launches Google ADK Web with persistent SQLite session trackingOpen http://localhost:8000 to chat with the ADK coordinator.
python telegram_bot.py --debugThe Scummbar ADK application (src/scummbar_chat/) is designed around clean software engineering and multi-agent patterns. Here is how the system is organized:
Instead of a single monolith prompt, the Scummbar uses a Hierarchical Router-Delegate pattern using Google ADK's root_agent and sub_agents.
[Telegram / Web Input]
โ
โผ
[root_agent]
(Shared Coordinator)
โ
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ โผ
[Barnaby] [Barnacle] [Isolde] [Balthazar]
(The Bartender) (The Tavern Cat) (The Fortune Teller) (The Navigator)
- Memory read/write - Read-only Memory - Independent Auth - RSS Feed Fetching
- Auto-discovered - Ephemeral replies - Gemini Nano Image - Comedic News
Skills (Grog/Menu) generation tool Translation
- How routing works: In
src/scummbar_chat/telegram/adapter.py, the function_resolve_intent()applies two priority levels:- Explicit Mention:
@barnaby,@barnacle,@isolde,@balthazar(always wins). - Semantic Keyword Matching: The message is scanned against
_INTENT_MAP(e.g.,grogroutes to Barnaby,tarocchiorcarteto Isolde,politicaormappeto Balthazar).
- Explicit Mention:
- Routing Prefix: Once resolved, the router prepends
[Risponde NAME]to the text, which instructs the coordinator (root_agent) to route the call to the corresponding sub-agent.
To create an immersive atmosphere, the bar never closes but changes its mood in real-time. In src/scummbar_chat/time_context.py, the day is split into 6 periods (Dawn, Noon, Sunset, Night, etc.).
- The Choice: Instead of passing the world description statically, we use ADK's
global_instructionbound to anInstructionProviderfunction. This dynamically updates the bar's description at every model turn based on the actual system hour. - Why: This is cache-friendly for Gemini and ensures the agents always know if it's sunset or dawn without manual prompt editing.
All group chats are mapped to a single persistent SQLite database (data/scummbar_chat/sessions.db) via ADK's DatabaseSessionService.
- Context Compaction: As history grows, the context window fills up. We configured an automated, LLM-based compaction scheme (
EventsCompactionConfig+LlmEventSummarizer):- After every 30 events, the older portion of the conversation is replaced by an LLM-generated summary (
COMPACTION_MODEL). - The last 2 events are kept verbatim to maintain immediate conversational context.
- After every 30 events, the older portion of the conversation is replaced by an LLM-generated summary (
One of the key technical highlights of this repository is how authentication is parameterized:
- The Problem: The standard Google GenAI SDK throws a fatal error if you supply both an API Key and Vertex AI variables globally in the environment (they are mutually exclusive).
- The Solution: We built
get_gemini_client_kwargs(prefix="")inutils.py.- If
GEMINI_API_KEYis present, it forcesvertexai=Falseand programmatically overridesproject=Noneandlocation=None, shielding the client from environment pollution. - If
prefix="IMAGE_"is specified, it isolates the Image Generation auth entirely, allowing Isolde to run on a separate billing project, key, or Vertex regional project without affecting Chat/Compaction! - Thread Safety: For Vertex AI Service Accounts, we load the JSON directly as an in-memory
Credentialsobject rather than mutatingos.environglobally, ensuring perfect safety during async concurrent loops.
- If
We wanted the agents to be able to "hand over" items to players:
- Barnaby & Balthazar's Scrolls & Portolans: Generates recipes, nautical maps, and portolans as
.txtfiles using ADK'sInMemoryArtifactServicevia thewrite_secret_scrolltool. Delivered as downloadable Telegram documents. - Isolde's Tarot Images: Uses
draw_tarot_cardtool via Gemini's nativeresponse_modalities=["IMAGE"]or a customized Pillow (PIL) local rendering fallback if the API is offline. Automatically detects the file format (PNG vs. JPEG) via byte headers and delivers it as an inline native photo via/sendPhoto.
The Scummbar is designed to be model-agnostic. You can switch the brain of the tavern simply by changing one line in the .env file (LLM_MODEL).
- Gemini Support: Native ADK support for the
gemini-3.6,gemini-3.5, andgemini-3.1families. - DeepSeek Support: Fully integrated using ADK's
LiteLlmadapter. Theutils.pyfactory automatically detects the"deepseek/"prefix in the model name, enables DeepSeek'sthinkingmode, and sets thereasoning_effortnatively without requiring any code changes.
This repository was designed to be developed, refactored, and maintained collaboratively with an AI coding assistant (Pi-Agent).
To achieve this, we configured a specialized autonomous system directly in the codebase using Agent Skills.
[.agents/skills/]
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
[scummbar-docs-analyzer] [scummbar-memory-updater] [scummbar-web-to-markdown]
- Hybrid RAG engine - Automated logging rules - HTML/Web to Markdown
(FTS5 BM25 + Vector) - Roadmap state compiler converter & updater
- gemini-embedding-2 - Fence marker validator - BS4 + html2text pipeline
- Reciprocal Rank Fusion
A Pi-Agent skill is a self-contained, capability package located in .agents/skills/. At startup, Pi-Agent scans this directory and learns about the available capabilities via the skill's description. The full instructions are kept separate and loaded on-demand when the skill is called.
This implements Progressive Disclosure: it keeps the AI's initial context window incredibly clean, saving tokens, speeding up response times, and maximizing the LLM's reasoning focus.
- Why: The
docs/folder contains dozens of framework guides. Storing their indexes in the main developer instructions (AGENTS.mdorMEMORY.md) wasted thousands of tokens. Plainrg/grepsearches can't capture semantic intent. - What it does: This skill provides a local Hybrid RAG Search Engine (
rag/) that chunks all 325 Markdown documents (10,891 chunks), generates embeddings via Googlegemini-embedding-2, stores vectors in SQLite (sqlite-vec), and performs hybrid search using Reciprocal Rank Fusion (RRF) between FTS5 keyword matching (BM25) and Vector Cosine Similarity โ no manual index needed. - How to use:
# Semantic + keyword search (returns ranked chunk results) PYTHONPATH=.agents/skills/scummbar-docs-analyzer python3 .agents/skills/scummbar-docs-analyzer/rag/search.py "context compaction" --top_k 5 # Incremental re-indexing after adding new docs PYTHONPATH=.agents/skills/scummbar-docs-analyzer python3 .agents/skills/scummbar-docs-analyzer/rag/indexer.py
- Why: Keeping architectural decisions (
MEMORY.md), developer guides (AGENTS.md), and public manuals (README.md) synchronized across dozens of commits is extremely error-prone for humans and AIs alike. - What it does: Standardizes how the AI must document changes. It enforces rules on how to append session logs, update the roadmap, register design decisions, and includes an automated Python validator to ensure no markdown code blocks are left open or broken.
- Why: Importing external technical documentation or web guides into clean Markdown format for the offline
docs/repository can be tedious and prone to formatting issues. - What it does: Automatically converts web pages or URL lists into clean, standardized Markdown files using
beautifulsoup4andhtml2text. Supports auto-updates, relative-to-absolute link resolution, UTF-8 emoji preservation, and file overwrite protection. After conversion, automatically triggers the RAG incremental indexer to update the vector database.
If you are developing this repository using Pi-Agent, you can invoke these skills or execute their CLI tools directly:
# 1. Search framework documentation across 325 docs using Hybrid RAG (FTS5 + Cosine)
PYTHONPATH=.agents/skills/scummbar-docs-analyzer python3 .agents/skills/scummbar-docs-analyzer/rag/search.py "agent evaluation custom metrics" --top_k 5
# 2. Convert a web page to clean Markdown and auto-index into the RAG vector database
python3 .agents/skills/scummbar-web-to-markdown/scripts/convert.py "https://adk.dev/evaluate/" "docs/google-api/"
PYTHONPATH=.agents/skills/scummbar-docs-analyzer python3 .agents/skills/scummbar-docs-analyzer/rag/indexer.py
# 3. Update memory, roadmap, and check markdown fence health after refactoring
/skill:scummbar-memory-updaterBy combining Google ADK and Pi-Agent Skills for autonomous workspace organization, this repository stands as a state-of-the-art template for modern, AI-collaborative software engineering.
Inspired by the Scumm Bar from Monkey Island. Built for learning and study purposes. No commercial affiliation.
