Class: PromptBuilder::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/prompt_builder/session.rb

Overview

The main DSL entry point for building Open Responses API request payloads. Manages conversation items, tool registration, and serialization to multiple API formats.

Constant Summary collapse

INITIALIZE_OPTIONS =

All keyword options accepted by initialize.

This constant is public API — unlike the private field-group constants above, it must not be marked with private_constant. Integrating gems use it to validate or partition option hashes before constructing a Session, e.g. options.slice(*PromptBuilder::Session::INITIALIZE_OPTIONS).

Returns:

  • (Array<Symbol>)

    the supported keyword option names

(
  STRING_FIELDS + FLOAT_FIELDS + INTEGER_FIELDS + BOOLEAN_FIELDS + JSONIFY_FIELDS + %i[input extra system]
).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**attributes) ⇒ Session

Create a new Session with the given options. Accepts keyword arguments for all typed field groups (STRING_FIELDS, FLOAT_FIELDS, INTEGER_FIELDS, BOOLEAN_FIELDS, JSONIFY_FIELDS); all default to nil. The system and input shorthands auto-create a system and user message if provided. Unsupported keyword options raise an ArgumentError.

Parameters:

  • attributes (Hash)

    keyword options; see attribute declarations above

Options Hash (**attributes):

  • :system (String, nil)

    optional string shorthand; a system message is automatically added with this text

  • :input (String, nil)

    optional string shorthand; a user message is automatically added with this text

  • :extra (Hash, nil)

    provider-specific extra data for serializers; recognized keys vary by target format. Keys are stringified. Defaults to an empty Hash and can be replaced later with extra=.

Raises:

  • (ArgumentError)

    if an unsupported option is passed



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/prompt_builder/session.rb', line 215

def initialize(**attributes)
  unsupported = attributes.keys - INITIALIZE_OPTIONS
  unless unsupported.empty?
    raise ArgumentError, "unsupported option#{"s" if unsupported.size > 1}: #{unsupported.join(", ")}"
  end

  (STRING_FIELDS + FLOAT_FIELDS + INTEGER_FIELDS + BOOLEAN_FIELDS + JSONIFY_FIELDS).each do |f|
    send(:"#{f}=", attributes[f])
  end

  self.extra = attributes[:extra]

  @items = []
  system(attributes[:system]) if attributes[:system]

  @tool_definitions = {}
  @response_boundary_index = 0
  user(attributes[:input]) if attributes[:input]
end

Instance Attribute Details

#backgroundBoolean?

Returns whether this is a background request.

Returns:

  • (Boolean, nil)

    whether this is a background request



102
103
104
105
106
# File 'lib/prompt_builder/session.rb', line 102

BOOLEAN_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v) }
  alias_method :"#{f}?", f
end

#frequency_penaltyFloat?

Returns the frequency penalty.

Returns:

  • (Float, nil)

    the frequency penalty



78
79
80
81
# File 'lib/prompt_builder/session.rb', line 78

FLOAT_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_f) }
end

#includeArray?

Returns fields to include in the response.

Returns:

  • (Array, nil)

    fields to include in the response



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#instructionsString?

Returns the system instructions.

Returns:

  • (String, nil)

    the system instructions



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#itemsArray<Items::Base> (readonly)

Returns all conversation items.

Returns:



126
127
128
# File 'lib/prompt_builder/session.rb', line 126

def items
  @items
end

#max_output_tokensInteger?

Returns the maximum output tokens.

Returns:

  • (Integer, nil)

    the maximum output tokens



89
90
91
92
# File 'lib/prompt_builder/session.rb', line 89

INTEGER_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_i) }
end

#max_tool_callsInteger?

Returns the maximum number of tool calls.

Returns:

  • (Integer, nil)

    the maximum number of tool calls



89
90
91
92
# File 'lib/prompt_builder/session.rb', line 89

INTEGER_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_i) }
end

#metadataHash?

Returns arbitrary metadata.

Returns:

  • (Hash, nil)

    arbitrary metadata



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#modelString?

Returns the model identifier.

Returns:

  • (String, nil)

    the model identifier



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#parallel_tool_callsBoolean?

