Expose nevermind intent to LLMs

This commit is contained in:
Paulus Schoutsen 2024-11-30 04:02:43 +00:00
parent e8ced4fa12
commit cf259c2278
3 changed files with 33 additions and 8 deletions

View File

@ -364,7 +364,7 @@ class NevermindIntentHandler(intent.IntentHandler):
"""Takes no action."""
intent_type = intent.INTENT_NEVERMIND
description = "Cancels the current request and does nothing"
description = "Cancel the current conversation if it was started by mistake or the user wants it to stop."
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
"""Do nothing and produces an empty response."""

View File

@ -30,6 +30,7 @@ from homeassistant.exceptions import HomeAssistantError, TemplateError
from homeassistant.helpers import device_registry as dr, intent, llm, template
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import ulid
from homeassistant.util.json import JsonObjectType
from . import OpenAIConfigEntry
from .const import (
@ -292,6 +293,8 @@ class OpenAIConversationEntity(
if not tool_calls or not llm_api:
break
aborting = False
for tool_call in tool_calls:
tool_input = llm.ToolInput(
tool_name=tool_call.function.name,
@ -301,8 +304,21 @@ class OpenAIConversationEntity(
"Tool call: %s(%s)", tool_input.tool_name, tool_input.tool_args
)
# OpenAI requires a tool response for every tool call in history
if aborting:
tool_response: JsonObjectType = {
"error": "Aborted",
"error_text": "Abort conversation requested",
}
if not aborting:
try:
tool_response = await llm_api.async_call_tool(tool_input)
except llm.AbortConversation as e:
aborting = True
tool_response = {
"error": "Aborted",
"error_text": str(e) or "Abort conversation requested",
}
except (HomeAssistantError, vol.Invalid) as e:
tool_response = {"error": type(e).__name__}
if str(e):
@ -317,6 +333,9 @@ class OpenAIConversationEntity(
)
)
if aborting:
break
self.history[conversation_id] = messages
intent_response = intent.IntentResponse(language=user_input.language)

View File

@ -113,6 +113,10 @@ def async_get_apis(hass: HomeAssistant) -> list[API]:
return list(_async_get_apis(hass).values())
class AbortConversation(HomeAssistantError):
"""Abort the conversation."""
@dataclass(slots=True)
class LLMContext:
"""Tool input to be processed."""
@ -169,6 +173,9 @@ class APIInstance:
{"tool_name": tool_input.tool_name, "tool_args": tool_input.tool_args},
)
if tool_input.tool_name == intent.INTENT_NEVERMIND:
raise AbortConversation("Nevermind intent called")
for tool in self.tools:
if tool.name == tool_input.tool_name:
break
@ -273,7 +280,6 @@ class AssistAPI(API):
INTENT_OPEN_COVER, # deprecated
INTENT_CLOSE_COVER, # deprecated
intent.INTENT_GET_STATE,
intent.INTENT_NEVERMIND,
intent.INTENT_TOGGLE,
intent.INTENT_GET_CURRENT_DATE,
intent.INTENT_GET_CURRENT_TIME,