lluminary 0.1.2 → 0.1.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.
@@ -12,8 +12,6 @@ RSpec.describe Lluminary::Task do
12
12
  string :summary, description: "A brief summary of the message"
13
13
  end
14
14
 
15
- private
16
-
17
15
  def task_prompt
18
16
  "Say: #{message}"
19
17
  end
@@ -30,67 +28,10 @@ RSpec.describe Lluminary::Task do
30
28
  )
31
29
  end
32
30
 
33
- it "string input allows providing a string input" do
34
- result = task_class.call(message: "hello")
35
- expect(result.output.raw_response).to eq(
36
- '{"summary": "Test string value"}'
37
- )
38
- end
39
-
40
31
  it "string output returns the output in the result" do
41
32
  result = task_class.call(message: "hello")
42
33
  expect(result.output.summary).to eq("Test string value")
43
34
  end
44
-
45
- it "includes schema descriptions in the prompt" do
46
- result = task_class.call(message: "hello")
47
- expected_schema = <<~SCHEMA
48
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
49
- The JSON object must contain the following fields:
50
-
51
- summary (string): A brief summary of the message
52
- Example: "your summary here"
53
-
54
- Your response must be ONLY this JSON object:
55
- {
56
- "summary": "your summary here"
57
- }
58
- SCHEMA
59
- expect(result.prompt).to include(expected_schema.chomp)
60
- end
61
- end
62
-
63
- describe ".call without descriptions" do
64
- let(:task_without_descriptions) do
65
- Class.new(described_class) do
66
- input_schema { string :message }
67
-
68
- output_schema { string :summary }
69
-
70
- private
71
-
72
- def task_prompt
73
- "Say: #{message}"
74
- end
75
- end
76
- end
77
-
78
- it "includes basic schema in the prompt" do
79
- result = task_without_descriptions.call(message: "hello")
80
- expected_schema = <<~SCHEMA
81
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
82
- The JSON object must contain the following fields:
83
-
84
- summary (string)
85
- Example: "your summary here"
86
-
87
- Your response must be ONLY this JSON object:
88
- {
89
- "summary": "your summary here"
90
- }
91
- SCHEMA
92
- expect(result.prompt).to include(expected_schema.chomp)
93
- end
94
35
  end
95
36
 
96
37
  describe ".provider" do
@@ -113,9 +54,25 @@ RSpec.describe Lluminary::Task do
113
54
  it "with :openai instantiates OpenAI provider with config" do
114
55
  task_class.use_provider(:openai, api_key: "test")
115
56
  expect(task_class.provider).to be_a(Lluminary::Providers::OpenAI)
