mirror of
https://github.com/we-promise/sure
synced 2026-04-25 17:15:07 +02:00
* Wire conversation history through OpenAI responses API * Fix RuboCop hash brace spacing in assistant tests * Pipelock ignores * Batch fixes --------- Co-authored-by: sokiee <sokysrm@gmail.com>
54 lines
1.4 KiB
Ruby
54 lines
1.4 KiB
Ruby
class Assistant::HistoryTrimmer
|
|
def initialize(messages, max_tokens:)
|
|
@messages = messages || []
|
|
@max_tokens = max_tokens.to_i
|
|
end
|
|
|
|
def call
|
|
return [] if @messages.empty? || @max_tokens <= 0
|
|
|
|
kept = []
|
|
tokens = 0
|
|
|
|
group_tool_pairs(@messages).reverse_each do |group|
|
|
group_tokens = Assistant::TokenEstimator.estimate(group)
|
|
break if tokens + group_tokens > @max_tokens
|
|
|
|
kept.unshift(*group)
|
|
tokens += group_tokens
|
|
end
|
|
|
|
kept
|
|
end
|
|
|
|
private
|
|
|
|
# Bundles each assistant message that has `tool_calls` with the
|
|
# consecutive `role: "tool"` results that follow it, so the trimmer
|
|
# never splits a call/result pair when dropping from the oldest end.
|
|
def group_tool_pairs(messages)
|
|
groups = []
|
|
current_group = nil
|
|
|
|
messages.each do |msg|
|
|
if assistant_with_tool_calls?(msg)
|
|
groups << current_group if current_group
|
|
current_group = [ msg ]
|
|
elsif msg[:role].to_s == "tool" && current_group
|
|
current_group << msg
|
|
else
|
|
groups << current_group if current_group
|
|
current_group = nil
|
|
groups << [ msg ]
|
|
end
|
|
end
|
|
|
|
groups << current_group if current_group
|
|
groups
|
|
end
|
|
|
|
def assistant_with_tool_calls?(msg)
|
|
msg[:role].to_s == "assistant" && msg[:tool_calls].is_a?(Array) && msg[:tool_calls].any?
|
|
end
|
|
end
|