ai-chat 0.5.1 → 0.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77efcbc43e3402b184ce49ff870671796904a0935a37d55dd9eeaaea93572b53
4
- data.tar.gz: 8996a14db31e7455815d10acac9827658fcbaf5358e1a461d2b83a946b8f3cc9
3
+ metadata.gz: 9012bf87a54da64ccab695a2d440249cf691f2f5943272c918065b24137fa6fb
4
+ data.tar.gz: 9d3931249dc62145f8eb3cc3fc44382a038c901b8bfc4a2ccda0d01d8653489d
5
5
  SHA512:
6
- metadata.gz: b1993b6e812a75387b53ade7f29785a80aa0c70c7b6aa97d5ac9eed7e73fc27a87f1a76676e9878416849af3c9ae3967d6b78838be0c681f077fa63c81e32993
7
- data.tar.gz: 0f463e8beef43965db7b85b94335624322f46bc39cc4dd2c1a02ad44993ae972bdbfb4a670890b3f55ddf9ce5ebf57fd8b2e92f85fd3340a2be1d7aa6d1ca549
6
+ metadata.gz: d9447afcbff626605c7b865675cd28d598e2c3cee19010aa86a9955b5a3cf109ea68ea40765bfe9aa92f43d823710eb91f7d4b3cfd92d4105c02f6ad9e45bdc9
7
+ data.tar.gz: 5ae2565d62ae358f62938a5b888e55d73bc581449e0f0e1c4de836f713832c1bf19fe0e9ba6d8ae0c4b108323532ab5e905dc22079e0aa4ecc833b6a9b884386
data/ai-chat.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "ai-chat"
5
- spec.version = "0.5.1"
5
+ spec.version = "0.5.4"
6
6
  spec.authors = ["Raghu Betina", "Jelani Woods"]
7
7
  spec.email = ["raghu@firstdraft.com", "jelani@firstdraft.com"]
8
8
  spec.homepage = "https://github.com/firstdraft/ai-chat"
@@ -18,18 +18,15 @@ Gem::Specification.new do |spec|
18
18
  "source_code_uri" => "https://github.com/firstdraft/ai-chat"
19
19
  }
20
20
 
21
- spec.required_ruby_version = "~> 3.2"
22
- spec.add_runtime_dependency "openai", "~> 0.34"
21
+ spec.required_ruby_version = ">= 3.2"
22
+ spec.add_runtime_dependency "openai", "~> 0.43"
23
23
  spec.add_runtime_dependency "marcel", "~> 1.0"
24
24
  spec.add_runtime_dependency "base64", "~> 0.1", "> 0.1.1"
25
25
  spec.add_runtime_dependency "json", "~> 2.0"
26
- spec.add_runtime_dependency "ostruct", "~> 0.2"
27
26
  spec.add_runtime_dependency "tty-spinner", "~> 0.9.3"
28
- spec.add_runtime_dependency "amazing_print", "~> 1.8"
27
+ spec.add_runtime_dependency "amazing_print", "~> 2.0"
29
28
 
30
29
  spec.add_development_dependency "dotenv", ">= 1.0.0"
31
- spec.add_development_dependency "refinements", "~> 11.1"
32
-
33
30
  spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
34
31
  spec.files = Dir["*.gemspec", "lib/**/*"]
35
32
  end
data/lib/ai/chat.rb CHANGED
@@ -4,7 +4,6 @@ require "base64"
4
4
  require "json"
5
5
  require "marcel"
6
6
  require "openai"
7
- require "ostruct"
8
7
  require "pathname"
9
8
  require "stringio"
10
9
  require "fileutils"
@@ -157,15 +156,14 @@ module AI
157
156
 
158
157
  def proxy=(value)
159
158
  @proxy = value
