-
Notifications
You must be signed in to change notification settings - Fork 5
EN Course 04 Session Store
The store layer gives each session a durable directory:
CONV_FILE="${session_dir}/conversation.jsonl"
SESSION_EVENT_FILE="${session_dir}/events.jsonl"
CONTEXT_SUMMARY_FILE="${session_dir}/summary.txt"
PLAN_FILE="${session_dir}/plan.md"
PLAN_DRAFT_FILE="${session_dir}/plan.draft"
STATS_FILE="${session_dir}/stats.json"These files have different jobs:
| File | Role |
|---|---|
conversation.jsonl |
model-facing message history |
events.jsonl |
replay and stream-json event log |
summary.txt |
compacted long-session summary |
plan.md |
locked plan included in prompt |
plan.draft |
draft plan that does not invalidate prompt cache |
stats.json |
turns, token usage, cache tokens, title data |
conversation.jsonl is for the model. It stores user, assistant, and tool-result messages in the format used to build the next request.
events.jsonl is for runtime observation. It records text, thinking, tool calls, tool results, usage, errors, sub-agent events, and context updates.
This split lets the runtime replay a session without reconstructing display output from model messages.
Replay reads recent events, not the full conversation:
store_event_recent_turn_lines() {
local turns="${1:-10}" _match _from_line
[[ -s "${SESSION_EVENT_FILE:-}" ]] || return 0
_match=$(grep -n '"type":"user_input"' "$SESSION_EVENT_FILE" | tail -n "$turns" | head -n 1) || true
_from_line="${_match%%:*}"
[[ -n "$_from_line" && "$_from_line" -ge 1 ]] || _from_line=1
tail -n +"$_from_line" "$SESSION_EVENT_FILE"
}This keeps entering long sessions cheap.
Replay is display-oriented. It does not rebuild conversation.jsonl; it turns recent events.jsonl lines back into display messages:
events.jsonl
-> event_replay.awk
-> RESP-like messages
-> display_stream
That means live execution and replay share the same display renderer.
Usage events update stats.json:
agent_record_usage() {
local kind="$1" counter_key="$2" write_event="${3:-true}"
store_stats_update ${counter_key}=+1 \
total_input_tokens=+${_in} \
total_output_tokens=+${_out} \
total_cache_read_tokens=+${_cr} \
total_cache_creation_tokens=+${_cc}
}Stats are not only for reporting. They drive:
- current context token estimate
- compaction decisions
- cache hit visibility
- terminal title formatting
- runtime parity tests
The title is generated from the same stats file:
store_stats_format_title() {
util_awk_run -v model="$1" -f "$AWK_DIR/term_title.awk" "$STATS_FILE"
}System Prompt Builder explains how stable prompt sections are assembled.