Move AI task prefs to system -> general (#25904)

Move AI task prefs
This commit is contained in:
Paulus Schoutsen 2025-06-25 01:27:09 -04:00 committed by GitHub
parent 3aafa47f6d
commit 9afc4260c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 42 deletions

View File

@ -1,12 +1,12 @@
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
export interface AITaskPreferences { export interface AITaskPreferences {
gen_text_entity_id: string | null; gen_data_entity_id: string | null;
} }
export interface GenTextTaskResult { export interface GenDataTaskResult {
conversation_id: string; conversation_id: string;
text: string; data: string;
} }
export const fetchAITaskPreferences = (hass: HomeAssistant) => export const fetchAITaskPreferences = (hass: HomeAssistant) =>
@ -23,17 +23,17 @@ export const saveAITaskPreferences = (
...preferences, ...preferences,
}); });
export const generateTextAITask = async ( export const generateDataAITask = async (
hass: HomeAssistant, hass: HomeAssistant,
task: { task: {
task_name: string; task_name: string;
entity_id?: string; entity_id?: string;
instructions: string; instructions: string;
} }
): Promise<GenTextTaskResult> => { ): Promise<GenDataTaskResult> => {
const result = await hass.callService<GenTextTaskResult>( const result = await hass.callService<GenDataTaskResult>(
"ai_task", "ai_task",
"generate_text", "generate_data",
task, task,
undefined, undefined,
true, true,

View File

@ -27,7 +27,7 @@ import type {
import { supportsMarkdownHelper } from "../../../../common/translations/markdown_support"; import { supportsMarkdownHelper } from "../../../../common/translations/markdown_support";
import { import {
fetchAITaskPreferences, fetchAITaskPreferences,
generateTextAITask, generateDataAITask,
} from "../../../../data/ai_task"; } from "../../../../data/ai_task";
import { isComponentLoaded } from "../../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
@ -93,7 +93,7 @@ class DialogAutomationSave extends LitElement implements HassDialog {
super.firstUpdated(changedProperties); super.firstUpdated(changedProperties);
if (isComponentLoaded(this.hass, "ai_task")) { if (isComponentLoaded(this.hass, "ai_task")) {
fetchAITaskPreferences(this.hass).then((prefs) => { fetchAITaskPreferences(this.hass).then((prefs) => {
this._canSuggest = prefs.gen_text_entity_id !== null; this._canSuggest = prefs.gen_data_entity_id !== null;
}); });
} }
} }
@ -346,7 +346,7 @@ class DialogAutomationSave extends LitElement implements HassDialog {
} }
private async _suggest() { private async _suggest() {
const result = await generateTextAITask(this.hass, { const result = await generateDataAITask(this.hass, {
task_name: "frontend:automation:save", task_name: "frontend:automation:save",
instructions: `Suggest one name for the following Home Assistant automation. instructions: `Suggest one name for the following Home Assistant automation.
Your answer should only contain the name, without any additional text or formatting. Your answer should only contain the name, without any additional text or formatting.
@ -356,7 +356,7 @@ The name should be short, descriptive, sentence case, and written in the languag
${dump(this._params.config)} ${dump(this._params.config)}
`, `,
}); });
this._newName = result.text.trim(); this._newName = result.data.trim();
} }
private async _save(): Promise<void> { private async _save(): Promise<void> {

View File

@ -47,9 +47,7 @@ export class AITaskPref extends LitElement {
})} })}
crossorigin="anonymous" crossorigin="anonymous"
referrerpolicy="no-referrer" referrerpolicy="no-referrer"
/>${this.hass.localize( />${this.hass.localize("ui.panel.config.ai_task.header")}
"ui.panel.config.voice_assistants.ai_task.header"
)}
</h1> </h1>
<div class="header-actions"> <div class="header-actions">
<a <a
@ -68,30 +66,25 @@ export class AITaskPref extends LitElement {
</div> </div>
<div class="card-content"> <div class="card-content">
<p> <p>
${this.hass!.localize( ${this.hass!.localize("ui.panel.config.ai_task.description", {
"ui.panel.config.voice_assistants.ai_task.description", button: html`<ha-svg-icon
{ .path=${mdiStarFourPoints}
button: html`<ha-svg-icon ></ha-svg-icon>`,
.path=${mdiStarFourPoints} })}
></ha-svg-icon>`,
}
)}
</p> </p>
<ha-settings-row .narrow=${this.narrow}> <ha-settings-row .narrow=${this.narrow}>
<span slot="heading"> <span slot="heading">
${this.hass!.localize( ${this.hass!.localize("ui.panel.config.ai_task.gen_data_header")}
"ui.panel.config.voice_assistants.ai_task.gen_text_header"
)}
</span> </span>
<span slot="description"> <span slot="description">
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.config.voice_assistants.ai_task.gen_text_description" "ui.panel.config.ai_task.gen_data_description"
)} )}
</span> </span>
<ha-entity-picker <ha-entity-picker
data-name="gen_text_entity_id" data-name="gen_data_entity_id"
.hass=${this.hass} .hass=${this.hass}
.value=${this._prefs.gen_text_entity_id} .value=${this._prefs.gen_data_entity_id}
.includeDomains=${["ai_task"]} .includeDomains=${["ai_task"]}
@value-changed=${this._handlePrefChange} @value-changed=${this._handlePrefChange}
></ha-entity-picker> ></ha-entity-picker>
@ -119,6 +112,14 @@ export class AITaskPref extends LitElement {
} }
static styles = css` static styles = css`
.card-header {
display: flex;
align-items: center;
}
.card-header img {
max-width: 28px;
margin-right: 16px;
}
a { a {
color: var(--primary-color); color: var(--primary-color);
} }

