Skip to content

Commit 94cad50

Browse files
docs: review ai insights snippets (#1822)
* docs: review ai insights code snippets * docs: add ff example for custom ai client * docs: refactor ai-related code snippets * oops * fix code snippets --------- Co-authored-by: Dimitar Nikolov <[email protected]>
1 parent 0115e25 commit 94cad50

File tree

1 file changed

+267
-33
lines changed

1 file changed

+267
-33
lines changed

interactivity/AI-powered-insights.md

Lines changed: 267 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,60 +115,294 @@ Below is an example of how to configure the project for the `AzureOpenAI` option
115115
}
116116
````
117117
````XML
118-
<Telerik.Reporting>
119-
<AIClient
120-
friendlyName="MicrosoftExtensionsAzureOpenAI"
121-
model="gpt-4o-mini"
122-
endpoint="https://ai-explorations.openai.azure.com/"
123-
credential="..."
124-
requireConsent="false"
125-
allowCustomPrompts="false">
126-
<predefinedPrompts>
127-
<add text="Generate a summary of the report." />
128-
<add text="Translate the report into German." />
129-
</predefinedPrompts>
130-
</AIClient>
131-
</Telerik.Reporting>
118+
<Telerik.Reporting>
119+
<AIClient
120+
friendlyName="MicrosoftExtensionsAzureOpenAI"
121+
model="gpt-4o-mini"
122+
endpoint="https://ai-explorations.openai.azure.com/"
123+
credential="..."
124+
requireConsent="false"
125+
allowCustomPrompts="false">
126+
<predefinedPrompts>
127+
<add text="Generate a summary of the report." />
128+
<add text="Translate the report into German." />
129+
</predefinedPrompts>
130+
</AIClient>
131+
</Telerik.Reporting>
132132
````
133133

