From 5ff8bbfc76e52d81d3db50b2d1395ca1c72f2537 Mon Sep 17 00:00:00 2001 From: ModelHub XC Date: Mon, 20 Jul 2026 09:47:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=EF=BC=8C=E7=94=B1ModelHub=20XC=E7=A4=BE=E5=8C=BA=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Model: selorahomes/Selora-AI Source: Original Platform --- .gitattributes | 82 ++++ LICENSE | 0 Modelfile.answer | 34 ++ Modelfile.automation | 47 ++ Modelfile.clarification | 33 ++ Modelfile.command | 35 ++ Modelfile.utilities | 36 ++ README.md | 583 ++++++++++++++++++++++++ manifest.json | 105 +++++ ollama/Modelfile | 34 ++ ollama/README.md | 20 + ollama/selora-ollama.gguf | 3 + ollama/system_prompt.txt | 22 + params | 9 + prompts/answer_system_prompt.txt | 14 + prompts/automation_system_prompt.txt | 27 ++ prompts/clarification_system_prompt.txt | 13 + prompts/command_system_prompt.txt | 15 + prompts/utilities_system_prompt.txt | 16 + qwen3_17b_base.Q6_K.gguf | 3 + selora-answer.f16.gguf | 3 + selora-automation.f16.gguf | 3 + selora-clarification.f16.gguf | 3 + selora-command.f16.gguf | 3 + selora-ollama.Q6_K.gguf | 3 + selora-utilities.f16.gguf | 3 + system | 22 + template | 5 + 28 files changed, 1176 insertions(+) create mode 100644 .gitattributes create mode 100644 LICENSE create mode 100644 Modelfile.answer create mode 100644 Modelfile.automation create mode 100644 Modelfile.clarification create mode 100644 Modelfile.command create mode 100644 Modelfile.utilities create mode 100644 README.md create mode 100644 manifest.json create mode 100644 ollama/Modelfile create mode 100644 ollama/README.md create mode 100644 ollama/selora-ollama.gguf create mode 100644 ollama/system_prompt.txt create mode 100644 params create mode 100644 prompts/answer_system_prompt.txt create mode 100644 prompts/automation_system_prompt.txt create mode 100644 prompts/clarification_system_prompt.txt create mode 100644 prompts/command_system_prompt.txt create mode 100644 prompts/utilities_system_prompt.txt create mode 100644 qwen3_17b_base.Q6_K.gguf create mode 100644 selora-answer.f16.gguf create mode 100644 selora-automation.f16.gguf create mode 100644 selora-clarification.f16.gguf create mode 100644 selora-command.f16.gguf create mode 100644 selora-ollama.Q6_K.gguf create mode 100644 selora-utilities.f16.gguf create mode 100644 system create mode 100644 template diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e27ab1b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,82 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +qwen25_15b_answer.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen25_15b_automation.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen25_15b_base.Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text +qwen25_15b_clarification.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen25_15b_command.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_answer.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_automation.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_base.IQ4_XS.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_base.f16.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_clarification.lora.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_command.lora.gguf filter=lfs diff=lfs merge=lfs -text +selora-v042-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v042-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v042-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v042-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v043-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v043-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v043-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v043-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v043-recipe.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v046-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +qwen3_17b_base.Q6_K.gguf filter=lfs diff=lfs merge=lfs -text +selora-v047-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v047-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v047-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v047-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v048-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v048-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v048-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v048-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-v048-utilities.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-answer.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-automation.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-clarification.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-command.f16.gguf filter=lfs diff=lfs merge=lfs -text +selora-utilities.f16.gguf filter=lfs diff=lfs merge=lfs -text +ollama-single-q6/selora-qwen-0.4.8-q6.gguf filter=lfs diff=lfs merge=lfs -text +ollama/selora-qwen.gguf filter=lfs diff=lfs merge=lfs -text +ollama/selora-ollama.gguf filter=lfs diff=lfs merge=lfs -text +selora-ollama.Q6_K.gguf filter=lfs diff=lfs merge=lfs -text diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/Modelfile.answer b/Modelfile.answer new file mode 100644 index 0000000..95fe5fd --- /dev/null +++ b/Modelfile.answer @@ -0,0 +1,34 @@ +# selora-qwen-answer (Selora AI v0.4.8) — Ollama recipe. +# Put this file in the same directory as the downloaded GGUFs, then: +# ollama create selora-qwen-answer -f Modelfile.answer +FROM ./qwen3_17b_base.Q6_K.gguf +ADAPTER ./selora-answer.f16.gguf + +TEMPLATE """{{ if .System }}<|im_start|>system +{{ .System }}<|im_end|> +{{ end }}{{ if .Prompt }}<|im_start|>user +/no_think {{ .Prompt }}<|im_end|> +{{ end }}<|im_start|>assistant +""" + +SYSTEM """You are Selora AI's answer specialist for Home Assistant. + +Given a user question and the AVAILABLE ENTITIES list, respond with ONE JSON object only: +{"r":"","q":["",...]} + +Rules: +- r: response template. Use {entity_id} placeholders for any state references; the consumer substitutes live state. Keep r short — 1-2 sentences max. +- q: array of entity_ids to look up. Omit when no live state is needed. +- Either field can be omitted if not used, but never both. +- Only reference entity_ids that appear in AVAILABLE ENTITIES below. +- Never invent state values; always template them via {entity_id}. +- If the question is outside the home's scope, return {"r":"I can only answer questions about your home."}. + +Output JSON only — no narration, no markdown fences, no chain-of-thought. +""" + +PARAMETER temperature 0.0 +PARAMETER repeat_penalty 1.0 +PARAMETER repeat_last_n 256 +PARAMETER stop "<|im_end|>" +PARAMETER stop "<|endoftext|>" diff --git a/Modelfile.automation b/Modelfile.automation new file mode 100644 index 0000000..88dd508 --- /dev/null +++ b/Modelfile.automation @@ -0,0 +1,47 @@ +# selora-qwen-automation (Selora AI v0.4.8) — Ollama recipe. +# Put this file in the same directory as the downloaded GGUFs, then: +# ollama create selora-qwen-automation -f Modelfile.automation +FROM ./qwen3_17b_base.Q6_K.gguf +ADAPTER ./selora-automation.f16.gguf + +TEMPLATE """{{ if .System }}<|im_start|>system +{{ .System }}<|im_end|> +{{ end }}{{ if .Prompt }}<|im_start|>user +/no_think {{ .Prompt }}<|im_end|> +{{ end }}<|im_start|>assistant +""" + +SYSTEM """You are Selora AI, an automation architect for Home Assistant. The user wants a recurring rule, schedule, or multi-step sequence saved as an automation, OR a reusable parameterized blueprint. + +Choose the output format from the request: + +A) BLUEPRINT request — when the user asks to "create a blueprint automation", gives a "## Detailed Description" with an input table, or otherwise wants a REUSABLE/PARAMETERIZED automation with named inputs. Respond with markdown containing a single yaml block. The response MUST start with ```yaml and end with ``` because it is parsed by code. Inside, emit a Home Assistant automation BLUEPRINT: + - top-level `blueprint:` with `name:`, `description:`, `domain: automation`, and `input:` containing EVERY input named in the request (use the exact input keys from the request's input table). + - each input has a `name:` and a `selector:` (entity/number/duration/media/etc.); add `default:` for timeouts/durations/levels. + - wire inputs into triggers/conditions/actions with `!input ` references — never hardcode entity_ids in a blueprint. + - use `mode: single` and `max_exceeded: silent`. States are quoted strings. Times/durations are "HH:MM:SS". + - Output ONLY the ```yaml block (inline comments allowed). + +B) CONCRETE request — a one-off command/schedule grounded in this user's AVAILABLE ENTITIES. Return ONE JSON object: +{"intent":"automation","response":"<1-2 sentence explanation>","description":"<2-3 sentences>","automation":{"alias":"","description":"<...>","triggers":[],"conditions":[],"actions":[]}} +Or, if no entity matches, the clarification shape: +{"intent":"clarification","response":""} + +BLUEPRINT RULES (format A): +- The ```yaml fence is mandatory and literal — lowercase `yaml`, not `yml`/`YAML`/bare ```. +- `blueprint.domain` is ALWAYS `automation`. +- Triggers inside a blueprint use `platform:` (e.g. `- platform: state`, `- platform: numeric_state`, `- platform: time`, `- platform: sun`). +- `!input` may reference a scalar (`entity_id: !input door_sensor`), a whole `target:` (`target: !input light_switch`), or a whole `data:` (`data: !input alert_media`). +- Do NOT add a required input the caller will not supply; any input beyond the requested set MUST have a `default:`. + +CONCRETE RULES (format B): +- Use HA 2024+ plural keys: 'triggers', 'actions', 'conditions'. Service calls use the 'service' key. +- State 'to'/'from' MUST be strings. Times "HH:MM:SS". Durations "HH:MM:SS" or {"hours":N,...}. +- EVERY entity_id MUST appear VERBATIM in AVAILABLE ENTITIES; never invent placeholder names. +""" + +PARAMETER temperature 0.0 +PARAMETER repeat_penalty 1.0 +PARAMETER repeat_last_n 256 +PARAMETER stop "<|im_end|>" +PARAMETER stop "<|endoftext|>" diff --git a/Modelfile.clarification b/Modelfile.clarification new file mode 100644 index 0000000..63bf7e3 --- /dev/null +++ b/Modelfile.clarification @@ -0,0 +1,33 @@ +# selora-qwen-clarification (Selora AI v0.4.8) — Ollama recipe. +# Put this file in the same directory as the downloaded GGUFs, then: +# ollama create selora-qwen-clarification -f Modelfile.clarification +FROM ./qwen3_17b_base.Q6_K.gguf +ADAPTER ./selora-clarification.f16.gguf + +TEMPLATE """{{ if .System }}<|im_start|>system +{{ .System }}<|im_end|> +{{ end }}{{ if .Prompt }}<|im_start|>user +/no_think {{ .Prompt }}<|im_end|> +{{ end }}<|im_start|>assistant +""" + +SYSTEM """You are Selora AI's clarification specialist for Home Assistant. + +When the user's request is ambiguous, respond with ONE JSON object only: +{"q":"","o":["","",...]} + +Rules: +- q: short, specific clarifying question. 1 sentence max. +- o: optional array of suggested answers. Omit the o key when free-form input is appropriate. +- Reference entity aliases from AVAILABLE ENTITIES when the ambiguity is about which entity. +- Don't ask multiple questions in one turn — pick the single most important blocker. +- Don't restate the user's full request; ask the one thing you need. + +Output JSON only — no narration, no markdown fences, no chain-of-thought. +""" + +PARAMETER temperature 0.0 +PARAMETER repeat_penalty 1.0 +PARAMETER repeat_last_n 256 +PARAMETER stop "<|im_end|>" +PARAMETER stop "<|endoftext|>" diff --git a/Modelfile.command b/Modelfile.command new file mode 100644 index 0000000..e0de799 --- /dev/null +++ b/Modelfile.command @@ -0,0 +1,35 @@ +# selora-qwen-command (Selora AI v0.4.8) — Ollama recipe. +# Put this file in the same directory as the downloaded GGUFs, then: +# ollama create selora-qwen-command -f Modelfile.command +FROM ./qwen3_17b_base.Q6_K.gguf +ADAPTER ./selora-command.f16.gguf + +TEMPLATE """{{ if .System }}<|im_start|>system +{{ .System }}<|im_end|> +{{ end }}{{ if .Prompt }}<|im_start|>user +/no_think {{ .Prompt }}<|im_end|> +{{ end }}<|im_start|>assistant +""" + +SYSTEM """You are Selora AI's command specialist for Home Assistant. + +Given a user command and the AVAILABLE ENTITIES list, respond with ONE JSON object only: +{"c":[{"s":"","e":"","d":{}}],"r":""} + +Rules: +- c: ordered array of one or more service calls. Calls execute in array order. +- s: HA service in "domain.action" form (e.g. "light.turn_on", "lock.lock", "media_player.play_media", "scene.turn_on"). +- e: canonical entity_id from AVAILABLE ENTITIES. Never use the human alias — always the entity_id. +- d: service parameters object. Omit the d key entirely when there are no params (do not include "d":{}). +- r: ≤ 1 sentence past-tense confirmation describing what got done (e.g. "Kitchen light on."). +- The service domain (before the dot) must match the entity_id's domain. light.turn_on goes with light.* entities, lock.lock goes with lock.* entities, etc. +- For multi-target requests, produce one c entry per (service, entity_id) pair. + +Output JSON only — no narration, no markdown fences, no chain-of-thought. +""" + +PARAMETER temperature 0.0 +PARAMETER repeat_penalty 1.0 +PARAMETER repeat_last_n 256 +PARAMETER stop "<|im_end|>" +PARAMETER stop "<|endoftext|>" diff --git a/Modelfile.utilities b/Modelfile.utilities new file mode 100644 index 0000000..066f733 --- /dev/null +++ b/Modelfile.utilities @@ -0,0 +1,36 @@ +# selora-qwen-utilities (Selora AI v0.4.8) — Ollama recipe. +# Put this file in the same directory as the downloaded GGUFs, then: +# ollama create selora-qwen-utilities -f Modelfile.utilities +FROM ./qwen3_17b_base.Q6_K.gguf +ADAPTER ./selora-utilities.f16.gguf + +TEMPLATE """{{ if .System }}<|im_start|>system +{{ .System }}<|im_end|> +{{ end }}{{ if .Prompt }}<|im_start|>user +/no_think {{ .Prompt }}<|im_end|> +{{ end }}<|im_start|>assistant +""" + +SYSTEM """You are Selora AI's utilities specialist for Home Assistant. + +You handle docs-grounded help: maintenance (pending updates, version conflicts), troubleshooting (why a device is unavailable / offline / not responding), and setup help (how to add or configure an integration). You are given the user question, the AVAILABLE ENTITIES list, and a RELEVANT DOCS list of retrieved Home Assistant documentation chunks. + +Respond with ONE JSON object only: +{"r":"","q":["",...],"src":["",...]} + +Rules: +- r: advice prose grounded in RELEVANT DOCS. Use {entity_id} placeholders for any state references (e.g. which integration has an update, which device is unavailable); the consumer substitutes live state. Keep it focused — a short paragraph. +- q: array of entity_ids whose live state the advice depends on (update.* entities, problem/connectivity binary_sensors, the unavailable entity). Omit or use [] when no live state is needed (e.g. setup help for a device that does not exist yet). +- src: array of doc chunk ids from RELEVANT DOCS that the advice is drawn from. This is the citation provenance — only cite chunks that appear in RELEVANT DOCS. +- Only reference entity_ids that appear in AVAILABLE ENTITIES below. +- Ground the fix/steps in the retrieved docs, never in the entity state alone — the state is the signal, the docs supply the explanation. +- Never invent state values; always template them via {entity_id}. + +Output JSON only — no narration, no markdown fences, no chain-of-thought. +""" + +PARAMETER temperature 0.0 +PARAMETER repeat_penalty 1.0 +PARAMETER repeat_last_n 256 +PARAMETER stop "<|im_end|>" +PARAMETER stop "<|endoftext|>" diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9d8ede --- /dev/null +++ b/README.md @@ -0,0 +1,583 @@ +--- +license: apache-2.0 +base_model: Qwen/Qwen3-1.7B +tags: + - text-generation + - qwen + - qwen3 + - lora + - gguf + - home-assistant + - home-automation + - smart-home + - iot + - instruction-tuned + - tool-use + - ollama +language: + - en +library_name: transformers +pipeline_tag: text-generation +--- + +**Selora Homes:** [selorahomes.com](https://selorahomes.com) +**Selora AI Home Assistant Integration:** [github.com/SeloraHomes/ha-selora-ai](https://github.com/SeloraHomes/ha-selora-ai) + +--- + +# Selora AI + +Selora AI is an instruction-tuned language model for +[**Home Assistant**](https://www.home-assistant.io/), the open-source **smart home** +platform. It ships in two forms: **five small, single-purpose LoRA specialists** — the +reference setup the integration hot-swaps between — and a single general model, +**`selora-ollama`**, that folds all five into one for Ollama. Each specialist emits +one strict, compact JSON **"slim envelope"** for its intent, and +the [Selora AI integration](https://github.com/SeloraHomes/ha-selora-ai) executes that +envelope against your home — running service calls, resolving live state, or saving an +automation (see [Specialists](#specialists) for the exact shapes). The five specialists: + +- **command** — control devices ("turn off the kitchen lights") +- **automation** — author home automations and blueprints +- **answer** — answer questions about the home's live state +- **clarification** — ask a follow-up when a request is ambiguous +- **utilities** — docs-grounded maintenance, troubleshooting, and setup help + +The five specialists are LoRA adapters fine-tuned on a shared +[Qwen3 1.7B](https://huggingface.co/Qwen/Qwen3-1.7B) base. + +**Base:** Qwen3 1.7B · **Format:** GGUF Q6_K base + 5 per-specialist LoRA adapters (F16) · **License:** Apache-2.0 + +Selora AI powers the [Selora AI Home Assistant integration](https://github.com/SeloraHomes/ha-selora-ai) +and runs locally on Apple Silicon, Linux, or Windows via +[llama-server](#llama-server-home-assistant-integration-runtime) or +[Ollama](#ollama-evaluate-the-model-before-integrating), or in the cloud via +[vLLM](#vllm-cloud) — built for self-hosted **IoT** deployments that stay private and +offline-first. + +## Use cases + +- **Chat control of smart-home devices** — "turn off the kitchen + lights", "set the thermostat to 68", "open the garage door" — resolved against + live Home Assistant entity state. +- **Natural-language home automation creation** — describe an automation in + plain English ("when the front door opens after 10pm, turn on the porch + light") and Selora returns valid Home Assistant YAML as a draft you review + before it's saved. +- **Scene and routine orchestration** — chain actions across multiple entities + ("good night" → lock doors, dim bedroom lights, set thermostat) without + hand-writing scripts. +- **Q&A about your home** — "is the laundry running?", "what's the temperature + upstairs?" — the `answer` adapter returns the entities to check plus a + response template, and the integration fills in the live state. +- **Docs-grounded help** — "why is the living-room sensor unavailable?", "how do + I add the Hue integration?", "which integrations have pending updates?" — + answered from retrieved Home Assistant documentation, with live state pulled in + via entity placeholders and citations back to the source docs. +- **Privacy-first home assistant** — runs entirely on local hardware + (Raspberry Pi 5, Mac mini, NUC-class boxes) with no cloud dependency, so + device commands and home telemetry never leave the LAN. + +## Specialists + +Every specialist LoRA emits a compact **"slim envelope"** — a small JSON object whose +high-frequency keys are single characters to save tokens — and that envelope is an +**intermediate representation, not a finished action**. The Selora AI integration's +`_convert_slim_shape` parser turns it into real Home Assistant activity: run a +downloaded GGUF on its own and you get the envelope back; it takes the integration (or +an equivalent parser) to execute service calls, resolve live state, build YAML, or +attach citations. By design the model **never fabricates device state** — it emits the +calls to make, the entities to look up, the question to ask, or the automation to +build, and the integration completes the loop against live HA. + +| Adapter | Emits (raw model output) | What the integration does with it | +| --- | --- | --- | +| `command` | `{"c":[{"s":"","e":"","d":{…}}],"r":""}` | Executes each `c` as an HA service call, in array order, then shows `r`. The model does **not** call services itself. | +| `answer` | `{"r":"","q":["",…]}` | Looks up the `q` entities' live state and substitutes it into the `{entity_id}` placeholders in `r`. The model templates state; it never reads it. | +| `clarification` | `{"q":"","o":["