Files
Cognitive_Agent/apps/web-console/README.md
T

173 lines
13 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Web Console
Web 控制台是车机端的远程自编排与同步显示界面。网页保留一句话指令和预设功能模式入口,请求通过同源服务发送至车机执行;同时同步显示车机任务、编排结果、设备反馈和 USB 扩展能力。真实 CAN 与硬件执行权限仍由服务端安全门禁控制。
当前页面包括:
- 自编排和自扩展合并为一个实时界面,登录身份固定为 `user`,不再提供模块切换。
- AI助手默认展开;左侧控制台、车端设备状态、外设与扩展能力默认收起。四个板块统一通过页面右上角的图标按钮展开或收回,主工作区随面板状态自适应。
- AI助手支持普通问答、工程能力核对和车控工作。能力问答读取运行时权威目录,高置信度冷热请求走确定性快速控制链,其他问题和复杂车控由 Codex App Server 流式处理;车控结果仍以自然语言和可审计的动作进度呈现。
- 网页端可输入一句话指令或点击预设模式,车机端同样可发起任务;两端任务与结果统一同步。
- AI助手语音入口支持双模式:手动点击麦克风按钮会立即以 `manual` 模式录音,不要求唤醒词;浏览器已授权麦克风、助手展开且页面可见时自动进入 `wake` 待机,只有听到“你好,小迪”(兼容无标点与字间停顿)后才展示并继续转录。AudioWorklet 采集后,服务端 SenseVoiceSmall 以节流预览返回未语义清洗的实时文字;静音端点立即停止采音,再由 Silero VAD、幂等 TranscriptAssembler 和理解层生成最终 `assistant_text`。普通问答、未知能力、否定和撤销表达均可回填,`commands` 仅作为受信任车控旁路,不能反向过滤助手输入。
- 整车数字孪生位于工作区中央,点击或悬停热点可查看车窗、遮阳帘、主/副驾座椅、阅读灯、氛围灯、前大灯和空调的完整状态。
- 车端设备状态与外设能力板块均可独立隐藏或恢复,面板状态在当前浏览器会话中保留。
- USB 外设接入后同步显示 GSCU 链路、外设名称、类型、已学习能力和最近一次跨设备联动。
- 左侧运行日志集中显示网页/车机任务、链路、设备与外设同步事件。
UI 只展示可审计的“决策摘要”和“处理轨迹”,不展示模型私有思维过程。
## AI助手接口
浏览器只使用同源接口,不直接连接 App Server、MCP 或模型服务:
- `GET /api/assistant/status`:返回 App Server 状态、可用性和当前会话数。
- `GET /api/assistant/capabilities`:返回由运行时注册表、模式目录、CAN 绑定和已学习外设共同生成的权威能力快照。`service_surfaces` 只提供语音、手势、NFC、自标定和自修复的状态信息,不代表助手可调用;执行资格以 `assistant_callable` 和服务端校验为准。
- `POST /api/assistant/stream`:提交 `message`、`conversation_id`、执行模式和当前车型等上下文,返回 `application/x-ndjson`。前端消费 `message.accepted`、`work.*`、`action.*`、`answer.delta`、`control.suggestions`、`answer.completed` 与 `error` 事件,以增量方式展示回复和控制进度。不支持的车控请求可随 `control.suggestions` 返回当前车型可执行的替代指令;前端去重后渲染为按钮卡片,点击会作为新指令沿同一受控链路提交。
`POST /api/internal/codex/vehicle-control` 是 App Server MCP 子进程专用的回环接口,要求一次性内部令牌且与原始用户文本绑定,不是浏览器或第三方集成接口。浏览器也不能通过响应内容扩大执行目标、切换执行模式或提交原始 CAN。
当前座椅阶段一控制台为无构建静态页面,由 `cognitive_agent.server` 同源提供 API 和资源。运行:
```bash
make dev
```
语音听写首次运行前安装运行时、官方完整精度模型和 Silero VAD:
```bash
python -m pip install -e ".[speech]"
python tools/install_sensevoice_model.py
```
录音只用于当前请求,不落盘;`captured_text` 保留完整声学结果,`raw_text` 在 `manual` 模式保留完整原文、在 `wake` 模式剥离唤醒词,`assistant_text` 是面向问答的轻清洗会话,`clean_text/control_text` 与结构化 Intent 则保持严格车控语义。前后端通过 `X-Speech-Input-Mode: manual|wake` 显式区分模式;可用 `SPEECH_WAKE_WORD_ENABLED=false` 关闭唤醒门,或用竖线分隔的 `SPEECH_WAKE_WORDS` 配置主唤醒词与别名。远程浏览器必须通过 HTTPS 才能访问麦克风。诊断可设置后端 `SPEECH_DEBUG=1` 并用 `?speechDebug=1` 打开前端日志,默认关闭。
Android PAD/模拟器联调使用:
```powershell
powershell -ExecutionPolicy Bypass -File .\tools\android_pad_dev.ps1
```
脚本会启动已配置的 Pixel Tablet AVD、建立 `adb reverse tcp:8000 tcp:8000`、
以真实硬件关闭/模拟台架开启的方式启动服务,并在 Android Chrome 中打开
`http://127.0.0.1:8000`。停止联调环境:
```powershell
powershell -ExecutionPolicy Bypass -File .\tools\android_pad_dev.ps1 -Stop
```
局域网演示使用:
```bash
make dev-lan
```
其他设备访问启动日志打印的 `http://<LAN-IP>:8000`。页面与后端 API 由同一服务提供,无需单独配置前端地址。
自扩展接口统一位于 `/api/extension/*`。红外模块默认使用已验证的 GSCU1B TCP
模式:Linux 端在 `0.0.0.0:4444` 监听,GSCU1B 作为 TCP Client 主动接入。
“外设与扩展能力”中的“TCP 设置”可修改监听 IP、端口并立即重启监听,配置持久化到
`artifacts/tmp/gscu_gateway.json`;同一弹窗可执行查询、学习、取消、发射、读取、
写入、软重启、WiFi 配网锁、擦除、恢复出厂和原始 JSON 调试动作。模块配置的
服务器地址必须填写 Linux 的实际局域网 IP,不能填写 `0.0.0.0`。
TCP 发射、取消、写入和设置类动作在操作系统确认写入连接后立即返回“已下发”,
不会因设备不回 ACK 而阻塞前端。固件 1.1.5 的学习动作同样不主动返回 ACK,因此
前端在学习命令下发后自动读取目标槽位,以实际 `ir_data` 回读确认学习完成;设备查询
和读取槽位仍等待带 `messageId` 的实际回执。
学习时可为每个 `1–248` 红外槽位填写信号名称;槽位与名称持久化在本机
`artifacts/server/gscu_ir_catalog.sqlite3` 数据库中,并在 TCP 动作调试区按槽位号
升序显示为小卡片。浏览器中已有的旧名称会自动迁移到数据库。单卡片删除操作只删除
本地目录记录,不会擦除设备红外码;已验证的设备协议仅支持全部擦除。全部擦除会先
弹出不可恢复确认,设备命令提交成功后才同步清空本地槽位数据库。
如需回退 MQTT,可设置 `GSCU_TRANSPORT=mqtt`,通过 `GSCU_MQTT_*`、
`GSCU_COMMAND_TOPIC` 和 `GSCU_RESPONSE_TOPIC` 指定 Broker 与话题;通过
`GSCU_TRANSPORT=simulation` 使用演示学习器。MQTT 依赖已包含在核心环境中;
NFC 串口依赖通过 `ir` 可选依赖安装。自扩展不再需要独立的 `8010` 前端服务。
## NFC 玩具识别与红外学习
统一页面的“外设与扩展能力”区域提供“感应玩具 NFC”入口。点击后将玩具上的
NFC 卡片靠近 PCR532/PN532(CH340/CH341 串口)读卡器:新卡可建立或绑定
玩具档案,并立即进入现有 GSCU1B 红外学习流程;已绑定卡片会自动识别玩具,
展示全部已学习/待学习动作,并可直接发射已验证动作。
安装串口支持并启动:
```bash
python -m pip install -e ".[ir]"
make dev
```
服务会优先复用本机 `ir-toy-learning` 的 MQTT NFC 桥(默认
`127.0.0.1:1883`),避免两个进程同时抢占同一个 `COM` 口;桥不可用时再自动选择
唯一的 CH340/CH341、PN532 或 PCR532 串口。可通过 `NFC_PORT=COM5` 指定串口,
或用 `NFC_MQTT_HOST`、`NFC_MQTT_PORT` 调整桥地址;`NFC_MQTT_DISABLED=true`
强制只使用串口,`NFC_DISABLED=true` 可完全禁用读卡线程。
首次加载时页面会从 `http://localhost:3001/n7web-profile-bridge.html` 安全迁移旧
`ir-toy-learning` 浏览器档案,保留工牌 UID、玩具编号、动作名称和 GSCU1B 槽位。
不同浏览器运行时,旧工作台会把不含红外原始波形的档案元数据同步到本机 MQTT
保留主题 `toy/ir/profiles`,当前服务同样会自动导入。迁移按档案与槽位幂等合并,
不会覆盖当前工程中已经建立的能力。NFC UID 与玩具档案的绑定保存在当前浏览器,
红外波形仍保存在 GSCU1B 的 1–248 号物理槽位。
TCP 模式下本服务是服务器,GSCU1B 是客户端:设备配网页中的“TCP服务器”
必须填写运行本服务的主机地址,“TCP端口”必须与 `GSCU_TCP_PORT` 一致。
如需绑定指定网卡地址,可设置 `GSCU_TCP_LISTEN_HOST`;网卡晚于服务就绪或
端口被短暂占用时,监听器会按 `GSCU_TCP_BIND_RETRY_SECONDS`(默认 1 秒)
自动重试。`/api/extension/health` 的 `listening` 表示服务器已监听,只有收到
真实设备会话后 `connected`/`peer_connected` 才会变为 `true`。
车机与网页同步使用以下同源接口:
- `GET /api/vehicle-display-sync`:网页轮询最新车机任务、结果、外设目录与扩展链路状态。
- `POST /api/requests`:车机执行时附带 `client_type: "head_unit"`;网页控制台附带 `client_type: "web_console"`。两类任务的执行结果都会写入同步快照。
- `POST /api/extension/display-sync`:车机刚识别 USB 外设时上报 `device` 与 `peripherals` 能力目录,无需等待首次执行。
- `POST /api/extension/assistant/plan` 和 `/api/extension/vehicle/execute`:联动规划与车端执行结果同样写入同步快照。
右上角“能耗监测”入口以独立固定页面展示 7 个当前可控车端设备的实时功率、
本次监测累计能耗、总功率趋势和分设备趋势。能耗链路优先接收
`cognitive-agent:power-telemetry` 事件,也兼容调用
`window.updateDevicePowerTelemetry(payload)` 的现有集成方式;载荷可使用
`devices.<device>.power_w` 或 `total_power_w`,并可附带 `energy_wh`、
`trip_energy_kwh` 或 `today_energy_kwh`。累计能耗独立保留,瞬时功率超过 15 秒
未更新时只会回退到状态估算,不会让已上报的车端累计值消失。每条遥测应显式提供
`source: "vehicle_power_sensor"`(实测)或 `source: "estimated"`(估算)。
当前 CAN 状态协议没有独立电流/
功率电表信号,因此未注入新鲜功率数据的设备会显示带 `≈` 和“状态估算”标签的
确定性实时估算,绝不标记为车端实测。真实功率通道接入后页面会逐设备自动切换为
“实测”,无需更换页面或曲线实现。
公网入口由后端统一认证,前端不保存密码或 API Key。未认证访问自动进入
`/login`,主控制台提供退出按钮。固定入口是
`https://511.kendeji.fun`,应用容器只监听服务器回环地址,再由 Caddy 提供
HTTPS。部署方式见
[`deploy/server/README.md`](../../deploy/server/README.md)。
页面支持 GPT/本地解析切换、六阶段流水线、主副驾热舒适、五轴位置状态和 3D 座椅孪生、GPT 结构化能力请求、决策与校验轨迹、FunctionConfig、CommandPlan、虚拟帧和 ExecutionReport。真实硬件执行由服务端门禁控制,不是仅靠前端按钮限制;Android 联调脚本会显式关闭真实硬件执行。
## 手势资源与安全规则
手势模型随当前工程交付,默认位置为:
```text
assets/gesture/gesture_recognizer.task
../../config/gesture/default.yaml
```
后端提供 `/api/gesture/runtime` 和 `/api/gesture/model`,前端以二进制缓冲区加载模型,避免依赖外部 `seat_gesture_control` 目录。MediaPipe Web、Lucide 和 Three.js 均按固定版本保存在 `vendor/`,运行时不访问外部 CDN;摄像头帧和手部关键点只在当前浏览器中处理。
## PAD、PWA 与离线行为
- 竖屏 PAD 在 900 CSS px 以下切换为上下布局,横屏保留指令栏与结果区;触控目标最小 48 dp,并处理安全区和动态视口。
- 顶部连接徽标由 `/api/health` 周期探测驱动;GET 可有限重试,POST 控制请求不自动重试。
- Service Worker 缓存页面壳、固定版本依赖和按需访问的 3D/手势资源;`/api/requests` 等控制 API 始终走网络且不会写入缓存。
- 从 Android Chrome 的“安装应用”可进入 standalone PWA;首次完整在线加载后可离线打开控制台壳,实际编排仍要求 Windows 服务可达。
模拟台架需要 `COGNITIVE_AGENT_SIMULATED_HARDWARE_ENABLED=true`。选择“模拟台架”后可注入反馈超时、适配器断开、电机堵转、固件不匹配和部分反馈。结果会标记 `simulation=true`、`seat_feedback=simulated_hardware` 和 `physical_can_opened=false`,不会调用真实 CAN、ZLG 或 IAR。
安全规则:张掌保持 1 秒激活;动作保持 600 ms 且至少连续 8 帧才执行;换动作不重新锁止;握拳立即停止但不解除激活;3 秒无有效动作自动锁止;单次连续运动最多 1.5 秒;检测到多只手时不执行。自定义映射保存在浏览器 `localStorage`。
摄像头仅能在安全来源使用:本机访问 `http://127.0.0.1:8000`,远程访问必须使用 HTTPS。关闭抽屉、页面隐藏或离开页面时会立即停止摄像头轨道。