MentorAgent Docs
Menu

ReferencePackages: Novior.MentorAgent, Novior.MentorAgent.Abstractions, Novior.MentorAgent.Server, Novior.MentorAgent.Blazor, Novior.MentorAgent.Declarative

Configuration options

Every MentorOptions property with its type, default and effect, grouped by area, plus the options of the WebAssembly client and the YAML loader.

View as Markdown
On this page

MentorOptions holds every server-side setting of MentorAgent. You set it once, in the delegate you pass to AddMentorAgent. Each option below has its type, its default and its effect; a required option has no default.

Some options mention the coordinator, the main agent that answers the user, and its specialists: see The three agent levels.

Program.cs
builder.Services.AddScoped<CaseService>();
builder.Services.AddMentorAgent(options =>
{
    // Required: without them the options fail validation
    options.AppName = "Cases";
    options.ScanAssemblies = [typeof(CaseService).Assembly];
    options.ChatClient = chatClient; // or options.Agent, never both

    // Everything else has a default: set only what you change
    options.AppDescription = "Support case management for the service desk";
    options.RateLimitPerUser = 20;
});
ClassPackageWhere you set it
MentorOptionsNovior.MentorAgentAddMentorAgent(options => …)
MentorMcpServer, MentorHostedMcpServer, MentorRemoteAgent, AgentCardInfoNovior.MentorAgentThe McpServers, HostedMcpServers, RemoteAgents and AgentCard options
ModelPriceNovior.MentorAgent.AbstractionsThe values of ModelPricing
MentorAgentBlazorOptionsNovior.MentorAgent.BlazorAddMentorAgentBlazor(options => …), in a WebAssembly client
AgentDisplayInfoNovior.MentorAgent.AbstractionsThe values of MentorAgentBlazorOptions.RemoteAgentDisplays
MentorDeclarativeOptionsNovior.MentorAgent.DeclarativeAddMentorAgentDeclarative(o => …)

Novior.MentorAgent.Server has no options class. The SignalR hub, the Server-Sent Events (SSE) endpoint, the MCP server and the A2A agent all read MentorOptions. The paths of the hub and of the SSE endpoint are parameters of MapMentorAgentServer.

Novior.MentorAgent.Server also registers the MCP server and the A2A agent. AddMentorAgentServer() does it when their options are on. A host without the hub, such as a Blazor Server app, calls AddMentorAgentMcp() or AddMentorAgentA2A() after AddMentorAgent().

The widget reads a copy of its settings as MentorWidgetOptions, which MentorAgent fills from MentorOptions or from MentorAgentBlazorOptions. Set them there, not on MentorWidgetOptions.

MentorAgent checks the options when the host starts, not when you call AddMentorAgent. In an ASP.NET Core app or in a worker, an invalid configuration stops the start with the reason, before the first request. An app without such a host, such as a .NET MAUI app, has no start to check: the error appears the first time MentorAgent reads the options. The check throws InvalidOperationException when:

  • AppName is empty or blank;
  • ScanAssemblies is empty;
  • neither ChatClient nor Agent is set, or both are;
  • both ChatHistoryProvider and ChatHistoryProviderFactory are set.
  • The callback runs twice. AddMentorAgent runs your callback once on a copy of the options, to decide what to register, and once more when it builds the real options. Keep the callback free of side effects that must happen once.
  • Some options come from the copy. EnableObservability, ObservabilitySourceName, McpServerEnabled and A2AServerEnabled are read at registration, and so is AppName for the MCP server. Set them in the callback: a Configure<MentorOptions> registered after AddMentorAgent does not reach them. MentorAgent reads every other option from the real options.
  • A callback that throws on the copy leaves those options at their defaults. A warning with the exception is logged when the host starts.

string · Required

The name of your application. It goes into the system prompt, into the topic that the safety check and the off-topic check judge messages against, and into the A2A agent card.

string · Default: ""

One or two sentences on what your application does. The model reads it as context. The input safety check also uses it to judge messages: without a description, the check must guess what your application is about.

MentorLanguage · Default: English

The language of the replies and of the widget's texts: English, Italian, French, German, Spanish, Portuguese, Dutch, Polish, Japanese or Chinese. The confirmation box is built from the action's Description and its parameter names, which are not translated: write them in your users' language.

MentorshipLevel · Default: Standard

How much the agent explains and suggests:

  • Minimal: it carries out requests without explanations or suggestions. For expert users.
  • Standard: balanced answers, with suggestions when they are relevant.
  • Proactive: it explains what it did and why, suggests next steps and warns of risks. It may offer a next step only when a tool of the current request, a page, a skill, a specialist or a team can carry it out. The model does not always follow this rule, so it can still suggest an action your application does not have: see Known issues.

IChatClient? · Default: null

The model, as a Microsoft.Extensions.AI IChatClient: Azure OpenAI, OpenAI, Ollama or any provider that has one. This is the recommended path: specialists, teams, remote agents, hosted tools, tool filtering and routing need it. Set this or Agent, not both.

MentorAgent brings no SDK of a model provider. Add the package that your provider needs, for example Azure.AI.OpenAI or Microsoft.Extensions.AI.OpenAI. See Choose a path in Model providers.

AIAgent? · Default: null

A ready-made Agent Framework AIAgent. Use it for providers that do not expose an IChatClient, such as Foundry's AIProjectClient. For Foundry, add its package yourself. Features that need ChatClient are not available. Set this or ChatClient, not both. See Foundry agents (Path B).

IEmbeddingGenerator<string, Embedding<float>>? · Default: null

An embedding model, which turns a text into a list of numbers that represents its meaning, so that MentorAgent can compare texts. EnableToolFiltering, MemoryRelevanceFiltering and the Semantic RoutingStrategy need it. It does not turn them on: each has its own option. If you turn one on without an embedding model, MentorAgent logs a warning and the feature stays off.

Assembly[] · Required

The assemblies MentorAgent scans for actions, agents, teams, pages and skills. Usually [typeof(Program).Assembly]. See Attributes.

MentorTheme · Default: Default

The widget's theme: Default, Dark, Minimal or Custom. Custom injects no theme overrides and renders like Default: your stylesheet decides what changes.

ChatPosition · Default: BottomRight

Where the widget sits: BottomRight, BottomLeft, TopRight, TopLeft, or a full-height side panel with SideRight and SideLeft.

string? · Default: null

An accent color in hex, for example #2563EB. null keeps the theme's color.

string · Default: "Mentor AI"

The name shown in the widget header.

string? · Default: null

The URL of the avatar shown in the widget. null uses the built-in one.

string? · Default: null

The message shown while the chat is empty. The widget renders it as HTML, so never build it from user input. null uses the built-in message.

