1 //
2 // SitiDefaults.swift
3 // Siti AI visionOS
4 //
5
6 import SwiftUI
7 import Onde
8
9 /// Mirrors `CHAT_SYSTEM_PROMPT` in `src-tauri/src/chat/mod.rs` so the native
10 /// visionOS client and the Tauri desktop/mobile client present the same
11 /// assistant persona.
12 enum SitiDefaults {
13 static let systemPrompt = """
14 You are Siti, a friendly and capable personal assistant that runs entirely on the user's device. Nothing the user says ever leaves the device.
15
16 You help with everyday things: answering questions, brainstorming, drafting and editing text, summarising, explaining ideas in plain terms, and planning.
17
18 Keep replies clear and concise, and prefer plain language. If a request is ambiguous, ask one short question instead of guessing. Use a short list only when it genuinely helps, and go easy on emoji.
19
20 You run locally, so you may not know about very recent events. When you are not sure, say so instead of inventing an answer.
21 """
22
23 static let promptSuggestions: [PromptSuggestion] = [
24 PromptSuggestion(
25 title: "How can I help?",
26 prompt: "What can you help me with on visionOS?"
27 ),
28 PromptSuggestion(
29 title: "Brainstorm",
30 prompt: "Give me three ideas for staying focused while working in a shared space."
31 ),
32 PromptSuggestion(
33 title: "Summarize",
34 prompt: "Explain the difference between a window and a volume in visionOS, in plain terms."
35 ),
36 PromptSuggestion(
37 title: "Draft something",
38 prompt: "Draft a short, friendly message asking a teammate to review my PR."
39 )
40 ]
41 }
42
43 struct PromptSuggestion: Identifiable, Hashable {
44 let title: String
45 let prompt: String
46
47 var id: String { title }
48 }
49
50 enum SamplingPreset: String, CaseIterable, Identifiable {
51 case balanced
52 case deterministic
53 case mobile
54
55 var id: String { rawValue }
56
57 var title: String {
58 switch self {
59 case .balanced:
60 return "Balanced"
61 case .deterministic:
62 return "Deterministic"
63 case .mobile:
64 return "Fast"
65 }
66 }
67
68 var subtitle: String {
69 switch self {
70 case .balanced:
71 return "General-purpose responses with a bit of creativity."
72 case .deterministic:
73 return "Reproducible, focused answers."
74 case .mobile:
75 return "Shorter responses with lower latency."
76 }
77 }
78
79 var samplingConfig: SamplingConfig {
80 switch self {
81 case .balanced:
82 return defaultSamplingConfig()
83 case .deterministic:
84 return deterministicSamplingConfig()
85 case .mobile:
86 return mobileSamplingConfig()
87 }
88 }
89 }
90
91 /// Makes any `Error` `Identifiable` so it can drive a SwiftUI `.alert`.
92 struct IdentifiableError: Identifiable {
93 let id = UUID()
94 let underlying: Error
95
96 init(_ error: Error) {
97 self.underlying = error
98 }
99
100 var message: String {
101 underlying.localizedDescription
102 }
103 }