Files
OSGKeyboard/OSGKeyboardShared/Models/PolishContext.swift
T
Rocky 200265fbd6 feat(macos): local ASR model manager, menu-bar polish, and release 0.5.2
Adds a bundled local ASR model catalog for the macOS app with one-click
Sherpa Qwen3 / SenseVoice downloads (pause/resume, inline actions) and a
shared model storage directory used by MLX Qwen3. Fixes the light-mode
sidebar material and makes the menu-bar icon follow the system appearance
with a refreshed status mark. Renames the built product to OSGKeyboard.app.

Bumps version to 0.5.2 (build 19).
2026-07-09 08:55:37 +08:00

58 lines
2.2 KiB
Swift

// PolishContext.swift
// OSGKeyboard · Shared
//
// Bag of inputs the LLM polish service needs. Caller assembles it
// before calling `IntelligentPolishingService.polish(_:context:)`.
// Splitting it out keeps the polish service's signature stable as
// we add more signals (app context, intensity, personal dictionary,
// preceding text, etc.) over time.
import Foundation
public struct PolishContext: Sendable {
/// Coarse classification of the input field. When `.unknown` the
/// LLM is told to pick a neutral tone on its own.
public let appContext: AppContext
/// User-configured intensity. Drives how aggressively the LLM
/// is allowed to rewrite.
public let intensity: PolishIntensity
/// Optional preceding text (e.g. a few hundred characters of
/// what the user already typed before the recording). The LLM
/// uses it to resolve "this / 那个 / 刚才" references and to
/// bias terminology choices.
public let precedingText: String?
/// Extra dictionary block appended after `PersonalDictionary.promptFragment()`
/// (e.g. builtin `phrases.tsv` terms on macOS local ASR).
public let dictionarySupplement: String?
/// Cap on how many characters of `precedingText` we actually
/// include in the prompt. The full preceding text is often
/// hundreds of KB in a long note — we only need the tail.
public let maxPrecedingChars: Int
public init(
appContext: AppContext = .unknown,
intensity: PolishIntensity = .default,
precedingText: String? = nil,
dictionarySupplement: String? = nil,
maxPrecedingChars: Int = 500
) {
self.appContext = appContext
self.intensity = intensity
self.precedingText = precedingText
self.dictionarySupplement = dictionarySupplement
self.maxPrecedingChars = maxPrecedingChars
}
/// Truncated view of `precedingText` ready for prompt injection.
/// Returns `nil` when there is nothing meaningful to add.
public var precedingForPrompt: String? {
guard let raw = precedingText, !raw.isEmpty else { return nil }
if raw.count <= maxPrecedingChars { return raw }
return String(raw.suffix(maxPrecedingChars))
}
}