Class: Girb::ConversationHistory

Inherits:
Object
  • Object
show all
Defined in:
lib/girb/conversation_history.rb

Overview

AI会話履歴をchat API形式で管理するクラス

Defined Under Namespace

Classes: Message

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConversationHistory

Returns a new instance of ConversationHistory.



56
57
58
59
# File 'lib/girb/conversation_history.rb', line 56

def initialize
  @messages = []
  @pending_tool_calls = []
end

Instance Attribute Details

#messagesObject (readonly)

Returns the value of attribute messages.



54
55
56
# File 'lib/girb/conversation_history.rb', line 54

def messages
  @messages
end

Class Method Details

.add_assistant_message(content) ⇒ Object



21
22
23
# File 'lib/girb/conversation_history.rb', line 21

def add_assistant_message(content)
  instance.add_assistant_message(content)
end

.add_tool_call(tool_name, args, result, id: nil, metadata: nil) ⇒ Object



25
26
27
# File 'lib/girb/conversation_history.rb', line 25

def add_tool_call(tool_name, args, result, id: nil, metadata: nil)
  instance.add_tool_call(tool_name, args, result, id: id, metadata: )
end

.add_user_message(content) ⇒ Object



17
18
19
# File 'lib/girb/conversation_history.rb', line 17

def add_user_message(content)
  instance.add_user_message(content)
end

.clear!Object



37
38
39
# File 'lib/girb/conversation_history.rb', line 37

def clear!
  instance.clear!
end

.instanceObject



9
10
11
# File 'lib/girb/conversation_history.rb', line 9

def instance
  @instance ||= new
end

.messagesObject



33
34
35
# File 'lib/girb/conversation_history.rb', line 33

def messages
  instance.messages
end

.pending_tool_calls?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/girb/conversation_history.rb', line 49

def pending_tool_calls?
  instance.pending_tool_calls?
end

.reset!Object



13
14
15
# File 'lib/girb/conversation_history.rb', line 13

def reset!
  @instance = new
end

.summaryObject



41
42
43
# File 'lib/girb/conversation_history.rb', line 41

def summary
  instance.summary
end

.to_contentsObject



29
30
31
# File 'lib/girb/conversation_history.rb', line 29

def to_contents
  instance.to_contents
end

.to_normalizedObject



45
46
47
# File 'lib/girb/conversation_history.rb', line 45

def to_normalized
  instance.to_normalized
end

Instance Method Details

#add_assistant_message(content) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/girb/conversation_history.rb', line 65

def add_assistant_message(content)
  # ツール呼び出しがあった場合は、それも含める
  if @pending_tool_calls.any?
    @messages << Message.new(
      role: "model",
      content: content,
      tool_calls: @pending_tool_calls.dup
    )
    @pending_tool_calls.clear
  else
    @messages << Message.new(role: "model", content: content)
  end
end

#add_tool_call(tool_name, args, result, id: nil, metadata: nil) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/girb/conversation_history.rb', line 79

def add_tool_call(tool_name, args, result, id: nil, metadata: nil)
  @pending_tool_calls << {
    id: id || "call_#{SecureRandom.hex(12)}",
    name: tool_name,
    args: args,
    result: result,
    metadata: 
  }.compact
end

#add_user_message(content) ⇒ Object



61
62
63
# File 'lib/girb/conversation_history.rb', line 61

def add_user_message(content)
  @messages << Message.new(role: "user", content: content)
end

#clear!Object



93
94
95
96
# File 'lib/girb/conversation_history.rb', line 93

def clear!
  @messages.clear
  @pending_tool_calls.clear
end

#pending_tool_calls?Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/girb/conversation_history.rb', line 89

def pending_tool_calls?
  @pending_tool_calls.any?
end

#summaryObject

会話履歴のサマリー(デバッグ用)



137
138
139
140
141
142
143
144
# File 'lib/girb/conversation_history.rb', line 137

def summary
  @messages.map do |msg|
    role_label = msg.role == "user" ? "USER" : "AI"
    content_preview = msg.content.to_s[0, 50]
    content_preview += "..." if msg.content.to_s.length > 50
    "#{role_label}: #{content_preview}"
  end
end

#to_contentsObject

Gemini API の contents 形式に変換(後方互換性のため残す)



99
100
101
102
103
104
105
106
# File 'lib/girb/conversation_history.rb', line 99

def to_contents
  @messages.map do |msg|
    {
      role: msg.role,
      parts: [{ text: msg.content }]
    }
  end
end

#to_normalizedObject

Provider-agnostic normalized format



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/girb/conversation_history.rb', line 109

def to_normalized
  result = []

  @messages.each do |msg|
    role = msg.role == "model" ? :assistant : :user
    result << { role: role, content: msg.content }

    # Add tool calls and results if present
    msg.tool_calls&.each do |tc|
      tool_call = { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
      tool_call[:metadata] = tc[:metadata] if tc[:metadata]
      result << tool_call
      result << { role: :tool_result, id: tc[:id], name: tc[:name], result: tc[:result] }
    end
  end

  # Add pending tool calls
  @pending_tool_calls.each do |tc|
    tool_call = { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
    tool_call[:metadata] = tc[:metadata] if tc[:metadata]
    result << tool_call
    result << { role: :tool_result, id: tc[:id], name: tc[:name], result: tc[:result] }
  end

  result
end