@@ -51,33 +51,26 @@ final class AIChatViewModel {
5151
5252 // MARK: - AI Action Dispatch
5353
54- private var queryLanguage : String {
55- guard let type = connection? . type else { return " sql " }
56- return PluginManager . shared. editorLanguage ( for: type) . codeBlockTag
57- }
58-
59- private var queryTypeName : String {
60- guard let type = connection? . type else { return " SQL query " }
61- return " \( PluginManager . shared. queryLanguageName ( for: type) ) query "
62- }
63-
6454 func handleFixError( query: String , error: String ) {
6555 startNewConversation ( )
66- let prompt = " Fix this \( queryTypeName) error: \n \n Query: \n ``` \( queryLanguage) \n \( query) \n ``` \n \n Error: \( error) "
56+ let databaseType = connection? . type ?? . mysql
57+ let prompt = AIPromptTemplates . fixError ( query: query, error: error, databaseType: databaseType)
6758 sendWithContext ( prompt: prompt, feature: . fixError)
6859 }
6960
7061 func handleExplainSelection( _ selectedText: String ) {
7162 guard !selectedText. isEmpty else { return }
7263 startNewConversation ( )
73- let prompt = " Explain this \( queryTypeName) : \n ``` \( queryLanguage) \n \( selectedText) \n ``` "
64+ let databaseType = connection? . type ?? . mysql
65+ let prompt = AIPromptTemplates . explainQuery ( selectedText, databaseType: databaseType)
7466 sendWithContext ( prompt: prompt, feature: . explainQuery)
7567 }
7668
7769 func handleOptimizeSelection( _ selectedText: String ) {
7870 guard !selectedText. isEmpty else { return }
7971 startNewConversation ( )
80- let prompt = " Optimize this \( queryTypeName) : \n ``` \( queryLanguage) \n \( selectedText) \n ``` "
72+ let databaseType = connection? . type ?? . mysql
73+ let prompt = AIPromptTemplates . optimizeQuery ( selectedText, databaseType: databaseType)
8174 sendWithContext ( prompt: prompt, feature: . optimizeQuery)
8275 }
8376
@@ -318,8 +311,7 @@ final class AIChatViewModel {
318311
319312 let settings = AppSettingsManager . shared. ai
320313
321- // Resolve provider from feature routing or use first enabled provider
322- guard let ( config, apiKey) = AIProviderFactory . resolveProvider ( for: feature, settings: settings) else {
314+ guard let resolved = AIProviderFactory . resolve ( for: feature, settings: settings) else {
323315 errorMessage = String ( localized: " No AI provider configured. Go to Settings > AI to add one. " )
324316 return
325317 }
@@ -342,8 +334,6 @@ final class AIChatViewModel {
342334 }
343335 }
344336
345- let provider = AIProviderFactory . createProvider ( for: config, apiKey: apiKey)
346- let model = AIProviderFactory . resolveModel ( for: feature, config: config, settings: settings)
347337 let systemPrompt = buildSystemPrompt ( settings: settings)
348338
349339 // Create assistant message placeholder
@@ -361,9 +351,9 @@ final class AIChatViewModel {
361351 do {
362352 // Exclude the empty assistant placeholder from sent messages
363353 let chatMessages = Array ( self . messages. dropLast ( ) )
364- let stream = provider. streamChat (
354+ let stream = resolved . provider. streamChat (
365355 messages: chatMessages,
366- model: model,
356+ model: resolved . model,
367357 systemPrompt: systemPrompt
368358 )
369359
@@ -432,4 +422,50 @@ final class AIChatViewModel {
432422 identifierQuote: idQuote
433423 )
434424 }
425+
426+ // MARK: - Schema Context
427+
428+ func fetchSchemaContext( ) async {
429+ let settings = AppSettingsManager . shared. ai
430+ guard settings. includeSchema,
431+ let connection,
432+ let driver = DatabaseManager . shared. driver ( for: connection. id)
433+ else { return }
434+
435+ let tablesToFetch = Array ( tables. prefix ( settings. maxSchemaTables) )
436+ var columns : [ String : [ ColumnInfo ] ] = [ : ]
437+ var foreignKeys : [ String : [ ForeignKeyInfo ] ] = [ : ]
438+
439+ for table in tablesToFetch {
440+ if let schemaProvider {
441+ let cached = await schemaProvider. getColumns ( for: table. name)
442+ if !cached. isEmpty {
443+ columns [ table. name] = cached
444+ }
445+ }
446+
447+ if columns [ table. name] == nil {
448+ do {
449+ let cols = try await driver. fetchColumns ( table: table. name)
450+ columns [ table. name] = cols
451+ } catch {
452+ Self . logger. warning (
453+ " Failed to fetch columns for table ' \( table. name) ': \( error. localizedDescription) "
454+ )
455+ }
456+ }
457+ }
458+
459+ do {
460+ let fkResult = try await driver. fetchForeignKeys ( forTables: tablesToFetch. map ( \. name) )
461+ for (table, fks) in fkResult {
462+ foreignKeys [ table] = fks
463+ }
464+ } catch {
465+ Self . logger. warning ( " Failed to bulk fetch foreign keys: \( error. localizedDescription) " )
466+ }
467+
468+ columnsByTable = columns
469+ foreignKeysByTable = foreignKeys
470+ }
435471}
0 commit comments