MAWB's picture
adding
67f8819
"""
Chat API Pydantic schemas for request/response validation.
Per @specs/001-chatbot-mcp/contracts/openapi.yaml
"""
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from datetime import datetime
from uuid import UUID
# =============================================================================
# Request Schemas
# =============================================================================
class ChatRequest(BaseModel):
"""
Request schema for chat endpoint.
Per @specs/001-chatbot-mcp/contracts/openapi.yaml
"""
conversation_id: Optional[UUID] = Field(
default=None,
description="Optional conversation ID to continue existing chat. If not provided, a new conversation is created."
)
message: str = Field(
...,
min_length=1,
max_length=5000,
description="User's message content"
)
class Config:
json_schema_extra = {
"example": {
"conversation_id": None,
"message": "Add a task to buy groceries"
}
}
# =============================================================================
# Response Schemas
# =============================================================================
class Message(BaseModel):
"""
Message schema for chat responses.
Represents a single message in the conversation.
Per @specs/001-chatbot-mcp/data-model.md
"""
id: UUID = Field(..., description="Unique message identifier")
role: str = Field(..., description="Message role: 'user' or 'assistant'")
content: str = Field(..., description="Message content")
created_at: datetime = Field(..., description="Timestamp when message was created")
class Config:
json_schema_extra = {
"example": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"role": "assistant",
"content": "I've added a task 'Buy groceries' to your list.",
"created_at": "2026-01-11T22:00:00Z"
}
}
class TaskSummary(BaseModel):
"""
Task summary schema for chat responses.
Simplified task representation returned in chat responses.
Per @specs/001-chatbot-mcp/contracts/openapi.yaml
"""
id: UUID = Field(..., description="Task ID")
title: str = Field(..., description="Task title")
description: Optional[str] = Field(None, description="Task description")
completed: bool = Field(..., description="Task completion status")
class Config:
json_schema_extra = {
"example": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Buy groceries",
"description": None,
"completed": False
}
}
class ChatResponse(BaseModel):
"""
Response schema for chat endpoint.
Per @specs/001-chatbot-mcp/contracts/openapi.yaml
"""
conversation_id: UUID = Field(..., description="Conversation ID (new or existing)")
message: Message = Field(..., description="Assistant's response message")
tasks: Optional[List[TaskSummary]] = Field(
default=None,
description="List of tasks affected by the chat (optional, for context)"
)
class Config:
json_schema_extra = {
"example": {
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"message": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"role": "assistant",
"content": "I've added a task 'Buy groceries' to your list.",
"created_at": "2026-01-11T22:00:00Z"
},
"tasks": [
{
"id": "123e4567-e89b-12d3-a456-426614174002",
"title": "Buy groceries",
"description": None,
"completed": False
}
]
}
}
# =============================================================================
# Error Schemas
# =============================================================================
class ChatError(BaseModel):
"""
Error response schema for chat endpoint.
Returned when chat processing fails.
"""
error: str = Field(..., description="Error message")
detail: Optional[str] = Field(None, description="Detailed error information")
conversation_id: Optional[UUID] = Field(
None,
description="Conversation ID if error occurred during existing conversation"
)
class Config:
json_schema_extra = {
"example": {
"error": "Failed to process chat message",
"detail": "OpenAI API timeout",
"conversation_id": None
}
}