Skip to content

Releases

Novior.MentorAgent 1.3.0

Choose a tag to compare

@macria97 macria97 released this 11 Nov 13:55

Added

  • ACTION-RULES.md lists the rules by which a method becomes an action, how actions are named, and how roles and
    confirmations add up. Each rule has a name that does not change and at least one test that fails when the rule does;
    a rule that comes in, changes or is retired is named in the release notes of its version. The rules of 1.3.0:
    scan.assemblies-once, scan.concrete-classes, scan.public-instance-declared, scan.marker,
    scan.mentor-action-wins, scan.override-keeps-action, kind.one-per-class, kind.page-is-separate,
    kind.agent-owns-methods, kind.skill-methods-level1, kind.team-needs-members, kind.member-tools-leave-level1,
    kind.member-tools-same-rules, name.snake-case, name.team-tool, name.shared-warned,
    name.called-method-decides, confirm.declared-decides, confirm.default-for-writes,
    confirm.description-only-not-defaulted, confirm.predicate-adds, confirm.master-switch,
    confirm.beats-read-only, confirm.unconfirmed-writes-warned, roles.any-of, roles.signed-in,
    roles.checked-before-confirmation, roles.offered-when-allowed, surface.coordinator-only,
    surface.mcp-withholds-gated and surface.card-ungated-only.

  • An action can ship off, and the application can turn its actions on and off from outside its code.
    [MentorAction(Enabled = false)] keeps an action in the catalogue (MentorActionInfo.EnabledByDefault is false)
    and nowhere else: no agent is offered it, no model reads about it, the MCP server does not list it, the A2A card
    does not show it, and a call to it does not run. An IMentorActionGovernor, registered with
    AddMentorActionGovernor<T>(), answers for each action whether it is on, and can turn on one the code ships off:
    registering one gives whoever implements it the power to widen what the code allows. It is asked once as a session
    builds its tools, on every tools/list of the MCP server and before every call, with the session's id; a session
    keeps the tools it was built with, and a call to an action turned off meanwhile is refused. There can be one: a
    second registration throws. A governor that throws, or does not answer within ActionPolicyTimeout, stops the
    action. The A2A card follows the code only, so an action turned on from outside is not on it. New reason codes:
    disabled (Denied) and governor-failed (PolicyFailed). New rules: enabled.off-by-default,
    enabled.external-decides and surface.governor-session; surface.mcp-withholds-gated and
    surface.card-ungated-only now also leave out an action that is off.

  • The governor can also give an action its roles: IMentorActionGovernor.GetRequiredRolesAsync answers in place of
    [MentorAction(RequiredRoles = ...)], with null for the code's roles and an empty list for none. The answer
    decides whom the action is offered to, the check at every call, before a confirmation and again after it, and which
    MCP callers see and call it: an action the MCP server withheld only for its roles is published once the governor
    requires none. MentorActionDecision.RolesFromOutside says when the roles came from the governor. New rule:
    roles.external-replace; roles.checked-before-confirmation now checks the governor's roles when it gives them.

  • The governor can also decide whether the user confirms an action: IMentorActionGovernor.GetConfirmationAsync
    answers MentorConfirmationChoice.Code for the code's confirmation, Required to ask even if the code does not,
    and None not to ask even if the code does — declared, by default for writes, or by RequiresApproval. A
    confirmation added counts from the call, one taken away from the next session, and in Native mode no auto-approval
    rule lets a required one through. A policy's Confirm still asks, a hosted MCP server's approval still comes from
    its provider, and with RequireConfirmation off nobody is asked. An action whose confirmation is taken away still
    counts as one that changes data. The MCP server publishes an action that asks for confirmation once the governor
    takes it away, and withholds one it requires. MentorActionDecision.ConfirmationFromOutside says when the governor
    changed whether a call is confirmed. New rule: confirm.external-decides; confirm.predicate-adds and
    surface.mcp-withholds-gated now say what the governor can take away.

  • The governor can also rewrite the description the model reads: IMentorActionGovernor.GetDescriptionAsync answers
    in place of the code's, with null or a blank text for the code's. It is asked as a session builds its tools and
    on every tools/list of the MCP server, and the answer is what the coordinator, the specialists and the team
    members read, what tool filtering ranks, and what tools/list shows; the action's name and argument schema never
    change, and the code's ProactiveHint still follows the description. What the user sees keeps the code's
    description: the confirmation banner, the bar of the running action and MentorActionDecision.DisplayName. On a
    call to the MCP server the policies are asked with the code's description. New rule: describe.external-replace.

  • An IMentorAgentSource says what it loaded and what it left out, and when it is asked is a promise. A source is
    asked whenever a coordinator is built: at least once per session — once per Blazor circuit, MAUI app scope or hub
    connection, and at every request on /mentor/chat and every task over A2A — and MentorAgentSourceContext.SessionId
    names the session, as MentorActionRequest.SessionId does. MentorAgent now calls IMentorAgentSource.LoadAsync,
    which returns a MentorAgentSourceResult: the agents, and a MentorAgentRejection (Name, ReasonCode, Detail,
    Tool) for each definition left out or tool taken away. Its default body returns the agents of GetAgentsAsync, so
    an existing source works unchanged. An IMentorAgentSourceObserver, registered with
    AddMentorAgentSourceObserver<T>(), receives a MentorAgentSourceReport for each source every time a coordinator
    is built, also when the source loaded nothing; a source that throws is reported as source-failed, with the
    exception's type and never its message. The reason codes, in MentorAgentRejectionReasons: invalid-definition,
    not-an-agent, foreign-tools, invalid-configuration, source-failed, tool-not-found and
    hosted-tool-removed. Novior.MentorAgent.Declarative reports every definition it does not load and every tool
    it takes away. New rules: declarative.functions-match and declarative.no-hosted-tools.

  • MentorRuntimeOptions.Changeable lists the options that can be changed while the application runs, and from when
    a change applies (MentorOptionReadAt). From the next turn of every session: Language, RateLimitPerUser,
    RateLimitWindowSecs, ConfirmationMessage, ConfirmationTimeout, ActionPolicyTimeout, EnableActionFeedback,
    EnableGenerativeCards, EnableSafetyCheck and CheckAnnouncedActions. From the sessions that begin after the
    change: MentorshipLevel,
    ProactiveNextSteps, EnableRichResponses, RefuseOutOfScope, ToolFilterMaxTools and MaxSessionMessages. To
    change one, assign it on the IOptions<MentorOptions> value, replacing a collection rather than changing it in
    place. Every other option is read before the application starts: set it there. Each option listed has a test that
    changes it on a running application, and every option declares when it is read, so a new one cannot ship without
    the decision.

  • After a turn in which the coordinator called no tool, MentorAgent asks a model whether its reply announces an action
    ("I'm registering the note…") or reports one as done when nothing ran (MentorOptions.CheckAnnouncedActions, on by
    default). If it does, the coordinator gets one more request in the same turn, with the same tools, told to call the
    tool now or to say that it was not done. The question names the tools the model was sent, and the answer names the
    one that does the action: the second request then says that this tool is there to call now. The instruction is that
    request's last message, read after the reply it is about, and never stored. A call to an action of the application
    the agent was not given (one that is off for the session) runs nothing, and the turn is checked as one in which
    nothing ran. The call is never required and passes the gate as any other, the reply
    already shown is not held back, and the second reply is not checked again. The question goes to
    ClassifierChatClient, or to ChatClient without one: a few hundred tokens after every reply that called no tool,
    so a small deployment there is worth configuring. Its verdict is logged at Information for every reply it checks,
    with the time and the tokens it took. On Path A with the history kept by MentorAgent; not with
    UseServiceManagedHistory nor with a pre-built Agent (BUG-220).

  • A call the model makes to an action of the application that the coordinator was not given in the turn — one that
    is off, or another agent's — reaches no gate and runs nothing. IMentorActionObserver now receives its one
    decision, Denied with the new reason code not-offered, and the call's span says the same, in Blocking and in
    Native mode, with CheckAnnouncedActions on or off. A call the coordinator was given keeps the decisions of its
    gate, and only those.

  • One instance of the application can tell which tenant a request belongs to. IMentorTenantResolver, registered with
    services.AddMentorTenantResolver<T>() (one per application), names it from the caller, the surface and the
    request's services; IMentorTenant.Id reads it, in an action, a policy or the governor, and
    IMentorTenant.GetIdAsync() resolves it first in a scope that had n...

