update
This commit is contained in:
119
AzA march 2026/workforce_planner/api/routes_ai.py
Normal file
119
AzA march 2026/workforce_planner/api/routes_ai.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# -*- 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}")
|
||||
Reference in New Issue
Block a user