- meetrec-server: Ollama integration (chat API, gemma4:12b, num_ctx
32768); German structured summary (topic/points/decisions/to-dos)
written to summary.md; agenda coverage returns strict JSON (covered,
time, evidence) parsed defensively; both run automatically in a
background thread after upload plus manual trigger endpoints
(POST /summary, POST /agenda) with status tracking in the index
- phone: agenda input on the Record tab (one item per line, persisted)
is uploaded with the recording; Library detail shows the summary and
a per-item agenda checklist with timestamps and evidence quotes,
with polling while the server generates and manual re-trigger buttons
- validated end-to-end against the live Ollama server: crafted German
test meeting produced a correct structured summary and perfect agenda
discrimination (covered items with correct timestamps + quotes,
undiscussed item correctly false)
- server/meetrec-server: FastAPI storage API (upload bundle with wav/
txt/srt/json + metadata incl. agenda, list, fetch, download, delete);
file-based index.json, no database; Docker Compose on port 8090,
Tailscale-only bind like whisper-server; Ollama env prepared for M3c
(gemma4:12b, German)
- phone: StorageClient (stdlib multipart upload); RecorderService uploads
the bundle in the background after the final pass and publishes
UploadState (Uploading/Done/Error) to the UI
- app: Library URL setting (persisted, default http://100.103.83.12:8090,
empty disables upload); status line reports upload progress
- storage API validated locally end-to-end: upload, list, metadata,
download, path-traversal rejected, delete
The first server deployment downloaded only 1101 bytes (a redirect/error
page) and the entrypoint promoted it to ggml-large-v3.bin, after which
every restart skipped the download and the server ran without a valid
model. Now both fresh downloads and existing files are validated
(minimum 50 MB + the ggml magic bytes); invalid files are logged,
deleted, and re-downloaded, and a failed download dumps the first 400
bytes of what was actually received for diagnosis before exiting.
Validated locally: a poisoned model file is detected, removed, and a
valid one re-downloaded; inference served correctly afterwards.
- server/whisper-server: compose stack built from the pinned whisper.cpp
v1.9.3 release, same as the Android JNI layer
- Vulkan GPU backend (AMD Radeon AI PRO R9700 / RADV) with transparent
CPU fallback and NO_GPU override; GGML models auto-download on first
start (MODEL env, default large-v3)
- API bound to the Tailscale interface only (100.103.83.12:8080) since
whisper-server has no authentication; render-group GID passthrough for
/dev/dri
- validated locally: image builds, entrypoint downloads tiny, POST
/inference returns verbose_json with language + segments; GPU-less
fallback confirmed