Class: RubyLLM::Team::Session
- Inherits:
-
Object
- Object
- RubyLLM::Team::Session
- Defined in:
- lib/ruby_llm/team.rb
Overview
Preserves coworker results, limits calls, and exposes a trace for one run.
Defined Under Namespace
Classes: Call
Instance Method Summary collapse
- #artifact(name) ⇒ Object
- #artifacts(name) ⇒ Object
- #ask(coworker, prompt, as: nil, from: nil) ⇒ Object
- #calls ⇒ Object
-
#calls_remaining ⇒ Object
Calls still allowed by the budget, or
nilwhen the session is unbounded. - #collaboration_tools ⇒ Object (also: #tools)
- #consult(action:, prompt:, coworker:, as: nil, from: nil) ⇒ Object
- #coworkers ⇒ Object
-
#initialize(agents, max_calls:, share_context:, context:) ⇒ Session
constructor
A new instance of Session.
- #parallel(tasks, concurrency: :threads, from: nil) ⇒ Object
-
#to_h(include_content: false) ⇒ Object
Machine-readable trace: structure and best-known usage by default; pass
include_content: trueto also export prompts and results. -
#to_json(*_args, include_content: false) ⇒ Object
Accepts JSON's positional generator state so JSON.generate(session) works.
- #to_markdown ⇒ Object
- #value(name) ⇒ Object
Constructor Details
#initialize(agents, max_calls:, share_context:, context:) ⇒ Session
Returns a new instance of Session.
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/ruby_llm/team.rb', line 72 def initialize(agents, max_calls:, share_context:, context:) validate_max_calls(max_calls) @agents = agents @max_calls = max_calls @share_context = share_context @context = context&.to_s&.dup&.freeze @calls = [] @accepted_calls = 0 @mutex = Mutex.new initialize_run_state initialize_agent_mutexes(agents) end |
Instance Method Details
#artifact(name) ⇒ Object
113 114 115 |
# File 'lib/ruby_llm/team.rb', line 113 def artifact(name) @mutex.synchronize { @artifacts.fetch(name.to_s, []).last } end |
#artifacts(name) ⇒ Object
117 118 119 |
# File 'lib/ruby_llm/team.rb', line 117 def artifacts(name) @mutex.synchronize { @artifacts.fetch(name.to_s, []).dup.freeze } end |
#ask(coworker, prompt, as: nil, from: nil) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/ruby_llm/team.rb', line 91 def ask(coworker, prompt, as: nil, from: nil) result = consult( action: 'delegate_work', prompt: prompt, coworker: coworker, as: as, from: from ) raise_on_error(result) end |
#calls ⇒ Object
105 |
# File 'lib/ruby_llm/team.rb', line 105 def calls = @mutex.synchronize { @calls.dup.freeze } |
#calls_remaining ⇒ Object
Calls still allowed by the budget, or nil when the session is unbounded.
Lets an application decide whether an optional pass still fits.
109 110 111 |
# File 'lib/ruby_llm/team.rb', line 109 def calls_remaining @mutex.synchronize { @max_calls && [@max_calls - @accepted_calls, 0].max } end |
#collaboration_tools ⇒ Object Also known as: tools
86 87 88 |
# File 'lib/ruby_llm/team.rb', line 86 def collaboration_tools [DelegateWork.new(self), AskQuestion.new(self)] end |
#consult(action:, prompt:, coworker:, as: nil, from: nil) ⇒ Object
156 157 158 159 |
# File 'lib/ruby_llm/team.rb', line 156 def consult(action:, prompt:, coworker:, as: nil, from: nil) role = coworker.to_s perform(reserve(action, role, prompt, as: as || role, from: from), coworker) end |
#coworkers ⇒ Object
154 |
# File 'lib/ruby_llm/team.rb', line 154 def coworkers = @agents.keys.join(', ') |
#parallel(tasks, concurrency: :threads, from: nil) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/ruby_llm/team.rb', line 98 def parallel(tasks, concurrency: :threads, from: nil) runner = parallel_runner(concurrency) reject_duplicate_roles(tasks) work = reserve_batch(tasks, from) send(runner, work).transform_values { |result| raise_on_error(result) } end |
#to_h(include_content: false) ⇒ Object
Machine-readable trace: structure and best-known usage by default;
pass include_content: true to also export prompts and results.
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ruby_llm/team.rb', line 138 def to_h(include_content: false) # One snapshot under one lock: calls and artifacts must not disagree. @mutex.synchronize do { calls: @calls.each_with_index.map { |call, index| call_to_h(call, index, include_content) }, artifacts: artifacts_to_h, usage: usage_totals(@calls) } end end |
#to_json(*_args, include_content: false) ⇒ Object
Accepts JSON's positional generator state so JSON.generate(session) works.
150 151 152 |
# File 'lib/ruby_llm/team.rb', line 150 def to_json(*_args, include_content: false) JSON.generate(to_h(include_content: include_content)) end |
#to_markdown ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/ruby_llm/team.rb', line 123 def to_markdown trace = calls.map.with_index(1) do |call, index| result = call.complete? ? format_result(call.result) : '_In progress_' inputs = call.inputs.empty? ? '_None_' : call.inputs.join(', ') # The whole prompt, handoffs included: "what was actually sent" is the point of # the trace, so the readable format must not be the one that hides it. "## #{index}. #{call.coworker} via #{call.action}\n\n" \ "### Inputs\n\n#{inputs}\n\n### Request\n\n#{call.prompt}\n\n" \ "### Result\n\n#{result}" end.join("\n\n") @context ? "## Shared team context\n\n#{@context}\n\n#{trace}" : trace end |
#value(name) ⇒ Object
121 |
# File 'lib/ruby_llm/team.rb', line 121 def value(name) = artifact(name)&.value |