Class: Lyman::Conversation
- Inherits:
-
Object
- Object
- Lyman::Conversation
- Defined in:
- lib/lyman/conversation.rb
Overview
The item that flows through the spine and the circuit: the whole conversation so far, plus the control data workers consult to decide whether to act (never which of several things to do).
An immutable value. Shifty 0.6 deep-freezes every value at a worker boundary (the :frozen handoff policy), so change is expressed as new values: each with_* method returns a new Conversation and leaves the receiver untouched. Data#with structurally shares the unchanged members — safe precisely because handed-off values are frozen.
Messages use string keys throughout, for clean round-tripping with OpenAI-compatible wire formats.
Instance Method Summary collapse
- #finish ⇒ Object
- #finished? ⇒ Boolean
-
#initialize(system_prompt: nil, messages: nil, rounds: 0, max_rounds: 10, finished: false) ⇒ Conversation
constructor
A new instance of Conversation.
- #last_assistant_content ⇒ Object
- #pending_tool_calls ⇒ Object
- #runaway? ⇒ Boolean
-
#with_assistant_message(message) ⇒ Object
A round is one model reply, so the counter lives here rather than in the transport worker — swap the transport and the runaway guard still can't be forgotten.
- #with_tool_result(tool_call_id, content) ⇒ Object
- #with_user_message(text) ⇒ Object
Constructor Details
#initialize(system_prompt: nil, messages: nil, rounds: 0, max_rounds: 10, finished: false) ⇒ Conversation
Returns a new instance of Conversation.
15 16 17 18 |
# File 'lib/lyman/conversation.rb', line 15 def initialize(system_prompt: nil, messages: nil, rounds: 0, max_rounds: 10, finished: false) ||= system_prompt ? [{"role" => "system", "content" => system_prompt}] : [] super(messages: , rounds: rounds, max_rounds: max_rounds, finished: finished) end |
Instance Method Details
#finish ⇒ Object
54 55 56 |
# File 'lib/lyman/conversation.rb', line 54 def finish with(finished: true) end |
#finished? ⇒ Boolean
58 59 60 |
# File 'lib/lyman/conversation.rb', line 58 def finished? finished end |
#last_assistant_content ⇒ Object
49 50 51 52 |
# File 'lib/lyman/conversation.rb', line 49 def last_assistant_content = .rfind { |m| m["role"] == "assistant" } && ["content"] end |
#pending_tool_calls ⇒ Object
43 44 45 46 47 |
# File 'lib/lyman/conversation.rb', line 43 def pending_tool_calls last = .last return [] unless last && last["role"] == "assistant" last["tool_calls"] || [] end |
#runaway? ⇒ Boolean
62 63 64 |
# File 'lib/lyman/conversation.rb', line 62 def runaway? rounds >= max_rounds end |
#with_assistant_message(message) ⇒ Object
A round is one model reply, so the counter lives here rather than in the transport worker — swap the transport and the runaway guard still can't be forgotten.
31 32 33 |
# File 'lib/lyman/conversation.rb', line 31 def () with(messages: + [], rounds: rounds + 1) end |
#with_tool_result(tool_call_id, content) ⇒ Object
35 36 37 38 39 40 41 |
# File 'lib/lyman/conversation.rb', line 35 def with_tool_result(tool_call_id, content) with(messages: + [{ "role" => "tool", "tool_call_id" => tool_call_id, "content" => content }]) end |
#with_user_message(text) ⇒ Object
20 21 22 23 24 25 26 |
# File 'lib/lyman/conversation.rb', line 20 def (text) with( messages: + [{"role" => "user", "content" => text}], rounds: 0, finished: false ) end |