string? · Default: null

The placeholder of the input box. With null, the widget uses the text in the language of Language: "Write a message..." in English.

bool · Default: true

Shows starter suggestion chips in the widget's welcome panel. No hub event or SSE frame carries suggestions, so it has no effect on a React, Angular or Vue client, or on any other client of the hub.

bool · Default: true

Shows a feedback line while one of your tools runs; over the hub it sends ActionExecuting and ActionCompleted. Hosted tools have their own switch, ShowHostedToolActivity.

bool · Default: false

Shows a short guided tour the first time a user opens the widget. MentorAgent generates it from your [MentorPage] pages and the agent's tools. Novior.MentorAgent.Server answers GET /mentor/tour even when this option is false: a client of the server decides for itself whether to show the tour.

bool · Default: true

Renders a MentorCard returned by a tool as a card. With false the data reaches the model as text, and the model describes it.

bool · Default: true

Asks the coordinator to format answers as Markdown, with tables and lists. The widget always renders Markdown safely. With false, the coordinator is asked for short answers in plain text.

bool · Default: false

Shows a microphone button that uses the browser's Speech Recognition API. The browser does the recognition: in Chrome, for example, it sends the audio to its vendor's service, and only the transcript reaches MentorAgent. Another client does its own capture and sends the transcript as an ordinary message.

bool · Default: false

Reads replies aloud with the browser's Speech Synthesis API. Synthesis always happens on the client.

bool · Default: true

Speaks each sentence as it streams, instead of reading the finished answer back.

bool · Default: true

Stops the spoken answer when the user acts: presses the microphone, sends a message, presses Stop or starts a new conversation.

bool · Default: false

Lets the user talk without touching the widget: the message is sent when the user stops speaking, and the microphone opens again when the spoken answer ends. Ignored unless both EnableVoiceInput and EnableVoiceOutput are on.

double · Default: 1.0

The speech rate, passed to SpeechSynthesisUtterance.rate. The useful range is about 0.5 to 2.0.

bool · Default: false

Lets users send images with a message. In the widget, they can upload, paste or drag and drop an image, or give its URL. In Novior.MentorAgent.Server, images arrive as attachments of SendMessage and POST /mentor/chat. The chat model must support images.

int · Default: 4194304

The maximum size of one image, 4 MB. Checked on the server.

int · Default: 4

The maximum number of images in one message. Checked on the server.

IReadOnlyList<string> · Default: ["image/png", "image/jpeg", "image/gif", "image/webp"]

The accepted MIME types, as an allow-list. Anything else is dropped with a warning.

Before an action runs, MentorAgent can ask the user to confirm it, in the confirmation box. Agent Framework calls this step an approval: on this page, confirmation and approval mean the same thing. See Roles, confirmation and governance.

bool · Default: true

Turns confirmation on or off for the whole application. With true, the default, a tool asks for confirmation in three cases:

Do not confuse this option, RequireConfirmation, with the attribute parameter RequiresConfirmation.

With false:

  • no action or tool asks for confirmation;
  • RequiredRoles still refuses a user without the role;
  • the only approvals that still appear are those for the MCP servers that the model provider calls directly (HostedMcpServers);
  • tool filtering still reads what you declared: see EnableToolFiltering;
  • RequireActionForChangeRequests requires no action, because no action shows a confirmation box.

See Roles, confirmation and governance.

bool · Default: true

Makes a [MentorAction] ask for confirmation when it declares neither ReadOnly = true nor RequiresConfirmation. MentorAgent treats such an action as one that changes data. To keep an action out, declare it:

  • ReadOnly = true on an action that only reads, or IsReadOnlyAction by tool name;
  • RequiresConfirmation = false on a write that must run without asking.
CaseReview.cs
public class CaseReview(ICaseReviewStore store)
{
    // Declares nothing: MentorAgent treats it as a write, and it asks for confirmation
    [MentorAction(Description = "Reopens a closed support case")]
    public Task ReopenCaseAsync(string caseNumber, string reason)
        => store.ReopenAsync(caseNumber, reason);

    // Only reads: it never asks
    [MentorAction(Description = "Lists the notes of a support case", ReadOnly = true)]
    public Task<string> ListCaseNotesAsync(string caseNumber)
        => store.ListNotesAsync(caseNumber);

    // A write that is easy to undo and must run without asking
    [MentorAction(Description = "Flags a support case for review", RequiresConfirmation = false)]
    public Task FlagCaseAsync(string caseNumber)
        => store.FlagAsync(caseNumber);
}

An action that asks is withheld from the MCP server and from the A2A agent card, like every action that asks: nobody there can answer. Tool filtering does not send it when a message matches nothing.

The option covers [MentorAction] methods only. A method with only [Description] asks for nothing and stays on /mcp: mark it [MentorAction] to have the default.

The first time MentorAgent reads your actions, a warning lists the writes that run without confirmation, in two lists: the [MentorAction] methods that opted out, and the methods with only [Description] that are not declared read-only. MentorAgent reads your actions:

  • at startup, when the host maps the A2A agent or turns on WarmUpAtStartup;
  • at the first MCP request or the first request for the tour;
  • otherwise, at the first message.

With false, an action asks only when it declares RequiresConfirmation = true. RequireConfirmation set to false turns off every confirmation of your actions, this default included.

MentorHitlMode · Default: Blocking

How the server handles a confirmation. HITL stands for human in the loop, and Agent Framework calls a confirmation an approval.

  • Blocking: MentorAgent's own flow. The run waits for the user's answer.
  • Native: Agent Framework's approval protocol, for interoperability. After the answer, the turn resumes in a new run.

The confirmation box, the client protocol and the model calls are the same in both modes. When the user declines, in both modes the model is told that the user declined, that nothing was checked or changed, and that it must not give another reason.

With Native, Stop pressed while a confirmation box waits does not break the conversation: the next message answers the open request as not run. A snapshot saved after that Stop and restored later still carries the open request: see Known issues. See Blocking and Native modes.

Func<string, bool>? · Default: null

A predicate on the tool name: return true to ask the user to confirm before that tool runs. It works in addition to RequiresConfirmation. Use it for tools that have no attribute you can set, such as MCP tools and skills. The name is the tool name, not the method name: CloseCaseAsync becomes close_case.

Func<string, bool>? · Default: null

A predicate on the tool name: return true to declare that the action only reads. It does the same as ReadOnly on [MentorAction], for methods that have only [Description], or to declare many actions in one place. MentorAgent takes your word for it and does not check it.

  • The MCP server publishes the action with readOnlyHint.
  • RequireLookupForRecordQuestions can require the agent to call it.
  • A tool that needs confirmation is never read-only, whatever the predicate returns.
  • It does not apply to the tools of the MCP servers you connect to: their own readOnlyHint decides.

