Commit 55ea7dcf authored by Kantz's avatar Kantz
Browse files

adden GWDG API

parent 9c04fca1
......@@ -2,11 +2,20 @@ from __future__ import annotations
from typing import List, Optional
import os
from fastapi import APIRouter, HTTPException
from dotenv import load_dotenv
import httpx
from pydantic import BaseModel, Field
router = APIRouter()
load_dotenv()
OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
class ChatMessage(BaseModel):
role: str = Field(..., pattern="^(user|assistant)$")
......@@ -28,6 +37,31 @@ def chat(request: ChatRequest) -> ChatResponse:
if not request.messages:
raise HTTPException(status_code=400, detail="messages required")
last = request.messages[-1]
reply = f"Mock reply to: {last.text}"
return ChatResponse(reply=reply, sources=["doc:example"])
if not OPENAI_BASE_URL or not OPENAI_API_KEY:
last = request.messages[-1]
reply = f"Mock reply to: {last.text}"
return ChatResponse(reply=reply, sources=["doc:example"])
messages_payload = [
{"role": message.role, "content": message.text}
for message in request.messages
]
payload = {
"model": OPENAI_MODEL,
"messages": messages_payload,
}
headers = {"Authorization": f"Bearer {OPENAI_API_KEY}"}
url = f"{OPENAI_BASE_URL.rstrip('/')}/v1/chat/completions"
try:
with httpx.Client(timeout=60.0) as client:
response = client.post(url, headers=headers, json=payload)
response.raise_for_status()
except httpx.HTTPError as exc:
raise HTTPException(status_code=502, detail="chat provider failed") from exc
data = response.json()
reply = data["choices"][0]["message"]["content"]
return ChatResponse(reply=reply, sources=["openai-compatible"])
......@@ -2,4 +2,5 @@ fastapi
uvicorn
python-dotenv
mpxpy
pillow
\ No newline at end of file
pillow
httpx
......@@ -33,7 +33,7 @@ export default function App() {
const [draft, setDraft] = useState("");
const [isCanvasVisible, setIsCanvasVisible] = useState(true);
const handleSend = () => {
const handleSend = async () => {
const trimmed = draft.trim();
if (!trimmed) {
return;
......@@ -45,14 +45,47 @@ export default function App() {
text: trimmed,
};
const assistantMessage: ChatMessage = {
id: `m-${Date.now()}-assistant`,
role: "assistant",
text: "Got it. I will solve that step by step.",
};
setMessages((prev) => [...prev, userMessage, assistantMessage]);
setMessages((prev) => [...prev, userMessage]);
setDraft("");
try {
const response = await fetch("http://localhost:8000/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [...messages, userMessage].map((message) => ({
role: message.role,
text: message.text,
})),
}),
});
if (!response.ok) {
throw new Error(`Chat failed: ${response.status}`);
}
const payload: { reply?: string } = await response.json();
if (payload.reply) {
setMessages((prev) => [
...prev,
{
id: `m-${Date.now()}-assistant`,
role: "assistant",
text: payload.reply,
},
]);
}
} catch (error) {
setMessages((prev) => [
...prev,
{
id: `m-${Date.now()}-assistant`,
role: "assistant",
text: "Chat request failed. Check the API logs.",
},
]);
void error;
}
};
const handleToggleCanvas = () => {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment