# How to Manage Chat History in AntSK: 7 Proven Strategies for Persistent Conversations

> Discover 7 proven strategies to effectively manage chat history in AntSK using Semantic Kernel and local storage. Maintain persistent, isolated conversations with ease.

- Repository: [AIDotNet/antsk](https://github.com/aidotnet/antsk)
- Tags: best-practices
- Published: 2026-02-24

---

**AntSK uses Semantic Kernel's `ChatHistory` class combined with browser local storage to maintain conversational context across page reloads while isolating knowledge-base queries from general chat.**

Effective management of conversational context is critical for building coherent AI applications. In the `aidotnet/antsk` repository, chat history management follows a structured lifecycle that balances in-memory performance with persistent storage. Understanding these patterns ensures your LLM interactions remain contextual and survive browser refreshes.

## Initialize ChatHistory with Optional System Prompts

Every conversation in AntSK starts with a fresh `ChatHistory` instance. In [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) (lines 233–238), the `GetHistory` method creates a new history object and optionally seeds it with a system prompt:

```csharp
private async Task<(string, ChatHistory)> GetHistory(OpenAIModel model, string systemPrompt)
{
    ChatHistory history = new ChatHistory();
    if (!string.IsNullOrWhiteSpace(systemPrompt))
        history = new ChatHistory(systemPrompt);
    return (model.ModelId, history);
}

```

This guarantees that each dialogue begins with the correct role instructions while maintaining a clean separation between different application contexts.

## Merge Persisted Messages with In-Memory History

When a user returns to a chat session, AntSK restores previous turns by merging stored messages into the current `ChatHistory`. The [`ChatView.razor.cs`](https://github.com/aidotnet/antsk/blob/main/ChatView.razor.cs) component (lines 254–256) handles this reconciliation:

```csharp
ChatHistory history = new ChatHistory();
history = await _chatService.GetChatHistory(MessageList, history);
await SendChat(history, app);   // Pass combined history to the LLM

```

This pattern allows users to refresh the page or navigate away without losing conversational continuity.

## Persist Conversations to Browser Storage

AntSK ensures durability by saving each turn to the browser's local storage immediately after message transmission. In [`ChatView.razor.cs`](https://github.com/aidotnet/antsk/blob/main/ChatView.razor.cs) (lines 119–134), the component persists the message list using `ILocalStorage`:

```csharp
await _localStorage.SetItemAsync($"msgs:{AppId}", MessageList);

```

The key naming convention `$"msgs:{AppId}"` enables per-application isolation, preventing conversation leakage between different AI apps within the same AntSK instance.

## Send Full Context to the Language Model

Before invoking the LLM, AntSK appends the current user message to the accumulated history. The `SendChat` and `SendKms` methods in [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) (lines 100–107 and 126–129) demonstrate this pattern:

```csharp
var chatResult = _chatService.SendChatByAppAsync(app, history);
ChatMessageContent result = await chat.GetChatMessageContentAsync(
        history, settings, _kernel);

```

Passing the complete `ChatHistory` object ensures the model receives the full dialogue context necessary for coherent, multi-turn responses.

## Isolate Knowledge-Base History from General Chat

AntSK maintains strict separation between retrieval-augmented generation (KMS) flows and standard chat interactions. The `GetHistory` method in [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) (lines 170–197) returns both a system prompt string and a `ChatHistory` object, while KMS-related methods (`SendKms`, `SendKmsStream`) manage their own history flow independently.

This architectural decision prevents prompt leakage between knowledge-base queries and general conversation, ensuring that specialized retrieval contexts do not contaminate casual chat sessions.

## Support Streaming with Shared Context

Whether using standard or streaming responses, AntSK reuses the same `ChatHistory` instance. The `SendChatStream` method in [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) (lines 100–107) feeds the existing history into Semantic Kernel's streaming API:

```csharp
// Reuse the same ChatHistory instance for streaming
var response = await _chatService.SendChatStreamAsync(history, app);

```

This approach guarantees that token-by-token streaming respects the identical conversational context as non-streaming calls, maintaining consistency across different interaction modes.

## Reset History for New Conversations

When users initiate a fresh dialogue by navigating to `openchat/{AppId}`, AntSK explicitly creates a new `ChatHistory` instance. The [`AppOpen.razor.cs`](https://github.com/aidotnet/antsk/blob/main/AppOpen.razor.cs) component (line 54) demonstrates this cleanup:

```csharp
// Fresh ChatHistory created, discarding previous context
ChatHistory history = new ChatHistory();

```

This explicit reset mechanism enables clean conversation boundaries without residual context from previous sessions.

## Summary

- **Initialize fresh history**: Create a new `ChatHistory` instance per conversation, optionally seeded with system prompts via `GetHistory` in [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs).
- **Merge persisted data**: Use `_chatService.GetChatHistory` to restore previous messages from local storage when reloading the chat interface.
- **Client-side persistence**: Store message lists using `ILocalStorage.SetItemAsync` with application-specific keys to survive browser refreshes.
- **Complete context transmission**: Always pass the full `ChatHistory` object to `SendChatByAppAsync` so the LLM receives the entire dialogue.
- **Separate KMS flows**: Maintain isolation between knowledge-base retrieval and general chat to prevent context contamination.
- **Unified streaming support**: Reuse the same `ChatHistory` instance for both streaming and standard completion calls.
- **Explicit reset capability**: Create new history instances when opening fresh conversations via [`AppOpen.razor.cs`](https://github.com/aidotnet/antsk/blob/main/AppOpen.razor.cs).

## Frequently Asked Questions

### How does AntSK store chat history between page reloads?

AntSK persists chat history to the browser's local storage using `ILocalStorage.SetItemAsync` with a key formatted as `$"msgs:{AppId}"`. When the user returns to the application, [`ChatView.razor.cs`](https://github.com/aidotnet/antsk/blob/main/ChatView.razor.cs) retrieves these messages and merges them into a new `ChatHistory` instance via `_chatService.GetChatHistory`, restoring the full conversational context.

### What is the difference between KMS and regular chat history in AntSK?

KMS (Knowledge Management System) history is isolated from general chat history to prevent retrieval-augmented generation contexts from leaking into casual conversations. According to [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) lines 170–197, KMS methods like `SendKms` and `SendKmsStream` maintain separate history flows, while standard chat uses the primary `ChatHistory` instance passed through `SendChatByAppAsync`.

### Can system prompts be customized per conversation in AntSK?

Yes. The `GetHistory` method in [`OpenApiService.cs`](https://github.com/aidotnet/antsk/blob/main/OpenApiService.cs) accepts an optional `systemPrompt` parameter. When provided, it initializes the `ChatHistory` with `new ChatHistory(systemPrompt)`, allowing different applications or conversation threads to start with specific role instructions or behavioral guidelines.

### How does AntSK handle streaming responses with existing chat history?

AntSK reuses the same `ChatHistory` instance for streaming operations. The `SendChatStream` method passes the accumulated history directly to Semantic Kernel's streaming API, ensuring that token-by-token responses maintain awareness of all previous turns in the conversation, identical to standard completion behavior.