View File

@ -25,8 +25,10 @@ import type { ConfigUpdateValues } from "../../../data/core";
import { saveCoreConfig } from "../../../data/core"; import { saveCoreConfig } from "../../../data/core";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/hass-subpage"; import "../../../layouts/hass-subpage";
import "./ai-task-pref";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import type { HomeAssistant, ValueChangedEvent } from "../../../types"; import type { HomeAssistant, ValueChangedEvent } from "../../../types";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
@customElement("ha-config-section-general") @customElement("ha-config-section-general")
class HaConfigSectionGeneral extends LitElement { class HaConfigSectionGeneral extends LitElement {
@ -265,6 +267,12 @@ class HaConfigSectionGeneral extends LitElement {
</ha-progress-button> </ha-progress-button>
</div> </div>
</ha-card> </ha-card>
${isComponentLoaded(this.hass, "ai_task")
? html`<ai-task-pref
.hass=${this.hass}
.narrow=${this.narrow}
></ai-task-pref>`
: nothing}
</div> </div>
</hass-subpage> </hass-subpage>
`; `;
@ -377,7 +385,8 @@ class HaConfigSectionGeneral extends LitElement {
max-width: 1040px; max-width: 1040px;
margin: 0 auto; margin: 0 auto;
} }
ha-card { ha-card,
ai-task-pref {
max-width: 600px; max-width: 600px;
margin: 0 auto; margin: 0 auto;
height: 100%; height: 100%;
@ -385,6 +394,9 @@ class HaConfigSectionGeneral extends LitElement {
flex-direction: column; flex-direction: column;
display: flex; display: flex;
} }
ha-card {
margin-bottom: 24px;
}
.card-content { .card-content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -8,7 +8,6 @@ import "../../../layouts/hass-loading-screen";
import "../../../layouts/hass-tabs-subpage"; import "../../../layouts/hass-tabs-subpage";
import type { HomeAssistant, Route } from "../../../types"; import type { HomeAssistant, Route } from "../../../types";
import "./assist-pref"; import "./assist-pref";
import "./ai-task-pref";
import "./cloud-alexa-pref"; import "./cloud-alexa-pref";
import "./cloud-discover"; import "./cloud-discover";
import "./cloud-google-pref"; import "./cloud-google-pref";
@ -54,12 +53,6 @@ export class HaConfigVoiceAssistantsAssistants extends LitElement {
></assist-pref> ></assist-pref>
` `
: nothing} : nothing}
${isComponentLoaded(this.hass, "ai_task")
? html`<ai-task-pref
.hass=${this.hass}
.narrow=${this.narrow}
></ai-task-pref>`
: nothing}
${this.cloudStatus?.logged_in ${this.cloudStatus?.logged_in
? html` ? html`
<cloud-alexa-pref <cloud-alexa-pref

View File

@ -2207,6 +2207,12 @@
"add_area": "Add area" "add_area": "Add area"
} }
}, },
"ai_task": {
"header": "AI suggestions",
"description": "Home Assistant can use generative AI to help you with tasks like writing automations, creating scripts, and more. Look for the button with the {button} icon throughout Home Assistant to get suggestions.",
"gen_data_header": "Data generation tasks",
"gen_data_description": "Suggest automation names or dashboards."
},
"category": { "category": {
"caption": "Categories", "caption": "Categories",
"assign": { "assign": {
@ -3442,12 +3448,6 @@
"sign_in": "Sign in" "sign_in": "Sign in"
} }
}, },
"ai_task": {
"header": "AI suggestions",
"description": "Home Assistant can use generative AI to help you with tasks like writing automations, creating scripts, and more. Look for the button with the {button} icon throughout Home Assistant to get suggestions.",
"gen_text_header": "Text generation tasks",
"gen_text_description": "Used to create summaries and names."
},
"debug": { "debug": {
"header": "Debug assistant", "header": "Debug assistant",
"no_runs_found": "No runs found", "no_runs_found": "No runs found",