# Pydantic models will be defined here (e.g., ParsedDocument, SearchResultItem, TopicItem)
from typing import Optional, Dict, Any
from pydantic import BaseModel, Field
class ParsedDocument(BaseModel):
"""Represents a parsed Markdown document from the Pydantic documentation."""
id: str = Field(..., description="Unique identifier for the document")
path: str = Field(..., description="Relative file path from the docs/ directory")
title: str = Field(..., description="Document title")
content: str = Field(..., description="Raw Markdown content")
class SearchResultItem(BaseModel):
"""Represents a single search result."""
document: ParsedDocument = Field(..., description="The matched document")
score: float = Field(..., description="Relevance score from the search engine")
snippet: Optional[str] = Field(
None, description="Text snippet showing the match context"
)
class TopicItem(BaseModel):
"""Represents a documentation topic (file or directory)."""
name: str = Field(..., description="File or directory name")
path: str = Field(..., description="Relative path from the docs/ root")
is_directory: bool = Field(..., description="Whether this item is a directory")
# The following response models are good practice but might be overkill if tools return simple dicts.
# For stdio.js parity, simple dicts might be closer. Let's include StatusResponse for now.
class StatusResponse(BaseModel):
"""Standard response format for operations like update_documentation."""
status: str = Field(..., description="'success' or 'error'")
message: str = Field(..., description="Status message or error details")
data: Optional[Dict[str, Any]] = Field(None, description="Optional additional data")
# For search_documents, the tool directly returns List[SearchResultItem]
# For get_document_by_path, it returns Optional[ParsedDocument] or an error dict.
# For list_topics, it returns List[TopicItem] or an error dict.
# So, specific SearchResponse or TopicsResponse models might not be used by the tools directly
# if they return lists or specific model instances directly.
class ChangelogFile(BaseModel):
"""Represents a single changelog file, typically for a specific version."""
name: str = Field(..., description="Filename of the changelog (e.g., '0.2.0.md')")
path: str = Field(
...,
description="Relative path to the changelog file from the docs/history/ directory",
)
version: str = Field(
..., description="Version extracted from the filename (e.g., '0.2.0')"
)
class ChangelogContent(BaseModel):
"""Represents the parsed content of a specific changelog version."""
path: str = Field(
...,
description="Relative path of the source changelog file from the repository root",
)
version: str = Field(
..., description="The version this changelog content pertains to"
)
content: str = Field(
..., description="Raw Markdown content of the changelog for this version"
)
release_date: Optional[str] = Field(
None, description="Release date if parsable from content (e.g., 'YYYY-MM-DD')"
)