openai-term 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/openai +69 -29
- metadata +4 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1b541d1b3b223edaa022070e38cbf187104deed56fe67f321c3197a3ff7c2992
|
|
4
|
+
data.tar.gz: 5d6f9cf9ee175e59b6b90a790c2ae273a12cad80069ca1662a64b14ba4ecd199
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4de85e3718a0c94b6d8173a25424222e4b496960207151953a07557046ef81be336f495235439c25c31c324e3998de5b5e2c384aa0dc805d6ed95055aebdc00
|
|
7
|
+
data.tar.gz: 1e0f248ac0d35859d2a2fee6446358205f454f5b4e37b75da83828803f8ca2f512a230f7f139c285e7f1cf7c4748bcfe4e734e21f55011c7c1f55dc573e173e1
|
data/bin/openai
CHANGED
|
@@ -18,7 +18,10 @@ CONFIG_FILE = File.join(Dir.home, '.openai.conf')
|
|
|
18
18
|
HISTORY_FILE = File.join(Dir.home, '.openai_history.json')
|
|
19
19
|
DEFAULT_MODEL = "gpt-4-turbo-preview"
|
|
20
20
|
DEFAULT_MAX_TOKENS = 2048
|
|
21
|
-
VERSION = "3.0.
|
|
21
|
+
VERSION = "3.0.3"
|
|
22
|
+
REQUEST_TIMEOUT = 30
|
|
23
|
+
MAX_RETRIES = 2
|
|
24
|
+
RETRY_DELAY = 2
|
|
22
25
|
|
|
23
26
|
# Global variables
|
|
24
27
|
@model = DEFAULT_MODEL
|
|
@@ -138,10 +141,39 @@ end
|
|
|
138
141
|
# Initialize OpenAI client
|
|
139
142
|
def init_client
|
|
140
143
|
@client = OpenAI::Client.new(
|
|
141
|
-
access_token: @api_key
|
|
144
|
+
access_token: @api_key,
|
|
145
|
+
request_timeout: REQUEST_TIMEOUT
|
|
142
146
|
)
|
|
143
147
|
end
|
|
144
148
|
|
|
149
|
+
# Retry wrapper for transient API failures
|
|
150
|
+
def with_retry
|
|
151
|
+
retries = 0
|
|
152
|
+
begin
|
|
153
|
+
yield
|
|
154
|
+
rescue Net::OpenTimeout, Net::ReadTimeout, Errno::ETIMEDOUT => e
|
|
155
|
+
if retries < MAX_RETRIES
|
|
156
|
+
retries += 1
|
|
157
|
+
msg = "Timeout, retrying (#{retries}/#{MAX_RETRIES})..."
|
|
158
|
+
@chat_pane ? add_to_chat("system", msg.fg(208)) : $stderr.puts(msg)
|
|
159
|
+
sleep(RETRY_DELAY)
|
|
160
|
+
retry
|
|
161
|
+
end
|
|
162
|
+
raise
|
|
163
|
+
rescue Faraday::Error => e
|
|
164
|
+
status = e.respond_to?(:response_status) ? e.response_status : nil
|
|
165
|
+
if status && [429, 500, 502, 503].include?(status) && retries < MAX_RETRIES
|
|
166
|
+
retries += 1
|
|
167
|
+
delay = status == 429 ? RETRY_DELAY * 2 : RETRY_DELAY
|
|
168
|
+
msg = "HTTP #{status}, retrying (#{retries}/#{MAX_RETRIES})..."
|
|
169
|
+
@chat_pane ? add_to_chat("system", msg.fg(208)) : $stderr.puts(msg)
|
|
170
|
+
sleep(delay)
|
|
171
|
+
retry
|
|
172
|
+
end
|
|
173
|
+
raise
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
145
177
|
# Setup UI
|
|
146
178
|
def setup_ui
|
|
147
179
|
unless $stdin.tty?
|
|
@@ -309,13 +341,15 @@ def get_openai_response(message, generate_image = false)
|
|
|
309
341
|
|
|
310
342
|
begin
|
|
311
343
|
if generate_image
|
|
312
|
-
response =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
344
|
+
response = with_retry do
|
|
345
|
+
@client.images.generate(
|
|
346
|
+
parameters: {
|
|
347
|
+
prompt: message,
|
|
348
|
+
n: 1,
|
|
349
|
+
size: "1024x1024"
|
|
350
|
+
}
|
|
351
|
+
)
|
|
352
|
+
end
|
|
319
353
|
|
|
320
354
|
url = response.dig("data", 0, "url")
|
|
321
355
|
if url
|
|
@@ -334,28 +368,32 @@ def get_openai_response(message, generate_image = false)
|
|
|
334
368
|
end
|
|
335
369
|
end
|
|
336
370
|
|
|
337
|
-
response =
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
371
|
+
response = with_retry do
|
|
372
|
+
@client.chat(
|
|
373
|
+
parameters: {
|
|
374
|
+
model: @model,
|
|
375
|
+
messages: messages,
|
|
376
|
+
max_tokens: @max_tokens,
|
|
377
|
+
temperature: @temperature
|
|
378
|
+
}
|
|
379
|
+
)
|
|
380
|
+
end
|
|
345
381
|
|
|
346
382
|
content = response.dig("choices", 0, "message", "content")
|
|
347
383
|
else
|
|
348
384
|
# Use completion for older models
|
|
349
385
|
prompt = @current_conversation.map { |m| "#{m['role']}: #{m['content']}" }.join("\n") + "\nassistant:"
|
|
350
386
|
|
|
351
|
-
response =
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
387
|
+
response = with_retry do
|
|
388
|
+
@client.completions(
|
|
389
|
+
parameters: {
|
|
390
|
+
model: @model,
|
|
391
|
+
prompt: prompt,
|
|
392
|
+
max_tokens: @max_tokens,
|
|
393
|
+
temperature: @temperature
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
end
|
|
359
397
|
|
|
360
398
|
content = response.dig("choices", 0, "text")
|
|
361
399
|
end
|
|
@@ -398,7 +436,7 @@ def show_model_selection
|
|
|
398
436
|
|
|
399
437
|
# Get available models
|
|
400
438
|
begin
|
|
401
|
-
models_response = @client.models.list
|
|
439
|
+
models_response = with_retry { @client.models.list }
|
|
402
440
|
@available_models = models_response["data"]
|
|
403
441
|
.map { |m| m["id"] }
|
|
404
442
|
.select { |id| id.include?("gpt") || id.include?("davinci") || id.include?("curie") }
|
|
@@ -951,9 +989,11 @@ def main
|
|
|
951
989
|
input_loop
|
|
952
990
|
|
|
953
991
|
ensure
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
992
|
+
if @chat_pane # Only cleanup UI if TUI was initialized
|
|
993
|
+
save_history if defined?(@conversation_history)
|
|
994
|
+
Rcurses::Cursor.show if defined?(Rcurses::Cursor)
|
|
995
|
+
Rcurses.clear_screen if defined?(Rcurses)
|
|
996
|
+
end
|
|
957
997
|
end
|
|
958
998
|
|
|
959
999
|
# Run the program
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openai-term
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ruby-openai
|
|
@@ -40,9 +40,8 @@ dependencies:
|
|
|
40
40
|
version: '6.0'
|
|
41
41
|
description: 'A modern terminal interface to OpenAI with a full TUI using rcurses.
|
|
42
42
|
Features include interactive chat mode, conversation history, model selection, and
|
|
43
|
-
more. Version 3.0.
|
|
44
|
-
|
|
45
|
-
added missing io/console requirement, improved configuration help.'
|
|
43
|
+
more. Version 3.0.3: Add configurable request timeout and retry logic for transient
|
|
44
|
+
API failures (timeout, 429, 500/502/503).'
|
|
46
45
|
email: g@isene.com
|
|
47
46
|
executables:
|
|
48
47
|
- openai
|