feat: add fields= projection to ha_search_entities#1212
Conversation
Adds an optional `fields` parameter that filters the top-level response
keys before timezone metadata is added, reducing response size for
callers that only need specific fields (e.g. ["results"]).
A `_project_fields` module-level helper handles the projection:
- `success` is always retained regardless of what fields lists
- unknown keys are silently dropped
- projection happens before `add_timezone_metadata` so the outer
{"data": ..., "metadata": ...} wrapper shape is always preserved
Covers all 5 return paths in ha_search_entities (exact, area, empty
area, domain listing, fuzzy/smart). Adds 9 unit tests for
_project_fields.
Closes homeassistant-ai#1199 (search entities)
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a field projection mechanism for the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces field projection to the ha_search_entities tool, allowing users to specify which top-level keys to return to reduce response size. Feedback suggests moving the projection logic to a shared utility module to improve reusability, enhancing the helper to handle comma-separated string inputs from AI agents, and correcting the tool's documentation regarding available response keys.
- Move _project_fields from tools_search.py to util_helpers.py as the public project_fields() function so it can be shared across modules - Accept str | list[str] | None for fields; parse_string_list_param normalises CSV and JSON-array strings from AI clients - Remove time_zone from ha_search_entities fields= description (it is metadata, not part of the inner data dict) - Add test cases for CSV string and JSON-array string inputs
SealKan
left a comment
There was a problem hiding this comment.
Addressed all Gemini review feedback in bcb2ab5:
- Moved
_project_fieldstoutil_helpers.pyas the publicproject_fields()shared across modules - Updated
fieldstype tostr | list[str] | None; the helper callsparse_string_list_paraminternally to normalise CSV/JSON-array strings - Removed
time_zonefrom the available keys description (it is in themetadatawrapper, not the inner data dict) - Added string input test cases (
test_csv_string_input_parsed_correctlyandtest_json_array_string_input_parsed_correctly)
|
Superseded by #1225 which consolidates all six fields= projection PRs into a single implementation. |
Summary
Adds an optional
fieldsparameter toha_search_entitiesthat trims the responseto only the requested top-level keys, reducing payload size by up to 80%.
fields=["results"]cuts the typical 5 KB response to ~1.2 KBsuccessis always retained regardless of whatfieldslistsfieldsare silently droppedadd_timezone_metadataso the outer{"data": ..., "metadata": ...}wrapper shape is always preservedA module-level
_project_fieldshelper centralizes the logic and iscalled at all 5 return paths inside
ha_search_entities.Part of #1199 (alongside
ha_config_list_areasPR #1210 andha_get_historyPR #1211).Changes
src/ha_mcp/tools/tools_search.py— adds_project_fieldshelper +fieldsparameter with all 5 return paths updatedtests/src/unit/test_search_fields_projection.py— 9 unit tests for_project_fieldscovering: no-op (None), single/multiple fields,success-always-retained, unknown-key drop, empty list, no-mutation
Test plan
uv run pytest tests/src/unit/test_search_fields_projection.py— 9/9 passuv run mypy src/— no issues