Marc-André Bombeck
b91649d6de
feat(ai): UI-configurable response timeout, local streaming, dedicated OCR provider
...
Add three per-user AI settings, all configured in the app (no new env vars),
behind one migration (0198):
- Response timeout (seconds). A per-user upstream timeout threaded onto the
provider call. A local/self-hosted backend can take more than the legacy
60 s default to load a model on the first request, which timed the Coach
out before the first token. Defaults to a generous ~180 s when unset;
validated to 10–600 s.
- True token streaming for the local OpenAI-compatible client. The client now
POSTs with stream:true and parses the SSE delta chunks, emitting tokens as
they arrive, with a per-idle-gap timeout instead of a whole-call ceiling and
a graceful fallback to the buffered path when a server cannot stream. The
Coach route runs the provider call inside the response stream behind a
keepalive heartbeat so a reverse proxy no longer idle-drops the connection
during model load or generation. Grounding, refusal, and sentinel-stripping
still run on the complete reply before any token reaches the client.
- Dedicated document-scan (Lab-OCR) provider. Off by default — the OCR path
uses the main provider chain. When enabled, lab-report processing resolves a
separate provider/model/key, with a hint when the chosen model is not
vision-capable. The new key column is AES-256-GCM at rest and registered in
the encrypted-columns registry and the rotation script.
i18n: EN + DE translations for the new Settings → AI strings (other locales
carry interim copies to keep locale parity green).
2026-06-27 15:21:40 +02:00
..
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-03-10 20:14:33 +01:00
2026-04-06 00:42:46 +02:00
2026-04-18 22:20:12 +02:00
2026-05-08 01:05:56 +02:00
2026-05-03 21:52:57 +02:00
2026-05-08 01:05:56 +02:00
2026-05-08 14:33:39 +02:00
2026-05-08 14:29:44 +02:00
2026-05-08 21:36:36 +02:00
2026-05-08 21:45:18 +02:00
2026-05-09 21:01:45 +02:00
2026-05-09 21:04:04 +02:00
2026-05-09 21:14:00 +02:00
2026-05-09 21:36:47 +02:00
2026-05-09 23:46:56 +02:00
2026-05-10 00:20:12 +02:00
2026-05-10 01:25:57 +02:00
2026-05-10 15:54:28 +02:00
2026-05-11 02:44:12 +02:00
2026-05-11 00:35:58 +02:00
2026-05-11 01:35:45 +02:00
2026-05-11 01:36:27 +02:00
2026-05-11 01:51:27 +02:00
2026-05-11 02:13:47 +02:00
2026-05-11 02:38:17 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-14 23:49:32 +02:00
2026-05-15 22:59:10 +02:00
2026-05-16 12:37:55 +02:00
2026-05-16 12:37:55 +02:00
2026-05-16 12:37:55 +02:00
2026-05-16 14:19:57 +02:00
2026-05-16 21:25:26 +02:00
2026-05-17 09:55:33 +02:00
2026-05-17 13:22:51 +02:00
2026-05-17 23:08:17 +02:00
2026-05-21 07:39:10 +02:00
2026-05-21 07:39:10 +02:00
2026-05-21 07:39:10 +02:00
2026-05-21 11:20:24 +02:00
2026-05-21 12:48:02 +02:00
2026-05-21 23:13:21 +02:00
2026-05-22 09:18:52 +02:00
2026-05-22 09:18:52 +02:00
2026-05-22 09:18:52 +02:00
2026-05-23 12:51:41 +02:00
2026-05-23 12:51:41 +02:00
2026-05-28 07:52:11 +02:00
2026-05-28 19:33:11 +02:00
2026-05-28 22:32:18 +02:00
2026-05-28 22:32:40 +02:00
2026-05-28 22:39:20 +02:00
2026-05-28 23:38:21 +02:00
2026-05-29 22:07:10 +02:00
2026-05-30 00:10:12 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-05-31 14:36:17 +02:00
2026-06-01 17:31:45 +02:00
2026-06-01 20:25:34 +02:00
2026-06-01 20:25:34 +02:00
2026-06-01 20:25:42 +02:00
2026-06-01 23:24:10 +02:00
2026-06-02 16:45:23 +02:00
2026-06-02 22:02:50 +02:00
2026-06-02 22:07:28 +02:00
2026-06-02 23:43:22 +02:00
2026-06-02 22:02:46 +02:00
2026-06-02 22:49:43 +02:00
2026-06-03 19:31:16 +02:00
2026-06-04 00:49:31 +02:00
2026-06-04 00:49:31 +02:00
2026-06-04 00:50:13 +02:00
2026-06-04 01:21:42 +02:00
2026-06-04 03:38:19 +02:00
2026-06-04 09:29:49 +02:00
2026-06-04 10:11:19 +02:00
2026-06-04 21:02:10 +02:00
2026-06-04 22:36:58 +02:00
2026-06-05 01:05:47 +02:00
2026-06-05 01:07:27 +02:00
2026-06-05 03:01:36 +02:00
2026-06-05 03:01:36 +02:00
2026-06-05 03:01:36 +02:00
2026-06-05 08:10:13 +02:00
2026-06-05 14:45:58 +02:00
2026-06-05 15:28:47 +02:00
2026-06-05 20:50:05 +02:00
2026-06-06 08:19:32 +02:00
2026-06-06 08:19:32 +02:00
2026-06-06 08:19:32 +02:00
2026-06-06 11:49:23 +02:00
2026-06-06 08:57:12 +02:00
2026-06-06 12:39:28 +02:00
2026-06-06 16:54:43 +02:00
2026-06-07 13:26:41 +02:00
2026-06-07 19:23:59 +02:00
2026-06-08 18:29:05 +02:00
2026-06-10 13:34:46 +02:00
2026-06-10 15:40:48 +02:00
2026-06-10 15:40:48 +02:00
2026-06-10 15:40:48 +02:00
2026-06-10 16:18:48 +02:00
2026-06-10 16:18:48 +02:00
2026-06-10 22:21:44 +02:00
2026-06-11 00:10:01 +02:00
2026-06-11 11:45:58 +02:00
2026-06-11 13:57:15 +02:00
2026-06-11 21:17:05 +02:00
2026-06-12 17:42:31 +02:00
2026-06-12 18:10:21 +02:00
2026-06-12 21:04:09 +02:00
2026-06-12 22:03:01 +02:00
2026-06-12 22:56:03 +02:00
2026-06-13 16:07:50 +02:00
2026-06-14 10:29:22 +02:00
2026-06-14 15:04:25 +02:00
2026-06-14 15:23:26 +02:00
2026-06-14 17:19:09 +02:00
2026-06-14 17:42:00 +02:00
2026-06-14 21:23:56 +02:00
2026-06-14 20:58:49 +02:00
2026-06-15 01:49:28 +02:00
2026-06-14 23:20:54 +02:00
2026-06-14 23:22:52 +02:00
2026-06-15 00:09:33 +02:00
2026-06-15 00:07:30 +02:00
2026-06-15 20:53:46 +02:00
2026-06-15 22:44:35 +02:00
2026-06-16 20:36:13 +02:00
2026-06-16 23:11:08 +02:00
2026-06-16 23:11:08 +02:00
2026-06-16 23:11:08 +02:00
2026-06-18 19:27:28 +02:00
2026-06-18 20:17:13 +02:00
2026-06-18 21:37:13 +02:00
2026-06-18 22:05:17 +02:00
2026-06-18 22:41:47 +02:00
2026-06-19 20:52:31 +02:00
2026-06-19 21:25:22 +02:00
2026-06-19 22:07:46 +02:00
2026-06-20 11:17:43 +02:00
2026-06-20 11:58:58 +02:00
2026-06-20 16:52:19 +02:00
2026-06-20 16:50:06 +02:00
2026-06-21 10:22:29 +02:00
2026-06-21 10:44:15 +02:00
2026-06-21 21:06:17 +02:00
2026-06-21 21:06:09 +02:00
2026-06-21 21:06:42 +02:00
2026-06-22 07:01:42 +02:00
2026-06-22 07:20:41 +02:00
2026-06-26 12:05:49 +02:00
2026-06-26 13:24:30 +02:00
2026-06-27 01:25:35 +02:00
2026-06-27 12:48:48 +02:00
2026-06-27 13:37:50 +02:00
2026-06-27 15:21:40 +02:00
2026-05-09 21:04:04 +02:00