Commit d040fafa authored by Kantz's avatar Kantz
Browse files

GWDG jetzt auch für chat

parent 3a6de9fc
...@@ -5,7 +5,7 @@ def generate_hint( ...@@ -5,7 +5,7 @@ def generate_hint(
task: str, task: str,
solution: str, solution: str,
history: str | None = None, history: str | None = None,
context_sheet: str | None = None, retrival: str | None = None,
) -> str: ) -> str:
prompt = ( prompt = (
"Du bist ein didaktischer Tutor. " "Du bist ein didaktischer Tutor. "
...@@ -20,9 +20,9 @@ def generate_hint( ...@@ -20,9 +20,9 @@ def generate_hint(
+ "\n" + "\n"
) )
if history: if history:
prompt += "\nHistorie:\n" + history + "\n" prompt = "\nHistorie:\n" + history + "\n" + prompt
if context_sheet: if retrival:
prompt += "\nKontext:\n" + context_sheet + "\n" prompt = "\nKontext:\n" + retrival + "\n" + prompt
prompt += "Halte dich kurz und klar. Gibt nicht die Lösung aus." prompt += "Halte dich kurz und klar. Gibt nicht die Lösung aus."
result = llm_client.chat( result = llm_client.chat(
...@@ -51,7 +51,7 @@ TOOL_SPEC = { ...@@ -51,7 +51,7 @@ TOOL_SPEC = {
"type": "string", "type": "string",
"description": "Optionaler Verlauf, kann leer sein", "description": "Optionaler Verlauf, kann leer sein",
}, },
"context_sheet": { "retrival": {
"type": "string", "type": "string",
"description": "Optionales Kontextblatt mit Werkzeug- und Retrieval-Infos", "description": "Optionales Kontextblatt mit Werkzeug- und Retrieval-Infos",
}, },
......
...@@ -21,6 +21,13 @@ class EmbeddingSettings: ...@@ -21,6 +21,13 @@ class EmbeddingSettings:
model: str model: str
target_dim: int target_dim: int
@dataclass(frozen=True)
class OpenAIChatSettings:
base_url: str
api_key: str
model: str
timeout: float | None
@dataclass(frozen=True) @dataclass(frozen=True)
class MathpixSettings: class MathpixSettings:
app_id: str app_id: str
...@@ -63,6 +70,21 @@ def get_embedding_settings() -> EmbeddingSettings: ...@@ -63,6 +70,21 @@ def get_embedding_settings() -> EmbeddingSettings:
target_dim=1024, target_dim=1024,
) )
def get_openai_chat_settings() -> OpenAIChatSettings | None:
model = os.getenv("OPENAI_CHAT_MODEL")
if not model:
return None
base_url = os.getenv("OPENAI_BASE_URL")
api_key = os.getenv("OPENAI_API_KEY")
if not base_url or not api_key:
raise ValueError("Missing OPENAI_BASE_URL or OPENAI_API_KEY for chat")
return OpenAIChatSettings(
base_url=base_url,
api_key=api_key,
model=model,
timeout=_read_float(os.getenv("OPENAI_CHAT_TIMEOUT")),
)
def get_postgres_url() -> str: def get_postgres_url() -> str:
pg_url = os.getenv("POSTGRES_URL") pg_url = os.getenv("POSTGRES_URL")
......
...@@ -163,6 +163,12 @@ def format_sheet(sheet: dict[str, Any]) -> str: ...@@ -163,6 +163,12 @@ def format_sheet(sheet: dict[str, Any]) -> str:
return "\n\n".join(parts) return "\n\n".join(parts)
def get_retrival(sheet: dict[str, Any]) -> str:
retrievals = sheet.get("retrieval_contexts", [])
if not retrievals:
return ""
latest = retrievals[-1]
return latest.get("context", "")
def save_sheet(sheet: dict[str, Any]) -> None: def save_sheet(sheet: dict[str, Any]) -> None:
os.makedirs(_LOG_DIR, exist_ok=True) os.makedirs(_LOG_DIR, exist_ok=True)
......
import inspect import inspect
import ollama import ollama
from openai import OpenAI
from app import config from app import config
...@@ -12,7 +14,27 @@ def _filter_kwargs(func, kwargs: dict) -> dict: ...@@ -12,7 +14,27 @@ def _filter_kwargs(func, kwargs: dict) -> dict:
return {key: value for key, value in kwargs.items() if key in signature.parameters} return {key: value for key, value in kwargs.items() if key in signature.parameters}
def _chat_openai(messages: list[dict]) -> dict:
settings = config.get_openai_chat_settings()
if not settings:
return {}
timeout = settings.timeout or 60.0
client = OpenAI(api_key=settings.api_key, base_url=settings.base_url, timeout=timeout)
response = client.chat.completions.create(
messages=messages,
model=settings.model,
)
message = response.choices[0].message if response.choices else {}
return {"raw": response, "message": message}
def chat(messages: list[dict], tools: list[dict] | None = None) -> dict: def chat(messages: list[dict], tools: list[dict] | None = None) -> dict:
if not tools:
openai_result = _chat_openai(messages)
if openai_result:
return openai_result
settings = config.get_ollama_settings() settings = config.get_ollama_settings()
client = ollama.Client(host=settings.base_url, timeout=settings.timeout) client = ollama.Client(host=settings.base_url, timeout=settings.timeout)
......
...@@ -62,7 +62,7 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict: ...@@ -62,7 +62,7 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict:
"task": last_user.get("content", ""), "task": last_user.get("content", ""),
"solution": context_store.first_math_solution(sheet), "solution": context_store.first_math_solution(sheet),
"history": history_text, "history": history_text,
"context_sheet": sheet_text, "retrival": context_store.get_retrival(sheet),
} }
reply = hint_LLM.generate_hint(**hint_args) reply = hint_LLM.generate_hint(**hint_args)
_append_tool_log(tool_log, "generate_hint", hint_args, reply) _append_tool_log(tool_log, "generate_hint", hint_args, reply)
......
...@@ -5,6 +5,7 @@ mpxpy ...@@ -5,6 +5,7 @@ mpxpy
pillow pillow
httpx httpx
ollama ollama
openai
sympy sympy
psycopg[binary] psycopg[binary]
pgvector pgvector
......
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