Class: Kward::SessionDiff
- Inherits:
-
Object
- Object
- Kward::SessionDiff
- Defined in:
- lib/kward/session_diff.rb
Overview
Counts unified-diff additions and deletions for summaries.
Instance Attribute Summary collapse
-
#additions ⇒ Object
readonly
Returns the value of attribute additions.
-
#deletions ⇒ Object
readonly
Returns the value of attribute deletions.
Class Method Summary collapse
- .common_line_count(left, right) ⇒ Object
- .count(diff) ⇒ Object
- .from_records(records) ⇒ Object
- .from_session_file(path) ⇒ Object
- .parse_record(line) ⇒ Object
- .truncated_diff?(diff) ⇒ Boolean
- .truncated_diff_stats(diff) ⇒ Object
Instance Method Summary collapse
- #add_diff(diff) ⇒ Object
- #add_tool_result(content) ⇒ Object
- #empty? ⇒ Boolean
-
#initialize(additions: 0, deletions: 0) ⇒ SessionDiff
constructor
A new instance of SessionDiff.
Constructor Details
#initialize(additions: 0, deletions: 0) ⇒ SessionDiff
Returns a new instance of SessionDiff.
9 10 11 12 |
# File 'lib/kward/session_diff.rb', line 9 def initialize(additions: 0, deletions: 0) @additions = additions.to_i @deletions = deletions.to_i end |
Instance Attribute Details
#additions ⇒ Object (readonly)
Returns the value of attribute additions.
7 8 9 |
# File 'lib/kward/session_diff.rb', line 7 def additions @additions end |
#deletions ⇒ Object (readonly)
Returns the value of attribute deletions.
7 8 9 |
# File 'lib/kward/session_diff.rb', line 7 def deletions @deletions end |
Class Method Details
.common_line_count(left, right) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/kward/session_diff.rb', line 100 def self.common_line_count(left, right) previous = Array.new(right.length + 1, 0) left.each do |left_line| current = Array.new(right.length + 1, 0) right.each_with_index do |right_line, index| current[index + 1] = if left_line == right_line previous[index] + 1 else [current[index], previous[index + 1]].max end end previous = current end previous.last end |
.count(diff) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/kward/session_diff.rb', line 35 def self.count(diff) if (stats = truncated_diff_stats(diff)) return stats elsif truncated_diff?(diff) return { additions: 0, deletions: 0 } end additions = 0 deletions = 0 removed = [] added = [] flush = lambda do common = common_line_count(removed, added) additions += added.length - common deletions += removed.length - common removed.clear added.clear end diff.to_s.each_line do |line| if line.start_with?("+") && !line.start_with?("+++") added << line[1..] elsif line.start_with?("-") && !line.start_with?("---") removed << line[1..] else flush.call end end flush.call { additions: additions, deletions: deletions } end |
.from_records(records) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/kward/session_diff.rb', line 21 def self.from_records(records) execution_records = records.select { |record| record["type"] == "tool_execution_end" } source_records = execution_records.empty? ? records : execution_records source_records.each_with_object(new) do |record, diff| if record["type"] == "tool_execution_end" next if record["isError"] || record.dig("result", "isError") diff.add_diff(record.dig("result", "diff")) elsif record["type"] == "message" && (record.dig("message", "role") == "tool" || record.dig("message", :role) == "tool") diff.add_tool_result(record.dig("message", "content") || record.dig("message", :content)) end end end |
.from_session_file(path) ⇒ Object
14 15 16 17 18 19 |
# File 'lib/kward/session_diff.rb', line 14 def self.from_session_file(path) records = File.readlines(path, chomp: true).filter_map { |line| parse_record(line) } from_records(records) rescue Errno::ENOENT, Errno::EACCES new end |
.parse_record(line) ⇒ Object
116 117 118 119 120 |
# File 'lib/kward/session_diff.rb', line 116 def self.parse_record(line) JSON.parse(line) rescue JSON::ParserError nil end |
.truncated_diff?(diff) ⇒ Boolean
96 97 98 |
# File 'lib/kward/session_diff.rb', line 96 def self.truncated_diff?(diff) diff.to_s.match?(/^\.\.\. diff truncated to \d+ bytes;/) end |
.truncated_diff_stats(diff) ⇒ Object
89 90 91 92 93 94 |
# File 'lib/kward/session_diff.rb', line 89 def self.truncated_diff_stats(diff) match = diff.to_s.match(/^\.\.\. diff truncated to \d+ bytes; full diff stats: \+(\d+)\|-(\d+)\./) return nil unless match { additions: match[1].to_i, deletions: match[2].to_i } end |
Instance Method Details
#add_diff(diff) ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/kward/session_diff.rb', line 78 def add_diff(diff) counts = self.class.count(diff) return false if counts[:additions].zero? && counts[:deletions].zero? @additions += counts[:additions] @deletions += counts[:deletions] true end |
#add_tool_result(content) ⇒ Object
71 72 73 74 75 76 |
# File 'lib/kward/session_diff.rb', line 71 def add_tool_result(content) text = content.to_s return false if text.start_with?("Error:", "Declined:") add_diff(extract_unified_diff(text)) end |
#empty? ⇒ Boolean
67 68 69 |
# File 'lib/kward/session_diff.rb', line 67 def empty? @additions.zero? && @deletions.zero? end |