# Saki

> Saki is a private Discord assistant combining permission-aware LLM tools, deterministic moderation, SQLite memory, scheduled workflows, multimodal input, and Lavalink music.

- HTML: https://estebanech.com/projects/saki
- Markdown: https://estebanech.com/projects/saki.md

## Permission-Aware AI Agent for Discord

Saki is a private, single-guild Discord assistant built as a persistent Gateway service. It combines a structured tool-calling LLM agent with deterministic moderation, persistent memory, scheduled reminders, server administration, image understanding, and music playback.

## Metadata

- Role: Sole Designer and Engineer
- Type: Independent Production Project
- Status: Live
- Runtime: Persistent Discord Gateway Service
- Repository: Private

## Overview

Saki is designed for one private Discord community rather than as a multi-tenant SaaS product. A guild allowlist rejects requests from every server except its configured home guild.

Unlike a traditional command bot, Saki can interpret natural-language requests and take controlled actions through structured tools. Depending on the requesting user's authorization level, the agent can search server knowledge, summarize conversations, create reminders and events, manage music, perform moderation, or operate Discord resources.

AI is invoked only during explicit interactions such as mentions, replies, /ask, and summarization flows. Fast moderation, member onboarding, reminders, and command handling remain deterministic application services.

Discord acts as the user interface, while the bot process owns command handling, authorization, agent orchestration, moderation, persistence, music, and service integration.

## Problem

Traditional Discord bots are reliable but limited to predefined commands. General-purpose AI chatbots understand natural language but should not receive unrestricted access to moderation tools or server infrastructure.

The engineering question behind Saki was:

> How can an LLM understand natural-language requests and take useful actions inside Discord without receiving uncontrolled administrative authority?

## Solution

### Discord Gateway Interface

A persistent discord.js process receives messages, slash commands, button interactions, member events, voice-state updates, and raw gateway events required by Lavalink.

### Explicit AI Invocation

The LLM runs only when a user directly mentions Saki, replies to Saki, invokes /ask, or uses another AI-specific flow. It does not process every server message.

### Permission-Aware Agent

The agent receives only the tool schemas available to the requesting user. Public, moderator, and owner tools are exposed separately.

### Defense-in-Depth Execution

Permissions are checked when tools are exposed to the model and checked again when a tool executes.

### Persistent Memory and Knowledge

SQLite stores guild settings, reminders, learned server facts, user memories, and searchable conversation history.

### Deterministic Moderation

Spam bursts and malicious links are handled outside the model for predictable latency, cost, and enforcement.

### Independent Music Service

Music playback runs through a separate Lavalink service so chat, commands, memory, and moderation remain available if music is offline.

## Capabilities

### Structured Tool Agent

Executes Discord actions through typed function tools instead of giving the model unrestricted API access.

### Permission-Aware Operations

Filters tools according to public, moderator, and owner authorization levels.

### Persistent Memory

Stores personal facts, guild knowledge, reminders, and searchable conversation history.

### Deterministic Moderation

Handles malicious links and message-burst spam without calling an LLM.

### Scheduled Workflows

Creates reminders, polls, and Discord scheduled events.

### Multimodal Input

Uses a separate vision-model path for image understanding and comparison requests.

### Model Resilience

Supports model fallback, per-model cooldowns, rate-limit handling, and oversized-request recovery.

### Music Infrastructure

Uses Lavalink for playback, queue controls, loop modes, shuffle, volume, empty-channel cleanup, and source resolution.

### Skills and Knowledge

Loads Markdown playbooks and static guild documentation when relevant.

### Graceful Degradation

Keeps moderation and normal commands available if the AI provider or music service is temporarily unavailable.

## Design Decisions

### Run as a persistent Discord Gateway process.

Message events, member events, voice state, moderation, and Lavalink integration require a long-running connection rather than an interaction-only webhook architecture.

### Invoke AI only during explicit interactions.

This reduces cost, unnecessary message processing, context noise, accidental responses, and privacy concerns.

### Keep moderation deterministic.

Spam and malicious-link enforcement need predictable behavior independent of model availability or interpretation.

### Filter tools before inference.

A user cannot persuade the model to call a capability it was never given.

### Re-check permissions during execution.

Tool visibility is not a replacement for deterministic server-side authorization.

### Fail closed on malformed arguments.

Invalid model-generated JSON must not silently become empty or default arguments for destructive operations.

### Use SQLite for a single-guild deployment.

SQLite with WAL mode provides sufficient durable persistence without unnecessary distributed database infrastructure.

### Separate Lavalink from the bot process.

Music failures should not bring down commands, moderation, memory, reminders, or AI interactions.

### Bound agent rounds and context.

Tool-loop and context limits reduce duplicate actions, runaway requests, and provider token-limit failures.

### Restrict allowed mentions.

AI-generated responses must not be able to mass-ping roles or @everyone.

## Permissions

### Public

Can use approved knowledge, reminders, polls, personal memory, music, channel discovery, social interactions, and self-service tools.

### Moderator

Can use moderation, message cleanup, slowmode, channel and role operations, voice moderation, event management, and server-fact tools.

### Owner

Can access invites, emoji management, webhooks, AutoMod operations, and higher-risk administrative capabilities.

## Personality

Saki has a configurable personality layer designed to make a utility bot feel native to its community rather than like a generic corporate assistant.

The product presentation is K-pop idol themed, inspired by Sakura Miyawaki of LE SSERAFIM, including profile and banner visuals in that aesthetic. Guild-wide personality modes include Normal, Sarcastic, Overkill, and Cute.

The persona is implemented separately from authorization and tool execution. Changing the personality does not grant additional permissions or alter deterministic moderation rules.

## Privacy

The source repository is private because it contains server-specific configuration, private knowledge structures, moderation behavior, internal prompts, Discord resource identifiers, infrastructure conventions, and security-sensitive integrations.

The public case study focuses on architecture, authorization, persistence, agent orchestration, deployment, and non-sensitive demonstrations.

## Highlights

- TypeScript ESM runtime
- Node.js 22+
- discord.js v14
- Single allowed guild
- Approximately 29 slash commands
- Three authorization levels
- Maximum five agent tool rounds
- Three memory tiers
- SQLite WAL mode
- FTS5-backed search
- 15-second reminder polling
- Maximum two images per applicable vision request
- Separate bot and Lavalink services
- Optional Message Content and Guild Members intents
- Model fallback and cooldown handling
- Graceful shutdown for reminders, Lavalink, Discord, and SQLite

## Technology

### Runtime

- TypeScript
- Node.js 22
- tsx
- pnpm

### Discord

- discord.js v14
- Discord Gateway
- Slash commands
- Interactive components

### AI

- OpenAI SDK
- Groq
- OpenAI-compatible model APIs
- Tool calling
- Vision models
- Model routing

### Persistence

- better-sqlite3
- SQLite WAL
- FTS5

### Music

- Lavalink 4
- lavalink-client

### Infrastructure

- Docker
- Railway
- Persistent volume
- Private service networking

## Status

Saki is deployed as a persistent private-server assistant. Its AI agent, deterministic moderation, memory, reminders, commands, onboarding, and music systems are separated into modules so individual services can degrade without disabling the entire bot.

## Next Steps

- Destructive-action confirmation workflows
- More detailed tool-execution audit logs
- Protected user, role, and channel configuration
- Expanded permission-boundary tests
- Structured privacy and data-export controls
- Automated SQLite backup validation
- Agent evaluation tasks
- Improved observability and tool-success metrics
- Memory provenance and expiration controls
- Additional reusable server workflow skills

Author: Andres Echeverria (estebanech)