Read more

Novior.MentorAgent 1.2.0

Choose a tag to compare

@macria97 macria97 released this 27 Oct 14:22

Added

  • Novior.MentorAgent.Abstractions: IMentorStateService.OnActionStarted gives the tool's technical name next to
    the text shown, in a MentorActionStarted: OnActionExecuting carries only the text shown, so whoever recorded
    the actions from it could not tell for sure which tool ran. It is raised where the turn runs, not by the WebAssembly
    client, and the interface implements it as an event nobody raises, so an implementation written for 1.1.0 still
    compiles. The documentation of OnActionExecuting now says it carries the text shown, not the tool name.

  • Novior.MentorAgent.Abstractions, Novior.MentorAgent: IMentorActionObserver receives every decision of the tool
    gate, on every surface and for every agent; AddMentorActionObserver<T>() registers one. A MentorActionDecision
    carries the outcome (MentorActionOutcome), a reason code that stays the same across versions
    (MentorActionReasons), the tool, the agent, the surface, the session, turn and call ids, the user and who
    confirmed — never the arguments. A decision never waits for an observer: each has a queue of its own and 5 seconds a
    call.

  • Novior.MentorAgent.Abstractions: an action that asks for confirmation knows who confirmed it and when:
    MentorActionConfirmation.Current, read inside the action's method, carries the confirmation's id, the tool, the
    time and who confirmed — the caller of POST /mentor/approve, or the session's user in a circuit and in the MAUI
    app — in Blocking and in Native mode. It is null for an action nobody confirmed. The approval event came when
    the action was already on its way, so a ledger of the writes could not say who approved one.

  • Novior.MentorAgent: MentorOptions.ConfirmationTimeout bounds how long a confirmation waits for its answer,
    counted from when the banner is shown. Once it has passed with no answer, the confirmation counts as rejected: the
    action does not run, its decision is Rejected with the new reason code confirmation-timeout, the span's
    mentoragent.tool.confirmation is timed-out, and the model is told nobody confirmed it in time, not that the user
    declined. An answer that comes later is ignored, as one after Stop is: POST /mentor/approve answers 404. It applies
    to a confirmation a policy asks for too, in Blocking and in Native mode, and for specialists and team members. Zero or
    a negative value, the default, is no limit, as before.

  • Novior.MentorAgent, .Abstractions, .Blazor, .Server: two tools for article 50 of the EU AI Act. A notice that
    tells people they are talking to an AI assistant, under the widget's header for the whole conversation
    (ShowAiDisclosure, AiDisclosureMessage, on MentorOptions and MentorAgentBlazorOptions), with a default text
    in the ten languages of Language; and a machine-readable marker on every reply the model writes:
    data-ai-generated="true" on the reply in the widget, "aiGenerated": true on the chunk and completed frames of
    /mentor/chat, the hub event ReplyStarted before each reply, whose argument is a MentorReplyStarted
    ({ "aiGenerated": true }), and aiGenerated in the metadata of the reply to an A2A task. Turning the notice off
    leaves the marker. The results of the MCP server, the spoken replies and the images and files of the provider's
    hosted tools carry no marker. Which words to show, and whether the article applies, is the application's to decide.

  • Novior.MentorAgent.Abstractions: MentorTheme.Auto follows the visitor's system setting
    (prefers-color-scheme): the light theme, Minimal, when it asks for light, which is also what a browser reports
    when the system states no preference, and Default when it asks for dark. It follows the system, not the page: on
    a page that is always light, a visitor whose system is dark sees the dark widget. No script is involved, and the
    default theme stays Default.

  • Novior.MentorAgent, .Abstractions, .Blazor, .Server: a language per page. <ChatWidget Language="…" /> gives
    the widget a language of its own for its texts, its voice and its onboarding tour, and every turn it sends carries
    it: the assistant answers in it, and what MentorAgent writes for that turn follows it. The language travels as
    MentorUserMessage.Language, in the hub's new SendUserMessage, as language on /mentor/chat and on GET /mentor/tour?language=. IMentorOrchestrator and IMentorTour get default methods, so implementations written for
    1.1.0 compile. A change of MentorOptions.Language while the application runs applies from the next turn. A2A and
    MCP requests stay on MentorOptions.Language.

  • Novior.MentorAgent: MentorOptions.SessionContextPlacement. With LastUserMessage the context of each request
    — the page, its data, its address, the date and time — goes at the start of the user's last message instead of the
    end of the instructions, which then stay the same through the session: a model that caches the prompt by its prefix,
    a local engine above all, no longer reads the whole conversation again on every new minute or page. The stored
    conversation keeps the user's words. Path A with local history only; the default, Instructions, changes nothing.

