Initial commit: breakpilot-core - Shared Infrastructure

Docker Compose with 24+ services:
- PostgreSQL (PostGIS), Valkey, MinIO, Qdrant
- Vault (PKI/TLS), Nginx (Reverse Proxy)
- Backend Core API, Consent Service, Billing Service
- RAG Service, Embedding Service
- Gitea, Woodpecker CI/CD
- Night Scheduler, Health Aggregator
- Jitsi (Web/XMPP/JVB/Jicofo), Mailpit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-11 23:47:13 +01:00
commit ad111d5e69
244 changed files with 84288 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
"""
Pydantic Models für OpenAI-kompatible API.
"""
from .chat import (
ChatMessage,
ChatCompletionRequest,
ChatCompletionResponse,
ChatCompletionChunk,
ChatChoice,
ChatChoiceDelta,
Usage,
ToolCall,
FunctionCall,
Tool,
ToolFunction,
)
__all__ = [
"ChatMessage",
"ChatCompletionRequest",
"ChatCompletionResponse",
"ChatCompletionChunk",
"ChatChoice",
"ChatChoiceDelta",
"Usage",
"ToolCall",
"FunctionCall",
"Tool",
"ToolFunction",
]

View File

@@ -0,0 +1,135 @@
"""
OpenAI-kompatible Chat Completion Models.
Basiert auf OpenAI API Spezifikation:
https://platform.openai.com/docs/api-reference/chat/create
"""
from __future__ import annotations
from typing import Optional, Literal, Any, Union, List, Dict
from pydantic import BaseModel, Field
import time
import uuid
class FunctionCall(BaseModel):
"""Function call in einer Tool-Anfrage."""
name: str
arguments: str # JSON string
class ToolCall(BaseModel):
"""Tool Call vom Modell."""
id: str = Field(default_factory=lambda: f"call_{uuid.uuid4().hex[:12]}")
type: Literal["function"] = "function"
function: FunctionCall
class ChatMessage(BaseModel):
"""Eine Nachricht im Chat."""
role: Literal["system", "user", "assistant", "tool"]
content: Optional[str] = None
name: Optional[str] = None
tool_call_id: Optional[str] = None
tool_calls: Optional[list[ToolCall]] = None
class ToolFunction(BaseModel):
"""Definition einer Tool-Funktion."""
name: str
description: Optional[str] = None
parameters: dict[str, Any] = Field(default_factory=dict)
class Tool(BaseModel):
"""Tool-Definition für Function Calling."""
type: Literal["function"] = "function"
function: ToolFunction
class RequestMetadata(BaseModel):
"""Zusätzliche Metadaten für die Anfrage."""
playbook_id: Optional[str] = None
tenant_id: Optional[str] = None
user_id: Optional[str] = None
class ChatCompletionRequest(BaseModel):
"""Request für Chat Completions."""
model: str
messages: list[ChatMessage]
stream: bool = False
temperature: Optional[float] = Field(default=0.7, ge=0, le=2)
top_p: Optional[float] = Field(default=1.0, ge=0, le=1)
max_tokens: Optional[int] = Field(default=None, ge=1)
stop: Optional[Union[List[str], str]] = None
presence_penalty: Optional[float] = Field(default=0, ge=-2, le=2)
frequency_penalty: Optional[float] = Field(default=0, ge=-2, le=2)
user: Optional[str] = None
tools: Optional[list[Tool]] = None
tool_choice: Optional[Union[str, Dict[str, Any]]] = None
metadata: Optional[RequestMetadata] = None
class ChatChoice(BaseModel):
"""Ein Choice in der Response."""
index: int = 0
message: ChatMessage
finish_reason: Optional[Literal["stop", "length", "tool_calls", "content_filter"]] = None
class ChatChoiceDelta(BaseModel):
"""Delta für Streaming Response."""
role: Optional[str] = None
content: Optional[str] = None
tool_calls: Optional[list[ToolCall]] = None
class StreamChoice(BaseModel):
"""Choice in Streaming Response."""
index: int = 0
delta: ChatChoiceDelta
finish_reason: Optional[Literal["stop", "length", "tool_calls", "content_filter"]] = None
class Usage(BaseModel):
"""Token Usage Statistiken."""
prompt_tokens: int = 0
completion_tokens: int = 0
total_tokens: int = 0
class ChatCompletionResponse(BaseModel):
"""Response für Chat Completions (non-streaming)."""
id: str = Field(default_factory=lambda: f"chatcmpl-{uuid.uuid4().hex[:12]}")
object: Literal["chat.completion"] = "chat.completion"
created: int = Field(default_factory=lambda: int(time.time()))
model: str
choices: list[ChatChoice]
usage: Optional[Usage] = None
class ChatCompletionChunk(BaseModel):
"""Chunk für Streaming Response."""
id: str = Field(default_factory=lambda: f"chatcmpl-{uuid.uuid4().hex[:12]}")
object: Literal["chat.completion.chunk"] = "chat.completion.chunk"
created: int = Field(default_factory=lambda: int(time.time()))
model: str
choices: list[StreamChoice]
# Model Info
class ModelInfo(BaseModel):
"""Information über ein verfügbares Modell."""
id: str
object: Literal["model"] = "model"
created: int = Field(default_factory=lambda: int(time.time()))
owned_by: str = "breakpilot"
description: Optional[str] = None
context_length: int = 8192
class ModelListResponse(BaseModel):
"""Response für /v1/models."""
object: Literal["list"] = "list"
data: list[ModelInfo]