"""BaseAgent — foundation for all KOAN agents."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING

from koan.agents.types import AgentConfig, AgentResult, RunContext
from koan.llm.config import LLMConfig

if TYPE_CHECKING:
    from koan.llm.client import LLMClient
    from koan.tools.types import ToolProvider


class BaseAgent(ABC):
    """Abstract base agent with config, tools, and LLM client.

    Subclasses implement ``run()`` with their specific execution strategy.
    """

    def __init__(
        self,
        name: str,
        *,
        client: LLMClient,
        config: AgentConfig | None = None,
        tools: ToolProvider | None = None,
    ) -> None:
        self.name = name
        self.client = client
        self.config = config or AgentConfig()
        self.tools = tools

    def _build_llm_config(self) -> LLMConfig:
        """Build LLMConfig from AgentConfig, including tool definitions."""
        tools: list[dict] = []
        if self.tools:
            defns = self.tools.definitions()
            tools = [
                {
                    "type": "function",
                    "function": {
                        "name": d.name,
                        "description": d.description,
                        "parameters": d.parameters,
                    },
                }
                for d in defns
            ]
        return LLMConfig(
            provider=self.config.provider,  # type: ignore[arg-type]
            model=self.config.model,
            temperature=self.config.temperature,
            max_tokens=self.config.max_tokens,
            tools=tools,
        )

    @abstractmethod
    async def run(self, input_text: str, *, context: RunContext | None = None) -> AgentResult:
        """Execute the agent with the given input."""
        ...
