mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Enable minimal thinking budget by default for Anthropic integration (#167593)
This commit is contained in:
@@ -36,13 +36,15 @@ class PromptCaching(StrEnum):
|
||||
AUTOMATIC = "automatic"
|
||||
|
||||
|
||||
MIN_THINKING_BUDGET = 1024
|
||||
|
||||
DEFAULT = {
|
||||
CONF_CHAT_MODEL: "claude-haiku-4-5",
|
||||
CONF_CODE_EXECUTION: False,
|
||||
CONF_MAX_TOKENS: 3000,
|
||||
CONF_PROMPT_CACHING: PromptCaching.PROMPT.value,
|
||||
CONF_TEMPERATURE: 1.0,
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
CONF_THINKING_BUDGET: MIN_THINKING_BUDGET,
|
||||
CONF_THINKING_EFFORT: "low",
|
||||
CONF_TOOL_SEARCH: False,
|
||||
CONF_WEB_SEARCH: False,
|
||||
@@ -50,8 +52,6 @@ DEFAULT = {
|
||||
CONF_WEB_SEARCH_MAX_USES: 5,
|
||||
}
|
||||
|
||||
MIN_THINKING_BUDGET = 1024
|
||||
|
||||
NON_THINKING_MODELS = [
|
||||
"claude-3-haiku",
|
||||
]
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
'type': 'text',
|
||||
}),
|
||||
]),
|
||||
'temperature': 1.0,
|
||||
'thinking': dict({
|
||||
'type': 'disabled',
|
||||
'budget_tokens': 1024,
|
||||
'type': 'enabled',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_disabled_thinking
|
||||
# name: test_disabled_thinking[subentry_data0]
|
||||
list([
|
||||
dict({
|
||||
'content': '''
|
||||
@@ -224,7 +224,72 @@
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_disabled_thinking.1
|
||||
# name: test_disabled_thinking[subentry_data0].1
|
||||
dict({
|
||||
'container': None,
|
||||
'max_tokens': 3000,
|
||||
'messages': list([
|
||||
dict({
|
||||
'content': 'hello',
|
||||
'role': 'user',
|
||||
}),
|
||||
dict({
|
||||
'content': 'Hello, how can I help you today?',
|
||||
'role': 'assistant',
|
||||
}),
|
||||
]),
|
||||
'model': 'claude-haiku-4-5',
|
||||
'stream': True,
|
||||
'system': list([
|
||||
dict({
|
||||
'cache_control': dict({
|
||||
'type': 'ephemeral',
|
||||
}),
|
||||
'text': '''
|
||||
You are a voice assistant for Home Assistant.
|
||||
Answer questions about the world truthfully.
|
||||
Answer in plain text. Keep it simple and to the point.
|
||||
Only if the user wants to control a device, tell them to expose entities to their voice assistant in Home Assistant.
|
||||
''',
|
||||
'type': 'text',
|
||||
}),
|
||||
]),
|
||||
'temperature': 1.0,
|
||||
'thinking': dict({
|
||||
'type': 'disabled',
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_disabled_thinking[subentry_data1]
|
||||
list([
|
||||
dict({
|
||||
'content': '''
|
||||
You are a voice assistant for Home Assistant.
|
||||
Answer questions about the world truthfully.
|
||||
Answer in plain text. Keep it simple and to the point.
|
||||
Only if the user wants to control a device, tell them to expose entities to their voice assistant in Home Assistant.
|
||||
''',
|
||||
'created': HAFakeDatetime(2024, 5, 24, 12, 0, tzinfo=datetime.timezone.utc),
|
||||
'role': 'system',
|
||||
}),
|
||||
dict({
|
||||
'attachments': None,
|
||||
'content': 'hello',
|
||||
'created': HAFakeDatetime(2024, 5, 24, 12, 0, tzinfo=datetime.timezone.utc),
|
||||
'role': 'user',
|
||||
}),
|
||||
dict({
|
||||
'agent_id': 'conversation.claude_conversation',
|
||||
'content': 'Hello, how can I help you today?',
|
||||
'created': HAFakeDatetime(2024, 5, 24, 12, 0, tzinfo=datetime.timezone.utc),
|
||||
'native': None,
|
||||
'role': 'assistant',
|
||||
'thinking_content': None,
|
||||
'tool_calls': None,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_disabled_thinking[subentry_data1].1
|
||||
dict({
|
||||
'container': None,
|
||||
'max_tokens': 3000,
|
||||
|
||||
@@ -10,7 +10,10 @@ from syrupy.assertion import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import ai_task, media_source
|
||||
from homeassistant.components.anthropic.const import CONF_CHAT_MODEL
|
||||
from homeassistant.components.anthropic.const import (
|
||||
CONF_CHAT_MODEL,
|
||||
CONF_THINKING_BUDGET,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er, selector
|
||||
@@ -127,6 +130,7 @@ async def test_generate_structured_data_legacy(
|
||||
subentry,
|
||||
data={
|
||||
CONF_CHAT_MODEL: "claude-sonnet-4-0",
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -183,7 +187,11 @@ async def test_generate_structured_data_legacy_tools(
|
||||
hass.config_entries.async_update_subentry(
|
||||
mock_config_entry,
|
||||
subentry,
|
||||
data={"chat_model": "claude-sonnet-4-0", "web_search": True},
|
||||
data={
|
||||
"chat_model": "claude-sonnet-4-0",
|
||||
"web_search": True,
|
||||
"thinking_budget": 0,
|
||||
},
|
||||
)
|
||||
|
||||
result = await ai_task.async_generate_data(
|
||||
|
||||
@@ -330,7 +330,7 @@ async def test_subentry_web_search_user_location(
|
||||
"recommended": False,
|
||||
"region": "California",
|
||||
"temperature": 1.0,
|
||||
"thinking_budget": 0,
|
||||
"thinking_budget": 1024,
|
||||
"timezone": "America/Los_Angeles",
|
||||
"tool_search": False,
|
||||
"user_location": True,
|
||||
@@ -487,7 +487,7 @@ async def test_model_list_error(
|
||||
CONF_TEMPERATURE: 1.0,
|
||||
CONF_CHAT_MODEL: "claude-haiku-4-5",
|
||||
CONF_MAX_TOKENS: DEFAULT[CONF_MAX_TOKENS],
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
CONF_THINKING_BUDGET: DEFAULT[CONF_THINKING_BUDGET],
|
||||
CONF_WEB_SEARCH: False,
|
||||
CONF_WEB_SEARCH_MAX_USES: 10,
|
||||
CONF_WEB_SEARCH_USER_LOCATION: False,
|
||||
@@ -614,7 +614,7 @@ async def test_model_list_error(
|
||||
CONF_TEMPERATURE: 0.3,
|
||||
CONF_CHAT_MODEL: DEFAULT[CONF_CHAT_MODEL],
|
||||
CONF_MAX_TOKENS: DEFAULT[CONF_MAX_TOKENS],
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
CONF_THINKING_BUDGET: DEFAULT[CONF_THINKING_BUDGET],
|
||||
CONF_WEB_SEARCH: False,
|
||||
CONF_WEB_SEARCH_MAX_USES: 5,
|
||||
CONF_WEB_SEARCH_USER_LOCATION: False,
|
||||
@@ -788,7 +788,7 @@ async def test_creating_ai_task_subentry_advanced(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_CHAT_MODEL: "claude-sonnet-4-5",
|
||||
CONF_MAX_TOKENS: 200,
|
||||
CONF_MAX_TOKENS: 1200,
|
||||
CONF_TEMPERATURE: 0.5,
|
||||
},
|
||||
)
|
||||
@@ -809,13 +809,13 @@ async def test_creating_ai_task_subentry_advanced(
|
||||
assert result4.get("data") == {
|
||||
CONF_RECOMMENDED: False,
|
||||
CONF_CHAT_MODEL: "claude-sonnet-4-5",
|
||||
CONF_MAX_TOKENS: 200,
|
||||
CONF_MAX_TOKENS: 1200,
|
||||
CONF_TEMPERATURE: 0.5,
|
||||
CONF_TOOL_SEARCH: False,
|
||||
CONF_WEB_SEARCH: False,
|
||||
CONF_WEB_SEARCH_MAX_USES: 5,
|
||||
CONF_WEB_SEARCH_USER_LOCATION: False,
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
CONF_THINKING_BUDGET: 1024,
|
||||
CONF_CODE_EXECUTION: False,
|
||||
CONF_PROMPT_CACHING: "prompt",
|
||||
}
|
||||
|
||||
@@ -706,6 +706,21 @@ async def test_extended_thinking(
|
||||
assert call_args == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"subentry_data",
|
||||
[
|
||||
{
|
||||
CONF_LLM_HASS_API: "assist",
|
||||
CONF_CHAT_MODEL: "claude-haiku-4-5",
|
||||
CONF_THINKING_BUDGET: 0,
|
||||
},
|
||||
{
|
||||
CONF_LLM_HASS_API: "assist",
|
||||
CONF_CHAT_MODEL: "claude-opus-4-6",
|
||||
CONF_THINKING_EFFORT: "none",
|
||||
},
|
||||
],
|
||||
)
|
||||
@freeze_time("2024-05-24 12:00:00")
|
||||
async def test_disabled_thinking(
|
||||
hass: HomeAssistant,
|
||||
@@ -713,16 +728,13 @@ async def test_disabled_thinking(
|
||||
mock_init_component,
|
||||
mock_create_stream: AsyncMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
subentry_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test conversation with thinking effort disabled."""
|
||||
hass.config_entries.async_update_subentry(
|
||||
mock_config_entry,
|
||||
next(iter(mock_config_entry.subentries.values())),
|
||||
data={
|
||||
CONF_LLM_HASS_API: "assist",
|
||||
CONF_CHAT_MODEL: "claude-opus-4-6",
|
||||
CONF_THINKING_EFFORT: "none",
|
||||
},
|
||||
data=subentry_data,
|
||||
)
|
||||
|
||||
mock_create_stream.return_value = [
|
||||
|
||||
Reference in New Issue
Block a user