Class: RubynCode::Agent::Conversation
- Inherits:
-
Object
- Object
- RubynCode::Agent::Conversation
- Defined in:
- lib/rubyn_code/agent/conversation.rb
Instance Attribute Summary collapse
-
#messages ⇒ Object
readonly
Returns the value of attribute messages.
Instance Method Summary collapse
-
#add_assistant_message(content, tool_calls: []) ⇒ Hash
Append an assistant turn to the conversation.
-
#add_tool_result(tool_use_id, _tool_name, output, is_error: false) ⇒ Hash
Append a tool result turn to the conversation.
-
#add_user_message(content) ⇒ Hash
Append a user turn to the conversation.
-
#clear! ⇒ void
Reset the conversation to an empty state.
-
#initialize ⇒ Conversation
constructor
A new instance of Conversation.
-
#last_assistant_text ⇒ String?
Extract the text from the most recent assistant message.
- #length ⇒ Integer
-
#replace!(new_messages) ⇒ Object
Replace messages with a new array (used after compaction).
-
#to_api_format ⇒ Array<Hash>
Return the messages array formatted for the Claude API.
-
#undo_last! ⇒ void
Remove the last user + assistant exchange.
Constructor Details
#initialize ⇒ Conversation
Returns a new instance of Conversation.
8 9 10 |
# File 'lib/rubyn_code/agent/conversation.rb', line 8 def initialize @messages = [] end |
Instance Attribute Details
#messages ⇒ Object (readonly)
Returns the value of attribute messages.
6 7 8 |
# File 'lib/rubyn_code/agent/conversation.rb', line 6 def @messages end |
Instance Method Details
#add_assistant_message(content, tool_calls: []) ⇒ Hash
Append an assistant turn to the conversation.
27 28 29 30 31 32 |
# File 'lib/rubyn_code/agent/conversation.rb', line 27 def (content, tool_calls: []) blocks = normalize_content(content, tool_calls) = { role: 'assistant', content: blocks } @messages << end |
#add_tool_result(tool_use_id, _tool_name, output, is_error: false) ⇒ Hash
Append a tool result turn to the conversation.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/rubyn_code/agent/conversation.rb', line 41 def add_tool_result(tool_use_id, _tool_name, output, is_error: false) result_block = { type: 'tool_result', tool_use_id: tool_use_id, content: output.to_s } result_block[:is_error] = true if is_error # The Claude API expects tool results as a user message whose content # is an array of tool_result blocks. When the previous message is # already a user/tool_result message we append to it so that multiple # tool results for the same assistant turn are batched together. if @messages.last && @messages.last[:role] == 'user' && (@messages.last) @messages.last[:content] << result_block else @messages << { role: 'user', content: [result_block] } end result_block end |
#add_user_message(content) ⇒ Hash
Append a user turn to the conversation.
16 17 18 19 20 |
# File 'lib/rubyn_code/agent/conversation.rb', line 16 def (content) = { role: 'user', content: content } @messages << end |
#clear! ⇒ void
This method returns an undefined value.
Reset the conversation to an empty state.
80 81 82 |
# File 'lib/rubyn_code/agent/conversation.rb', line 80 def clear! @messages.clear end |
#last_assistant_text ⇒ String?
Extract the text from the most recent assistant message.
65 66 67 68 69 70 |
# File 'lib/rubyn_code/agent/conversation.rb', line 65 def last_assistant_text assistant_msg = @messages.reverse_each.find { |m| m[:role] == 'assistant' } return nil unless assistant_msg extract_text(assistant_msg[:content]) end |
#length ⇒ Integer
73 74 75 |
# File 'lib/rubyn_code/agent/conversation.rb', line 73 def length @messages.length end |
#replace!(new_messages) ⇒ Object
Replace messages with a new array (used after compaction).
121 122 123 |
# File 'lib/rubyn_code/agent/conversation.rb', line 121 def replace!() @messages.replace() end |
#to_api_format ⇒ Array<Hash>
Return the messages array formatted for the Claude API. Ensures proper role alternation and content structure.
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rubyn_code/agent/conversation.rb', line 88 def to_api_format formatted = @messages.map do |msg| { role: msg[:role], content: format_content(msg[:content]) } end repair_orphaned_tool_uses(formatted) end |
#undo_last! ⇒ void
This method returns an undefined value.
Remove the last user + assistant exchange. Useful for undo. If the last two messages are assistant then user (most recent first), removes both. Otherwise removes only the last message.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/rubyn_code/agent/conversation.rb', line 104 def undo_last! return if @messages.empty? # Walk backwards and remove the most recent user+assistant pair. # The typical pattern is: [..., user, assistant] or # [..., assistant, user(tool_results)]. removed = 0 while @messages.any? && removed < 2 last = @messages.last break if removed == 1 && last[:role] != 'assistant' && last[:role] != 'user' @messages.pop removed += 1 end end |