160
- if value
161
- @client = OpenAI::Client.new(
159
+ @client = if value
160
+ OpenAI::Client.new(
162
161
  api_key: @api_key,
163
162
  base_url: BASE_PROXY_URL
164
163
  )
165
164
  else
166
- @client = OpenAI::Client.new(api_key: @api_key)
165
+ OpenAI::Client.new(api_key: @api_key)
167
166
  end
168
- value
169
167
  end
170
168
 
171
169
  def schema=(value)
@@ -208,8 +206,8 @@ module AI
208
206
  attrs << [:@conversation_id, @conversation_id]
209
207
  attrs << [:@last_response_id, @last_response_id] if @last_response_id
210
208
 
211
- # 3. Messages (the main content, without response details)
212
- display_messages = @messages.map { |msg| msg.except(:response) }
209
+ # 3. Messages (the main content, without response details, with truncated data URIs)
210
+ display_messages = @messages.map { |msg| AI.truncate_data_uris(msg.except(:response)) }
213
211
  attrs << [:@messages, display_messages]
214
212
 
215
213
  # 4. Optional features (only if enabled/changed from default)
@@ -228,11 +226,11 @@ module AI
228
226
  end
229
227
 
230
228
  def inspect
231
- ai(plain: !$stdout.tty?, multiline: true)
229
+ AI.amazing_print(self, plain: !$stdout.tty?, multiline: true)
232
230
  end
233
231
 
234
232
  def to_html
235
- AI.wrap_html(ai(html: true, multiline: true))
233
+ AI.wrap_html(AI.amazing_print(self, html: true, multiline: true))
236
234
  end
237
235
 
238
236
  def pretty_inspect
@@ -525,8 +523,8 @@ module AI
525
523
  image_filenames = []
526
524
 
527
525
  image_outputs = response.output.select { |output|
528
- output.respond_to?(:type) && output.type == :image_generation_call
529
- }
526
+ output.respond_to?(:type) && output.type == :image_generation_call
527
+ }
530
528
 
531
529
  return image_filenames if image_outputs.empty?
532
530
 
@@ -574,7 +572,7 @@ module AI
574
572
  @api_key_validated = true
575
573
  rescue OpenAI::Errors::AuthenticationError
576
574
  message = if proxy
577
- <<~STRING
575
+ <<~STRING
578
576
  It looks like you're using an invalid API key. Proxying is enabled, so you must use an OpenAI API key from prepend.me. Please disable proxy or update your API key before generating a response.
579
577
  STRING
580
578
  else
data/lib/ai/items.rb CHANGED
@@ -29,7 +29,7 @@ module AI
29
29
 
30
30
  def build_output(html: false, plain: false)
31
31
  box = build_box
32
- items_output = data.ai(html: html, plain: plain, limit: 100, indent: 2, index: true)
32
+ items_output = AI.amazing_print(data, html: html, plain: plain, limit: 100, indent: 2, index: true)
33
33
 
34
34
  if html
35
35
  "<pre>#{box}</pre>\n#{items_output}"
data/lib/ai/message.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module AI
4
4
  class Message < Hash
5
5
  def inspect
6
- ai(plain: !$stdout.tty?, index: false)
6
+ AI.amazing_print(display_hash, plain: !$stdout.tty?, index: false)
7
7
  end
8
8
 
9
9
  def pretty_inspect
@@ -17,7 +17,13 @@ module AI
17
17
  end
18
18
 
19
19
  def to_html
20
- AI.wrap_html(ai(html: true, index: false))
20
+ AI.wrap_html(AI.amazing_print(display_hash, html: true, index: false))
21
+ end
22
+
23
+ private
24
+
25
+ def display_hash
26
+ AI.truncate_data_uris(to_h)
21
27
  end
22
28
  end
23
29
  end
data/lib/ai-chat.rb CHANGED
@@ -1,10 +1,43 @@
1
1
  module AI
2
- HTML_PRE_STYLE = "background-color: #1e1e1e; color: #d4d4d4; padding: 1em; white-space: pre-wrap; word-wrap: break-word;"
2
+ HTML_PRE_STYLE = "background-color: #1e1e1e; color: #d4d4d4; padding: 1em; " \
3
+ "border-radius: 4px; overflow-x: auto; " \
4
+ "white-space: pre-wrap; word-wrap: break-word;"
3
5
 
