Assist: Get Source when Running a Script with an LLM?

I’ve run into what I think is a limitation with scripts and the Assist pipeline.

The whole goal I’m trying to accomplish is to write a HA script that a voice assistant can call, which will use Music Assistant to search for a track and play it on the device the request originated from (assuming the assist device has a companion media_player on the same device).

The core problem I’m having: I don’t see any way to identify the “source” of the script being run.

So if I have a script: script.my_script And this is invoked from a device like Voice PE, I get the following context:

this:
  entity_id: script.my_script
  state: 'off'
  attributes:
    last_triggered: '2025-03-10T13:56:10.221730+00:00'
    mode: single
    current: 0
    icon: mdi:bullhorn-variant
    friendly_name: My Script
  last_changed: '2025-03-10T13:56:17.617790+00:00'
  last_reported: '2025-03-10T13:56:17.617790+00:00'
  last_updated: '2025-03-10T13:56:17.617790+00:00'
  context:
    id: 01JP05F4JHHRABG3H5RXFHYGS2
    parent_id: null
    user_id: null
some_script_var: 'some value'
context:
  id: 01JP06VNDDE9S0A0ZRPWRNXE0H
  parent_id: null
  user_id: null

From this, how can I determine what the source is? For example, I want to know that this script was invoked by assist_satellite.office and not assist_satellite.kitchen.

Is this possible? If so, how?

Edit: Adjusted title for clarity.

What are the reasons to use a script if you are going to activate the process by voice? Сreate automation.

{{'media_player.'~device_attr(trigger.device_id, "name")~'_something_else'}}

Because it may not always be the same sentence trigger.

What Jake is doing allows it to be used more like a tool.

If going the hard way, I would try to make an auxiliary sensor that stored the value of the device that was last queried from. :upside_down_face:

Hm, that could work - assuming that nobody queries their Voice PE device to play music at (roughly) the same time. I didn’t think of this, I’ll give it a try and report back if it works!

Sorry, I wasn’t specific. I’m using an LLM to call the script so I can use natural language. The Custom Sentence trigger on intents doesn’t fit my needs.

It works! For those wondering, here’s what you have to do:

Create an input_text helper.

Then add the following automation:

alias: Set Last Used Voice Device
description: ""
conditions: []
mode: single
triggers:
  - trigger: state
    to: listening
    entity_id:
      # Replace with the list of your voice assistants.
      - assist_satellite.one
      - assist_satellite.two
      - assist_satellite.three
actions:
  - action: input_text.set_value
    target:
      # Replace with your helper entity ID.
      entity_id: input_text.last_queried_voice_entity_id
    data:
      # This template assumes you have an assist satellite and a 
      # media player with the same device name.
      # Tweak to map your entities accordingly.
      value: >-
        {{ trigger.entity_id | replace('assist_satellite.', 'media_player.') |
        replace('_assist_satellite', '_media_player') }}

To use in an action:

# In a service call / action:
target:
  entity_id: "{{ states('input_text.your_last_used_assist_id_helper') }}"
1 Like

Do you have any idea for getting who the last request came from, could that be available from some entity - if the sentence came from either a mobile app or from the web interface?

User currently isn’t in the stream. (who is the user from a given voice call on a VPE? who knows without voice identification) you can Make guesses based on states but that’s about it.

The mobile companion apps have their own respective users, so knowing that would be pretty handy. Web interface is also tied to user login. I have no idea how to deduct from any states from who the latest command came from. :confused: (So its not just voice id.)

If you launch a pipeline from script or the UI you can absolutely capture

 {{user}}

(i think it’s user maybe user_id)
Thats pretty easy actually. When you fire it from voice that will be blank and you’d have to fall back on which voice station ID

Thanks for the tip. I have this custom sentence:

intents:
  custom_intents:
    data:
      - sentences:
          - "{custom_text}"
lists:
  custom_text:
    wildcard: true

And this script to handle it (and pass it on to nodered):

intent_script:
  custom_intents:
    action:
      - action: mqtt.publish
        data:
          topic: /nodered/assist
          payload: "{{user}} {{user_id}}: {{custom_text}}"
      ...
    speech:
      text: ...

Unfortunately, none of the user or user_id get replaced by anything.

@NathanCu did say:

So that is expected. It’s not possible to know which user initiated a voice action. There is no “voice recognition” in Home Assistant currently.

In case anyone else comes across this thread, I solved a similar problem by using a variable in the esp firmware (similar scope as name or friendly name).

substitutions:
name: office-echo
default_speaker: media_player.office

Then using shared firmware, I send that variable to the scripts that I call. I use this to play music with the voice assist, but primarily to play a “ding” to acknowledge when micro_wake_word detects. My esp devices are hidden, so there is no feedback from the leds.