Working with Select entities through the Assist API (OpenAI Integration)

I recently started using the official OpenAI integration through the Assist API but had a significant amount of difficulty working with select entities. It seems that the integration’s tools are more focused on working with devices, and does not natively have the ability to read Select entity options or call the select_option service.

I couldn’t find a working example, so I wanted to document one for the community here. Note that I’m new to working with LLM’s in home assistant so there may be a more optimal way to do this!

In this example I am controlling the effect attribute for a WLED device. I have a helper select template entity that mirrors the attribute and triggers changes on the underlying device. Please modify to fit your needs!

Intent Script:

  ListInputSelectOptions:
    description: "Return select options for a select.* or input_select.* entity by Friendly name."
    fields:
      name:
        description: "Friendly name to use for state options lookup."
        example: "kitchen under cabinet lighting effect"
        required: yes
    action:
      - variables:
          id: >
            {% set search = name | lower %}
            {% set ns = namespace(found='') %}
            {% for e in states.select | list + states.input_select | list %}
              {% if e.name | lower == search %}
                {% set ns.found = e.entity_id %}
              {% endif %}
            {% endfor %}
            {{ ns.found }}
          options: >
            {% if id %}
              {{ state_attr(id, 'options') | list }}
            {% else %}
              Could not find a select entity named "{{ name }}".
            {% endif %}
      - stop: ""
        response_variable: options
    speech:
      text: "{{ action_response }}"

The above was the most confusing part, I couldn’t get the conversation agent to pass the entity_id or the domain directly (even when hardcoded in the prompt). Because of this, I am passing the friendly name as a parameter and then mapping it to the entity_id in the script.

Script:

set_select_option:
  description: Set an option on a select.* or input_select.* entity by friendly name.
  fields:
    name:
      description: Friendly name of the select or input_select entity.
      example: kitchen under cabinet lighting effect
      required: true
      selector:
        text:
    option:
      description: The option value to set.
      example: Rainbow
      required: true
      selector:
        text:
  sequence:
  - variables:
      id: "{% set search = name | lower %} {% set ns = namespace(found='') %} {% for
        e in states.select | list + states.input_select | list %}\n  {% if e.name
        | lower == search %}\n    {% set ns.found = e.entity_id %}\n  {% endif %}\n{%
        endfor %} {{ ns.found }}\n"
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ id.startswith(''select.'') }}'
      sequence:
      - action: select.select_option
        target:
          entity_id: '{{ id }}'
        data:
          option: '{{ option }}'
    - conditions:
      - condition: template
        value_template: '{{ id.startswith(''input_select.'') }}'
      sequence:
      - action: input_select.select_option
        target:
          entity_id: '{{ id }}'
        data:
          option: '{{ option }}'
  alias: Set Select Option

Make sure the above script is exposed to your conversation agent.

Prompt (except):

Rules for tools:
- Do NOT say you executed an action unless you actually called a tool/service.
- If you need a list of state options for a "select.*" or a "input_select.*" entity, call the ListInputSelectOptions service to obtain a list.
- ALLWAYS consider if an action can be completed using a "script.*" service. If a script can complete the request, always prefer this option.
- To select an option for a "select.* "or "input_select.*" entity, use script.set_select_option. Never use turn_on, turn_off, or toggle on select entities — they do not support those services.

Kitchen Under Cabinet Lighting effect rule:
- Do NOT call the light service to complete the request; first, determine what state options are available for the select.kitchen_under_cabinet_lighting_effect entity by calling ListInputSelectOptions.
- Check if requested effect (ALWAYS strip the word “effect” and format in Title Case) is in the returned list.
  A) If true; select the modified effect name option on select.kitchen_under_cabinet_lighting_effect entity. Do NOT ask for confirmation. The request is now complete.
  B) If false; suggest using the closest match in the option list to complete the request.

General note for newbies like myself: I am using an intent_script to return the list to my conversation agent because scripts cannot return data (to my knowledge). I am using a script to set the option because it is easier to monitor/troubleshoot from the UI and no response is required.