Files
Agents/gateway/discord/discord.md
T

2.3 KiB

Discord — Connector

The Discord module embeds a Discord bot in-process alongside FastAPI. It uses the same LangGraph graphs and LLM client as the REST API — there is no HTTP loopback, no separate process, and no code duplication.


Files

File Purpose
bot.py Discord Client subclass (AgentBot) — DM handler, command parser, graph invoker, Quick Connect orchestrator
conversation.py In-memory conversation history store, keyed by Discord user ID

Architecture

Discord Gateway (websocket)
  │  DM: "What's trending?"
  ▼
discord.Client.on_message()
  │  1. Check: is this a DM? shares a guild? not a command?
  │  2. Build message history from ConversationStore
  │  3. Append user message
  ▼
_create_agent_graph(agent_id="media-agent")
  │  Uses the exact same create_agent_graph() from src/graph.py
  │  as the REST API — same LLM client, same tools, same cache.
  ▼
graph.ainvoke({"messages": [...]})
  │  LangGraph runs agent_node → tool_node → agent_node → END
  ▼
Response text → split into ≤2000-char Discord messages → sent to user

Commands

Commands are DMs that start with /. The bot parses them before hitting the LLM:

Command Action
/login <service> Generate a one-time auth link, DM it to the user
/jellyfin login Alias for /login jellyfin
/help Show available agents and commands
/<agent_id> Switch to a different agent for future messages

Auth Flow (Quick Connect)

When a user types /login jellyfin:

  1. Bot generates a one-time token via auth_store
  2. Bot calls auth_store.create_link_token(discord_id, "jellyfin")
  3. Bot DMs the user: https://<BASE_URL>/api/v1/auth/login?service=jellyfin&token=...&discord_id=...
  4. User clicks the link → FastAPI serves the Jellyfin login form (or Quick Connect prompt)
  5. User authenticates → credentials stored in auth_store
  6. Future tool calls (e.g. watch_history) automatically use the stored Jellyfin session

Conversation Persistence

  • Per-user history stored in ConversationStore (in-memory dict)
  • Max history length configurable via DISCORD_MAX_HISTORY env var (default: 7)
  • Oldest messages are silently dropped when the limit is exceeded
  • History is NOT persisted across restarts (future: could use SQLite)