feat: integrate calibration extension and self-repair modules

This commit is contained in:
vee
2026-08-07 23:39:45 +08:00
parent 156b10fda1
commit 3bceb0d5a1
41 changed files with 21310 additions and 314 deletions
-71
View File
@@ -19,11 +19,6 @@ function loadHardwareClientId() {
return clientId;
}
function defaultHardwareClientLabel(clientId) {
return localStorage.getItem("cognitive-agent.hardware-client-label")
|| `测试终端-${clientId.slice(-6)}`;
}
const state = {
provider: "openai",
executionMode: "dry_run",
@@ -3395,32 +3390,6 @@ function isLocalDecisionHost() {
function renderHardwareAccess(status) {
state.hardwareAccess = status;
const statusNode = $("#hardwareAccessStatus");
const requestButton = $("#requestHardwareAccess");
const releaseButton = $("#releaseHardwareAccess");
if (!statusNode || !requestButton || !releaseButton) return;
const accessState = status?.state || "none";
statusNode.dataset.state = accessState;
if (accessState === "approved") {
statusNode.textContent = `本地已同意。剩余空闲时间 ${status.idle_remaining_seconds ?? 180} 秒;每次真实执行后重新计时。`;
requestButton.hidden = true;
releaseButton.hidden = false;
} else if (accessState === "pending") {
statusNode.textContent = `正在等待本地审批,当前排队第 ${status.queue_position || 1} 位;未获批前不会进入 CAN 链路。`;
requestButton.textContent = "更新申请";
requestButton.hidden = false;
releaseButton.hidden = false;
} else if (accessState === "expired") {
statusNode.textContent = "因 3 分钟未执行测试,使用权已自动停止;再次使用请重新申请。";
requestButton.textContent = "重新申请";
requestButton.hidden = false;
releaseButton.hidden = true;
} else {
statusNode.textContent = "尚未申请;真实台架指令不会进入 CAN 链路。";
requestButton.textContent = "向本地申请";
requestButton.hidden = false;
releaseButton.hidden = true;
}
}
async function loadHardwareAccessStatus({ silent = false } = {}) {
@@ -3436,42 +3405,6 @@ async function loadHardwareAccessStatus({ silent = false } = {}) {
}
}
async function requestHardwareAccess() {
const input = $("#hardwareClientLabel");
const label = input.value.trim() || defaultHardwareClientLabel(state.hardwareClientId);
input.value = label;
localStorage.setItem("cognitive-agent.hardware-client-label", label);
try {
const response = await apiRequest("/api/hardware/access/request", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ client_id: state.hardwareClientId, label }),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.message || payload.error);
renderHardwareAccess(payload);
showToast(payload.state === "approved" ? "当前使用权仍然有效" : "申请已发送到台架本机,请等待审批");
} catch (error) {
showToast(`申请失败:${error.message}`);
}
}
async function releaseHardwareAccess() {
try {
const response = await apiRequest("/api/hardware/access/release", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ client_id: state.hardwareClientId }),
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.message || payload.error);
renderHardwareAccess(payload);
showToast("已停止使用真实台架;再次使用需要重新申请");
} catch (error) {
showToast(`停止使用失败:${error.message}`);
}
}
function selectProvider(provider) {
state.provider = provider;
$$(".segment[data-provider]").forEach((button) => {
@@ -3514,7 +3447,6 @@ function selectExecutionMode(mode) {
const simulatedHardware = mode === "simulated_hardware";
const approvalRequired = Boolean(state.runtime?.hardware?.approval_required);
$("#approvalField").hidden = !hardware || !approvalRequired;
$("#hardwareAccessField").hidden = !hardware;
$("#simulationFaultField").hidden = !simulatedHardware;
$("#executionBadge").className = `status-badge ${hardware ? "" : simulatedHardware ? "warning" : "neutral"}`.trim();
$("#executionBadge").innerHTML = hardware
@@ -5001,9 +4933,6 @@ document.addEventListener("DOMContentLoaded", async () => {
refreshIcons();
initSeatTwin();
$("#requestForm").addEventListener("submit", submitRequest);
$("#hardwareClientLabel").value = defaultHardwareClientLabel(state.hardwareClientId);
$("#requestHardwareAccess").addEventListener("click", requestHardwareAccess);
$("#releaseHardwareAccess").addEventListener("click", releaseHardwareAccess);
$("#utterance").addEventListener("keydown", (event) => {
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
event.preventDefault();