Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,7 @@ This event is meant to be used only for providing data source for the report. On

Below is an example that illustrates how to provide data source to the __Report__ item using the `Report.NeedDataSource` event.

```C#
private void Report1_NeedDataSource(object sender, System.EventArgs e)
{
string sql = @"SELECT Production.Product.Name, Production.Product.ProductNumber FROM Production.Product";
string connectionString = "Data Source=(local)\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True";
SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
(sender as Telerik.Reporting.Processing.Report).DataSource = dataSet;
}
```
{{source=CodeSnippets\CS\API\Telerik\Reporting\DataSourceEventSnippets.cs region=ReportNeedDataSource}}
{{source=CodeSnippets\VB\API\Telerik\Reporting\DataSourceEventSnippets.vb region=ReportNeedDataSource}}
## See Also

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,7 @@ When running the report in production the above code should work just fine. Howe

> When using __DbContext__ by default the context class generated (Database First or Model First) provides only a default (parameterless) constructor. However for design time purposes a constructor with connection string (string argument) is needed so that while processing the report the correct connection string can be passed. If Code First is used there is no need for a constructor with string parameter. That is because this approach uses connection strings without metadata (which is needed for the mapping). This means that the connection string of the context can be directly set to this connection string, without the need to be resolved first. Adding the needed constructor is as simple as it is adding the snippet below:

```C#
partial class AdventureWorksContext
{
public AdventureWorksContext(string connectionString) : base(connectionString) {}
}
```
{{source=CodeSnippets\CS\API\Telerik\Reporting\DataSourceEventSnippets.cs region=AdventureWorksDbContextConstructor}}
{{source=CodeSnippets\VB\API\Telerik\Reporting\DataSourceEventSnippets.vb region=AdventureWorksDbContextConstructor}}