Returns whether parallel tool calls are enabled.

Returns:

  • (Boolean, nil)

    whether parallel tool calls are enabled



102
103
104
105
106
# File 'lib/prompt_builder/session.rb', line 102

BOOLEAN_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v) }
  alias_method :"#{f}?", f
end

#presence_penaltyFloat?

Returns the presence penalty.

Returns:

  • (Float, nil)

    the presence penalty



78
79
80
81
# File 'lib/prompt_builder/session.rb', line 78

FLOAT_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_f) }
end

#previous_response_idString?

Returns the previous response identifier for server-side state.

Returns:

  • (String, nil)

    the previous response identifier for server-side state



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#prompt_cache_keyString?

Returns the prompt cache key.

Returns:

  • (String, nil)

    the prompt cache key



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#prompt_cache_retentionString?

Returns the prompt cache retention policy.

Returns:

  • (String, nil)

    the prompt cache retention policy



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#reasoningHash?

Returns the reasoning configuration.

Returns:

  • (Hash, nil)

    the reasoning configuration



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#response_boundary_indexInteger

Returns the index in items marking the boundary after the last response.

Returns:

  • (Integer)

    the index in items marking the boundary after the last response



129
130
131
# File 'lib/prompt_builder/session.rb', line 129

def response_boundary_index
  @response_boundary_index
end

#safety_identifierString?

Returns the safety identifier.

Returns:

  • (String, nil)

    the safety identifier



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#service_tierString?

Returns the service tier.

Returns:

  • (String, nil)

    the service tier



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

#storeBoolean?

Returns whether to store the response.

Returns:

  • (Boolean, nil)

    whether to store the response



102
103
104
105
106
# File 'lib/prompt_builder/session.rb', line 102

BOOLEAN_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v) }
  alias_method :"#{f}?", f
end

#streamBoolean?

Returns whether to stream the response.

Returns:

  • (Boolean, nil)

    whether to stream the response



102
103
104
105
106
# File 'lib/prompt_builder/session.rb', line 102

BOOLEAN_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v) }
  alias_method :"#{f}?", f
end

#stream_optionsHash?

Returns stream configuration options.

Returns:

  • (Hash, nil)

    stream configuration options



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#temperatureFloat?

Returns the temperature.

Returns:

  • (Float, nil)

    the temperature



78
79
80
81
# File 'lib/prompt_builder/session.rb', line 78

FLOAT_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_f) }
end

#textHash?

Returns text output configuration.

Returns:

  • (Hash, nil)

    text output configuration



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#tool_choiceString, ...

Returns the tool choice configuration.

Returns:

  • (String, Hash, nil)

    the tool choice configuration



120
121
122
123
# File 'lib/prompt_builder/session.rb', line 120

JSONIFY_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : PromptBuilder.jsonify(v)) }
end

#top_logprobsInteger?

Returns the number of top log probabilities to return.

Returns:

  • (Integer, nil)

    the number of top log probabilities to return



89
90
91
92
# File 'lib/prompt_builder/session.rb', line 89

INTEGER_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_i) }
end

#top_pFloat?

Returns the top_p sampling parameter.

Returns:

  • (Float, nil)

    the top_p sampling parameter



78
79
80
81
# File 'lib/prompt_builder/session.rb', line 78

FLOAT_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_f) }
end

#truncationString?

Returns the truncation strategy.

Returns:

  • (String, nil)

    the truncation strategy



65
66
67
68
# File 'lib/prompt_builder/session.rb', line 65

STRING_FIELDS.each do |f|
  attr_reader f
  define_method(:"#{f}=") { |v| instance_variable_set(:"@#{f}", v.nil? ? nil : v.to_s) }
end

Class Method Details

.from_h(hash) ⇒ Session

Deserialize a Session from a Hash produced by to_h or parsed JSON. Reconstructs all config fields and conversation items. Tool definitions are restored without handlers; re-register handlers separately if you need to invoke the tools.

Parameters:

  • hash (Hash)

    a Hash with string keys

Returns:



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/prompt_builder/session.rb', line 178