The name is the tool name, not the method name: GetCaseStatusAsync becomes get_case_status.

IList<Func<ToolAutoApprovalRuleContext, ValueTask<bool>>> · Default: empty

Works only with HitlMode = Native. MentorAgent evaluates the rules in order. The first rule that returns true approves the call, and no confirmation box appears. Setting a rule, or MaxAutoApprovalIterations, also turns on "don't ask again": after the user approves a call, matching calls stop asking for the rest of the session. A rule skips the question, not the role check: RequiredRoles still applies. Rules do not cover the tools of specialists and teams. A call that RequireActionForChangeRequests requires is never approved by a rule: the confirmation box always appears.

int? · Default: null

Native mode only. A cap on how many times one turn may run again because its approvals were granted by AutoApprovalRules. Each run is a billable model call. null uses Agent Framework's default.

bool · Default: false

Before each turn, asks a model whether the message is a prompt injection, a jailbreak or an attempt to extract the system prompt or credentials. It adds one call per message, on ClassifierChatClient.

TimeSpan · Default: 00:00:15

How long the input and output checks may take before they count as failed. TimeSpan.Zero or a negative value means no limit, and Stop still cancels a check. Raise it for a slow local model.

MentorSafetyCheckFailure · Default: Allow

What happens when a safety check gives no verdict, after a timeout or an error. Allow lets the message or the reply through, and logs a warning. Block refuses the message, or withholds the reply. A check that finds the message or the reply unsafe blocks it with both values.

bool · Default: false

Politely refuses a message that plainly has nothing to do with your application, without calling the coordinator. When the classifier is unsure, the message is answered: a name it does not recognize may be one of your records, and greetings, follow-up questions and questions about the agent are answered too.

MentorAgent judges the message against HostedToolDomainScope or, when that is not set, against your app's name, description, and the names and descriptions of your pages. With EnableSafetyCheck on, one call answers both questions, with a longer prompt. Without it, the option adds one small model call per turn. When HostedToolDomainCheck is on, a turn that is about to declare a hosted tool still asks that check its own, stricter question. Each refusal counts in GuardrailBlockCount and in the mentoragent.guardrail_blocks metric.

bool · Default: false

Builds one coordinator when the application starts, so the first user does not wait for the shared work: tool embeddings, shared MCP sessions, remote agent cards. It runs once the host has started, after a web host starts listening. A failure of the warm-up itself never stops the application, but an invalid configuration does. It needs a generic host, such as ASP.NET Core or a worker: a .NET MAUI app runs no hosted service, so there the option does nothing.

int · Default: 4000

The maximum length of a message, in characters. A longer message is refused before the model is called. 0 means no limit.

int · Default: 0

The maximum number of messages per user in each RateLimitWindowSecs window. 0 turns the limit off. MentorAgent counts a signed-in user by the same key as memory: the NameIdentifier claim, else sub, oid or the name. It counts an anonymous user by AnonymousIdentity. With the default, PerSession, a page reload starts a new count. So only signed-in users get a real limit per user.

The tool calls of the MCP server are limited too, with the same limit and window, but in an allowance of their own, separate from the chat messages of the same user. MentorAgent counts the caller by its NameIdentifier, sub or oid claim, or else by its name. A caller with none of them is counted by remote address when the host registers IHttpContextAccessor, as AddMentorAgentServer() and AddMentorAgentA2A() do. Otherwise all such callers share one allowance, and one busy client can use it up for the others. A call over the limit gets an isError result.

int · Default: 60

The length of the rate-limit window, in seconds.

bool · Default: false

Puts the exception message of a failing specialist or team into the reply the user reads. Development only.

These options add checks on messages and replies, your own or built in, and let you change tool results, error messages and the pipeline around ChatClient. A guardrail is a check you write: it returns true when the text is safe.

Func<string, CancellationToken, Task<bool>>? · Default: null

Your own check on each incoming message; return true when it is safe. When set, it runs on every message and replaces the built-in check of EnableSafetyCheck.

Func<string, CancellationToken, Task<bool>>? · Default: null

Your own check on the completed reply; return true when it is safe. While it is set, each reply is held back and shown after the check, without live streaming.

bool · Default: false

The built-in check on the reply: it blocks a reply that leaks instructions or secrets, discloses someone's personal data or contains harmful content. The reply is shown after the check. It runs on ClassifierChatClient, or on ChatClient when that is not set, and a custom OutputGuardrail takes precedence.

Func<string, object?, object?>? · Default: null

Transforms or redacts a tool result before it returns to the model. It receives the tool name and the result. It also runs on the result of each call to the MCP server, before the caller sees it. If the hook throws, an MCP caller gets an isError result and not the data. In the chat, the model is told that the action ran and that its result was withheld, and not to run it again.

Func<Exception, string?>? · Default: null

Maps an exception to the message the user sees. Return null to keep the built-in message.

When a tool throws, the message goes to the chat and to the model:

  • With the hook set, the chat never shows the text of the exception. It shows your message. When the hook returns null or an empty string, or throws, it shows "The action could not be completed." in the language of the widget.
  • The model gets your message or, without one, the message of the exception, because it needs a reason to answer. Return a message for any exception whose text must not reach the model.
  • Without the hook, the chat and the model both get the message of the exception.

Only an exception of the tool itself counts as a failure. The log has the type of the exception, and the whole exception at Debug level.

Func<ChatClientBuilder, ChatClientBuilder>? · Default: null

Adds your own middleware, such as logging or caching, to the pipeline that MentorAgent builds around ChatClient. Your middleware wraps MentorAgent's own middleware: it is the outermost layer.

These options control the history: the messages of the current conversation, which the model receives again at each turn. By default MentorAgent keeps the history in memory. A history provider can store it elsewhere, for example in a database.

int · Default: 50

The maximum number of messages that the default in-memory history keeps. Every message counts, tool calls and tool results included. MentorAgent removes whole turns, oldest first, so the model still sees the data that a tool read in the previous turn. 0 or a negative value turns trimming off, with a warning. MentorAgent does not read it when ChatReducer is set, for a history provider you supply, or with UseServiceManagedHistory.

IChatReducer? · Default: null

Replaces the reducer that keeps the default in-memory history short. A reducer decides which messages the history keeps. With null, MentorAgent uses a MentorChatReducer of MaxSessionMessages messages. It cuts whole turns, oldest first, and keeps every tool call together with its result.

