Module: OpenAI

Defined in:
lib/monadic_chat/open_ai.rb

Defined Under Namespace

Classes: Completion

Class Method Summary collapse

Class Method Details

.default_model(research_mode: false) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/monadic_chat/open_ai.rb', line 17

def self.default_model(research_mode: false)
  if research_mode
    "gpt-4o-latest"
  else # normal mode
    "gpt-4o-mini"
  end
end

.model_to_method(model) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/monadic_chat/open_ai.rb', line 25

def self.model_to_method(model)
  res = {
    "gpt-3.5-turbo-0125" => "chat/completions",
    "gpt-3.5-turbo-1106" => "chat/completions",
    "gpt-3.5-turbo" => "chat/completions",
    "gpt-3.5-turbo-16k" => "chat/completions",
    "gpt-4o-mini-2024-07-18" => "chat/completions",
    "gpt-4o-mini" => "chat/completions",
    "gpt-4o" => "chat/completions",
    "gpt-4o-latest" => "chat/completions",
    "gpt-4o-2024-08-06" => "chat/completions",
    "gpt-4o-2024-05-13" => "chat/completions",
    "gpt-4-0125-preview" => "chat/completions",
    "gpt-4-turbo-preview" => "chat/completions",
    "gpt-4-1106-preview" => "chat/completions",
    "gpt-4" => "chat/completions",
    "gpt-4-0613" => "chat/completions",
    "gpt-4-32K" => "chat/completions"
  }[model]
  if res.nil?
    puts ""
    puts "============================================================="
    puts "Model #{model} not found."
    puts "Maybe you are trying to use a model not available any more."
    puts "Check your monadic_chat.conf and try again."
    puts "============================================================="
    puts ""
    exit 1
  end
  res
end

.models(access_token) ⇒ Object



148
149
150
151
# File 'lib/monadic_chat/open_ai.rb', line 148

def self.models(access_token)
  res = query(access_token, "get", "models")
  res.fetch("data", []).sort_by { |m| -m["created"] }
end

.query(access_token, mode, method, timeout_sec = 60, query = {}, &block) ⇒ Object



57
58
59
60
61
62
63
64
65
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/monadic_chat/open_ai.rb', line 57

def self.query(access_token, mode, method, timeout_sec = 60, query = {}, &block)
  target_uri = "https://api.openai.com/v1/#{method}"
  headers = {
    "Content-Type" => "application/json",
    "Authorization" => "Bearer #{access_token}"
  }
  headers["Accept"] = "text/event-stream" if query["stream"]
  http = HTTP.headers(headers)

  timeout_settings = {
    connect: OPEN_TIMEOUT,
    write: timeout_sec,
    read: timeout_sec
  }

  case mode
  when "post"
    res = http.timeout(timeout_settings).post(target_uri, json: query)
  when "get"
    res = http.timeout(timeout_settings).get(target_uri)
  end

  if query["stream"]
    json = nil
    buffer = ""

    res.body.each do |chunk|
      break if /\Rdata: [DONE]\R/ =~ chunk

      buffer << chunk
      scanner = StringScanner.new(buffer)
      pattern = /data: (\{.*?\})(?=\n|\z)/m
      until scanner.eos?
        matched = scanner.scan_until(pattern)
        if matched
          json_data = matched.match(pattern)[1]

          begin
            res = JSON.parse(json_data)
            choice = res.dig("choices", 0) || {}

            fragment = choice.dig("delta", "content").to_s
            next if !fragment || fragment == ""

            block&.call fragment

            json ||= res
            json["choices"][0]["text"] ||= +""
            json["choices"][0]["text"] << fragment

            if choice["finish_reason"] == "length" || choice["finish_reason"] == "stop"
              finish = { "type" => "message", "content" => "DONE" }
              block&.call finish
              break
            end
          rescue JSON::ParserError
            res = { "type" => "error", "content" => "Error: JSON Parsing" }
            pp res
            block&.call res
            res
          end
        else
          buffer = scanner.rest
          break
        end
      end
    end
    json
  else
    begin
      JSON.parse res.body
    rescue JSON::ParserError
      res = { "type" => "error", "content" => "Error: JSON Parsing" }
      pp res
      block&.call res
      res
    end
  end
rescue HTTP::Error, HTTP::TimeoutError
  if num_retrial < MAX_RETRIES
    num_retrial += 1
    sleep RETRY_DELAY
    retry
  else
    res = { "type" => "error", "content" => "Error: Timeout" }
    pp res
    block&.call res
    res
  end
end