def from_h(hash)
  attrs = (STRING_FIELDS + FLOAT_FIELDS + INTEGER_FIELDS + BOOLEAN_FIELDS + JSONIFY_FIELDS)
    .each_with_object({}) { |f, acc| acc[f] = hash[f.to_s] }
  attrs[:extra] = hash["extra"]
  session = new(**attrs)

  Array(hash["input"]).each do |item_hash|
    session.add_item(Items::Base.from_h(item_hash))
  end

  Array(hash["tools"]).each do |tool_hash|
    defn = Tools::Definition.from_h(tool_hash)
    extra = defn.extra.transform_keys(&:to_sym)
    session.register_tool(defn.name, description: defn.description, parameters: defn.parameters, strict: defn.strict, **extra)
  end

  session.response_boundary_index = hash["response_boundary_index"] if hash["response_boundary_index"]

  session
end

Instance Method Details

#add_function_call_output(call_id:, result:) ⇒ Items::FunctionCallOutput

Add a tool call output to the conversation.

Parameters:

  • call_id (String)

    the tool call identifier

  • result (String, Array<Content::Base, Hash>, nil)

    the tool call result

Returns:



289
290
291
# File 'lib/prompt_builder/session.rb', line 289

def add_function_call_output(call_id:, result:)
  add_item(Items::FunctionCallOutput.new(call_id: call_id, output: result))
end

#add_item(item) ⇒ Items::Base

Add a raw item to the conversation.

Parameters:

Returns:

Raises:

  • (ArgumentError)


297
298
299
300
301
302
# File 'lib/prompt_builder/session.rb', line 297

def add_item(item)
  raise ArgumentError, "item must be an instance of Items::Base" unless item.is_a?(Items::Base)

  @items << item
  item
end

#add_response(response) ⇒ void

This method returns an undefined value.

Add a response to the conversation. Output items are always appended to items so that the full history is available locally. When the session is in server state mode (previous_response_id already set), the id is also updated so to_h can use it as a serialization optimization.

Parameters:

  • response (Response)

    the API response

Raises:

  • (ArgumentError)


312
313
314
315
316
317
318
319
320
321
322
# File 'lib/prompt_builder/session.rb', line 312

def add_response(response)
  raise ArgumentError, "response must be an instance of Response" unless response.is_a?(Response)

  @items.concat(response.output)
  # Only refresh previous_response_id when the session is already in
  # server-state mode AND the response actually carries an id; otherwise
  # leave the existing pointer alone (responses from formats that don't
  # populate `id` would otherwise silently drop us back into local state).
  self.previous_response_id = response.id if !local_state? && response.id
  @response_boundary_index = @items.length
end

#assistant(content) ⇒ Items::Message

Add an assistant message to the conversation.

Parameters:

Returns:



260
261
262
# File 'lib/prompt_builder/session.rb', line 260

def assistant(content)
  add_item(Items::Message.new(role: "assistant", content: content))
end

#clearself

Clear all conversation items and the system instructions, returning the session to a fresh local-state start. Model configuration and registered tools are preserved.

Returns:

  • (self)


329
330
331
332
333
334
335
# File 'lib/prompt_builder/session.rb', line 329

def clear
  @items.clear
  self.instructions = nil
  self.previous_response_id = nil
  @response_boundary_index = 0
  self
end

#clear_toolsArray<Tools::Definition>

Remove all registered tools from the session.

Returns:



434
435
436
437
438
# File 'lib/prompt_builder/session.rb', line 434

def clear_tools
  removed = @tool_definitions.values
  @tool_definitions.clear
  removed
end

#clone_configSession

Create a new Session with the same configuration and tools but no items.

Returns:

  • (Session)

    a new session with cloned configuration



523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/prompt_builder/session.rb', line 523

def clone_config
  session = Session.new(**config_hash)
  @tool_definitions.each do |name, defn|
    extra = defn.extra.transform_keys(&:to_sym)
    session.register_tool(
      name,
      description: defn.description,
      parameters: defn.parameters,
      strict: defn.strict,
      **extra
    )
  end
  session
end

#developer(content) ⇒ Items::Message

Add a developer message to the conversation.

Parameters:

Returns:



