Add AI Task to suggest automation name
parent
67c7a3931f
commit
ac2476babd
|
@ -0,0 +1,39 @@
|
||||||
|
import type { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
export interface AITaskPreferences {
|
||||||
|
gen_text_summary_entity_id: string | null;
|
||||||
|
gen_text_generate_entity_id: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GenTextTaskResult {
|
||||||
|
conversation_id: string;
|
||||||
|
result: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchAITaskPreferences = (hass: HomeAssistant) =>
|
||||||
|
hass.callWS<AITaskPreferences>({
|
||||||
|
type: "ai_task/preferences/get",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const saveAITaskPreferences = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
preferences: Partial<AITaskPreferences>
|
||||||
|
) =>
|
||||||
|
hass.callWS<AITaskPreferences>({
|
||||||
|
type: "ai_task/preferences/set",
|
||||||
|
...preferences,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const generateTextAITask = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
task: {
|
||||||
|
task_name: string;
|
||||||
|
entity_id?: string;
|
||||||
|
task_type: "summary" | "generate";
|
||||||
|
prompt: string;
|
||||||
|
}
|
||||||
|
) =>
|
||||||
|
hass.callWS<GenTextTaskResult>({
|
||||||
|
type: "ai_task/generate_text",
|
||||||
|
...task,
|
||||||
|
});
|
|
@ -1,8 +1,9 @@
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import type { CSSResultGroup } from "lit";
|
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { mdiClose, mdiPlus } from "@mdi/js";
|
import { mdiClose, mdiPlus, mdiStarFourPoints } from "@mdi/js";
|
||||||
|
import { dump } from "js-yaml";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-alert";
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-domain-icon";
|
import "../../../../components/ha-domain-icon";
|
||||||
|
@ -24,6 +25,11 @@ import type {
|
||||||
SaveDialogParams,
|
SaveDialogParams,
|
||||||
} from "./show-dialog-automation-save";
|
} from "./show-dialog-automation-save";
|
||||||
import { supportsMarkdownHelper } from "../../../../common/translations/markdown_support";
|
import { supportsMarkdownHelper } from "../../../../common/translations/markdown_support";
|
||||||
|
import {
|
||||||
|
fetchAITaskPreferences,
|
||||||
|
generateTextAITask,
|
||||||
|
} from "../../../../data/ai_task";
|
||||||
|
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
|
||||||
|
|
||||||
@customElement("ha-dialog-automation-save")
|
@customElement("ha-dialog-automation-save")
|
||||||
class DialogAutomationSave extends LitElement implements HassDialog {
|
class DialogAutomationSave extends LitElement implements HassDialog {
|
||||||
|
@ -37,6 +43,8 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
||||||
|
|
||||||
@state() private _entryUpdates!: EntityRegistryUpdate;
|
@state() private _entryUpdates!: EntityRegistryUpdate;
|
||||||
|
|
||||||
|
@state() private _canSuggest = false;
|
||||||
|
|
||||||
private _params!: SaveDialogParams;
|
private _params!: SaveDialogParams;
|
||||||
|
|
||||||
private _newName?: string;
|
private _newName?: string;
|
||||||
|
@ -81,6 +89,15 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProperties: PropertyValues): void {
|
||||||
|
super.firstUpdated(changedProperties);
|
||||||
|
if (isComponentLoaded(this.hass, "ai_task")) {
|
||||||
|
fetchAITaskPreferences(this.hass).then((prefs) => {
|
||||||
|
this._canSuggest = prefs.gen_text_summary_entity_id !== null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected _renderOptionalChip(id: string, label: string) {
|
protected _renderOptionalChip(id: string, label: string) {
|
||||||
if (this._visibleOptionals.includes(id)) {
|
if (this._visibleOptionals.includes(id)) {
|
||||||
return nothing;
|
return nothing;
|
||||||
|
@ -250,6 +267,16 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
||||||
.path=${mdiClose}
|
.path=${mdiClose}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<span slot="title">${this._params.title || title}</span>
|
<span slot="title">${this._params.title || title}</span>
|
||||||
|
${this._canSuggest
|
||||||
|
? html`
|
||||||
|
<ha-icon-button
|
||||||
|
slot="actionItems"
|
||||||
|
.label=${this.hass.localize("ui.common.suggest_ai")}
|
||||||
|
.path=${mdiStarFourPoints}
|
||||||
|
@click=${this._suggest}
|
||||||
|
></ha-icon-button>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
</ha-dialog-header>
|
</ha-dialog-header>
|
||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alert-type="error"
|
? html`<ha-alert alert-type="error"
|
||||||
|
@ -313,6 +340,20 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _suggest() {
|
||||||
|
const result = await generateTextAITask(this.hass, {
|
||||||
|
task_name: "frontend:automation:save",
|
||||||
|
task_type: "summary",
|
||||||
|
prompt: `Give me a name for the following Home Assistant automation.
|
||||||
|
The name should be short, descriptive, and written in the language ${this.hass.language}.
|
||||||
|
|
||||||
|
${dump(this._params.config)}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
this._newName = result.result.trim();
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
private async _save(): Promise<void> {
|
private async _save(): Promise<void> {
|
||||||
if (!this._newName) {
|
if (!this._newName) {
|
||||||
this._error = "Name is required";
|
this._error = "Name is required";
|
||||||
|
|
|
@ -380,7 +380,8 @@
|
||||||
"replace": "Replace",
|
"replace": "Replace",
|
||||||
"append": "Append",
|
"append": "Append",
|
||||||
"supports_markdown": "Supports {markdown_help_link}",
|
"supports_markdown": "Supports {markdown_help_link}",
|
||||||
"markdown": "Markdown"
|
"markdown": "Markdown",
|
||||||
|
"suggest_ai": "Suggest with AI"
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"selectors": {
|
"selectors": {
|
||||||
|
|
Loading…
Reference in New Issue