feat: polish scenarios and stabilize keyboard layout height

Add preset-driven polish scenarios (Settings, onboarding, ScenarioChip)
with ScenarioPrompt and style directives; drive keyboard height from
content (240pt) and use viewIsAppearing encapsulated-height offset for
smoother keyboard switches; remove redundant StatusBadge and hide system
dictation via hasDictationKey.
This commit is contained in:
Rocky
2026-06-29 00:08:00 +08:00
parent 4fec0da7f0
commit 1bdb8824ac
32 changed files with 1247 additions and 340 deletions
+25 -5
View File
@@ -560,11 +560,12 @@ final class FlowSessionManager: ObservableObject {
let engineMode = store.engineMode
let chunkNote = Self.chunkWarningMessage(chunkWarnings)
let shouldPolish = (engineMode == "cloud")
|| (engineMode == "local" && store.localModeCloudPolishEnabled)
// Re-read App Group at finalize so chip-side translation changes
// from the keyboard extension are visible before polish/translate.
let pipelineStore = AppGroupStore()
if !shouldPolish {
// Local engine, cloud-polish toggle off pure ASR.
if !pipelineStore.shouldRunCloudLLMStep {
// Local engine with cloud polish off ASR-only.
FlowSessionBridge.storeTranscriptionResult(text, polishWarning: chunkNote)
FlowDiagnostics.log(
"finalize ASR-only total=\(String(format: "%.1f", Date().timeIntervalSince(pipelineStarted)))s " +
@@ -580,8 +581,18 @@ final class FlowSessionManager: ObservableObject {
var delivered = text
let polishStarted = Date()
let polishMode = pipelineStore.polishModeForPipeline
FlowDiagnostics.log(
"finalize LLM mode=\(Self.polishModeLogLabel(polishMode)) " +
"translationTarget=\(pipelineStore.translationTargetLocaleId) " +
"cloudPolish=\(pipelineStore.localModeCloudPolishEnabled)"
)
do {
let polished = try await polisher.polish(text)
let polished = try await polisher.polish(
text,
mode: polishMode,
providerIdOverride: pipelineStore.polishProviderIdOverride
)
delivered = polished
FlowSessionBridge.storeTranscriptionResult(polished, polishWarning: chunkNote)
FlowDiagnostics.log(
@@ -611,6 +622,15 @@ final class FlowSessionManager: ObservableObject {
debug("utterance finalized length=\(text.count)")
}
private static func polishModeLogLabel(_ mode: PolishingService.PolishMode) -> String {
switch mode {
case .polish:
return "polish"
case .translate(let targetLocaleId):
return "translate(\(targetLocaleId))"
}
}
private static func chunkWarningMessage(_ warnings: [String]) -> String? {
guard !warnings.isEmpty else { return nil }
return warnings.joined(separator: "\n")