AI Assistant plugin: backend with LiteLLM, agents, tools, streaming chat
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
"""Pydantic schemas for the AI Assistant plugin."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
# ─── Providers ───
|
||||
|
||||
class AIProviderCreate(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=100)
|
||||
provider_type: str = Field(..., min_length=1, max_length=50)
|
||||
api_key: str = Field(default="", max_length=2000)
|
||||
base_url: str = Field(default="", max_length=500)
|
||||
is_active: bool = True
|
||||
is_default: bool = False
|
||||
config: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class AIProviderUpdate(BaseModel):
|
||||
name: str | None = Field(None, min_length=1, max_length=100)
|
||||
provider_type: str | None = Field(None, min_length=1, max_length=50)
|
||||
api_key: str | None = Field(None, max_length=2000)
|
||||
base_url: str | None = Field(None, max_length=500)
|
||||
is_active: bool | None = None
|
||||
is_default: bool | None = None
|
||||
config: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class AIProviderResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
name: str
|
||||
provider_type: str
|
||||
api_key: str # masked in routes
|
||||
base_url: str
|
||||
is_active: bool
|
||||
is_default: bool
|
||||
config: dict[str, Any]
|
||||
created_at: datetime | None = None
|
||||
updated_at: datetime | None = None
|
||||
|
||||
|
||||
# ─── Models ───
|
||||
|
||||
class AIModelCreate(BaseModel):
|
||||
provider_id: str
|
||||
model_id: str = Field(..., min_length=1, max_length=200)
|
||||
display_name: str = Field(..., min_length=1, max_length=200)
|
||||
context_window: int = Field(default=4096, ge=1)
|
||||
supports_tools: bool = False
|
||||
supports_streaming: bool = True
|
||||
is_active: bool = True
|
||||
config: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class AIModelUpdate(BaseModel):
|
||||
model_id: str | None = Field(None, min_length=1, max_length=200)
|
||||
display_name: str | None = Field(None, min_length=1, max_length=200)
|
||||
context_window: int | None = Field(None, ge=1)
|
||||
supports_tools: bool | None = None
|
||||
supports_streaming: bool | None = None
|
||||
is_active: bool | None = None
|
||||
config: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class AIModelResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
provider_id: str
|
||||
model_id: str
|
||||
display_name: str
|
||||
context_window: int
|
||||
supports_tools: bool
|
||||
supports_streaming: bool
|
||||
is_active: bool
|
||||
config: dict[str, Any]
|
||||
|
||||
|
||||
# ─── Presets ───
|
||||
|
||||
class AIPresetCreate(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=100)
|
||||
model_id: str = Field(..., min_length=1, max_length=200)
|
||||
provider_id: str | None = None
|
||||
temperature: float = Field(default=0.7, ge=0.0, le=2.0)
|
||||
max_tokens: int = Field(default=2048, ge=1, le=128000)
|
||||
top_p: float = Field(default=1.0, ge=0.0, le=1.0)
|
||||
system_prompt: str = ""
|
||||
config: dict[str, Any] = Field(default_factory=dict)
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class AIPresetUpdate(BaseModel):
|
||||
name: str | None = Field(None, min_length=1, max_length=100)
|
||||
model_id: str | None = Field(None, min_length=1, max_length=200)
|
||||
provider_id: str | None = None
|
||||
temperature: float | None = Field(None, ge=0.0, le=2.0)
|
||||
max_tokens: int | None = Field(None, ge=1, le=128000)
|
||||
top_p: float | None = Field(None, ge=0.0, le=1.0)
|
||||
system_prompt: str | None = None
|
||||
config: dict[str, Any] | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class AIPresetResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
name: str
|
||||
model_id: str
|
||||
provider_id: str | None = None
|
||||
temperature: float
|
||||
max_tokens: int
|
||||
top_p: float
|
||||
system_prompt: str
|
||||
config: dict[str, Any]
|
||||
is_active: bool
|
||||
|
||||
|
||||
# ─── Agents ───
|
||||
|
||||
class AIAgentCreate(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=100)
|
||||
description: str = ""
|
||||
system_prompt: str = ""
|
||||
preset_id: str | None = None
|
||||
tool_ids: list[str] = Field(default_factory=list)
|
||||
is_active: bool = True
|
||||
config: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class AIAgentUpdate(BaseModel):
|
||||
name: str | None = Field(None, min_length=1, max_length=100)
|
||||
description: str | None = None
|
||||
system_prompt: str | None = None
|
||||
preset_id: str | None = None
|
||||
tool_ids: list[str] | None = None
|
||||
is_active: bool | None = None
|
||||
config: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class AIAgentResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
name: str
|
||||
description: str
|
||||
system_prompt: str
|
||||
preset_id: str | None = None
|
||||
tool_ids: list[str]
|
||||
is_default: bool
|
||||
is_active: bool
|
||||
config: dict[str, Any]
|
||||
created_at: datetime | None = None
|
||||
updated_at: datetime | None = None
|
||||
|
||||
|
||||
# ─── Chat Sessions ───
|
||||
|
||||
class ChatSessionCreate(BaseModel):
|
||||
title: str = Field(default="Neuer Chat", max_length=255)
|
||||
agent_id: str | None = None
|
||||
is_sidebar: bool = False
|
||||
|
||||
|
||||
class ChatSessionUpdate(BaseModel):
|
||||
title: str | None = Field(None, max_length=255)
|
||||
is_pinned: bool | None = None
|
||||
agent_id: str | None = None
|
||||
|
||||
|
||||
class ChatSessionResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
user_id: str
|
||||
agent_id: str | None = None
|
||||
title: str
|
||||
is_pinned: bool
|
||||
is_sidebar: bool
|
||||
created_at: datetime | None = None
|
||||
updated_at: datetime | None = None
|
||||
|
||||
|
||||
# ─── Chat Messages ───
|
||||
|
||||
class ChatMessageResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: str
|
||||
session_id: str
|
||||
role: str
|
||||
content: str
|
||||
tool_calls: list[dict[str, Any]] | None = None
|
||||
tool_results: list[dict[str, Any]] | None = None
|
||||
tokens: int
|
||||
model_used: str
|
||||
created_at: datetime | None = None
|
||||
|
||||
|
||||
class ChatSendRequest(BaseModel):
|
||||
content: str = Field(..., min_length=1)
|
||||
agent_id: str | None = None # override session agent
|
||||
|
||||
|
||||
# ─── Tools ───
|
||||
|
||||
class AIToolResponse(BaseModel):
|
||||
name: str
|
||||
description: str
|
||||
parameters: dict[str, Any]
|
||||
plugin_name: str
|
||||
required_permission: str | None = None
|
||||
category: str
|
||||
Reference in New Issue
Block a user