280
281
282
# File 'lib/prompt_builder/session.rb', line 280

def developer(content)
  add_item(Items::Message.new(role: "developer", content: content))
end

#extraHash

Provider-specific extra data for serializers. Always returns a Hash, empty when nothing is set. Keys are always Strings.

The returned Hash is a copy, so mutating it does not change the session. To add or remove a key, modify a copy and assign it back:

session.extra = session.extra.merge("guardrail_config" => {"guardrailIdentifier" => "gr-1"})

Recognized keys vary by target format. Unrecognized keys are silently ignored by each serializer.

Returns:

  • (Hash)

    a copy of the provider-specific extra data



153
154
155
# File 'lib/prompt_builder/session.rb', line 153

def extra
  PromptBuilder.jsonify(@extra)
end

#extra=(value) ⇒ Hash

Replace the provider-specific extra data. Keys are deep-stringified with PromptBuilder.jsonify and the value is copied, so the assigned Hash is not shared with the session. Pass nil to clear.

Parameters:

  • value (Hash, nil)

    the extra data, or nil to clear it

Returns:

  • (Hash)

    the stored extra data

Raises:

  • (ArgumentError)

    if the value is neither a Hash nor nil



164
165
166
167
168
# File 'lib/prompt_builder/session.rb', line 164

def extra=(value)
  raise ArgumentError, "extra must be a Hash" unless value.nil? || value.is_a?(Hash)

  @extra = PromptBuilder.jsonify(value || {})
end

#json_output(schema, name: "response", strict: nil, description: nil) ⇒ Hash

Configure JSON Schema structured output. Writes the canonical text.format wire hash consumed by all serializers, preserving any other text keys (e.g. verbosity) already set.

Examples:

session.json_output({"type" => "object", "properties" => {...}}, strict: true)

Parameters:

  • schema (Hash)

    the JSON Schema for the response

  • name (String) (defaults to: "response")

    the schema name

  • strict (Boolean, nil) (defaults to: nil)

    whether strict schema adherence is requested; omitted from the format when nil

  • description (String, nil) (defaults to: nil)

    an optional schema description

Returns:

  • (Hash)

    the resulting text configuration



452
453
454
455
456
457
# File 'lib/prompt_builder/session.rb', line 452

def json_output(schema, name: "response", strict: nil, description: nil)
  format = {"type" => "json_schema", "name" => name.to_s, "schema" => schema}
  format["strict"] = strict unless strict.nil?
  format["description"] = description.to_s if description
  self.text = (text || {}).merge("format" => format)
end

#local_state?Boolean

Check if this session is in local state mode (no previous_response_id). This indicates that the full conversation history is stored in the session and will be sent with each request. Once a response with an id is added, the session switches to server state mode, where only new items after the last response are sent and the previous_response_id is used to reference the last response.

Returns:

  • (Boolean)


545
546
547
# File 'lib/prompt_builder/session.rb', line 545

def local_state?
  @previous_response_id.nil?
end

#register_tool(name, description: nil, parameters: nil, strict: false, **extra) ⇒ Tools::Definition

Register a tool on this session.

Parameters:

  • name (String)

    the tool name

  • description (String, nil) (defaults to: nil)

    the tool description

  • parameters (Hash, nil) (defaults to: nil)

    the JSON Schema for parameters

  • strict (Boolean) (defaults to: false)

    whether strict mode is enabled

  • extra (Hash)

    provider-specific extra keyword arguments (e.g. cache_control)

Returns:



345
346
347
348
349
350
351
352
353
354
355
# File 'lib/prompt_builder/session.rb', line 345

def register_tool(name, description: nil, parameters: nil, strict: false, **extra)
  definition = Tools::Definition.new(
    name: name,
    description: description,
    parameters: parameters,
    strict: strict,
    **extra
  )
  @tool_definitions[name.to_s] = definition
  definition
end

#register_tools(registry) ⇒ void

This method returns an undefined value.

Register all tools from a ToolRegistry.

Parameters:

  • registry (ToolRegistry)

    the registry to copy tools from

Raises:

  • (ArgumentError)


361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/prompt_builder/session.rb', line 361

