ox-ai-workers 1.1.0.2 → 1.1.1.2

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: 4afc56ab5707889f6c7f49b2efbc78d7506d9b15fed6ecdd3532fe5be830d3f9
4
- data.tar.gz: 1adf7f70b822a9abb734a0f79b4ae08424649c8e8ce18d38bdf03295a75b169f
3
+ metadata.gz: 88cf2322e5e5f9f67360a09801767f58b5a926411e24a53fd03887e035c2c2d7
4
+ data.tar.gz: 0da9e2585f0e347cc193aee650fcec6b6458a091869f9bd4af6e857cc9c30aec
5
5
  SHA512:
6
- metadata.gz: 55bae419790315cd87157cce6c96fa533baa55f54f8c2d8fb06026c23d871103d6e00d05259e626dfbf59df380e61e004f4e2db56ded769887f87dd6ea40fe78
7
- data.tar.gz: fe625123a64b4707698028514b68078587b4a849fe84cc1e8b68dcd66f60ccee7342ca94ecb15d0fc511b5bfc666705ad78f9cb0bcc6107dce73907744e619a9
6
+ metadata.gz: 3f060a38af2fca2f37a01cc44cc19e573565852b735571882a53c9376d4b81d37f77b848fbd6ebd5cf42e71ba3a68045ea021ab967cd140af2a83c22872e6056
7
+ data.tar.gz: 7cdd9fc305a3e2498a14cf81949abfc38fafa6845378f42c431c65591259f4cd931fa21dbaefda72156ee0dc3644ecc98b2673d15d3676a65a405b61f019ac76
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [1.1.1] - 2025-05-26
2
+
3
+ - Removed task appending in `Iterator`
4
+
1
5
  ## [1.1.0] - 2025-05-21
2
6
 
3
7
  - Added `add_base64` and `add_url` for Models
@@ -264,15 +264,15 @@ module OxAiWorkers
264
264
  add_raw_context({ role:, content: text })
265
265
  end
266
266
 
267
- def add_file(pdf:, filename:, text:, role: :user)
268
- content = @worker.model.add_base64(binary: pdf, filename:, text:, mime_type: 'application/pdf')
267
+ def add_file(pdf:, text:, role: :user)
268
+ content = @worker.model.add_base64(binary: pdf, text:, mime_type: 'application/pdf')
269
269
  add_raw_context({ role:, content: })
270
270
  end
271
271
 
272
272
  def add_image(text:, url: nil, binary: nil, role: :user, detail: 'auto', mime_type: 'image/png')
273
273
  content = []
274
274
  if binary.present?
275
- content = @worker.model.add_base64(binary:, filename:, text:, mime_type:, detail:)
275
+ content = @worker.model.add_base64(binary:, text:, mime_type:, detail:)
276
276
  elsif url.present?
277
277
  content = @worker.model.add_url(url:, text:, detail:, mime_type:)
278
278
  end
@@ -70,7 +70,7 @@ module OxAiWorkers
70
70
  ]
71
71
  end
72
72
 
73
- def add_base64(binary:, filename:, text:, mime_type:)
73
+ def add_base64(binary:, text:, mime_type:, detail:)
74
74
  content = []
75
75
  content << { type: 'text', text: } if text.present?
