Class: Rubino::LLM::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/llm/request.rb

Overview

The single value object the conversation loop hands the LLM boundary on each model call. Pure data — it carries everything a provider needs to issue one request, so the loop never threads positional args through the adapter. Mirrors the reference per-call request shape feeding the normalize_response seam: build a request, call the boundary, read back a normalized response.

Fields:

messages    : [{role:, content:, tool_calls?, tool_call_id?}] — api copy
tools       : [tool schema] — may be [] (e.g. max-iter toolless summary)
temperature : Float | nil — nil ⇒ provider default; forced to 1 w/ thinking
max_tokens  : Integer | nil — bumped on thinking + truncation continuation
thinking    : {enabled:, effort:|budget:} | nil — rendered to wire later
prefill     : String | nil — assistant-turn seed for prefill-to-continue
image_paths : [path] — native attachments, first call of a turn only
stream      : Bool — loop decides (interactive turn ⇒ false)

Round-trip hooks (#355 #351). ruby_llm runs the ENTIRE model↔tool round-trip loop inside one chat.ask (Chat#complete → #handle_tool_calls recurses), so the Loop never re-enters its own iteration check between the intermediate round-trips of a single streaming turn. These optional hooks let the Loop observe and bound that inner loop without the adapter knowing anything about budgets or persistence — it just calls them per round-trip:

on_intermediate_message : called once per INTERMEDIATE assistant message
  that carries tool_calls (NOT the final text turn) with a normalized
  hash {content:, tool_calls:, input_tokens:, output_tokens:}. The Loop
  persists it so the streaming path writes the same assistant(tool_use)
  rows the non-streaming path already writes (#351).
on_round_trip : 0-arity, called once per round-trip (each
  assistant-with-tool_calls). The Loop bumps its round-trip counter so
  the per-turn iteration/time budget can be consulted mid-loop (#355a).
budget_exhausted : 0-arity predicate ToolBridge consults BEFORE executing
  each tool. When it returns truthy the bridge returns RubyLLM::Tool::Halt
  instead of running the tool, which makes handle_tool_calls stop the auto
  loop after the current batch and hand control back to the Loop (#355a).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(messages:, tools: nil, temperature: nil, max_tokens: nil, thinking: nil, prefill: nil, image_paths: nil, stream: false, on_intermediate_message: nil, on_round_trip: nil, budget_exhausted: nil) ⇒ Request

Returns a new instance of Request.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rubino/llm/request.rb', line 45

def initialize(messages:, tools: nil, temperature: nil, max_tokens: nil,
               thinking: nil, prefill: nil, image_paths: nil, stream: false,
               on_intermediate_message: nil, on_round_trip: nil, budget_exhausted: nil)
  @messages    = messages || []
  @tools       = tools || []
  @temperature = temperature
  @max_tokens  = max_tokens
  @thinking    = thinking
  @prefill     = prefill
  @image_paths = image_paths || []
  @stream      = stream ? true : false
  @on_intermediate_message = on_intermediate_message
  @on_round_trip           = on_round_trip
  @budget_exhausted        = budget_exhausted
end

Instance Attribute Details

#budget_exhaustedObject (readonly)

Returns the value of attribute budget_exhausted.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def budget_exhausted
  @budget_exhausted
end

#image_pathsObject (readonly)

Returns the value of attribute image_paths.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def image_paths
  @image_paths
end

#max_tokensObject (readonly)

Returns the value of attribute max_tokens.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def max_tokens
  @max_tokens
end

#messagesObject (readonly)

Returns the value of attribute messages.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def messages
  @messages
end

#on_intermediate_messageObject (readonly)

Returns the value of attribute on_intermediate_message.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def on_intermediate_message
  @on_intermediate_message
end

#on_round_tripObject (readonly)

Returns the value of attribute on_round_trip.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def on_round_trip
  @on_round_trip
end

#prefillObject (readonly)

Returns the value of attribute prefill.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def prefill
  @prefill
end

#streamObject (readonly)

Returns the value of attribute stream.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def stream
  @stream
end

#temperatureObject (readonly)

Returns the value of attribute temperature.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def temperature
  @temperature
end

#thinkingObject (readonly)

Returns the value of attribute thinking.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def thinking
  @thinking
end

#toolsObject (readonly)

Returns the value of attribute tools.



41
42
43
# File 'lib/rubino/llm/request.rb', line 41

def tools
  @tools
end

Instance Method Details

#stream?Boolean

True when the loop asked the boundary to stream this call.

Returns:

  • (Boolean)


62
63
64
# File 'lib/rubino/llm/request.rb', line 62

def stream?
  @stream
end

#to_hObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rubino/llm/request.rb', line 66

def to_h
  {
    messages: @messages,
    tools: @tools,
    temperature: @temperature,
    max_tokens: @max_tokens,
    thinking: @thinking,
    prefill: @prefill,
    image_paths: @image_paths,
    stream: @stream,
    on_intermediate_message: @on_intermediate_message,
    on_round_trip: @on_round_trip,
    budget_exhausted: @budget_exhausted
  }
end