When you set it, MentorAgent uses it as it is and does not read MaxSessionMessages. One instance serves every session, so it must not keep the state of one conversation. To keep only the text of the conversation, set a MessageCountingChatReducer: it is experimental in Microsoft.Extensions.AI (diagnostic MEAI001).

It applies to the default history of ChatClient only. A ChatHistoryProvider or ChatHistoryProviderFactory of yours is used as it is: give it a reducer yourself, for example new MentorChatReducer(50) from the namespace Novior.MentorAgent.Core. With UseServiceManagedHistory, or when you supply a provider, a set ChatReducer has no effect and MentorAgent logs a warning.

ChatHistoryProvider? · Default: null

A persistent history provider. One instance serves every user in the process: use it only in a single-user host, or with a provider that partitions its own storage. With Agent, set the provider on the agent instead.

Func<IServiceProvider, ChatHistoryProvider>? · Default: null

Builds a history provider once per coordinator: per circuit, per hub connection, per app instance. Prefer it whenever the application has more than one user. Setting it together with ChatHistoryProvider fails validation. The provider is kept across new conversations, so it must keep the transcript in the session, not in a field: see Conversation history and memory.

bool · Default: false

Set it when the chat client keeps the conversation on the service, as the OpenAI and Azure OpenAI Responses client does. MentorAgent then installs no history provider and no compaction, and MaxSessionMessages, ChatReducer, EnableCompaction and your history provider no longer apply. A session snapshot records how the history is kept, and a host that keeps it the other way refuses the snapshot.

Memory keeps facts about each user across conversations, such as a name, a role or a preference, and adds them to the prompt.

bool · Default: false

Turns on memory across conversations. MentorAgent identifies a signed-in user by the NameIdentifier claim, else by sub, oid or the name of the identity. A key made from sub, oid or the name starts with the claim name (sub:…, name:…), so a name never matches the identifier of another user. It identifies an anonymous user by AnonymousIdentity. A signed-in user with none of these is keyed as an anonymous one. Memories live in RAM unless you register your own IMentorMemoryStore before AddMentorAgent.

MentorAnonymousIdentity · Default: PerSession

Who an anonymous user is, for memory and for the rate limit. PerSession gives each circuit or connection its own key. Shared gives every anonymous user the same key, anonymous. Use Shared only in a single-user app, such as a .NET MAUI app: on a website, users would share memories and the rate limit. Ignored for a signed-in user.

int · Default: 10

How many memories go into the prompt: the most recent, or the most relevant with MemoryRelevanceFiltering.

bool · Default: false

Injects only the memories related to the message, by embedding similarity, plus the identity and preference facts. Needs EmbeddingGenerator; without it the most recent ones are used.

bool · Default: true

With UseMemoryContext on, a small extraction call after each message saves lasting facts about the user. With ChatClient, this call is the only way memories are saved, and the remember tool is removed. With Agent, the remember tool stays, and the extraction runs only when ClassifierChatClient is set. false saves the extra call.

Retrieval-augmented generation (RAG) lets the model answer from your own documents. For each message, before the coordinator answers, MentorAgent searches them and adds the relevant ones to the prompt.

You write the search yourself, as a class that implements IMentorRagSource, and register it in dependency injection. MentorAgent does not wrap an ITextSearch for you: call it from your own source.

MemberWhat it does
SearchAsync(string query, int maxResults, CancellationToken)Searches with the text of the message. Every source implements it.
SearchAsync(MentorRagRequest request, CancellationToken)The method that MentorAgent calls. Its default implementation calls the first one, so implement it only when the search needs more than the text.
DefaultMinScoreThe relevance threshold for the scores of your source. It applies when you do not set RagMinScore.

Do not make each SearchAsync call the other: the search would never return.

A MentorRagRequest holds:

PropertyHolds
Query, MaxResultsThe message of the user, and RagResultCount.
RecentMessagesThe messages before this one, oldest first: the user's messages and the replies of the last three turns of this conversation, as text. It is empty on the first turn, after a reset and after a restore. Over Server-Sent Events it is always empty, because each request is a conversation of its own.
UserThe caller of the hub, of /mentor/chat or of an A2A request. In a Blazor circuit, the user that the AuthenticationStateProvider of the host reports. It is null when the host has no authentication. An anonymous visitor has an unauthenticated principal. Filter restricted documents on it.
PageName, PageDataThe name of the current page and the data that the page put in context with IMentorPageContext.

A result is a MentorRagResult: the content, the source URL, the title and the score. It can also carry Metadata, facts about the document such as a date or a version. The model sees them under the title of the document, one key: value per entry, so it can tell the 2025 price list from the 2026 one. They also travel to the client with the citation chips, and the model can repeat them in its reply. Put nothing in them that the user must not see.

CaseKnowledgeSource.cs
public class CaseKnowledgeSource(ICaseKnowledge knowledge) : IMentorRagSource
{
    // The scores of this source are cosine similarities, between 0 and 1: say which threshold suits them
    public float? DefaultMinScore => 0.6f;

    // The method that MentorAgent calls: it sees who is asking
    public Task<IReadOnlyList<MentorRagResult>> SearchAsync(MentorRagRequest request, CancellationToken ct = default)
        => FindAsync(request.Query, request.MaxResults, request.User, ct);

    // Required by the interface. Share the search through a third method: never call one SearchAsync from the other
    public Task<IReadOnlyList<MentorRagResult>> SearchAsync(string query, int maxResults, CancellationToken ct = default)
        => FindAsync(query, maxResults, user: null, ct);

    async Task<IReadOnlyList<MentorRagResult>> FindAsync(string text, int max, ClaimsPrincipal? user, CancellationToken ct)
    {
        // The knowledge base returns only the articles that this user may read
        var articles = await knowledge.FindAsync(text, max, user, ct);
        return [.. articles.Select(a => new MentorRagResult(a.Text, a.Url, a.Title, a.Score)
        {
            // Facts the model weighs with the text: it can tell the 2025 price list from the 2026 one
            Metadata = new Dictionary<string, string> { ["valid from"] = a.ValidFrom },
        })];
    }
}

bool · Default: false

Searches your knowledge base before each coordinator call and adds the relevant documents to the prompt. Needs a registered IMentorRagSource.

int · Default: 5

How many documents are retrieved for each message.

float · Default: 2

The minimum relevance score of a document. The scale depends on your source. With keyword search, 2 means about two matches. With cosine similarity (a score from 0 to 1), use 0.5 to 0.75. 0 turns filtering off.

MentorAgent uses the first of these thresholds that applies:

  1. this option, when you set it in code or in configuration;
  2. the DefaultMinScore of the source, when it declares one;
  3. the default of this option, 2.

