|
|
@@ -10,16 +10,88 @@ Discord bot that provisions [Daytona](https://daytona.io) sandboxes running [Ope
|
|
|
4. Inactive threads pause their sandbox automatically; activity resumes them
|
|
|
5. Conversational context is preserved across bot restarts
|
|
|
|
|
|
-## Quick Start
|
|
|
+## Setup
|
|
|
+
|
|
|
+### Prerequisites
|
|
|
+
|
|
|
+- [Bun](https://bun.sh) installed
|
|
|
+- A Discord bot application (see below)
|
|
|
+- A [Daytona](https://daytona.io) account with API access
|
|
|
+- An [OpenCode](https://opencode.ai) API key
|
|
|
+
|
|
|
+### 1. Create a Discord Bot
|
|
|
+
|
|
|
+1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
|
|
|
+2. Create a new application
|
|
|
+3. Go to **Bot** and click **Reset Token** — save this as `DISCORD_TOKEN`
|
|
|
+4. Enable **Message Content Intent** under **Privileged Gateway Intents**
|
|
|
+5. Go to **OAuth2 > URL Generator**, select the `bot` scope with permissions: **Send Messages**, **Create Public Threads**, **Send Messages in Threads**, **Read Message History**
|
|
|
+6. Use the generated URL to invite the bot to your server
|
|
|
+
|
|
|
+### 2. Get Your API Keys
|
|
|
+
|
|
|
+- **Daytona**: Sign up at [daytona.io](https://daytona.io) and generate an API key from your dashboard
|
|
|
+- **OpenCode**: Get an API key from [opencode.ai](https://opencode.ai)
|
|
|
+- **GitHub Token** (optional): A personal access token — enables authenticated `gh` CLI inside sandboxes
|
|
|
+
|
|
|
+### 3. Configure and Run
|
|
|
|
|
|
```bash
|
|
|
bun install
|
|
|
cp .env.example .env
|
|
|
-# Fill in required values in .env
|
|
|
+# Fill in required values (see below)
|
|
|
bun run db:init
|
|
|
bun run dev
|
|
|
```
|
|
|
|
|
|
+### Environment Variables
|
|
|
+
|
|
|
+#### Required
|
|
|
+
|
|
|
+| Variable | Description |
|
|
|
+| ---------------------- | ------------------------------------------- |
|
|
|
+| `DISCORD_TOKEN` | Bot token from the Discord Developer Portal |
|
|
|
+| `DAYTONA_API_KEY` | API key from your Daytona dashboard |
|
|
|
+| `OPENCODE_ZEN_API_KEY` | API key from OpenCode |
|
|
|
+
|
|
|
+#### Optional — Discord
|
|
|
+
|
|
|
+| Variable | Default | Description |
|
|
|
+| -------------------------- | --------- | ----------------------------------------------------------------------- |
|
|
|
+| `ALLOWED_CHANNEL_IDS` | _(empty)_ | Comma-separated channel IDs where the bot listens. Empty = all channels |
|
|
|
+| `DISCORD_CATEGORY_ID` | _(empty)_ | Restrict the bot to a specific channel category |
|
|
|
+| `DISCORD_ROLE_ID` | _(empty)_ | Role ID that triggers the bot via @role mentions |
|
|
|
+| `DISCORD_REQUIRED_ROLE_ID` | _(empty)_ | Role users must have to interact with the bot |
|
|
|
+
|
|
|
+#### Optional — Storage & Runtime
|
|
|
+
|
|
|
+| Variable | Default | Description |
|
|
|
+| ---------------- | ---------------------------- | -------------------------------------------------- |
|
|
|
+| `DATABASE_PATH` | `discord.sqlite` | Path to the local SQLite file |
|
|
|
+| `GITHUB_TOKEN` | _(empty)_ | Injected into sandboxes for authenticated `gh` CLI |
|
|
|
+| `OPENCODE_MODEL` | `opencode/claude-sonnet-4-5` | Model used inside OpenCode sessions |
|
|
|
+
|
|
|
+#### Optional — Bot Behavior
|
|
|
+
|
|
|
+| Variable | Default | Description |
|
|
|
+| -------------------------- | ------------------ | ------------------------------------------------------------------------------ |
|
|
|
+| `SANDBOX_REUSE_POLICY` | `resume_preferred` | `resume_preferred` or `recreate` |
|
|
|
+| `SANDBOX_TIMEOUT_MINUTES` | `30` | Minutes of inactivity before pausing a sandbox |
|
|
|
+| `PAUSED_TTL_MINUTES` | `180` | Minutes a paused sandbox lives before being destroyed |
|
|
|
+| `RESUME_HEALTH_TIMEOUT_MS` | `120000` | Timeout (ms) when waiting for a sandbox to resume |
|
|
|
+| `SANDBOX_CREATION_TIMEOUT` | `180` | Timeout (s) for sandbox creation |
|
|
|
+| `TURN_ROUTING_MODE` | `ai` | How the bot decides if a message needs a response: `off`, `heuristic`, or `ai` |
|
|
|
+| `TURN_ROUTING_MODEL` | `claude-haiku-4-5` | Model used for AI turn routing |
|
|
|
+
|
|
|
+#### Optional — Observability
|
|
|
+
|
|
|
+| Variable | Default | Description |
|
|
|
+| ------------- | --------- | ----------------------------------- |
|
|
|
+| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, or `error` |
|
|
|
+| `LOG_PRETTY` | `false` | Pretty-print JSON logs |
|
|
|
+| `HEALTH_HOST` | `0.0.0.0` | Host for the health HTTP server |
|
|
|
+| `HEALTH_PORT` | `8787` | Port for the health HTTP server |
|
|
|
+
|
|
|
## Commands
|
|
|
|
|
|
| Command | Description |
|
|
|
@@ -31,15 +103,6 @@ bun run dev
|
|
|
| `bun run build` | Bundle for deployment |
|
|
|
| `bun run check` | Typecheck + build |
|
|
|
|
|
|
-## Configuration
|
|
|
-
|
|
|
-See [`.env.example`](.env.example) for all available environment variables. Required:
|
|
|
-
|
|
|
-- `DISCORD_TOKEN` — Discord bot token
|
|
|
-- `DATABASE_PATH` — SQLite file path (default: `discord.sqlite`)
|
|
|
-- `DAYTONA_API_KEY` — Daytona API key
|
|
|
-- `OPENCODE_ZEN_API_KEY` — OpenCode API key
|
|
|
-
|
|
|
## Health Endpoints
|
|
|
|
|
|
- `GET /healthz` — Liveness check (uptime, Discord status, active sessions)
|