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:
@@ -97,6 +97,8 @@ async def run_pipeline(job_id: int) -> None:
|
||||
audio_path = settings.upload_dir / job.filename
|
||||
title = job.title or audio_path.stem
|
||||
profile = job.profile or "meeting"
|
||||
# Leeres `model` → Mac-Worker nutzt seinen .env-Default.
|
||||
model = (job.model or "").strip() or None
|
||||
existing_tx_path = _existing(job.transcript_path)
|
||||
existing_sum_path = _existing(job.summary_path)
|
||||
existing_pro_path = _existing(job.protocol_path)
|
||||
@@ -131,16 +133,17 @@ async def run_pipeline(job_id: int) -> None:
|
||||
_update(job_id, status=JobStatus.SUMMARIZING, progress=70)
|
||||
else:
|
||||
_start_step(job_id, JobStatus.SUMMARIZING, 50)
|
||||
log.info("[job %s] preload model", job_id)
|
||||
log.info("[job %s] preload model=%s", job_id, model or "(worker default)")
|
||||
try:
|
||||
await _with_heartbeat(job_id, client.preload(profile=profile, job_id=job_id))
|
||||
await _with_heartbeat(job_id, client.preload(profile=profile, model=model, job_id=job_id))
|
||||
except Exception as e: # noqa: BLE001
|
||||
log.warning("[job %s] preload failed (non-fatal): %s", job_id, e)
|
||||
_update(job_id, progress=55)
|
||||
log.info("[job %s] summarize", job_id)
|
||||
summary = await _with_heartbeat(
|
||||
job_id,
|
||||
client.summarize(transcript_text, title=title, profile=profile, job_id=job_id),
|
||||
client.summarize(transcript_text, title=title, profile=profile, model=model,
|
||||
job_id=job_id),
|
||||
)
|
||||
summary_path = job_dir / "summary.json"
|
||||
summary_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
@@ -156,7 +159,8 @@ async def run_pipeline(job_id: int) -> None:
|
||||
log.info("[job %s] protocol", job_id)
|
||||
protocol = await _with_heartbeat(
|
||||
job_id,
|
||||
client.protocol(transcript_text, summary, title=title, profile=profile, job_id=job_id),
|
||||
client.protocol(transcript_text, summary, title=title, profile=profile, model=model,
|
||||
job_id=job_id),
|
||||
)
|
||||
protocol_path = job_dir / "protocol.json"
|
||||
protocol_path.write_text(json.dumps(protocol, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user