A source with cosine scores should declare a DefaultMinScore. Without one, the default 2 discards every document, and a warning says which threshold discarded them.

string · Default: "Use the following documents to answer:\n{documents}"

The text that introduces the documents in the prompt; {documents} is replaced with them.

bool · Default: false

Shows citation chips under the agent's replies. The pages of a hosted web search and the documents of a file search use the same chips. The Metadata of a document travels with its chip. Over the hub, the client receives it in the metadata field of RagSourcesReady.

A skill is a set of instructions, with optional resources, that the model loads only when it needs them. Until then, the prompt carries only the skill's name and description.

bool · Default: false

Turns on skill discovery and the load_skill and read_skill_resource tools. Skills are declared with [MentorSkill] or as files.

string · Default: "Skills"

The folder of file-based skills, with one sub-folder and one SKILL.md per skill. Relative to the content root, or absolute.

IList<AgentSkillsSource> · Default: empty

More skill sources, through Agent Framework's own abstraction: a database, a remote catalog or AgentFileSkillsSource. Your own skills win a name collision.

Func<AgentSkill, bool>? · Default: null

Keeps or drops a skill that comes from SkillSources. It never applies to the skills MentorAgent discovered itself.

TimeSpan? · Default: null

How long a list of skills from SkillSources stays fresh. While it is fresh, every session in the process shares it. The first session that starts after the interval reads the sources again. With null, there is no shared list: every new session reads the sources. Set it for a remote or slow source.

The Model Context Protocol (MCP) lets an AI application use tools from other programs. MentorAgent can be an MCP client: it uses the tools of external MCP servers. It can also be an MCP server: it publishes your actions to MCP clients.

MentorMcpServer[]? · Default: null

External MCP servers your application connects to as a client. Their tools become tools of the coordinator, like your actions. See MentorMcpServer.

bool · Default: false

Exposes your actions as an MCP server. The server is in the Novior.MentorAgent.Server package: call AddMentorAgentMcp() after AddMentorAgent (AddMentorAgentServer() does it for you), and app.MapMentorAgentMcp(). MentorAgent reads this option when you call AddMentorAgent, so set it in that callback.

Actions that need confirmation are never published, and that includes a [MentorAction] that asks by default: see RequireConfirmationForWrites and where nobody can answer. An action declared read-only is published with readOnlyHint: some MCP clients skip their own confirmation for such a tool, so declare it only on an action that really only reads. Every tool call passes through OnToolResult and RateLimitPerUser.

The endpoint has no CORS policy, which suits desktop and IDE clients. A client that runs in a browser needs an opt-in. See MCP server.

string · Default: "/mcp"

The path MapMentorAgentMcp() maps when you pass none. A path passed to the method wins.

Func<ClaimsPrincipal?>? · Default: null

Tells MentorAgent who is calling the MCP server. An action with RequiredRoles is then published to an authenticated caller who has one of its roles. With null, every action with RequiredRoles is withheld. They are also withheld when the resolver returns null or an unauthenticated user, or when it throws.

MentorAgent tests the roles with ClaimsPrincipal.IsInRole. A roles claim works once the identity names it as its RoleClaimType. With JwtBearer and MapInboundClaims = false, set TokenValidationParameters.RoleClaimType = "roles". MentorAgent calls the resolver once for each MCP request and never keeps the answer for another caller, so keep it cheap.

bool · Default: false

Shows a badge in the widget header with the connection status of McpServers.

The Agent-to-Agent (A2A) protocol lets AI agents call each other. MentorAgent can hand requests to remote A2A agents, and it can answer as an A2A agent itself. An A2A agent describes itself in an agent card, a JSON document at /.well-known/agent-card.json.

MentorRemoteAgent[]? · Default: null

Remote A2A agents the coordinator can hand requests to, like local specialists. They need ChatClient. Any user of your application can reach them: see MentorRemoteAgent.

bool · Default: false

Exposes your application as an A2A agent. The agent is in the Novior.MentorAgent.Server package: call AddMentorAgentA2A() after AddMentorAgent (AddMentorAgentServer() does it for you), and app.MapMentorAgentA2A(). MentorAgent reads this option when you call AddMentorAgent. See A2A server.

string · Default: "/a2a"

The path of the A2A task handler when you pass none to MapMentorAgentA2A(). The agent card stays at /.well-known/agent-card.json.

string? · Default: null

The full public URL of your A2A endpoint, path included. MentorAgent publishes it as it is in the agent card. With null, the card carries only the path: a MentorAgent caller resolves it against the address of the card, and another A2A client may not. Set it whenever other agents call this one.

AgentCardInfo? · Default: null

Extra metadata for the agent card; the name and description come from AppName and AppDescription. See AgentCardInfo.

bool · Default: false

Shows a badge in the widget header that lists the configured remote agents.

Hosted tools run on the model provider's infrastructure, not in your application: web search, code interpreter, file search, image generation and remote MCP servers. MentorAgent's roles and confirmation do not apply to them: see HostedTools.

MentorHostedTools · Default: None

The provider-hosted tools that the model may use, as flags: WebSearch, CodeInterpreter, FileSearch, ImageGeneration, HostedMcp. They run on the provider's infrastructure and need ChatClient. Which ones work depends on the client: the Responses client supports them all, and the Chat Completions client supports at most web search. Roles, confirmation and OnToolResult do not apply to them.

IReadOnlyList<string>? · Default: null

The provider's vector stores that FileSearch searches. Required when FileSearch is on: without an id the tool is skipped and a warning is logged.

int? · Default: null

An upper bound on file-search matches. null lets the provider decide.

string? · Default: null

The model ImageGeneration uses, for example gpt-image-1-mini. On Azure OpenAI it is not enough: the image deployment must also travel in the x-ms-oai-image-generation-deployment request header, which you add where you build the Azure client.

string? · Default: null

The size of generated images as WIDTHxHEIGHT, for example 1024x1024: the setting that controls the cost of image generation. A value that cannot be read is ignored with a warning.

IReadOnlyList<MentorHostedMcpServer>? · Default: null

The remote MCP servers the provider connects to for HostedMcp. Required when HostedMcp is on. See MentorHostedMcpServer.

bool · Default: true

Shows hosted-tool work while it happens: "Searching the web…", "Running code…", "Generating the image…". Citations also need ShowRagSources.

bool · Default: false

Shows a badge in the widget header that lists the active hosted tools. A development aid.

bool · Default: true

Offers each hosted tool to the model only when the semantic filter finds it relevant to the message. Needs EnableToolFiltering and EmbeddingGenerator; without them nothing is filtered and a warning is logged.

float? · Default: null

