ox-ai-workers 0.9.6 → 0.9.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09fdb6954c507cc0d70433141a70a4974b42feb625719c525d2b7c093d9e1ce5'
4
- data.tar.gz: e93b4e8040e831c73d8dd0379466f70e48eafd07513d7e78fee3f19985ef4331
3
+ metadata.gz: 768550f6fde8e654917a2b01404856abcbe643429ba725d7c86c853b472f4bed
4
+ data.tar.gz: 9444f8c6869caa2e7039d3632605885579364942de95ba2fa6b201d5ca00c3e5
5
5
  SHA512:
6
- metadata.gz: c7b1f5a861cc8b4536fd22d6dbe479f0886ebb260317d585bf80ba19c0b1e5dbb6d9c5998ab1e25f367a112a5a7e3dce6bca1a48d2edecb9a6db8af3aa19b1bb
7
- data.tar.gz: d7e64a09aa0351a62fdb74c52a25c99db79a4fd7c2765001cd715e8ac32deb6cd2b81aef5e385e57c66aa4b9fb3ef616145eb7953e5eefadc3321ae9678e697f
6
+ metadata.gz: 6a0c8f3622ab30d8a199b367ad3b0bab3c985a292cc786d3c38380515b5adbe02b945eaff4606073b199a59bf4237bb36c86a0a89b07f6c62c0bc0b738ed7593
7
+ data.tar.gz: 491720defa83f4b26cccc0d389975f1125c8636821c37314814fdbe9bf714d9233f22456a09b2f8ec890e2b52d3fcb96065295563b1272336316f34461fe6667
data/README.md CHANGED
@@ -88,6 +88,7 @@ For a more robust setup, you can configure the gem with your API keys, for examp
88
88
  OxAiWorkers.configure do |config|
89
89
  config.access_token_openai = ENV.fetch("OPENAI")
90
90
  config.access_token_deepseek = ENV.fetch("DEEPSEEK")
91
+ config.access_token_stability = ENV.fetch("STABILITY")
91
92
  config.max_tokens = 4096 # Default
92
93
  config.temperature = 0.7 # Default
93
94
  config.wait_for_complete = true # Default
@@ -420,10 +421,50 @@ image_data = File.read('local_image.jpg')
420
421
  iterator.add_image(
421
422
  text: 'Image from binary data',
422
423
  binary: image_data,
423
- mime_type: 'image/jpeg' # Defaults to 'image/jpeg'
424
+ mime_type: 'image/jpeg' # Defaults to 'image/png'
424
425
  )
425
426
  ```
426
427
 
428
+ #### Image Input Requirements
429
+
430
+ When using images with the API, your input images must meet the following requirements:
431
+
432
+ **Supported file types:**
433
+
434
+ - PNG (.png)
435
+ - JPEG (.jpeg and .jpg)
436
+ - WEBP (.webp)
437
+ - Non-animated GIF (.gif)
438
+
439
+ **Size limits:**
440
+
441
+ - Up to 20MB per image
442
+ - Low-resolution: 512px x 512px
443
+ - High-resolution: 768px (short side) x 2000px (long side)
444
+
445
+ **Other requirements:**
446
+
447
+ - No watermarks or logos
448
+ - No text
449
+ - No NSFW content
450
+ - Clear enough for a human to understand
451
+
452
+ **Image detail level:**
453
+
454
+ The `detail` parameter controls what level of detail the model uses when processing the image:
455
+
456
+ ```ruby
457
+ iterator.add_image(
458
+ text: 'Nature boardwalk image',
459
+ url: 'https://example.com/nature.jpg',
460
+ detail: 'high' # Options: 'auto', 'low', or 'high'
461
+ )
462
+ ```
463
+
464
+ - `detail: 'low'`: Uses less tokens (85) and processes a low-resolution 512px x 512px version of the image. Best for simple use cases like identifying dominant colors or shapes.
465
+ - `detail: 'high'`: Provides better image understanding for complex tasks requiring higher resolution detail.
466
+ - `detail: 'auto'`: Lets the model decide the appropriate detail level (default if not specified).
467
+
427
468
  ### Handling State Transitions with Callbacks
428
469
 
429
470
  You can track and respond to state transitions with callbacks:
@@ -519,7 +560,7 @@ OxAiWorkers provides several specialized tools to extend functionality:
519
560
  pixels = OxAiWorkers::Tool::Pixels.new(
520
561
  worker: worker, # Required: Request or DelayedRequest instance
521
562
  current_dir: Dir.pwd, # Optional: Directory to save generated images
522
- image_model: 'dall-e-3', # Optional: 'dall-e-3' or 'gpt-image-1'
563
+ image_model: OxAiWorkers::Models::StabilityImages.new, # Optional, default is OpenaiDalle3
523
564
  only: [:generate_image] # Optional: Limit available functions
524
565
  )
525
566
  ```
@@ -654,6 +695,92 @@ module OxAiWorkers
654
695
  end
655
696
  ```
656
697
 
698
+ ## Image Generation
699
+
700
+ OxAiWorkers supports image generation through the Painter assistant and Pixels tool, with multiple AI image generation models.
701
+
702
+ ### Supported Image Models
703
+
704
+ - **OpenaiDalle3** - OpenAI's DALL-E 3 model
705
+ - **OpenaiGptImage** - OpenAI's GPT-Image-1 model
706
+ - **StabilityImages** - Stability AI's image generation models
707
+
708
+ ### Using the Painter Assistant
709
+
710
+ ```ruby
711
+ # Using DALL-E 3 (default)
712
+ painter = OxAiWorkers::Assistant::Painter.new(current_dir: Dir.pwd)
713
+ painter.task = "Create an image of a sunset over mountains"
714
+
715
+ # Using GPT-Image-1
716
+ painter = OxAiWorkers::Assistant::Painter.new(
717
+ image_model: OxAiWorkers::Models::OpenaiGptImage.new,
718
+ current_dir: Dir.pwd
719
+ )
720
+ painter.task = "Generate a photorealistic red apple"
721
+
722
+ # Using Stability AI
723
+ painter = OxAiWorkers::Assistant::Painter.new(
724
+ image_model: OxAiWorkers::Models::StabilityImages.new,
725
+ current_dir: Dir.pwd
726
+ )
727
+ painter.task = "Create a fantasy landscape with dragons"
728
+ ```
729
+
730
+ ### Using the Pixels Tool Directly
731
+
732
+ For more direct control over image generation:
733
+
734
+ ```ruby
735
+ # Initialize with DALL-E 3
736
+ pixels = OxAiWorkers::Tool::Pixels.new(
737
+ worker: OxAiWorkers::Models::OpenaiDalle3.new,
738
+ current_dir: Dir.pwd
739
+ )
740
+ pixels.generate_image(
741
+ prompt: "A photorealistic red apple on a wooden table",
742
+ file_name: "apple.png",
743
+ size: "1024x1024",
744
+ quality: "hd"
745
+ )
746
+
747
+ # Initialize with GPT-Image-1
748
+ pixels = OxAiWorkers::Tool::Pixels.new(
749
+ worker: OxAiWorkers::Models::OpenaiGptImage.new,
750
+ current_dir: Dir.pwd
751
+ )
752
+ pixels.generate_image(
753
+ prompt: "Futuristic cityscape at night",
754
+ file_name: "city.png",
755
+ size: "1536x1024",
756
+ quality: "high"
757
+ )
758
+
759
+ # Initialize with Stability AI
760
+ pixels = OxAiWorkers::Tool::Pixels.new(
761
+ worker: OxAiWorkers::Models::StabilityImages.new,
762
+ current_dir: Dir.pwd
763
+ )
764
+ pixels.generate_image(
765
+ prompt: "Photorealistic mountain landscape",
766
+ file_name: "mountains.png"
767
+ )
768
+ ```
769
+
770
+ ### Model-Specific Features
771
+
772
+ - **OpenaiDalle3**
773
+ - Sizes: '1024x1024', '1024x1792', '1792x1024'
774
+ - Qualities: 'standard', 'hd'
775
+
776
+ - **OpenaiGptImage**
777
+ - Sizes: 'auto', '1024x1024', '1536x1024', '1024x1536'
778
+ - Qualities: 'auto', 'low', 'medium', 'high'
779
+
780
+ - **StabilityImages**
781
+ - Uses Stability AI's API with different engine options
782
+ - Configuration via options parameter
783
+
657
784
  ## Contributing
658
785
 
659
786
  Bug reports and pull requests are welcome on GitHub at <https://github.com/neonix20b/ox-ai-workers>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/neonix20b/ox-ai-workers/blob/main/CODE_OF_CONDUCT.md).
@@ -29,12 +29,6 @@ module OxAiWorkers
29
29
  on_outer_voice: ->(text:) { puts "voice: #{text}".colorize(:green) }
30
30
  )
31
31
  end
32
-
33
- def cleanup
34
- Dir.glob(File.join(@current_dir, '*.png')).each do |file|
35
- File.delete(file) if File.exist?(file)
36
- end
37
- end
38
32
  end
39
33
  end
40
34
  end
@@ -266,7 +266,7 @@ module OxAiWorkers
266
266
  add_raw_context({ role:, content: })
267
267
  end
268
268
 
269
- def add_image(text:, url: nil, binary: nil, role: :user, detail: 'auto', mime_type: 'image/jpeg')
269
+ def add_image(text:, url: nil, binary: nil, role: :user, detail: 'auto', mime_type: 'image/png')
270
270
  content = []
271
271
  content << { type: 'text', text: } if text.present?
272
272
 
@@ -53,10 +53,11 @@ module OxAiWorkers
53
53
  frequency_penalty: @model.frequency_penalty
54
54
  }
55
55
  if @tools.present?
56
- parameters[:tools] = @tools.reject do |f|
56
+ parameters[:tools] = @tools.select do |f|
57
57
  tool_name = f[:function][:name]
58
58
  tool_name == @last_call && @stop_double_calls.include?(tool_name)
59
59
  end
60
+ OxAiWorkers.logger.debug("tools: #{parameters[:tools]} last_call=#{@last_call} stop_double_calls=#{@stop_double_calls}", for: self.class)
60
61
  if @call_stack&.any?
61
62
  func1 = @call_stack.first
62
63
  @call_stack = @call_stack.drop(1)
@@ -146,7 +147,7 @@ module OxAiWorkers
146
147
  name: function['name'].split('__').last,
147
148
  args: args
148
149
  }
149
- @last_call = function['name']
150
+ @last_call = function['name'].to_s
150
151
  end
151
152
  end
152
153
  end
@@ -62,29 +62,9 @@ module OxAiWorkers
62
62
  end
63
63
  end
64
64
 
65
- def edit_image(input_image:, prompt:, output_file_name: nil, size: nil, mask: nil)
66
- size ||= @image_model['size'].first
67
- mask ||= @mask
68
-
69
- response = @worker.client.images.edit(
70
- parameters: {
71
- image: input_image,
72
- model: @image_model['model'],
73
- prompt:,
74
- size:,
75
- mask:
76
- }
77
- )
78
-
79
- @url = response.dig('data', 0, 'url')
80
- revised_prompt = response.dig('data', 0, 'revised_prompt')
81
- if output_file_name.present?
82
- path = save_generated_image(file_name: output_file_name)
83
- "url: #{@url}\nfile_name: #{path}\n\nrevised_prompt: #{revised_prompt}"
84
- else
85
- "url: #{@url}\n\nrevised_prompt: #{revised_prompt}"
86
- end
87
- end
65
+ # def edit_image(input_image:, prompt:, output_file_name: nil, size: nil, mask: nil)
66
+ # # TODO: Implement edit_image
67
+ # end
88
68
 
89
69
  def save_generated_image(file_name:, binary:)
90
70
  unless @current_dir.present?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OxAiWorkers
4
- VERSION = '0.9.6'
4
+ VERSION = '0.9.6.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox-ai-workers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Smolev