# IMentorStateService interface

> The IMentorStateService interface of Novior.MentorAgent.Abstractions.Interfaces: Thread-safe event bus between the AI layer (Agent Framework) and the UI…

- URL: https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstateservice
- Verified with: MentorAgent 1.2.0
- Last updated: 2026-10-27
- Packages: Novior.MentorAgent.Abstractions

Thread-safe event bus between the AI layer (Agent Framework) and the UI layer (Blazor). Agent Framework executes on background threads; Blazor requires StateHasChanged() to be called on the circuit's UI thread. MentorAgentUIMiddleware intercepts AI updates and publishes them through this service. Razor components subscribe and call InvokeAsync(StateHasChanged) to update the UI in a thread-safe manner.

## Definition

Namespace: `Novior.MentorAgent.Abstractions.Interfaces`. Package: `Novior.MentorAgent.Abstractions`.

`public interface IMentorStateService`

```shell
dotnet add package Novior.MentorAgent.Abstractions
```

## Methods

### `Cancel`

`void Cancel(Guid actionId)`

### `ConfirmAsync`

`Task ConfirmAsync(Guid actionId)`

### `NotifyActionCompleted`

`void NotifyActionCompleted(string toolName)`

### `NotifyActionExecuting`

`void NotifyActionExecuting(string toolName, string? displayName = null)`

### `NotifyActionFailed`

`void NotifyActionFailed(string toolName, string error)`

### `NotifyBusyChanged`

`void NotifyBusyChanged(bool isBusy)`

### `NotifyCardsReady`

`void NotifyCardsReady(IReadOnlyList<MentorCard> cards)`

### `NotifyConfirmationRequired`

`void NotifyConfirmationRequired(ConfirmationRequest request)`

### `NotifyError`

`void NotifyError(string message)`

### `NotifyGeneratedImages`

`void NotifyGeneratedImages(IReadOnlyList<string> imageSources)`

### `NotifyHostedToolsDeclared`

`void NotifyHostedToolsDeclared(MentorHostedTools tools)`

### `NotifyMcpServerStatusChanged`

`void NotifyMcpServerStatusChanged(string serverName, bool connected)`

### `NotifyNavigationRequested`

`void NotifyNavigationRequested(string url)`

### `NotifyRagSourcesReady`

`void NotifyRagSourcesReady(IReadOnlyList<MentorRagResult> sources)`

### `NotifyStreamingChunk`

`void NotifyStreamingChunk(string chunk)`

### `NotifyStreamingCompleted`

`void NotifyStreamingCompleted()`

### `NotifyTeamMemberSpeaking`

`void NotifyTeamMemberSpeaking(string teamName, string memberName)`

### `NotifyUIActionCompleted`

`void NotifyUIActionCompleted(string actionName)`

### `NotifyUIActionExecuting`

`void NotifyUIActionExecuting(string actionName)`

## Events

### `OnActionCompleted`

`event Action<string>? OnActionCompleted`

Event: a tool call has completed successfully.

### `OnActionExecuting`

`event Action<string>? OnActionExecuting`

Event: a tool call has started. Payload: the text shown to the user for it — the action's description, else a readable form of its name, or the routing, team or hosted-tool text. The tool's technical name is in [`IMentorStateService.OnActionStarted`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstateservice#onactionstarted).

### `OnActionFailed`

`event Action<string>? OnActionFailed`

Event: a tool call has failed. Payload: error message.

### `OnActionStarted`

`event Action<MentorActionStarted>? OnActionStarted`

Event: a tool call has started, with the tool's technical name next to the text shown. Raised with [`IMentorStateService.OnActionExecuting`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstateservice#onactionexecuting), where the turn runs: in the Blazor Server circuit or the MAUI app, and on the server for the hub, SSE and A2A. The WebAssembly client's implementation does not raise it, since the hub sends it only the text shown: record actions on the server.

The interface implements it as an event nobody raises, so an implementation written before it still compiles and runs.

### `OnApprovalResponse`

`event Action<ConfirmationRequest, bool>? OnApprovalResponse`

Event: the user's answer to a confirmation dialog (approved or denied) reached the turn that was waiting for it. Not raised for an answer that reaches nothing — given after Stop, after the connection or circuit closed, or a second time — so it can be logged as a decision that was acted on.

### `OnBusyChanged`

`event Action<bool>? OnBusyChanged`

Event: the AI is busy (true) or idle (false).

### `OnCardsReady`

`event Action<IReadOnlyList<MentorCard>>? OnCardsReady`

Event: a tool returned one or more [`MentorCard`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentorcard)s to render with the reply (roadmap \#14, generative UI L2). Purely additive — a client that ignores it still gets the assistant's text, which describes the same data.

### `OnConfirmationRequired`

`event Action<ConfirmationRequest>? OnConfirmationRequired`

Event: confirmation required for a destructive action.

### `OnError`

`event Action<string>? OnError`

Event: critical error to display in the widget.

### `OnGeneratedImages`

`event Action<IReadOnlyList<string>>? OnGeneratedImages`

Event: a provider-hosted image generation tool produced one or more images for the current response. Payload: image sources ready for an `<img src>` — a `data:` URI when the provider returned bytes, a remote URL when it returned a link. Fired before [`IMentorStateService.OnStreamingCompleted`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstateservice#onstreamingcompleted), so the widget can attach them to the finished message.

### `OnHostedToolsDeclared`

`event Action<MentorHostedTools>? OnHostedToolsDeclared`

Event: the server declared which provider-hosted tools are actually active (roadmap \#15).

Only a remote transport raises this. Hosted tools are a **server-side** capability, so a detached client (WASM, React, MAUI) cannot know them from its own configuration — mirroring the list by hand means the badge keeps claiming tools the server dropped, or missing ones it gained. The widget prefers this value over its local options as soon as it arrives.

### `OnMcpServerStatusChanged`

`event Action<string, bool>? OnMcpServerStatusChanged`

Event: an MCP server connection changed status. Payload: server name, connected (true) or disconnected (false).

### `OnNavigationRequested`

`event Action<string>? OnNavigationRequested`

Event: automatic navigation after tool execution.

### `OnRagSourcesReady`

`event Action<IReadOnlyList<MentorRagResult>>? OnRagSourcesReady`

Event: RAG sources available for the current response. Fired just before [`IMentorStateService.OnStreamingCompleted`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstateservice#onstreamingcompleted).

### `OnStreamingChunk`

`event Action<string>? OnStreamingChunk`

Event: new streaming text chunk from the AI.

### `OnStreamingCompleted`

`event Action? OnStreamingCompleted`

Event: streaming completed.

### `OnTeamMemberSpeaking`

`event Action<string, string>? OnTeamMemberSpeaking`

Event: a team member has started speaking during a GroupChat discussion. Payload: team name, member role name.

### `OnUIActionCompleted`

`event Action<string>? OnUIActionCompleted`

Event: UI action completed.

### `OnUIActionExecuting`

`event Action<string>? OnUIActionExecuting`

Event: UI action is executing.

---

- Previous: [IMentorPageContext interface](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorpagecontext.md)
- Next: [IMentorStructured interface](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentorstructured.md)
