A multi-agent system built with LangGraph and LangChain that intelligently routes user requests to specialized agents for Email (Gmail), Slack, and General Chat operations. Powered by a local LLM via an OpenAI-compatible API.
User Input (CLI)
│
▼
Router ── keyword match (fast path) ──┐
│ │
▼ (ambiguous) │
LLM classification │
│ │
├── compose signals? ─► LLM Compose ─┤
│ ("write", "professional", │
│ "in 50 words", etc.) │
│ │
▼ ▼
┌──────────────────────────────────────────┐
│ "email" → Email Agent (send / read) │
│ "slack" → Slack Agent (send / read / │
│ list channels) │
│ "general"→ General Chat (plain LLM) │
└──────────────────────────────────────────┘
│
▼
Preview & Confirm (send / edit / cancel)
│
▼
Output (Rich formatted panel)
The Router uses keyword matching first (fast path), then falls back to LLM classification for ambiguous inputs. If compose signals are detected (e.g. "write a professional 50 word message"), the LLM drafts the message before routing to the target agent. All outgoing messages go through an interactive preview where you can send, edit, or cancel.
GP-AGENT/
├── main.py # Interactive CLI entry point
├── pyproject.toml # Project metadata and dependencies
├── config.json # User config (sender name, auto-created)
├── .env.example # Environment variable template
├── HOW-TO-RUN.md # Quick-start guide
└── src/
├── __init__.py
├── agents.py # Email, Slack, and general chat agent logic
├── graphs.py # LangGraph state graph definition
├── router.py # Intent classification (keyword + LLM fallback)
├── config.py # Config file management (sender name)
├── utils.py # Message composition, editing, subject generation
├── display.py # Rich console output (banners, tables, panels)
└── tools/
├── email_tool.py # Gmail API tools (Send, Search, Get)
└── slack_tool.py # Slack API tools (Send, GetChannel, GetMessage)
- Python 3.11+
- uv (recommended) or pip
- A local LLM server with an OpenAI-compatible API (e.g., Ollama, llama.cpp, vLLM, or LM Studio)
- Google Cloud Project with Gmail API enabled (for email features)
- Slack App with a User OAuth Token (for Slack features)
git clone <repository-url>
cd GP-AGENTUsing uv (recommended):
uv venv && source .venv/bin/activate
uv syncUsing pip:
python -m venv .venv && source .venv/bin/activate
pip install -e .cp .env.example .envEdit .env with your values:
# Slack
SLACK_USER_TOKEN=xoxp-your-token-here
# LLM (optional, defaults shown)
LLM_BASE_URL=http://localhost:11434/v1
LLM_MODEL=qwen2.5:3bAny local LLM server that exposes an OpenAI-compatible API will work:
| Server | LLM_BASE_URL |
|---|---|
| Ollama | http://localhost:11434/v1 |
| llama.cpp | http://localhost:8000/v1 |
| vLLM | http://localhost:8000/v1 |
| LM Studio | http://localhost:1234/v1 |
- Go to Google Cloud Console
- Create a project and enable the Gmail API (APIs & Services > Library)
- Create OAuth 2.0 credentials (APIs & Services > Credentials > OAuth client ID > Desktop application)
- Download and rename the file to
credentials.json, place it in the project root - On first run, a browser window opens for authorization. A
token.jsonis created automatically for subsequent runs.
Both
credentials.jsonandtoken.jsonare git-ignored. Never commit these.
- Go to Slack API Apps and create a new app
- Go to OAuth & Permissions and add these User Token Scopes:
channels:readchannels:historychat:writeusers:read
- Install the app to your workspace
- Copy the User OAuth Token (
xoxp-...) into your.envfile
Start the LLM server, then run:
python main.pyOn first run, you'll be prompted for your name (used in email sign-offs). This is saved to config.json.
| Command | Description |
|---|---|
/help |
Show available commands |
/info |
Display session info (model, uptime) |
/clear |
Clear the terminal |
/quit, /exit |
Exit the application |
Multi-line input is supported — end a line with \ to continue on the next line. Command history is saved across sessions.
> send a slack message to #general saying deployment complete
> write a professional 50 word slack message to #general about the release
> read slack messages from #general
> list my slack channels
> send an email to john@example.com saying the meeting is rescheduled
> write a formal email to jane@example.com about project update
> read my emails from boss@company.com
> what is machine learning?
When sending messages, you'll get a preview with options to send, edit, or cancel before anything is sent.
- "Cannot connect to LLM server" — Your local LLM server isn't running. Start it before running the agent.
- Gmail auth errors — Ensure
credentials.jsonexists. Deletetoken.jsonto re-authenticate. - "Slack token invalid" — Check your
.envfile has a validSLACK_USER_TOKEN. - Wrong routing — Include "email" or "slack" in your query for reliable routing. Ambiguous queries fall back to LLM classification, whose accuracy depends on your local model.
- Email fields wrong — Use
sayingbefore the body, andabout/regarding/onbefore the subject for best extraction. - Name not showing in emails — Edit
config.jsonin the project root, or delete it to be prompted again on next run.