Commit 0ba900da authored by Kantz's avatar Kantz
Browse files

mistral hinzugefügt

parent 0e2fdffd
...@@ -72,6 +72,14 @@ class OpenAIChatSettings: ...@@ -72,6 +72,14 @@ class OpenAIChatSettings:
temperature: float | None temperature: float | None
@dataclass(frozen=True)
class MistralChatSettings:
api_key: str
model: str
timeout: float | None
temperature: float | None
@dataclass(frozen=True) @dataclass(frozen=True)
class OpenAIBaseSettings: class OpenAIBaseSettings:
base_url: str base_url: str
...@@ -144,6 +152,21 @@ def get_openai_chat_settings() -> OpenAIChatSettings | None: ...@@ -144,6 +152,21 @@ def get_openai_chat_settings() -> OpenAIChatSettings | None:
) )
def get_mistral_chat_settings() -> MistralChatSettings | None:
model = os.getenv("MISTRAL_CHAT_MODEL")
api_key = os.getenv("MISTRAL_API_KEY")
if not model:
return None
if not api_key:
raise ValueError("Missing MISTRAL_API_KEY for chat")
return MistralChatSettings(
api_key=api_key,
model=model,
timeout=_read_float(os.getenv("MISTRAL_CHAT_TIMEOUT")),
temperature=_read_float(os.getenv("MISTRAL_CHAT_TEMPERATURE")),
)
def get_postgres_url() -> str: def get_postgres_url() -> str:
pg_url = os.getenv("POSTGRES_URL") pg_url = os.getenv("POSTGRES_URL")
if not pg_url: if not pg_url:
......
...@@ -4,6 +4,7 @@ from typing import Any, Callable ...@@ -4,6 +4,7 @@ from typing import Any, Callable
import ollama import ollama
from openai import OpenAI from openai import OpenAI
from mistralai.client import Mistral
from app import config from app import config
...@@ -38,6 +39,29 @@ def _chat_openai(messages: list[dict]) -> dict: ...@@ -38,6 +39,29 @@ def _chat_openai(messages: list[dict]) -> dict:
return {"raw": response, "message": message} return {"raw": response, "message": message}
def _chat_mistral(messages: list[dict]) -> dict:
settings = config.get_mistral_chat_settings()
if not settings:
return {}
kwargs: dict[str, Any] = {
"model": settings.model,
"messages": messages,
"stream": False,
"response_format": {"type": "text"},
}
if settings.temperature is not None:
kwargs["temperature"] = settings.temperature
if settings.timeout is not None:
kwargs["timeout_ms"] = int(settings.timeout * 1000)
with Mistral(api_key=settings.api_key) as client:
response = client.chat.complete(**kwargs)
message = response.choices[0].message if getattr(response, "choices", None) else {}
return {"raw": response, "message": message}
def get_message_content(result: dict | object) -> str: def get_message_content(result: dict | object) -> str:
message = result.get("message") if isinstance(result, dict) else result message = result.get("message") if isinstance(result, dict) else result
if isinstance(message, dict): if isinstance(message, dict):
...@@ -51,12 +75,25 @@ def chat( ...@@ -51,12 +75,25 @@ def chat(
messages: list[dict], messages: list[dict],
tools: list[Callable[..., Any]] | None = None, tools: list[Callable[..., Any]] | None = None,
use_ollama: bool = False, use_ollama: bool = False,
use_mistral: bool = False,
) -> dict: ) -> dict:
if use_mistral and tools:
raise RuntimeError("Mistral chat is currently only implemented for calls without tools.")
if use_mistral:
mistral_result = _chat_mistral(messages)
if mistral_result:
return mistral_result
if not tools and not use_ollama: if not tools and not use_ollama:
openai_result = _chat_openai(messages) openai_result = _chat_openai(messages)
if openai_result: if openai_result:
return openai_result return openai_result
mistral_result = _chat_mistral(messages)
if mistral_result:
return mistral_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)
...@@ -83,16 +120,27 @@ def chat_with_tools( ...@@ -83,16 +120,27 @@ def chat_with_tools(
messages: list[dict], messages: list[dict],
tools: list[Callable[..., Any]], tools: list[Callable[..., Any]],
use_ollama: bool = True, use_ollama: bool = True,
use_mistral: bool = False,
return_after_tools: bool = False, return_after_tools: bool = False,
) -> tuple[dict, list[dict[str, Any]]]: ) -> tuple[dict, list[dict[str, Any]]]:
tool_map = {tool.__name__: tool for tool in tools} tool_map = {tool.__name__: tool for tool in tools}
result = chat(messages=messages, tools=tools, use_ollama=use_ollama) result = chat(
messages=messages,
tools=tools,
use_ollama=use_ollama,
use_mistral=use_mistral,
)
tool_outputs = _apply_tool_calls(result, messages, tool_map) tool_outputs = _apply_tool_calls(result, messages, tool_map)
if not tool_outputs or return_after_tools: if not tool_outputs or return_after_tools:
return result, tool_outputs return result, tool_outputs
final_result = chat(messages=messages, tools=tools, use_ollama=use_ollama) final_result = chat(
messages=messages,
tools=tools,
use_ollama=use_ollama,
use_mistral=use_mistral,
)
return final_result, tool_outputs return final_result, tool_outputs
......
...@@ -6,6 +6,7 @@ pillow ...@@ -6,6 +6,7 @@ pillow
httpx httpx
ollama ollama
openai openai
mistralai
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