SMILE-factory
This repository hosts two projects:
- Delulu Discord Orchestrator (active) — a Discord bot that dispatches Claude Code tasks to ephemeral Modal sandboxes. Lives under
apps/delulu_discord and apps/delulu_sandbox_modal.
- LoRA-Instruct (archived) — earlier fine-tuning work with HuggingFace PEFT + LoRA, kept in-tree pending a later migration. Lives at the repo root (
finetune.py, dataset/, inference/, etc.).
Discord Orchestrator
Discord bot that dispatches Claude Code tasks to ephemeral Modal Sandboxes.
How it works
- User
@mentions the bot in any channel it can see
- Bot creates a Discord thread off that message and a new Claude Code session
- Bot dispatches the task to a Modal Sandbox (ephemeral container with Claude Code installed)
- Sandbox runs the task against a per-thread workspace on the Modal Volume, returns output, dies
- Bot posts the result in the thread
- Replies inside the thread auto-continue the same session via
claude --continue — no need to re-mention the bot
The bot process itself is tiny (~50MB RAM) and just dispatches jobs — all
heavy lifting (and all Claude Code execution) happens inside Modal sandboxes.
See ARCHITECTURE.md for the full design.
Architecture
flowchart LR
U([User])
subgraph Discord
Ch["any channel<br/>(@mention gated)"]
Th["thread"]
end
subgraph Droplet["DO Droplet"]
Bot["disco<br/>(bot container)"]
SM["session_manager<br/>thread_id → session"]
Bot --- SM
end
subgraph Modal["Modal"]
App["discord-orchestrator App"]
Fn["run_claude_code<br/>(ephemeral sandbox)"]
Vol[("claude-workspaces<br/>Volume")]
Sec["claude-oauth<br/>Secret"]
App --- Fn
end
subgraph Anthropic["Anthropic"]
API["Claude API<br/>(Pro/Max OAuth)"]
end
U -->|@mention| Ch
Ch -->|gateway event| Bot
Bot -->|create| Th
Bot -->|Function.from_name.remote| Fn
Sec -.->|seeds /vol/claude-home/.claude| Vol
Vol <-.->|HOME=/vol/claude-home<br/>cwd=/vol/workspaces/<thread_id>| Fn
Fn -->|claude -p --continue| API
Fn -->|stdout| Bot
Bot -->|reply| Th
Th --> U
Runtime request flow — an @mention in any channel triggers the bot
to open a thread, look up or create a session, and call the deployed Modal
function via Function.from_name(...).remote(...). Modal spins up an
ephemeral container from a pre-baked image (Node + Claude Code), runs
claude --print with HOME=/vol/claude-home and cwd=/vol/workspaces/<thread_id>,
captures stdout, and exits. Because both Claude Code's state directory
(~/.claude/) and the workspace are on the persistent Modal Volume,
follow-up replies in the same thread can resume via claude --continue
— which keys off cwd — even across ephemeral sandbox invocations and bot
restarts.
Key invariants worth knowing:
- The bot never runs Claude Code itself. It only holds a Discord
WebSocket connection and a hydrated Modal function reference. Any VPS
with Docker can host it.
- Sandboxes are ephemeral but the volume is not. Workspaces
(
/vol/workspaces/<thread_id>) and Claude Code's entire home
(/vol/claude-home/.claude/ — credentials, settings, session history)
survive across invocations. That's what makes session resume,
refresh-token rotation, and --continue all work.
- Auth is one-way from laptop → Modal Secret → Volume. The secret only
seeds the volume on first run; after that, the volume's copy is the
source of truth. The droplet never stores Claude credentials at rest.
workspace_path is deterministic per thread_id. The in-memory
session map is a convenience; even if it's wiped by a bot restart, the
same Discord thread always maps to the same volume directory.
Prerequisites
- Python 3.14 and uv
- A Discord account
- A Modal account (
uv tool install modal or pip install modal)
- A Claude Pro or Max subscription (Claude Code authenticates via OAuth, no API key needed)
- (For deployment) a server to run the bot — anything that can run Docker. A
$4–6/mo Digital Ocean droplet is plenty.
Setup
The setup has three parts:
- Discord — create a bot application and invite it to your server.
- Modal — authenticate, upload Claude OAuth credentials as a secret, deploy the sandbox app.
- Bot host — run the bot process (locally or on a server).
1. Create the Discord bot