Repository navigation
Novior.MentorAgent 1.1.0
Added
-
Novior.MentorAgent:
MentorOptions.ConfirmationMessagewrites the text of the confirmation banner, in the
application's own words or language. It gets the tool, its description, the arguments as the banner shows them,
Languageand the services of the conversation's scope. When it returnsnullthe default text is shown; when it
throws or returns only white space, the default text and a warning (BUG-186). -
Every package carries its software bill of materials: SPDX 2.2, at
_manifest/spdx_2.2/manifest.spdx.json
inside the.nupkg, with its SHA-256 beside it. It lists the package's files and the packages restored to build
it, build-time tools included. -
Novior.MentorAgent:
MentorActionAttribute.RequiresConfirmationDeclaredis public and read-only: whether the
attribute writesRequiresConfirmation, true or false. WithRequireConfirmationForWriteson, an action that
declares nothing asks for confirmation and one that declaresRequiresConfirmation = falsedoes not, while
RequiresConfirmationreads false for both; a component outside the library can now tell them apart.
Security
- Novior.MentorAgent.Blazor: BUG-173 (S2): the package depended on
Microsoft.AspNetCore.SignalR.Client
10.0.3, whoseMicrosoft.AspNetCore.SignalR.Commonis covered by advisory GHSA-334f-vvp4-7g6p
(CVE-2026-70159, high): a client using stateful reconnect can block a server's broadcasts. It now depends on
10.0.13, the patched release. With 1.0.0, add
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.13" />to the client project.
MentorAgent turns stateful reconnect on neither in its hub nor in its client. - Novior.MentorAgent.Server: the hub runs on the SignalR of the ASP.NET Core shared framework, not on a
package: a host is patched by the ASP.NET Core runtime 10.0.13 or later. - A package with a high or critical advisory (NuGet audit NU1903, NU1904), direct or transitive, now fails the
Release build of the packages.
Changed
-
Every package is now checked at pack time against the public API of 1.0.0, so a 1.x release cannot break
code built against 1.0.0 by accident. An intended break is listed in this file as Breaking. -
Novior.MentorAgent, .Server, .Blazor, .Abstractions, .Declarative: NOTICE says that "MentorAgent" and its
logo are trademarks of Antonio Macrì and Emanuele Longo, to be assigned to Novior, not licensed under the Apache
License 2.0, and points to the trademark policy, TRADEMARKS.md, in the GitHub repository.
Fixed
-
Novior.MentorAgent: the README's Migrating from the MentorAgent.* packages listed the build diagnostic
MENTOR001among what stays the same. That check, and itsMentorAgentSkipOpenAIVersionCheckswitch, were
removed in 1.0.0-rc.15: the core package has no build target, and there is no switch to keep (BUG-159, S3). -
Novior.MentorAgent.Server: three sentences of the README did not match the code.
IncludeWorkflowExceptionDetails
puts the exception message of a failing handoff or group chat agent into the reply, not a stack trace.
EnableSuggestionsand the widget options do take effect in a MAUI Blazor Hybrid app, which runs the Blazor
widget; only a MAUI app with its own native UI ignores them. And theAuthorizationheader is missing from a
WebSocket or Server-Sent Events connection because a browser cannot send one, not because the protocol forbids
it; the Blazor README said the same and is corrected too (BUG-160, S4). -
Novior.MentorAgent.Server: the README's React example for image input did not compile: a
<textarea>outside
any component and anawaitat the top level. It is now a component that keeps the attachments in its state and
sends them from anasynchandler, passingnullwhen there are none (BUG-161, S3). -
Novior.MentorAgent.Server: the README said that
POST /mentor/cancelanswers404when Stop is pressed just as
the turn ends, and that it is not an error; its React, Angular and Vue components ignored it. The endpoint answers
200whenever the connection exists, with or without a turn running, and404only when the connection is closed
or unknown, which is the case a client must not hide. The README and the three components now say so (BUG-162, S3). -
Novior.MentorAgent: the option reference tables of the README and the Server README left out options that only
their own sections described:SkillSources,SkillFilter,SkillsRefreshInterval,AutoApprovalRulesand
MaxAutoApprovalIterationsin the README;EnableRichResponses,IsReadOnlyAction,EnableOutputSafetyCheck,
RequireLookupForRecordQuestions,RequireActionForChangeRequestsandMcpCallerPrincipalin the Server README.
Every public option ofMentorOptionsis now in a reference table of both, or among the Server README's options
not listed on purpose. The[MentorAction]tables markDescriptionas required, and the Server README's lists
ReadOnly(BUG-163, S4). -
Novior.MentorAgent: with a pre-built
Agent(Path B),MemoryAutoCaptureand aClassifierChatClient, memory
had two writers: the post-turn extraction ran through the classifier, one call per message, and theremember
tool was sent too. The log and the documentation said the extraction does not run on Path B. The tool is now left
out whenever the extraction runs, and the build log names the writer: on Path B the extraction with a
ClassifierChatClient, theremembertool without one (BUG-174, S3). -
Novior.MentorAgent: a
[MentorTeam]withHandoffTowas approved when[TEAM:APPROVED]appeared anywhere
in the discussion, so a member's "yes" followed by another's "no" still told the coordinator to execute the
actions. The team is now approved only if its final message carries[TEAM:APPROVED]and no member wrote
[TEAM:REJECTED]; a discussion that ends without a verdict is not approved. Without a[TeamTerminationCondition]
the discussion now ends at the first verdict, instead of running allMaxIterationsrounds; a host's condition
still decides alone when to stop. The members' instructions keep[TEAM:REJECTED]for a definitive no and ask for
changes without a token (BUG-175, S3). -
Novior.MentorAgent, .Server, .Blazor, .Abstractions, .Declarative: the XML documentation that IntelliSense
shows no longer contradicts the code: anonymous callers share the memory key"anonymous"only with
AnonymousIdentity = Shared; an emptyAllowedToolsallows every tool, likenull(the README says so too);
MentorTheme.Customrenders likeDefault;IMentorAgentis optional and validates nothing; the hub's events list
Cards, andMapMentorAgentServerlists/mentor/session(BUG-164, S4). -
Novior.MentorAgent: the README did not say that with
UseRagthe search runs on every message, before the
model is called, so its time (an embedding call, the search, a reranker) is added to every reply; nor that the
absence of a keyword pre-gate relies onRagMinScorebeing on the source's scale. It says both now, and so does
the comment inRagContextProvider(BUG-165, S4). -
Novior.MentorAgent: the XML documentation of
RequiresApprovalsaid the predicate is evaluated once per
tool while the coordinator is built. It is asked again on every call to a tool in Blocking mode and on every turn
the tool filter matches a tool, so a predicate that reads a file or a database pays for it each time. The
documentation now says when it is asked and that it must stay a cheap, pure function of the tool name
(BUG-176, S4). -
Novior.MentorAgent: the documentation of
ConfigureChatClientPipelinesaid only that the pipeline goes
outermost. It is built once per coordinator, so once per circuit on Blazor Server and once per SignalR connection
on the hub: a limit placed there does not limit the process. And only the coordinator's own calls go through it:
the auxiliary calls — classifier, safety checks, out-of-scope refusal, memory extraction, the lookup and action
checks — useClassifierChatClient ?? ChatClient, and specialists, team members and the handoff router use
ChatClient. The READMEs and the XML documentation now say both (BUG-166, S4). -
Novior.MentorAgent: the READMEs said that
navigate_towaits forSignalReady()on aHasUIActionspage
only in a Blazor Server circuit. It waits wherever the page runs in the same process as the turn, so in a MAUI
Blazor Hybrid app too; turns over the hub, SSE or A2A still do not wait. The READMEs now say so (BUG-171, S4). -
Novior.MentorAgent: on Path B (a pre-built
Agent),EnableSafetyCheckandEnableOutputSafetyCheck
without aClassifierChatClientnow log a warning when the coordinator is built: neither check can run, so every
message and every reply goes through unchecked. Both checks run onClassifierChatClient, or onChatClientwhen
none is set, so on Path B aClassifierChatClientturns them on; the README and the XML documentation said they
required aChatClient(BUG-167, S3). -
Novior.MentorAgent: the README and the XML documentation of
HitlModesaid thatNativecosts one
model call more per approved action, and thatBlockingis cheaper. Both modes make the same model calls:
Nativeadds one agent run per round of confirmations, and its reply arrives in two segments (BUG-168, S3). -
Novior.MentorAgent.Blazor: the README said twice that the server must enable
EnableOnboardingTourtoo,
and the widget's log said so when the tour had no steps.MapMentorAgentServer()mapsGET /mentor/tour
whatever the server's flag says: the client's flag alone decides whether the tour is shown. The README and the
log now say so (BUG-169, S3). -
Novior.MentorAgent: the README has an example of
RequiredRoleswith Windows groups (Negotiate,DOMAIN\Group)
and with Microsoft Entra ID (app roles, or thegroupsclaim's ids). The XML documentation ofEnableObservability
said the embedding generator is traced too, and the README "the chat client calls": only the coordinator's model
calls are traced, and both now say how to trace the rest (BUG-170, S4). -
Novior.MentorAgent.Server: the A2A agent card listed the actions of classes not registered in the DI container,
which no turn can run, and repeated a skill id when two actions share a tool name. It now lists only the actions a
turn can call, once per name, and leaves a name out when any action carrying it is gated (BUG-177, S3). -
Novior.MentorAgent.Server: the warning that lists the actions withheld from the MCP server was written on the
first MCP request, not at startup as the README says.MapMentorAgentMcp()now writes it when it maps the
endpoint; the tools are still built by the first request, and which of them a caller sees is still decided per
request (BUG-178, S3). -
Novior.MentorAgent: on Path B (a pre-built
Agent) the[MentorAgent]specialists, the[MentorTeam]teams
and theRemoteAgentsare not built, because they run onoptions.ChatClient, and nothing said so. A warning now
names each of them when the coordinator is built, and the remote agents' cards are no longer fetched on Path B,
where no turn could reach them (BUG-179, S3). -
Novior.MentorAgent: the two log lines that open and close the discovery were in Italian ("Discovery avviata",
"Discovery completata"). They now read "Discovery started on …" and "Discovery completed — …" (BUG-180, S4). -
Novior.MentorAgent: a team's discussion reached the coordinator as one run-on text ("… is solved.I agree"), so
it could not tell who said what. Each message is now a paragraph of its own, headed by its author. The team tool's
description gets a full stop before the handoff note when the team'sDescriptionhas none (BUG-181, S4). -
Novior.MentorAgent: two methods carrying the same tool name were reported only with tool filtering on. A model
calls a tool by name, so an agent offered both reaches only one of them, and up to 1.0.0 one method's attributes
decided the other's call (BUG-188). A warning now names every shared tool name and its methods when the actions
are first read, with tool filtering on or off (BUG-182, S4). -
Novior.MentorAgent: the signed-in user's roles told to the model came from
ClaimTypes.Roleclaims only, while
the gate decides withIsInRole, which reads each identity's ownRoleClaimType. With roles in arolesclaim —
Microsoft Entra ID, or JwtBearer withMapInboundClaims = false— an action passed the gate while the model was
told no role. The model is now told the rolesIsInRoleanswers to, from every identity of the user; a Windows
identity's group SIDs are left out (BUG-183, S3). -
Novior.MentorAgent: the RAG citation chips knew one number per marker, "[1] [2]". An answer that cited "[1, 2]"
or "[1-2]", as models also write, showed no chip at all. A list or a range now raises a chip for each document it
names; a range with an end that names no document, such as "[0-9]" in a code sample, cites nothing (BUG-184, S3). -
Novior.MentorAgent: the instruction that tells the model how to cite the RAG documents was in English whatever
Languagesaid. It is now written in the configured language, in each of the ten, with the same[1], [2]
markers the citation chips read (BUG-185, S3). -
Novior.MentorAgent: the confirmation banner showed each argument whole, control and bidirectional characters
included, in the order of the model's JSON. Each value is now cleaned and cut at 200 characters, and the arguments
follow the order of the method's parameters (BUG-186, S2). -
Novior.MentorAgent: with
HitlMode.Native, a confirmation that a Stop or a failure left open was answered
from memory only. A snapshot saved in that state and restored in another scope, or after a reset, still held the
open request, and every later turn failed as in BUG-116 (a known issue since 1.0.0-rc.15). The open requests and
their answers now travel with the snapshot, and the first turn after the restore answers them (BUG-187, S3). -
Novior.MentorAgent: two methods carrying one tool name shared one set of rules. The roles, the confirmation,
the banner's text and the page to open came from the first method found with the name, level 1 first, so a
level-1 method without roles opened a specialist's role-gated action of the same name to every user. The gate now
applies the rules of the method the call runs, at every level and in both HITL modes (BUG-188, S2). -
Novior.MentorAgent, .Abstractions, .Blazor: the README taught
PageContext.Clear()in a page'sDispose().
Blazor disposes the previous page after it has initialized the next one, so from one page with UI actions to
another, the previous page'sClear()wiped the actions the next page had just registered, and the assistant
answered that the action did not exist.IMentorPageContext.Clear(pageName)clears only what that page
registered, or everything when it is still the current page: call it inDispose()with the page's name.
Clear()still clears everything (BUG-192, S2). -
Novior.MentorAgent.Abstractions: in a table inside an assistant bubble, a number stood one digit per line. The
bubble lets a word break anywhere, so the table's columns could shrink to one character. The cells now break
between words only, a cell holding only a number, an amount, a date or a time stays on one line, and a table wider
than the bubble scrolls inside it instead of widening the conversation (BUG-193, S4). -
Novior.MentorAgent:
navigate_toto a page withHasUIActionscould return before the new page had registered
its actions. The page being left had calledSignalReady()when it opened, and that signal ended the wait at once.
navigate_tonow takes it back before asking for the navigation, so it waits for the new page'sSignalReady();
to the page already shown it does not wait, since Blazor does not initialize that page again (BUG-194, S3).