{{source=CodeSnippets\CS\API\Telerik\Reporting\EntityDataSourceSnippets.cs region=ConnectionStringSnippet}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ reportingArea: WRDHTML5, WRDBlazorWrapper

The article explains how to configure the **AI Report Generator** in the Web Report Designer embedded in your Reporting web application.

For information on the AI Report Generator usage refer to the article [AI Report Generator](slug:wrd-genai-graph-gauge-design).
For information on the AI Report Generator usage, refer to the article [AI Report Generator](slug:wrd-genai-graph-gauge-design).

> note AI Report Generator for `Graph` and `Gauge` items is available starting with the `2026 Q2 (20.1.26.615)` Telerik Reporting release.

Expand All @@ -31,113 +31,51 @@ To enable AI Report Generator, follow these steps:

- Register the agent services in `Program.cs`. You must provide the `createClientCallback` implementation:

```CSharp
builder.Services.AddAIReportGenerator(
createClientCallback: GetChatClient
);
```
{{source=CodeSnippets\Blazor\Docs\ProgramWithRestConfig.cs region=WRD_AddAIReportGenerator}}

- Provide a custom `IChatClient` factory implementation for the `createClientCallback`.

The following snippets show the typical wiring with a custom `IChatClient` factory:

- **Azure OpenAI**:

```CSharp
static IChatClient GetChatClient(IConfiguration configuration)
{
const string aiClientConfigSection = "telerikReporting:AIReportGenerator";
var aiClientCreds = configuration[$"{aiClientConfigSection}:credential"];
var endpoint = configuration[$"{aiClientConfigSection}:endpoint"];
var model = configuration[$"{aiClientConfigSection}:model"];

return new Azure.AI.OpenAI.AzureOpenAIClient(new Uri(endpoint),
new ApiKeyCredential(aiClientCreds))
.GetChatClient(model)
.AsIChatClient();
}
```
{{source=CodeSnippets\Blazor\Docs\ProgramWithRestConfig.cs region=AzureOpenAI_IChatClientImplementation}}

- **OpenAI**:

```CSharp
static IChatClient GetChatClient(IConfiguration configuration)
{
const string aiClientConfigSection = "telerikReporting:AIReportGenerator";
var aiClientCreds = configuration[$"{aiClientConfigSection}:credential"];
var model = configuration[$"{aiClientConfigSection}:model"];

return new OpenAI.Chat.ChatClient(model, aiClientCreds).AsIChatClient();
}
```
{{source=CodeSnippets\Blazor\Docs\WrdAiReportGenerator.cs region=OpenAI_IChatClientImplementation}}

- Map the agent endpoint in `Program.cs`:

```CSharp
app.MapControllers();
app.UseAIAgentServices();
```
{{source=CodeSnippets\Blazor\Docs\ProgramWithConfigSection.cs region=MapAgentEndpoint}}

`UseAIAgentServices` maps the agent SignalR hub at `/wrd-ai-report-generator`. The Web Report Designer client connects to this endpoint when the **AI Report Generator** button is invoked. If the host removes this registration, the **AI Report Generator** button does not appear in the designer.

To host the hub at a custom path, for example when the application is deployed under a virtual application path, pass the path to `UseAIAgentServices`:
To host the hub at a custom path, for example, when the application is deployed under a virtual application path, pass the path to `UseAIAgentServices`:

```CSharp
app.UseAIAgentServices("/my-app/wrd-ai-report-generator");
```
{{source=CodeSnippets\Blazor\Docs\ProgramWithConfigSection.cs region=UseAIAgentServices}}

When you override the hub path, set `reportDesignerHubUrl` in `reportGeneratorHubOptions` to the same path "/my-app/wrd-ai-report-generator" so that the Web Report Designer client connects to the correct endpoint:

```TypeScript
reportGeneratorHubOptions: {
reportDesignerHubUrl: "/my-app/wrd-ai-report-generator"
}
```
{{source=CodeSnippets\Blazor\Docs\TypeScript\WrdAiReportGenerator.ts region=reportGeneratorHubOptions}}

To require authorization for the **AIAgentServices** SignalR endpoint, call `.RequireAuthorization()` on `UseAIAgentServices`. This is sufficient for **cookie-based authentication**:

```C#
app.UseAIAgentServices().RequireAuthorization();
```
{{source=CodeSnippets\Blazor\Docs\ProgramWithConfigSection.cs region=UseAIAgentServicesRequireAuthorization}}

The **bearer token authentication** requires additional back-end configuration: see [Authentication and authorization in ASP.NET Core SignalR: Bearer token authentication](https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-10.0#bearer-token-authentication). For this scenario, you must also configure the `reportGeneratorHubOptions` property of the Web Report Designer. The property accepts an `accessTokenFactory` callback that returns a `string` or `Promise<string>`.

The following example reads the token from the `localStorage`:

```TypeScript
reportGeneratorHubOptions: {
accessTokenFactory: () => localStorage.getItem("access_token") ?? ""
}
```
{{source=CodeSnippets\Blazor\Docs\TypeScript\WrdAiReportGenerator.ts region=reportGeneratorHubOptionsLocalStorage}}

The following example retrieves the token asynchronously from the endpoint "/auth/token":

```TypeScript
reportGeneratorHubOptions: {
accessTokenFactory: () => fetch("/auth/token").then(r => r.text())
}
```
{{source=CodeSnippets\Blazor\Docs\TypeScript\WrdAiReportGenerator.ts region=reportGeneratorHubOptionsEndpoint}}

As an alternative to passing delegates directly, call the `AddAIReportGenerator(IConfiguration)` overload to read the options from a `telerikReporting:AIReportGenerator` section in `appsettings.json`:

```JSON
{
"telerikReporting": {
"AIReportGenerator": {
"friendlyName": "MicrosoftExtensionsAzureOpenAI",
"credential": "YOUR_API_KEY",
"endpoint": "https://your-azure-openai-endpoint.cognitiveservices.azure.com",
"model": "gpt-4.1-mini",
"Store_SessionIdleTimeoutMinutes": 30,
"EnableConversationLogging": false,
"ConversationLogPath": null,
"ShowTokenUsage": false,
"RequestTimeout": 60,
"RequestMaxTokens": 100000
}
}
}
```
{{source=CodeSnippets\Blazor\Docs\JSON\WrdAiReportGenerator.json region=telerikReportingAIReportGenerator}}

The available options are:

Expand All @@ -147,11 +85,11 @@ The available options are:
| `endpoint` | The AI provider endpoint URL. For Azure OpenAI, this is your Azure Cognitive Services resource URL. Required when using the configuration-only overload. |
| `credential` | The API key used to authenticate with the AI provider. Required when using the configuration-only overload. |
| `model` | The deployment or model name to invoke (for example `gpt-4.1-mini`). Required when using the configuration-only overload. |
| `Store_SessionIdleTimeoutMinutes` | Idle timeout, in minutes, for an AI Report Generator chat session. Defaults to 1 day (1 440 minutes) when omitted. |
| `Store_SessionIdleTimeoutMinutes` | Idle timeout, in minutes, for an AI Report Generator chat session. Defaults to 1 day (1440 minutes) when omitted. |
| `EnableConversationLogging` | When `true`, conversation transcripts are written to disk after each agent interaction. Defaults to `false`. |
| `ConversationLogPath` | Base directory for conversation logs. Logs are organized into per-user, timestamped subfolders. When `null`, defaults to `{AppContext.BaseDirectory}/Conversations`. Used only when `EnableConversationLogging` is `true`. |
| `ShowTokenUsage` | When `true`, the chat progress bubble in the designer shows token usage information after each interaction. Defaults to `false`. |
| `RequestTimeout` | Timeout in seconds for a single agent interaction. When the request does not complete in the allotted time, it is cancelled and an error message is sent to the client. Defaults to `60`. |
| `RequestTimeout` | Timeout in seconds for a single agent interaction. When the request does not complete in the allotted time, it is cancelled, and an error message is sent to the client. Defaults to `60`. |
| `RequestMaxTokens` | Maximum total number of tokens (input and output) that a single agent interaction is allowed to consume. The interaction is terminated when the cumulative token count reaches this limit. Defaults to `100000`. |
| `Hub_MaximumReceiveMessageSize` | Maximum size in bytes of a SignalR message received from the client. Increase this value when working with large report definitions. Defaults to `1048576` (1 MB). |
| `Hub_ClientTimeoutInterval` | SignalR client timeout in seconds. When the client does not respond within this interval, the connection is dropped. Defaults to `60`. |
Expand All @@ -164,17 +102,13 @@ To restrict who can invoke AI Report Generator, gate the `Commands_AIAgent_Use`

The Web Report Designer requires `SignalR` version 10 or newer to run the AI Report Generator. For example, you may reference it from the official CDN:

```HTML
<script src="https://unpkg.com/@microsoft/signalr@10.0.0/dist/browser/signalr.js"></script>
```
{{source=CodeSnippets\Blazor\Docs\html\WrdAiReportGenerator.html region=SignalR_OfficialCdn}}

The **AI Report Generator** button does not appear in the designer without the SignalR reference.

Add the minimum required Kendo UI for jQuery set from our CDN if your app is not already using it:

```HTML
<script src="https://reporting.cdn.telerik.com/{{site.buildversion}}/js/webReportDesigner.kendo.min.js"></script>
```
{{source=CodeSnippets\Blazor\Docs\html\WrdAiReportGenerator.html region=KendoUIforJQuery_ReportingCdn}}

## Data Source Usage

Expand Down Expand Up @@ -208,7 +142,7 @@ The **AI Report Generator** is built on an agentic loop powered by `Microsoft.Ex
| `ResolveMinimalSchemaSet` | Returns the JSON Schemas for one or more Telerik Reporting model types and recursively pulls in the schemas of their required, non-polymorphic property types. The agent calls this first to learn the shape of the item it must produce. |
| `GetItemGuidance` | Returns curated, item-specific authoring guidance (for example, for `Graph`, `BarChart`, `LineChart`, `RadialGauge`, or `LinearGauge`) so the agent applies recommended defaults and avoids common pitfalls. |
| `GetSkill` | Returns cross-cutting authoring skills that cover concerns such as [expressions](slug:telerikreporting/designing-reports/connecting-to-data/expressions/using-expressions/expressions-as-values-of-item-properties), [conditional formatting](slug:telerikreporting/designing-reports/connecting-to-data/expressions/using-expressions/conditional-formatting), [bindings](slug:telerikreporting/designing-reports/connecting-to-data/expressions/using-expressions/bindings), [aggregates](slug:telerikreporting/designing-reports/connecting-to-data/expressions/expressions-reference/functions/aggregate-functions), and [sorting and filtering](slug:telerikreporting/designing-reports/connecting-to-data/expressions/using-expressions/grouping,-filtering-and-sorting). The agent loads only the skills relevant to the user's intent. |
| `GetDataSources` | Returns the data sources defined on the current report along with their field names and types. The agent calls this before writing any field expression so it never invents tables or columns. |
| `GetDataSources` | Returns the data sources defined on the current report along with their field names and types. The agent calls this before writing any field expression, so it never invents tables or columns. |
| `ValidateDefinitionDeep` | Validates the crafted JSON item definition in two stages: first against the JSON Schema for the given type, then by deserializing the definition into a live report item. The agent explicitly calls this tool after producing a candidate definition and receives any errors in natural language. It then revises the JSON and retries until both stages pass or a configured retry limit is reached. |

After the agent crafts a candidate item, it calls `ValidateDefinitionDeep` to check the definition. If validation fails, the agent receives the errors in natural language and revises the JSON. This cycle repeats until the item passes both the schema check and deserialization, or the configured retry limit is reached.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,8 @@ The `restReportService` element specifies the configuration settings for the Rep

For example, initializing the [ReportServiceConfiguration](/api/Telerik.Reporting.Services.WebApi.ReportsControllerBase#Telerik_Reporting_Services_WebApi_ReportsControllerBase_ReportServiceConfiguration) for the [ReportsControllerBase](/api/Telerik.Reporting.Services.WebApi.ReportsControllerBase) instance would look like this:

```C#
configurationInstance = new ConfigSectionReportServiceConfiguration
{
HostAppId = "Html5DemoApp",
ReportSourceResolver = new UriReportSourceResolver("PATH_TO_REPORTS_FOLDER")
.AddFallbackResolver(new TypeReportSourceResolver());
};
```
{{source=CodeSnippets\MvcCS\Controllers\ReportsControllerConfigSection.cs region=ConfigSectionReportServiceConfiguration}}
{{source=CodeSnippets\MvcVB\Controllers\ReportsControllerConfigSection.vb region=ConfigSectionReportServiceConfiguration}}

>note The initialization block does not have the [Storage](/api/Telerik.Reporting.Services.IReportServiceConfiguration#Telerik_Reporting_Services_IReportServiceConfiguration_Storage) property set, because it would override the values obtained from the configuration file.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@ position: 0

With the [2024 Q3 (18.2.24.806)](https://www.telerik.com/support/whats-new/reporting/release-history/progress-telerik-reporting-2024-q3-18-2-24-806) release of Telerik Reporting, the border radius of the WPF Report Viewer's borders can be modified from the code behind or the XAML:

```C#
public MainWindow()
{
this.InitializeComponent();
this.ReportViewer1.CornerRadius = new CornerRadius(15);
}
```
{{source=CodeSnippets\CS\API\Telerik\ReportViewer\Wpf\WindowRoundCorners.xaml.cs region=WpfViewerRoundCorners}}
{{source=CodeSnippets\CS\API\Telerik\ReportViewer\Wpf\WindowRoundCorners.xaml region=WpfViewerRoundCorners}}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,12 @@ In the examples below we show how to access a report item from within the report

If we are in the context of a WinForm or WPF Window and we need to access an item from the Report that is shown in a ReportViewer control with an embedded Reporting engine, we can proceed directly following the report hierarchy. We use a report source object of the same type as the report source assigned to the ReportViewer control. Consider the following code:

```C#
protected void Button1_Click(object sender, EventArgs e)
{
Telerik.Reporting.InstanceReportSource instanceReportSource = (Telerik.Reporting.InstanceReportSource)this.reportViewer1.ReportSource;
Telerik.Reporting.Report report = (Telerik.Reporting.Report)instanceReportSource.ReportDocument;
Telerik.Reporting.TextBox txt = report.Items.Find("productNameDataTextBox", true)[0] as Telerik.Reporting.TextBox;
}
```
{{source=CodeSnippets\CS\API\Telerik\ReportViewer\WinForms\Form1.cs region=AccessReportItemFromApp}}
{{source=CodeSnippets\VB\API\Telerik\Reporting\ProgrammaticReportCreationSnippets.vb region=AccessReportItemFromApp}}
Comment thread
todorarabadzhiev marked this conversation as resolved.

## Access report fields from a Table item

You can reference the report fields from a table item easily using the Report API hierarchy. Consider the following code:

```C#
private void tableTextBox_ItemDataBinding(object sender, EventArgs eventArgs)
{
//get the textbox from the sender object
Telerik.Reporting.Processing.TextBox textBox = (Telerik.Reporting.Processing.TextBox)sender;
//get the table object
Telerik.Reporting.Processing.Table table = (Telerik.Reporting.Processing.Table)textBox.Parent;
//get the detail section
Telerik.Reporting.Processing.DetailSection detail = (Telerik.Reporting.Processing.DetailSection)table.Parent;
//get the raw value from the Report datasource directly
textBox.Value = detail.DataObject["Data"];
}
```
{{source=CodeSnippets\CS\API\Telerik\Reporting\ReportItemValueSnippets.cs region=AccessTableFieldFromDataBinding}}
{{source=CodeSnippets\VB\API\Telerik\Reporting\ProgrammaticReportCreationSnippets.vb region=AccessTableFieldFromDataBinding}}
Loading