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.

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 input shorthand auto-creates a user message if provided.

Parameters:

  • attributes (Hash)

    keyword options; see attribute declarations above

Options Hash (**attributes):

  • :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



155
156
157
158
159
160
161
162
163
164
# File 'lib/prompt_builder/session.rb', line 155

def initialize(**attributes)
  (STRING_FIELDS + FLOAT_FIELDS + INTEGER_FIELDS + BOOLEAN_FIELDS + JSONIFY_FIELDS).each do |f|
    send(:"#{f}=", attributes[f])
  end
  @extra = PromptBuilder.jsonify(attributes[:extra]) if attributes[:extra]
  @items = []
  @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



83
84
85
86
87
# File 'lib/prompt_builder/session.rb', line 83

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

#extraHash? (readonly)

Returns provider-specific extra data for serializers. Recognized keys vary by target format. Unrecognized keys are silently ignored by each serializer.

Returns:

  • (Hash, nil)

    provider-specific extra data for serializers. Recognized keys vary by target format. Unrecognized keys are silently ignored by each serializer.



115
116
117
# File 'lib/prompt_builder/session.rb', line 115

def extra
  @extra
end

#frequency_penaltyFloat?

Returns the frequency penalty.

Returns:

  • (Float, nil)

    the frequency penalty



59
60
61
62
# File 'lib/prompt_builder/session.rb', line 59

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



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

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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:



107
108
109
# File 'lib/prompt_builder/session.rb', line 107

def items
  @items
end

#max_output_tokensInteger?

Returns the maximum output tokens.

Returns:

  • (Integer, nil)

    the maximum output tokens



70
71
72
73
# File 'lib/prompt_builder/session.rb', line 70

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



70
71
72
73
# File 'lib/prompt_builder/session.rb', line 70

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



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

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



83
84
85
86
87
# File 'lib/prompt_builder/session.rb', line 83

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



59
60
61
62
# File 'lib/prompt_builder/session.rb', line 59

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



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

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 (readonly)

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



110
111
112
# File 'lib/prompt_builder/session.rb', line 110

def response_boundary_index
  @response_boundary_index
end

#safety_identifierString?

Returns the safety identifier.

Returns:

  • (String, nil)

    the safety identifier



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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



83
84
85
86
87
# File 'lib/prompt_builder/session.rb', line 83

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



83
84
85
86
87
# File 'lib/prompt_builder/session.rb', line 83

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



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

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



59
60
61
62
# File 'lib/prompt_builder/session.rb', line 59

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



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

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



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

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



70
71
72
73
# File 'lib/prompt_builder/session.rb', line 70

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



59
60
61
62
# File 'lib/prompt_builder/session.rb', line 59

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



46
47
48
49
# File 'lib/prompt_builder/session.rb', line 46

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:



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/prompt_builder/session.rb', line 125

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"] if 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
end

Instance Method Details

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

Add a tool call output to the conversation.

Parameters:

  • call_id (String)

    the tool call identifier

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

    the tool call result

Returns:

  • (Items::FunctionOutput)

    the added function output item



215
216
217
# File 'lib/prompt_builder/session.rb', line 215

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

#add_item(item) ⇒ Items::Base

Add a raw item to the conversation.

Parameters:

Returns:

Raises:

  • (ArgumentError)


223
224
225
226
227
228
# File 'lib/prompt_builder/session.rb', line 223

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)


238
239
240
241
242
243
244
245
246
247
248
# File 'lib/prompt_builder/session.rb', line 238

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:



190
191
192
# File 'lib/prompt_builder/session.rb', line 190

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

#clone_configSession

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

Returns:

  • (Session)

    a new session with cloned configuration



299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/prompt_builder/session.rb', line 299

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:



206
207
208
# File 'lib/prompt_builder/session.rb', line 206

def developer(content)
  add_item(Items::Message.new(role: "developer", content: content))
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)


321
322
323
# File 'lib/prompt_builder/session.rb', line 321

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:



258
259
260
261
262
263
264
265
266
267
268
# File 'lib/prompt_builder/session.rb', line 258

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] = 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)


274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/prompt_builder/session.rb', line 274

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

#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



370
371
372
# File 'lib/prompt_builder/session.rb', line 370

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

#system(content) ⇒ Items::Message

Add a system message to the conversation.

Parameters:

Returns:



198
199
200
# File 'lib/prompt_builder/session.rb', line 198

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

#to_hHash

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

Returns:

  • (Hash)


328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/prompt_builder/session.rb', line 328

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["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 if @extra

  h
end

#tool_definitionsArray<Tools::Definition>

Return all tool definitions registered on this session.

Returns:



292
293
294
# File 'lib/prompt_builder/session.rb', line 292

def tool_definitions
  @tool_definitions.values
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([
  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:



182
183
184
# File 'lib/prompt_builder/session.rb', line 182

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