- frontend_vue3/src/types/runtime.ts(全新 · RuntimeTarget / RuntimeKind / DspProfile / EngineRuntimeState)
- frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue(扩展 · 加 RuntimeTarget 下拉 + 切换流程)
- frontend_vue3/src/composables/useRuntimeTarget.ts(全新 · GET /api/runtime/available + POST /api/runtime/switch + WS runtime:switched 订阅)
- frontend_vue3/src/stores/linkStore.ts(read-only 引用 · 链路状态切换协调)
- frontend_vue3/tests/components/DrawerEngine.test.ts(新增)
- frontend_vue3/tests/composables/useRuntimeTarget.test.ts(新增) occupies: [P1.K-drawer-engine(写), P1.K-types(写), P1.K-composables(写)] adr: docs/08-implementation/40-aios/ADR/ADR-AIOS-08-xilink-stage-ux.md ref_section: §2.4 引擎运行核心选择 + §3.2 边界铁律 #3 + §4.2 fork P1.U-runtime-selector-ui derived_from: ADR-AIOS-08 created: 2026-05-30 last_modified: 2026-05-30 16:17 dispatched_at: 2026-05-30 09:32 estimated: 1.5d unblocks:
- 验证 ADR-08 §2.4 RuntimeTarget 7 枚举切换闭环(对标 AWE Designer Target Selection)
- ADR-08 §3.2 边界铁律 #3 验证(切换不破坏链路状态 · 拓扑+参数保持) related_zombie:
- P0.U-meter-types-v3(9fc31c4 · 同部门前端 · types 扩展模式参考) related_dispatched:
- P5.U-runtime-mode-refactor(同 ADR-08 §2.4 后端配套 · RuntimeTarget 7-enum + LEGACY_RUNTIME_MODE_MAP + /api/runtime/{available,switch} REST + ws/runtime:switched · 本任务先按 ADR contract 跑 mock 后切真接口)
- P1.UA8-link-error-check(同 ADR-08 前端 · 文件正交 · bottom/)
- P1.UA8-perf-monitor-frontend(同 ADR-08 前端 · 文件正交 · drawers/DrawerMetrics.vue · 本 fork 改 drawers/DrawerEngine.vue)
P1.UA8-runtime-selector-ui · 引擎运行核心选择前端 UI(ADR-AIOS-08 §2.4 fork · 前端配套)
Worker:TBD(用户分配 · isolation: file · 主仓 04_development/ 任一空闲前端 worker)· 部门:前端 (frontend_vue3) 预计:1.5d · 优先级:P1 · 状态:dispatched 隔离:🧵 文件隔离(stages/xilink/drawers/DrawerEngine.vue + composables/useRuntimeTarget + types/runtime.ts · 与 ADR-08 P1.UA8-link-error-check(bottom/) + P1.UA8-perf-monitor-frontend(drawers/DrawerMetrics.vue)文件正交 · 与 ADR-12/ADR-11 stages 完全正交)
🔍 触发与解锁链
| 触发 | 状态 | 影响 |
|---|---|---|
| ADR-AIOS-08 accepted v1.1 | ✅ 2026-05-29 17:25 | 10 fork 启动 · 用户 09:23 拍板 start 三前端 fork |
| .clinerules v1.4 §任务隔离类型分配准则 | ✅ 2026-05-30 09:25 | 本 fork 标 isolation: file · 不绑定 worker |
| 用户拍板方向 A 就地扩展 | ✅ 2026-05-30 09:00 "zhujian" | 后端 P5.U-runtime-mode-refactor 保留 RuntimeModeService [Obsolete] · 7 天宽限 |
| AWE Designer 对标 | ADR §2.4 用户拍板 | 7 RuntimeTarget(pc-native-0~3 + dsp-21489/21569/hexagon-v73) |
| P5.U-runtime-mode-refactor(同期派) | 🟢 dispatched | 后端 RuntimeTargetService 7 枚举 + REST + WS 双广播 · 前端先按 ADR §2.4 contract 跑 mock |
→ 跨栈独立(纯前端) · 不修改 contract-v1.0(已 frozen) · 与同 ADR P1.UA8-link-error-check / P1.UA8-perf-monitor-frontend 文件正交(本 fork 改 drawers/DrawerEngine.vue) · 与 ADR-12/ADR-11 前端 fork 完全正交。
任务定义(基于 ADR-AIOS-08 §2.4)
按 ADR-08 §2.4 引擎运行核心选择 · 在 DrawerEngine 实装 RuntimeTarget 下拉切换 UI:7 预定义 target(pc-native-0~3 + dsp-21489/21569/hexagon-v73)+ 切换流程(loading 态 → success/failure)+ 当前 target 元信息显示(Kind / ThreadAffinity / DspProfile)+ 订阅 ws/runtime:switched 广播。
后端 P5.U-runtime-mode-refactor 同期派(2.0d)· 本任务不强等其 zombie:先按 ADR §2.4 schema 跑 mock 数据 · 后端 zombie 后切真接口零改动。
完整 prompt(直接复制粘贴 worker 终端)
[U-thread] P1.UA8-runtime-selector-ui(alias: P1.U-runtime-selector-ui)
[部门] 前端 (frontend_vue3) · 推荐 skill: vuejs-typescript-best-practices
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/(由用户分配的 worker / worktree 决定)
[Occupies] P1.K-drawer-engine(写 · DrawerEngine.vue 扩展) + P1.K-types(写 · types/runtime.ts 全新) + P1.K-composables(写 · useRuntimeTarget)
[隔离] 🧵 文件隔离(.clinerules v1.4 §任务隔离类型分配准则)· 仅写:
- frontend_vue3/src/types/runtime.ts(全新)
- frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue(扩展 · 加 RuntimeTarget 下拉 + 切换流程)
- frontend_vue3/src/composables/useRuntimeTarget.ts(全新)
- frontend_vue3/tests/* 新增
严禁动 stages/xilink/bottom/*(P1.UA8-link-error-check 拥有) · stages/xilink/drawers/DrawerMetrics.vue(P1.UA8-perf-monitor-frontend 拥有) · stages/xilink/drawers/Drawer{Connection,Inspector,Log,Modules,Profile,Project,PropertyPanel}.vue(留本 ADR 其他 fork 或下季度评估) · stages/xitest/* / stages/xitune/*
[优先级] P1 · 1.5d · ADR-08 §2.4 前端配套 · 与 P5.U-runtime-mode-refactor(后端 2.0d)同期跑 · 文件正交
[ADR] d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-08-xilink-stage-ux.md(必读 §2.4 + §3.2 边界铁律 #3 + §4.2 fork P1.U-runtime-selector-ui + §3.2 LEGACY_SOURCE_INJECT_MODE_MAP)
[业务行为契约引用] ADR-AIOS-08 §2.4 RuntimeTarget 7 枚举 · DrawerEngine 下拉切换 · ws/runtime:switched 订阅 · ADR §3.2 边界铁律 #3(切换不破坏链路状态)
[参考文档](绝对路径)
- d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-08-xilink-stage-ux.md(主 ADR · §2.4 必读)
- d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/active/P5.U-runtime-mode-refactor.md(后端配套 prompt · 同期派 · REST + WS schema 真值源 · 7 RuntimeTarget 预定义 + LEGACY_RUNTIME_MODE_MAP)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue(壳已存在 · 含 AudioEnginePanel · 本任务扩展 RuntimeTarget 下拉 · 不破坏现有 AudioEnginePanel)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/backend_csharp/Services/AudioEngine/RuntimeModeService.cs(64 行 · 旧 API 真值源 · 后端会标 [Obsolete] 7 天宽限)
- 同部门标本(强制 read · 4 维度对齐):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/active/P0.U-measurement-rms-fft-phase.md(同部门前端 · WS 订阅 + 状态机模式)
- 同 ADR 同期前端 fork(读以同步 namespace):
· prompts/active/P1.UA8-link-error-check.md(看 useLinkErrorWS 模式)
· prompts/active/P1.UA8-perf-monitor-frontend.md(看 useMetricsWS / usePerfPerModule REST poll 模式 · 本任务 useRuntimeTarget 仿)
- contract-v1.0(已 frozen · 不改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md
【背景】
ADR-AIOS-08 accepted v1.1(2026-05-29 17:25)· 议题① 引擎运行核心选择:用户原话"引擎界面添加运行核心 · 原本的 source 设计逻辑是 source 中有一个控制变量,可以选择 PC 注入还是 DSP 直接生成,但是这里存在一个矛盾点 ... 在引擎中可以选择算法的运行平台,比如 PC native0, native1 等等"。
🚨 **真值核查发现**:
- 后端 `RuntimeModeService.cs` 64 行二态(normal/legacy) · 同期 P5.U-runtime-mode-refactor 重构为 RuntimeTargetService 7 枚举 + LEGACY_RUNTIME_MODE_MAP(normal↔pc-native-0 / legacy↔pc-native-legacy)+ /api/runtime/{available,switch} REST + ws/runtime:switched(新)+ ws/mode_changed(旧 · 7 天宽限)
- 前端 `DrawerEngine.vue` 壳已存在 · 含 AudioEnginePanel · 但无 RuntimeTarget 选择器(0 命中 platform / runtime / native0)
**对标 AWE Designer Target Selection**:
- 7 预定义 RuntimeTarget(MVP):
· PC Native:pc-native-0(主) / pc-native-1/2/3(辅)· ThreadAffinity 0~3
· DSP Simulated:dsp-21489(450 MIPS · 5 MB · 48kHz)/ dsp-21569(800 MIPS · 16 MB · 96kHz)/ hexagon-v73(2000 MIPS · 32 MB · 192kHz)
**ADR §3.2 边界铁律 #3**:切换不破坏链路状态 · 拓扑+参数保持(后端 SwitchRuntimeAsync 复用 DeviceSwitchRestartCoordinator 模式)· 前端只显示 loading/success/failure · 不重建链路状态。
**本任务执行策略**(不强等后端 zombie):
- Phase A:按 ADR §2.4 schema 实装 types + DrawerEngine 下拉 + useRuntimeTarget · 跑 mock(REST + WS 都 mock · 7 RuntimeTarget hardcode 在 useRuntimeTarget · 同步后端预定义)
- Phase B:后端 P5.U-runtime-mode-refactor zombie 后 · 切真 REST/WS(改 useRuntimeTarget 一处 · UI 零改动)
**契约策略**:不修改 contract-v1.0(已 frozen) · `/api/runtime/*` REST + `ws/runtime:switched` WS 走 dev-api(待 K2-protocol-v2 §runtime-selector 正式入)。
【执行步骤】
Step 1 · read 已有基础(只读 · 必做)
- read ADR-AIOS-08 §2.4 全文(7 RuntimeTarget 预定义 + RuntimeTarget/DspProfile 字段 + 切换流程 + LEGACY_RUNTIME_MODE_MAP)
- read 同期 P5.U-runtime-mode-refactor.md(看后端 REST/WS schema + 7 预定义清单 + LEGACY map 真值源)
- read backend_csharp/Services/AudioEngine/RuntimeModeService.cs 64 行(旧 API 兼容理解)
- read frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue 当前壳(含 AudioEnginePanel · 不破坏)
- read 标本 prompts/active/P0.U-measurement-rms-fft-phase.md(同部门前端 · WS + 状态机)
- read 同期 prompts/active/P1.UA8-link-error-check.md + P1.UA8-perf-monitor-frontend.md(看 useLinkErrorWS / useMetricsWS / usePerfPerModule 风格 · 本任务 useRuntimeTarget 仿)
Step 2 · 新建 frontend_vue3/src/types/runtime.ts(与后端 RuntimeTargetService schema 一对一)
- export type RuntimeKind = 'pc-native' | 'dsp-simulated'
- export interface DspProfile {
chipModel: string // 'ADSP-21489' / 'ADSP-21569' / 'Hexagon-V73'
maxMips: number
maxMemoryKB: number
sampleRateHz: number
}
- export interface RuntimeTarget {
id: string // 'pc-native-0' / 'dsp-21489' / etc
kind: RuntimeKind
label: string // UI 显示
threadAffinity?: number // PC native 专属(0~3)
dspProfile?: DspProfile // DSP simulated 专属
available: boolean
unavailableReason?: string
}
- export interface EngineRuntimeState {
current: RuntimeTarget
available: RuntimeTarget[]
switching: boolean
lastError?: string
}
- export interface RuntimeSwitchedEvent {
type: 'runtime:switched'
targetId: string
durationMs: number
timestampMs: number
}
Step 3 · 新建 frontend_vue3/src/composables/useRuntimeTarget.ts(REST + WS 双源 · mock 双模式)
- 提供:
· loadAvailable() Promise<RuntimeTarget[]> — GET /api/runtime/available
· switchTo(targetId: string) Promise<{success, current, durationMs, error?}> — POST /api/runtime/switch
· subscribeSwitched() — 订阅 ws/runtime:switched(新)+ ws/mode_changed(旧 · 7 天宽限期内兼容)
· current: Vue ref<RuntimeTarget | null>
· available: Vue ref<RuntimeTarget[]>
· switching: Vue ref<boolean>
· lastError: Vue ref<string | undefined>
- dev/test 提供 __mockAvailable(targets) + __mockSwitchResult(result) + __mockWSEvent(evt) helpers
- 7 RuntimeTarget hardcode fallback(若后端不可达):pc-native-0~3 + dsp-21489/21569/hexagon-v73(对齐 ADR §2.4 预定义)
- ❌ 不在前端做 RuntimeTarget 切换的"挂起链路 → 重建 module"逻辑(后端职责 · 前端只显示 loading)
Step 4 · 扩展 frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue
- 现有 AudioEnginePanel 保留 · 顶部新增 [Runtime Target] section:
· Dropdown 显示 current.label(默认 "PC Native (Thread 0)")
· 展开后 7 RuntimeTarget 分两组:[PC Native] (4 项) / [DSP Simulated] (3 项)
· 每项显示 label + (available 否)灰显 + tooltip 显示 unavailableReason
· DSP Simulated 项额外显示 DspProfile 概要(eg "450 MIPS · 5 MB · 48kHz")
- 切换流程:
· 用户选 target → 弹 confirm modal "切换到 X · 链路将短暂挂起 · 拓扑+参数保持"
· 确认后调 useRuntimeTarget.switchTo(targetId) · UI 显示 switching loading
· 成功 → toast "已切换到 X · 耗时 1.2s" · current 更新
· 失败 → toast "切换失败:reason" · current 不变
· WS runtime:switched 广播也会触发 current 更新(其他 client 切换的同步)
- 当前 target 元信息卡片(下拉旁):Kind / ThreadAffinity 或 DspProfile 详情
Step 5 · 单元测试 + e2e mock 真值
- 新增 tests/composables/useRuntimeTarget.test.ts(>= 5 case:loadAvailable + switchTo 成功 + switchTo 失败 + LEGACY map normal↔pc-native-0 + WS 订阅 runtime:switched/mode_changed)
- 新增 tests/components/DrawerEngine.test.ts(>= 5 case:渲染 7 RuntimeTarget + 分组 PC/DSP + 切换 confirm modal + loading 态 + DspProfile 卡片)
- 至少 10 个新 case
- typecheck + build + test:unit 基线 356/3 → 目标 ≥ 366/3(+10 用例)
Step 6 · 端到端真值(.clinerules v1.8 §业务行为契约必填段)
- vitest 真值脚本:
· __mockAvailable 注入 7 RuntimeTarget → 断言 DrawerEngine 渲染分组(PC 4 / DSP 3)
· 用户点 dsp-21569 → confirm modal 显示 "切换到 ADSP-21569 (800 MIPS · 16 MB · 96kHz)"
· 确认 → __mockSwitchResult({success:true, durationMs:1200}) → toast "已切换 · 1200ms" · current 更新为 dsp-21569
· __mockWSEvent({type:'runtime:switched', targetId:'pc-native-1'}) → current 自动同步为 pc-native-1
· 失败:__mockSwitchResult({success:false, error:'audio engine busy'}) → toast 显示错误 · current 不变
Step 7 · Commit + push
- git status / git pull origin xistudio --no-rebase / git add 隔离文件清单
- 三元组 trailer 必须含 [files=...]
- git push origin xistudio
【验收】
形式合规:
- npm run typecheck → ✓ exit 0
- npm run build → ✓ 零错误
- npm run test:unit → ≥ 366/3(基线 +10 用例)
- 5-7 文件落地(types ×1 + drawers ×1 改 + composables ×1 + tests ×2)
业务行为契约自查清单(ADR §2.4):
- [ ] ① 7 RuntimeTarget 渲染(PC Native 4 + DSP Simulated 3)· 字段 id/kind/label/threadAffinity/dspProfile/available/unavailableReason
- [ ] ② 切换流程:confirm modal → loading → success/failure toast → current 更新
- [ ] ③ DspProfile 卡片显示(MIPS/Memory/SampleRate)· PC native 显示 ThreadAffinity
- [ ] ④ ADR §3.2 边界铁律 #3 验证:前端不重建链路状态(后端 SwitchRuntimeAsync 职责 · 前端单测覆盖 "不调 linkStore 任何 reset/clear")
- [ ] ⑤ LEGACY_RUNTIME_MODE_MAP 双向兼容:normal↔pc-native-0 + legacy↔pc-native-legacy(单测覆盖)
- [ ] ⑥ WS 双订阅:runtime:switched(新 · 主)+ mode_changed(旧 · 7 天宽限期内不忽略)
- [ ] ⑦ Phase A mock 跑通 · ① 输入输出 schema 与 Phase B 真接口零改动切换(留 useRuntimeTarget TODO 切换点)
【commit】
subject:`feat(P1.UA8-runtime-selector-ui): DrawerEngine RuntimeTarget dropdown + useRuntimeTarget · ADR-08 §2.4 frontend (AWE Designer parity)`
trailer(必须精确):
[step=7/7] [pid=P1] [uid=UA8-runtime-selector-ui] [occupies=P1.K-drawer-engine+P1.K-types+P1.K-composables]
[files=frontend_vue3/src/types/runtime.ts, frontend_vue3/src/stages/xilink/drawers/DrawerEngine.vue, frontend_vue3/src/composables/useRuntimeTarget.ts, frontend_vue3/tests/composables/useRuntimeTarget.test.ts, frontend_vue3/tests/components/DrawerEngine.test.ts]
[ipc=api/runtime/available(consumer), api/runtime/switch(consumer), ws/runtime:switched(consumer-new), ws/mode_changed(consumer-deprecated-7d)]
[isolation] file(同 worktree 同 branch · 文件正交于 ADR-08 P1.UA8-link-error-check + P1.UA8-perf-monitor-frontend + ADR-12/ADR-11 前端 fork)
[derived_from] ADR-AIOS-08 §2.4 fork
【禁止】
1. ❌ 不动 stages/xilink/bottom/*(P1.UA8-link-error-check 拥有)
2. ❌ 不动 stages/xilink/drawers/DrawerMetrics.vue(P1.UA8-perf-monitor-frontend 拥有)
3. ❌ 不动 stages/xilink/drawers/Drawer{Connection,Inspector,Log,Modules,Profile,Project,PropertyPanel}.vue(本 fork 仅 DrawerEngine.vue · 9→4 dock 裁剪走另一 fork P1.U-dock-cleanup-9to4)
4. ❌ 不动 stages/xitest/* / stages/xitune/*
5. ❌ 不在前端做 RuntimeTarget 切换"挂起链路→重建 module"逻辑(后端职责 · 前端只显示 loading + 等 WS/REST 响应)
6. ❌ 不嵌入完整 Vue SFC 骨架(.clinerules v1.6)· worker 自决具体实现风格
7. ❌ 不绑定 worker(本 prompt frontmatter worker: TBD · isolation: file · 用户分配)
8. ❌ 不修改 source 模块的"PC 注入 vs DSP 直接生成"控制变量(若存在)· 后端 P5.U-runtime-mode-refactor 拥有 LEGACY_SOURCE_INJECT_MODE_MAP 处理权
9. ❌ 不忽略 mode_changed 旧 WS 事件(7 天宽限期内必须双订阅 · 否则 7 天内其他 client 切换不同步)
10. ❌ 不验"typecheck 全绿就 commit"——必须按 ADR §2.4 7 项契约 + e2e mock 真值脚本(7 RuntimeTarget 渲染 + 切换流程 + LEGACY map)
11. ❌ 不强等 P5.U-runtime-mode-refactor zombie 才开工(Phase A mock 先跑 · Phase B 切真接口零改动)
解锁链(本任务 zombie 后)
- ✅ ADR-08 §2.4 引擎运行核心选择前端闭环验证(对标 AWE Designer Target Selection)
- ✅ ADR-08 §3.2 边界铁律 #3 验证(切换不破坏链路状态 · 前端不重建)
- ✅ Phase B 切真接口零改动(后端 P5.U-runtime-mode-refactor zombie 后 · useRuntimeTarget 切换点零 UI 改动)
- ✅ 给 K2-protocol-v2 §runtime-selector 起草提供 RuntimeTarget + Switch 端到端实测数据
- ✅ 解锁 ADR-08 §2.2 P1.UA8-link-error-check 的 RUNTIME_PLATFORM_MISMATCH 错误码触发(前端可读 current.kind 判定)
风险评估
| 风险 | 缓解 |
|---|---|
| ⚠️ 切换中用户重复点击下拉 | switching ref 为 true 时下拉禁用 + 单测覆盖 |
| ⚠️ WS runtime:switched 与 mode_changed 双订阅同时触发(后端双广播) | useRuntimeTarget 内 dedupe 100ms 时间窗 · 同 targetId 的两次事件合并 |
| ⚠️ DSP simulated 切换实际不真跑 DSP(MVP 仅描述) | confirm modal 文案明确"模拟 X 平台算力边界 · 实际仍跑 PC native" · ADR §3.2 长期演进 #12 标 |
| ⚠️ 7 RuntimeTarget hardcode fallback 与后端不一致 | step 1 强制 read 后端 prompt 7 预定义清单 · 字段一对一 · commit 前 grep 双方 id 字面值 |
| ⚠️ legacy 模式映射(legacy↔pc-native-legacy)前端不知道这个 target 是否 available | 后端 GET /api/runtime/available 不返回 pc-native-legacy(隐藏)· 前端仅在加载旧 .xilink 文件时才看到 LEGACY map |
历史
| 时间 | 事件 | hash |
|---|---|---|
| 2026-05-30 09:32 | dispatched · 用户拍板 start 三前端 fork(.clinerules v1.4 §UID 命名规范 · UID 升级 P1.U → P1.UA8 · alias 兼容 · isolation: file 标注 · AWE Designer 对标) | — |
| 2026-05-30 16:17 | zombie · 用户拍板 stop · DrawerEngine RuntimeTarget 7-enum 下拉 + useRuntimeTarget composable + types/runtime.ts 落地 · ADR-08 §2.4 前端闭环(对标 AWE Designer) | c671aa4 |