The similarity threshold for hosted tools; null means 0.15. Keep it low: this filter is only a first, rough selection, and HostedToolDomainCheck makes the final decision.

bool · Default: false

Before a hosted tool runs, asks a small model whether the message concerns your application. The check runs once per turn, and only when a hosted tool passed the filter. If the check itself fails, because of an error or an unexpected answer, the turn goes on. When the check says that the message is not about your application, the agent is told that the hosted tools are not for this request. It still answers with your own actions when the request is about your application.

string? · Default: null

The topic the off-topic check judges against: what counts as being about your application. null derives it from AppName, AppDescription and the page names. When hosted tools are on, the derived text also lists the enabled capabilities, and says that they do not widen the topic. RefuseOutOfScope uses the text you set, as written.

Func<string, CancellationToken, Task<bool>>? · Default: null

Replaces the model call of the off-topic check with your own decision: return true when the message is about your application.

int · Default: 0

A hard cap on hosted-tool calls per session. Beyond it, hosted tools are no longer offered to the model. 0 means no cap. Over SignalR the session is the connection, while each request to /mentor/chat, GET or POST, is a session of its own.

These options reduce the tokens sent to the model on each call, and so the cost.

bool · Default: false

Sends the model only the tools relevant to the message, by embedding similarity. The core tools are always sent: navigation, memory, delegation to specialists and teams, skills and UI actions. Needs EmbeddingGenerator and ChatClient: without them, every tool is sent and a warning is logged.

The embedding ranks the actions well, but its score is not calibrated: a question that needs data can score below a greeting. So the filter does not rely on the threshold alone:

  • When no action scores above ToolFilterMinScore, the three best-ranked actions that need no confirmation and no role are sent anyway, within ToolFilterMaxTools. An MCP tool qualifies only when its server marks it readOnlyHint. This adds about 80 input tokens to each model call on such turns, greetings included.
  • When every selected action needs confirmation, up to three of the best-ranked actions that do not need it are sent with them, within ToolFilterMaxTools.
  • When a single selected action needs no confirmation, it is sent alone, unless ToolFilterMinTools asks for more.

An action needs confirmation when it has RequiresConfirmation, when RequiresApproval matches it, when it comes from a server with MentorMcpServer.RequiresConfirmation, or when it is a [MentorAction] that RequireConfirmationForWrites makes ask. The filter reads these declarations even when RequireConfirmation is false. An action without confirmation can therefore reach the model on any message. Let every action that changes data ask: a [MentorAction] does by default, but a method with [Description] alone does not.

A message that matches no action carries the actions that the previous message selected. So the answer to the agent's own question, such as "Yes, go ahead", still arrives with the action that the question was about. The actions are carried one message back only, never twice, and an action that needs confirmation is never carried alone. A new or restored conversation carries nothing.

Two opt-in options use the selection of the filter: RequireLookupForRecordQuestions and RequireActionForChangeRequests.

int · Default: 12

The maximum number of matched tools sent, in addition to the core tools.

int · Default: 0

Once one action scores above ToolFilterMinScore, at least this many of the best-ranked actions are sent, up to ToolFilterMaxTools. With 0, the threshold alone decides. It is a trade-off. It can add the read action that the model needed. It can also add a wrong action that the model picks instead. You do not need it to keep an action that needs confirmation from reaching the model alone: EnableToolFiltering already sends other actions with it. It does not apply to a message where no action scores above ToolFilterMinScore: that message gets the three best-ranked actions that need no confirmation and no role.

float · Default: 0.35

The minimum cosine similarity, from 0 to 1, for a tool to count as relevant. Higher is stricter. The line decides which actions match, not whether a message needs an action: see EnableToolFiltering.

bool · Default: false

Makes the agent read a value before it answers a question about your records. A classifier model reads each message. When it says that the message asks for a value of your records (a price, a stock level, the status of an order), the first model call must call a read-only action. It must be one that the tool filter selected for that message. The agent can also hand the request to a specialist or a team. It then writes the reply from what the action returned.

  • Which actions. Those you declared read-only, with ReadOnly or IsReadOnlyAction, and the tools that a connected MCP server marks readOnlyHint. An action that needs confirmation or a role is never required.
  • What it needs. EnableToolFiltering, an EmbeddingGenerator, a ChatClient and at least one declared read. Otherwise the option has no effect, and a startup warning says so.
  • What it costs. One small classifier call on each turn whose selection holds a declared read. Because tool filtering also sends reads when nothing matches, that is nearly every turn. The call runs on ClassifierChatClient when you set one, within SafetyCheckTimeout. The reply starts after the result of the action, so a Proactive sentence such as "I am looking it up" no longer comes first.
  • When it does not force. A message addressed by name to one of your specialists, teams or remote agents is not forced. If the classifier fails, times out or gives an answer it cannot read, the turn runs as it would without the option.

bool · Default: false

Makes the agent start a change with the action itself. The confirmation box then comes before any sentence. Without it, the model can answer "Stock updated" without calling anything: no box appears, and nothing changes.

A classifier model reads each message. It checks two things: whether the message asks to carry out one of your actions that need confirmation, and whether the message gives every input that the action needs. If both are true, the first model call must call one of those actions, chosen from the ones that the tool filter selected for that message. The agent can also hand the request to a specialist or a team. When the message asks for one of your [MentorPage] pages, the first call must be navigate_to.

  • A request that leaves something out is not forced. The classifier sees the inputs that each action requires. A request is not complete when an input is missing, when the record is only described ("cancel the last order"), when a name is given where the input is an ID, or when the new value depends on the current one ("add 5 units"). The agent may then ask, as it would without the option. An input counts as needed only when the action's schema marks it required.
  • Which actions. Only actions that show a confirmation box: confirmation declared with RequiresConfirmation, RequiresApproval or MentorMcpServer.RequiresConfirmation, or asked by default for a [MentorAction] that changes data (RequireConfirmationForWrites), and RequireConfirmation on. An action is never required when its input schema cannot be shown faithfully: a schema with $ref or a combination of schemas, or an MCP tool that marks no parameter as required.
  • With HitlMode.Native. No rule of AutoApprovalRules is consulted for a required call, so the box always appears.
  • Pages. A page that your application does not have, or something within the page that is already open, is not forced. A request from another agent never has to navigate.
  • What it needs and costs. EnableToolFiltering and an EmbeddingGenerator. One small classifier call on each turn while the application has a page, or the message selected such an action. With RequireLookupForRecordQuestions on as well, one call answers both. A startup warning says when the option has no effect, or covers page requests only.

The turn that answers a confirmation left open by Stop is never forced.

bool · Default: false

