11using Microsoft . Extensions . AI ;
22using Rappen . AI . WinForm ;
33using Rappen . XRM . Helpers . Extensions ;
4+ using Rappen . XTB . FetchXmlBuilder . AppCode ;
5+ using Rappen . XTB . FXB . AppCode ;
46using Rappen . XTB . FXB . Settings ;
57using System ;
68using System . Collections . Generic ;
@@ -21,7 +23,8 @@ public partial class AiChatControl : WeifenLuo.WinFormsUI.Docking.DockContent
2123 private AiModel model ;
2224 private string lastquery ;
2325 private Stopwatch callingstopwatch ;
24- private Dictionary < string , string > metaAttributes = new Dictionary < string , string > ( ) ;
26+ private Dictionary < string , List < SimpleAiMeta > > metaAttributes = new Dictionary < string , List < SimpleAiMeta > > ( ) ;
27+ private string logname = "AI" ;
2528
2629 #region Public Constructor
2730
@@ -54,6 +57,7 @@ internal void Initialize()
5457 fxb . ShowSettings ( "tabAiChat" ) ;
5558 return ;
5659 }
60+ logname = $ "AI-{ supplier . Name } ";
5761 model = supplier . Model ( fxb . settings . AiSettings . Model ) ;
5862 if ( model == null )
5963 {
@@ -83,8 +87,26 @@ private void SetTitle()
8387 TabText = Text ;
8488 }
8589
86- private void SendChatToAI ( string text )
90+ private void SendChatToAI ( object sender , EventArgs e = null )
8791 {
92+ var text = string . Empty ;
93+ var action = "Ask" ;
94+ switch ( sender )
95+ {
96+ case Button btn when btn == btnAiChatAsk :
97+ text = txtAiChat . Text ;
98+ break ;
99+
100+ case Button btn when btn == btnYes :
101+ text = "Yes please!" ;
102+ action = "Yes!" ;
103+ break ;
104+
105+ case Button btn when btn == btnExecute :
106+ text = "Please execute the FetchXML query!" ;
107+ action = "Execute!" ;
108+ break ;
109+ }
88110 if ( string . IsNullOrWhiteSpace ( text ) )
89111 {
90112 MessageBoxEx . Show ( fxb , "Please enter a question or request." , "AI Chat" , MessageBoxButtons . OK , MessageBoxIcon . Information ) ;
@@ -131,7 +153,7 @@ private void SendChatToAI(string text)
131153 + Environment . NewLine
132154 + PromptMyName . Replace ( "{callme}" , fxb . settings . AiSettings . MyName ) . Trim ( ) ;
133155 chatHistory . Initialize ( intro ) ;
134- fxb . LogUse ( action : "AI -Init", count : intro . Length , ai2 : true , ai1 : false ) ;
156+ fxb . LogUse ( $ " { logname } -Init", count : intro . Length , ai2 : true , ai1 : false ) ;
135157 }
136158 else if ( ! manualquery . EqualXml ( lastquery ) )
137159 {
@@ -141,6 +163,7 @@ private void SendChatToAI(string text)
141163
142164 chatHistory . IsRunning = true ;
143165 EnableButtons ( ) ;
166+ fxb . LogUse ( $ "{ logname } -{ action } ", count : text . Length , ai2 : true , ai1 : false ) ;
144167 callingstopwatch = Stopwatch . StartNew ( ) ;
145168 AiCommunication . CallingAI (
146169 text ,
@@ -176,7 +199,10 @@ private string ExecuteFetchXMLQuery([Description("The FetchXML Query to be Execu
176199 try
177200 {
178201 SetQueryFromAi ( fetchXml ) ;
202+ var sw = Stopwatch . StartNew ( ) ;
179203 var result = fxb . RetrieveMultipleSync ( fetchXml , null , null ) ;
204+ sw . Stop ( ) ;
205+ fxb . LogUse ( $ "{ logname } -Query-Execute", count : result is QueryInfo qi ? qi . Results . Entities . Count : 0 , duration : sw . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
180206 fxb . HandleRetrieveMultipleResult ( result ) ;
181207 return "Query executed successfully" ;
182208 }
@@ -210,11 +236,13 @@ private string UpdateCurrentFetchXmlQuery([Description("A well formed FetchXml q
210236 [ Description ( "Retrieves the logical name and display name of tables/entity that matches a description. The result is returned in a JSON list with entries of the format {\" LN\" :\" [logical name of entity]\" ,\" DN\" :\" [display name of entity]\" }. There may be many results, if a unique table cannot be found." ) ]
211237 private string GetMetadataForUnknownEntity ( [ Description ( "The name/description of a table." ) ] string tableDescription )
212238 {
239+ var entities = fxb . EntitiesToAi ( ) ;
240+ var json = System . Text . Json . JsonSerializer . Serialize ( entities , new System . Text . Json . JsonSerializerOptions ( ) ) ;
213241 var sw = Stopwatch . StartNew ( ) ;
214- var result = AiCommunication . SamplingAI ( PromptEntityMeta . Replace ( "{metadata}" , fxb . EntitiesToAiJson ( ) ) ,
242+ var result = AiCommunication . SamplingAI ( PromptEntityMeta . Replace ( "{metadata}" , json ) ,
215243 $ "Please find entries that match the description { tableDescription } ", supplier . Name , model . Name , fxb . settings . AiSettings . ApiKey ) ;
216244 sw . Stop ( ) ;
217- fxb . LogUse ( action : $ "AI- Entity-{ tableDescription } ", count : result . Length , duration : sw . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
245+ fxb . LogUse ( $ " { logname } -Meta- Entity-{ tableDescription } ", count : entities . Count , duration : sw . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
218246 return result ;
219247 }
220248
@@ -230,27 +258,28 @@ private string GetMetadataForUnknownAttribute([Description("The logical name of
230258 {
231259 try
232260 {
233- var aimeta = fxb . AttributesToAiJson ( entityName ) ;
261+ var aimeta = fxb . AttributesToAi ( entityName ) ;
234262 metaAttributes [ entityName ] = aimeta ;
235263 }
236264 catch ( Exception ex )
237265 {
238266 return $ "Error retrieving attribute metadata: { ex . Message } ";
239267 }
240268 }
241-
269+ var attributes = metaAttributes [ entityName ] ;
270+ var json = System . Text . Json . JsonSerializer . Serialize ( attributes , new System . Text . Json . JsonSerializerOptions ( ) ) ;
242271 var sw = Stopwatch . StartNew ( ) ;
243- var result = AiCommunication . SamplingAI ( PromptAttributeMeta . Replace ( "{metadata}" , metaAttributes [ entityName ] ) ,
272+ var result = AiCommunication . SamplingAI ( PromptAttributeMeta . Replace ( "{metadata}" , json ) ,
244273 $ "Please find attributes that match the description { attributeDescription } ", supplier . Name , model . Name , fxb . settings . AiSettings . ApiKey ) ;
245274 sw . Stop ( ) ;
246- fxb . LogUse ( action : $ "AI- Attribute-{ entityName } ", count : result . Length , duration : sw . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
275+ fxb . LogUse ( $ " { logname } -Meta- Attribute-{ entityName } ", count : attributes . Count , duration : sw . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
247276 return result ;
248277 }
249278
250279 private void HandlingResponseFromAi ( ChatResponse response )
251280 {
252281 callingstopwatch ? . Stop ( ) ;
253- fxb . LogUse ( action : "AI -Response", count : response . ToString ( ) . Length , duration : callingstopwatch ? . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
282+ fxb . LogUse ( $ " { logname } -Response", count : response . ToString ( ) . Length , duration : callingstopwatch ? . ElapsedMilliseconds , ai2 : true , ai1 : false ) ;
254283 txtAiChat . Clear ( ) ;
255284 txtUsage . Text = chatHistory . Responses . UsageToString ( ) ;
256285 EnableButtons ( ) ;
@@ -266,7 +295,7 @@ private void SetQueryFromAi(string fetch)
266295 lastquery = fetch ;
267296 MethodInvoker mi = ( ) => { fxb . dockControlBuilder . Init ( fetch , null , false , "Query from AI" , true ) ; } ;
268297 if ( InvokeRequired ) Invoke ( mi ) ; else mi ( ) ;
269- fxb . LogUse ( "AI-ChangingQuery ", ai2 : true , ai1 : false ) ;
298+ fxb . LogUse ( $ " { logname } -Query-Change ", ai2 : true , ai1 : false ) ;
270299 }
271300
272301 #endregion Private Methods
@@ -276,6 +305,10 @@ private void SetQueryFromAi(string fetch)
276305 private void AiChatControl_FormClosing ( object sender , FormClosingEventArgs e )
277306 {
278307 chatHistory ? . Save ( Paths . LogsPath , "FXB" ) ;
308+ if ( chatHistory ? . Initialized == true )
309+ {
310+ fxb . LogUse ( $ "{ logname } -Closing", count : chatHistory . Responses ? . Count , ai2 : true , ai1 : false ) ;
311+ }
279312 }
280313
281314 private void AiChatControl_DockStateChanged ( object sender , EventArgs e )
@@ -301,30 +334,15 @@ private void txtAiChatAsk_KeyDown(object sender, KeyEventArgs e)
301334 if ( e . KeyCode == Keys . Enter && e . Control && ! string . IsNullOrWhiteSpace ( txtAiChat . Text ) )
302335 {
303336 e . Handled = true ;
304- SendChatToAI ( txtAiChat . Text ) ;
337+ SendChatToAI ( btnAiChatAsk ) ;
305338 }
306339 else if ( e . KeyCode == Keys . Y && e . Control )
307340 {
308341 e . Handled = true ;
309- btnYes_Click ( ) ;
342+ SendChatToAI ( btnYes ) ;
310343 }
311344 }
312345
313- private void btnAiChatAsk_Click ( object sender , EventArgs e )
314- {
315- SendChatToAI ( txtAiChat . Text ) ;
316- }
317-
318- private void btnYes_Click ( object sender = null , EventArgs e = null )
319- {
320- SendChatToAI ( "Yes please!" ) ;
321- }
322-
323- private void btnExecute_Click ( object sender , EventArgs e )
324- {
325- SendChatToAI ( "Please execute the FetchXML query!" ) ;
326- }
327-
328346 private void btnCopy_Click ( object sender , EventArgs e )
329347 {
330348 var chat = chatHistory . ToString ( ) ;
0 commit comments