fix: compose named cockpit modes from capabilities

This commit is contained in:
vee
2026-09-07 20:52:19 +08:00
parent cf9b89508c
commit 6b2b644ee6
23 changed files with 2917 additions and 124 deletions
+36 -15
View File
@@ -271,7 +271,7 @@
followLatest();
}
function appendModeCreatedState(message, profile) {
function appendModeCreatedState(message, profile, { updated = false } = {}) {
if (!message?.body || !profile?.id) return;
const selector = `[data-assistant-mode-created="${CSS.escape(String(profile.id))}"]`;
if ($(selector, message.body)) return;
@@ -286,7 +286,7 @@
const copy = document.createElement("span");
copy.className = "assistant-mode-created-copy";
const label = document.createElement("small");
label.textContent = "已添加到「我的模式」";
label.textContent = updated ? "已更新「我的模式」" : "已添加到「我的模式」";
const name = document.createElement("strong");
name.textContent = String(profile.name || "新功能模式");
copy.append(label, name);
@@ -396,9 +396,16 @@
icon = "panels-top-left";
order = instructionOrder("车窗");
} else if (domain === "seat") {
label = ["passenger", "front_right"].includes(zone) ? "副驾座椅" : "主驾座椅";
const seatLabel = ["passenger", "front_right"].includes(zone) ? "副驾" : "主驾";
const seatCapabilityLabels = {
"seat.set_longitudinal_position": "座椅前后位置",
"seat.set_cushion_tilt": "坐垫角度",
"seat.set_backrest_recline": "靠背角度",
"seat.set_legrest_height": "腿托高度",
};
label = `${seatLabel}${seatCapabilityLabels[capability] || "座椅"}`;
value = params.position_pct != null
? `${params.position_pct}%`
? `${params.position_pct}%${params.angle_deg != null ? `(${params.angle_deg}°)` : ""}`
: motionLabel(params.state || params.mode_id);
icon = "armchair";
order = instructionOrder("座椅", "副驾", "主驾");
@@ -408,8 +415,12 @@
icon = "thermometer";
order = instructionOrder("空调", "温度");
} else if (domain === "climate") {
label = "空调";
value = params.level != null ? `${params.level}档` : motionLabel(params.state);
const cycleLabels = { internal: "内循环", external: "外循环", auto: "自动循环" };
label = capability === "climate.set_fan_level" ? "空调风量"
: capability === "climate.set_cycle_mode" ? "空调循环" : "空调";
value = params.level != null ? `${params.level}档`
: params.mode != null ? (cycleLabels[String(params.mode)] || String(params.mode))
: motionLabel(params.state);
icon = "fan";
order = instructionOrder("空调", "风量");
} else if (capability === "interior_light.set_reading_power") {
@@ -433,9 +444,15 @@
card.classList.add("is-busy");
status.hidden = false;
status.className = "assistant-mode-draft-status working";
status.textContent = "正在保存到「我的模式」…";
const existingModeId = String(draft.existing_mode_id || "").trim();
status.textContent = existingModeId
? "正在将验证结果保存为模式更新…"
: "正在保存到「我的模式」…";
try {
const response = await window.CognitiveAgentNetwork.request("/api/mode-profiles", {
const endpoint = existingModeId
? `/api/mode-profiles/${encodeURIComponent(existingModeId)}`
: "/api/mode-profiles";
const response = await window.CognitiveAgentNetwork.request(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -456,10 +473,10 @@
card.classList.remove("is-busy");
card.classList.add("is-saved");
status.className = "assistant-mode-draft-status success";
status.textContent = "模式已保存";
status.textContent = existingModeId ? "模式已更新" : "模式已保存";
card.querySelector(".assistant-mode-draft-actions")?.setAttribute("hidden", "");
await window.CognitiveAgentConsole?.refreshModeProfiles?.(payload.mode_profile?.id);
appendModeCreatedState(message, payload.mode_profile);
appendModeCreatedState(message, payload.mode_profile, { updated: Boolean(existingModeId) });
persistMessages();
} catch (error) {
card.classList.remove("is-busy");
@@ -469,14 +486,14 @@
}
}
async function tryModeProfileDraft(card, draft, buttons, status) {
async function tryModeProfileDraft(card, draft, actions, buttons, status) {
buttons.forEach((button) => { button.disabled = true; });
card.classList.add("is-busy");
status.hidden = false;
status.className = "assistant-mode-draft-status working";
status.textContent = "正在进行模拟试运行…";
try {
const result = await window.CognitiveAgentConsole?.tryModeDraft?.(draft);
const result = await window.CognitiveAgentConsole?.tryModeDraft?.({ ...draft, actions });
if (!result || result.status !== "succeeded") throw new Error("试运行未通过,请检查动作设置。");
status.className = "assistant-mode-draft-status success";
status.textContent = "试运行通过 · 尚未保存";
@@ -501,7 +518,9 @@
const heading = document.createElement("header");
const headingCopy = document.createElement("span");
const eyebrow = document.createElement("small");
eyebrow.textContent = "已为你生成功能模式";
eyebrow.textContent = draft.existing_mode_id
? "已载入现有功能模式"
: "已为你生成功能模式";
const title = document.createElement("strong");
title.textContent = `「${draft.name}」`;
headingCopy.append(eyebrow, title);
@@ -530,7 +549,9 @@
const save = document.createElement("button");
save.type = "button";
save.className = "assistant-mode-draft-save";
save.innerHTML = '<i data-lucide="bookmark-plus"></i><span>保存为功能模式</span>';
save.innerHTML = draft.existing_mode_id
? '<i data-lucide="refresh-cw"></i><span>确认更新此模式</span>'
: '<i data-lucide="bookmark-plus"></i><span>保存为功能模式</span>';
const trial = document.createElement("button");
trial.type = "button";
trial.className = "assistant-mode-draft-trial";
@@ -545,7 +566,7 @@
void saveModeProfileDraft(message, card, draft, buttons, status);
});
trial.addEventListener("click", () => {
void tryModeProfileDraft(card, draft, buttons, status);
void tryModeProfileDraft(card, draft, actions, buttons, status);
});
card.append(heading, list, controls, status);