76
76
  content << {
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OxAiWorkers
4
+ module Models
5
+ class GeminiPro < LLMBase
6
+ def initialize(uri_base: nil, api_key: nil, model: nil, max_tokens: nil, temperature: nil, frequency_penalty: nil)
7
+ @model = model || 'gemini-pro'
8
+ @uri_base = uri_base # || 'https://api.anthropic.com/v1/'
9
+ @api_key = api_key || OxAiWorkers.configuration.access_token_gemini
10
+ super(uri_base: @uri_base, api_key: @api_key, model: @model, max_tokens:, temperature:, frequency_penalty:)
11
+ end
12
+
13
+ def client
14
+ Gemini.new(
15
+ credentials: {
16
+ service: 'generative-language-api',
17
+ api_key: ENV['GOOGLE_API_KEY']
18
+ },
19
+ options: { model: 'gemini-pro', server_sent_events: true }
20
+ )
21
+ end
22
+
23
+ def request(parameters)
24
+ client.messages(parameters:)
25
+ end
26
+
27
+ def build_parameters(messages:, tools: [], filtered_functions: [], tool_choice: nil)
28
+ parameters = {
29
+ model: @model,
30
+ system: messages.select { |m| m[:role] == :system }.map { |m| m[:content] }.join("\n\n"),
31
+ messages: messages.reject { |m| m[:role] == :system },
32
+ temperature: @temperature,
33
+ max_tokens: @max_tokens
34
+ }
35
+ if tools.present?
36
+ functions = tools.map(&:to_anthropic_format).flatten
37
+
38
+ @names = functions.map { |f| f[:name] }
39
+
40
+ parameters[:tools] = functions.reject { |f| filtered_functions.include?(f[:name]) }
41
+
42
+ parameters[:tool_choice] =
43
+ tool_choice.nil? ? { type: 'any' } : { type: 'tool', name: tool_choice }
44
+ end
45
+ parameters
46
+ end
47
+
48
+ def tool_call(name:, args:, call_id:, out:)
49
+ [
50
+ {
51
+ role: :assistant,
52
+ content: [
53
+ {
54
+ type: 'tool_use',
55
+ id: "call_#{call_id}",
56
+ name:,
57
+ input: args
58
+ }
59
+ ]
60
+ },
61
+ {
62
+ role: :user,
63
+ content: [
64
+ {
65
+ type: 'tool_result',
66
+ tool_use_id: "call_#{call_id}",
67
+ content: out.present? ? out : "Tool call #{name} successful."
68
+ }
69
+ ]
70
+ }
71
+ ]
72
+ end
73
+
74
+ def add_base64(binary:, filename:, text:, mime_type:)
75
+ content = []
76
+ content << { type: 'text', text: } if text.present?
77
+ content << {
78
+ type: mime_type.include?('image') ? 'image' : 'document',
79
+ source: {
80
+ type: 'base64',
81
+ media_type: mime_type,
82
+ data: Base64.strict_encode64(binary)
83
+ }
84
+ }
85
+ content
86
+ end
87
+
88
+ def add_url(url:, text:, mime_type:)
89
+ content = []
90
+ content << { type: 'text', text: } if text.present?
91
+ content << {
92
+ type: mime_type.include?('image') ? 'image' : 'document',
93
+ source: {
94
+ type: 'url',
95
+ url: url
96
+ }
97
+ }
98
+ content
99
+ end
100
+
101
+ def parse_response(response, &)
102
+ choices = response['content']
103
+ @is_truncated = (response['stop_reason'] == 'max_tokens')
104
+ return if choices.nil? || choices.empty?
105
+
106
+ choices.each do |choice|
107
+ result, tool_calls = parse_one_choice(choice)
108
+ yield(result, @is_truncated, tool_calls)
109
+ end
110
+ end
111
+
112
+ def parse_one_choice(choice)
113
+ return unless choice # Skip if there's no choice
114
+
115
+ # Initialize result variables
116
+ @result = nil
117
+ @tool_calls = []
118
+
119
+ # Process content item
120
+ if choice['type'] == 'tool_use'
121
+ # Handle tool use
122
+ begin
123
+ # Attempt to parse arguments, handle potential JSON errors
124
+ args = JSON.parse(choice['input'].to_json, symbolize_names: true)
125
+ rescue JSON::ParserError => e
126
+ OxAiWorkers.logger.error("Failed to parse tool call arguments: #{e.message}", for: self.class)
127
+ OxAiWorkers.logger.debug("Raw arguments: #{choice['input']}", for: self.class)
128
+ end
129
+
130
+ fname = @names.find { |n| n.end_with?(choice['name']) }
131
+ if fname != choice['name']
132
+ OxAiWorkers.logger.error("Tool call name #{choice['name']} not found. Using #{fname} instead.",
133
+ for: self.class)
134
+ end
135
+
136
+ tool_call = {
137
+ class: fname.split('__').first,
138
+ name: fname.split('__').last,
139
+ args:
140
+ }
141
+ @tool_calls << tool_call
142
+ elsif choice['type'] == 'text'
143
+ # Handle text content
144
+ @result = choice['text']
145
+ end
146
+
147
+ [@result, @tool_calls]
148
+ end
149
+ end
150
+ end
151
+ end
@@ -66,7 +66,7 @@ module OxAiWorkers
66
66
  ]
67
67
  end
68
68
 
69
- def add_base64(binary:, filename:, text:, mime_type:, detail: 'auto')
69
+ def add_base64(binary:, text:, mime_type:, detail: 'auto')
70
70
  content = []
71
71
  content << { type: 'text', text: } if text.present?
72
72
  content << if mime_type.include?('image')
@@ -80,7 +80,7 @@ module OxAiWorkers
80
80
  {
81
81
  type: 'file',
82
82
  file: {
83
- filename:,
83
+ filename: "file.#{mime_type.split('/').last}",
84
84
  file_data: "data:#{mime_type};base64,#{Base64.strict_encode64(binary)}"
85
85
  }
86
86
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OxAiWorkers
4
- VERSION = '1.1.0.2'
4
+ VERSION = '1.1.1.2'
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: 1.1.0.2
4
+ version: 1.1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Smolev
@@ -159,6 +159,7 @@ files:
159
159
  - lib/oxaiworkers/load_i18n.rb
160
160
  - lib/oxaiworkers/models/anthropic_max.rb
161
161
  - lib/oxaiworkers/models/deepseek_max.rb
162
+ - lib/oxaiworkers/models/gemini_pro.rb
162
163
  - lib/oxaiworkers/models/images_base.rb
163
164
  - lib/oxaiworkers/models/llm_base.rb
164
165
  - lib/oxaiworkers/models/openai_dalle3.rb