120 lines
3.5 KiB
Python
120 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""API-Routen für KI-Services (Transkription, KG-Erstellung, Chat)."""
|
|
|
|
from typing import Optional
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
|
|
from pydantic import BaseModel
|
|
|
|
from ..core.models import Employee
|
|
from .auth import get_current_user
|
|
from ..ai import service as ai_service
|
|
|
|
router = APIRouter(prefix="/ai", tags=["KI-Service"])
|
|
|
|
|
|
# ── Transkription ──────────────────────────────
|
|
|
|
class TranscribeResponse(BaseModel):
|
|
text: str
|
|
tokens_estimated: int
|
|
|
|
|
|
@router.post("/transcribe", response_model=TranscribeResponse)
|
|
async def transcribe(
|
|
file: UploadFile = File(...),
|
|
language: str = Form("de"),
|
|
_user: Employee = Depends(get_current_user),
|
|
):
|
|
if not file.filename or not file.filename.lower().endswith(".wav"):
|
|
raise HTTPException(400, "Nur WAV-Dateien erlaubt")
|
|
|
|
wav_bytes = await file.read()
|
|
if len(wav_bytes) > 50 * 1024 * 1024:
|
|
raise HTTPException(413, "Datei zu gross (max 50 MB)")
|
|
|
|
try:
|
|
result = ai_service.transcribe_audio(wav_bytes, language)
|
|
return TranscribeResponse(**result)
|
|
except RuntimeError as e:
|
|
raise HTTPException(503, str(e))
|
|
except Exception as e:
|
|
raise HTTPException(500, f"Transkription fehlgeschlagen: {e}")
|
|
|
|
|
|
# ── KG-Erstellung ─────────────────────────────
|
|
|
|
class SummarizeRequest(BaseModel):
|
|
transcript: str
|
|
system_prompt: str = ""
|
|
model: str = "gpt-4o"
|
|
|
|
|
|
class SummarizeResponse(BaseModel):
|
|
text: str
|
|
tokens_used: int
|
|
model: str
|
|
|
|
|
|
@router.post("/summarize", response_model=SummarizeResponse)
|
|
def summarize(
|
|
data: SummarizeRequest,
|
|
_user: Employee = Depends(get_current_user),
|
|
):
|
|
try:
|
|
result = ai_service.summarize_transcript(
|
|
data.transcript, data.system_prompt, data.model
|
|
)
|
|
return SummarizeResponse(**result)
|
|
except RuntimeError as e:
|
|
raise HTTPException(503, str(e))
|
|
except Exception as e:
|
|
raise HTTPException(500, f"Zusammenfassung fehlgeschlagen: {e}")
|
|
|
|
|
|
# ── KG-Merge ──────────────────────────────────
|
|
|
|
class MergeRequest(BaseModel):
|
|
existing_kg: str
|
|
full_transcript: str
|
|
system_prompt: str = ""
|
|
model: str = "gpt-4o"
|
|
|
|
|
|
@router.post("/merge", response_model=SummarizeResponse)
|
|
def merge_kg(
|
|
data: MergeRequest,
|
|
_user: Employee = Depends(get_current_user),
|
|
):
|
|
try:
|
|
result = ai_service.merge_kg(
|
|
data.existing_kg, data.full_transcript,
|
|
data.system_prompt, data.model,
|
|
)
|
|
return SummarizeResponse(**result)
|
|
except RuntimeError as e:
|
|
raise HTTPException(503, str(e))
|
|
except Exception as e:
|
|
raise HTTPException(500, f"Merge fehlgeschlagen: {e}")
|
|
|
|
|
|
# ── Generischer Chat ──────────────────────────
|
|
|
|
class ChatRequest(BaseModel):
|
|
messages: list[dict]
|
|
model: str = "gpt-4o"
|
|
|
|
|
|
@router.post("/chat", response_model=SummarizeResponse)
|
|
def chat_completion(
|
|
data: ChatRequest,
|
|
_user: Employee = Depends(get_current_user),
|
|
):
|
|
try:
|
|
result = ai_service.chat_completion(data.messages, data.model)
|
|
return SummarizeResponse(**result)
|
|
except RuntimeError as e:
|
|
raise HTTPException(503, str(e))
|
|
except Exception as e:
|
|
raise HTTPException(500, f"Chat fehlgeschlagen: {e}")
|