Class: Kward::SessionStore::Session
- Inherits:
-
Object
- Object
- Kward::SessionStore::Session
- Defined in:
- lib/kward/session_store.rb
Overview
Live handle that attaches persistence callbacks to a conversation.
Once attached, every append/compact/tool execution writes a JSONL record and
advances leaf_id for session tree navigation. Avoid mutating the attached
conversation directly without these callbacks unless deliberately importing
or reconstructing history.
Instance Attribute Summary collapse
-
#created_at ⇒ Time
readonly
Creation timestamp used for sorting and filenames.
-
#cwd ⇒ String
readonly
Workspace directory recorded when the session was created.
-
#id ⇒ String
readonly
Stable persisted session id from the JSONL header.
-
#leaf_id ⇒ String?
Active tree leaf id used to restore the selected branch.
-
#name ⇒ String?
User-visible session name persisted as metadata records.
-
#parent_id ⇒ String?
readonly
Source session id when this session was cloned or forked.
-
#parent_path ⇒ String?
readonly
Source session path when this session was cloned or forked.
-
#path ⇒ String
readonly
Absolute JSONL session file path.
Instance Method Summary collapse
-
#append_branch_summary(parent_id, from_id:, summary:, details: {}) ⇒ Object
Adds a branch-summary node under
parent_idand selects it as the leaf. -
#append_label_change(entry_id, label) ⇒ Object
Persists a display label override for one tree entry.
-
#append_message(message) ⇒ Object
Persists a message as a tree entry and advances the session leaf.
-
#append_system_prompt_snapshot(system_message, reason: "changed") ⇒ Object
Persists the current system prompt as audit metadata when it changes.
-
#append_tool_execution(tool_call, content) ⇒ Object
Persists normalized tool execution metadata alongside transcript messages.
-
#attach(conversation) ⇒ Object
Installs persistence callbacks on
conversation. -
#branch(entry_id) ⇒ Object
Moves the active leaf to an existing entry so future messages fork there.
-
#compact(message) ⇒ Object
Persists a compaction summary entry and makes it the active leaf.
-
#delete_if_unused ⇒ Object
Removes this session file when it is still empty and unnamed.
-
#initialize(store:, id:, path:, cwd:, created_at:, name: nil, parent_id: nil, parent_path: nil, leaf_id: nil) ⇒ Session
constructor
Creates an object for JSONL session persistence.
-
#rename(name) ⇒ Object
Persists a user-visible session name without rewriting earlier records.
-
#reset_leaf ⇒ Object
Clears the active leaf so the next append starts a fresh root branch.
-
#update_memory_state(session_memories:, last_retrieval: nil) ⇒ Object
Persists the session memory snapshot used when the session is restored.
-
#update_runtime(provider: nil, model:, reasoning_effort:) ⇒ Object
Persists model/runtime metadata so restored sessions keep their context.
Constructor Details
#initialize(store:, id:, path:, cwd:, created_at:, name: nil, parent_id: nil, parent_path: nil, leaf_id: nil) ⇒ Session
Creates an object for JSONL session persistence.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/kward/session_store.rb', line 60 def initialize(store:, id:, path:, cwd:, created_at:, name: nil, parent_id: nil, parent_path: nil, leaf_id: nil) @store = store @id = id @path = path @cwd = cwd @created_at = created_at @name = name @parent_id = parent_id @parent_path = parent_path @leaf_id = leaf_id end |
Instance Attribute Details
#created_at ⇒ Time (readonly)
Returns creation timestamp used for sorting and filenames.
49 50 51 |
# File 'lib/kward/session_store.rb', line 49 def created_at @created_at end |
#cwd ⇒ String (readonly)
Returns workspace directory recorded when the session was created.
47 48 49 |
# File 'lib/kward/session_store.rb', line 47 def cwd @cwd end |
#id ⇒ String (readonly)
Returns stable persisted session id from the JSONL header.
43 44 45 |
# File 'lib/kward/session_store.rb', line 43 def id @id end |
#leaf_id ⇒ String?
Returns active tree leaf id used to restore the selected branch.
57 58 59 |
# File 'lib/kward/session_store.rb', line 57 def leaf_id @leaf_id end |
#name ⇒ String?
Returns user-visible session name persisted as metadata records.
55 56 57 |
# File 'lib/kward/session_store.rb', line 55 def name @name end |
#parent_id ⇒ String? (readonly)
Returns source session id when this session was cloned or forked.
51 52 53 |
# File 'lib/kward/session_store.rb', line 51 def parent_id @parent_id end |
#parent_path ⇒ String? (readonly)
Returns source session path when this session was cloned or forked.
53 54 55 |
# File 'lib/kward/session_store.rb', line 53 def parent_path @parent_path end |
#path ⇒ String (readonly)
Returns absolute JSONL session file path.
45 46 47 |
# File 'lib/kward/session_store.rb', line 45 def path @path end |
Instance Method Details
#append_branch_summary(parent_id, from_id:, summary:, details: {}) ⇒ Object
Adds a branch-summary node under parent_id and selects it as the leaf.
148 149 150 151 152 153 |
# File 'lib/kward/session_store.rb', line 148 def append_branch_summary(parent_id, from_id:, summary:, details: {}) record = @store.build_tree_record(@path, "branch_summary", parent_id, fromId: from_id, summary: summary, details: details || {}) @leaf_id = record[:id] @store.append_record(@path, record) record[:id] end |
#append_label_change(entry_id, label) ⇒ Object
Persists a display label override for one tree entry.
143 144 145 |
# File 'lib/kward/session_store.rb', line 143 def append_label_change(entry_id, label) @store.append_label_change(@path, entry_id, label) end |
#append_message(message) ⇒ Object
Persists a message as a tree entry and advances the session leaf.
88 89 90 91 92 |
# File 'lib/kward/session_store.rb', line 88 def () record = @store.build_tree_record(@path, "message", @leaf_id, message: ) @leaf_id = record[:id] @store.append_record(@path, record) end |
#append_system_prompt_snapshot(system_message, reason: "changed") ⇒ Object
Persists the current system prompt as audit metadata when it changes.
107 108 109 |
# File 'lib/kward/session_store.rb', line 107 def append_system_prompt_snapshot(, reason: "changed") @store.append_system_prompt_snapshot(@path, , reason: reason) end |
#append_tool_execution(tool_call, content) ⇒ Object
Persists normalized tool execution metadata alongside transcript messages.
102 103 104 |
# File 'lib/kward/session_store.rb', line 102 def append_tool_execution(tool_call, content) @store.append_record(@path, RPC::ToolEventNormalizer.new(tool_call, content: content).execution_record) end |
#attach(conversation) ⇒ Object
Installs persistence callbacks on conversation.
The callbacks are intentionally simple lambdas so Conversation remains
storage-agnostic while SessionStore remains the only owner of JSONL
record shape.
77 78 79 80 81 82 83 84 85 |
# File 'lib/kward/session_store.rb', line 77 def attach(conversation) conversation.on_append = lambda { || () } conversation.on_compact = lambda { || compact() } conversation.on_tool_execution = lambda { |tool_call, content| append_tool_execution(tool_call, content) } conversation.on_runtime_update = lambda { |provider:, model:, reasoning_effort:| update_runtime(provider: provider, model: model, reasoning_effort: reasoning_effort) } conversation. = lambda { || append_system_prompt_snapshot(, reason: "changed") } append_system_prompt_snapshot(conversation., reason: "attach") self end |
#branch(entry_id) ⇒ Object
Moves the active leaf to an existing entry so future messages fork there.
132 133 134 135 |
# File 'lib/kward/session_store.rb', line 132 def branch(entry_id) @leaf_id = entry_id.to_s.empty? ? nil : entry_id.to_s @store.append_leaf_change(@path, @leaf_id) end |
#compact(message) ⇒ Object
Persists a compaction summary entry and makes it the active leaf.
95 96 97 98 99 |
# File 'lib/kward/session_store.rb', line 95 def compact() record = @store.build_tree_record(@path, "compaction", @leaf_id, message: ) @leaf_id = record[:id] @store.append_record(@path, record) end |
#delete_if_unused ⇒ Object
Removes this session file when it is still empty and unnamed.
168 169 170 |
# File 'lib/kward/session_store.rb', line 168 def delete_if_unused @store.delete_unused_session(self) end |
#rename(name) ⇒ Object
Persists a user-visible session name without rewriting earlier records.
122 123 124 125 126 127 128 129 |
# File 'lib/kward/session_store.rb', line 122 def rename(name) @name = name.to_s.strip.empty? ? nil : name.to_s.strip @store.append_record(@path, { type: "session_info", timestamp: Time.now.utc.iso8601(3), name: @name }) end |
#reset_leaf ⇒ Object
Clears the active leaf so the next append starts a fresh root branch.
138 139 140 |
# File 'lib/kward/session_store.rb', line 138 def reset_leaf branch(nil) end |
#update_memory_state(session_memories:, last_retrieval: nil) ⇒ Object
Persists the session memory snapshot used when the session is restored.
112 113 114 115 116 117 118 119 |
# File 'lib/kward/session_store.rb', line 112 def update_memory_state(session_memories:, last_retrieval: nil) @store.append_record(@path, { type: "memory_state", timestamp: Time.now.utc.iso8601(3), sessionMemories: Array(session_memories), lastRetrieval: last_retrieval }) end |
#update_runtime(provider: nil, model:, reasoning_effort:) ⇒ Object
Persists model/runtime metadata so restored sessions keep their context.
156 157 158 159 160 161 162 163 164 165 |
# File 'lib/kward/session_store.rb', line 156 def update_runtime(provider: nil, model:, reasoning_effort:) @store.append_record(@path, { type: "session_info", timestamp: Time.now.utc.iso8601(3), name: @name, provider: provider.to_s, model: model.to_s, reasoningEffort: reasoning_effort.to_s }.delete_if { |_key, value| value.to_s.empty? }) end |