Changed

  • Novior.MentorAgent, .Abstractions, .Blazor: the widget now shows, by default, under its header: "You are talking
    to an AI assistant: its replies are generated automatically.", in the configured Language, for the whole
    conversation. Set AiDisclosureMessage to your own words, or ShowAiDisclosure to false to show none.

  • Novior.MentorAgent.Server: the hub sends ReplyStarted before each reply. A client that does not register it
    keeps working, and SignalR logs a warning for every reply ("Failed to find handler" in .NET, "No client method with
    the name" in JavaScript): register it, even with a handler that does nothing — connection.on("ReplyStarted", () => {}), or hub.On<MentorReplyStarted>("ReplyStarted", _ => { }). The WebAssembly client of Novior.MentorAgent.Blazor
    registers it.

  • Every package is now checked at pack time against the public API of 1.1.0, so 1.2.0 cannot break code built
    against 1.1.0 by accident. An intended break is listed in this file as Breaking.

  • The family moves onto the Microsoft Agent Framework 1.26.0 line (Microsoft.Agents.AI and
    Microsoft.Agents.AI.Workflows 1.26.0) and Microsoft.Extensions.AI 10.11.0. Novior.MentorAgent.Declarative:
    Microsoft.Agents.AI.Declarative moves to 1.26.0-rc1, on the same line. In Agent Framework 1.26
    AgentSessionStore.DeleteSessionAsync is abstract: a host with an AgentSessionStore of its own implements it.
    1.26 also refuses two tool approval requests with one id; MentorAgent gives each call of a response an id of its
    own (BUG-225), except with UseServiceManagedHistory.

  • With Agent Framework 1.25 or later, when control returns to an agent of the handoff workflow behind route_to_specialist,
    the workflow repeats the user's request to it instead of leaving it a tool result alone: whoever reads the
    workflow's messages sees one more after each return. The answers do not change.

  • ModelContextProtocol moves to 2.3.0: the MCP client in Novior.MentorAgent, and
    ModelContextProtocol.AspNetCore 2.3.0 in Novior.MentorAgent.Server. The SDK's HTTP server is stateless by
    default from 2.0; the MCP endpoint asks for the stateful transport, so a client keeps its Mcp-Session-Id and the
    endpoint answers as before, a GET without a session with 400 included.

  • An MCP server of the host that lists a tool without inputSchema is no longer connected: ModelContextProtocol 2.0
    refuses such a tool where 1.x gave it an empty schema, and the server's whole tool list is lost with it. The
    warning names the server, and its exception names inputSchema; the assistant goes on without that server.

  • The A2A SDK moves to 1.0.0-preview3: A2A in Novior.MentorAgent and A2A.AspNetCore in
    Novior.MentorAgent.Server.

  • Novior.MentorAgent: a call refused for its roles is logged once, at Warning, in Blocking and in Native mode
    alike. In Native mode a user who was not signed in was refused before the banner with a Debug line only, and in
    Blocking mode a missing role wrote two Warnings. A confirmation cancelled by Stop or by the end of the session is
    now logged at Debug in Native mode too, and a tool call's Debug line is written once instead of twice.

  • The mentor.tool.{toolName} and mentor.mcp.tool.{toolName} spans carry the outcome
    (mentoragent.tool.outcome), the reason code (mentoragent.tool.reason), the confirmation
    (mentoragent.tool.confirmation) and the surface (mentoragent.surface), and a failed call sets the span's
    status to error. In Native mode a call refused, rejected or stopped before it runs now has its span too.

  • Novior.MentorAgent.Server: the MCP server's line for each tools/call tells apart a call refused for its roles
    (denied-role), an action the server never publishes (withheld) and a name nothing defines (unknown): the
    three were all unknown. A call the client cancels is cancelled. The caller is still told the same for every name
    it may not use.

  • Novior.MentorAgent.Abstractions, Novior.MentorAgent, .Server: IMentorActionPolicy lets the application's own
    code decide whether a user may use an action and whether a call may run — a permission per company or per record, a
    rule on the arguments — on every surface: the coordinator on both paths and in both modes, the specialists, team
    members and agent sources, the MCP servers the application consumes, the MCP server and A2A tasks.
    AddMentorActionPolicy<T>() registers one. IsAllowedAsync decides what is offered and is asked again before every
    ...

Read more

Novior.MentorAgent 1.1.0

Choose a tag to compare

@macria97 macria97 released this 21 Oct 08:24

Added

  • Novior.MentorAgent: MentorOptions.ConfirmationMessage writes 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,
    Language and the services of the conversation's scope. When it returns null the 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.RequiresConfirmationDeclared is public and read-only: whether the
    attribute writes RequiresConfirmation, true or false. With RequireConfirmationForWrites on, an action that
    declares nothing asks for confirmation and one that declares RequiresConfirmation = false does not, while
    RequiresConfirmation reads 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, whose Microsoft.AspNetCore.SignalR.Common is 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
    MENTOR001 among what stays the same. That check, and its MentorAgentSkipOpenAIVersionCheck switch, 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.
    EnableSuggestions and 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 the Authorization header 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 an await at the top level. It is now a component that keeps the attachments in its state and
    sends them from an async handler, passing null when there are none (BUG-161, S3).

  • Novior.MentorAgent.Server: the README said that POST /mentor/cancel answers 404 when 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
    200 whenever the connection exists, with or without a turn running, and 404 only 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, AutoApprovalRules and
    MaxAutoApprovalIterations in the README; EnableRichResponses, IsReadOnlyAction, EnableOutputSafetyCheck,
    RequireLookupForRecordQuestions, RequireActionForChangeRequests and McpCallerPrincipal in the Server README.
    Every public option of MentorOptions is now in a reference table of both, or among the Server README's options
    not listed on purpose. The [MentorAction] tables mark Description as required, and the Server README's lists
    ReadOnly (BUG-163, S4).

  • Novior.MentorAgent: with a pre-built Agent (Path B), MemoryAutoCapture and a ClassifierChatClient, memory
    had two writers: the post-turn extraction ran through the classifier, one call per message, and the remember
    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, the remember tool without one (BUG-174, S3).

  • Novior.MentorAgent: a [MentorTeam] with HandoffTo was 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 all MaxIterations rounds; 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 empty AllowedTools allows every tool, like null (the README says so too);
    MentorTheme.Custom renders like Default; IMentorAgent is optional and validates nothing; the hub's events list
    Cards, and MapMentorAgentServer lists /mentor/session (BUG-164, S4).

  • Novior.MentorAgent: the README did not say that with UseRag the 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 on RagMinScore being on the source's scale. It says both now, and so does
    the comment in RagContextProvider (BUG-165, S4).

  • Novior.MentorAgent: the XML documentation of RequiresApproval said 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 ConfigureChatClientPipeline said 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 — use ClassifierChatClient ?? 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_to waits for SignalReady() on a HasUIActions page
    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), EnableSafetyCheck and EnableOutputSafetyCheck
    without a ClassifierChatClient now log a warning when the coordinator is built: neither check can run, so every
    message and every reply goes through unchecked. Both checks run on ClassifierChatClient, or on ChatClient when
    none is set, so on Path B a ClassifierChatClient turns them on; the README and the XML documentation said they
    required a ChatClient (BUG-167, S3).

  • Novior.MentorAgent: the README and the XML documentation of HitlMode said that Native costs one
    model call more per approved action, and that Blocking is cheaper. Both modes make the same model calls:
    Native adds 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 EnableOnboardingTour too,
    and the widget's log said so when the tour had no steps. MapMentorAgentServer() maps GET /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).

  • **No...

Read more

Novior.MentorAgent 1.0.0

Choose a tag to compare

@macria97 macria97 released this 13 Oct 15:24

Changed

  • Breaking — all packages: the packages are now Novior.MentorAgent, Novior.MentorAgent.Abstractions,
    Novior.MentorAgent.Blazor, Novior.MentorAgent.Declarative and Novior.MentorAgent.Server; the MentorAgent.*
    ids end at 1.0.0-rc.15. The namespaces follow (using Novior.MentorAgent.Extensions;), the widget's static files
    are served from _content/Novior.MentorAgent.Abstractions/, and the log categories start with
    Novior.MentorAgent, so a "MentorAgent" filter under Logging:LogLevel no longer matches. The five packages
    depend on each other at their exact version. Unchanged: the types and extension methods (AddMentorAgent,
    MentorOptions, …), the routes, the telemetry source, meter and metric names, the session snapshot format, the
    MentorAgentMcp CORS policy, MentorAgent.css, MentorAgent.js and window.MentorAgent. The README's
    Migrating from the MentorAgent.* packages walks through the move.

Fixed

  • Novior.MentorAgent: four Warnings outside the tool gate still carried a whole exception, whose text comes from the
    host's code: a UI action that threw, with a ChatClient or a pre-built Agent, and an OnToolResult or a
    McpCallerPrincipal that threw on the MCP server. As in the gate, they name the exception's type; the whole
    exception is logged at Debug (BUG-152, S3).
  • Breaking — Novior.MentorAgent.Server: AddMentorAgentMcp() or AddMentorAgentA2A() called before AddMentorAgent(),
    or with McpServerEnabled / A2AServerEnabled turned on after AddMentorAgent() read them (a Configure or
    PostConfigure of MentorOptions), registered nothing and said nothing; the map call failed later, in the
    second case naming a call the host had made. The host now stops at start-up with the reason and the fix, and
    one that ran without the server because of it no longer starts (BUG-153, S3).
  • Novior.MentorAgent: the README and the rc.15 notes said that the warning about writes that run without
    confirmation comes at startup. It comes the first time the actions are read: at startup only with
    WarmUpAtStartup or MapMentorAgentA2A(), otherwise with the first conversation or the first MCP or tour
    request. With [Description] alone it also names the methods that only read, until IsReadOnlyAction or
    [MentorAction(ReadOnly = true)] declares them. The README now says both (BUG-154, S3).
  • Novior.MentorAgent.Server: the README's minimal SignalR client called Stop, the confirmations and the session
    save and restore without the hub's credentials: with cookies from another origin, or a bearer token, those
    calls were anonymous and did nothing. It now sends them, like the complete components. The README also no
    longer says that the MCP and A2A servers are built into MentorAgent (BUG-155, S3).
  • Novior.MentorAgent: the READMEs, the XML documentation of AddMentorAgent() and the start-up warning for a
    callback that throws listed AppDescription and AgentCard among the options read at registration.
    Only AppName is, as the MCP server's name; the A2A card is built from the real options when
    MapMentorAgentA2A() runs (BUG-156, S4).
  • Novior.MentorAgent: the README's MAUI step 3, pasted into the MAUI Blazor Hybrid template, did not compile: it
    lacked using System.Reflection; and using Microsoft.Extensions.Configuration;, and AddUserSecrets needs
    Microsoft.Extensions.Configuration.UserSecrets, which neither the template nor MentorAgent brings. The step
    now names both and the package, and says that AddUserSecrets needs the project's UserSecretsId and finds
    the secrets only on the development machine (BUG-157, S3).
  • Novior.MentorAgent.Abstractions: its README said that the core package depends on
    ModelContextProtocol.AspNetCore; since rc.15 that transport is in the Server package, and the core
    references ModelContextProtocol (BUG-158, S3).