Skip to content
Kward Search API index

Class: Kward::SessionTreeNodes

Inherits:
Object
  • Object
show all
Defined in:
lib/kward/session_tree_nodes.rb

Overview

Shared traversal helpers for persisted session trees.

Frontends own their final labels or payloads. This class owns only the frontend-neutral mechanics needed by both terminal and RPC tree views: active-path lookup, hidden tool-call-only assistant nodes, visible-node flattening, and assistant tool-call lookup by id.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(roots:, current_leaf: nil) ⇒ SessionTreeNodes

Returns a new instance of SessionTreeNodes.



14
15
16
17
# File 'lib/kward/session_tree_nodes.rb', line 14

def initialize(roots:, current_leaf: nil)
  @roots = roots
  @current_leaf = current_leaf
end

Class Method Details

.truncate_text(text) ⇒ Object



71
72
73
74
# File 'lib/kward/session_tree_nodes.rb', line 71

def self.truncate_text(text)
  normalized = text.to_s.gsub(/\s+/, " ").strip
  normalized.length > 120 ? "#{normalized.slice(0, 117)}..." : normalized
end

Instance Method Details

#active_pathObject



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/kward/session_tree_nodes.rb', line 19

def active_path
  by_id = entries_by_id
  ids = []
  entry = by_id[@current_leaf.to_s]
  seen = {}
  while entry && !seen[entry["id"].to_s]
    seen[entry["id"].to_s] = true
    ids << entry["id"].to_s
    entry = by_id[entry["parentId"].to_s]
  end
  ids
end

#contains_active_path?(node, active_path) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/kward/session_tree_nodes.rb', line 36

def contains_active_path?(node, active_path)
  stack = [node]
  seen = {}
  until stack.empty?
    current = stack.pop
    next if seen[current.object_id]

    seen[current.object_id] = true
    entry_id = (current[:source]["entry"] || {})["id"].to_s
    return true if active_path.include?(entry_id)

    stack.concat(current[:children])
  end
  false
end

#tool_callsObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/kward/session_tree_nodes.rb', line 52

def tool_calls
  @roots.each_with_object({}) do |root, calls|
    stack = [root]
    seen = {}
    until stack.empty?
      node = stack.pop
      next if seen[node.object_id]

      seen[node.object_id] = true
      entry = node["entry"] || {}
      message = entry["message"]
      if entry["type"] == "message" && message.is_a?(Hash) && MessageAccess.role(message) == "assistant"
        MessageAccess.tool_calls(message).each { |tool_call| calls[ToolCall.id(tool_call).to_s] = tool_call }
      end
      stack.concat(Array(node["children"]))
    end
  end
end

#visible_rootsObject



32
33
34
# File 'lib/kward/session_tree_nodes.rb', line 32

def visible_roots
  @roots.flat_map { |root| visible_nodes(root) }
end