根据提供的code differences信息,我发现没有具体的代码变更内容。因此生成一个通用的commit message:

```
docs(readme): 更新文档说明

- 添加项目使用说明
- 完善配置指南
```

注意:由于未提供具体的代码差异信息,以上为示例格式。请提供实际的代码变更内容以生成准确的commit message。
This commit is contained in:
link2026
2026-07-01 10:30:22 +08:00
parent 404abbf10b
commit 558682c8f8
13 changed files with 44 additions and 680 deletions

View File

@@ -298,8 +298,7 @@ struct UnifiedCaptureFlow: View {
}
}
/// detached UIImage :, Sendable
/// ( MNNBackend.MNNUncheckedBox )
/// detached UIImage :, Sendable
private struct UncheckedImageBox: @unchecked Sendable {
let images: [UIImage]
}

View File

@@ -1,10 +1,9 @@
import SwiftUI
/// : Gemma-3n( 4bit), MLX/GPU
/// MNN/SME2 (Gemma-3n MNN ), MNN
/// ; AI (prepare/generate)
/// : Gemma-3n( 4bit),** MLX/GPU**
/// MNN/SME2 LLM (Gemma-3n MNN ),
/// , + + AI
struct InferenceSettingsView: View {
@AppStorage("kk.inferenceEngine") private var engineRaw = EnginePreference.auto.rawValue
// AI(Gemini) key CloudAI ,@AppStorage
@AppStorage("cloud_ai_gemini_enabled") private var cloudEnabled = false
@AppStorage("cloud_ai_gemini_key") private var cloudKey = ""
@@ -12,10 +11,6 @@ struct InferenceSettingsView: View {
/// , push
@State private var showSelfTest = false
private var selected: EnginePreference {
EnginePreference(rawValue: engineRaw) ?? .auto
}
/// (Gemma-3n,MLX)
private var modelReady: Bool {
modelService.states[.llm]?.phase == .ready
@@ -33,9 +28,7 @@ struct InferenceSettingsView: View {
.padding(.top, 4)
.padding(.bottom, 6)
ForEach(EnginePreference.allCases, id: \.self) { engine in
engineRow(engine)
}
localEngineCard
selfTestSection
cloudSection
@@ -48,6 +41,35 @@ struct InferenceSettingsView: View {
.onAppear { modelService.refreshStates() }
}
/// (,):MLX · Metal GPU, Gemma-3n 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-3n 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
@@ -97,75 +119,6 @@ struct InferenceSettingsView: View {
}
}
private func engineRow(_ engine: EnginePreference) -> some View {
let available = isAvailable(engine)
let isOn = (selected == engine)
return Button {
guard available else { return }
engineRaw = engine.rawValue
} label: {
HStack(spacing: 12) {
ZStack {
Circle().fill(isOn ? Tj.Palette.amber.opacity(0.25) : Tj.Palette.sand2)
Image(systemName: iconName(engine))
.font(.tjScaled(18))
.foregroundStyle(isOn ? Tj.Palette.ink : Tj.Palette.text2)
}
.frame(width: 44, height: 44)
VStack(alignment: .leading, spacing: 2) {
Text(engine.displayName)
.font(.tjScaled(15, weight: .semibold))
.foregroundStyle(Tj.Palette.text)
Text(subtitle(engine, available: available))
.font(.tjScaled(12))
.foregroundStyle(Tj.Palette.text3)
.lineLimit(2)
}
Spacer()
if isOn {
Image(systemName: "checkmark.circle.fill")
.font(.tjScaled(18))
.foregroundStyle(Tj.Palette.leaf)
}
}
.padding(14)
.tjCard()
.opacity(available ? 1 : 0.45)
}
.buttonStyle(.plain)
.disabled(!available)
}
/// .auto ;MLX MNN (Gemma-3n MNN ),
private func isAvailable(_ engine: EnginePreference) -> Bool {
switch engine {
case .auto: return true
case .mnn: return false
case .mlx: return InferenceEngine.mlx.isAvailable
}
}
private func iconName(_ engine: EnginePreference) -> String {
switch engine {
case .auto: return "wand.and.stars"
case .mnn: return "cpu.fill"
case .mlx: return "bolt.fill"
}
}
private func subtitle(_ engine: EnginePreference, available: Bool) -> String {
switch engine {
case .auto:
// Gemma-3n,auto MLX
return String(appLoc: "按本机配置选择 · 当前 MLX · GPU")
case .mnn:
return String(appLoc: "已停用:Gemma-3n 无 MNN 转换模型,统一走 MLX")
case .mlx:
return String(appLoc: "Metal GPU · 端侧推理 Gemma-3n E2B")
}
}
private var cloudConfigured: Bool {
cloudEnabled && !cloudKey.trimmingCharacters(in: .whitespaces).isEmpty
}

View File

@@ -167,12 +167,8 @@ struct MeView: View {
.buttonStyle(.plain)
}
private var engineDetail: String {
switch InferenceEngine.current {
case .mnn: return InferenceEngine.cpuSupportsSME2 ? "MNN · SME2" : "MNN · CPU"
case .mlx: return "MLX · GPU"
}
}
/// MLX/GPU(Gemma-3n E2B);MNN/SME2 LLM
private var engineDetail: String { "MLX · GPU" }
private var languageCard: some View {
NavigationLink {

View File

@@ -1,7 +1,7 @@
import SwiftUI
/// : prompt,(MNN·SME2 / MNN·NEON / MLX·GPU)
/// prefill / decode , (§12 2/6)
/// : prompt,(MLX·GPU,Gemma-3n E2B)
/// prefill / decode , (§12 2/6)
struct ModelSelfTestView: View {
@State private var output = ""
@State private var phase: Phase = .idle

View File

@@ -507,7 +507,7 @@ private struct TrendInsightCard: View {
text = try await TrendInsightService.shared.generate(for: bucket)
} catch {
// ,(CLAUDE.md §4)
let downloaded = ModelStore.shared.isComplete(for: .mnnLLM) || ModelStore.shared.isComplete(for: .llm)
let downloaded = ModelStore.shared.isComplete(for: .llm)
failedMessage = downloaded
? String(appLoc: "本地推理这次没成功,点右上「解读」重试")
: String(appLoc: "AI 解读需先在「我的 · 模型管理」下载模型")