116
- expect(task_class.provider.config).to eq(
57
+ expect(task_class.provider.config).to include(
117
58
  api_key: "test",
118
- model: "gpt-3.5-turbo"
59
+ model: Lluminary::Models::OpenAi::Gpt35Turbo
60
+ )
61
+ end
62
+
63
+ it "with :bedrock instantiates Bedrock provider with config" do
64
+ task_class.use_provider(
65
+ :bedrock,
66
+ access_key_id: "test",
67
+ secret_access_key: "test",
68
+ region: "us-east-1"
69
+ )
70
+ expect(task_class.provider).to be_a(Lluminary::Providers::Bedrock)
71
+ expect(task_class.provider.config).to include(
72
+ access_key_id: "test",
73
+ secret_access_key: "test",
74
+ region: "us-east-1",
75
+ model: Lluminary::Models::Bedrock::AnthropicClaudeInstantV1
119
76
  )
120
77
  end
121
78
 
@@ -127,487 +84,6 @@ RSpec.describe Lluminary::Task do
127
84
  end
128
85
  end
129
86
 
130
- describe "#json_schema_example" do
131
- it "generates a schema example with descriptions" do
132
- task = task_class.new(message: "test")
133
- expected_output = <<~SCHEMA
134
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
135
- The JSON object must contain the following fields:
136
-
137
- summary (string): A brief summary of the message
138
- Example: "your summary here"
139
-
140
- Your response must be ONLY this JSON object:
141
- {
142
- "summary": "your summary here"
143
- }
144
- SCHEMA
145
- expect(task.send(:json_schema_example)).to eq(expected_output.chomp)
146
- end
147
-
148
- it "generates a schema example with datetime field" do
149
- task_with_datetime =
150
- Class.new(described_class) do
151
- input_schema { string :message }
152
-
153
- output_schema do
154
- datetime :start_time, description: "When the event starts"
155
- end
156
-
157
- private
158
-
159
- def task_prompt
160
- "Say: #{message}"
161
- end
162
- end
163
-
164
- task = task_with_datetime.new(message: "test")
165
- expected_output = <<~SCHEMA
166
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
167
- The JSON object must contain the following fields:
168
-
169
- start_time (datetime in ISO8601 format): When the event starts
170
- Example: "2024-01-01T12:00:00+00:00"
171
-
172
- Your response must be ONLY this JSON object:
173
- {
174
- "start_time": "2024-01-01T12:00:00+00:00"
175
- }
176
- SCHEMA
177
- expect(task.send(:json_schema_example)).to eq(expected_output.chomp)
178
- end
179
-
180
- it "generates a schema example with boolean field" do
181
- task_with_boolean =
182
- Class.new(described_class) do
183
- input_schema { string :message }
184
-
185
- output_schema do
186
- boolean :is_valid, description: "Whether the input is valid"
187
- end
188
-
189
- private
190
-
191
- def task_prompt
192
- "Say: #{message}"
193
- end
194
- end
195
-
196
- task = task_with_boolean.new(message: "test")
197
- expected_output = <<~SCHEMA
198
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
199
- The JSON object must contain the following fields:
200
-
201
- is_valid (boolean): Whether the input is valid
202
- Example: true
203
-
204
- Your response must be ONLY this JSON object:
205
- {
206
- "is_valid": true
207
- }
208
- SCHEMA
209
- expect(task.send(:json_schema_example)).to eq(expected_output.chomp)
210
- end
211
-
212
- it "generates a schema example with float field" do
213
- task_with_float =
214
- Class.new(described_class) do
215
- input_schema { string :message }
216
-
217
- output_schema { float :score, description: "The confidence score" }
218
-
219
- private
220
-
221
- def task_prompt
222
- "Say: #{message}"
223
- end
224
- end
225
-
226
- task = task_with_float.new(message: "test")
227
- expected_output = <<~SCHEMA
228
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
229
- The JSON object must contain the following fields:
230
-
231
- score (float): The confidence score
232
- Example: 0.0
233
-
234
- Your response must be ONLY this JSON object:
235
- {
236
- "score": 0.0
237
- }
238
- SCHEMA
239
- expect(task.send(:json_schema_example)).to eq(expected_output.chomp)
240
- end
241
-
242
- it "generates a schema example without descriptions" do
243
- task_without_descriptions =
244
- Class.new(described_class) do
245
- input_schema { string :message }
246
-
247
- output_schema { string :summary }
248
-
249
- private
250
-
251
- def task_prompt
252
- "Say: #{message}"
253
- end
254
- end
255
-
256
- task = task_without_descriptions.new(message: "test")
257
- expected_output = <<~SCHEMA
258
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
259
- The JSON object must contain the following fields:
260
-
261
- summary (string)
262
- Example: "your summary here"
263
-
264
- Your response must be ONLY this JSON object:
265
- {
266
- "summary": "your summary here"
267
- }
268
- SCHEMA
269
- expect(task.send(:json_schema_example)).to eq(expected_output.chomp)
270
- end
271
-
272
- context "validation descriptions" do
273
- context "presence validation" do
274
- it "includes presence validation description" do
275
- task_class =
276
- Class.new(described_class) do
277
- output_schema do
278
- string :name, description: "The person's name"
279
- validates :name, presence: true
280
- end
281
-
282
- private
283
-
284
- def task_prompt = "Test prompt"
285
- end
286
-
287
- task = task_class.new
288
- expect(task.send(:json_schema_example)).to include(
289
- "name (string): The person's name\nValidation: must be present\nExample: \"your name here\""
290
- )
291
- end
292
- end
293
-
294
- context "length validation" do
295
- it "includes minimum length validation description" do
296
- task_class =
297
- Class.new(described_class) do
298
- output_schema do
299
- string :name, description: "The person's name"
300
- validates :name, length: { minimum: 2 }
301
- end
302
-
303
- private
304
-
305
- def task_prompt = "Test prompt"
306
- end
307
-
308
- task = task_class.new
309
- expect(task.send(:json_schema_example)).to include(
310
- "name (string): The person's name\nValidation: must be at least 2 characters\nExample: \"your name here\""
311
- )
312
- end
313
-
314
- it "includes maximum length validation description" do
315
- task_class =
316
- Class.new(described_class) do
317
- output_schema do
318
- string :name, description: "The person's name"
319
- validates :name, length: { maximum: 20 }
320
- end
321
-
322
- private
323
-
324
- def task_prompt = "Test prompt"
325
- end
326
-
327
- task = task_class.new
328
- expect(task.send(:json_schema_example)).to include(
329
- "name (string): The person's name\nValidation: must be at most 20 characters\nExample: \"your name here\""
330
- )
331
- end
332
-
333
- it "includes range length validation description" do
334
- task_class =
335
- Class.new(described_class) do
336
- output_schema do
337
- string :password, description: "The password"
338
- validates :password, length: { in: 8..20 }
339
- end
340
-
341
- private
342
-
343
- def task_prompt = "Test prompt"
344
- end
345
-
346
- task = task_class.new
347
- expect(task.send(:json_schema_example)).to include(<<~DESCRIPTION)
348
- password (string): The password
349
- Validation: must be between 8 and 20 characters
350
- Example: "your password here"
351
- DESCRIPTION
352
- end
353
-
354
- it "includes multiple length validations in description" do
355
- task_class =
356
- Class.new(described_class) do
357
- output_schema do
358
- string :username, description: "The username"
359
- validates :username, length: { minimum: 3, maximum: 20 }
360
- end
361
-
362
- private
363
-
364
- def task_prompt = "Test prompt"
365
- end
366
-
367
- task = task_class.new
368
- expect(task.send(:json_schema_example)).to include(<<~DESCRIPTION)
369
- username (string): The username
370
- Validation: must be at least 3 characters, must be at most 20 characters
371
- Example: "your username here"
372
- DESCRIPTION
373
- end
374
- end
375
-
376
- context "numericality validation" do
377
- it "includes odd validation description" do
378
- task_class =
379
- Class.new(described_class) do
380
- output_schema do
381
- integer :number, description: "Odd number"
382
- validates :number, numericality: { odd: true }
383
- end
384
-
385
- private
386
-
387
- def task_prompt = "Test prompt"
388
- end
389
-
390
- task = task_class.new
391
- expect(task.send(:json_schema_example)).to include(
392
- "number (integer): Odd number\nValidation: must be odd\nExample: 0"
393
- )
394
- end
395
-
396
- it "includes equal to validation description" do
397
- task_class =
398
- Class.new(described_class) do
399
- output_schema do
400
- integer :level, description: "Level"
401
- validates :level, numericality: { equal_to: 5 }
402
- end
403
-
404
- private
405
-
406
- def task_prompt = "Test prompt"
407
- end
408
-
409
- task = task_class.new
410
- expect(task.send(:json_schema_example)).to include(
411
- "level (integer): Level\nValidation: must be equal to 5\nExample: 0"
412
- )
413
- end
414
-
415
- it "includes less than or equal to validation description" do
416
- task_class =
417
- Class.new(described_class) do
418
- output_schema do
419
- integer :score, description: "Score"
420
- validates :score, numericality: { less_than_or_equal_to: 100 }
421
- end
422
-
423
- private
424
-
425
- def task_prompt = "Test prompt"
426
- end
427
-
428
- task = task_class.new
429
- expect(task.send(:json_schema_example)).to include(
430
- "score (integer): Score\nValidation: must be less than or equal to 100\nExample: 0"
431
- )
432
- end
433
-
434
- it "includes other than validation description" do
435
- task_class =
436
- Class.new(described_class) do
437
- output_schema do
438
- integer :value, description: "Value"
439
- validates :value, numericality: { other_than: 0 }
440
- end
441
-
442
- private
443
-
444
- def task_prompt = "Test prompt"
445
- end
446
-
447
- task = task_class.new
448
- expect(task.send(:json_schema_example)).to include(
449
- "value (integer): Value\nValidation: must be other than 0\nExample: 0"
450
- )
451
- end
452
-
453
- it "includes in range validation description" do
454
- task_class =
455
- Class.new(described_class) do
456
- output_schema do
457
- integer :rating, description: "Rating"
458
- validates :rating, numericality: { in: 1..5 }
459
- end
460
-
461
- private
462
-
463
- def task_prompt = "Test prompt"
464
- end
465
-
466
- task = task_class.new
467
- expect(task.send(:json_schema_example)).to include(
468
- "rating (integer): Rating\nValidation: must be in: 1, 2, 3, 4, 5\nExample: 0"
469
- )
470
- end
471
-
472
- it "includes multiple numericality validations in description" do
473
- task_class =
474
- Class.new(described_class) do
475
- output_schema do
476
- integer :score, description: "Score"
477
- validates :score,
478
- numericality: {
479
- greater_than: 0,
480
- less_than_or_equal_to: 100
481
- }
482
- end
483
-
484
- private
485
-
486
- def task_prompt = "Test prompt"
487
- end
488
-
489
- task = task_class.new
490
- expect(task.send(:json_schema_example)).to include(
491
- "score (integer): Score\nValidation: must be greater than 0, must be less than or equal to 100\nExample: 0"
492
- )
493
- end
494
-
495
- it "includes multiple comparison validations in description" do
496
- task_class =
497
- Class.new(described_class) do
498
- output_schema do
499
- integer :age, description: "Age"
500
- validates :age, comparison: { greater_than: 0, less_than: 120 }
501
- end
502
-
503
- private
504
-
505
- def task_prompt = "Test prompt"
506
- end
507
-
508
- task = task_class.new
509
- expect(task.send(:json_schema_example)).to include(
510
- "age (integer): Age\nValidation: must be greater than 0, must be less than 120\nExample: 0"
511
- )
512
- end
513
- end
514
-
515
- context "format validation" do
516
- it "includes format validation description" do
517
- task_class =
518
- Class.new(described_class) do
519
- output_schema do
520
- string :email, description: "Email address"
521
- validates :email, format: { with: /\A[^@\s]+@[^@\s]+\z/ }
522
- end
523
-
524
- private
525
-
526
- def task_prompt = "Test prompt"
527
- end
528
-
529
- task = task_class.new
530
- expect(task.send(:json_schema_example)).to eq(<<~SCHEMA.chomp)
531
- You must respond with ONLY a valid JSON object. Do not include any other text, explanations, or formatting.
532
- The JSON object must contain the following fields:
533
-
534
- email (string): Email address
535
- Validation: must match format: (?-mix:\\A[^@\\s]+@[^@\\s]+\\z)
536
- Example: "your email here"
537
-
538
- Your response must be ONLY this JSON object:
539
- {
540
- "email": "your email here"
541
- }
542
- SCHEMA
543
- end
544
- end
545
-
546
- context "inclusion validation" do
547
- it "includes inclusion validation description" do
548
- task_class =
549
- Class.new(described_class) do
550
- output_schema do
551
- string :role, description: "User role"
552
- validates :role, inclusion: { in: %w[admin user guest] }
553
- end
554
-
555
- private
556
-
557
- def task_prompt = "Test prompt"
558
- end
559
-
560
- task = task_class.new
561
- expect(task.send(:json_schema_example)).to include(
562
- "role (string): User role\nValidation: must be one of: admin, user, guest\nExample: \"your role here\""
563
- )
564
- end
565
- end
566
-
567
- context "exclusion validation" do
568
- it "includes exclusion validation description" do
569
- task_class =
570
- Class.new(described_class) do
571
- output_schema do
572
- string :status, description: "Status"
573
- validates :status, exclusion: { in: %w[banned blocked] }
574
- end
575
-
576
- private
577
-
578
- def task_prompt = "Test prompt"
579
- end
580
-
581
- task = task_class.new
582
- expect(task.send(:json_schema_example)).to include(
583
- "status (string): Status\nValidation: must not be one of: banned, blocked\nExample: \"your status here\""
584
- )
585
- end
586
- end
587
-
588
- context "absence validation" do
589
- it "includes absence validation description" do
590
- task_class =
591
- Class.new(described_class) do
592
- output_schema do
593
- string :deleted_at, description: "Deletion timestamp"
594
- validates :deleted_at, absence: true
595
- end
596
-
597
- private
598
-
599
- def task_prompt = "Test prompt"
600
- end
601
-
602
- task = task_class.new
603
- expect(task.send(:json_schema_example)).to include(
604
- "deleted_at (string): Deletion timestamp\nValidation: must be absent\nExample: \"your deleted_at here\""
605
- )
606
- end
607
- end
608
- end
609
- end
610
-
611
87
  describe "#validate_input" do
612
88
  let(:task_with_types) do
613
89
  Class.new(described_class) do
@@ -617,8 +93,6 @@ RSpec.describe Lluminary::Task do
617
93
  datetime :start_time
618
94
  end
619
95
 
620
- private
621
-
622
96
  def task_prompt
623
97
  "Test prompt"
624
98
  end
@@ -690,8 +164,6 @@ RSpec.describe Lluminary::Task do
690
164
  integer :word_count
691
165
  end
692
166
 
693
- private
694
-
695
167
  def task_prompt
696
168
  "Test prompt"
697
169
  end
@@ -761,8 +233,6 @@ RSpec.describe Lluminary::Task do
761
233
  string :author, description: "The person who said the quote"
762
234
  end
763
235
 
764
- private
765
-
766
236
  def task_prompt
767
237
  "Generate an inspirational quote and its author"
768
238
  end
@@ -792,8 +262,6 @@ RSpec.describe Lluminary::Task do
792
262
  datetime :event_time, description: "When the event occurred"
793
263
  end
794
264
 
795
- private
796
-
797
265
  def task_prompt
798
266
  "Test prompt"
799
267
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ require "dotenv"
3
3
  Dotenv.load
4
4
 
5
5
  require "lluminary"
6
+ require "pry-byebug"
6
7
 
7
8
  RSpec.configure do |config|
8
9
  config.before(:each) { Lluminary.reset_configuration }