diff --git a/康康/Services/DiaryAssistService.swift b/康康/Services/DiaryAssistService.swift index b5fdd15..5f2ed52 100644 --- a/康康/Services/DiaryAssistService.swift +++ b/康康/Services/DiaryAssistService.swift @@ -98,4 +98,29 @@ struct DiaryAssistService { guard !questions.isEmpty else { throw AssistError.empty } return (Array(questions.prefix(4)), lastRate) } + + /// 把语音转写稿整理成健康日记草稿(spec 2026-06-10-voice-diary)。 + /// 失败(模型未就绪 / 输出为空)抛错,调用方回退为直接使用原话,不卡死。 + /// 与 suggest 同样走 AIRuntime actor 队列,自然与追问/拍照串行。 + func organize(transcript: String) async throws -> (text: String, decodeRate: Double) { + do { + try await AIRuntime.shared.prepare() + } catch { + throw AssistError.modelNotReady + } + + let prompt = DiaryAssistPrompts.organize(transcript: transcript) + var collected = "" + var lastRate: Double = 0 + let stream = await AIRuntime.shared.generate(prompt: prompt, maxTokens: 400) + for try await chunk in stream { + collected += chunk.text + if chunk.decodeRate > 0 { lastRate = chunk.decodeRate } + } + + let text = HealthExportService.stripThinkBlocks(collected) + .trimmingCharacters(in: .whitespacesAndNewlines) + guard !text.isEmpty else { throw AssistError.empty } + return (text, lastRate) + } }