feat(model): wählbares LLM-Modell pro User & pro Job

Mac-Worker:
- /api/summarize, /api/protocol, /api/preload akzeptieren optionales
  model-Feld → überschreibt den .env-Default pro Call, kein Restart nötig
- /api/models listet die lokal verfügbaren Ollama-Modelle + Default

LXC:
- User.default_model + Job.model (Migration für SQLite)
- /api/auth/me liefert default_model, PATCH speichert ihn sofort
- /api/mac/models proxiet die Liste an die UI
- Pipeline reicht job.model an Mac-Worker durch; leer = Worker-Default
- create_job & reprocess akzeptieren model-Override
- Snapshot-Meta nutzt job.model (genauer als /health-Snapshot)

UI:
- Header-Dropdown "Modell:" neben "Profil:" — sofort-speichert User-Default
- Jeder Job zeigt sein Modell als Tag (lila); leer bedeutet Worker-Default
- Reprocess öffnet einen Modal-Picker (statt simplem confirm), Auswahl
  aller verfügbaren Modelle inkl. "Worker-Default"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-05-16 16:48:11 +00:00
co-authored by Claude Opus 4.7
parent dbf7bca6c7
commit c6164d946c
13 changed files with 386 additions and 54 deletions
+4
View File
@@ -28,6 +28,10 @@ class Job(SQLModel, table=True):
protocol_path: str = ""
docx_path: str = ""
pdf_path: str = ""
# LLM-Modell für diesen Job — leer = Worker-Default. Wird beim Erstellen
# aus dem Upload-Form oder dem User-Default gefüllt; bleibt auch nach
# Reprocess als Audit-Spur erhalten (mit dem aktuell gewählten Modell).
model: str = ""
step_started_at: Optional[datetime] = Field(default=None)
last_heartbeat_at: Optional[datetime] = Field(default=None)
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
+3
View File
@@ -10,4 +10,7 @@ class User(SQLModel, table=True):
password_hash: str
is_admin: bool = Field(default=False)
default_profile: str = Field(default="meeting")
# Leerer Wert = der Worker-Default aus der Mac-.env wird verwendet.
# Sonst überschreibt diese Auswahl das LLM pro Job — kein Worker-Restart nötig.
default_model: str = Field(default="")
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))