Class: Kward::SessionStore
- Inherits:
-
Object
- Object
- Kward::SessionStore
- Defined in:
- lib/kward/session_store.rb
Defined Under Namespace
Classes: Session, SessionInfo
Constant Summary collapse
- VERSION =
1
Instance Attribute Summary collapse
-
#cwd ⇒ Object
readonly
Returns the value of attribute cwd.
Class Method Summary collapse
Instance Method Summary collapse
- #append_record(path, record) ⇒ Object
- #create(model: nil, reasoning_effort: nil, parent_id: nil, parent_path: nil) ⇒ Object
- #create_from_conversation(conversation, parent_session: nil) ⇒ Object
- #create_independent_from_conversation(conversation, parent_session: nil) ⇒ Object
- #create_independent_from_messages(messages, read_paths: [], model: nil, reasoning_effort: nil, parent_session: nil) ⇒ Object
- #delete_unused_session(session) ⇒ Object
-
#initialize(config_dir: ConfigFiles.config_dir, cwd: Dir.pwd) ⇒ SessionStore
constructor
A new instance of SessionStore.
- #load(path, workspace: Workspace.new, model: nil, reasoning_effort: nil) ⇒ Object
- #recent(limit: 20) ⇒ Object
- #recent_tree(limit: 20) ⇒ Object
- #session_dir ⇒ Object
- #session_location(path) ⇒ Object
Constructor Details
#initialize(config_dir: ConfigFiles.config_dir, cwd: Dir.pwd) ⇒ SessionStore
Returns a new instance of SessionStore.
93 94 95 96 |
# File 'lib/kward/session_store.rb', line 93 def initialize(config_dir: ConfigFiles.config_dir, cwd: Dir.pwd) @config_dir = config_dir @cwd = File.(cwd) end |
Instance Attribute Details
#cwd ⇒ Object (readonly)
Returns the value of attribute cwd.
98 99 100 |
# File 'lib/kward/session_store.rb', line 98 def cwd @cwd end |
Class Method Details
.safe_cwd(cwd) ⇒ Object
225 226 227 |
# File 'lib/kward/session_store.rb', line 225 def self.safe_cwd(cwd) "--#{File.(cwd).sub(%r{\A[/\\]}, "").gsub(%r{[/\\:]}, "-")}--" end |
Instance Method Details
#append_record(path, record) ⇒ Object
218 219 220 221 222 223 |
# File 'lib/kward/session_store.rb', line 218 def append_record(path, record) File.open(path, "a", 0o600) do |file| file.write(JSON.generate(record)) file.write("\n") end end |
#create(model: nil, reasoning_effort: nil, parent_id: nil, parent_path: nil) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/kward/session_store.rb', line 100 def create(model: nil, reasoning_effort: nil, parent_id: nil, parent_path: nil) dir = session_dir FileUtils.mkdir_p(dir, mode: 0o700) created_at = Time.now.utc id = SecureRandom.uuid path = File.join(dir, "#{created_at.iso8601(3).tr(':', '-')}_#{id}.jsonl") header = { type: "session", version: VERSION, id: id, timestamp: created_at.iso8601(3), cwd: @cwd, model: model.to_s, reasoningEffort: reasoning_effort.to_s, parentId: parent_id.to_s, parentPath: parent_path.to_s }.delete_if { |_key, value| value.to_s.empty? } File.open(path, File::WRONLY | File::CREAT | File::EXCL, 0o600) do |file| file.write(JSON.generate(header)) file.write("\n") end File.chmod(0o600, path) Session.new(store: self, id: id, path: path, cwd: @cwd, created_at: created_at, parent_id: parent_id, parent_path: parent_path) end |
#create_from_conversation(conversation, parent_session: nil) ⇒ Object
127 128 129 130 131 132 |
# File 'lib/kward/session_store.rb', line 127 def create_from_conversation(conversation, parent_session: nil) session = create(model: conversation.model, reasoning_effort: conversation.reasoning_effort, parent_id: parent_session&.id, parent_path: parent_session&.path) (conversation).each { || session.() } session.attach(conversation) session end |
#create_independent_from_conversation(conversation, parent_session: nil) ⇒ Object
134 135 136 137 138 139 140 141 142 |
# File 'lib/kward/session_store.rb', line 134 def create_independent_from_conversation(conversation, parent_session: nil) ( (conversation), read_paths: Array(conversation.read_paths), model: conversation.model, reasoning_effort: conversation.reasoning_effort, parent_session: parent_session ) end |
#create_independent_from_messages(messages, read_paths: [], model: nil, reasoning_effort: nil, parent_session: nil) ⇒ Object
144 145 146 147 148 149 150 151 |
# File 'lib/kward/session_store.rb', line 144 def (, read_paths: [], model: nil, reasoning_effort: nil, parent_session: nil) session = create(model: model, reasoning_effort: reasoning_effort, parent_id: parent_session&.id, parent_path: parent_session&.path) persisted = deep_copy() persisted.each { || session.() } conversation = Conversation.new(messages: deep_copy(persisted), read_paths: read_paths, workspace_root: @cwd, model: model, reasoning_effort: reasoning_effort) session.attach(conversation) [session, conversation] end |
#delete_unused_session(session) ⇒ Object
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/kward/session_store.rb', line 203 def delete_unused_session(session) path = session.path return false if session_named?(session) return false unless unused_session_file?(path) File.delete(path) true rescue StandardError false end |
#load(path, workspace: Workspace.new, model: nil, reasoning_effort: nil) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/kward/session_store.rb', line 160 def load(path, workspace: Workspace.new, model: nil, reasoning_effort: nil) resolved_path = resolve_session_path(path) records = records_from_file(resolved_path) header = session_header(records, resolved_path) = (records) name = session_name(records) read_paths = restored_read_paths(, workspace) memory_state = restored_memory_state(records) runtime = session_runtime(records, header) conversation = Conversation.new( messages: , read_paths: read_paths, workspace_root: workspace.root, model: runtime["model"] || model, reasoning_effort: runtime["reasoningEffort"] || reasoning_effort, session_memories: memory_state["sessionMemories"], last_memory_retrieval: memory_state["lastRetrieval"] ) conversation.mark_last_entry_compaction! if latest_record_type(records) == "compaction" session = Session.new( store: self, id: header["id"], path: resolved_path, cwd: header["cwd"].to_s, created_at: parse_time(header["timestamp"]) || File.mtime(resolved_path), name: name, parent_id: header["parentId"], parent_path: header["parentPath"] ) session.attach(conversation) [session, conversation] end |
#recent(limit: 20) ⇒ Object
195 196 197 |
# File 'lib/kward/session_store.rb', line 195 def recent(limit: 20) recent_sessions.first(limit) end |
#recent_tree(limit: 20) ⇒ Object
199 200 201 |
# File 'lib/kward/session_store.rb', line 199 def recent_tree(limit: 20) decorate_tree(recent_sessions.first(limit)) end |
#session_dir ⇒ Object
214 215 216 |
# File 'lib/kward/session_store.rb', line 214 def session_dir File.join(@config_dir, "sessions", self.class.safe_cwd(@cwd)) end |
#session_location(path) ⇒ Object
153 154 155 156 157 158 |
# File 'lib/kward/session_store.rb', line 153 def session_location(path) resolved_path = resolve_session_path(path) records = records_from_file(resolved_path) header = session_header(records, resolved_path) { path: resolved_path, cwd: header["cwd"].to_s.empty? ? @cwd : header["cwd"].to_s } end |