intelligence 0.8.0 → 1.0.0.beta02

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35084b4f3df27ee21c0a21a759b74bcca9c05c6b47e0311026d6e6587f8661a3
4
- data.tar.gz: 76afc7ad3e1f2e3637c82e8613b492680be20962ca5daf263d3c457968512c04
3
+ metadata.gz: e92ea1646a9ec5f91a9a8e991c838896c415a94715aeeccd7013363e34009b1b
4
+ data.tar.gz: 67b7fcb6020325d405e463ab2efbc18b44c772e94b76d3ce622fc652de7b4c18
5
5
  SHA512:
6
- metadata.gz: 643f9acfde921655b5861901f5ea11646d00e9673a852e8546ec112a275d9f4e695934c314c577ca5cf44684ee3ce86b57cb5da9100e67b5c016c3bd90672f14
7
- data.tar.gz: 6a9bb70335d3cd9f5b5ef48f1029e8b7997d880a1ebed37168c6d5cae88ec4abb48c2c8ffb95ef63c5b4b82a0e5c00904b0320321c124d8cf24fabb1928e5453
6
+ metadata.gz: 107cb5ddec885d6700b88742474e2948e2abc94da6500b0b1fb39d039c8292fbd648efe4e67b2866d918107759ac111a15de949b3256dc8d2049df52af6cd792
7
+ data.tar.gz: 5052f6057fafd04bd1c310f67de4a89dbbea32f8c279ec5e2bdbd397378629e1cff17ce853774881c0736ee0f9407a5dfd25b63aab9750955737885f8829c489
@@ -104,7 +104,7 @@ module Intelligence
104
104
 
105
105
  tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
106
106
  result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
107
-
107
+
108
108
  JSON.generate( result )
109
109
  end
110
110
 
@@ -35,6 +35,19 @@ module Intelligence
35
35
  response_mime_type String, as: :responseMimeType
36
36
  response_schema as: :responseSchema
37
37
 
38
+ # google tools setup
39
+ tools do
40
+ google_search as: :google_search_retrieval do
41
+ dynamic_retrieval as: :dynamic_retrieval_config, default: {} do
42
+ mode String, default: 'MODE_DYNAMIC'
43
+ threshold Float, as: :dynamic_threshold, in: 0..1, default: 0.3
44
+ end
45
+ end
46
+
47
+ code_execution do
48
+ end
49
+ end
50
+
38
51
  # google specific tool configuration
39
52
  tool_configuration as: :tool_config do
40
53
  function_calling as: :function_calling_config do
@@ -61,16 +61,33 @@ module Intelligence
61
61
  # discard properties not part of the google generationConfig schema
62
62
  gc.delete( :model )
63
63
  gc.delete( :stream )
64
-
64
+
65
+ # googlify tools
66
+ tools = gc.delete( :tools )
67
+ if tools&.any?
68
+ tools = tools.then do | tools_object |
69
+ tools_array ||= []
70
+ tools_object.each { | key, value | tools_array << { key => value } }
71
+ tools_array
72
+ end
73
+ end
74
+ tool_functions = to_google_tools( conversation[ :tools ] )
75
+ if tool_functions&.any?
76
+ tools ||= {}
77
+ tools[ :function_declarations ] ||= []
78
+ tools[ :function_declarations ].concat( tool_functions )
79
+ end
80
+
65
81
  # googlify tool configuration
66
82
  if tool_config = gc.delete( :tool_config )
67
83
  mode = tool_config[ :function_calling_config ]&.[]( :mode )
68
84
  tool_config[ :function_calling_config ][ :mode ] = mode.to_s.upcase if mode
69
85
  end
70
-
86
+
71
87
  result = {}
72
88
  result[ :generationConfig ] = gc
73
- result[ :tool_config ] = tool_config if tool_config
89
+ result[ :tools ] = tools if tools
90
+ result[ :tool_config ] = tool_config if tools && tool_config
74
91
 
75
92
  # construct the system prompt in the form of the google schema
76
93
  system_instructions = to_google_system_message( conversation[ :system_message ] )
@@ -163,10 +180,6 @@ module Intelligence
163
180
 
164
181
  end
165
182
 
166
- tools_attributes = to_google_tools( conversation[ :tools ] )
167
- result[ :tools ] = [ { function_declarations: tools_attributes } ] \
168
- if tools_attributes&.any?
169
-
170
183
  JSON.generate( result )
171
184
  end
172
185
 
@@ -40,9 +40,8 @@ module Intelligence
40
40
  end
41
41
  logit_bias
42
42
  logprobs [ TrueClass, FalseClass ]
43
+ top_logprobs Integer
43
44
  modalities String, array: true
44
- # the parallel_tool_calls parameter is only allowed when 'tools' are specified
45
- parallel_tool_calls [ TrueClass, FalseClass ]
46
45
  response_format do
47
46
  # 'text' and 'json_schema' are the only supported types
48
47
  type Symbol, in: [ :text, :json_schema ]
@@ -52,9 +51,34 @@ module Intelligence
52
51
  stream_options do
53
52
  include_usage [ TrueClass, FalseClass ]
54
53
  end
