Three new Foundation Models features to deepen user engagement with mental wellness: 1. AI Reflection Companion — personalized feedback after completing guided reflections, referencing the user's actual words with personality-pack-adapted tone 2. Mood Pattern Tags — auto-extracts theme tags (work, family, stress, etc.) from notes and reflections, displayed as colored pills on entries 3. Weekly Emotional Digest — BGTask-scheduled Sunday digest with headline, summary, highlight, and intention; shown as card in Insights tab with notification All features: on-device (zero cost), premium-gated, iOS 26+ with graceful degradation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
129 lines
4.7 KiB
Swift
129 lines
4.7 KiB
Swift
//
|
|
// FoundationModelsReflectionService.swift
|
|
// Reflect
|
|
//
|
|
// Generates personalized AI feedback after a user completes a guided reflection.
|
|
//
|
|
|
|
import Foundation
|
|
import FoundationModels
|
|
|
|
@available(iOS 26, *)
|
|
@MainActor
|
|
class FoundationModelsReflectionService {
|
|
|
|
// MARK: - Initialization
|
|
|
|
init() {}
|
|
|
|
// MARK: - Feedback Generation
|
|
|
|
/// Generate personalized feedback based on a completed guided reflection
|
|
/// - Parameters:
|
|
/// - reflection: The completed guided reflection with Q&A responses
|
|
/// - mood: The mood associated with this entry
|
|
/// - Returns: AI-generated reflection feedback
|
|
func generateFeedback(
|
|
for reflection: GuidedReflection,
|
|
mood: Mood
|
|
) async throws -> AIReflectionFeedback {
|
|
let session = LanguageModelSession(instructions: systemInstructions)
|
|
|
|
let prompt = buildPrompt(from: reflection, mood: mood)
|
|
|
|
let response = try await session.respond(
|
|
to: prompt,
|
|
generating: AIReflectionFeedback.self
|
|
)
|
|
|
|
return response.content
|
|
}
|
|
|
|
// MARK: - System Instructions
|
|
|
|
private var systemInstructions: String {
|
|
let personalityPack = UserDefaultsStore.personalityPackable()
|
|
|
|
switch personalityPack {
|
|
case .Default:
|
|
return defaultInstructions
|
|
case .MotivationalCoach:
|
|
return coachInstructions
|
|
case .ZenMaster:
|
|
return zenInstructions
|
|
case .BestFriend:
|
|
return bestFriendInstructions
|
|
case .DataAnalyst:
|
|
return analystInstructions
|
|
}
|
|
}
|
|
|
|
private var defaultInstructions: String {
|
|
"""
|
|
You are a warm, supportive companion responding to someone who just completed a guided mood reflection. \
|
|
Validate their effort, reflect their own words back to them, and offer a gentle takeaway. \
|
|
Be specific — reference what they actually wrote. Keep each field to 1 sentence. \
|
|
SF Symbols: sparkles, heart.fill, star.fill, sun.max.fill, leaf.fill
|
|
"""
|
|
}
|
|
|
|
private var coachInstructions: String {
|
|
"""
|
|
You are a HIGH ENERGY motivational coach responding to someone who just completed a guided mood reflection! \
|
|
Celebrate their self-awareness, pump them up about the growth they showed, and give them a power move for tomorrow. \
|
|
Reference what they actually wrote. Keep each field to 1 sentence. Use exclamations! \
|
|
SF Symbols: trophy.fill, flame.fill, bolt.fill, star.fill, figure.run
|
|
"""
|
|
}
|
|
|
|
private var zenInstructions: String {
|
|
"""
|
|
You are a calm, mindful guide responding to someone who just completed a guided mood reflection. \
|
|
Acknowledge their practice of self-awareness with gentle wisdom. Use nature metaphors. \
|
|
Reference what they actually wrote. Keep each field to 1 sentence. Speak with serene clarity. \
|
|
SF Symbols: leaf.fill, moon.fill, drop.fill, sunrise.fill, wind
|
|
"""
|
|
}
|
|
|
|
private var bestFriendInstructions: String {
|
|
"""
|
|
You are their supportive best friend responding after they completed a guided mood reflection. \
|
|
Be warm, casual, and validating. Use conversational tone. \
|
|
Reference what they actually wrote. Keep each field to 1 sentence. \
|
|
SF Symbols: heart.fill, hand.thumbsup.fill, sparkles, star.fill, face.smiling.fill
|
|
"""
|
|
}
|
|
|
|
private var analystInstructions: String {
|
|
"""
|
|
You are a clinical data analyst providing feedback on a completed mood reflection. \
|
|
Note the cognitive patterns observed, the technique application quality, and a data-informed recommendation. \
|
|
Reference what they actually wrote. Keep each field to 1 sentence. Be objective but encouraging. \
|
|
SF Symbols: chart.bar.fill, brain.head.profile, doc.text.magnifyingglass, chart.line.uptrend.xyaxis
|
|
"""
|
|
}
|
|
|
|
// MARK: - Prompt Construction
|
|
|
|
private func buildPrompt(from reflection: GuidedReflection, mood: Mood) -> String {
|
|
let moodName = mood.widgetDisplayName
|
|
let technique = reflection.moodCategory.techniqueName
|
|
|
|
let qaPairs = reflection.responses
|
|
.filter { !$0.answer.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }
|
|
.map { response in
|
|
let chips = response.selectedChips.isEmpty ? "" : " [themes: \(response.selectedChips.joined(separator: ", "))]"
|
|
return "Q: \(response.question)\nA: \(response.answer)\(chips)"
|
|
}
|
|
.joined(separator: "\n\n")
|
|
|
|
return """
|
|
The user logged their mood as "\(moodName)" and completed a \(technique) reflection:
|
|
|
|
\(qaPairs)
|
|
|
|
Respond with personalized feedback that references their specific answers.
|
|
"""
|
|
}
|
|
}
|