def register_tools(registry)
  raise ArgumentError, "registry must be an instance of ToolRegistry" unless registry.is_a?(ToolRegistry)

  registry.definitions.each do |defn|
    extra = defn.extra.transform_keys(&:to_sym)
    register_tool(
      defn.name,
      description: defn.description,
      parameters: defn.parameters,
      strict: defn.strict,
      **extra
    )
  end
end

#remove_tool(name) ⇒ Tools::Definition?

Remove a single registered tool by name. Accepts a string or symbol and matches regardless of how the tool's key was stored.

Parameters:

  • name (String, Symbol)

    the tool name

Returns:



420
421
422
423
424
425
426
427
428
429
# File 'lib/prompt_builder/session.rb', line 420

def remove_tool(name)
  key = name.to_s
  removed = nil
  @tool_definitions.delete_if do |k, defn|
    match = k.to_s == key
    removed = defn if match
    match
  end
  removed
end

#request_payload(serializer_class) ⇒ Hash

Export this session to an alternate API format using the given serializer.

Parameters:

  • serializer_class (Class, Symbol)

    a serializer class (e.g. Serializers::ChatCompletion) or a symbol shorthand (+:open_responses+, :chat_completion, :messages, :gemini, :converse)

Returns:

  • (Hash)

    the serialized request payload

Raises:

  • (ArgumentError)

    if a symbol is given that does not map to a known serializer



595
596
597
# File 'lib/prompt_builder/session.rb', line 595

def request_payload(serializer_class)
  Serializers.resolve(serializer_class).request_payload(self)
end

#system(content) ⇒ Items::Message

Add a system message to the conversation.

Examples:

session.system("You are a helpful assistant.")
session.system(text: "You are a helpful assistant.") # type defaults to "input_text"
session.system(text: "You are a helpful assistant.", cache_point: true, cache_control: {type: "ephemeral"})

Parameters:

Returns:



272
273
274
# File 'lib/prompt_builder/session.rb', line 272

def system(content)
  add_item(Items::Message.new(role: "system", content: content))
end

#think(enabled = true, effort: nil, budget_tokens: nil) ⇒ Hash?

Configure reasoning/extended thinking portably across serializers. Stores a normalized reasoning configuration; each serializer maps it to its native parameter:

  • effort — Messages (+output_config.effort+), Chat Completions (+reasoning_effort+), Gemini (+thinkingConfig.thinkingLevel+), and Open Responses (+reasoning.effort+)
  • budget_tokens — Messages (+thinking.budget_tokens+) and Gemini (+thinkingConfig.thinkingBudget+); ignored by effort-based APIs
  • Converse supports neither and warns once at serialization time

Pass either effort or budget_tokens, not both — providers reject requests that set both controls. Direct session.reasoning = {...} assignment keeps working for provider-specific keys.

Examples:

session.think(effort: :medium)       # portable across serializers
session.think(budget_tokens: 8_000)  # explicit where supported
session.think(false)                 # disable

Parameters:

  • enabled (Boolean) (defaults to: true)

    pass false to clear the reasoning configuration

  • effort (String, Symbol, nil) (defaults to: nil)

    a portable effort level; one of minimal, low, medium, high, xhigh, max (unsupported levels are omitted by serializers whose target API does not accept them)

  • budget_tokens (Integer, nil) (defaults to: nil)

    an explicit thinking token budget

Returns:

  • (Hash, nil)

    the resulting reasoning configuration

Raises:

  • (ArgumentError)

    if neither or both of effort and budget_tokens are given when enabling, or the values are invalid



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/prompt_builder/session.rb', line 486

def think(enabled = true, effort: nil, budget_tokens: nil)
  unless enabled
    raise ArgumentError, "cannot combine think(false) with effort or budget_tokens" if effort || budget_tokens

    return self.reasoning = nil
  end

  if effort && budget_tokens
    raise ArgumentError, "pass either effort or budget_tokens, not both"
  elsif effort.nil? && budget_tokens.nil?
    raise ArgumentError, "think requires effort: or budget_tokens:"
  end

  if effort
    effort = effort.to_s
    unless THINK_EFFORT_LEVELS.include?(effort)
      raise ArgumentError, "effort must be one of: #{THINK_EFFORT_LEVELS.join(", ")}"
    end
    self.reasoning = {"effort" => effort}
  else
    budget_tokens = Integer(budget_tokens)
    raise ArgumentError, "budget_tokens must be positive" unless budget_tokens.positive?

    self.reasoning = {"budget_tokens" => budget_tokens}
  end
