feat(AI): 集成MNN推理引擎替换MLX作为主AI运行时

- 引入MNN(alibaba) + Arm SME2 + CPU作为主AI运行时,支持A19/iPhone17的
  SME2和A17的NEON加速
- 添加MLX Swift作为兜底GPU推理方案,实现双后端切换机制
- 使用单一Qwen3.5-2B多模态模型(1.2GB),替代原有的LLM+VL分离架构
- 实现InferenceEngine.current引擎选择逻辑,真机默认MNN,模拟器回退MLX
- 更新AIAgent架构,通过MNNLLMBridge(ObjC++) → MNNBackend进行推理
- 修改队列机制防止并发推理导致OOM,使用信号量闸门控制显存占用
- 更新文档中的技术栈说明、模块边界和周次交付计划
```
This commit is contained in:
link2026
2026-06-15 09:24:59 +08:00
parent 6c6a950140
commit 9d856fcfc4
37 changed files with 2605 additions and 430 deletions

View File

@@ -1,13 +1,15 @@
import SwiftUI
enum RecordKind: String, Identifiable, CaseIterable {
case quick, indicator, healthExport, archive, diary, symptom, reminder
case quick, indicator, healthExport, archive, diary, symptom, reminder, medicationLibrary
var id: String { rawValue }
/// RecordSheet () enum ,
/// :`.quick`() `.indicator`();
/// `.symptom`() `.diary`(),
static let displayOrder: [RecordKind] = [.diary, .reminder, .indicator, .healthExport, .archive]
/// `.symptom`() `.diary`(),;
/// `.medicationLibrary`()/,Tab ,
/// (,)
static let displayOrder: [RecordKind] = [.diary, .reminder, .indicator, .healthExport, .archive, .medicationLibrary]
/// pill( subtitle,"/")
/// :,( ProfileEditView presets )
@@ -24,6 +26,7 @@ enum RecordKind: String, Identifiable, CaseIterable {
case .diary: return String(appLoc: "健康日记")
case .symptom: return String(appLoc: "记录症状")
case .reminder: return String(appLoc: "开启一个提醒")
case .medicationLibrary: return String(appLoc: "药品库")
}
}
var subtitle: String {
@@ -35,6 +38,7 @@ enum RecordKind: String, Identifiable, CaseIterable {
case .diary: return String(appLoc: "写日记或拍药盒记录用药 · 可让 AI 辅助")
case .symptom: return String(appLoc: "开始一个持续症状,结束时再点结束")
case .reminder: return String(appLoc: "管理用药、复查、监测的周期提醒")
case .medicationLibrary: return String(appLoc: "管理常用药清单 · 拍药盒或手动添加")
}
}
var icon: String {
@@ -46,6 +50,7 @@ enum RecordKind: String, Identifiable, CaseIterable {
case .diary: return "heart.text.square"
case .symptom: return "waveform.path.ecg"
case .reminder: return "bell.badge"
case .medicationLibrary: return "pills.fill"
}
}
var accent: Color {
@@ -57,6 +62,7 @@ enum RecordKind: String, Identifiable, CaseIterable {
case .diary: return Tj.Palette.leaf
case .symptom: return Tj.Palette.amber
case .reminder: return Tj.Palette.leaf
case .medicationLibrary: return Tj.Palette.ink
}
}
}
@@ -83,7 +89,7 @@ struct RecordSheet: View {
}
.padding(.bottom, 14)
// ScrollView :6 detent ,
// ScrollView : detent ,
ScrollView {
VStack(spacing: 10) {
ForEach(RecordKind.displayOrder) { kind in