1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-31 20:54:23 +01:00
Files
core/homeassistant/components/conversation/models.py
T
2026-05-13 18:17:23 +02:00

108 lines
2.9 KiB
Python

"""Agent foundation for conversation integration."""
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any, Literal
from homeassistant.core import Context
from homeassistant.helpers import intent, llm
from .const import DOMAIN
@dataclass(frozen=True)
class AgentInfo:
"""Container for conversation agent info."""
id: str
name: str
supports_streaming: bool
@dataclass(slots=True)
class ConversationInput:
"""User input to be processed."""
text: str
"""User spoken text."""
context: Context
"""Context of the request."""
conversation_id: str | None
"""Unique identifier for the conversation."""
device_id: str | None
"""Unique identifier for the device."""
satellite_id: str | None
"""Unique identifier for the satellite."""
language: str
"""Language of the request."""
agent_id: str
"""Agent to use for processing."""
extra_system_prompt: str | None = None
"""Extra prompt to provide extra info to LLMs how to understand the command."""
def as_dict(self) -> dict[str, Any]:
"""Return input as a dict."""
return {
"text": self.text,
"context": self.context.as_dict(),
"conversation_id": self.conversation_id,
"device_id": self.device_id,
"satellite_id": self.satellite_id,
"language": self.language,
"agent_id": self.agent_id,
"extra_system_prompt": self.extra_system_prompt,
}
def as_llm_context(self, conversing_domain: str) -> llm.LLMContext:
"""Return input as an LLM context."""
return llm.LLMContext(
platform=conversing_domain,
context=self.context,
language=self.language,
assistant=DOMAIN,
device_id=self.device_id,
)
@dataclass(slots=True)
class ConversationResult:
"""Result of async_process."""
response: intent.IntentResponse
conversation_id: str | None = None
continue_conversation: bool = False
def as_dict(self) -> dict[str, Any]:
"""Return result as a dict."""
return {
"response": self.response.as_dict(),
"conversation_id": self.conversation_id,
"continue_conversation": self.continue_conversation,
}
class AbstractConversationAgent(ABC):
"""Abstract conversation agent."""
@property
@abstractmethod
def supported_languages(self) -> list[str] | Literal["*"]:
"""Return a list of supported languages."""
@abstractmethod
async def async_process(self, user_input: ConversationInput) -> ConversationResult:
"""Process a sentence."""
async def async_reload(self, language: str | None = None) -> None: # noqa: B027
"""Clear cached intents for a language."""
async def async_prepare(self, language: str | None = None) -> None: # noqa: B027
"""Load intents for a language."""