end

#to_hHash

Serialize to an Open Responses API request Hash with string keys.

Returns:

  • (Hash)


552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
# File 'lib/prompt_builder/session.rb', line 552

def to_h
  h = {}
  h["model"] = @model if @model
  h["instructions"] = @instructions if @instructions

  h["input"] = @items.map(&:to_h) unless @items.empty?
  h["previous_response_id"] = @previous_response_id if @previous_response_id
  h["response_boundary_index"] = @response_boundary_index if @response_boundary_index.positive?

  h["tools"] = tool_definitions.map(&:to_h) unless @tool_definitions.empty?

  (STRING_FIELDS - %i[model instructions previous_response_id]).each do |f|
    val = send(f)
    h[f.to_s] = val if val
  end
  FLOAT_FIELDS.each { |f|
    val = send(f)
    h[f.to_s] = val if val
  }
  INTEGER_FIELDS.each { |f|
    val = send(f)
    h[f.to_s] = val if val
  }
  BOOLEAN_FIELDS.each { |f|
    val = send(f)
    h[f.to_s] = val unless val.nil?
  }
  JSONIFY_FIELDS.each { |f|
    val = send(f)
    h[f.to_s] = val if val
  }
  h["extra"] = extra unless @extra.empty?

  h
end

#tool_definitionsArray<Tools::Definition>

Return all tool definitions registered on this session.

Returns:



516
517
518
# File 'lib/prompt_builder/session.rb', line 516

def tool_definitions
  @tool_definitions.values
end

#use_tools(*names, registry: nil) ⇒ Array<Tools::Definition>

Copy tool definitions from a ToolRegistry onto this session by name. With no names, all tools in the registry are copied (same as register_tools). Definitions are copied, so later registry changes do not affect the session and the tools survive +to_h+/+from_h+ round-trips.

Examples:

session.use_tools("weather", "traffic_conditions")
session.use_tools                                  # all registry tools
session.use_tools(:weather, registry: my_registry)

Parameters:

  • names (Array<String, Symbol>)

    the tool names to copy; empty for all

  • registry (ToolRegistry, nil) (defaults to: nil)

    the registry to copy from; defaults to the global PromptBuilder.tool_registry

Returns:

Raises:



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/prompt_builder/session.rb', line 390

def use_tools(*names, registry: nil)
  registry ||= PromptBuilder.tool_registry
  raise ArgumentError, "registry must be an instance of ToolRegistry" unless registry.is_a?(ToolRegistry)

  definitions = if names.empty?
    registry.definitions
  else
    names.map do |name|
      registry.definition_for(name.to_s) ||
        raise(ToolNotFoundError, "No tool registered with name: #{name.to_s.inspect}")
    end
  end

  definitions.map do |defn|
    extra = defn.extra.transform_keys(&:to_sym)
    register_tool(
      defn.name,
      description: defn.description,
      parameters: defn.parameters,
      strict: defn.strict,
      **extra
    )
  end
end

#user(content) ⇒ Items::Message

Add a user message to the conversation.

Examples:

session.user("Hello, how are you?")
session.user(Content::InputText.new(text: "Hello, how are you?"))
session.user(type: "input_text", text: "Hello, how are you?")
session.user(text: "Hello, how are you?") # type defaults to "input_text"
session.user([
  Content::InputText.new(text: "What is in this image?"),
  Content::InputImage.new(url: "http://example.com/image.png")
])
session.user([
  {type: "input_text", text: "What is in this image?"},
  {type: "input_image", url: "http://example.com/image.png"}
])

Parameters:

Returns:



252
253
254
# File 'lib/prompt_builder/session.rb', line 252

def user(content)
  add_item(Items::Message.new(role: "user", content: content))
end