How Session References (@) Work in Reasonix: A Complete Technical Guide

Reasonix treats any token starting with @ as a reference that loads saved session files and injects their content into the current conversation turn, enabling cross-session continuity.

The esengine/DeepSeek-Reasonix repository implements a sophisticated reference system that allows users to pull context from previous conversations using the @ symbol. When you type @filename in a prompt, the system parses this token, resolves it to a session file, and feeds that conversation history into the current LLM context. This mechanism is implemented across several key packages in the Go codebase, from token parsing in the control layer to session loading in the tool layer.

The Session Reference Processing Pipeline

The session reference mechanism operates through a rigid five-stage pipeline defined in internal/control/refs.go and internal/tool/sessiontool/sessiontool.go.

Stage 1: Token Extraction with parseRefTokens

The pipeline begins when user input containing @ tokens enters the system. The parseRefTokens function in internal/control/refs.go uses a regular expression to scan lines for reference patterns.

// internal/control/refs.go
var refTokenRe = regexp.MustCompile(`@([^\s]+)`)
func parseRefTokens(line string) []string { … }

This regex captures everything after the @ symbol until it hits whitespace, stripping punctuation and preparing the token for classification.

Stage 2: Classification via classifyRef

Once extracted, tokens pass through classifyRef, which determines the reference type. The function checks if the token matches a known MCP server resource or exists as a file path.

// internal/control/refs.go
func classifyRef(token string, known map[string]bool, exists func(string) bool) (ref, bool) {
    …
    if exists(token) {
        return ref{kind: refFile, path: token, raw: token}, true
    }
    …
}

If the token corresponds to an existing file in the session directory (such as 20260618-231556.000000000-gpt-4.jsonl), it returns a refFile type.

Stage 3: Resolution with Controller.ResolveRefs

When a turn is submitted, the controller orchestrates reference resolution. The Controller.ResolveRefs method invokes detectRefs, which calls classifyRef to identify refFile entries pointing to session files.

Upon detecting a session file reference, the controller triggers the session-tool read_session to fetch the content.

Stage 4: Session Loading via read_session Tool

The readSessionTool.Execute function in internal/tool/sessiontool/sessiontool.go handles the actual file operations. It loads the JSON-L file using agent.LoadSession, applies truncation limits, and formats the output as markdown.

// internal/tool/sessiontool/sessiontool.go
func (t *readSessionTool) Execute(_ context.Context, args json.RawMessage) (string, error) {
    …
    ses, err := agent.LoadSession(sessionPath)          // ← loads the .jsonl
    …
    // truncate and format messages → markdown
}

By default, the tool truncates each message to 2000 runes and strips system prompts to maintain privacy.

Stage 5: Context Injection into the Current Turn

The formatted markdown string returned by the session tool is inserted directly into the user prompt. This injection gives the LLM immediate access to the prior conversation's context, allowing seamless continuation of cross-session discussions.

Practical Examples of Using Session References

Listing Available Sessions

Before referencing past conversations, users can discover available sessions using the list_sessions tool. This produces a formatted table of all saved sessions.

// In the chat UI (or via CLI)
{
  "name": "list_sessions",
  "arguments": {}
}

The output includes timestamps, models, turn counts, and filenames:


# Saved Sessions (3 total)

| # | Timestamp          | Model | Turns | Preview                     | File |

|---|-------------------|-------|-------|-----------------------------|------|
| 1 | 2026-06-18 23:15  | gpt‑4 | 12    | “How do I …?”               | `20260618-231556.000000000-gpt-4.jsonl` |
…

Referencing a Past Session in Your Prompt

To leverage session references, simply include the filename with an @ prefix in your message:


Please continue the discussion from my previous run: @20260618-231556.000000000-gpt-4.jsonl

Behind the scenes, Reasonix executes three steps:

  1. Detects the @20260618‑… token via detectRefs
  2. Calls read_session with the session identifier
  3. Inserts the formatted excerpt into the current turn:

# Session: 20260618-231556.000000000-gpt-4.jsonl

## User (turn 1)

How do I …?

## Assistant (turn 1)

…

Programmatically Invoking the Read-Session Tool

For scripted interactions or custom integrations, instantiate the tool directly:

tool := sessiontool.NewReadSessionTool("/path/to/.reasonix/sessions")
output, err := tool.Execute(context.Background(),
    json.RawMessage(`{"session":"20260618-231556.000000000-gpt-4.jsonl","max_turns":0}`))
if err != nil { log.Fatalf("read error: %v", err) }
fmt.Println(output)

Privacy and Safety Controls

The session reference system implements several safeguards to protect sensitive data. According to the source code in internal/tool/sessiontool/sessiontool.go, the read_session tool automatically strips system prompts and caps each message at 2000 runes. Furthermore, tool results are omitted unless explicitly requested via the show_tool_results parameter. These defaults ensure that referencing past conversations does not inadvertently expose system instructions or verbose tool outputs.

Summary

  • Token Parsing: The @ symbol triggers parseRefTokens in internal/control/refs.go to extract reference candidates from user input.
  • File Resolution: classifyRef validates whether tokens map to existing session files in the .reasonix/sessions directory.
  • Session Loading: The read_session tool loads JSON-L files via agent.LoadSession and truncates content to 2000 runes per message.
  • Context Injection: Processed session history is formatted as markdown and injected into the current LLM prompt.
  • Privacy Defaults: System prompts are automatically stripped, and tool results require explicit opt-in via show_tool_results.

Frequently Asked Questions

How does Reasonix distinguish between session references and other @ mentions?

The classifyRef function in internal/control/refs.go checks if the token following @ exists as a file path in the session directory. If the file exists, it becomes a refFile type; otherwise, the system may treat it as a different resource type or ignore it. This existence check ensures only valid session files trigger the session-loading pipeline.

Can I limit how many turns from a previous session get loaded?

Yes. When invoking the read_session tool programmatically, you can pass the max_turns parameter in the JSON arguments. Setting "max_turns": 0 loads all available turns, while positive integers restrict the loaded history to that specific number of recent exchanges.

Where does Reasonix store session files that can be referenced?

Session files are stored in the .reasonix/sessions directory, configured via sessionDir in desktop/main.go. The files follow a strict naming convention: YYYYMMDDHHMMSS.NNNNNNNNN-<model>.jsonl, containing JSON-L formatted conversation history that the readSessionTool parses and formats.

Why are system prompts stripped when referencing past sessions?

The read_session tool strips system prompts by default to maintain privacy and security boundaries. This prevents prior system instructions from leaking into new conversation contexts, ensuring that only the actual dialogue between user and assistant carries forward. Tool results are similarly excluded unless explicitly requested with show_tool_results.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →