Files
kangkang/康康/Features/Me/InferenceSettingsView.swift
link2026 32180d7c0e 根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:
```
docs(readme): 更新文档说明

- 添加项目使用指南
- 完善API接口说明
- 修正错误的配置示例
```
2026-07-13 18:47:11 +08:00

192 lines
7.8 KiB
Swift

import SwiftUI
/// : Gemma 4( 4bit),** MLX/GPU**
/// MNN/SME2 LLM (Gemma 4 MNN ),
/// , + + AI
struct InferenceSettingsView: View {
// AI(Gemini) key CloudAI ,@AppStorage
@AppStorage("cloud_ai_gemini_enabled") private var cloudEnabled = false
@AppStorage("cloud_ai_gemini_key") private var cloudKey = ""
@State private var modelService = ModelDownloadService.shared
/// , push
@State private var showSelfTest = false
/// (Gemma 4,MLX)
private var modelReady: Bool {
modelService.states[.llm]?.phase == .ready
}
var body: some View {
ScrollView {
VStack(spacing: 12) {
HStack {
Text("推理引擎")
.font(.tjTitle())
.foregroundStyle(Tj.Palette.text)
Spacer()
}
.padding(.top, 4)
.padding(.bottom, 6)
localEngineCard
selfTestSection
cloudSection
noteCard
}
.padding(.horizontal, 16)
.padding(.vertical, 20)
}
.background(Tj.Palette.sand.ignoresSafeArea())
.onAppear { modelService.refreshStates() }
}
/// (,):MLX · Metal GPU, Gemma 4 E2B
private var localEngineCard: some View {
HStack(spacing: 12) {
ZStack {
Circle().fill(Tj.Palette.amber.opacity(0.25))
Image(systemName: "bolt.fill")
.font(.tjScaled(18))
.foregroundStyle(Tj.Palette.ink)
}
.frame(width: 44, height: 44)
VStack(alignment: .leading, spacing: 2) {
Text("MLX · GPU")
.font(.tjScaled(15, weight: .semibold))
.foregroundStyle(Tj.Palette.text)
Text("Metal GPU · 端侧推理 Gemma 4 E2B")
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
.lineLimit(2)
}
Spacer()
Image(systemName: "checkmark.circle.fill")
.font(.tjScaled(18))
.foregroundStyle(Tj.Palette.leaf)
}
.padding(14)
.tjCard()
}
/// :/,(TjGhostButton),
/// /
@ViewBuilder
private var selfTestSection: some View {
if modelReady {
VStack(spacing: 12) {
Button {
withAnimation(.easeInOut(duration: 0.22)) { showSelfTest.toggle() }
} label: {
HStack(spacing: 8) {
Image(systemName: "gauge.with.needle")
.font(.tjScaled(15, weight: .semibold))
Text("性能自检")
Image(systemName: "chevron.down")
.font(.tjScaled(13, weight: .semibold))
.rotationEffect(.degrees(showSelfTest ? 180 : 0))
}
.frame(maxWidth: .infinity)
}
.buttonStyle(TjGhostButton())
if showSelfTest {
ModelSelfTestView(embedded: true)
.transition(.opacity.combined(with: .move(edge: .top)))
}
}
.padding(.top, 4)
} else {
VStack(spacing: 8) {
HStack(spacing: 8) {
Image(systemName: "gauge.with.needle")
.font(.tjScaled(15, weight: .semibold))
Text("性能自检")
}
.font(.tjScaled(15, weight: .semibold))
.foregroundStyle(Tj.Palette.text3)
.frame(maxWidth: .infinity)
.frame(height: 48)
.background(Capsule().strokeBorder(Tj.Palette.line, lineWidth: 1))
.opacity(0.6)
Text("模型未就绪,前往「模型管理」下载后可用")
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
}
.padding(.top, 4)
}
}
private var cloudConfigured: Bool {
cloudEnabled && !cloudKey.trimmingCharacters(in: .whitespaces).isEmpty
}
/// AI(Gemini)hybrid :(),
/// AI Studio key , / / Google Gemini
private var cloudSection: some View {
VStack(alignment: .leading, spacing: 12) {
HStack {
Text("云端 AI · Gemini")
.font(.tjTitle())
.foregroundStyle(Tj.Palette.text)
Spacer()
}
.padding(.top, 10)
VStack(alignment: .leading, spacing: 12) {
Toggle(isOn: $cloudEnabled) {
VStack(alignment: .leading, spacing: 2) {
Text("启用云端增强")
.font(.tjScaled(15, weight: .semibold))
.foregroundStyle(Tj.Palette.text)
Text("默认端侧 Gemma 4;开启后「读报告原图 / 深度解读 / 多语言」走 Google Gemini。")
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
}
}
.tint(Tj.Palette.leaf)
if cloudEnabled {
SecureField(String(appLoc: "粘贴 Google AI Studio 的 API Key"), text: $cloudKey)
.font(.tjScaled(14))
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.padding(12)
.background(RoundedRectangle(cornerRadius: Tj.Radius.md).fill(Tj.Palette.sand2))
HStack(spacing: 6) {
Image(systemName: cloudConfigured ? "checkmark.seal.fill" : "exclamationmark.circle")
.font(.tjScaled(13))
.foregroundStyle(cloudConfigured ? Tj.Palette.leaf : Tj.Palette.text3)
Text(cloudConfigured
? String(appLoc: "已就绪 · \(AIRuntime.cloudLabel)")
: String(appLoc: "请填入 API Key(aistudio.google.com 免费获取)"))
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
}
Text("Key 仅存本机;断网或额度用尽时自动回退端侧 Gemma 4,功能不中断。")
.font(.tjScaled(11))
.foregroundStyle(Tj.Palette.text3)
}
}
.padding(14)
.tjCard()
}
}
private var noteCard: some View {
Text("隐私优先:默认端侧 Gemma 4(MLX · Metal GPU)推理,数据不出设备;仅在你开启「云端 AI」后,深度任务才走 Google Gemini。切换后下一次 AI 调用生效。")
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(14)
.tjCard()
}
}
#Preview {
InferenceSettingsView()
}