Shortens a long conversation history before each model call, without calling a model: old tool results are collapsed, and the last CompactionMaxTurns turns are kept. It changes what is sent to the model, never the conversation that is stored: the history provider and the session snapshots keep every message. It works with ChatClient and a history kept by your application: the built-in provider, ChatHistoryProviderFactory or ChatHistoryProvider. With UseServiceManagedHistory it is not installed.

int · Default: 4000

The size of the history, in tokens, at which compaction starts. If the history is still larger after compaction, it is truncated to this size.

int · Default: 8

The recent user turns kept intact.

Model routing sends the turns that need it to a stronger, more expensive model, StrongChatClient, and keeps the others on ChatClient. ClassifierChatClient is the model for MentorAgent's own short decisions: a small, fast model is enough.

IChatClient? · Default: null

A stronger, more expensive model for the turns that need it; ChatClient stays the default. Routing also needs what RoutingStrategy requires: otherwise a warning is logged and every turn stays on ChatClient.

MentorRoutingStrategy · Default: Custom

How MentorAgent chooses between ChatClient and StrongChatClient:

  • Custom: calls your UseStrongModelAsync or UseStrongModel.
  • Semantic: compares the message with RoutingComplexExemplars. Needs EmbeddingGenerator.
  • Classifier: asks a small model, RoutingClassifierClient, with one extra call per turn.
  • Cascade: answers with the cheap model first, and runs the turn again on the strong model when the answer is not good enough. This works only on calls that do not stream. Chat turns stream, so there Cascade decides like Classifier.

Func<IReadOnlyList<ChatMessage>, CancellationToken, Task<bool>>? · Default: null

Custom only: your router. It sees the whole conversation; return true to use StrongChatClient. It wins over UseStrongModel.

Func<string, bool>? · Default: null

Custom only: a synchronous predicate on the latest user message. Prefer UseStrongModelAsync.

IReadOnlyList<string>? · Default: null

Semantic only: example turns that deserve the strong model. null uses a built-in multilingual set.

float · Default: 0.35

Semantic only: the similarity at which a turn is escalated. Higher is stricter.

IChatClient? · Default: null

Classifier and Cascade only: the client that judges the turn. null uses ChatClient.

IChatClient? · Default: null

The client for MentorAgent's own small decisions:

Most of these calls run before the user sees the reply, so point it at a small, fast deployment. null uses ChatClient. With Agent and no ChatClient, the safety checks run only when this is set.

bool · Default: false

Emits OpenTelemetry traces and metrics that follow the OpenTelemetry conventions for generative AI (GenAI), plus MentorAgent's own spans and counters.

bool · Default: false

Includes prompt and response content in the telemetry. Development only.

string · Default: "MentorAgent"

The name of the ActivitySource and of the Meter: add it with .AddSource(name).AddMeter(name). An exporter that listens on another name receives nothing.

IReadOnlyDictionary<string, ModelPrice>? · Default: null

Token prices per model, for the dashboard's cost estimate. MentorAgent ships no prices. Enter them under the model id that the dashboard shows; on Azure OpenAI, that id is the deployment name. See ModelPrice.

string · Default: "Admin"

The role that GET /mentor/admin/metrics of Novior.MentorAgent.Server requires; "" leaves it open, for development only. The MentorDashboard component does not check it: protect the page that hosts it.

TimeSpan · Default: 00:00:30

How often the metrics are saved to a registered IMentorMetricsStore; they are also saved on shutdown. Without a store the metrics live in RAM and restart from zero.

TimeSpan · Default: 7.00:00:00

How far back the dashboard keeps its hourly time series: seven days.

An entry of McpServers: an MCP server your application connects to, over HTTP or by starting a local process.

string · Required

The server's name, shown in the MCP status badge.

string? · Default: null

The endpoint of an HTTP MCP server. Set this or Command.

string? · Default: null

The executable of a local server that talks over stdio, for example npx. On Windows, script launchers such as npx run through cmd.exe /c for you.

IList<string>? · Default: null

The command-line arguments of the local process.

IDictionary<string, string>? · Default: null

Environment variables for the local process.

string[]? · Default: null

The only tools to take from the server. null takes them all.

bool · Default: false

Asks the user to confirm every call to a tool of this server.

bool? · Default: null

Whether one connection serves the whole process. null decides by transport: a ServerUrl server is shared, a Command server gets one process per session. Set true only for a local server you know is stateless.

An entry of HostedMcpServers: a remote MCP server the model provider connects to. Your process never talks to it.

string · Required

The identifier the provider uses for the server. The model sees it.

string · Required

The address of the server. The provider connects to it, so it must be reachable from the provider's network: localhost does not work.

string? · Default: null

A description passed to the provider, for more context.

IList<string>? · Default: null

The only tools the provider may call. null allows them all; prefer a list for a server you do not control.

bool · Default: true

Every call needs the user's approval, shown in the usual confirmation box. Set false only for a read-only server you trust.

MentorHostedMcpServer.AlwaysRequireApprovalTools

Section titled “MentorHostedMcpServer.AlwaysRequireApprovalTools”

IList<string>? · Default: null

Tools that always need approval. This list wins over RequireApproval.

MentorHostedMcpServer.NeverRequireApprovalTools

Section titled “MentorHostedMcpServer.NeverRequireApprovalTools”

IList<string>? · Default: null

Tools that never need approval. This list wins over RequireApproval.

IDictionary<string, string>? · Default: null

HTTP headers that the provider sends to the server, for example an authorization token. They leave your process: use a token with few permissions that expires soon.

An entry of RemoteAgents: an A2A agent the coordinator can hand requests to.

A remote agent has no role check of its own: any user of your application can reach it through route_to_specialist. To restrict it, do one of these:

  • protect the /a2a endpoint on the remote host and give roles to the actions there;
  • do not configure the agent on hosts whose users may not use it.

The remote host receives the credentials in Headers, and they are the same for every user of your application. So the roles on the remote host limit what your application may do there. They do not limit which of your users may do it.

string · Required

The agent's name in the handoff graph and in the coordinator's prompt. It must be unique.

string · Required

What the agent does. The coordinator reads it to decide when to hand a request to it.

string · Required

The base URL of the agent, without /.well-known/agent-card.json: the SDK adds it.

Dictionary<string, string>? · Default: null

HTTP headers sent with the card request and with every task, for example Authorization.

The value of AgentCard: extra fields of the card served at /.well-known/agent-card.json.

string · Default: "1.0.0"

The agent version published on the card.

string? · Default: null

The URL of the agent's icon.

string? · Default: null

The provider or organization name.

string? · Default: null

The URL of the agent's documentation.

string[]? · Default: null

Reserved: it is not published on the card.

