I have a script with a multi select input, to do a task that requires these inputs. Part of the script validates that the user did not select more than four inputs, because the code downstream cannot cope with that (it's a vacuum).
I have two ways of handling this:
I have a step in the script that stops it with an unexpected error. When I use this, calling the script via the UI shows the error onscreen, but calling the script via Assist shows no error and in fact assumes the script finished correctly.
I can change the step of the script to stop normally with a response saying "Too many choices selected". When I use this, calling the script via the UI shows no error (AAAAAAAAAAA) but calling the script via Assist makes the assistant tell me "cannot complete this task because too many choices were selected".
Why do I have to choose between one or the other???????????? FML.
Only choose the first 4 of the selection and output a persistent notification when it's more than 4. If you need help with the template, post the automation/blueprint.
This is possible. You have to error but you have to capture your error and return the errors to the agent... AS THE RESPONSE.
In my agent focused tools they return success/error as an enum with the throw content if there is one...
Generally error messages under a conversation blow up the conversation. You should expect a throw and kick out of a convo if you call an intent or script with an unhandled error.
Go look at the scripts in Fridayss Party (in the repo once you find the thread) I do this all the time I think every script has an example where we do this.
@petro I don't want a persistent notification — I want the agent to speak the error to me. I'm talking to the agent, I don't have interest in going to pick up my phone and read a message on the app. I've temporarily chosen option #2 in my scripts to do this. Also, persistent notifications are shown to all users — I don't want this notification to be visible to my partner when I start the vacuum or vice versa.
@NathanCu your suggestion is far too complex. I simply want the stop script step to bubble up as an error to the agent. I would also like the stop script step to be able to return the exact error in the response variable field, when the stop step is set to return an error. This is illegal in the current script engine — you have to choose either return an error, or return a response.
I could settle for using the stop step with the error: True flag and no response dict, if the agent engine could handle that as an actual error! Currently it does not — no error is sent to the agent, it's almost as if the script had never run.
No I can't. There is no way from the script to identify which agent needs to synthesize the response. There's not even a way to identify IF an agent called the script. If there was, guaranteed I would have already done that (although doing that would be hacky as heck compared to the agent code handling errors from scripts properly, which is the entire point I'm raising).
The only way to communicate back to the specific calling agent that an error took place is to stop the script with a response variable. But response and error stops are mutually exclusive.
Right, I'm going to show you but you aren't posting the code and you're arguing. So, do you want help or do you want to shoot down all the people trying to help?
I could be wrong, I have no idea until I see the full context via the yaml.
sequence:
- alias: Abort if unavailable
if:
- condition: template
value_template: "{{ not has_value('vacuum.dreame_x40_ultra_complete') }}"
then:
- variables:
response:
error: Cleaning cannot start because the vacuum is not available
- stop: Cleaning cannot start because the vacuum is not available
response_variable: response
- alias: Abort if error
if:
- condition: template
value_template: "{{ is_state('vacuum.dreame_x40_ultra_complete', 'error') }}"
then:
- variables:
response:
error: >-
Cleaning cannot start because the vacuum is experiencing an
error. The error is {{
states("sensor.dreame_x40_ultra_complete_error") }}.
- stop: Cleaning cannot start because the vacuum is experiencing an error
response_variable: response
- variables:
mode: "{{ mode }}"
area: "{{ area | map('lower') | list }}"
iterations: "{{ iterations | default(1) }}"
- alias: Abort if too many areas
if:
- condition: template
value_template: "{{ area | length > 4 }}"
then:
- variables:
response:
error: >-
The vacuum cannot clean more than four areas in a single request.
If you need that, use multiple requests.
- stop: Too many areas selected
response_variable: response
- action: logbook.log
metadata: {}
data:
entity_id: script.clean_specific_areas_of_the_home
message: >-
queued to {{ mode }} {{ area | join(", ") }}{% if iterations|default(1)
> 1 %} {{ iterations }} times{% endif %}
name: Clean specific areas of the home
- action: script.turn_on
metadata: {}
data:
variables:
mode: "{{ mode }}"
area: "{{ area }}"
iterations: "{{ iterations }}"
target:
entity_id: script.queue_cleaning_specific_areas_of_the_home
enabled: true
- wait_template: |-
{{ is_state("vacuum.dreame_x40_ultra_complete", "cleaning")
or
is_state("sensor.dreame_x40_ultra_complete_dock_status",
["cleaning", "emptying"]) }}
continue_on_timeout: true
timeout: "00:00:30"
enabled: true
- alias: Abort if not cleaning
if:
- condition: template
value_template: |-
{{ not(
is_state("vacuum.dreame_x40_ultra_complete", "cleaning")
or
is_state("sensor.dreame_x40_ultra_complete_dock_status",
["cleaning", "emptying"])
) }}
then:
- action: logbook.log
metadata: {}
data:
entity_id: vacuum.dreame_x40_ultra_complete
name: Vacuum
message: failed to start after 30 seconds
- variables:
response:
error: The vacuum did not start
- stop: The vacuum did not start
response_variable: response
enabled: true
- variables:
action:
message: The vacuum has been instructed to {{ mode }} {{ area | join(", ") }}
- stop: The vacuum has been instructed to clean the designated areas.
response_variable: action
fields:
area:
selector:
select:
options:
- Foyer
- Office
- Master bedroom
- Baby bedroom
- Living room
- Kitchen
- Dining room
- Master bathroom
- Guest bathroom
- Reduit
- Entranceway
- Where the baby eats
- Under the table
multiple: true
required: true
mode:
selector:
select:
options:
- vacuum
- mop
- vacuum and mop
- vacuum then mop
multiple: false
name: Mode
default:
- vacuum
required: true
description: What kind of cleaning action to perform.
iterations:
selector:
number:
min: 1
max: 5
step: 1
name: Iterations
default: 1
required: true
description: How many times to clean the areas.
alias: Clean specific areas of the home
description: >-
This tool can vacuum or mop one or more areas of the home. Use the area
parameter (it accepts multiple values) to specify the area(s) that the user
requested to be cleaned — to clean the whole house just leave out the area
parameter. The mode parameter (one of `vacuum`, `mop`, `vacuum and mop`,
`vacuum then mop`) tells the vacuum what to do in what order — use whatever
the user requested; if the user merely requested to clean, use 'vacuum'.
mode: parallel
max: 5
If it's an LLM Script it can be called direct, P. The llm fills in the fields just as if you hit it from the action tab...
No trigger or intent required.
What op wants to do they have to do it like I Do with the zenos scripts. - the too complicated way. No the error is not trapped and sent you have to gate it, prevent the condition raise your own error, and send the result
That's what I was thinking because mode is limited to 4 in it's selector, where area is limited to 11 or whatever that number is.
All the LLM can see is the number of options (and their value) the selector allows. So the only way it'd produce that error is if the user is supplying more than what the selector provides.
The LLM does it just fine. If I tell it to vacuum both bedrooms, the kitchen, the foyer and the dining room, the LLM calls the tool impeccably, and the script starts with all five areas I told it to. I'm actually quite impressed that it works so reliably (90% of the time) — then again it's a 35 B parameter model on an RTX Pro. This works correctly whether I use Assist via text or voice (speech to text).
Then of course the script aborts (currently the code is set to abort without error and return the error message to the LLM, which makes the LLM handle the situation very well). I'd like the script to abort with error and have the LLM handle that (it does not — the LLM doesn't even see the error).
Intents are handy but are not the solution. To be clear, I'm trying to solve a recurring problem with quite a few of my scripts exposed to Assist — this isn't the only script of mine with the requirement of Assist handling stop: error True correctly — and I can't really be bothered with adding intents for each one of those scripts, then having to remember which key words to use to trigger them. I have like a dozen scripts that let me interact conversationally with Grocy, the media players, and many more things — all of them benefit from Assist properly handling script errors instead of ignoring them.
There's probably quite a few Home Assistant users who are using scripts exposed to Assist, and are completely unaware that their scripts are failing, because Assist simply doesn't report script errors back to the user. This is a bug and it should be fixed.
A further feature request: the select selector should gain a max_selections option that lets me limit how many selections I can make. But that's a separate issue.
Correct! That has happened in the past, and the vacuum simply didn't start; we came home to a dirty apartment, minutes before we had guests.
When I hit this condition (before I added error handling for the "too many areas" corner case) I did not use Assist to start the script — I used the app on my phone instead; the script did fail further down (at the step where the vacuum is awaited to begin cleaning), but *obviously, I did not see any error onscreen (remember: stop: error = False) so I incorrectly assumed the vacuum had started. Result: dirty home.
Which is precisely why I have added an error handling step coded into the script ({{ ... |length > 4 }}, telling the user "please yo do not select more than four areas".
Now if I could actually get both Assist and the app reacting usefully to any error handling step, that would be great.
No, you aren't understanding. The LLM is providing more items to the selector:
This is before your script even executes. Anything you put in the script isn't going to stop that from happening.
So your statements here:
Is not really correct. The LLM is doing something wrong. It's either providing it too many areas or it's providing your area list to the mode selector.