134134
## Customization
135-
The workflow of instantiating the AI Client and passing a request to it can be customized by overriding the following methods of the [ReportsController](/api/telerik.reporting.services.webapi.reportscontrollerbase) class:
136-
* [CreateAIThread(string, string, ClientReportSource)](/api/telerik.reporting.services.webapi.reportscontrollerbase#Telerik_Reporting_Services_WebApi_ReportsControllerBase_CreateAIThread_System_String_System_String_Telerik_Reporting_Services_WebApi_ClientReportSource_) - called when the AI Prompt dialog is to be displayed. In this method, the AI Client is instantiated either using the settings provided in the application configuration file, or by using the AIClientFactory instance provided with the Reporting REST Service Configuration (see [Extensibility]({%slug telerikreporting/designing-reports/adding-interactivity-to-reports/ai-powered-insights%}#extensibility) below. Providing custom logic in the method allows to control the UI properties of the AI Prompt dialog: changing or disabling the consent message, enabling/disabling custom prompts, etc. This logic can be based on the currently previewed report, represented by the property **ClientReportSource**.
137135

138-
{{source=CodeSnippets\MvcCS\Controllers\ReportsController.cs region=ReportsController_CreateAIThread_CheckReportSource}}
136+
The workflow of instantiating the AI client and passing a request to it can be customized by overriding the following methods of the [ReportsController](/api/telerik.reporting.services.webapi.reportscontrollerbase) class:
137+
* [CreateAIThread(string, string, ClientReportSource)](/api/telerik.reporting.services.webapi.reportscontrollerbase#Telerik_Reporting_Services_WebApi_ReportsControllerBase_CreateAIThread_System_String_System_String_Telerik_Reporting_Services_WebApi_ClientReportSource_) - called when the AI Prompt dialog is to be displayed. In this method, the AI client is instantiated either using the settings provided in the application configuration file, or by using the `AIClientFactory` instance provided with the Reporting REST Service Configuration (see [Extensibility]({%slug telerikreporting/designing-reports/adding-interactivity-to-reports/ai-powered-insights%}#extensibility) below). Providing custom logic in the method allows to control the UI properties of the AI Prompt dialog: changing or disabling the consent message, enabling/disabling custom prompts, etc. This logic can be based on the currently previewed report, represented by the property `ClientReportSource`.
138+
139+
* .NET
140+
141+
````C#
142+
/// <summary>
143+
/// Overrides the default <see cref="CreateAIThread(string, string, ClientReportSource)"/>, adding verification depending on the passed <see cref="ClientReportSource"/> parameter.
144+
/// </summary>
145+
/// <returns></returns>
146+
public override IActionResult CreateAIThread(string clientID, string instanceID, ClientReportSource reportSource)
147+
{
148+
if (reportSource.Report == "report-with-disabled-ai-insights.trdp")
149+
{
150+
return StatusCode(
151+
StatusCodes.Status403Forbidden,
152+
new
153+
{
154+
message = "An error has occurred.",
155+
exceptionMessage = "AI Insights functionality is not allowed for this report.",
156+
exceptionType = "Exception",
157+
stackTrace = (string?)null
158+
}
159+
);
160+
}
161+
162+
return base.CreateAIThread(clientID, instanceID, reportSource);
163+
}
164+
````
165+
166+
167+
* .NET Framework
168+
169+
````C#
170+
/// <summary>
171+
/// Overrides the default <see cref="CreateAIThread(string, string, ClientReportSource)"/>, adding verification depending on the passed <see cref="ClientReportSource"/> parameter.
172+
/// </summary>
173+
/// <returns></returns>
174+
public override HttpResponseMessage CreateAIThread(string clientID, string instanceID, ClientReportSource reportSource)
175+
{
176+
if (reportSource.Report == "SampleReport.trdp")
177+
{
178+
var errorResponse = new
179+
{
180+
message = "An error has occurred.",
181+
exceptionMessage = "AI Insights functionality is not allowed for this report.",
182+
exceptionType = "Exception",
183+
stackTrace = (string)null
184+
};
185+
186+
return this.Request.CreateResponse(HttpStatusCode.Forbidden, errorResponse);
187+
}
188+
189+
return base.CreateAIThread(clientID, instanceID, reportSource);
190+
}
191+
````
192+
193+
194+
* [UpdateAIPrompts(ClientReportSource, AIThreadInfo)](/api/telerik.reporting.services.webapi.reportscontrollerbase#collapsible-Telerik_Reporting_Services_WebApi_ReportsControllerBase_UpdateAIPrompts_Telerik_Reporting_Services_WebApi_ClientReportSource_Telerik_Reporting_Services_Engine_AIThreadInfo_) - called internally during the execution of the `CreateAIThread()` method. Provides easier access to the predefined prompts, allowing to alter or disable them based on custom logic like the role of the currently logged user, or on the currently previewed report, represented by the property `ClientReportSource`.
195+
196+
* .NET
197+
198+
````C#
199+
/// <summary>
200+
/// Modifies the collection of predefined prompts before displaying it in the AI Insights dialog.
201+
/// </summary>
202+
/// <param name="reportSource"></param>
203+
/// <param name="aiThreadInfo"></param>
204+
protected override void UpdateAIPrompts(ClientReportSource reportSource, AIThreadInfo aiThreadInfo)
205+
{
206+
if (reportSource.Report == "report-suitable-for-markdown-output.trdp")
207+
{
208+
aiThreadInfo.PredefinedPrompts.Add("Create a summary of the report in Markdown (.md) format.");
209+
}
210+
211+
base.UpdateAIPrompts(reportSource, aiThreadInfo);
212+
}
213+
````
214+
215+
216+
* .NET Framework
217+
218+
````C#
219+
/// <summary>
220+
/// Modifies the collection of predefined prompts before displaying it in the AI Insights dialog.
221+
/// </summary>
222+
/// <param name="reportSource"></param>
223+
/// <param name="aiThreadInfo"></param>
224+
protected override void UpdateAIPrompts(ClientReportSource reportSource, AIThreadInfo aiThreadInfo)
225+
{
226+
if (reportSource.Report == "report-suitable-for-markdown-output.trdp")
227+
{
228+
aiThreadInfo.PredefinedPrompts.Add("Create a summary of the report in Markdown (.md) format.");
229+
}
230+
231+
base.UpdateAIPrompts(reportSource, aiThreadInfo);
232+
}
233+
````
234+
235+
236+
* [GetAIResponse(string, string, string, string, AIQueryArgs)](/api/telerik.reporting.services.webapi.reportscontrollerbase#Telerik_Reporting_Services_WebApi_ReportsControllerBase_GetAIResponse_System_String_System_String_System_String_System_String_Telerik_Reporting_Services_Engine_AIQueryArgs_) - called every time when a prompt is sent to the AI model. Allows for examining or altering the prompt sent from the client, inspecting the state of the RAG optimization, or checking the estimated amount of tokens that the prompt will consume, by implementing a callback function assigned to the [ConfirmationCallback](/api/telerik.reporting.services.engine.aiqueryargs#collapsible-Telerik_Reporting_Services_Engine_AIQueryArgs_ConfirmationCallBack) property. Below, you will find several examples of how to override the `GetAIResponse` method to handle different scenarios.
237+
238+
* .NET
239+
240+
````C#
241+
/// <summary>
242+
/// Modifies the prompt sent from the client before passing it to the LLM.
243+
/// </summary>
244+
/// <returns></returns>
245+
public override async Task<IActionResult> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
246+
{
247+
args.Query += $"{Environment.NewLine}Keep your response concise.";
248+
249+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
250+
}
251+
````
252+
253+
254+
````C#
255+
/// <summary>
256+
/// Examines the approximate tokens count and determines whether the prompt should be sent to the LLM.
257+
/// </summary>
258+
/// <returns></returns>
259+
public override async Task<IActionResult> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
260+
{
261+
const int MAX_TOKEN_COUNT = 500;
262+
args.ConfirmationCallBack = (AIRequestInfo info) =>
263+
{
264+
if (info.EstimatedTokensCount > MAX_TOKEN_COUNT)
265+
{
266+
return ConfirmationResult.CancelResult($"The estimated token count exceeds the allowed limit of {MAX_TOKEN_COUNT} tokens.");
267+
}
268+
269+
return ConfirmationResult.ContinueResult();
270+
};
271+
272+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
273+
}
274+
````
275+
276+
277+
````C#
278+
/// <summary>
279+
/// Examines whether the RAG optimization is applied for the current prompt.
280+
/// </summary>
281+
/// <returns></returns>
282+
public override async Task<IActionResult> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
283+
{
284+
args.ConfirmationCallBack = (AIRequestInfo info) =>
285+
{
286+
if (info.Origin == AIRequestInfo.AIRequestOrigin.Client)
287+
{
288+
System.Diagnostics.Trace.TraceInformation($"RAG optimization is {info.RAGOptimization} for this prompt.");
289+
}
290+
291+
return ConfirmationResult.ContinueResult();
292+
};
293+
294+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
295+
}
296+
````
139297
140298
141-
* [UpdateAIPrompts(ClientReportSource, AIThreadInfo)](/api/telerik.reporting.services.webapi.reportscontrollerbase#collapsible-Telerik_Reporting_Services_WebApi_ReportsControllerBase_UpdateAIPrompts_Telerik_Reporting_Services_WebApi_ClientReportSource_Telerik_Reporting_Services_Engine_AIThreadInfo_) - called internally during the execution of the **CreateAIThread()** method. Provides easier access to the predefined prompts, allowing to alter or disable them based on custom logic like the role of the currently logged user, or on the currently previewed report, represented by the property **ClientReportSource**.
299+
* .NET Framework
142300
143-
{{source=CodeSnippets\MvcCS\Controllers\ReportsController.cs region=ReportsController_CreateAIThread_UpdateAIPrompts}}
301+
````C#
302+
/// <summary>
303+
/// Modifies the prompt sent from the client before passing it to the LLM.
304+
/// </summary>
305+
/// <returns></returns>
306+
public override async Task<HttpResponseMessage> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
307+
{
308+
args.Query += $"{Environment.NewLine}Keep your response concise.";
309+
310+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
311+
}
312+
````
144313

145314

146-
* [GetAIResponse(string, string, string, string, AIQueryArgs)](/api/telerik.reporting.services.webapi.reportscontrollerbase#Telerik_Reporting_Services_WebApi_ReportsControllerBase_GetAIResponse_System_String_System_String_System_String_System_String_Telerik_Reporting_Services_Engine_AIQueryArgs_) - called every time when a prompt is sent to the AI model. Allows for examining or altering the prompt sent from the client, inspecting the state of the RAG optimization, or checking the estimated amount of tokens that the prompt will consume, by implementing a callback function assigned to the [ConfirmationCallback](/api/telerik.reporting.services.engine.aiqueryargs#collapsible-Telerik_Reporting_Services_Engine_AIQueryArgs_ConfirmationCallBack) property.
315+
````C#
316+
/// <summary>
317+
/// Examines the approximate tokens count and determines whether the prompt should be sent to the LLM.
318+
/// </summary>
319+
/// <returns></returns>
320+
public override async Task<HttpResponseMessage> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
321+
{
322+
const int MAX_TOKEN_COUNT = 500;
323+
args.ConfirmationCallBack = (AIRequestInfo info) =>
324+
{
325+
if (info.EstimatedTokensCount > MAX_TOKEN_COUNT)
326+
{
327+
return ConfirmationResult.CancelResult($"The estimated token count exceeds the allowed limit of {MAX_TOKEN_COUNT} tokens.");
328+
}
329+
330+
return ConfirmationResult.ContinueResult();
331+
};
332+
333+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
334+
}
335+
````
147336
148-
{{source=CodeSnippets\MvcCS\Controllers\ReportsController.cs region=ReportsController_CreateAIThread_ModifyPrompt}}
149337
150-
{{source=CodeSnippets\MvcCS\Controllers\ReportsController.cs region=ReportsController_CreateAIThread_ConfirmationCallback_TokenCount}}
338+
````C#
339+
/// <summary>
340+
/// Examines whether the RAG optimization is applied for the current prompt.
341+
/// </summary>
342+
/// <returns></returns>
343+
public override async Task<HttpResponseMessage> GetAIResponse(string clientID, string instanceID, string documentID, string threadID, AIQueryArgs args)
344+
{
345+
args.ConfirmationCallBack = (AIRequestInfo info) =>
346+
{
347+
if (info.Origin == AIRequestInfo.AIRequestOrigin.Client)
348+
{
349+
System.Diagnostics.Trace.TraceInformation($"RAG optimization is {info.RAGOptimization} for this prompt.");
350+
}
351+
352+
return ConfirmationResult.ContinueResult();
353+
};
354+
355+
return await base.GetAIResponse(clientID, instanceID, documentID, threadID, args);
356+
}
357+
````
151358

152-
{{source=CodeSnippets\MvcCS\Controllers\ReportsController.cs region=ReportsController_CreateAIThread_ConfirmationCallback_RAGOptimization}}
153359

154360
## Extensibility
155361

156362
If necessary, the Reporting engine can use a custom `Telerik.Reporting.AI.IClient` implementation, which can be registered in the Reporting REST Service configuration:
157363

158-
````C#
364+
* .NET
365+
366+
````C#
159367
builder.Services.TryAddSingleton<IReportServiceConfiguration>(sp => new ReportServiceConfiguration
160-
{
161-
HostAppId = "MyApp",
162-
AIClientFactory = GetCustomAIClient,
163-
...
164-
});
368+
{
369+
HostAppId = "MyApp",
370+
AIClientFactory = GetCustomAIClient,
371+
// ...
372+
});
373+
374+
static Telerik.Reporting.AI.IClient GetCustomAIClient()
375+
{
376+
return new MyCustomAIClient(...);
377+
}
378+
````
165379
166-
static Telerik.Reporting.AI.IClient GetCustomAIClient()
167-
{
168-
return new MyCustomAIClient(...);
169-
}
380+
381+
* .NET Framework
382+
383+
````C#
384+
public class CustomResolverReportsController : ReportsControllerBase
385+
{
386+
static ReportServiceConfiguration configurationInstance;
387+
388+
static CustomResolverReportsController()
389+
{
390+
configurationInstance = new ReportServiceConfiguration
391+
{
392+
HostAppId = "MyApp",
393+
AIClientFactory = GetCustomAIClient,
394+
// ...
395+
};
396+
}
397+
}
398+
399+
static Telerik.Reporting.AI.IClient GetCustomAIClient()
400+
{
401+
return new MyCustomAIClient(...);
402+
}
170403
````
171404

405+
172406
## See Also
173407

174408
* [AI Insights Report Demo](https://demos.telerik.com/reporting/ai-insights)

0 commit comments

Comments
 (0)