mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix: clean up description escaping, add string-data tests
Follow-up for cherry-picked PR #8918.
This commit is contained in:
parent
bca22f3090
commit
8dfee98d06
2 changed files with 59 additions and 4 deletions
|
|
@ -5,6 +5,7 @@ handler validation, and availability gating.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -304,6 +305,60 @@ class TestEntityIdValidation:
|
||||||
assert "Invalid entity_id" not in result["error"]
|
assert "Invalid entity_id" not in result["error"]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# String-data deserialization (XML tool calling workaround)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class TestCallServiceStringData:
|
||||||
|
"""data param may arrive as a JSON string (XML tool calling mode)."""
|
||||||
|
|
||||||
|
@patch("tools.homeassistant_tool._run_async", return_value={"success": True})
|
||||||
|
def test_string_data_deserialized(self, mock_run):
|
||||||
|
"""JSON string data is parsed into a dict before dispatch."""
|
||||||
|
_handle_call_service({
|
||||||
|
"domain": "climate",
|
||||||
|
"service": "set_hvac_mode",
|
||||||
|
"entity_id": "climate.living_room",
|
||||||
|
"data": '{"hvac_mode": "heat"}',
|
||||||
|
})
|
||||||
|
call_args = mock_run.call_args[0][0] # the coroutine arg
|
||||||
|
# _run_async was called, meaning we got past validation
|
||||||
|
|
||||||
|
@patch("tools.homeassistant_tool._run_async", return_value={"success": True})
|
||||||
|
def test_dict_data_passthrough(self, mock_run):
|
||||||
|
"""Dict data (JSON tool calling mode) still works unchanged."""
|
||||||
|
_handle_call_service({
|
||||||
|
"domain": "light",
|
||||||
|
"service": "turn_on",
|
||||||
|
"entity_id": "light.bedroom",
|
||||||
|
"data": {"brightness": 255},
|
||||||
|
})
|
||||||
|
mock_run.assert_called_once()
|
||||||
|
|
||||||
|
def test_invalid_json_string_returns_error(self):
|
||||||
|
"""Malformed JSON string in data returns a clear error."""
|
||||||
|
result = json.loads(_handle_call_service({
|
||||||
|
"domain": "light",
|
||||||
|
"service": "turn_on",
|
||||||
|
"entity_id": "light.bedroom",
|
||||||
|
"data": "{not valid json}",
|
||||||
|
}))
|
||||||
|
assert "error" in result
|
||||||
|
assert "Invalid JSON" in result["error"]
|
||||||
|
|
||||||
|
@patch("tools.homeassistant_tool._run_async", return_value={"success": True})
|
||||||
|
def test_empty_string_data_becomes_none(self, mock_run):
|
||||||
|
"""Empty/whitespace string data is treated as None."""
|
||||||
|
_handle_call_service({
|
||||||
|
"domain": "light",
|
||||||
|
"service": "turn_on",
|
||||||
|
"entity_id": "light.bedroom",
|
||||||
|
"data": " ",
|
||||||
|
})
|
||||||
|
mock_run.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Security: domain/service name format validation
|
# Security: domain/service name format validation
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -458,10 +458,10 @@ HA_CALL_SERVICE_SCHEMA = {
|
||||||
"data": {
|
"data": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": (
|
"description": (
|
||||||
"Additional service data provided as a valid JSON string. Examples: "
|
"Additional service data as a JSON string. Examples: "
|
||||||
'\'{"brightness": 255, "color_name": "blue"}\' for lights, '
|
'{"brightness": 255, "color_name": "blue"} for lights, '
|
||||||
'\'{"temperature": 22, "hvac_mode": "heat"}\' for climate, '
|
'{"temperature": 22, "hvac_mode": "heat"} for climate, '
|
||||||
'\'{"volume_level": 0.5}\' for media players.'
|
'{"volume_level": 0.5} for media players.'
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue