AI Assistant
The AI Assistant is an admin-side conversational helper that wires GEM's data model into natural-language requests. It opens as a drawer from the admin top bar and stays scoped to the integrator/admin context — it does not control end-user devices on its own (homeowner-facing voice control is a separate, more constrained surface).
You talk to it in plain English. It picks the right tool, asks for confirmation on anything that changes state, and shows you a one-line description of what it's about to do before it runs.
Where to find it
- Click the AI icon in the admin top bar to open the drawer.
- The drawer is also reachable from Admin → Help.
- The assistant runs against Anthropic's Claude API. If the drawer says Configuration Required, paste your Claude API key (starts with
sk-) into the inline field and click Save & Enable — the key is stored as the encrypted system attributeanthropic_api_keyand the assistant re-initializes automatically. Get a key at console.anthropic.com.
How it decides what to do
Every skill is registered with a description, a JSON input schema, and (for mutations) a confirmation requirement. When you ask the assistant to do something, it:
- Picks the skill whose description matches your request.
- Resolves IDs (zones, devices, macros, etc.) against the live in-memory state — not the database — so values are current.
- For mutations: shows a one-line preview and waits for your confirmation before writing.
- For atomic bulk operations: pre-validates every entry, writes them, and rolls back the entire batch if any one fails.
If you're not sure what the assistant can do, just ask it: "what can you do?" — it will call its list_skills tool and return the live catalog.
Skill categories
Skills are grouped by intent. The same categories are returned by list_skills.
create — commission new entities
| Skill | One-line summary |
|---|---|
bulk_create_devices | Atomic batch device commissioning with command_set / device_type auto-resolve. |
bulk_create_zones | Atomic batch zone commissioning with subsystem name/id resolve + device/site_space validation. |
bulk_create_site_spaces | Atomic batch room/floor/area creation with in-batch parent_name resolution. |
bulk_create_triggers | Atomic batch attribute_trigger creation with template + targets fan-out. |
bulk_create_schedules | Atomic batch macro_schedule creation with natural-language at/days → cron. |
bulk_create_channels | Atomic batch channel-lineup commissioning under one provider. |
bulk_create_av_sources | Atomic batch add of av_sources to an existing av_zone. |
bulk_create_av_zones | Atomic batch creation of many distinct av_zones, each with its own backing zone + per-zone sources. |
bulk_create_widgets | Atomic batch add of ui_page_widget rows to a ui_page. |
bulk_create_ui_pages | Atomic batch ui_page creation with optional pre-seeded widgets and multi-UI linking. |
bulk_create_macros | Atomic batch macro creation (each with optional steps) for scene-per-room rollouts. |
bulk_create_monitors | Atomic batch ping/HTTP/TCP monitor commissioning with device-ip auto-resolve and in-batch depends_on chains. |
create_av_zone_with_sources | Atomic AV zone + sources + placeholder macros. |
create_motion_automation | Wire motion sensor → on-macro + off-macro + on-trigger + off-trigger in one call. |
create_scene | Author a multi-zone scene macro from per-zone intent (off / on / level / color_temp), auto-emitting the right command steps. |
create_macro_with_steps | Atomic macro + steps with metadata-validated drivers. |
create_macro | Create one empty macro. |
add_macro_step | Add a single step to an existing macro. |
create_trigger | Create one attribute_trigger. |
create_schedule | Create one macro_schedule. |
create_access_rule | Create a physical access_control rule (reader + users + action). |
bulk_create_access_rules | Atomic batch access_control rule creation with a shared defaults block, natural-language day/hour parsing, and full rollback. |
create_notification_profile | Create notification_profile + bulk-assign auth_users. |
create_user_with_roles | Atomic auth_user + roles + profile + sites + credentials. |
create_ui_room | Create a UI for a room with auto-discovered controls. |
configure_device | Configure an existing device's network/auth attributes. |
add_device_from_discovery | Add a single device discovered via network scan. |
discover_network | Scan the local network for new devices. |
wire — link existing entities together
| Skill | One-line summary |
|---|---|
bulk_assign_zones_to_ui | Wire many zones to a manual UI (ui_zone rows). |
bulk_assign_macros_to_ui | Wire many macros as scene-buttons on a manual UI (ui_macro rows). |
bulk_assign_pages_to_ui | Link many existing ui_pages to a UI (ui_page_ui rows). |
link_zones_to_site_spaces | Auto-suggest or apply zone → site_space linkage based on name/label matching. |
remap_av_zone_devices | Rebind av_source.device_id across one or many av_zones. |
clone — deep-copy existing entities
| Skill | One-line summary |
|---|---|
clone_ui | Deep-copy a UI with all its zones, controls, macros, and page links. |
clone_ui_page | Deep-copy a single ui_page (and its widgets) with optional re-linking. |
clone_macro | Clone a macro to one or many new names. |
clone_trigger | Clone a trigger to one name OR fan out across many targets. |
clone_schedule | Clone a schedule to one or many new names. |
clone_av_zone | Deep-copy an av_zone with all sources (and optionally their macros). |
clone_zone | Deep-copy a plain zone with every attribute row (and optionally its ui_zone links) to one or many new zones, with per-clone device/address overrides. |
clone_user | Clone an auth_user (roles + sites + notification profile + flags) to one or many new accounts — credentials are never copied. |
clone_notification_profile | Clone a notification_profile (delivery methods + day/hour masks) to one or many, optionally copying user assignments. |
edit — modify existing rows
| Skill | One-line summary |
|---|---|
update_model | Update fields on one row in any table. |
update_macro_steps | Atomic add / update / remove / renumber for steps in an existing macro. |
insert_model | Insert one row into any table. |
batch_insert | Insert multiple rows into one table in a single transaction. |
set_attribute | Set one attribute value. |
build_widget | Create or update a ui_widget definition (with code). |
bulk_edit — same change to many rows
| Skill | One-line summary |
|---|---|
bulk_set_attribute | Set the same attribute on many targets (with dry_run + rollback). |
bulk_toggle_enabled | Flip the enabled flag on many rows (with dry_run + rollback). |
bulk_rename | Find/replace the name and/or label columns across many rows (with dry_run + rollback). |
run — execute or undo
| Skill | One-line summary |
|---|---|
run_macro | Run a macro on demand. |
send_command | Dispatch a single command to a device or zone. |
undo_last_action | Revert the last update_model or set_attribute change. |
reload | Reload a single entity from the database into memory. |
discover — read-only lookups
| Skill | One-line summary |
|---|---|
list_skills | Return this catalog grouped by category. |
query_database | Generic Sequelize-style query against any table. |
describe_attributes | List attributes on an entity, enriched with registry metadata. |
describe_macro_step | Get the data-payload schema for a macro step driver. |
get_attributes | Get current attribute values for an entity. |
get_zone_states | Read live state attributes for one or many zones. |
query_automation_history | Search attribute_history for past events. |
diagnose | System health diagnostics. |
navigate | Open an admin page or entity in the UI. |
search_docs | Search the GEM documentation. |
recall_memory_notes | Search persistent per-site memory notes captured in prior sessions. |
notes — capture knowledge
| Skill | One-line summary |
|---|---|
record_attribute_note | Attach a note to a specific attribute. |
update_registry_description | Update the canonical description in the attribute registry. |
record_memory_note | Save site-specific knowledge that future sessions should know. |
automate — multi-artifact one-shots
| Skill | One-line summary |
|---|---|
create_motion_automation | Wire one motion sensor to N target zones with on/off macros and triggers in one call. |
create_scene | Build one scene macro that fans out command steps to many zones at known levels / colors. |
Workflow patterns
A few recurring shapes the assistant uses well:
Commission then wire. Use bulk_create_zones (or device commissioning) to bring rows into existence, then link_zones_to_site_spaces to bin them into rooms, then bulk_assign_zones_to_ui (manual UIs) — or skip the last step entirely if the install uses space-driven UIs (the 90/10 default).
Suggest then apply. Several skills support a discover/commit split: link_zones_to_site_spaces returns ranked suggestions when called with no mapping, then is called again with the user-confirmed mapping to write. bulk_set_attribute and bulk_toggle_enabled accept dry_run: true for the same purpose. Prefer this two-call shape whenever scope might be broader than expected.
Atomic with rollback. Every bulk_* and clone_* skill validates the whole batch first and rolls back every partial write if any one step fails. This means it's safe to rerun after a failure once you've fixed the offending entry — the state is exactly as it was before the failed call.
Stored data is a public API. The assistant never silently migrates DB rows on a write path. If a stored macro / trigger / attribute predates a feature, the new code paths default to the old behavior; the new shape is opt-in.
Confirmation gate
Mutation skills (anything in create, wire, clone, edit, bulk_edit, notes, automate, plus run_macro) trigger a one-line confirmation prompt in the drawer before they execute. The prompt shows the resolved description (e.g. "Wire 12 zones to UI 'security_panel'") — not the raw JSON — so you can sanity-check intent without inspecting the call. Read-only skills (discover) run without prompting.
Where the catalog lives
The single source of truth is the defineTools() method in lib/ai_assistant.js. The list_skills tool iterates this list at runtime and groups by category, so the assistant's self-description stays in sync with the actual code automatically. This page may lag the code by a release or two — when in doubt, ask the assistant.