Class: ChatRequestDetails

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

Overview

GlimRequest delegates to this

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(req) ⇒ ChatRequestDetails

only for requests that involve a message array, like OpenAI



14
15
16
# File 'lib/chat_request_details.rb', line 14

def initialize(req)
  @req = req
end

Instance Attribute Details

#functions_objectObject (readonly)

Returns the value of attribute functions_object.



125
126
127
# File 'lib/chat_request_details.rb', line 125

def functions_object
  @functions_object
end

#message_historyObject (readonly)

Returns the value of attribute message_history.



54
55
56
# File 'lib/chat_request_details.rb', line 54

def message_history
  @message_history
end

#output_schemaObject (readonly)

Returns the value of attribute output_schema.



100
101
102
# File 'lib/chat_request_details.rb', line 100

def output_schema
  @output_schema
end

#reqObject

Returns the value of attribute req.



17
18
19
# File 'lib/chat_request_details.rb', line 17

def req
  @req
end

Instance Method Details

#expected_output_is_list?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/chat_request_details.rb', line 102

def expected_output_is_list?
  @output_schema && @output_schema[:type] == 'object' && @output_schema[:properties] && @output_schema[:properties][:list]
end

#force_function_call(function_name) ⇒ Object



121
122
123
# File 'lib/chat_request_details.rb', line 121

def force_function_call(function_name)
  req.request_hash[:function_call] = { "name": function_name }
end

#llm_class_changedObject



23
24
25
# File 'lib/chat_request_details.rb', line 23

def llm_class_changed
  update_request_hash
end

#replace_initial_system_message(system_message) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/chat_request_details.rb', line 56

def replace_initial_system_message(system_message)
  @message_history ||= []
  @message_history[0] ||=  {
    "role": "system",
    "content": system_message
  }
end

#response_classObject



19
20
21
# File 'lib/chat_request_details.rb', line 19

def response_class
  ChatResponse
end

#set_functions_object(functions_object) ⇒ Object

function that in this request we offer to the LLM API to call



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/chat_request_details.rb', line 108

def set_functions_object(functions_object)
  @functions_object = functions_object
  # update_request_hash
  req.request_hash[:functions] = functions_object.class.ai_method_signatures_clean
  # [{
  #   name: extract_data_function_name,
  #   description: "Extracts data from the user's message",
  #   parameters: @output_schema
  # }]
  # # Specifying a particular function via {"name":\ "my_function"} forces the model to call that function.
  # request_data[:function_call] = { "name": extract_data_function_name }
end

#set_message_history(messages) ⇒ Object



50
51
52
53
# File 'lib/chat_request_details.rb', line 50

def set_message_history(messages)
  @message_history = messages
  update_request_hash
end

#set_output_schema(output_schema, *flags) ⇒ Object

for convenience, if you want a list, you can specify the schema for the items



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/chat_request_details.rb', line 66

def set_output_schema(output_schema, *flags)
  output_schema.must_be_a Hash
  meta_schema = JSON::Validator.validator_for_name('draft4').metaschema
  begin
    JSON::Validator.validate!(meta_schema, output_schema)
    # putt :extract_data, 'The schema is valid.'        
    @output_schema = output_schema
  rescue JSON::Schema::ValidationError => e
    putt :extract_data, "The schema is not valid. Reason: #{e.message}"
    putt :extract_data, "Schema: #{output_schema}"
    raise
  end

  if flags.include?(:list)
    @output_schema = {
      type: 'object',
      properties: {
        list: {
          type: 'array',
          items: output_schema
        }
      }
    }
  end

  extract_data_function_name = 'extract_data'
  req.request_hash[:functions] = [{
    name: extract_data_function_name,
    description: "Extracts data from the user's message",
    parameters: @output_schema
  }]
  # Specifying a particular function via {"name":\ "my_function"} forces the model to call that function.
  req.request_hash[:function_call] = { "name": extract_data_function_name }
end

#to_sObject



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/chat_request_details.rb', line 127

def to_s
  s = "ChatRequestDetails: "
  if output_schema
    schema = JSON.pretty_generate(output_schema)
    s += "\nSchema:\n#{schema}\n"
  end
  if functions_object
    s += "\nFunctions object: #{functions_object}"
  end
  return s
end

#update_request_hashObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/chat_request_details.rb', line 27

def update_request_hash
  req.request_hash[:temperature] = req.temperature / 2.0 if req.temperature # for some reason, OpenAI goes from 0 to 2, not 0 to 1
  req.request_hash[:max_tokens] = req.max_tokens
  req.request_hash[:model] = req.llm_name 
  
  #this is risky because it can overwrite things....

  if @message_history
      messages = req.message_history.dup
  else
    messages = [{"role":"system","content":"You are a helpful assistant."}] 
  end
  # this could make sense, for example, if message_history
  # has a function call in it, along with the response to the function call that glim inserted
  # TODO: we might want to handle that case differently.
  if req.prompt
    messages.append({ role: 'user', content: req.prompt }) 
  end

  req.request_hash[:messages] = messages

end