from __future__ import annotations from typing import TYPE_CHECKING, Any from pydantic import BaseModel, ConfigDict, Field from .runtime import AgentRuntime, SkillPolicy from .workspace import WorkspaceAccess if TYPE_CHECKING: from .agent import A2AAgent class SkillCard(BaseModel): """Public description of a single skill, shaped for the A2A spec.""" model_config = ConfigDict(extra="forbid") id: str name: str description: str tags: list[str] = Field(default_factory=list) scopes: list[str] = Field(default_factory=list) stream: bool = False policy: SkillPolicy = Field(default_factory=SkillPolicy) input_schema: dict[str, Any] output_schema: dict[str, Any] class AgentCard(BaseModel): """Public description of an agent. Mirrors the A2A Agent Card spec: identity, capabilities, IO modes, and the catalog of skills the agent advertises. """ model_config = ConfigDict(extra="forbid") name: str description: str version: str skills: list[SkillCard] capabilities: dict[str, Any] = Field(default_factory=dict) input_modes: list[str] = Field(default_factory=lambda: ["application/json"]) output_modes: list[str] = Field(default_factory=lambda: ["application/json"]) required_secrets: list[str] = Field(default_factory=list) required_env: list[str] = Field(default_factory=list) runtime: AgentRuntime = Field(default_factory=AgentRuntime) state_schema: dict[str, Any] | None = None workspace_access: WorkspaceAccess = Field(default_factory=WorkspaceAccess.none) @classmethod def from_agent(cls, agent: "A2AAgent") -> "AgentCard": agent_cls = type(agent) skills = [ SkillCard( id=spec.name, name=spec.name, description=spec.description, tags=list(spec.tags), scopes=list(spec.scopes), stream=spec.stream, policy=spec.policy, input_schema=spec.input_schema, output_schema=spec.output_schema, ) for spec in agent.skills.values() ] state_schema = ( agent_cls.state_model.model_json_schema() if agent_cls.state_model is not None else None ) return cls( name=agent_cls.name, description=agent_cls.description, version=agent_cls.version, skills=skills, capabilities=dict(agent_cls.capabilities), input_modes=list(agent_cls.input_modes), output_modes=list(agent_cls.output_modes), required_secrets=list(agent_cls.required_secrets), required_env=list(agent_cls.required_env), runtime=agent_cls.runtime(), state_schema=state_schema, workspace_access=agent_cls.workspace_access, )