A value of ModelPricing, created with new ModelPrice(InputPer1M, OutputPer1M). Prices are in your billing currency, per million tokens.

decimal · Required

The price of one million input tokens.

decimal · Required

The price of one million output tokens.

In a Blazor WebAssembly or Auto client, AddMentorAgentBlazor(options => …) configures the widget and the connection to the server's hub. The model, the actions and every rule stay in MentorOptions, on the server. See option B of Blazor WebAssembly and Auto.

string · Default: "/mentor-hub"

The URL of the Novior.MentorAgent.Server SignalR hub. A relative value, such as the default, is resolved against the base address of the page, as a browser does: /mentor-hub at the root of the origin, and mentor-hub under the base path of the app. Use a relative value when the server also serves the client. For a server on another origin, set its absolute URL.

If the URL is absolute, the widget also sends Stop (/mentor/cancel) and the answers to confirmations (/mentor/approve) to the same origin. If it is relative, they resolve against the BaseAddress of the HttpClient of the client. The widget sends them through an HttpClient that you register: the client project of a Blazor Web App has none.

MentorAgentBlazorOptions.AccessTokenProvider

Section titled “MentorAgentBlazorOptions.AccessTokenProvider”

Func<Task<string?>>? · Default: null

Returns the bearer token for the hub. It is read on connect and on every reconnect, and sent with every Stop and confirmation request. Without it every user is anonymous to the server: RequiredRoles actions are refused, and memory and rate limit follow the server's AnonymousIdentity.

MentorAgentBlazorOptions.ConfigureConnection

Section titled “MentorAgentBlazorOptions.ConfigureConnection”

Action<HttpConnectionOptions>? · Default: null

Changes the hub's connection options: headers, transports, cookies. It runs after AccessTokenProvider.

string · Default: "Mentor AI"

The name shown in the widget header.

string? · Default: null

The message shown while the chat is empty. It is rendered as HTML, so never build it from user input.

string? · Default: null

The URL of the avatar shown in the widget.

string? · Default: null

The placeholder of the input box. null uses the text in the language of Language.

MentorTheme · Default: Default

The widget's theme, as Theme on the server.

ChatPosition · Default: BottomRight

Where the widget sits, as Position on the server.

string? · Default: null

An accent color in hex.

MentorLanguage · Default: English

The language of the widget's texts. The language of the replies is Language on the server.

bool · Default: false

Shows the microphone button.

bool · Default: false

Reads replies aloud.

bool · Default: true

Speaks each sentence as it streams.

bool · Default: true

Stops the spoken answer when the user acts, as VoiceBargeIn on the server.

bool · Default: false

Lets the user talk without touching the widget, as VoiceHandsFree on the server. Ignored unless both voice options are on.

double · Default: 1.0

The speech rate; the useful range is about 0.5 to 2.0.

bool · Default: false

Shows suggestion chips in the welcome panel. Off by default here, unlike the server's option.

MentorAgentBlazorOptions.EnableOnboardingTour

Section titled “MentorAgentBlazorOptions.EnableOnboardingTour”

bool · Default: false

Shows the guided tour on first open, with the steps fetched from TourUrl. The server answers GET /mentor/tour even when its own EnableOnboardingTour is false.

string · Default: "/mentor/tour"

Where the tour steps come from. A relative value is resolved against the origin of HubUrl when that is absolute, otherwise against the app's base address.

bool · Default: false

Shows the image attachment controls. The server's EnableImageInput must be on too: that is where images are checked.

int · Default: 4194304

The size cap per image in the client, 4 MB. Keep it equal to the server's option.

MentorAgentBlazorOptions.MaxImagesPerMessage

Section titled “MentorAgentBlazorOptions.MaxImagesPerMessage”

int · Default: 4

The cap on images per message in the client. Keep it equal to the server's option.

List<string> · Default: ["image/png", "image/jpeg", "image/gif", "image/webp"]

The MIME allow-list in the client. Keep it equal to the server's option.

bool · Default: false

Shows citation chips under the agent's replies.

MentorAgentBlazorOptions.ShowHostedToolsStatus

Section titled “MentorAgentBlazorOptions.ShowHostedToolsStatus”

bool · Default: false

Shows the badge of the active hosted tools.

MentorHostedTools · Default: None

Leave it unset. The widget uses it only until the connection is up; then the server sends the hosted tools it really has, and the widget uses those.

bool · Default: false

Shows the MCP status badge.

bool · Default: false

Tells the widget that the server has MCP servers, which enables the MCP badge.

List<string> · Default: empty

The names of the server's MCP servers, shown as connecting until their status arrives.

bool · Default: false

Shows the badge of the remote A2A agents.

bool · Default: false

Tells the widget that the server has remote agents, which enables the A2A badge.

MentorAgentBlazorOptions.RemoteAgentDisplays

Section titled “MentorAgentBlazorOptions.RemoteAgentDisplays”

List<AgentDisplayInfo> · Default: empty

The remote agents listed in the A2A badge, one AgentDisplayInfo each.

A value of RemoteAgentDisplays: a remote agent as the WebAssembly widget shows it in the A2A detail bar. It only drives the display; the remote agents themselves are configured on the server, in RemoteAgents.

string · Default: ""

The agent's name in the detail bar.

string? · Default: null

The address shown next to the name, usually the agent's base URL, as in MentorRemoteAgent.AgentCardUrl.

AddMentorAgentDeclarative(o => …) tells Novior.MentorAgent.Declarative where to find agents written in YAML. A definition chooses the model, writes the instructions and names the tools, so treat it as code. See Specialists in YAML.

string? · Default: null

The folder to scan, absolute or relative to the application's base directory. Use a path that ships with the application, never an upload folder or a path built from a request.

string · Default: "*.agent.yaml"

The file pattern inside Directory.

bool · Default: false

Scans the sub-folders too.

IList<string> · Default: empty

YAML definitions passed as text, for example from a database. They load before the files of Directory. Add to the list: it cannot be replaced.

MentorDeclarativeOptions.ConfigurationSection

Section titled “MentorDeclarativeOptions.ConfigurationSection”

string? · Default: null

The configuration section whose values a definition may reference. null exposes no configuration. Name one section, never the whole configuration: a single key that is not a valid Power Fx name stops every definition from loading.

  • Attributes — The parameters of MentorAction, MentorAgent, MentorTeam, TeamMember, MentorPage and MentorSkill, with their defaults and rules.
  • Roles, confirmation and governance — How MentorAgent checks roles and asks for confirmation before an action runs, on every channel, and what it leaves to your code.
  • Production checklist — Settings to review before you go to production: governance defaults, safety check, rate limits, cost and routing, history, observability, and outgoing data.