feat(domain): añade modelo AgentDefinition + LLMConfig + AgentVersionMeta
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
"""Modelos de dominio del agente: definición, configuración LLM y metadata de versión."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Literal
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class LLMConfig(BaseModel):
|
||||||
|
"""Configuración del proveedor LLM utilizado por un agente."""
|
||||||
|
|
||||||
|
provider: Literal["mock", "azure", "openai"] = "mock"
|
||||||
|
model: str = "gpt-4o"
|
||||||
|
temperature: float = Field(default=0.2, ge=0.0, le=2.0)
|
||||||
|
max_tokens: int = Field(default=2000, ge=1, le=128_000)
|
||||||
|
|
||||||
|
|
||||||
|
class AgentVersionMeta(BaseModel):
|
||||||
|
"""Metadatos de una versión concreta de un agente (estilo commit Git)."""
|
||||||
|
|
||||||
|
id: str
|
||||||
|
hash: str
|
||||||
|
author: str
|
||||||
|
message: str
|
||||||
|
created_at: datetime
|
||||||
|
|
||||||
|
|
||||||
|
class AgentDefinition(BaseModel):
|
||||||
|
"""Definición declarativa completa de un agente."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
version: str
|
||||||
|
owner: str
|
||||||
|
purpose: str
|
||||||
|
state: Literal["draft", "active", "deprecated"]
|
||||||
|
guardrails: list[str]
|
||||||
|
llm: LLMConfig
|
||||||
|
system_prompt: str
|
||||||
|
output_schema: dict[str, Any]
|
||||||
|
risk_threshold_for_hitl: int = Field(default=4, ge=1, le=5)
|
||||||
|
updated_at: datetime
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
"""Tests unitarios para los modelos de dominio del agente."""
|
||||||
|
|
||||||
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
|
from agentforge_core.domain.agent import (
|
||||||
|
AgentDefinition,
|
||||||
|
AgentVersionMeta,
|
||||||
|
LLMConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_llm_config_default_provider_is_mock() -> None:
|
||||||
|
cfg = LLMConfig()
|
||||||
|
assert cfg.provider == "mock"
|
||||||
|
assert cfg.model == "gpt-4o"
|
||||||
|
assert cfg.temperature == 0.2
|
||||||
|
|
||||||
|
|
||||||
|
def test_llm_config_rechaza_provider_invalido() -> None:
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
LLMConfig(provider="bedrock") # type: ignore[arg-type]
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_version_meta_serialize() -> None:
|
||||||
|
meta = AgentVersionMeta(
|
||||||
|
id="v1",
|
||||||
|
hash="abc123",
|
||||||
|
author="Juan",
|
||||||
|
message="inicial",
|
||||||
|
created_at=datetime(2026, 5, 9, tzinfo=UTC),
|
||||||
|
)
|
||||||
|
dumped = meta.model_dump(mode="json")
|
||||||
|
assert dumped["id"] == "v1"
|
||||||
|
assert dumped["created_at"].startswith("2026-05-09")
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_definition_minimo_valido() -> None:
|
||||||
|
agent = AgentDefinition(
|
||||||
|
name="incident_analyzer",
|
||||||
|
version="v1",
|
||||||
|
owner="Juan",
|
||||||
|
purpose="Análisis de incidentes",
|
||||||
|
state="active",
|
||||||
|
guardrails=["default"],
|
||||||
|
llm=LLMConfig(),
|
||||||
|
system_prompt="eres un analista...",
|
||||||
|
output_schema={"type": "object"},
|
||||||
|
updated_at=datetime.now(UTC),
|
||||||
|
)
|
||||||
|
assert agent.risk_threshold_for_hitl == 4 # default
|
||||||
|
assert agent.state == "active"
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_definition_rechaza_state_invalido() -> None:
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
AgentDefinition(
|
||||||
|
name="x",
|
||||||
|
version="v1",
|
||||||
|
owner="x",
|
||||||
|
purpose="x",
|
||||||
|
state="archived", # type: ignore[arg-type]
|
||||||
|
guardrails=[],
|
||||||
|
llm=LLMConfig(),
|
||||||
|
system_prompt="x",
|
||||||
|
output_schema={},
|
||||||
|
updated_at=datetime.now(UTC),
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user