Class: Kward::RPC::SessionManager
- Inherits:
-
Object
- Object
- Kward::RPC::SessionManager
- Defined in:
- lib/kward/rpc/session_manager.rb
Defined Under Namespace
Classes: RpcSession, Turn
Constant Summary collapse
- RECENT_EVENT_LIMIT =
1_000- RPC_ATTACHMENT_MAX_BYTES =
10 * 1024 * 1024
- RPC_IMAGE_MIME_TYPES =
["image/png", "image/jpeg", "image/gif", "image/webp"].freeze
- STREAMING_BEHAVIORS =
["newTurn", "followUp", "steer"].freeze
- FOOTER_REFRESH_INTERVAL =
1.0- WORKER_STOP =
Object.new.freeze
Instance Method Summary collapse
- #answer_question(session_id:, question_request_id:, answers:) ⇒ Object
- #available_models ⇒ Object
- #cancel_turn(turn_id:) ⇒ Object
- #cleanup_unused_sessions ⇒ Object
- #clone_session(session_id:) ⇒ Object
- #close_session(session_id:) ⇒ Object
- #compact_session(session_id:, custom_instructions: "") ⇒ Object
- #create_session(workspace_root: Dir.pwd, name: nil, resume_last: false) ⇒ Object
- #current_model ⇒ Object
- #delete_session(session_id:) ⇒ Object
- #export_session(session_id:, path: nil, format: nil) ⇒ Object
- #fork_messages(session_id:) ⇒ Object
- #fork_session(session_id:, entry_id:) ⇒ Object
- #in_flight_steer_supported? ⇒ Boolean
-
#initialize(server:, client: Client.new, config_dir: ConfigFiles.config_dir, context_usage: ContextUsage.new, session_trash: SessionTrash.new) ⇒ SessionManager
constructor
A new instance of SessionManager.
- #list_sessions(workspace_root: Dir.pwd, limit: nil) ⇒ Object
- #memory_add(text:, scope: nil, tags: []) ⇒ Object
- #memory_add_core(text:, scope: nil, tags: []) ⇒ Object
- #memory_auto_summary_disable ⇒ Object
- #memory_auto_summary_enable ⇒ Object
- #memory_disable ⇒ Object
- #memory_enable ⇒ Object
- #memory_forget(id:) ⇒ Object
- #memory_inspect ⇒ Object
- #memory_list(include_inactive: false, workspace_root: Dir.pwd) ⇒ Object
- #memory_manager ⇒ Object
- #memory_promote(id:) ⇒ Object
- #memory_relax(id:, workspace_root: Dir.pwd) ⇒ Object
- #memory_status ⇒ Object
- #memory_summarize(session_id:) ⇒ Object
- #memory_why(session_id: nil) ⇒ Object
- #navigate_tree(session_id:, entry_id:, summarize: false, custom_instructions: nil) ⇒ Object
- #openrouter_catalog ⇒ Object
- #plugin_commands ⇒ Object
- #refresh_client_config ⇒ Object
- #reload_plugins ⇒ Object
- #rename_session(session_id:, name:) ⇒ Object
- #resume_session(path:, workspace_root: nil, include_transcript: false) ⇒ Object
- #run_command(session_id:, command:, arguments: "") ⇒ Object
- #run_plugin_command(session_id:, command:, arguments: "") ⇒ Object
- #runtime_state(session_id:) ⇒ Object
- #runtime_stats(session_id:) ⇒ Object
- #session_modified_at(session) ⇒ Object
- #session_payload(rpc_session) ⇒ Object
- #session_tree(session_id:) ⇒ Object
- #set_tree_label(session_id:, entry_id:, label: nil) ⇒ Object
- #start_turn(session_id:, input:, streaming_behavior: nil, attachments: []) ⇒ Object
- #transcript(session_id:) ⇒ Object
- #turn_events(turn_id:, after_sequence: 0) ⇒ Object
- #turn_status(turn_id:) ⇒ Object
- #validate_workspace_root(root) ⇒ Object
Constructor Details
#initialize(server:, client: Client.new, config_dir: ConfigFiles.config_dir, context_usage: ContextUsage.new, session_trash: SessionTrash.new) ⇒ SessionManager
Returns a new instance of SessionManager.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/kward/rpc/session_manager.rb', line 44 def initialize(server:, client: Client.new, config_dir: ConfigFiles.config_dir, context_usage: ContextUsage.new, session_trash: SessionTrash.new) @server = server @client = client @config_dir = config_dir @context_usage = context_usage @session_trash = session_trash @sessions = {} @turns = {} @mutex = Mutex.new end |
Instance Method Details
#answer_question(session_id:, question_request_id:, answers:) ⇒ Object
317 318 319 320 321 |
# File 'lib/kward/rpc/session_manager.rb', line 317 def answer_question(session_id:, question_request_id:, answers:) rpc_session = fetch_session(session_id) rpc_session.prompt.answer(question_request_id, answers) { ok: true } end |
#available_models ⇒ Object
422 423 424 425 426 427 428 |
# File 'lib/kward/rpc/session_manager.rb', line 422 def available_models models = @client.respond_to?(:available_models) ? Array(@client.available_models) : [] normalized = models.map { |model| normalize_model(model) } current = current_model normalized << current if normalized.none? { |model| model[:provider] == current[:provider] && model[:id] == current[:id] } normalized end |
#cancel_turn(turn_id:) ⇒ Object
293 294 295 296 297 298 299 300 301 302 |
# File 'lib/kward/rpc/session_manager.rb', line 293 def cancel_turn(turn_id:) turn = fetch_turn(turn_id) turn.cancel_requested = true turn.cancellation&.cancel! emit_turn_event(turn, "turnCancelRequested", {}) if turn.status == "queued" finish_turn(turn, "canceled") end turn_payload(turn) end |
#cleanup_unused_sessions ⇒ Object
243 244 245 246 247 248 249 250 251 |
# File 'lib/kward/rpc/session_manager.rb', line 243 def cleanup_unused_sessions rpc_sessions = @mutex.synchronize { @sessions.values.dup } rpc_sessions.reverse_each do |rpc_session| next unless session_idle?(rpc_session) close_rpc_session(rpc_session) end { closed: true } end |
#clone_session(session_id:) ⇒ Object
111 112 113 114 115 116 117 118 119 |
# File 'lib/kward/rpc/session_manager.rb', line 111 def clone_session(session_id:) source = fetch_session(session_id) session, conversation = source.store.create_independent_from_conversation(source.conversation, parent_session: source.session) rpc_session = build_rpc_session(source.store, session, conversation, source.workspace_root) remember_session(rpc_session) cleanup_other_unused_sessions(rpc_session) (rpc_session) session_payload(rpc_session) end |
#close_session(session_id:) ⇒ Object
237 238 239 240 241 |
# File 'lib/kward/rpc/session_manager.rb', line 237 def close_session(session_id:) rpc_session = fetch_session(session_id) close_rpc_session(rpc_session) { closed: true } end |
#compact_session(session_id:, custom_instructions: "") ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/kward/rpc/session_manager.rb', line 121 def compact_session(session_id:, custom_instructions: "") rpc_session = fetch_session(session_id) emit_session_event(rpc_session, "compactionStart", {}) result = Compactor.new(conversation: rpc_session.conversation, client: @client, settings: compaction_settings).compact(custom_instructions: custom_instructions) payload = { summary: result.summary, firstKeptEntryId: result.first_kept_entry_id, tokensBefore: result.tokens_before, details: result.details }.compact emit_session_event(rpc_session, "compactionEnd", { result: payload, aborted: false, willRetry: false, errorMessage: nil }) payload rescue StandardError => e emit_session_event(rpc_session, "compactionEnd", { result: nil, aborted: true, willRetry: false, errorMessage: e. }) if rpc_session raise e end |
#create_session(workspace_root: Dir.pwd, name: nil, resume_last: false) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/kward/rpc/session_manager.rb', line 55 def create_session(workspace_root: Dir.pwd, name: nil, resume_last: false) workspace_root = validate_workspace_root(workspace_root) store = SessionStore.new(config_dir: @config_dir, cwd: workspace_root) if resume_last && session_auto_resume_enabled? && name.to_s.strip.empty? path = store.remembered_last_session_path return resume_session(path: path, workspace_root: workspace_root, include_transcript: true) if path end conversation = new_conversation(workspace_root: workspace_root) session = store.create(model: conversation.model, reasoning_effort: conversation.reasoning_effort) session.rename(name) unless name.to_s.strip.empty? session.attach(conversation) rpc_session = build_rpc_session(store, session, conversation, workspace_root) remember_session(rpc_session) cleanup_other_unused_sessions(rpc_session) (rpc_session) session_payload(rpc_session) end |
#current_model ⇒ Object
435 436 437 438 439 440 |
# File 'lib/kward/rpc/session_manager.rb', line 435 def current_model provider = @client.respond_to?(:current_provider) ? @client.current_provider : nil model = @client.respond_to?(:current_model) ? @client.current_model : nil context_window = @client.respond_to?(:current_context_window) ? @client.current_context_window : nil normalize_model(provider: provider, id: model, model: model, contextWindow: context_window, current: true) end |
#delete_session(session_id:) ⇒ Object
229 230 231 232 233 234 235 |
# File 'lib/kward/rpc/session_manager.rb', line 229 def delete_session(session_id:) rpc_session = fetch_session(session_id) path = rpc_session.session.path close_rpc_session(rpc_session, delete_unused: false) deleted = @session_trash.delete(path) { deleted: deleted, path: path } end |
#export_session(session_id:, path: nil, format: nil) ⇒ Object
220 221 222 223 224 225 226 227 |
# File 'lib/kward/rpc/session_manager.rb', line 220 def export_session(session_id:, path: nil, format: nil) rpc_session = fetch_session(session_id) format = export_format(format) path = export_path(rpc_session, path, format) content = export_content(rpc_session.conversation, format) File.write(path, content) { path: path, format: format } end |
#fork_messages(session_id:) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/kward/rpc/session_manager.rb', line 138 def (session_id:) rpc_session = fetch_session(session_id) { messages: tree_entries(rpc_session).filter_map do |record| = record["message"] next unless .is_a?(Hash) && () == "user" { entryId: record["id"], text: () } end } end |
#fork_session(session_id:, entry_id:) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/kward/rpc/session_manager.rb', line 150 def fork_session(session_id:, entry_id:) source = fetch_session(session_id) entries = tree_entries(source) resolved_entry_id = resolve_tree_entry_id(entries, entry_id) selected_index = entries.index { |record| record["id"].to_s == resolved_entry_id.to_s } selected = selected_index && entries[selected_index] raise ArgumentError, "Unknown fork entryId: #{entry_id}" unless selected = selected["message"] raise ArgumentError, "Entry is not forkable: #{entry_id}" unless .is_a?(Hash) && () == "user" session, conversation = source.store.( entries[0...selected_index].filter_map { |record| record["message"] }, model: source.conversation.model, reasoning_effort: source.conversation.reasoning_effort, parent_session: source.session ) rpc_session = build_rpc_session(source.store, session, conversation, source.workspace_root) remember_session(rpc_session) cleanup_other_unused_sessions(rpc_session) { session: session_payload(rpc_session), text: (), cancelled: false } end |
#in_flight_steer_supported? ⇒ Boolean
442 443 444 |
# File 'lib/kward/rpc/session_manager.rb', line 442 def in_flight_steer_supported? supports_in_flight_steer? end |
#list_sessions(workspace_root: Dir.pwd, limit: nil) ⇒ Object
96 97 98 99 100 101 102 103 |
# File 'lib/kward/rpc/session_manager.rb', line 96 def list_sessions(workspace_root: Dir.pwd, limit: nil) root = validate_workspace_root(workspace_root) store = SessionStore.new(config_dir: @config_dir, cwd: root) requested_limit = limit.to_i if limit requested_limit = nil unless requested_limit&.positive? store.recent(limit: requested_limit) .map { |info| session_info_payload(info, workspace_root: root) } end |
#memory_add(text:, scope: nil, tags: []) ⇒ Object
363 364 365 |
# File 'lib/kward/rpc/session_manager.rb', line 363 def memory_add(text:, scope: nil, tags: []) { memory: memory_manager.add_soft(text, scope: scope || "global", tags: ) } end |
#memory_add_core(text:, scope: nil, tags: []) ⇒ Object
367 368 369 |
# File 'lib/kward/rpc/session_manager.rb', line 367 def memory_add_core(text:, scope: nil, tags: []) { memory: memory_manager.add_core(text, scope: scope || "global", tags: ) } end |
#memory_auto_summary_disable ⇒ Object
354 355 356 357 |
# File 'lib/kward/rpc/session_manager.rb', line 354 def memory_auto_summary_disable memory_manager.auto_summary_disable { autoSummary: false } end |
#memory_auto_summary_enable ⇒ Object
349 350 351 352 |
# File 'lib/kward/rpc/session_manager.rb', line 349 def memory_auto_summary_enable memory_manager.auto_summary_enable { autoSummary: true } end |
#memory_disable ⇒ Object
344 345 346 347 |
# File 'lib/kward/rpc/session_manager.rb', line 344 def memory_disable memory_manager.disable { enabled: false } end |
#memory_enable ⇒ Object
339 340 341 342 |
# File 'lib/kward/rpc/session_manager.rb', line 339 def memory_enable memory_manager.enable { enabled: true } end |
#memory_forget(id:) ⇒ Object
371 372 373 |
# File 'lib/kward/rpc/session_manager.rb', line 371 def memory_forget(id:) { forgotten: memory_manager.forget_memory(id) } end |
#memory_inspect ⇒ Object
383 384 385 |
# File 'lib/kward/rpc/session_manager.rb', line 383 def memory_inspect memory_manager.inspect_memory end |
#memory_list(include_inactive: false, workspace_root: Dir.pwd) ⇒ Object
359 360 361 |
# File 'lib/kward/rpc/session_manager.rb', line 359 def memory_list(include_inactive: false, workspace_root: Dir.pwd) memory_manager.hierarchy(include_inactive: include_inactive, workspace_root: workspace_root) end |
#memory_manager ⇒ Object
330 331 332 |
# File 'lib/kward/rpc/session_manager.rb', line 330 def memory_manager Memory::Manager.for_config_dir(@config_dir) end |
#memory_promote(id:) ⇒ Object
375 376 377 |
# File 'lib/kward/rpc/session_manager.rb', line 375 def memory_promote(id:) { memory: memory_manager.promote_memory(id) } end |
#memory_relax(id:, workspace_root: Dir.pwd) ⇒ Object
379 380 381 |
# File 'lib/kward/rpc/session_manager.rb', line 379 def memory_relax(id:, workspace_root: Dir.pwd) { memory: memory_manager.relax_core(id, workspace_root: workspace_root) } end |
#memory_status ⇒ Object
334 335 336 337 |
# File 'lib/kward/rpc/session_manager.rb', line 334 def memory_status manager = memory_manager { enabled: manager.enabled?, autoSummary: manager.auto_summary_enabled?, paths: manager.paths } end |
#memory_summarize(session_id:) ⇒ Object
395 396 397 398 399 400 |
# File 'lib/kward/rpc/session_manager.rb', line 395 def memory_summarize(session_id:) rpc_session = fetch_session(session_id) records = memory_manager.summarize_conversation(rpc_session.conversation, client: @client) persist_memory_state(rpc_session) { memories: records } end |
#memory_why(session_id: nil) ⇒ Object
387 388 389 390 391 392 393 |
# File 'lib/kward/rpc/session_manager.rb', line 387 def memory_why(session_id: nil) if session_id rpc_session = fetch_session(session_id) return rpc_session.conversation.last_memory_retrieval || memory_manager.explain_retrieval end memory_manager.explain_retrieval end |
#navigate_tree(session_id:, entry_id:, summarize: false, custom_instructions: nil) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/kward/rpc/session_manager.rb', line 189 def navigate_tree(session_id:, entry_id:, summarize: false, custom_instructions: nil) rpc_session = fetch_session(session_id) entries = tree_entries(rpc_session) resolved_entry_id = resolve_tree_entry_id(entries, entry_id) entry = rpc_session.store.session_entry(rpc_session.session.path, resolved_entry_id) raise ArgumentError, "Unknown tree entryId: #{entry_id}" unless entry raise ArgumentError, "Tree entry is not selectable: #{entry_id}" unless selectable_tree_entry?(entry) = entry["message"] user_entry = user_tree_entry?(entry) target_leaf = user_entry ? entry["parentId"] : entry["id"] editor_text = user_entry ? () : nil previous_leaf = rpc_session.session.leaf_id if summarize summary = summarize_branch(rpc_session, from_id: previous_leaf, to_id: target_leaf, custom_instructions: custom_instructions) target_leaf = rpc_session.session.append_branch_summary(target_leaf, from_id: previous_leaf, summary: summary, details: {}) else target_leaf ? rpc_session.session.branch(target_leaf) : rpc_session.session.reset_leaf end reload_rpc_session(rpc_session) { session: session_payload(rpc_session), editorText: editor_text, cancelled: false, aborted: false }.compact end |
#openrouter_catalog ⇒ Object
430 431 432 433 |
# File 'lib/kward/rpc/session_manager.rb', line 430 def openrouter_catalog models = @client.respond_to?(:openrouter_catalog) ? Array(@client.openrouter_catalog) : [] models.map { |model| normalize_model(model) } end |
#plugin_commands ⇒ Object
418 419 420 |
# File 'lib/kward/rpc/session_manager.rb', line 418 def plugin_commands plugin_registry.commands end |
#refresh_client_config ⇒ Object
489 490 491 492 493 |
# File 'lib/kward/rpc/session_manager.rb', line 489 def refresh_client_config @client.reload_config if @client.respond_to?(:reload_config) refresh_session_runtime_contexts refresh_session_tool_registries end |
#reload_plugins ⇒ Object
495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/kward/rpc/session_manager.rb', line 495 def reload_plugins registry = PluginRegistry.load(reserved_commands: reserved_plugin_command_names) sessions = @mutex.synchronize do @plugin_registry = registry @sessions.values end sessions.each do |rpc_session| rpc_session.conversation.plugin_registry = registry if rpc_session.conversation.respond_to?(:plugin_registry=) rpc_session.conversation. if rpc_session.conversation.respond_to?(:refresh_system_message!) (rpc_session) end end |
#rename_session(session_id:, name:) ⇒ Object
105 106 107 108 109 |
# File 'lib/kward/rpc/session_manager.rb', line 105 def rename_session(session_id:, name:) rpc_session = fetch_session(session_id) rpc_session.session.rename(name) session_payload(rpc_session) end |
#resume_session(path:, workspace_root: nil, include_transcript: false) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/kward/rpc/session_manager.rb', line 74 def resume_session(path:, workspace_root: nil, include_transcript: false) root = validate_workspace_root(workspace_root || Dir.pwd) store = SessionStore.new(config_dir: @config_dir, cwd: root) location = store.session_location(path) root = validate_workspace_root(location[:cwd]) store = SessionStore.new(config_dir: @config_dir, cwd: root) session, conversation = store.load( location[:path], workspace: configured_workspace(root), model: current_model_id, reasoning_effort: current_reasoning_effort ) rpc_session = build_rpc_session(store, session, conversation, root) remember_session(rpc_session) cleanup_other_unused_sessions(rpc_session) (rpc_session) payload = session_payload(rpc_session) payload[:messages] = TranscriptNormalizer.new(rpc_session.conversation.).normalize if include_transcript payload[:resumed] = true payload end |
#run_command(session_id:, command:, arguments: "") ⇒ Object
323 324 325 326 327 328 |
# File 'lib/kward/rpc/session_manager.rb', line 323 def run_command(session_id:, command:, arguments: "") name = command.to_s.delete_prefix("/") return { ok: false, error: "unsupported", reason: "clientClipboardOwnedByUi" } if name == "copy" run_plugin_command(session_id: session_id, command: name, arguments: arguments) end |
#run_plugin_command(session_id:, command:, arguments: "") ⇒ Object
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/kward/rpc/session_manager.rb', line 402 def run_plugin_command(session_id:, command:, arguments: "") rpc_session = fetch_session(session_id) command = plugin_registry.command_for(command.to_s.delete_prefix("/")) || raise(ArgumentError, "Unknown plugin command: #{command}") output = [] context = PluginRegistry::Context.new( conversation: rpc_session.conversation, args: arguments.to_s, session: rpc_session.session, workspace_root: rpc_session.workspace_root, say_callback: lambda { || output << .to_s } ) result = command.handler.call(arguments.to_s, context) output = rpc_session.plugin_output.shift(rpc_session.plugin_output.length) + output { command: command.name, output: output, result: result.nil? ? nil : result.to_s } end |
#runtime_state(session_id:) ⇒ Object
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
# File 'lib/kward/rpc/session_manager.rb', line 446 def runtime_state(session_id:) rpc_session = fetch_session(session_id) model = current_model compaction_settings = self.compaction_settings auto_compaction_reserve_tokens = compaction_reserve_tokens( context_window: model[:contextWindow], compaction_settings: compaction_settings ) session = session_payload(rpc_session) RuntimePayloads.state( session: session, model: model, streaming: streaming?(rpc_session), steering_supported: supports_in_flight_steer?, auto_compaction_reserve_tokens: auto_compaction_reserve_tokens, active_persona_label: active_persona_label(rpc_session), message_count: (rpc_session.conversation), pending_count: pending_turn_count(rpc_session.id), compaction_enabled: compaction_settings.enabled, workspace_guardrails_enabled: workspace_guardrails_enabled? ) end |
#runtime_stats(session_id:) ⇒ Object
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
# File 'lib/kward/rpc/session_manager.rb', line 469 def runtime_stats(session_id:) rpc_session = fetch_session(session_id) session = session_payload(rpc_session) counts = (rpc_session.conversation) model = current_model compaction_settings = self.compaction_settings auto_compaction_reserve_tokens = compaction_reserve_tokens( context_window: model[:contextWindow], compaction_settings: compaction_settings ) RuntimePayloads.stats( session: session, counts: counts, model: model, auto_compaction_reserve_tokens: auto_compaction_reserve_tokens, context_usage: context_usage(rpc_session, model), compaction_enabled: compaction_settings.enabled ) end |
#session_modified_at(session) ⇒ Object
516 517 518 |
# File 'lib/kward/rpc/session_manager.rb', line 516 def session_modified_at(session) File.exist?(session.path) ? File.mtime(session.path) : nil end |
#session_payload(rpc_session) ⇒ Object
508 509 510 511 512 513 514 |
# File 'lib/kward/rpc/session_manager.rb', line 508 def session_payload(rpc_session) RuntimePayloads.session( rpc_session, modified_at: session_modified_at(rpc_session.session), active_persona_label: active_persona_label(rpc_session) ) end |
#session_tree(session_id:) ⇒ Object
178 179 180 181 |
# File 'lib/kward/rpc/session_manager.rb', line 178 def session_tree(session_id:) rpc_session = fetch_session(session_id) { items: flatten_session_tree(rpc_session) } end |
#set_tree_label(session_id:, entry_id:, label: nil) ⇒ Object
183 184 185 186 187 |
# File 'lib/kward/rpc/session_manager.rb', line 183 def set_tree_label(session_id:, entry_id:, label: nil) rpc_session = fetch_session(session_id) rpc_session.session.append_label_change(entry_id, label) { ok: true } end |
#start_turn(session_id:, input:, streaming_behavior: nil, attachments: []) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/kward/rpc/session_manager.rb', line 258 def start_turn(session_id:, input:, streaming_behavior: nil, attachments: []) rpc_session = fetch_session(session_id) = () plugin_command, plugin_arguments = plugin_command_turn(input, ) display_input = input.to_s if input.is_a?(String) content = plugin_command ? input.to_s : user_turn_content((input), ) streaming_behavior = validate_streaming_behavior(default_streaming_behavior(rpc_session, streaming_behavior), rpc_session: rpc_session) if streaming_behavior == "steer" steered_turn = steer_running_turn(rpc_session, content) return steered_turn if steered_turn streaming_behavior = "followUp" end turn = Turn.new( id: SecureRandom.uuid, session_id: rpc_session.id, input: content, display_input: display_input, status: "queued", cancel_requested: false, cancellation: Cancellation.new, created_at: now, events: [], next_sequence: 1, streaming_behavior: streaming_behavior, plugin_command_name: plugin_command&.name, plugin_arguments: plugin_arguments ) @mutex.synchronize { @turns[turn.id] = turn } rpc_session.queue << turn.id ensure_worker(rpc_session) emit_turn_event(turn, "turnQueued", { status: "queued" }) turn_payload(turn) end |
#transcript(session_id:) ⇒ Object
253 254 255 256 |
# File 'lib/kward/rpc/session_manager.rb', line 253 def transcript(session_id:) rpc_session = fetch_session(session_id) { session: session_payload(rpc_session), messages: TranscriptNormalizer.new(rpc_session.conversation.).normalize } end |
#turn_events(turn_id:, after_sequence: 0) ⇒ Object
308 309 310 311 312 313 314 315 |
# File 'lib/kward/rpc/session_manager.rb', line 308 def turn_events(turn_id:, after_sequence: 0) turn = fetch_turn(turn_id) after_sequence = after_sequence.to_i { turn: turn_payload(turn), events: turn.events.select { |event| event[:sequence].to_i > after_sequence } } end |
#turn_status(turn_id:) ⇒ Object
304 305 306 |
# File 'lib/kward/rpc/session_manager.rb', line 304 def turn_status(turn_id:) turn_payload(fetch_turn(turn_id)) end |