Add CI workflow, full env docs, fix Up button navigation
Some checks failed
Build and Push / build (push) Failing after 2m15s
Some checks failed
Build and Push / build (push) Failing after 2m15s
- .gitea/workflows/build.yaml: Gitea Actions — push latest on main - docker-compose.example.yml: image-based pull, all NAT20_ vars shown - settings.py: add NAT20_PLAYER_RECAP_STYLE / CUSTOM_PROMPT overrides - README.md: full env var reference table with accepted values + rationale - files.py: fix parent_path to avoid up-button bug; add path traversal guard - Files.tsx: remove copy/paste/autoPlay, scope to campaign
This commit is contained in:
29
.gitea/workflows/build.yaml
Normal file
29
.gitea/workflows/build.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Build and Push
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Gitea Container Registry
|
||||
run: echo "${{ secrets.GITEA_TOKEN }}" | docker login gitea.kansaigaijin.com -u ${{ gitea.repository_owner }} --password-stdin
|
||||
|
||||
- name: Build and push backend
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./backend
|
||||
target: runtime
|
||||
push: true
|
||||
tags: gitea.kansaigaijin.com/${{ gitea.repository }}/backend:latest
|
||||
|
||||
- name: Build and push frontend
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./frontend
|
||||
push: true
|
||||
tags: gitea.kansaigaijin.com/${{ gitea.repository }}/frontend:latest
|
||||
63
README.md
63
README.md
@@ -40,39 +40,62 @@ A reference compose file using named volumes only (no host paths) is at
|
||||
|
||||
## Data layout
|
||||
|
||||
The app stores everything under `/data` (inside the container), which by default
|
||||
is a [bind mount](./docker-compose.yml) to a host path of your choice:
|
||||
The app stores everything under `/data` (inside the container):
|
||||
|
||||
| Directory / File | Contents |
|
||||
|---|---|
|
||||
| `audio/` | Uploaded recordings and extracted audio |
|
||||
| `transcriptions/` | Per-session transcript JSON files |
|
||||
| `notes/` | Generated notes (GM log + player recap) |
|
||||
| `app.db` | SQLite database (sessions, speakers, settings, jobs) |
|
||||
| `campaigns/{id}/audio/` | Uploaded recordings and extracted audio, organised per campaign |
|
||||
| `campaigns/{id}/transcriptions/` | Per-session transcript JSON files |
|
||||
| `campaigns/{id}/notes/` | Generated notes (GM log + player recap) |
|
||||
| `app.db` | SQLite database (sessions, speakers, campaigns, settings, jobs) |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Prefilling the setup wizard
|
||||
### Environment variables (`NAT20_*`)
|
||||
|
||||
Set `NAT20_*` environment variables under the `backend` service in
|
||||
`docker-compose.yml` — the wizard will pick them up as defaults:
|
||||
Set these under the `backend` service in `docker-compose.yml` to prefill
|
||||
the setup wizard and override defaults. All are optional — the wizard
|
||||
and Settings page can set them at runtime.
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
NAT20_HF_TOKEN: "hf_..."
|
||||
NAT20_WHISPER_MODEL: medium
|
||||
NAT20_OLLAMA_HOST: http://localhost:11434
|
||||
NAT20_WORLD_CONTEXT_PATH: /data/campaign-context.txt
|
||||
```
|
||||
#### Transcription
|
||||
|
||||
See the `environment:` block in `docker-compose.yml` for the full list.
|
||||
| Variable | What it does | Values | Default | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `NAT20_WHISPER_MODEL` | Whisper model size | `tiny` `base` `small` `medium` `large-v3` | `medium` | Larger = more accurate but uses more VRAM. `medium` fits most 6-8 GB GPUs; `large-v3` needs ~10 GB+ |
|
||||
| `NAT20_WHISPER_COMPUTE_TYPE` | Compute precision | `int8` `float16` `float32` | `int8` | `int8` = fastest / least VRAM. `float16` = more accurate, more VRAM. `float32` = full precision, slowest |
|
||||
| `NAT20_HF_TOKEN` | HuggingFace token for speaker diarization | `hf_...` | (none) | Required for speaker attribution. Must accept pyannote gated-model terms with the same account first |
|
||||
|
||||
#### LLM backend
|
||||
|
||||
| Variable | What it does | Values | Default | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `NAT20_OLLAMA_HOST` | Ollama server URL | URL | `http://localhost:11434` | Set to your Ollama host |
|
||||
| `NAT20_OLLAMA_MODEL` | Ollama model name | any model on your server | `qwen2.5:7b` | |
|
||||
| `NAT20_API_BASE_URL` | OpenAI-compatible API base | URL | `https://api.openai.com/v1` | Uncomment and set to switch from Ollama |
|
||||
| `NAT20_API_KEY` | API key | string | (none) | |
|
||||
| `NAT20_API_MODEL` | API model name | string | `gpt-4o-mini` | |
|
||||
|
||||
#### Summarization
|
||||
|
||||
| Variable | What it does | Values | Default | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `NAT20_CHUNK_WORD_TARGET` | Target words per summarisation chunk | number | `2500` | Long transcripts are split into chunks, each summarised separately, then combined. **Lower** = more LLM calls but finer granularity (good for models with small context windows). **Higher** = more context per chunk but may exceed the model's window. `2500` is safe for most models (8K–128K context) |
|
||||
| `NAT20_WORLD_CONTEXT` | Campaign context string | text | (none) | Injected into every summarisation prompt so the LLM recognises NPCs, places, and lore correctly |
|
||||
| `NAT20_WORLD_CONTEXT_PATH` | Path to campaign context file inside container | container path | (none) | Alternative to `NAT20_WORLD_CONTEXT` for large campaign bibles you update independently |
|
||||
| `NAT20_PLAYER_RECAP_STYLE` | Player recap format | `story` `diary` `bullets` `custom` | `story` | |
|
||||
| `NAT20_PLAYER_RECAP_CUSTOM_PROMPT` | Custom prompt (only when style is `custom`) | text | (none) | |
|
||||
|
||||
#### Setup wizard
|
||||
|
||||
| Variable | What it does | Values | Default | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `NAT20_ONBOARDING_COMPLETED` | Skip the setup wizard | `true` or `false` | `false` | Set to `"true"` after you finish the wizard once |
|
||||
|
||||
### Campaign context
|
||||
|
||||
You can paste context directly in the Settings page, or point to a file
|
||||
inside the container using the `world_context_path` setting (or the
|
||||
`NAT20_WORLD_CONTEXT_PATH` env var). The file path version is useful for
|
||||
large campaign bibles that you update independently.
|
||||
inside the container using `NAT20_WORLD_CONTEXT_PATH`. The file version is
|
||||
useful for large campaign bibles that you update independently.
|
||||
|
||||
## Notes on hardware
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ _ENV_OVERRIDES = {
|
||||
"chunk_word_target": "NAT20_CHUNK_WORD_TARGET",
|
||||
"world_context": "NAT20_WORLD_CONTEXT",
|
||||
"world_context_path": "NAT20_WORLD_CONTEXT_PATH",
|
||||
"player_recap_style": "NAT20_PLAYER_RECAP_STYLE",
|
||||
"player_recap_custom_prompt": "NAT20_PLAYER_RECAP_CUSTOM_PROMPT",
|
||||
}
|
||||
|
||||
_BOOL_KEYS = {"onboarding_completed"}
|
||||
|
||||
@@ -1,26 +1,69 @@
|
||||
# Example Docker Compose — uses a named volume so data persists across rebuilds
|
||||
# without needing a specific host path. Copy to docker-compose.yml and customise.
|
||||
# Example Docker Compose — copy to docker-compose.yml and customise.
|
||||
# Build locally: docker compose build
|
||||
# Pull pre-built: docker compose pull
|
||||
# Run: docker compose up -d
|
||||
services:
|
||||
whisperx-base:
|
||||
build:
|
||||
context: ./backend
|
||||
target: whisperx-base
|
||||
image: nat20-whisperx-base:latest
|
||||
restart: "no"
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
target: runtime
|
||||
image: nat20-backend:latest
|
||||
# ── Pre-built image (pull from registry) ──────────────────
|
||||
image: gitea.kansaigaijin.com/Jamie/Nat20-Notes/backend:latest
|
||||
# ── Or build locally (uncomment below) ────────────────────
|
||||
# build:
|
||||
# context: ./backend
|
||||
# target: runtime
|
||||
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- whisperx-base
|
||||
environment:
|
||||
# Skip setup wizard on container restart (or "false" to force re-run)
|
||||
NAT20_ONBOARDING_COMPLETED: "true"
|
||||
# ── Setup wizard ──────────────────────────────────────
|
||||
# "false" (or omit) to show the wizard on first run.
|
||||
# Set to "true" after onboarding completes.
|
||||
NAT20_ONBOARDING_COMPLETED: "false"
|
||||
|
||||
# ── Transcription ─────────────────────────────────────
|
||||
# Model size: tiny | base | small | medium | large-v3
|
||||
NAT20_WHISPER_MODEL: medium
|
||||
# Compute precision: int8 (fastest/least VRAM)
|
||||
# | float16 (more accurate)
|
||||
# | float32 (full precision, slowest)
|
||||
NAT20_WHISPER_COMPUTE_TYPE: int8
|
||||
|
||||
# Required for speaker diarization (accept HF gated-model terms first)
|
||||
# NAT20_HF_TOKEN: "hf_..."
|
||||
|
||||
# ── LLM backend (Ollama — local) ──────────────────────
|
||||
NAT20_OLLAMA_HOST: http://localhost:11434
|
||||
NAT20_OLLAMA_MODEL: qwen2.5:7b
|
||||
|
||||
# ── LLM backend (API — OpenAI-compatible) ─────────────
|
||||
# Uncomment these to use a hosted API instead of Ollama
|
||||
# NAT20_API_BASE_URL: https://api.openai.com/v1
|
||||
# NAT20_API_KEY: "sk-..."
|
||||
# NAT20_API_MODEL: gpt-4o-mini
|
||||
|
||||
# ── Summarization ─────────────────────────────────────
|
||||
# Target words per chunk. Long transcripts are split into
|
||||
# chunks, each summarized separately. Lower = more LLM
|
||||
# calls but finer granularity. Higher = more context per
|
||||
# chunk but may exceed the model's context window.
|
||||
# Default 2500 works for most models (8K–128K context).
|
||||
# NAT20_CHUNK_WORD_TARGET: "2500"
|
||||
|
||||
# Campaign context injected into every summarization prompt.
|
||||
# Inline string or path to a file inside the container.
|
||||
# NAT20_WORLD_CONTEXT: ""
|
||||
# NAT20_WORLD_CONTEXT_PATH: /data/campaign-context.txt
|
||||
|
||||
# Player recap format: story | diary | bullets | custom
|
||||
# NAT20_PLAYER_RECAP_STYLE: story
|
||||
# NAT20_PLAYER_RECAP_CUSTOM_PROMPT: ""
|
||||
|
||||
volumes:
|
||||
# ── Data persistence ──────────────────────────────────
|
||||
# Option A: Named volume (auto-managed, no host path needed)
|
||||
- app_data:/data
|
||||
# Option B: Host bind mount (replace with your path)
|
||||
# - /mnt/media/dnd-sessions:/data
|
||||
|
||||
# HuggingFace + Torch model caches (avoid re-downloading)
|
||||
- hf_cache:/root/.cache/huggingface
|
||||
- torch_cache:/root/.cache/torch
|
||||
|
||||
@@ -35,7 +78,8 @@ services:
|
||||
- "8000:8000"
|
||||
|
||||
frontend:
|
||||
build: ./frontend
|
||||
image: gitea.kansaigaijin.com/Jamie/Nat20-Notes/frontend:latest
|
||||
# build: ./frontend
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
Reference in New Issue
Block a user