55
- tool_choice
56
- top_logprobs Integer
57
- user
54
+ user
55
+
56
+ # open ai tool configuration; this allows you to enable build in tools ( currently
57
+ # that's just 'code_interpreter' )
58
+ #
59
+ # tool :code_interpreter
60
+ #
61
+ #tool array: true, as: :tools, arguments: :type
62
+ # type Symbol
63
+ #end
64
+
65
+ # open ai tool choice configuration
66
+ #
67
+ # `tool_choice :none`
68
+ # or
69
+ # ```
70
+ # tool_choice :function do
71
+ # function :my_function
72
+ # end
73
+ # ```
74
+ tool_choice arguments: :type do
75
+ type Symbol, in: [ :none, :auto, :required ]
76
+ function arguments: :name do
77
+ name Symbol
78
+ end
79
+ end
80
+ # the parallel_tool_calls parameter is only allowed when 'tools' are specified
81
+ parallel_tool_calls [ TrueClass, FalseClass ]
58
82
 
59
83
  end
60
84
 
@@ -0,0 +1,196 @@
1
+ require_relative 'generic/adapter'
2
+
3
+ module Intelligence
4
+ module XAi
5
+
6
+ class Adapter < Generic::Adapter
7
+
8
+ chat_request_uri "https://api.x.ai/v1/chat/completions"
9
+
10
+ schema do
11
+ key String
12
+ chat_options do
13
+ model String
14
+ frequency_penalty Float, in: -2..2
15
+ logit_bias Hash
16
+ logprobs [ TrueClass, FalseClass ]
17
+ max_tokens Integer
18
+ n Integer
19
+ presence_penalty Float, in: -2..2
20
+ response_format
21
+ seed Integer
22
+ stop String, array: true
23
+ stream [ TrueClass, FalseClass ]
24
+ stream_options
25
+ temperature Float, in: 0..2
26
+ tool_choice
27
+ top_logprobs Integer, in: 0..20
28
+ top_p Float
29
+ user String
30
+ end
31
+ end
32
+
33
+ def chat_result_attributes( response )
34
+ return nil unless response.success?
35
+ response_json = JSON.parse( response.body, symbolize_names: true ) rescue nil
36
+ return nil if response_json.nil? || response_json[ :choices ].nil?
37
+
38
+ result = {}
39
+ result[ :choices ] = []
40
+
41
+ ( response_json[ :choices ] || [] ).each do | json_choice |
42
+ end_reason = to_end_reason( json_choice[ :finish_reason ] )
43
+ if ( json_message = json_choice[ :message ] )
44
+ result_message = { role: json_message[ :role ] }
45
+ if json_message[ :content ]
46
+ result_message[ :contents ] = [ { type: :text, text: json_message[ :content ] } ]
47
+ end
48
+ if json_message[ :tool_calls ] && !json_message[ :tool_calls ].empty?
49
+ result_message[ :contents ] ||= []
50
+ end_reason = :tool_called if end_reason == :ended
51
+ json_message[ :tool_calls ].each do | json_message_tool_call |
52
+ result_message_tool_call_parameters =
53
+ JSON.parse( json_message_tool_call[ :function ][ :arguments ], symbolize_names: true ) \
54
+ rescue json_message_tool_call[ :function ][ :arguments ]
55
+ result_message[ :contents ] << {
56
+ type: :tool_call,
57
+ tool_call_id: json_message_tool_call[ :id ],
58
+ tool_name: json_message_tool_call[ :function ][ :name ],
59
+ tool_parameters: result_message_tool_call_parameters
60
+ }
61
+ end
62
+ end
63
+ end
64
+ result[ :choices ].push( { end_reason: end_reason, message: result_message } )
65
+ end
66
+
67
+ metrics_json = response_json[ :usage ]
68
+ unless metrics_json.nil?
69
+
70
+ metrics = {}
71
+ metrics[ :input_tokens ] = metrics_json[ :prompt_tokens ]
72
+ metrics[ :output_tokens ] = metrics_json[ :completion_tokens ]
73
+ metrics = metrics.compact
74
+
75
+ result[ :metrics ] = metrics unless metrics.empty?
76
+
77
+ end
78
+
79
+ result
80
+ end
81
+
82
+ def stream_result_chunk_attributes( context, chunk )
83
+ context ||= {}
84
+ buffer = context[ :buffer ] || ''
85
+ metrics = context[ :metrics ] || {
86
+ input_tokens: 0,
87
+ output_tokens: 0
88
+ }
89
+ choices = context[ :choices ] || Array.new( 1 , { message: {} } )
90
+
91
+ choices.each do | choice |
92
+ choice[ :message ][ :contents ] = choice[ :message ][ :contents ]&.map do | content |
93
+ { type: content[ :type ] }
94
+ end
95
+ end
96
+
97
+ buffer += chunk
98
+ while ( eol_index = buffer.index( "\n" ) )
99
+ line = buffer.slice!( 0..eol_index )
100
+ line = line.strip
101
+ next if line.empty? || !line.start_with?( 'data:' )
102
+ line = line[ 6..-1 ]
103
+ next if line.end_with?( '[DONE]' )
104
+
105
+ data = JSON.parse( line ) rescue nil
106
+ if data.is_a?( Hash )
107
+ data[ 'choices' ]&.each do | data_choice |
108
+
109
+ data_choice_index = data_choice[ 'index' ]
110
+ data_choice_delta = data_choice[ 'delta' ]
111
+ end_reason = to_end_reason( data_choice[ 'finish_reason' ] )
112
+
113
+ choices.fill( { message: {} }, choices.size, data_choice_index + 1 ) \
114
+ if choices.size <= data_choice_index
115
+ contents = choices[ data_choice_index ][ :message ][ :contents ] || []
116
+
117
+ text_content = contents.first&.[]( :type ) == :text ? contents.first : nil
118
+ if data_choice_content = data_choice_delta[ 'content' ]
119
+ if text_content.nil?
120
+ contents.unshift( text_content = { type: :text, text: data_choice_content } )
121
+ else
122
+ text_content[ :text ] = ( text_content[ :text ] || '' ) + data_choice_content
123
+ end
124
+ end
125
+ if data_choice_tool_calls = data_choice_delta[ 'tool_calls' ]
126
+ end_reason = :tool_called
127
+ data_choice_tool_calls.each_with_index do | data_choice_tool_call, data_choice_tool_call_index |
128
+ if data_choice_tool_call_function = data_choice_tool_call[ 'function' ]
129
+ data_choice_tool_index = data_choice_tool_call[ 'index' ] || data_choice_tool_call_index
130
+ data_choice_tool_id = data_choice_tool_call[ 'id' ]
131
+ data_choice_tool_name = data_choice_tool_call_function[ 'name' ]
132
+ data_choice_tool_parameters = data_choice_tool_call_function[ 'arguments' ]
133
+
134
+ tool_call_content_index = ( text_content.nil? ? 0 : 1 ) + data_choice_tool_index
135
+ if tool_call_content_index >= contents.length
136
+ contents.push( {
137
+ type: :tool_call,
138
+ tool_call_id: data_choice_tool_id,
139
+ tool_name: data_choice_tool_name,
140
+ tool_parameters: data_choice_tool_parameters
141
+ } )
142
+ else
143
+ tool_call = contents[ tool_call_content_index ]
144
+ tool_call[ :tool_call_id ] = ( tool_call[ :tool_call_id ] || '' ) + data_choice_tool_id \
145
+ if data_choice_tool_id
146
+ tool_call[ :tool_name ] = ( tool_call[ :tool_name ] || '' ) + data_choice_tool_name \
147
+ if data_choice_tool_name
148
+ tool_call[ :tool_parameters ] = ( tool_call[ :tool_parameters ] || '' ) + data_choice_tool_parameters \
149
+ if data_choice_tool_parameters
150
+ end
151
+ end
152
+ end
153
+ end
154
+ choices[ data_choice_index ][ :message ][ :contents ] = contents
155
+ choices[ data_choice_index ][ :end_reason ] ||= end_reason
156
+ end
157
+
158
+ if usage = data[ 'usage' ]
159
+ # note: A number of providers will resend the input tokens as part of their usage
160
+ # payload.
161
+ metrics[ :input_tokens ] = usage[ 'prompt_tokens' ] \
162
+ if usage.include?( 'prompt_tokens' )
163
+ metrics[ :output_tokens ] += usage[ 'completion_tokens' ] \
164
+ if usage.include?( 'completion_tokens' )
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+
171
+ context[ :buffer ] = buffer
172
+ context[ :metrics ] = metrics
173
+ context[ :choices ] = choices
174
+
175
+ [ context, choices.empty? ? nil : { choices: choices.dup } ]
176
+ end
177
+
178
+ def chat_result_error_attributes( response )
179
+ error_type, error_description = to_error_response( response.status )
180
+ error = error_type
181
+
182
+ parsed_body = JSON.parse( response.body, symbolize_names: true ) rescue nil
183
+ if parsed_body && parsed_body.respond_to?( :[] )
184
+ error = parsed_body[ :code ] || error_type
185
+ error_description = parsed_body[ :error ] || error_description
186
+ end
187
+
188
+ { error_type: error_type.to_s, error: error.to_s, error_description: error_description }
189
+ end
190
+
191
+ alias_method :stream_result_error_attributes, :chat_result_error_attributes
192
+
193
+ end
194
+
195
+ end
196
+ end
@@ -1,3 +1,3 @@
1
1
  module Intelligence
2
- VERSION = "0.8.0"
2
+ VERSION = "1.0.0.beta02"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intelligence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 1.0.0.beta02
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristoph Cichocki-Romanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-31 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -153,6 +153,7 @@ files:
153
153
  - lib/intelligence/adapters/open_router.rb
154
154
  - lib/intelligence/adapters/samba_nova.rb
155
155
  - lib/intelligence/adapters/together_ai.rb
156
+ - lib/intelligence/adapters/x_ai.rb
156
157
  - lib/intelligence/chat_error_result.rb
157
158
  - lib/intelligence/chat_metrics.rb
158
159
  - lib/intelligence/chat_request.rb