4
- def self.wrap_html(html)
5
- html = html.gsub("<pre>", "<pre style=\"#{HTML_PRE_STYLE}\">")
6
+ def self.wrap_html(content)
7
+ html = "<pre style=\"#{HTML_PRE_STYLE}\">#{content}</pre>"
6
8
  html.respond_to?(:html_safe) ? html.html_safe : html
7
9
  end
10
+
11
+ # Use AmazingPrint::Inspector directly to avoid conflicts with awesome_print gem
12
+ # which also defines an `ai` method on Object
13
+ def self.amazing_print(object, **options)
14
+ AmazingPrint::Inspector.new(**options).awesome(object)
15
+ end
16
+
17
+ # Recursively truncate base64 data URIs in nested structures for cleaner output
18
+ def self.truncate_data_uris(obj)
19
+ case obj
20
+ when Hash
21
+ obj.transform_values { |v| truncate_data_uris(v) }
22
+ when Array
23
+ obj.map { |v| truncate_data_uris(v) }
24
+ when String
25
+ truncate_data_uri(obj)
26
+ else
27
+ obj
28
+ end
29
+ end
30
+
31
+ def self.truncate_data_uri(str)
32
+ return str unless str.is_a?(String) && str.start_with?("data:") && str.include?(";base64,")
33
+
34
+ match = str.match(/\A(data:[^;]+;base64,)(.+)\z/)
35
+ return str unless match
36
+
37
+ prefix = match[1]
38
+ data = match[2]
39
+ "#{prefix}#{data[0, 20]}... (#{data.length} chars)"
40
+ end
8
41
  end
9
42
 
10
43
  require_relative "ai/message"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ai-chat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raghu Betina
8
8
  - Jelani Woods
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-29 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: openai
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.34'
19
+ version: '0.43'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.34'
26
+ version: '0.43'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: marcel
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,20 +72,6 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '2.0'
75
- - !ruby/object:Gem::Dependency
76
- name: ostruct
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.2'
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.2'
89
75
  - !ruby/object:Gem::Dependency
90
76
  name: tty-spinner
91
77
  requirement: !ruby/object:Gem::Requirement
@@ -106,14 +92,14 @@ dependencies:
106
92
  requirements:
107
93
  - - "~>"
108
94
  - !ruby/object:Gem::Version
109
- version: '1.8'
95
+ version: '2.0'
110
96
  type: :runtime
111
97
  prerelease: false
112
98
  version_requirements: !ruby/object:Gem::Requirement
113
99
  requirements:
114
100
  - - "~>"
115
101
  - !ruby/object:Gem::Version
116
- version: '1.8'
102
+ version: '2.0'
117
103
  - !ruby/object:Gem::Dependency
118
104
  name: dotenv
119
105
  requirement: !ruby/object:Gem::Requirement
@@ -128,28 +114,14 @@ dependencies:
128
114
  - - ">="
129
115
  - !ruby/object:Gem::Version
130
116
  version: 1.0.0
131
- - !ruby/object:Gem::Dependency
132
- name: refinements
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '11.1'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '11.1'
145
117
  email:
146
118
  - raghu@firstdraft.com
147
119
  - jelani@firstdraft.com
148
120
  executables: []
149
121
  extensions: []
150
122
  extra_rdoc_files:
151
- - README.md
152
123
  - LICENSE
124
+ - README.md
153
125
  files:
154
126
  - LICENSE
155
127
  - README.md
@@ -175,7 +147,7 @@ require_paths:
175
147
  - lib
176
148
  required_ruby_version: !ruby/object:Gem::Requirement
177
149
  requirements:
178
- - - "~>"
150
+ - - ">="
179
151
  - !ruby/object:Gem::Version
180
152
  version: '3.2'
181
153
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -184,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
156
  - !ruby/object:Gem::Version
185
157
  version: '0'
186
158
  requirements: []
187
- rubygems_version: 3.6.2
159
+ rubygems_version: 4.0.3
188
160
  specification_version: 4
189
161
  summary: A beginner-friendly Ruby interface for OpenAI's API
190
162
  test_files: []