ha-mcp-dev 7.4.1.dev459__tar.gz → 7.4.1.dev460__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ha_mcp_dev-7.4.1.dev459/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.4.1.dev460}/PKG-INFO +1 -1
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/pyproject.toml +1 -1
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_entry_flow.py +121 -13
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_helpers.py +940 -273
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/README.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/setup.cfg +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.4.1.
|
|
7
|
+
version = "7.4.1.dev460"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
{ha_mcp_dev-7.4.1.dev459 → ha_mcp_dev-7.4.1.dev460}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
@@ -69,6 +69,41 @@ FLOW_HELPER_TYPES: frozenset[str] = frozenset({
|
|
|
69
69
|
"generic_hygrostat",
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
+
# Issue #1149: full set accepted by ha_get_helper_schema (15 flow + 12
|
|
73
|
+
# simple). Simple types route to a static dict in tools_config_helpers
|
|
74
|
+
# rather than starting an HA flow.
|
|
75
|
+
ALL_HELPER_TYPES = Literal[
|
|
76
|
+
# Flow helpers (mirrors SUPPORTED_HELPERS above)
|
|
77
|
+
"template",
|
|
78
|
+
"group",
|
|
79
|
+
"utility_meter",
|
|
80
|
+
"derivative",
|
|
81
|
+
"min_max",
|
|
82
|
+
"threshold",
|
|
83
|
+
"integration",
|
|
84
|
+
"statistics",
|
|
85
|
+
"trend",
|
|
86
|
+
"random",
|
|
87
|
+
"filter",
|
|
88
|
+
"tod",
|
|
89
|
+
"generic_thermostat",
|
|
90
|
+
"switch_as_x",
|
|
91
|
+
"generic_hygrostat",
|
|
92
|
+
# Simple helpers (mirrors SIMPLE_HELPER_TYPES in tools_config_helpers)
|
|
93
|
+
"input_button",
|
|
94
|
+
"input_boolean",
|
|
95
|
+
"input_select",
|
|
96
|
+
"input_number",
|
|
97
|
+
"input_text",
|
|
98
|
+
"input_datetime",
|
|
99
|
+
"counter",
|
|
100
|
+
"timer",
|
|
101
|
+
"schedule",
|
|
102
|
+
"zone",
|
|
103
|
+
"person",
|
|
104
|
+
"tag",
|
|
105
|
+
]
|
|
106
|
+
|
|
72
107
|
# Keys used to specify a menu selection — stripped before submitting form data.
|
|
73
108
|
_MENU_SELECTION_KEYS = frozenset({"group_type", "next_step_id", "menu_option"})
|
|
74
109
|
|
|
@@ -265,6 +300,10 @@ async def _fetch_data_schema_for_error_context(
|
|
|
265
300
|
user step's ``data_schema`` so the LLM has something concrete to react
|
|
266
301
|
to when HA's error body is unstructured. Returns ``None`` on any
|
|
267
302
|
failure or when the helper is menu-based without a chosen branch.
|
|
303
|
+
|
|
304
|
+
Public alias ``fetch_helper_data_schema`` is exported below for the
|
|
305
|
+
pre-flow validation gates in ``_handle_flow_helper`` (issue #1149) —
|
|
306
|
+
they need the same best-effort fetch but live in another module.
|
|
268
307
|
"""
|
|
269
308
|
if not helper_type or client is None:
|
|
270
309
|
return None
|
|
@@ -306,6 +345,13 @@ async def _fetch_data_schema_for_error_context(
|
|
|
306
345
|
)
|
|
307
346
|
|
|
308
347
|
|
|
348
|
+
# Public alias for use by pre-flow validation gates in tools_config_helpers
|
|
349
|
+
# (issue #1149). The underscore-prefixed original is kept to preserve the
|
|
350
|
+
# call sites already in this module; the alias avoids importing a private
|
|
351
|
+
# name across modules.
|
|
352
|
+
fetch_helper_data_schema = _fetch_data_schema_for_error_context
|
|
353
|
+
|
|
354
|
+
|
|
309
355
|
async def _raise_flow_api_error(
|
|
310
356
|
api_error: HomeAssistantAPIError,
|
|
311
357
|
*,
|
|
@@ -355,6 +401,16 @@ async def _raise_flow_api_error(
|
|
|
355
401
|
suggestions.append(
|
|
356
402
|
"Fix the field(s) listed in 'field_errors' and retry the call."
|
|
357
403
|
)
|
|
404
|
+
# Issue #1149: also attach the data_schema so the LLM sees the field
|
|
405
|
+
# shape (selector, required, ...) alongside the per-field error
|
|
406
|
+
# codes — symmetric with the unstructured-error branch below.
|
|
407
|
+
# `field_errors` tells "what failed", `data_schema` tells "what's
|
|
408
|
+
# accepted"; together they're enough for self-correction.
|
|
409
|
+
schema = await _fetch_data_schema_for_error_context(
|
|
410
|
+
client, helper_type, menu_choice
|
|
411
|
+
)
|
|
412
|
+
if schema is not None:
|
|
413
|
+
context["data_schema"] = schema
|
|
358
414
|
else:
|
|
359
415
|
# Unstructured — attach the data_schema so the LLM has something to use.
|
|
360
416
|
message = (
|
|
@@ -670,13 +726,14 @@ class ConfigEntryFlowTools:
|
|
|
670
726
|
@log_tool_usage
|
|
671
727
|
async def ha_get_helper_schema(
|
|
672
728
|
self,
|
|
673
|
-
helper_type: Annotated[
|
|
729
|
+
helper_type: Annotated[ALL_HELPER_TYPES, Field(description="Helper type")],
|
|
674
730
|
menu_option: Annotated[
|
|
675
731
|
str | None,
|
|
676
732
|
Field(
|
|
677
733
|
description=(
|
|
678
|
-
"For menu-based helpers: the sub-type to
|
|
679
|
-
"'binary_sensor' for template). Omit to
|
|
734
|
+
"For menu-based flow helpers (template, group): the sub-type to "
|
|
735
|
+
"inspect (e.g. 'sensor' or 'binary_sensor' for template). Omit to "
|
|
736
|
+
"see available menu options first. Ignored for simple helpers."
|
|
680
737
|
),
|
|
681
738
|
default=None,
|
|
682
739
|
),
|
|
@@ -684,21 +741,72 @@ class ConfigEntryFlowTools:
|
|
|
684
741
|
) -> dict[str, Any]:
|
|
685
742
|
"""Get configuration schema for a helper type.
|
|
686
743
|
|
|
687
|
-
Returns the
|
|
688
|
-
|
|
744
|
+
Returns the field list and types needed to create this helper. Use
|
|
745
|
+
before ha_config_set_helper when unsure of the required `config`
|
|
746
|
+
(flow helpers) or required typed parameters (simple helpers). The
|
|
747
|
+
same schema is also auto-attached to validation-error responses
|
|
748
|
+
from ha_config_set_helper, so an explicit pre-call is optional.
|
|
689
749
|
|
|
690
|
-
|
|
750
|
+
Three branches:
|
|
691
751
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
752
|
+
1. Simple helpers (input_*, counter, timer, schedule, zone, person,
|
|
753
|
+
tag): static schema returned from a built-in dict.
|
|
754
|
+
ha_get_helper_schema("input_select")
|
|
755
|
+
→ {flow_type: "form", data_schema: [{name: "name", required: True, ...}, ...]}
|
|
695
756
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
757
|
+
2. Form-based flow helpers (min_max, utility_meter, statistics, ...):
|
|
758
|
+
starts a fresh HA flow, reads the schema, and aborts the flow.
|
|
759
|
+
ha_get_helper_schema("min_max")
|
|
760
|
+
→ {flow_type: "form", data_schema: [...]}
|
|
699
761
|
|
|
700
|
-
|
|
762
|
+
3. Menu-based flow helpers (template, group): two-call workflow.
|
|
763
|
+
# Step 1 — discover sub-types:
|
|
764
|
+
ha_get_helper_schema("template")
|
|
765
|
+
→ {flow_type: "menu", menu_options: ["sensor", "binary_sensor", ...]}
|
|
766
|
+
|
|
767
|
+
# Step 2 — inspect form fields for a sub-type:
|
|
768
|
+
ha_get_helper_schema("template", menu_option="sensor")
|
|
769
|
+
→ {flow_type: "form", menu_option: "sensor", data_schema: [...]}
|
|
701
770
|
"""
|
|
771
|
+
# Issue #1149: simple-helper dispatch — return a static schema
|
|
772
|
+
# without round-tripping HA. Lazy import keeps the existing
|
|
773
|
+
# tools_config_helpers ↔ tools_config_entry_flow boundary intact.
|
|
774
|
+
from .tools_config_helpers import (
|
|
775
|
+
SIMPLE_HELPER_TYPES,
|
|
776
|
+
get_simple_helper_schema,
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
if helper_type in SIMPLE_HELPER_TYPES:
|
|
780
|
+
schema = get_simple_helper_schema(helper_type)
|
|
781
|
+
# Invariant in tools_config_helpers asserts every simple type
|
|
782
|
+
# has a schema entry — None here would indicate a developer
|
|
783
|
+
# error that should fail loudly rather than mask as empty.
|
|
784
|
+
if schema is None:
|
|
785
|
+
raise_tool_error(create_error_response(
|
|
786
|
+
ErrorCode.INTERNAL_UNEXPECTED,
|
|
787
|
+
f"No simple-helper schema registered for '{helper_type}'",
|
|
788
|
+
context={"helper_type": helper_type},
|
|
789
|
+
))
|
|
790
|
+
if menu_option is not None:
|
|
791
|
+
# Simple helpers have no menu — flag the misuse rather than
|
|
792
|
+
# silently ignore the parameter.
|
|
793
|
+
raise_tool_error(create_error_response(
|
|
794
|
+
ErrorCode.VALIDATION_INVALID_PARAMETER,
|
|
795
|
+
f"menu_option is not applicable to simple helper "
|
|
796
|
+
f"'{helper_type}' (only flow helpers like 'template' "
|
|
797
|
+
f"and 'group' use menus).",
|
|
798
|
+
suggestions=["Omit menu_option for simple helpers."],
|
|
799
|
+
context={"helper_type": helper_type},
|
|
800
|
+
))
|
|
801
|
+
return {
|
|
802
|
+
"success": True,
|
|
803
|
+
"helper_type": helper_type,
|
|
804
|
+
"flow_type": _FlowType.FORM,
|
|
805
|
+
"step_id": "user",
|
|
806
|
+
"data_schema": schema,
|
|
807
|
+
"description_placeholders": {},
|
|
808
|
+
}
|
|
809
|
+
|
|
702
810
|
flow_id = None # Track flow_id for error context
|
|
703
811
|
try:
|
|
704
812
|
flow_result = await self._client.start_config_flow(helper_type)
|