Skip to content
Kward Search API index

Class: Kward::TurnSummary

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

Overview

Collects reported usage for the main agent loop, independently of compaction and other auxiliary model calls. Missing usage is never treated as zero.

Constant Summary collapse

TOKEN_FIELDS =
%w[input_tokens output_tokens total_tokens cache_read_tokens cache_write_tokens reasoning_tokens].freeze

Instance Method Summary collapse

Constructor Details

#initialize ⇒ TurnSummary

Returns a new instance of TurnSummary.



9
10
11
12
13
14
15
16
17
# File 'lib/kward/turn_summary.rb', line 9

def initialize
  @model_requests = 0
  @tool_calls = 0
  @reported_requests = 0
  @usage = {}
  @field_requests = Hash.new(0)
  @estimated = false
  @retried = false
end

Instance Method Details

#finish(status:, elapsed_ms:) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/kward/turn_summary.rb', line 47

def finish(status:, elapsed_ms:)
  usage_status = if @reported_requests.zero?
    "unavailable"
  elsif @reported_requests == @model_requests && !@retried
    "complete"
  else
    "partial"
  end
  usage = @usage.merge("estimated" => @estimated)
  partial_fields = @usage.keys.reject { |field| @field_requests[field] == @model_requests && !@retried }
  usage["partial_fields"] = partial_fields unless partial_fields.empty?
  {
    "status" => status,
    "elapsedMs" => elapsed_ms,
    "modelRequests" => @model_requests,
    "toolCalls" => @tool_calls,
    "usageStatus" => usage_status,
    "usage" => @usage.empty? ? nil : usage
  }
end

#model_request ⇒ Object



19
20
21
# File 'lib/kward/turn_summary.rb', line 19

def model_request
  @model_requests += 1
end

#record(message) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/kward/turn_summary.rb', line 31

def record(message)
  usage = MessageAccess.value(message, :usage)
  return unless usage.is_a?(Hash)

  total = MessageAccess.value(usage, :total_tokens)
  @reported_requests += 1 if total.is_a?(Numeric) && total >= 0
  TOKEN_FIELDS.each do |field|
    value = MessageAccess.value(usage, field.to_sym)
    next unless value.is_a?(Numeric) && value >= 0

    @usage[field] = @usage.fetch(field, 0) + value
    @field_requests[field] += 1
  end
  @estimated ||= MessageAccess.value(usage, :estimated) == true
end

#retry ⇒ Object



27
28
29
# File 'lib/kward/turn_summary.rb', line 27

def retry
  @retried = true
end

#tool_call ⇒ Object



23
24
25
# File 'lib/kward/turn_summary.rb', line 23

def tool_call
  @tool_calls += 1
end