initial commit: FastAPI translator proxying to Ollama on radagast

- app.py: /api/models filtered to gemma+aya, /api/translate streams
  NDJSON from Ollama with stream:true, /healthz for k8s probes
- static/index.html: dark-mode UI, three dropdowns (source/target/model),
  live token streaming with spinner+pulse+timer indicators
- Dockerfile: two-stage uv build, slim Python 3.13 runtime
- .gitea/workflows/build.yml: multi-arch (amd64+arm64) build, push to
  Scaleway registry on push to main
- build.sh: manual fallback if Gitea Actions isn't available
This commit is contained in:
João Pedro Battistella Nadas
2026-06-09 15:13:48 +02:00
commit 777c80a0e1
10 changed files with 1236 additions and 0 deletions

45
README.md Normal file
View File

@@ -0,0 +1,45 @@
# finrod
Tiny web translator backed by Ollama on radagast. Named for Finrod Felagund, Noldor loremaster of the tongues of Men.
## Run
```sh
uv run uvicorn app:app --host 127.0.0.1 --port 8000 --reload
```
Then open http://127.0.0.1:8000.
## Config
| Env var | Default | Notes |
|---|---|---|
| `OLLAMA_URL` | `http://radagast.jpnadas.xyz:11434` | Ollama base URL |
| `MODEL_FILTER` | `gemma,aya` | Comma-separated substrings; model matches if it contains any. Empty = show all |
## Models
For Pt/Nl/En translation, three worth A/B-ing:
```sh
ssh radagast 'ollama pull gemma2:9b' # already there — big-and-broad baseline
ssh radagast 'ollama pull gemma3:4b' # newer multilingual training, ~2-3× faster on Ivy Bridge
ssh radagast 'ollama pull aya-expanse:8b' # Cohere multilingual model, strong on Dutch
```
All three fit in radagast's 10 GB at Q4. Switching models in the dropdown forces Ollama to load the new weights — expect a 5-15 s pause on the first call after a switch while it reads from disk.
## Build / push image
CI: `.gitea/workflows/build.yml` builds multi-arch (amd64+arm64) on push to `main` and pushes to `rg.nl-ams.scw.cloud/valinor/finrod:{latest, <short-sha>}`. Requires a `SCW_SECRET_KEY` secret on the Gitea repo with a Scaleway IAM key that has `ObjectStorage:RegistryPush` on the `valinor` registry.
Manual fallback if Gitea Actions isn't wired up:
```sh
docker login rg.nl-ams.scw.cloud -u nologin -p <SCW_SECRET_KEY>
./build.sh
```
## Deploy
Cluster manifests live in `valinor/apps/finrod/` (bjw-s app-template, internal-only ingress at `finrod.jpnadas.xyz`). Merging a PR there triggers ArgoCD to sync; bumping the image tag in `values.yaml` is how you roll out a new build.