# MentorChatReducer class

> The MentorChatReducer class of Novior.MentorAgent.Core: The reducer that keeps MentorAgent's built-in in-memory history bounded: it keeps the most recent…

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

The reducer that keeps MentorAgent's built-in in-memory history bounded: it keeps the most recent **whole turns** that fit in [`MentorChatReducer.MaxMessages`](https://docs.mentoragent.net/api/novior-mentoragent-core/mentorchatreducer#maxmessages), and every tool call together with its result.

**Why not `MessageCountingChatReducer`.** The framework's reducer drops every message that carries a function call or a function result. From the next turn on, the model no longer sees the data a tool read, and answers a follow-up ("and the second one?") by guessing or by calling the tool again. This reducer counts those messages like any other and cuts only where a turn starts.

**How it cuts.** A turn starts at a user message (one that only answers a tool approval does not start a turn). Turns are kept newest first while they fit; the first that does not fit is dropped with everything older, so a turn is never kept in part. When the newest turn alone is over the budget, its question and its most recent messages are kept. A tool result, or an approval response, whose call was cut away is removed with it: the model never sees a result without the call that produced it. The first system message, if any, is always kept and not counted, as `MessageCountingChatReducer` does.

It is stateless, so one instance can serve every session. Use it in a history provider of your own: `new InMemoryChatHistoryProvider(new() { ChatReducer = new MentorChatReducer(50) })`.

## Definition

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

`public sealed class MentorChatReducer : IChatReducer`

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

## Constructors

`public MentorChatReducer(int maxMessages)`

Creates a reducer that keeps at most `maxMessages` messages.

**Parameters**

- `maxMessages`: The budget, counting every message except the first system message — tool calls and tool results included. Must be at least 1.

## Properties

### `MaxMessages`

`public int MaxMessages { get; }`

The most messages the reduced history holds, not counting the first system message.

## Methods

### `ReduceAsync`

`public Task<IEnumerable<ChatMessage>> ReduceAsync(IEnumerable<ChatMessage> messages, CancellationToken cancellationToken = default)`

---

- Previous: [MentorAgentSourceContext record](https://docs.mentoragent.net/api/novior-mentoragent-core/mentoragentsourcecontext.md)
- Next: [MentorMetrics class](https://docs.mentoragent.net/api/novior-mentoragent-core/mentormetrics.md)
