import type { VoiceTool } from './_types' import { tabletJson } from './_http' /** * Универсальный вызов сервиса Home Assistant — «escape hatch» для устройств, * под которые нет отдельного tool. Модель берёт entity_id из снимка состояния * дома (он инжектится в системный промпт) и вызывает нужный сервис. * * Guardrails: разрешены только безопасные бытовые домены. Никаких automation/ * script/shell/notify и т.п. — только прямое управление устройствами. */ const ALLOWED_DOMAINS = new Set([ 'light', 'switch', 'fan', 'climate', 'media_player', 'cover', 'scene', 'humidifier', 'vacuum', ]) const haService: VoiceTool = { schema: { type: 'function', function: { name: 'ha_service', description: 'Универсальное управление устройством Home Assistant, если нет специального tool. ' + 'Передай domain, service и entity_id (возьми из снимка состояния дома). Примеры: ' + 'domain=switch service=turn_on entity_id=switch.kettle; ' + 'domain=cover service=open_cover entity_id=cover.blinds. ' + 'Разрешённые домены: light, switch, fan, climate, media_player, cover, scene, humidifier, vacuum.', parameters: { type: 'object', properties: { domain: { type: 'string', description: 'Домен HA (light, switch, fan, climate, media_player, cover, scene, humidifier, vacuum)' }, service: { type: 'string', description: 'Сервис, напр. turn_on, turn_off, toggle, open_cover, set_percentage' }, entity_id: { type: 'string', description: 'entity_id устройства из снимка состояния дома' }, data: { type: 'object', description: 'Доп. параметры сервиса (напр. {"brightness_pct": 50})' }, }, required: ['domain', 'service', 'entity_id'], }, }, }, async execute(args) { const domain = String(args?.domain || '').trim() const service = String(args?.service || '').trim() const entity_id = String(args?.entity_id || '').trim() if (!ALLOWED_DOMAINS.has(domain)) return { error: `domain not allowed: ${domain}` } if (!service || !entity_id) return { error: 'domain, service, entity_id required' } if (entity_id.split('.')[0] !== domain) return { error: 'entity_id domain must match domain' } const extra = (args?.data && typeof args.data === 'object') ? args.data : {} await tabletJson('POST', '/api/voice/tools/smart-home', { domain, service, entity_id, ...extra }) return { success: true, domain, service, entity_id } }, } export const tools: VoiceTool[] = [haService]