@@ -171,46 +171,33 @@ public final class Agent: ObservableObject {
171171 /// - Explicit negative rules to avoid unnecessary tool use
172172 /// Community insights: "Instructions in English work best", "Use CAPS for critical rules"
173173 private func buildSystemPrompt( ) async -> String {
174- // Keep prompt concise (~600 chars = ~150 tokens) to maximize context for conversation
174+ // Format current date/time for relative date understanding
175+ let dateFormatter = DateFormatter ( )
176+ dateFormatter. dateFormat = " EEEE, MMMM d, yyyy 'at' h:mm a "
177+ let currentTime = dateFormatter. string ( from: Date ( ) )
178+
179+ // Keep prompt concise to maximize context for conversation
180+ // Optimized based on Foundation Models community insights
175181 var prompt = """
176- You are Clarissa, an iOS assistant.
177-
178- ALWAYS USE TOOLS FOR:
179- - Weather/temperature/forecast/rain/hot/cold -> weather tool
180- - Math/calculate/percent/tip/convert -> calculator tool
181- - Schedule/meeting/event/calendar/what's on -> calendar tool
182- - Remind me/task/to-do/don't forget/list reminders -> reminders tool
183- - Phone number/email/contact/call/text -> contacts tool
184- - Where am I/my location/current location -> location tool
185- - Remember that/remember I/my preference/I like -> remember tool
186- - URL/webpage/fetch/read page/get content -> web_fetch tool
187- - Image file URL (file://) needs analysis -> image_analysis tool
188- - PDF file URL (file://) needs reading -> image_analysis tool (pdf_extract_text or pdf_ocr)
189-
190- ANSWER DIRECTLY (no tools):
191- - Message contains " [Image Analysis] " -> USE the provided OCR text and classifications to respond
192- - Date/time/day -> answer from your knowledge
193- - General knowledge -> answer directly
194- - Opinions/advice -> respond conversationally
195- - Greetings/chat -> respond naturally
182+ You are Clarissa, a personal assistant. Be warm but concise.
183+ Current time: \( currentTime)
184+
185+ TOOLS: weather(location?), calculator(expression), calendar(action,title?,date?), reminders(action,title?), contacts(query), location(), remember(content), web_fetch(url), image_analysis(file_url)
186+
187+ USE TOOLS for: weather, math, calendar, reminders, contacts, location, saving facts, fetching URLs, analyzing images/PDFs
188+ ANSWER DIRECTLY for: " [Image Analysis] " in message (use provided OCR/classifications), date/time questions, general knowledge, opinions, greetings
196189
197190 EXAMPLES:
198- " Weather? " -> weather (no params = current location)
199191 " Weather in Paris " -> weather(location= " Paris " )
200- " What's 20% of 85? " -> calculator(expression= " 85 * 0.20 " )
201- " Meeting tomorrow 2pm " -> calendar(action=create, title, startDate)
202- " What's on my calendar? " -> calendar(action=list)
203- " Remind me to call Bob " -> reminders(action=create, title= " Call Bob " )
204- " Show my reminders " -> reminders(action=list)
205- " What's John's phone number? " -> contacts(action=search, query= " John " )
206- " Fetch example.com " -> web_fetch(url= " https://example.com " )
207- User: " Analyze this image [Image Analysis] Text: Hello World Contains: sign " -> " This image shows a sign with the text 'Hello World'. "
208-
209- RESPONSE RULES:
210- - Be brief (1-2 sentences)
192+ " What's 20% of 85? " -> calculator(expression= " 85*0.20 " )
193+ " Meeting tomorrow 2pm " -> calendar(action=create,title,startDate)
194+
195+ RULES:
196+ - Brief responses (1-2 sentences)
211197 - State result, not process
198+ - If request is ambiguous, ask one clarifying question before using tools
212199 - If tool fails, explain and suggest alternative
213- - If user asks about saved facts (name, preferences), answer from Saved Facts section
200+ - Use saved facts when user asks about their name/preferences
214201 """
215202
216203 // Add disabled tools section so AI can inform user about features that can be enabled
@@ -380,7 +367,7 @@ public final class Agent: ObservableObject {
380367 // The LLM session has already executed tools and incorporated results
381368 if nativeToolHandling {
382369 ClarissaLogger . agent. info ( " Agent run completed (native tool handling) " )
383- let finalContent = Self . applyRefusalFallback ( fullContent)
370+ let finalContent = Self . applyRefusalFallback ( fullContent, userMessage : userMessage )
384371 callbacks? . onResponse ( content: finalContent)
385372 return finalContent
386373 }
@@ -413,7 +400,7 @@ public final class Agent: ObservableObject {
413400
414401 // No tool calls - final response
415402 ClarissaLogger . agent. info ( " Agent run completed with response " )
416- let finalContent = Self . applyRefusalFallback ( fullContent)
403+ let finalContent = Self . applyRefusalFallback ( fullContent, userMessage : userMessage )
417404 callbacks? . onResponse ( content: finalContent)
418405 return finalContent
419406 }
@@ -442,19 +429,39 @@ public final class Agent: ObservableObject {
442429 " i'm sorry, but i can't "
443430 ]
444431
445- /// Friendly redirect message when model refuses
446- private static let refusalFallback = """
447- I'm best at helping with tasks like checking your calendar, setting reminders, getting weather updates, and doing calculations. What can I help you with?
448- """
432+ /// Context-aware suggestions based on what the user was trying to do
433+ private static func getRefusalSuggestion( for userMessage: String ) -> String {
434+ let lowercased = userMessage. lowercased ( )
435+
436+ // Detect intent and suggest relevant alternatives
437+ if lowercased. contains ( " weather " ) || lowercased. contains ( " temperature " ) || lowercased. contains ( " forecast " ) {
438+ return " I can check the weather for you. Try asking \" What's the weather in [city]? \" or just \" Weather? \" "
439+ }
440+ if lowercased. contains ( " remind " ) || lowercased. contains ( " reminder " ) || lowercased. contains ( " task " ) {
441+ return " I can help with reminders. Try \" Remind me to [task] \" or \" Show my reminders \" . "
442+ }
443+ if lowercased. contains ( " calendar " ) || lowercased. contains ( " meeting " ) || lowercased. contains ( " schedule " ) || lowercased. contains ( " event " ) {
444+ return " I can help with your calendar. Try \" What's on my calendar? \" or \" Schedule a meeting \" . "
445+ }
446+ if lowercased. contains ( " calculate " ) || lowercased. contains ( " math " ) || lowercased. contains ( " % " ) || lowercased. contains ( " tip " ) {
447+ return " I can do calculations. Try \" What's 20% of 85? \" or \" Calculate 15 + 27 \" . "
448+ }
449+ if lowercased. contains ( " contact " ) || lowercased. contains ( " phone " ) || lowercased. contains ( " email " ) || lowercased. contains ( " call " ) {
450+ return " I can look up contacts. Try \" What's [name]'s phone number? \" or \" Find [name]'s email \" . "
451+ }
452+
453+ // Default fallback
454+ return " I'm best at helping with your calendar, reminders, weather, calculations, and contacts. What can I help you with? "
455+ }
449456
450- /// Check if a response is a refusal and provide a helpful redirect if so
451- private static func applyRefusalFallback( _ content: String ) -> String {
457+ /// Check if a response is a refusal and provide a context-aware redirect if so
458+ private static func applyRefusalFallback( _ content: String , userMessage : String ) -> String {
452459 let lowercased = content. lowercased ( )
453460
454461 for phrase in refusalPhrases {
455462 if lowercased. contains ( phrase) {
456- ClarissaLogger . agent. info ( " Detected refusal response, applying fallback " )
457- return refusalFallback
463+ ClarissaLogger . agent. info ( " Detected refusal response, applying context-aware fallback " )
464+ return getRefusalSuggestion ( for : userMessage )
458465 }
459466 }
460467
0 commit comments