# MentorMetrics class

> The MentorMetrics class of Novior.MentorAgent.Core: Thread-safe, process-wide implementation of IMentorMetrics that feeds the admin token & cost dashboard…

- URL: https://docs.mentoragent.net/api/novior-mentoragent-core/mentormetrics
- Verified with: MentorAgent 1.2.0
- Last updated: 2026-10-27
- Packages: Novior.MentorAgent

Thread-safe, process-wide implementation of [`IMentorMetrics`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentormetrics) that feeds the admin token &amp; cost dashboard (roadmap \#9). Usage is bucketed **per model** — the cheap chat model, the strong routing model and the embedding model are tracked separately (tokens, requests, latency) with an hourly time series for the temporal charts. Cost is computed per model, only for models present in [`MentorOptions.ModelPricing`](https://docs.mentoragent.net/api/novior-mentoragent-options/mentoroptions#modelpricing). Conversation-level counters (turns, errors, guardrail blocks, top actions) are model-independent.

## Definition

Namespace: `Novior.MentorAgent.Core`. Package: `Novior.MentorAgent`.

`public sealed class MentorMetrics : IMentorMetrics`

Implements [`IMentorMetrics`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentormetrics).

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

## Constructors

`public MentorMetrics(MentorTokenUsage tokens, IOptions<MentorOptions> options)`

## Properties

### `EmbeddingModelId`

`public string? EmbeddingModelId { get; set; }`

Embedding model id, set by the orchestrator when an embedding generator is configured.

### `ModelId`

`public string? ModelId { get; set; }`

Primary (cheap) chat model id — set once by the orchestrator. Also used for pricing lookup.

### `StrongModelId`

`public string? StrongModelId { get; set; }`

Strong routing model id (roadmap \#11), set by the orchestrator when configured.

## Methods

### `EnsureConfiguredModels`

`public void EnsureConfiguredModels()`

Registers the configured cheap / strong / embedding model ids as zero-usage buckets so they appear (and are selectable) in the dashboard **before** they serve any traffic — e.g. the strong routing model when no turn has escalated to it yet. Idempotent and non-destructive: it never resets a bucket that already has live counters.

The ids are read straight from the configured clients' metadata (the orchestrator captures the same values, but the coordinator is built lazily on first chat — this keeps the dashboard correct even when it's opened before any conversation).

### `GetSnapshot`

`public MentorMetricsSnapshot GetSnapshot()`

### `RecordError`

`public void RecordError()`

### `RecordGuardrailBlock`

`public void RecordGuardrailBlock()`

### `RecordModelUsage`

`public void RecordModelUsage(string? modelId, long inputTokens, long outputTokens, double? latencyMs = null, double? timeToFirstByteMs = null, bool usageMeasured = true)`

Records one model round-trip's usage against the given model id (roadmap \#9 per-model dashboard). Called by `TokenUsageChatClient` (chat, reading `response.ModelId`) and by `MeteringEmbeddingGenerator` (embeddings). Latency/TTFB are optional.

**Parameters**

- `usageMeasured`: `false` when the call reached the provider but never reported its token counts — a stream the user stopped. Such a call is still counted as a request (it was billed, input prompt included) and disclosed through [`MentorModelUsage.RequestsWithoutUsage`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentormodelusage#requestswithoutusage), but it contributes nothing to the token totals: the numbers are unknown, and zero is a fabricated measurement, not a cautious one (BUG-032).
- `modelId`: The model that served the call, as the provider reported it.
- `inputTokens`: Input tokens of the call.
- `outputTokens`: Output tokens of the call.
- `latencyMs`: Duration of the whole call, when measured.
- `timeToFirstByteMs`: Time to the first streamed byte, when measured.

### `RecordServed`

`public void RecordServed()`

### `RecordToolCall`

`public void RecordToolCall(string toolName)`

### `RecordTurn`

`public void RecordTurn()`

### `Reset`

`public void Reset()`

### `Seed`

`public void Seed(MentorMetricsSnapshot snapshot)`

Restores counters and per-model buckets from a persisted snapshot (roadmap \#9 durable dashboard). Called once at startup by the persistence hosted service so totals continue across a restart.

---

- Previous: [MentorChatReducer class](https://docs.mentoragent.net/api/novior-mentoragent-core/mentorchatreducer.md)
- Next: [MentorRateLimiter class](https://docs.mentoragent.net/api/novior-mentoragent-core/mentorratelimiter.md)
