from article_body import ARTICLE_BODIES
from article_common_strict import SAMPLE_HTML
from datetime import date
from typing import Literal
from pydantic import BaseModel, Field
from pydantic_ai import Agent


class ArticleInfo(BaseModel):
    """記事のメタデータ（カテゴリ・タグ付き）"""

    title: str = Field(min_length=1, description="記事のタイトル")
    author: str = Field(min_length=1, description="著者名")
    published_date: date = Field(description="公開日")
    url: str = Field(description="記事のURL（相対パス）")
    # カテゴリは以下の選択肢のいずれかとする
    category: Literal[
        "Web開発",
        "型・ツール",
        "AI・機械学習",
        "パッケージ管理",
        "Python新機能",
        "その他",
    ] = Field(description="記事のカテゴリ")
    # タグは1～5個のリストとする
    tags: list[str] = Field(
        min_length=1,
        max_length=5,
        description="技術タグのリスト",
    )


class ArticleList(BaseModel):
    """記事一覧"""

    articles: list[ArticleInfo]


# Agentのinstructionsで、ツールを使って記事本文を参照するように指示
agent = Agent(
    "openai:gpt-5.2",
    output_type=ArticleList,
    instructions=(
        "与えられたHTMLから記事の一覧情報を抽出してください。"
        "各記事のカテゴリとタグを判定するために、"
        "fetch_article_bodyツールで記事本文を参照してください。"
    ),
    retries=3,
)


# fetch_article_bodyツールを定義
@agent.tool_plain
def fetch_article_body(url: str) -> str:
    """記事のURLを受け取り、記事本文の冒頭部分を返す。

    Args:
        url: 記事の相対パス（例: /article/2026/01/monthly-python-2601）
    """
    body = ARTICLE_BODIES.get(url)
    if body:
        return body
    return f"{url}: 本文が見つかりません"


res = agent.run_sync(SAMPLE_HTML)
for article in res.output.articles:
    print(article)
