- SQLAlchemy async database layer (SQLite dev, PostgreSQL prod) - Conversation and Message models with UUID primary keys - Token counting utilities using litellm - Context summarization at 80% token threshold - REST API endpoints for multi-turn conversations - 19 conversation tests, 6 token tests (176 total passing) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
80 lines
2.0 KiB
Python
80 lines
2.0 KiB
Python
"""
|
|
Pydantic schemas for conversation API.
|
|
"""
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# === Request Schemas ===
|
|
|
|
class CreateConversationRequest(BaseModel):
|
|
"""Request to create a new conversation."""
|
|
agent_type: str = Field(default="explore", description="Agent type to use")
|
|
working_dir: str = Field(default=".", description="Working directory for agent")
|
|
title: str | None = Field(default=None, description="Optional conversation title")
|
|
|
|
|
|
class AddMessageRequest(BaseModel):
|
|
"""Request to add a message to a conversation."""
|
|
content: str = Field(..., min_length=1, description="Message content")
|
|
|
|
|
|
# === Response Schemas ===
|
|
|
|
class MessageResponse(BaseModel):
|
|
"""Response for a single message."""
|
|
id: UUID
|
|
role: str
|
|
content: str
|
|
token_count: int
|
|
is_summary: bool
|
|
created_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ConversationResponse(BaseModel):
|
|
"""Response for conversation metadata."""
|
|
id: UUID
|
|
agent_type: str
|
|
title: str | None
|
|
working_dir: str
|
|
total_tokens: int
|
|
created_at: datetime
|
|
updated_at: datetime | None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ConversationDetailResponse(BaseModel):
|
|
"""Response for conversation with messages."""
|
|
id: UUID
|
|
agent_type: str
|
|
title: str | None
|
|
working_dir: str
|
|
total_tokens: int
|
|
created_at: datetime
|
|
updated_at: datetime | None
|
|
messages: list[MessageResponse]
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ConversationListResponse(BaseModel):
|
|
"""Response for listing conversations."""
|
|
conversations: list[ConversationResponse]
|
|
total: int
|
|
|
|
|
|
class AddMessageResponse(BaseModel):
|
|
"""Response after adding a message (includes agent response)."""
|
|
user_message: MessageResponse
|
|
assistant_message: MessageResponse
|
|
total_tokens: int
|
|
summarized: bool = Field(
|
|
default=False,
|
|
description="Whether context was summarized due to token limit"
|
|
)
|