feat(llm): añade Protocol LLMProvider con Message y CompletionResult
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
"""Tipos y Protocol del proveedor LLM (Strategy pattern)."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Literal, Protocol
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class Message(BaseModel):
|
||||||
|
"""Mensaje individual de la conversación enviada al LLM."""
|
||||||
|
|
||||||
|
role: Literal["system", "user", "assistant"]
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
class CompletionResult(BaseModel):
|
||||||
|
"""Resultado normalizado de una llamada a un proveedor LLM."""
|
||||||
|
|
||||||
|
content: str
|
||||||
|
model: str
|
||||||
|
tokens_in: int
|
||||||
|
tokens_out: int
|
||||||
|
latency_ms: int
|
||||||
|
|
||||||
|
|
||||||
|
class LLMProvider(Protocol):
|
||||||
|
"""Interfaz mínima común a todos los proveedores LLM."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
|
||||||
|
async def complete(
|
||||||
|
self,
|
||||||
|
messages: list[Message],
|
||||||
|
schema: dict[str, Any] | None = None,
|
||||||
|
temperature: float = 0.2,
|
||||||
|
max_tokens: int = 2000,
|
||||||
|
) -> CompletionResult: ...
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
"""Test de los modelos base del proveedor LLM."""
|
||||||
|
|
||||||
|
from agentforge_core.llm.base import CompletionResult, Message
|
||||||
|
|
||||||
|
|
||||||
|
def test_message_serializable() -> None:
|
||||||
|
m = Message(role="user", content="hola")
|
||||||
|
assert m.model_dump()["role"] == "user"
|
||||||
|
|
||||||
|
|
||||||
|
def test_completion_result_campos_basicos() -> None:
|
||||||
|
r = CompletionResult(
|
||||||
|
content='{"a": 1}',
|
||||||
|
model="gpt-4o-mock",
|
||||||
|
tokens_in=10,
|
||||||
|
tokens_out=20,
|
||||||
|
latency_ms=42,
|
||||||
|
)
|
||||||
|
assert r.tokens_in == 10
|
||||||
Reference in New Issue
Block a user