llm.rb 0.4.0 → 0.4.1

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.
@@ -1,204 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "setup"
4
-
5
- RSpec.describe "LLM::OpenAI::Files" do
6
- let(:token) { ENV["LLM_SECRET"] || "TOKEN" }
7
- let(:provider) { LLM.openai(token) }
8
-
9
- context "when given a successful create operation (haiku1.txt)",
10
- vcr: {cassette_name: "openai/files/successful_create_haiku1"} do
11
- subject(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/haiku1.txt")) }
12
-
13
- it "is successful" do
14
- expect(file).to be_instance_of(LLM::Response::File)
15
- ensure
16
- provider.files.delete(file:)
17
- end
18
-
19
- it "returns a file object" do
20
- expect(file).to have_attributes(
21
- id: instance_of(String),
22
- filename: "haiku1.txt",
23
- purpose: "assistants"
24
- )
25
- ensure
26
- provider.files.delete(file:)
27
- end
28
- end
29
-
30
- context "when given a successful create operation (haiku2.txt)",
31
- vcr: {cassette_name: "openai/files/successful_create_haiku2"} do
32
- subject(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/haiku2.txt")) }
33
-
34
- it "is successful" do
35
- expect(file).to be_instance_of(LLM::Response::File)
36
- ensure
37
- provider.files.delete(file:)
38
- end
39
-
40
- it "returns a file object" do
41
- expect(file).to have_attributes(
42
- id: instance_of(String),
43
- filename: "haiku2.txt",
44
- purpose: "assistants"
45
- )
46
- ensure
47
- provider.files.delete(file:)
48
- end
49
- end
50
-
51
- context "when given a successful delete operation (haiku3.txt)",
52
- vcr: {cassette_name: "openai/files/successful_delete_haiku3"} do
53
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/haiku3.txt")) }
54
- subject { provider.files.delete(file:) }
55
-
56
- it "is successful" do
57
- is_expected.to be_instance_of(OpenStruct)
58
- end
59
-
60
- it "returns deleted status" do
61
- is_expected.to have_attributes(
62
- deleted: true
63
- )
64
- end
65
- end
66
-
67
- context "when given a successful get operation (haiku4.txt)",
68
- vcr: {cassette_name: "openai/files/successful_get_haiku4"} do
69
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/haiku4.txt")) }
70
- subject { provider.files.get(file:) }
71
-
72
- it "is successful" do
73
- is_expected.to be_instance_of(LLM::Response::File)
74
- ensure
75
- provider.files.delete(file:)
76
- end
77
-
78
- it "returns a file object" do
79
- is_expected.to have_attributes(
80
- id: instance_of(String),
81
- filename: "haiku4.txt",
82
- purpose: "assistants"
83
- )
84
- ensure
85
- provider.files.delete(file:)
86
- end
87
- end
88
-
89
- context "when given a successful all operation",
90
- vcr: {cassette_name: "openai/files/successful_all"} do
91
- let!(:files) do
92
- [
93
- provider.files.create(file: LLM::File("spec/fixtures/documents/haiku1.txt")),
94
- provider.files.create(file: LLM::File("spec/fixtures/documents/haiku2.txt"))
95
- ]
96
- end
97
- subject(:filelist) { provider.files.all }
98
-
99
- it "is successful" do
100
- expect(filelist).to be_instance_of(LLM::Response::FileList)
101
- ensure
102
- files.each { |file| provider.files.delete(file:) }
103
- end
104
-
105
- it "returns an array of file objects" do
106
- expect(filelist.files[0..1]).to match_array(
107
- [
108
- have_attributes(
109
- id: instance_of(String),
110
- filename: "haiku1.txt",
111
- purpose: "assistants"
112
- ),
113
- have_attributes(
114
- id: instance_of(String),
115
- filename: "haiku2.txt",
116
- purpose: "assistants"
117
- )
118
- ]
119
- )
120
- ensure
121
- files.each { |file| provider.files.delete(file:) }
122
- end
123
- end
124
-
125
- context "when asked to describe the contents of a file",
126
- vcr: {cassette_name: "openai/files/describe_freebsd.sysctl.pdf"} do
127
- subject { bot.last_message.content.downcase[0..2] }
128
- let(:bot) { LLM::Chat.new(provider).lazy }
129
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/freebsd.sysctl.pdf")) }
130
-
131
- before do
132
- bot.respond(file)
133
- bot.respond("Is this PDF document about FreeBSD?")
134
- bot.respond("Answer with yes or no. Nothing else.")
135
- end
136
-
137
- it "describes the document" do
138
- is_expected.to eq("yes")
139
- ensure
140
- provider.files.delete(file:)
141
- end
142
- end
143
-
144
- context "when asked to describe the contents of a file",
145
- vcr: {cassette_name: "openai/files/describe_freebsd.sysctl_2.pdf"} do
146
- subject { bot.last_message.content.downcase[0..2] }
147
- let(:bot) { LLM::Chat.new(provider).lazy }
148
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/freebsd.sysctl.pdf")) }
149
-
150
- before do
151
- bot.respond([
152
- "Is this PDF document about FreeBSD?",
153
- "Answer with yes or no. Nothing else.",
154
- file
155
- ])
156
- end
157
-
158
- it "describes the document" do
159
- is_expected.to eq("yes")
160
- ensure
161
- provider.files.delete(file:)
162
- end
163
- end
164
-
165
- context "when asked to describe the contents of a file",
166
- vcr: {cassette_name: "openai/files/describe_freebsd.sysctl_3.pdf"} do
167
- subject { bot.last_message.content.downcase[0..2] }
168
- let(:bot) { LLM::Chat.new(provider).lazy }
169
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/freebsd.sysctl.pdf")) }
170
-
171
- before do
172
- bot.chat(file)
173
- bot.chat("Is this PDF document about FreeBSD?")
174
- bot.chat("Answer with yes or no. Nothing else.")
175
- end
176
-
177
- it "describes the document" do
178
- is_expected.to eq("yes")
179
- ensure
180
- provider.files.delete(file:)
181
- end
182
- end
183
-
184
- context "when asked to describe the contents of a file",
185
- vcr: {cassette_name: "openai/files/describe_freebsd.sysctl_4.pdf"} do
186
- subject { bot.last_message.content.downcase[0..2] }
187
- let(:bot) { LLM::Chat.new(provider).lazy }
188
- let(:file) { provider.files.create(file: LLM::File("spec/fixtures/documents/freebsd.sysctl.pdf")) }
189
-
190
- before do
191
- bot.chat([
192
- "Is this PDF document about FreeBSD?",
193
- "Answer with yes or no. Nothing else.",
194
- file
195
- ])
196
- end
197
-
198
- it "describes the document" do
199
- is_expected.to eq("yes")
200
- ensure
201
- provider.files.delete(file:)
202
- end
203
- end
204
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "setup"
4
-
5
- RSpec.describe "LLM::OpenAI::Images" do
6
- let(:token) { ENV["LLM_SECRET"] || "TOKEN" }
7
- let(:provider) { LLM.openai(token) }
8
-
9
- context "when given a successful create operation (urls)",
10
- vcr: {cassette_name: "openai/images/successful_create_urls"} do
11
- subject(:response) { provider.images.create(prompt: "A dog on a rocket to the moon") }
12
-
13
- it "is successful" do
14
- expect(response).to be_instance_of(LLM::Response::Image)
15
- end
16
-
17
- it "returns an array of urls" do
18
- expect(response.urls).to be_instance_of(Array)
19
- end
20
-
21
- it "returns a url" do
22
- expect(response.urls[0]).to be_instance_of(String)
23
- end
24
- end
25
-
26
- context "when given a successful create operation (base64)",
27
- vcr: {cassette_name: "openai/images/successful_create_base64"} do
28
- subject(:response) do
29
- provider.images.create(
30
- prompt: "A dog on a rocket to the moon",
31
- response_format: "b64_json"
32
- )
33
- end
34
-
35
- it "is successful" do
36
- expect(response).to be_instance_of(LLM::Response::Image)
37
- end
38
-
39
- it "returns an array of images" do
40
- expect(response.images).to be_instance_of(Array)
41
- end
42
-
43
- it "returns an IO-like object" do
44
- expect(response.images[0]).to be_instance_of(StringIO)
45
- end
46
- end
47
-
48
- context "when given a successful variation operation",
49
- vcr: {cassette_name: "openai/images/successful_variation"} do
50
- subject(:response) do
51
- provider.images.create_variation(
52
- image: LLM::File("spec/fixtures/images/bluebook.png"),
53
- n: 5
54
- )
55
- end
56
-
57
- it "is successful" do
58
- expect(response).to be_instance_of(LLM::Response::Image)
59
- end
60
-
61
- it "returns data" do
62
- expect(response.urls.size).to eq(5)
63
- end
64
-
65
- it "returns multiple variations" do
66
- response.urls.each { expect(_1).to be_instance_of(String) }
67
- end
68
- end
69
-
70
- context "when given a successful edit",
71
- vcr: {cassette_name: "openai/images/successful_edit"} do
72
- subject(:response) do
73
- provider.images.edit(
74
- image: LLM::File("spec/fixtures/images/bluebook.png"),
75
- prompt: "Add white background"
76
- )
77
- end
78
-
79
- it "is successful" do
80
- expect(response).to be_instance_of(LLM::Response::Image)
81
- end
82
-
83
- it "returns data" do
84
- expect(response.urls).to be_instance_of(Array)
85
- end
86
-
87
- it "returns a url" do
88
- expect(response.urls[0]).to be_instance_of(String)
89
- end
90
- end
91
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "setup"
4
-
5
- RSpec.describe "LLM::OpenAI::Models" do
6
- let(:token) { ENV["LLM_SECRET"] || "TOKEN" }
7
- let(:provider) { LLM.openai(token) }
8
-
9
- context "when given a successful list operation",
10
- vcr: {cassette_name: "openai/models/successful_list"} do
11
- subject { provider.models.all }
12
-
13
- it "is successful" do
14
- is_expected.to be_instance_of(LLM::Response::ModelList)
15
- end
16
-
17
- it "returns a list of models" do
18
- expect(subject.models).to all(be_a(LLM::Model))
19
- end
20
- end
21
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "setup"
4
-
5
- RSpec.describe "LLM::OpenAI::Responses" do
6
- let(:token) { ENV["LLM_SECRET"] || "TOKEN" }
7
- let(:provider) { LLM.openai(token) }
8
-
9
- context "when given a successful create operation",
10
- vcr: {cassette_name: "openai/responses/successful_create"} do
11
- subject { provider.responses.create("Hello", :developer) }
12
-
13
- it "is successful" do
14
- is_expected.to be_instance_of(LLM::Response::Output)
15
- end
16
-
17
- it "has outputs" do
18
- is_expected.to have_attributes(
19
- outputs: [instance_of(LLM::Message)]
20
- )
21
- end
22
- end
23
-
24
- context "when given a successful get operation",
25
- vcr: {cassette_name: "openai/responses/successful_get"} do
26
- let(:response) { provider.responses.create("Hello", :developer) }
27
- subject { provider.responses.get(response) }
28
-
29
- it "is successful" do
30
- is_expected.to be_instance_of(LLM::Response::Output)
31
- end
32
-
33
- it "has outputs" do
34
- is_expected.to have_attributes(
35
- outputs: [instance_of(LLM::Message)]
36
- )
37
- end
38
- end
39
-
40
- context "when given a successful delete operation",
41
- vcr: {cassette_name: "openai/responses/successful_delete"} do
42
- let(:response) { provider.responses.create("Hello", :developer) }
43
- subject { provider.responses.delete(response) }
44
-
45
- it "is successful" do
46
- is_expected.to have_attributes(
47
- deleted: true
48
- )
49
- end
50
- end
51
- end
data/spec/readme_spec.rb DELETED
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "setup"
4
- require "test/cmd"
5
-
6
- RSpec.describe "The README examples" do
7
- before { ENV["key"] = key }
8
- after { ENV["key"] = nil }
9
- let(:key) { "" }
10
-
11
- context "when given the lazy conversation example" do
12
- subject(:command) do
13
- cmd RbConfig.ruby,
14
- "-Ilib",
15
- "-r", webmock("lazy_conversation.rb"),
16
- readme_example("lazy_conversation.rb")
17
- end
18
-
19
- let(:actual_conversation) do
20
- command.stdout.each_line.map(&:strip)
21
- end
22
-
23
- let(:expected_conversation) do
24
- [
25
- "[system] You are my math assistant.",
26
- "I will provide you with (simple) equations.",
27
- "You will provide answers in the format \"The answer to <equation> is <answer>\".",
28
- "I will provide you a set of messages. Reply to all of them.",
29
- "A message is considered unanswered if there is no corresponding assistant response.",
30
-
31
- "[user] Tell me the answer to 5 + 15",
32
- "[user] Tell me the answer to (5 + 15) * 2",
33
- "[user] Tell me the answer to ((5 + 15) * 2) / 10",
34
-
35
- "[assistant] The answer to 5 + 15 is 20.",
36
- "The answer to (5 + 15) * 2 is 40.",
37
- "The answer to ((5 + 15) * 2) / 10 is 4."
38
- ].map(&:strip)
39
- end
40
-
41
- it "is successful" do
42
- is_expected.to be_success
43
- end
44
-
45
- it "emits output" do
46
- expect(join(actual_conversation)).to eq(join(expected_conversation))
47
- end
48
- end
49
-
50
- def webmock(example)
51
- File.join(Dir.getwd, "share", "llm", "webmocks", example)
52
- end
53
-
54
- def readme_example(example)
55
- File.join(Dir.getwd, "share", "llm", "examples", example)
56
- end
57
-
58
- def join(lines)
59
- lines.reject(&:empty?).join("\n")
60
- end
61
- end
data/spec/setup.rb DELETED
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "llm"
4
- require "webmock/rspec"
5
- require "vcr"
6
-
7
- RSpec.configure do |config|
8
- config.disable_monkey_patching!
9
-
10
- config.expect_with :rspec do |c|
11
- c.syntax = :expect
12
- end
13
- end
14
-
15
- VCR.configure do |config|
16
- config.cassette_library_dir = "spec/fixtures/cassettes"
17
- config.hook_into :webmock
18
- config.configure_rspec_metadata!
19
-
20
- ##
21
- # scrub
22
- config.filter_sensitive_data("TOKEN") { ENV["LLM_SECRET"] }
23
- config.before_record do
24
- body = _1.response.body
25
- body.gsub! %r|#{Regexp.escape("https://oaidalleapiprodscus.blob.core.windows.net/")}[^"]+|,
26
- "https://openai.com/generated/image.png"
27
- end
28
- end