# DeepSeek TUI Session State Management: A Complete Guide to Turn-Based Conversation

> Master DeepSeek TUI session state management for turn-based conversation. Learn how the Session struct handles message flow, context, and safety controls.

- Repository: [Hunter Bown/DeepSeek-TUI](https://github.com/Hmbown/DeepSeek-TUI)
- Tags: deep-dive
- Published: 2026-05-04

---

**TLDR:** DeepSeek TUI maintains conversation state through a centralized `Session` struct that persists for the entire TUI lifetime, managing turn-based message flow, context compaction via cycles, and project-aware file tracking while enforcing safety controls over tool execution.

DeepSeek TUI is a Rust-based terminal interface for interacting with DeepSeek language models. At its core lies a robust **session state management** system that enables persistent, turn-based conversations with automatic context compaction and tool execution capabilities. The repository `Hmbown/DeepSeek-TUI` implements this architecture through a centralized `Session` object defined in [[`crates/tui/src/core/session.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/session.rs)](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/session.rs).

## The Session Struct: Central State Container

The `Session` struct encapsulates the entire conversation state and configuration. Created when the TUI starts or when the dispatcher launches new execution, it persists until the session terminates.

Key fields include:

- **`model`** – The identifier string (e.g., `deepseek-v4-flash`) specifying which LLM to query.
- **`messages`** – A `Vec<Message>` storing the raw OpenAI-compatible chat history where every turn appends new entries.
- **`reasoning_effort`** – Optional tier (`off`, `low`, `medium`, `high`, `max`) controlling DeepSeek's "thinking" mode depth.
- **`workspace`** – The root `PathBuf` for resolving all relative file operations during tool execution.
- **`system_prompt`** and **`compaction_summary_prompt`** – System-level prompts prepended to requests, with the latter storing compacted conversation summaries.
- **`total_usage`** – Cumulative token counters (`SessionUsage`) updated after each turn via `SessionUsage::add`.
- **`cycle_count`**, **`current_cycle_started`**, and **`cycle_briefings`** – Turn-based bookkeeping for conversation segmentation and the `/cycles` command.
- **`allow_shell`**, **`trust_mode`**, **`auto_approve`** – Boolean flags controlling shell tool invocation, workspace boundary trust, and automatic safety approval.
- **`working_set`** – A repo-aware file cache rebuilt from messages on demand, enabling the `/files` and `/search` commands.
- **`project_context`** – Information loaded from [`AGENTS.md`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/AGENTS.md) and [`CLAUDE.md`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/CLAUDE.md) files for context-aware tooling.
- **`id`** – A UUID for telemetry and debugging purposes.

## Turn-Based Conversation Lifecycle

Each interaction follows a strict **turn-based** execution model defined in [[`crates/tui/src/core/engine.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/engine.rs)](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/engine.rs). The lifecycle proceeds through five distinct phases:

### 1. User Input Capture

The UI creates a `Message::User` variant and calls `Session::add_message` to append the user content to the session history.

### 2. Engine Execution

The core engine reads `session.messages`, constructs the LLM request, transmits it to the DeepSeek API, and receives the response. The engine handles `ContentBlock::Thinking` segments by repeating reasoning blocks before final answers to comply with DeepSeek's "thinking mode" requirements.

### 3. Tool Call Processing

If the assistant response includes tool calls (e.g., `fetch_url`, `web_search`, `apply_patch`), the engine executes the appropriate handlers. Results are appended as `Message::Tool` entries, and the turn may replay until the model produces a final answer without tool requests.

### 4. Context Compaction and Cycle Handling

When the token budget approaches limits or after a configurable number of turns, the engine triggers compaction via `Session::compaction_summary_prompt`. The current conversation summarizes into a brief system prompt, `cycle_count` increments, and a `CycleBriefing` stores the phase summary. This bounds session size and enables the `/cycles` command timeline.

### 5. Working Set Reconstruction

`Session::rebuild_working_set` synchronizes the repo-aware file cache with the latest messages, ensuring subsequent `/files` and `/search` commands reference only conversation-relevant paths.

## Cycle Management and Context Compaction

Long-running sessions utilize **cycles** to prevent unbounded token growth. A cycle represents a logical conversation segment capped by compaction events.

The `CycleBriefing` type, defined in [[`crates/tui/src/rlm/turn.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/rlm/turn.rs)](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/rlm/turn.rs), stores summaries of approximately 3,000 tokens maximum. When compaction triggers:

1. The engine generates a summary of the current conversation context.
2. The summary populates `compaction_summary_prompt`.
3. `cycle_count` increments and `current_cycle_started` updates.
4. A new `CycleBriefing` entry appends to `cycle_briefings`.

This design ensures the session remains serializable to disk for later resumption while maintaining manageable context windows.

## Working Set and Project Awareness

The **`WorkingSet`** struct, implemented in [[`crates/tui/src/core/working_set.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/working_set.rs)](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/working_set.rs), maintains a cache of files the model may reference during the conversation. Rather than scanning the entire repository each turn, the working set rebuilds incrementally from message content via `rebuild_working_set`.

This enables efficient "search-and-open" functionality without filesystem overhead, while `project_context` fields load metadata from [`AGENTS.md`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/AGENTS.md) and [`CLAUDE.md`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/CLAUDE.md) files to provide contextual awareness of project conventions.

## Safety Controls and Session Configuration

The session enforces security boundaries through three critical flags stored as struct fields:

- **`allow_shell`** – Controls whether the model may invoke shell execution tools.
- **`trust_mode`** – Determines if paths outside the `workspace` root are trusted for file operations.
- **`auto_approve`** – When disabled, requires manual user confirmation before executing safety-sensitive actions.

These controls, alongside token accounting via `SessionUsage`, provide fine-grained governance over autonomous tool execution.

## Practical Implementation Example

The following Rust code demonstrates session initialization and turn processing patterns:

```rust
// Creating a new session (called from the dispatcher)
let session = Session::new(
    "deepseek-v4-flash".to_string(),
    PathBuf::from("./my_project"),
    /*allow_shell=*/ false,
    /*trust_mode=*/ false,
    PathBuf::from("./notes.md"),
    PathBuf::from("./mcp_config.toml"),
);

// Adding a user message
session.add_message(Message::User {
    role: "user".into(),
    content: "Explain the Rust ownership model".into(),
});

// Run a turn – this is done by the engine; simplified here
let response = engine::run_turn(&mut session)?;

// The response is added back to the session
session.add_message(response);

// After many turns, compact the context to keep the session small
if session.total_usage.output_tokens > 10_000 {
    let summary = engine::compact_context(&session)?;
    session.compaction_summary_prompt = Some(summary);
}

```

## Summary

- The `Session` struct in [`crates/tui/src/core/session.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/session.rs) serves as the single source of truth for conversation state, configuration, and safety controls.
- Turn-based processing follows a five-phase lifecycle: user input → engine execution → tool handling → compaction → working set rebuild.
- **Cycles** prevent context explosion by summarizing conversation segments into compact briefings stored in `cycle_briefings`.
- The **WorkingSet** provides repo-aware file caching without full repository scans.
- Safety flags (`allow_shell`, `trust_mode`, `auto_approve`) enforce execution boundaries while `SessionUsage` tracks cumulative token consumption.
- All message history persists in OpenAI-compatible format, enabling serialization and session resumption.

## Frequently Asked Questions

### How does DeepSeek TUI handle session persistence?

The `Session` struct maintains all conversation state in serializable fields (`messages`, `cycle_briefings`, `total_usage`) that can be written to disk. The implementation stores raw message history and compaction summaries, allowing users to save and resume sessions later without losing context. The UUID field (`id`) aids in telemetry correlation across resumed sessions.

### What triggers context compaction in a session?

Compaction triggers when `total_usage.output_tokens` exceeds configurable thresholds (e.g., 10,000 tokens) or after a set number of turns. The engine in [`crates/tui/src/core/engine.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/engine.rs) invokes `compact_context`, generating a summary that becomes the new `compaction_summary_prompt`. This increments `cycle_count` and creates a `CycleBriefing` entry to maintain conversation continuity while bounding memory usage.

### How are tool calls integrated into the turn-based flow?

When the LLM returns tool calls, the engine executes the corresponding tools (defined in the tool registry) and appends results as `Message::Tool` variants to `session.messages`. The turn replays with the tool results included until the model provides a final assistant response without additional tool requests. This cycle may iterate multiple times per user turn depending on tool dependencies.

### What is the working set and when does it rebuild?

The **WorkingSet** is a repo-aware cache of files referenced in the conversation, implemented in [`crates/tui/src/core/working_set.rs`](https://github.com/Hmbown/DeepSeek-TUI/blob/main/crates/tui/src/core/working_set.rs). It rebuilds via `rebuild_working_set` after each turn completion, scanning `session.messages` for file references. This enables the `/files` and `/search` commands to surface relevant project files without scanning the entire repository filesystem on every interaction.