@@ -738,16 +738,24 @@ struct ContentView: View {
738738 NavigationLink ( value: SidebarItem . voiceEngine) {
739739 Label ( " Voice Engine " , systemImage: " waveform " )
740740 . font ( . system( size: 15 , weight: . medium) )
741+ . padding ( . leading, 18 )
741742 }
742743 . listRowBackground ( self . sidebarRowBackground ( for: . voiceEngine) )
743744
744745 NavigationLink ( value: SidebarItem . aiEnhancements) {
745- Label ( " AI Enhancements " , systemImage: " sparkles " )
746+ Label ( " AI Enhancements " , systemImage: " brain " )
746747 . font ( . system( size: 15 , weight: . medium) )
748+ . padding ( . leading, 18 )
747749 }
748750 . listRowBackground ( self . sidebarRowBackground ( for: . aiEnhancements) )
749751 }
750752
753+ NavigationLink ( value: SidebarItem . preferences) {
754+ Label ( " Preferences " , systemImage: " gearshape.fill " )
755+ . font ( . system( size: 15 , weight: . medium) )
756+ }
757+ . listRowBackground ( self . sidebarRowBackground ( for: . preferences) )
758+
751759 NavigationLink ( value: SidebarItem . commandMode) {
752760 Label ( " Command Mode " , systemImage: " terminal.fill " )
753761 . font ( . system( size: 15 , weight: . medium) )
@@ -784,12 +792,6 @@ struct ContentView: View {
784792 }
785793 . listRowBackground ( self . sidebarRowBackground ( for: . history) )
786794
787- NavigationLink ( value: SidebarItem . preferences) {
788- Label ( " Preferences " , systemImage: " gearshape.fill " )
789- . font ( . system( size: 15 , weight: . medium) )
790- }
791- . listRowBackground ( self . sidebarRowBackground ( for: . preferences) )
792-
793795 NavigationLink ( value: SidebarItem . feedback) {
794796 Label ( " Feedback " , systemImage: " envelope.fill " )
795797 . font ( . system( size: 15 , weight: . medium) )
@@ -1228,13 +1230,27 @@ struct ContentView: View {
12281230 if let profile = SettingsStore . shared. selectedDictationPromptProfile {
12291231 let promptBody = SettingsStore . stripBaseDictationPrompt ( from: profile. prompt)
12301232 if !promptBody. isEmpty {
1233+ AnalyticsService . shared. capture (
1234+ . customPromptUsed,
1235+ properties: self . customPromptAnalyticsProperties (
1236+ promptSource: " profile " ,
1237+ overrideEmpty: nil
1238+ )
1239+ )
12311240 return SettingsStore . combineBasePrompt ( with: promptBody)
12321241 }
12331242 }
12341243
12351244 // Default override (including empty string to intentionally use no system prompt)
12361245 if let override = SettingsStore . shared. defaultDictationPromptOverride {
12371246 let trimmedOverride = override. trimmingCharacters ( in: . whitespacesAndNewlines)
1247+ AnalyticsService . shared. capture (
1248+ . customPromptUsed,
1249+ properties: self . customPromptAnalyticsProperties (
1250+ promptSource: " default_override " ,
1251+ overrideEmpty: trimmedOverride. isEmpty
1252+ )
1253+ )
12381254 // Empty override means explicitly use no system prompt
12391255 guard !trimmedOverride. isEmpty else { return override }
12401256
@@ -1245,6 +1261,28 @@ struct ContentView: View {
12451261 return SettingsStore . defaultDictationPromptText ( )
12461262 }
12471263
1264+ private func customPromptAnalyticsProperties( promptSource: String , overrideEmpty: Bool ? ) -> [ String : Any ] {
1265+ let providerID = SettingsStore . shared. selectedProviderID
1266+ let providerKey = self . providerKey ( for: providerID)
1267+ let selectedModel = SettingsStore . shared. selectedModelByProvider [ providerKey] ?? SettingsStore . shared. selectedModel ?? " "
1268+ let isCustomProvider = !ModelRepository. shared. isBuiltIn ( providerID)
1269+ let providerName = isCustomProvider ? " Custom Provider " : ModelRepository . shared. displayName ( for: providerID)
1270+
1271+ var properties : [ String : Any ] = [
1272+ " prompt_source " : promptSource,
1273+ " provider_id " : isCustomProvider ? " custom " : providerID,
1274+ " provider_name " : providerName,
1275+ " provider_type " : isCustomProvider ? " custom " : " built_in " ,
1276+ ]
1277+ if !selectedModel. isEmpty {
1278+ properties [ " model " ] = isCustomProvider ? " custom " : selectedModel
1279+ }
1280+ if let overrideEmpty {
1281+ properties [ " override_empty " ] = overrideEmpty
1282+ }
1283+ return properties
1284+ }
1285+
12481286 // MARK: - Local Endpoint Detection
12491287
12501288 private func isLocalEndpoint( _ urlString: String ) -> Bool {
0 commit comments