(function () { "use strict"; const pageDefinitions = [ { index: 0, label: "整车联合数字孪生", shortLabel: "数字孪生", target: ".joint-twin-shell" }, { index: 1, label: "决策轨迹与校验", shortLabel: "决策校验", target: "#panel-trace" }, { index: 2, label: "指令配置与硬件映射", shortLabel: "配置映射", target: "#panel-config" }, { index: 3, label: "CAN 编译计划", shortLabel: "CAN 计划", target: "#panel-plan" }, { index: 4, label: "执行结果与硬件回读", shortLabel: "执行回读", target: "#panel-result" }, ]; const $ = (selector, root = document) => root.querySelector(selector); const $$ = (selector, root = document) => [...root.querySelectorAll(selector)]; const initialRole = sessionStorage.getItem("cognitive-agent.demo-role") === "admin" ? "admin" : "user"; const storedModule = sessionStorage.getItem("cognitive-agent.active-module"); const ui = { role: initialRole, controlMode: sessionStorage.getItem("cognitive-agent.control-mode") === "gesture" ? "gesture" : "natural", activeModule: storedModule === "self-evolution" ? "self-evolution" : storedModule === "self-extension" ? "self-extension" : storedModule === "self-calibration" ? "self-calibration" : storedModule === "self-repair" ? "self-repair" : "self-orchestration", activePage: 0, sidebarCollapsed: sessionStorage.getItem("cognitive-agent.sidebar-collapsed") === "true", }; const dropdownControls = new Map(); let reasoningPickerControl = null; function make(tag, className, html) { const node = document.createElement(tag); if (className) node.className = className; if (html != null) node.innerHTML = html; return node; } function closeCustomDropdowns(except = null) { dropdownControls.forEach((control) => { if (control !== except) control.close(); }); } function closeReasoningPicker() { reasoningPickerControl?.close(); } function installReasoningPicker(reasoningField, originalForm) { const composer = $(".command-composer", originalForm); if (!composer || !reasoningField) return; reasoningField.classList.add("v2-reasoning-field"); reasoningField.hidden = true; const trigger = make("button", "v2-reasoning-trigger", ` 模型智能 均衡 `); trigger.id = "v2ReasoningTrigger"; trigger.type = "button"; trigger.setAttribute("aria-haspopup", "listbox"); trigger.setAttribute("aria-expanded", "false"); trigger.setAttribute("aria-controls", "reasoningField"); trigger.setAttribute("aria-label", "选择模型智能程度,当前均衡"); $(".reasoning-segmented", reasoningField)?.setAttribute("role", "listbox"); const options = () => $$('[data-reasoning-effort]', reasoningField); const place = () => { if (reasoningField.hidden) return; const triggerBox = trigger.getBoundingClientRect(); const width = Math.min(320, Math.max(250, window.innerWidth - 24)); const left = Math.min( Math.max(12, triggerBox.left), Math.max(12, window.innerWidth - width - 12), ); reasoningField.style.width = `${width}px`; reasoningField.style.left = `${left}px`; const height = reasoningField.offsetHeight; const above = triggerBox.top - height - 8; const top = above >= 12 ? above : Math.min(triggerBox.bottom + 8, window.innerHeight - height - 12); reasoningField.style.top = `${Math.max(12, top)}px`; }; const sync = () => { const selected = options().find((button) => button.classList.contains("active")); const label = selected?.querySelector("strong")?.textContent?.trim() || "均衡"; const unavailable = options().length > 0 && options().every((button) => button.disabled); $("#v2ReasoningValue", trigger).textContent = label; trigger.classList.toggle("unavailable", unavailable); trigger.setAttribute("aria-disabled", String(unavailable)); trigger.setAttribute("aria-label", `选择模型智能程度,当前${label}`); options().forEach((button) => { button.setAttribute("role", "option"); button.setAttribute("aria-selected", String(button === selected)); }); }; const close = () => { reasoningField.hidden = true; trigger.classList.remove("open"); trigger.setAttribute("aria-expanded", "false"); }; const open = () => { closeCustomDropdowns(); reasoningField.hidden = false; trigger.classList.add("open"); trigger.setAttribute("aria-expanded", "true"); place(); }; reasoningPickerControl = { close, open, place, sync, trigger }; composer.append(trigger); document.body.append(reasoningField); trigger.addEventListener("click", (event) => { event.stopPropagation(); if (reasoningField.hidden) open(); else close(); }); reasoningField.addEventListener("click", (event) => { event.stopPropagation(); if (!event.target.closest("[data-reasoning-effort]")) return; requestAnimationFrame(() => { sync(); close(); trigger.focus({ preventScroll: true }); }); }); new MutationObserver(sync).observe(reasoningField, { attributes: true, attributeFilter: ["class", "disabled"], subtree: true, }); window.addEventListener("resize", place); sync(); } function enhanceSelect(select) { if (!select || dropdownControls.has(select)) return; const shell = select.parentElement; if (!shell) return; shell.classList.add("v2-custom-select"); select.classList.add("v2-native-select"); const trigger = make("button", "v2-dropdown-trigger", ` `); trigger.type = "button"; trigger.setAttribute("aria-haspopup", "listbox"); trigger.setAttribute("aria-expanded", "false"); trigger.setAttribute("aria-label", select.getAttribute("aria-label") || "打开下拉菜单"); const menu = make("div", "v2-dropdown-menu", ""); menu.id = `${select.id}Menu`; menu.hidden = true; menu.setAttribute("role", "listbox"); menu.setAttribute("aria-label", select.getAttribute("aria-label") || "选项"); trigger.setAttribute("aria-controls", menu.id); shell.append(trigger, menu); const valueNode = $(".v2-dropdown-value", trigger); const render = () => { const selected = select.selectedOptions[0] || select.options[0]; valueNode.textContent = selected?.textContent?.trim() || "请选择"; trigger.disabled = select.disabled; menu.innerHTML = ""; [...select.options].forEach((option) => { const item = make("button", "v2-dropdown-option", ""); item.type = "button"; item.dataset.value = option.value; item.textContent = option.textContent.trim(); item.disabled = option.disabled; item.setAttribute("role", "option"); item.setAttribute("aria-selected", String(option.value === select.value)); menu.append(item); }); }; const close = () => { menu.hidden = true; shell.classList.remove("v2-dropdown-open"); trigger.setAttribute("aria-expanded", "false"); }; const open = () => { if (trigger.disabled) return; closeCustomDropdowns(); render(); menu.hidden = false; shell.classList.add("v2-dropdown-open"); trigger.setAttribute("aria-expanded", "true"); }; const control = { close, menu, open, select, shell, sync: render, trigger }; dropdownControls.set(select, control); trigger.addEventListener("click", (event) => { event.stopPropagation(); if (menu.hidden) open(); else close(); }); trigger.addEventListener("keydown", (event) => { if (event.key === "ArrowDown") { event.preventDefault(); open(); requestAnimationFrame(() => { $(".v2-dropdown-option[aria-selected=\"true\"]:not(:disabled)", menu)?.focus(); }); } else if (event.key === "Escape") { close(); } }); menu.addEventListener("click", (event) => { event.stopPropagation(); const item = event.target.closest(".v2-dropdown-option"); if (!item || item.disabled) return; select.value = item.dataset.value; select.dispatchEvent(new Event("change", { bubbles: true })); render(); close(); trigger.focus(); }); menu.addEventListener("keydown", (event) => { if (event.key !== "Escape") return; event.preventDefault(); close(); trigger.focus(); }); select.addEventListener("change", render); new MutationObserver(render).observe(select, { attributes: true, characterData: true, childList: true, subtree: true, }); render(); } function enhanceConfiguredDropdowns() { [$("#v2RoleSelect"), $("#vehicleSelect"), $("#v2ExecutionSelect")] .filter(Boolean) .forEach(enhanceSelect); } function buildSidebar(commandPanel) { commandPanel.classList.add("v2-sidebar"); commandPanel.innerHTML = ""; const profile = make("section", "v2-profile", `
WELCOME TO THE CABIN
Hi,
Hi,user
`); const control = make("section", "v2-sidebar-section v2-control-section", `
CONTROL DESK

控制台

控制方式
`); const config = make("section", "v2-sidebar-section v2-config-section", `
配置信息
`); const footer = make("footer", "v2-sidebar-footer", `
智舱控制链路正在连接服务
`); commandPanel.append(profile, control, config, footer); $("#v2RoleSelect").value = ui.role; return $("#v2ConfigStack"); } function buildConfigFields(configStack, originalForm) { const vehicleField = $(".vehicle-field", originalForm); const providerField = $(".field-group:has(.segmented [data-provider])", originalForm); const reasoningField = $("#reasoningField", originalForm); const executionField = $(".field-group:has(.execution-mode-options)", originalForm); const simulationFaultField = $("#simulationFaultField", originalForm); if (vehicleField) { vehicleField.classList.add("v2-config-field", "v2-vehicle-field"); const vehicleControl = $(".vehicle-select-control", vehicleField); const vehicleSelect = $("#vehicleSelect", vehicleField); const vehicleIcon = $("svg, [data-lucide]", vehicleControl); if (vehicleControl && vehicleSelect && vehicleIcon) { const copy = make("div", "v2-config-card-copy", "车型配置"); const selectSlot = make("div", "v2-config-card-select", ""); const state = make("span", "v2-field-state", "CHECK"); state.id = "v2VehicleState"; selectSlot.append(vehicleSelect); copy.append(selectSlot); vehicleControl.classList.add("v2-config-card", "v2-config-select-card"); vehicleControl.id = "v2VehicleCard"; vehicleControl.dataset.state = "checking"; vehicleControl.replaceChildren(vehicleIcon, copy, state); $(".field-label", vehicleField)?.remove(); } configStack.append(vehicleField); } const modelField = make("div", "v2-config-field v2-config-card v2-model-field", `
推理模型模型检测中
AUTO

模型由服务端安全配置

`); modelField.id = "v2ModelField"; configStack.append(modelField); installReasoningPicker(reasoningField, originalForm); const gestureModelField = make("div", "v2-config-field v2-config-card v2-gesture-model-field", `
手势模型MediaPipe GR
VISION Tasks Vision · 0.10.14`); gestureModelField.id = "v2GestureModelField"; configStack.append(gestureModelField); const userHardwareState = make("div", "v2-user-target-status", ` 正在准备虚拟 CAN`); configStack.append(userHardwareState); if (providerField) { providerField.classList.add("v2-provider-field"); providerField.hidden = true; configStack.append(providerField); } const executionSelect = make("div", "v2-config-field v2-execution-field", `
执行目标
ADMIN

管理员可切换执行环境

`); configStack.append(executionSelect); if (executionField) { executionField.classList.add("v2-native-execution-field"); executionField.hidden = true; configStack.append(executionField); } const advanced = make("div", "v2-advanced-stack", ""); [simulationFaultField].forEach((field) => { if (!field) return; field.classList.add("v2-config-field", "v2-advanced-field"); advanced.append(field); }); configStack.append(advanced); } function buildOperation(mainPanel, originalForm, panelHeading, modeRail, requestHeader, gestureDrawer) { const operation = make("section", "v2-operation-shell", `
`); mainPanel.prepend(operation); const naturalPanel = $("#v2NaturalPanel"); if (panelHeading) { panelHeading.classList.add("v2-operation-heading", "v2-module-heading"); const kicker = $(".section-kicker", panelHeading); const title = $("h2", panelHeading); const intro = $(".panel-intro", panelHeading); if (kicker) kicker.textContent = "SELF-ORCHESTRATION"; if (title) title.textContent = "一句话,调好整车"; if (intro) intro.textContent = "座椅、空调、天幕与氛围灯,一句话联动完成"; naturalPanel.append(panelHeading); } const naturalGrid = make("div", "v2-natural-grid", ""); naturalGrid.id = "v2NaturalGrid"; originalForm.classList.add("v2-request-form"); naturalGrid.append(originalForm); if (requestHeader) { requestHeader.classList.add("v2-request-status"); naturalGrid.append(requestHeader); } naturalPanel.append(naturalGrid); if (modeRail) { modeRail.classList.add("v2-mode-rail"); naturalPanel.append(modeRail); } const gesturePanel = $("#v2GesturePanel"); const gestureHeading = make("header", "v2-operation-heading v2-module-heading v2-gesture-operation-heading", ` SELF-ORCHESTRATION

抬抬手,控制整车

通过摄像头识别手势,直观控制车舱功能

`); gesturePanel.append(gestureHeading); if (gestureDrawer) { gestureDrawer.classList.add("v2-inline-gesture"); const cameraStage = $(".gesture-camera-stage", gestureDrawer); const cameraToggle = $("#gestureStartButton", gestureDrawer); const debugToggle = $("#gestureArmButton", gestureDrawer); const actionRail = $(".gesture-actions", gestureDrawer); const statusStrip = $(".gesture-status-strip", gestureDrawer); const gestureNow = $(".gesture-now", gestureDrawer); const guideCard = $(".gesture-guide-card", gestureDrawer); if (cameraToggle) { cameraToggle.classList.add("v2-camera-toggle"); cameraToggle.setAttribute("aria-label", "开启摄像头"); cameraToggle.setAttribute("title", "开启摄像头"); } if (actionRail && cameraToggle && debugToggle) { actionRail.classList.add("v2-gesture-action-rail"); actionRail.insertBefore(debugToggle, cameraToggle); actionRail.append(cameraToggle); } const resultStack = make("div", "v2-gesture-result-stack", ""); resultStack.id = "v2GestureResultStack"; const recognitionCard = make("section", "v2-gesture-recognition-card", ` 手势识别结果`); const executionSlot = make("section", "v2-gesture-execution-slot", ` 执行结果`); executionSlot.id = "v2GestureExecutionSlot"; if (statusStrip) recognitionCard.append(statusStrip); if (gestureNow) recognitionCard.append(gestureNow); resultStack.append(recognitionCard, executionSlot); if (cameraStage) gestureDrawer.append(cameraStage); if (actionRail) gestureDrawer.append(actionRail); gestureDrawer.append(resultStack); if (guideCard) gestureDrawer.append(guideCard); gesturePanel.append(gestureDrawer); } return operation; } function buildModuleSwitcher(mainPanel) { const modules = [ { id: "self-calibration", label: "自标定", available: true, adminOnly: true, }, { id: "self-orchestration", label: "自编排", available: true }, { id: "self-extension", label: "自扩展", available: true }, { id: "self-repair", label: "自修复", available: true, adminOnly: true, }, { id: "self-evolution", label: "自进化", available: true }, ]; const switcher = make("nav", "v2-module-switcher", ""); switcher.id = "v2ModuleSwitcher"; switcher.setAttribute("role", "tablist"); switcher.setAttribute("aria-label", "能力模块切换"); modules.forEach((module, index) => { const button = make("button", "v2-module-tab", `${module.label}`); button.type = "button"; button.id = `v2ModuleTab${index}`; button.dataset.module = module.id; button.setAttribute("role", "tab"); button.setAttribute("aria-selected", "false"); if (module.adminOnly) button.dataset.adminOnly = "true"; if (!module.available) { button.disabled = true; button.setAttribute("aria-disabled", "true"); button.title = module.adminOnly ? `${module.label}仅对 admin 开放` : `${module.label}模块待接入`; } switcher.append(button); }); mainPanel.prepend(switcher); } function buildOutput(mainPanel) { const output = make("section", "v2-output-shell", `
00
INFORMATION OUTPUT

整车联合数字孪生

LIVE STATE
`); mainPanel.append(output); const content = $("#v2OutputContent"); const twin = $(".joint-twin-shell", mainPanel); const resultWorkspace = $(".result-workspace", mainPanel); if (twin) content.append(twin); if (resultWorkspace) content.append(resultWorkspace); pageDefinitions.forEach((page) => { const target = $(page.target, content); if (!target) return; target.dataset.v2Page = String(page.index); target.classList.add("v2-output-page"); }); pageDefinitions.forEach((page) => { const button = make("button", "v2-page-button", ` ${String(page.index).padStart(2, "0")} ${page.shortLabel}`); button.type = "button"; button.dataset.v2PageTarget = String(page.index); button.setAttribute("aria-label", `${String(page.index).padStart(2, "0")} ${page.label}`); $("#v2PageRail").append(button); }); } function setPage(pageIndex) { const maxPage = ui.role === "admin" ? pageDefinitions.length - 1 : 0; ui.activePage = Math.max(0, Math.min(Number(pageIndex) || 0, maxPage)); const definition = pageDefinitions[ui.activePage]; $(".v2-output-shell")?.classList.toggle("v2-twin-active", definition.index === 0); $$(".v2-output-page").forEach((page) => { const active = Number(page.dataset.v2Page) === ui.activePage; page.classList.toggle("v2-active-output", active); page.setAttribute("aria-hidden", active ? "false" : "true"); }); $$(".v2-page-button").forEach((button) => { const active = Number(button.dataset.v2PageTarget) === ui.activePage; button.classList.toggle("active", active); button.setAttribute("aria-current", active ? "page" : "false"); }); $("#v2PageIndex").textContent = String(definition.index).padStart(2, "0"); $("#v2PageTitle").textContent = definition.label; $("#v2OutputState").textContent = definition.index === 0 ? "LIVE STATE" : "AUDIT VIEW"; requestAnimationFrame(updateScrollCues); } function updateScrollCues() { $$(".result-workspace .tab-panel").forEach((panel) => { const active = panel.classList.contains("v2-active-output"); panel.classList.toggle( "v2-scrollable", active && panel.scrollHeight > panel.clientHeight + 6, ); }); } function updateModeEdgeHints() { const chips = $(".v2-mode-rail .mode-chips"); if (!chips) return; const buttons = $$('button', chips); buttons.forEach((button) => { button.classList.remove("v2-edge-fade-left", "v2-edge-fade-right"); button.style.removeProperty("--v2-edge-fade-start"); button.style.removeProperty("--v2-edge-fade-end"); }); if (buttons.length < 2 || chips.clientWidth <= 0) return; const viewport = chips.getBoundingClientRect(); const visible = buttons.map((button) => ({ button, rect: button.getBoundingClientRect(), })).filter(({ rect }) => { return rect.right > viewport.left + 1 && rect.left < viewport.right - 1; }); if (!visible.length) return; const fadeSpan = 30; const firstVisible = visible[0]; const lastVisible = visible[visible.length - 1]; if (firstVisible.rect.left < viewport.left - 1) { const clippedAt = Math.min(100, Math.max( 0, ((viewport.left - firstVisible.rect.left) / firstVisible.rect.width) * 100, )); firstVisible.button.style.setProperty("--v2-edge-fade-start", `${clippedAt}%`); firstVisible.button.style.setProperty( "--v2-edge-fade-end", `${Math.min(100, clippedAt + fadeSpan)}%`, ); firstVisible.button.classList.add("v2-edge-fade-left"); } if (lastVisible.rect.right > viewport.right + 1) { const clippedAt = Math.min(100, Math.max( 0, ((viewport.right - lastVisible.rect.left) / lastVisible.rect.width) * 100, )); lastVisible.button.style.setProperty( "--v2-edge-fade-start", `${Math.max(0, clippedAt - fadeSpan)}%`, ); lastVisible.button.style.setProperty("--v2-edge-fade-end", `${clippedAt}%`); lastVisible.button.classList.add("v2-edge-fade-right"); } } function setControlMode(mode, { triggerGesture = true } = {}) { ui.controlMode = mode === "gesture" ? "gesture" : "natural"; sessionStorage.setItem("cognitive-agent.control-mode", ui.controlMode); document.body.dataset.controlMode = ui.controlMode; const requestStatus = $(".v2-request-status"); const statusTarget = ui.controlMode === "gesture" ? $("#v2GestureExecutionSlot") : $("#v2NaturalGrid"); if (requestStatus && statusTarget && requestStatus.parentElement !== statusTarget) { statusTarget.append(requestStatus); } $$('[data-v2-control]').forEach((button) => { const active = button.dataset.v2Control === ui.controlMode; button.classList.toggle("active", active); button.setAttribute("aria-pressed", String(active)); }); requestAnimationFrame(updateModeEdgeHints); const drawer = $("#gestureDrawer"); if (!triggerGesture) { const gestureVisible = ui.controlMode === "gesture"; drawer?.setAttribute("aria-hidden", String(!gestureVisible)); $("#gestureToggleButton")?.setAttribute("aria-expanded", String(gestureVisible)); return; } if (ui.controlMode === "gesture") { if (!drawer?.classList.contains("open")) $("#gestureToggleButton")?.click(); } else if (drawer?.classList.contains("open")) { $("#gestureCloseButton")?.click(); } } function syncSidebarControlForModule(evolutionView = window.CognitiveAgentSelfEvolution?.getView?.()) { const evolutionMode = ui.activeModule === "self-evolution"; const caption = $(".v2-control-section > .v2-field-caption"); if (caption) caption.textContent = evolutionMode ? "进化视图" : "控制方式"; const definitions = evolutionMode ? [ { label: "座椅称重进化", icon: "scale", active: evolutionView !== "system" }, { label: "系统能力日志", icon: "scroll-text", active: evolutionView === "system" }, ] : [ { label: "自然语言控制", icon: "message-square-text", active: ui.controlMode === "natural" }, { label: "手势控制", icon: "scan-face", active: ui.controlMode === "gesture" }, ]; $$('[data-v2-control]').forEach((button, index) => { const definition = definitions[index]; if (!definition) return; const label = $("span", button); const icon = $("svg, i", button); if (label) label.textContent = definition.label; if (icon) icon.setAttribute("data-lucide", definition.icon); button.classList.toggle("active", definition.active); button.setAttribute("aria-pressed", String(definition.active)); }); const switcher = $(".v2-control-switch"); switcher?.setAttribute("aria-label", evolutionMode ? "自进化视图" : "控制方式"); window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } }); } function setModule(module, { persist = true } = {}) { if (["self-calibration", "self-repair"].includes(module) && ui.role !== "admin") { setRole("admin", { allowModuleTransition: true }); } const allowed = new Set(["self-orchestration", "self-extension", "self-evolution"]); if (ui.role === "admin") { allowed.add("self-calibration"); allowed.add("self-repair"); } ui.activeModule = allowed.has(module) ? module : "self-orchestration"; if (ui.activeModule === "self-extension" && ui.role !== "user") { setRole("user"); } if (persist) { sessionStorage.setItem("cognitive-agent.active-module", ui.activeModule); } document.body.dataset.module = ui.activeModule; const roleSelect = $("#v2RoleSelect"); if (roleSelect) { roleSelect.disabled = ui.activeModule === "self-repair"; dropdownControls.get(roleSelect)?.sync(); } $$('.v2-module-tab').forEach((button) => { const active = button.dataset.module === ui.activeModule; button.classList.toggle("active", active); button.setAttribute("aria-selected", String(active)); button.tabIndex = active ? 0 : -1; }); if (["self-extension", "self-calibration", "self-repair", "self-evolution"].includes(ui.activeModule)) { const drawer = $("#gestureDrawer"); if (drawer?.classList.contains("open")) $("#gestureCloseButton")?.click(); } else { setControlMode(ui.controlMode, { triggerGesture: false }); } syncSidebarControlForModule(); window.dispatchEvent(new CustomEvent("cognitive-agent:module-change", { detail: { module: ui.activeModule }, })); window.setTimeout(() => window.dispatchEvent(new Event("resize")), 120); } function setRole(role, { allowModuleTransition = false } = {}) { if (ui.activeModule === "self-extension" && role !== "user" && !allowModuleTransition) { role = "user"; } if (ui.activeModule === "self-repair" && role !== "admin") { const roleSelect = $("#v2RoleSelect"); if (roleSelect) { roleSelect.value = "admin"; dropdownControls.get(roleSelect)?.sync(); } return; } ui.role = role === "admin" ? "admin" : "user"; sessionStorage.setItem("cognitive-agent.demo-role", ui.role); document.body.dataset.demoRole = ui.role; window.dispatchEvent(new CustomEvent("cognitive-agent:demo-role-change", { detail: { role: ui.role }, })); $("#v2RoleSelect").value = ui.role; dropdownControls.get($("#v2RoleSelect"))?.sync(); $("#v2PageRail").hidden = ui.role !== "admin"; const calibrationTab = $('.v2-module-tab[data-module="self-calibration"]'); if (calibrationTab) { calibrationTab.disabled = false; calibrationTab.setAttribute("aria-disabled", "false"); calibrationTab.title = ui.role === "admin" ? "" : "进入自标定时将自动切换为 admin"; } const repairTab = $('.v2-module-tab[data-module="self-repair"]'); if (repairTab) { repairTab.hidden = false; repairTab.disabled = false; repairTab.setAttribute("aria-disabled", "false"); repairTab.title = ui.role === "admin" ? "" : "进入自修复时将自动切换为 admin"; } if (ui.role !== "admin") { if (["self-calibration", "self-repair"].includes(ui.activeModule)) { setModule("self-orchestration"); } setPage(0); requestUserSafeExecutionMode(); } else { const note = $("#v2ExecutionNote"); if (note) note.textContent = "管理员可切换虚拟 CAN、模拟台架与真实台架"; const runButton = $("#runButton"); if (runButton && !runButton.classList.contains("loading")) runButton.disabled = false; syncExecutionSelector(); } } function setSidebarCollapsed(collapsed) { ui.sidebarCollapsed = Boolean(collapsed); sessionStorage.setItem( "cognitive-agent.sidebar-collapsed", String(ui.sidebarCollapsed), ); document.body.classList.toggle("v2-sidebar-collapsed", ui.sidebarCollapsed); const button = $("#v2SidebarToggle"); if (button) { button.setAttribute("aria-expanded", String(!ui.sidebarCollapsed)); button.setAttribute( "aria-label", ui.sidebarCollapsed ? "展开左侧控制台" : "折叠左侧控制台", ); button.innerHTML = ``; } window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } }); window.setTimeout(() => window.dispatchEvent(new Event("resize")), 180); } function requestUserSafeExecutionMode() { const dryRunButton = $('[data-execution-mode="dry_run"]'); const note = $("#v2ExecutionNote"); const userTarget = $(".v2-user-target-status"); const userTargetText = $("#v2UserTargetText"); const runButton = $("#runButton"); if (!dryRunButton) return; if (!dryRunButton.classList.contains("active")) dryRunButton.click(); if (note) note.textContent = "测试用户使用虚拟 CAN;真实台架仅由管理员显式启用"; if (userTarget) userTarget.dataset.state = "ready"; if (userTargetText) userTargetText.textContent = "执行目标:虚拟 CAN"; if (runButton && !runButton.classList.contains("loading")) runButton.disabled = false; syncExecutionSelector(); } function syncExecutionSelector() { const select = $("#v2ExecutionSelect"); if (!select) return; const active = $('[data-execution-mode].active'); if (active) select.value = active.dataset.executionMode; ["dry_run", "simulated_hardware", "hardware"].forEach((value) => { const option = $(`option[value="${value}"]`, select); const button = $(`[data-execution-mode="${value}"]`); if (option && button) option.disabled = button.disabled; }); dropdownControls.get(select)?.sync(); } function syncRuntimePresentation() { const modelBadge = $("#modelBadge"); const connectionBadge = $("#connectionBadge"); const modelValue = $("#v2ModelValue"); const modelNote = $("#v2ModelNote"); const connectionText = $("#v2ConnectionText"); if (modelBadge && modelValue) { const text = modelBadge.textContent.trim() || "模型检测中"; modelValue.textContent = text; const unavailable = modelBadge.classList.contains("danger"); $("#v2ModelField")?.classList.toggle("unavailable", unavailable); $("#v2ModelState").textContent = unavailable ? "LOCAL" : "READY"; if (modelNote) modelNote.textContent = unavailable ? "GPT 不可用,自动使用本地规则" : "服务端安全托管 · 失败自动降级"; } if (connectionBadge && connectionText) { connectionText.textContent = connectionBadge.textContent.trim() || "正在连接服务"; const online = !connectionBadge.classList.contains("danger") && !connectionBadge.classList.contains("warning"); $(".v2-sidebar-footer")?.classList.toggle("offline", !online); } syncExecutionSelector(); if (ui.role === "user") requestUserSafeExecutionMode(); } function setVehicleLinkState(connected) { const card = $("#v2VehicleCard"); const state = $("#v2VehicleState"); if (!card || !state) return; card.dataset.state = connected ? "online" : "offline"; state.textContent = connected ? "READY" : "OFFLINE"; } async function refreshVehicleLinkState() { const card = $("#v2VehicleCard"); const state = $("#v2VehicleState"); if (card) card.dataset.state = "checking"; if (state) state.textContent = "CHECK"; try { const response = await fetch("/api/extension/health", { credentials: "same-origin", headers: { Accept: "application/json" }, }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const health = await response.json(); setVehicleLinkState(Boolean(health.vehicle?.connected)); } catch (_error) { setVehicleLinkState(false); } } function bindEvents() { $("#v2RoleSelect")?.addEventListener("change", (event) => setRole(event.target.value)); $$('[data-v2-control]').forEach((button) => { button.addEventListener("click", () => { if (ui.activeModule === "self-evolution") { const view = button.dataset.v2Control === "gesture" ? "system" : "weighing"; window.CognitiveAgentSelfEvolution?.setView?.(view); syncSidebarControlForModule(view); return; } setControlMode(button.dataset.v2Control); }); }); window.addEventListener("cognitive-agent:evolution-view-change", (event) => { if (ui.activeModule === "self-evolution") syncSidebarControlForModule(event.detail?.view); }); $$('.v2-module-tab').forEach((button) => { button.addEventListener("click", () => { if (!button.disabled) setModule(button.dataset.module); }); }); $("#v2ExecutionSelect")?.addEventListener("change", (event) => { $(`[data-execution-mode="${event.target.value}"]`)?.click(); syncExecutionSelector(); }); $$(".v2-page-button").forEach((button) => { button.addEventListener("click", () => setPage(button.dataset.v2PageTarget)); }); $("#v2LogoutButton")?.addEventListener("click", () => $("#logoutButton")?.click()); window.addEventListener("cognitive-agent:connection", (event) => { if (event.detail?.status === "online") refreshVehicleLinkState(); else if (["offline", "degraded"].includes(event.detail?.status)) setVehicleLinkState(false); }); $("#v2SidebarToggle")?.addEventListener( "click", () => setSidebarCollapsed(!ui.sidebarCollapsed), ); document.addEventListener("click", () => { closeCustomDropdowns(); closeReasoningPicker(); }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") { closeCustomDropdowns(); closeReasoningPicker(); } }); window.addEventListener("resize", updateScrollCues); window.addEventListener("resize", updateModeEdgeHints); window.addEventListener("cognitive-agent:result", () => requestAnimationFrame(updateScrollCues)); const modeChips = $(".v2-mode-rail .mode-chips"); modeChips?.addEventListener( "scroll", () => requestAnimationFrame(updateModeEdgeHints), { passive: true }, ); if (modeChips) { new MutationObserver(() => requestAnimationFrame(updateModeEdgeHints)) .observe(modeChips, { childList: true }); } const observer = new MutationObserver(syncRuntimePresentation); [$("#modelBadge"), $("#connectionBadge"), $("#hardwareMode"), $("#simulationMode")] .filter(Boolean) .forEach((node) => observer.observe(node, { attributes: true, childList: true, subtree: true, characterData: true, })); } function init() { const workspace = $(".workspace"); const commandPanel = $(".command-panel"); const mainPanel = $(".main-panel"); const originalForm = $("#requestForm"); if (!workspace || !commandPanel || !mainPanel || !originalForm) return; document.body.classList.add("console-v2"); const panelHeading = $(".panel-heading", commandPanel); const modeRail = $(".mode-rail", commandPanel); const exampleGroup = $(".example-group", commandPanel); const safetyStrip = $("#safetyStrip", commandPanel); const requestHeader = $(".request-header", mainPanel); const gestureDrawer = $("#gestureDrawer"); const detached = { panelHeading, modeRail, requestHeader, gestureDrawer, originalForm, exampleGroup, safetyStrip, }; Object.values(detached).filter(Boolean).forEach((node) => node.remove()); const legacyParking = make("div", "v2-legacy-parking v2-legacy-hidden", ""); [exampleGroup, safetyStrip].filter(Boolean).forEach((node) => legacyParking.append(node)); document.body.append(legacyParking); const configStack = buildSidebar(commandPanel); buildConfigFields(configStack, originalForm); enhanceConfiguredDropdowns(); buildOperation( mainPanel, originalForm, panelHeading, modeRail, requestHeader, gestureDrawer, ); buildModuleSwitcher(mainPanel); window.CognitiveAgentSelfEvolution?.mount(mainPanel); $(".pipeline", mainPanel)?.classList.add("v2-legacy-hidden"); $(".topbar")?.classList.add("v2-legacy-hidden"); $(".gesture-backdrop")?.classList.add("v2-legacy-hidden"); buildOutput(mainPanel); bindEvents(); setControlMode(ui.controlMode, { triggerGesture: false }); setModule(ui.activeModule, { persist: false }); setRole(ui.role); setSidebarCollapsed(ui.sidebarCollapsed); setPage(0); syncRuntimePresentation(); refreshVehicleLinkState(); window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } }); requestAnimationFrame(() => { updateModeEdgeHints(); document.body.classList.add("v2-ready"); }); } window.CognitiveAgentConsoleV2 = { enhanceSelect, getModule: () => ui.activeModule, getRole: () => ui.role, setModule, }; document.addEventListener("DOMContentLoaded", init); }());