Class: Nanobot::Session::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/nanobot/session/manager.rb

Overview

SessionManager manages conversation sessions with JSONL persistence

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workspace) ⇒ Manager

Returns a new instance of Manager.

Parameters:

  • workspace (String) —

    path to the project workspace directory



79
80
81
82
83
84
85
# File 'lib/nanobot/session/manager.rb', line 79

def initialize(workspace)
  @workspace = Pathname.new(workspace).expand_path
  @sessions_dir = Pathname.new(File.expand_path('~/.nanobot/sessions'))
  @sessions_dir.mkpath unless @sessions_dir.exist?
  FileUtils.chmod(0o700, @sessions_dir) if @sessions_dir.exist?
  @cache = {}
end

Instance Attribute Details

#sessions_dir ⇒ Object (readonly)

Returns the value of attribute sessions_dir.



76
77
78
# File 'lib/nanobot/session/manager.rb', line 76

def sessions_dir
  @sessions_dir
end

#workspace ⇒ Object (readonly)

Returns the value of attribute workspace.



76
77
78
# File 'lib/nanobot/session/manager.rb', line 76

def workspace
  @workspace
end

Instance Method Details

#cache_size ⇒ Object

Get number of cached sessions



172
173
174
# File 'lib/nanobot/session/manager.rb', line 172

def cache_size
  @cache.size
end

#clear_cache ⇒ Object

Clear all cached sessions



167
168
169
# File 'lib/nanobot/session/manager.rb', line 167

def clear_cache
  @cache.clear
end

#delete(key) ⇒ Boolean

Delete a session

Parameters:

  • key (String) —

    session key

Returns:

  • (Boolean) —

    true if deleted



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/nanobot/session/manager.rb', line 128

def delete(key)
  @cache.delete(key)
  path = @sessions_dir / "#{safe_filename(key)}.jsonl"

  if path.exist?
    path.delete
    true
  else
    false
  end
end

#get_or_create(key) ⇒ Session

Get or create a session by key

Parameters:

  • key (String) —

    session key (format: "channel:chat_id")

Returns:



90
91
92
93
94
95
96
# File 'lib/nanobot/session/manager.rb', line 90

def get_or_create(key)
  return @cache[key] if @cache[key]

  session = load(key) || Session.new(key)
  @cache[key] = session
  session
end

#list_sessions ⇒ Array<Hash>

List all sessions

Returns:

  • (Array<Hash>) —

    array of session info



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/nanobot/session/manager.rb', line 142

def list_sessions
  sessions = []

  @sessions_dir.glob('*.jsonl').each do |path|
    first_line = path.readlines.first
    next unless first_line

    data = JSON.parse(first_line, symbolize_names: true)
    next unless data[:_type] == 'metadata'

    # Prefer the key stored in metadata; fall back to decoding the filename
    key = data[:key] || URI.decode_www_form_component(path.basename('.jsonl').to_s)

    sessions << {
      key: key,
      created_at: data[:created_at],
      updated_at: data[:updated_at],
      path: path.to_s
    }
  end

  sessions.sort_by { |s| s[:updated_at] }.reverse
end

#save(session) ⇒ Object

Save a session to disk

Parameters:

  • session (Session) —

    session to save



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/nanobot/session/manager.rb', line 100

def save(session)
  path = @sessions_dir / "#{safe_filename(session.key)}.jsonl"

  File.open(path, 'w') do |f|
    # Write metadata line
     = {
      _type: 'metadata',
      key: session.key,
      created_at: session.created_at.iso8601,
      updated_at: session.updated_at.iso8601,
      metadata: session.
    }
    f.puts(JSON.generate())

    # Write message lines
    session.messages.each do |msg|
      f.puts(JSON.generate(msg))
    end
  end

  FileUtils.chmod(0o600, path)

  @cache[session.key] = session
end