@@ -17,6 +17,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
1717 case xai
1818 case venice
1919 case openrouter
20+ case azure
2021 case custom
2122
2223 var id : String { rawValue }
@@ -30,6 +31,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
3031 case . xai: return " xAI "
3132 case . venice: return " Venice AI "
3233 case . openrouter: return " OpenRouter "
34+ case . azure: return " Azure OpenAI "
3335 case . custom: return " Custom "
3436 }
3537 }
@@ -43,6 +45,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
4345 case . xai: return " Grok models "
4446 case . venice: return " Privacy-first AI "
4547 case . openrouter: return " Multi-provider "
48+ case . azure: return " Azure AI Foundry "
4649 case . custom: return " Custom endpoint "
4750 }
4851 }
@@ -56,6 +59,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
5659 case . xai: return " bolt.fill "
5760 case . venice: return " lock.shield.fill "
5861 case . openrouter: return " arrow.triangle.branch "
62+ case . azure: return " cloud.fill "
5963 case . custom: return " slider.horizontal.3 "
6064 }
6165 }
@@ -69,6 +73,8 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
6973 case . xai: return [ Color ( red: 0.1 , green: 0.1 , blue: 0.1 ) , Color ( red: 0.2 , green: 0.2 , blue: 0.2 ) ]
7074 case . venice: return [ Color ( red: 0.83 , green: 0.66 , blue: 0.33 ) , Color ( red: 0.72 , green: 0.53 , blue: 0.17 ) ]
7175 case . openrouter: return [ Color ( red: 0.95 , green: 0.55 , blue: 0.25 ) , Color ( red: 0.85 , green: 0.4 , blue: 0.2 ) ]
76+ // Azure blue brand colors
77+ case . azure: return [ Color ( red: 0.0 , green: 0.47 , blue: 0.84 ) , Color ( red: 0.0 , green: 0.35 , blue: 0.69 ) ]
7278 case . custom: return [ Color ( red: 0.55 , green: 0.55 , blue: 0.6 ) , Color ( red: 0.4 , green: 0.4 , blue: 0.45 ) ]
7379 }
7480 }
@@ -82,6 +88,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
8288 case . xai: return " https://console.x.ai/ "
8389 case . venice: return " https://venice.ai/settings/api "
8490 case . openrouter: return " https://openrouter.ai/keys "
91+ case . azure: return " https://portal.azure.com/#blade/Microsoft_Azure_ProjectOxford/CognitiveServicesHub/OpenAI "
8592 case . custom: return " "
8693 }
8794 }
@@ -98,6 +105,7 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
98105 var documentationURL : String ? {
99106 switch self {
100107 case . venice: return " https://docs.venice.ai "
108+ case . azure: return " https://learn.microsoft.com/en-us/azure/ai-services/openai/ "
101109 default : return nil
102110 }
103111 }
@@ -121,6 +129,13 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
121129 " Generate a new API key " ,
122130 " Copy and paste it here " ,
123131 ]
132+ case . azure:
133+ return [
134+ " Open Azure Portal and go to your OpenAI resource " ,
135+ " Click \" Keys and Endpoint \" in the left menu " ,
136+ " Copy KEY 1 or KEY 2 " ,
137+ " Paste it here — also set your resource name and deployment " ,
138+ ]
124139 default :
125140 return [
126141 " Go to \( name) console " ,
@@ -204,6 +219,19 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
204219 authType: . apiKey,
205220 providerType: . openaiLegacy
206221 )
222+ case . azure:
223+ // Host is intentionally empty: the user must supply their Azure resource name.
224+ // The actual host will be "<resource>.openai.azure.com".
225+ // basePath is unused for Azure — the full URL is constructed from azureDeploymentName.
226+ return ProviderPresetConfiguration (
227+ name: " Azure OpenAI " ,
228+ host: " " ,
229+ providerProtocol: . https,
230+ port: nil ,
231+ basePath: " / " ,
232+ authType: . apiKey,
233+ providerType: . azureOpenAI
234+ )
207235 case . custom:
208236 return ProviderPresetConfiguration (
209237 name: " " ,
@@ -222,6 +250,10 @@ enum ProviderPreset: String, CaseIterable, Identifiable {
222250 /// Attempts to match an existing RemoteProvider to a known preset by host.
223251 static func matching( provider: RemoteProvider ) -> ProviderPreset ? {
224252 let host = provider. host. lowercased ( ) . trimmingCharacters ( in: . whitespaces)
253+ // Match Azure by provider type (host varies per resource name)
254+ if provider. providerType == . azureOpenAI {
255+ return . azure
256+ }
225257 return knownPresets. first { preset in
226258 preset. configuration. host. lowercased ( ) == host
227259 }
0 commit comments