intelligence 0.5.0 → 0.7.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 +4 -4
- data/README.md +555 -0
- data/intelligence.gemspec +1 -1
- data/lib/intelligence/adapter/base.rb +23 -3
- data/lib/intelligence/adapter/class_methods.rb +15 -0
- data/lib/intelligence/adapter/{construction_methods.rb → module_methods.rb} +8 -4
- data/lib/intelligence/adapter.rb +2 -2
- data/lib/intelligence/adapters/anthropic/adapter.rb +21 -30
- data/lib/intelligence/adapters/anthropic/chat_request_methods.rb +189 -0
- data/lib/intelligence/adapters/anthropic/{chat_methods.rb → chat_response_methods.rb} +8 -124
- data/lib/intelligence/adapters/cerebras.rb +17 -17
- data/lib/intelligence/adapters/generic/adapter.rb +1 -12
- data/lib/intelligence/adapters/generic/chat_methods.rb +42 -11
- data/lib/intelligence/adapters/generic.rb +1 -1
- data/lib/intelligence/adapters/google/adapter.rb +33 -35
- data/lib/intelligence/adapters/google/chat_request_methods.rb +233 -0
- data/lib/intelligence/adapters/google/{chat_methods.rb → chat_response_methods.rb} +52 -162
- data/lib/intelligence/adapters/groq.rb +46 -28
- data/lib/intelligence/adapters/hyperbolic.rb +13 -13
- data/lib/intelligence/adapters/legacy/adapter.rb +0 -2
- data/lib/intelligence/adapters/legacy/chat_methods.rb +22 -6
- data/lib/intelligence/adapters/mistral.rb +57 -0
- data/lib/intelligence/adapters/open_ai/adapter.rb +38 -45
- data/lib/intelligence/adapters/open_ai/chat_request_methods.rb +186 -0
- data/lib/intelligence/adapters/open_ai/{chat_methods.rb → chat_response_methods.rb} +60 -131
- data/lib/intelligence/adapters/open_ai.rb +1 -1
- data/lib/intelligence/adapters/open_router.rb +62 -0
- data/lib/intelligence/adapters/samba_nova.rb +13 -13
- data/lib/intelligence/adapters/together_ai.rb +21 -19
- data/lib/intelligence/chat_request.rb +57 -7
- data/lib/intelligence/chat_result.rb +4 -0
- data/lib/intelligence/chat_result_choice.rb +4 -2
- data/lib/intelligence/conversation.rb +38 -9
- data/lib/intelligence/message.rb +103 -20
- data/lib/intelligence/message_content/base.rb +3 -0
- data/lib/intelligence/message_content/binary.rb +6 -0
- data/lib/intelligence/message_content/file.rb +35 -0
- data/lib/intelligence/message_content/text.rb +5 -0
- data/lib/intelligence/message_content/tool_call.rb +12 -1
- data/lib/intelligence/message_content/tool_result.rb +15 -3
- data/lib/intelligence/message_content.rb +12 -3
- data/lib/intelligence/tool.rb +139 -0
- data/lib/intelligence/version.rb +1 -1
- data/lib/intelligence.rb +6 -4
- metadata +18 -9
@@ -1,57 +1,48 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'chat_request_methods'
|
2
|
+
require_relative 'chat_response_methods'
|
2
3
|
|
3
4
|
module Intelligence
|
4
5
|
module Anthropic
|
5
6
|
class Adapter < Adapter::Base
|
6
7
|
|
7
|
-
|
8
|
+
schema do
|
8
9
|
|
9
10
|
# normalized properties for all endpoints
|
10
|
-
|
11
|
+
key
|
11
12
|
|
12
13
|
# anthropic specific properties for all endpoints
|
13
|
-
|
14
|
+
version String, default: '2023-06-01'
|
14
15
|
|
15
|
-
|
16
|
+
chat_options do
|
16
17
|
|
17
18
|
# normalized properties for anthropic generative text endpoint
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
model String
|
20
|
+
max_tokens Integer
|
21
|
+
temperature Float
|
22
|
+
top_k Integer
|
23
|
+
top_p Float
|
24
|
+
stop String, array: true, as: :stop_sequences
|
25
|
+
stream [ TrueClass, FalseClass ]
|
25
26
|
|
26
27
|
# anthropic variant of normalized properties for anthropic generative text endpoints
|
27
|
-
|
28
|
+
stop_sequences String, array: true
|
28
29
|
|
29
30
|
# anthropic specific properties for anthropic generative text endpoints
|
30
|
-
|
31
|
-
|
31
|
+
tool_choice do
|
32
|
+
type String
|
32
33
|
# the name parameter should only be set if type = 'tool'
|
33
|
-
|
34
|
+
name String
|
34
35
|
end
|
35
|
-
|
36
|
-
|
36
|
+
metadata do
|
37
|
+
user_id String
|
37
38
|
end
|
38
39
|
|
39
40
|
end
|
40
41
|
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
attr_reader :chat_options
|
46
|
-
|
47
|
-
def initialize( attributes = nil, &block )
|
48
|
-
configuration = self.class.configure( attributes, &block )
|
49
|
-
@key = configuration[ :key ]
|
50
|
-
@version = configuration[ :version ]
|
51
|
-
@chat_options = configuration[ :chat_options ] || {}
|
52
|
-
end
|
53
|
-
|
54
|
-
include ChatMethods
|
44
|
+
include ChatRequestMethods
|
45
|
+
include ChatResponseMethods
|
55
46
|
|
56
47
|
end
|
57
48
|
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Intelligence
|
2
|
+
module Anthropic
|
3
|
+
module ChatRequestMethods
|
4
|
+
|
5
|
+
CHAT_REQUEST_URI = "https://api.anthropic.com/v1/messages"
|
6
|
+
|
7
|
+
def chat_request_uri( options )
|
8
|
+
CHAT_REQUEST_URI
|
9
|
+
end
|
10
|
+
|
11
|
+
def chat_request_headers( options = nil )
|
12
|
+
options = @options.merge( build_options( options ) )
|
13
|
+
result = {}
|
14
|
+
|
15
|
+
key = options[ :key ]
|
16
|
+
version = options[ :version ] || "2023-06-01"
|
17
|
+
|
18
|
+
raise ArgumentError.new(
|
19
|
+
"An Anthropic key is required to build an Anthropic chat request."
|
20
|
+
) if key.nil?
|
21
|
+
|
22
|
+
result[ 'content-type' ] = 'application/json'
|
23
|
+
result[ 'x-api-key' ] = "#{key}"
|
24
|
+
result[ 'anthropic-version' ] = version unless version.nil?
|
25
|
+
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def chat_request_body( conversation, options = nil )
|
30
|
+
options = @options.merge( build_options( options ) )
|
31
|
+
result = options[ :chat_options ]&.compact || {}
|
32
|
+
|
33
|
+
system_message = to_anthropic_system_message( conversation[ :system_message ] )
|
34
|
+
result[ :system ] = system_message unless system_message.nil?
|
35
|
+
result[ :messages ] = []
|
36
|
+
|
37
|
+
messages = conversation[ :messages ]
|
38
|
+
length = messages&.length || 0
|
39
|
+
index = 0; while index < length
|
40
|
+
|
41
|
+
message = messages[ index ]
|
42
|
+
unless message.nil?
|
43
|
+
|
44
|
+
# The Anthropic API will not accept a sequence of messages where the role of two
|
45
|
+
# sequentian messages is the same.
|
46
|
+
#
|
47
|
+
# The purpose of this code is to identify such occurences and coalece them such
|
48
|
+
# that the first message in the sequence aggregates the contents of all subsequent
|
49
|
+
# messages with the same role.
|
50
|
+
look_ahead_index = index + 1; while look_ahead_index < length
|
51
|
+
ahead_message = messages[ look_ahead_index ]
|
52
|
+
unless ahead_message.nil?
|
53
|
+
if ahead_message[ :role ] == message[ :role ]
|
54
|
+
message[ :contents ] =
|
55
|
+
( message[ :contents ] || [] ) +
|
56
|
+
( ahead_message[ :contents ] || [] )
|
57
|
+
messages[ look_ahead_index ] = nil
|
58
|
+
look_ahead_index += 1
|
59
|
+
else
|
60
|
+
break
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
result_message = { role: message[ :role ] }
|
66
|
+
result_message_content = []
|
67
|
+
|
68
|
+
message[ :contents ]&.each do | content |
|
69
|
+
case content[ :type ]
|
70
|
+
when :text
|
71
|
+
result_message_content << { type: 'text', text: content[ :text ] }
|
72
|
+
when :binary
|
73
|
+
content_type = content[ :content_type ]
|
74
|
+
bytes = content[ :bytes ]
|
75
|
+
if content_type && bytes
|
76
|
+
mime_type = MIME::Types[ content_type ].first
|
77
|
+
if mime_type&.media_type == 'image'
|
78
|
+
result_message_content << {
|
79
|
+
type: 'image',
|
80
|
+
source: {
|
81
|
+
type: 'base64',
|
82
|
+
media_type: content_type,
|
83
|
+
data: Base64.strict_encode64( bytes )
|
84
|
+
}
|
85
|
+
}
|
86
|
+
else
|
87
|
+
raise UnsupportedContentError.new(
|
88
|
+
:anthropic,
|
89
|
+
'only support content of type image/*'
|
90
|
+
)
|
91
|
+
end
|
92
|
+
else
|
93
|
+
raise UnsupportedContentError.new(
|
94
|
+
:anthropic,
|
95
|
+
'requires file content to include content type and (packed) bytes'
|
96
|
+
)
|
97
|
+
end
|
98
|
+
when :tool_call
|
99
|
+
result_message_content << {
|
100
|
+
type: 'tool_use',
|
101
|
+
id: content[ :tool_call_id ],
|
102
|
+
name: content[ :tool_name ],
|
103
|
+
input: content[ :tool_parameters ] || {}
|
104
|
+
}
|
105
|
+
when :tool_result
|
106
|
+
result_message_content << {
|
107
|
+
type: 'tool_result',
|
108
|
+
tool_use_id: content[ :tool_call_id ],
|
109
|
+
content: content[ :tool_result ]
|
110
|
+
}
|
111
|
+
else
|
112
|
+
raise InvalidContentError.new( :anthropic )
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
result_message[ :content ] = result_message_content
|
117
|
+
result[ :messages ] << result_message
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
index += 1
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
|
126
|
+
result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
|
127
|
+
|
128
|
+
JSON.generate( result )
|
129
|
+
end
|
130
|
+
|
131
|
+
def chat_request_tools_attributes( tools )
|
132
|
+
properties_array_to_object = lambda do | properties |
|
133
|
+
return nil unless properties&.any?
|
134
|
+
object = {}
|
135
|
+
required = []
|
136
|
+
properties.each do | property |
|
137
|
+
name = property.delete( :name )
|
138
|
+
required << name if property.delete( :required )
|
139
|
+
if property[ :properties ]&.any?
|
140
|
+
property_properties, property_required =
|
141
|
+
properties_array_to_object.call( property[ :properties ] )
|
142
|
+
property[ :properties ] = property_properties
|
143
|
+
property[ :required ] = property_required if property_required.any?
|
144
|
+
end
|
145
|
+
object[ name ] = property
|
146
|
+
end
|
147
|
+
[ object, required.compact ]
|
148
|
+
end
|
149
|
+
|
150
|
+
tools&.map do | tool |
|
151
|
+
tool_attributes = {
|
152
|
+
name: tool[ :name ],
|
153
|
+
description: tool[ :description ],
|
154
|
+
input_schema: { type: 'object' }
|
155
|
+
}
|
156
|
+
|
157
|
+
if tool[ :properties ]&.any?
|
158
|
+
properties_object, properties_required =
|
159
|
+
properties_array_to_object.call( tool[ :properties ] )
|
160
|
+
input_schema = {
|
161
|
+
type: 'object',
|
162
|
+
properties: properties_object
|
163
|
+
}
|
164
|
+
input_schema[ :required ] = properties_required if properties_required.any?
|
165
|
+
tool_attributes[ :input_schema ] = input_schema
|
166
|
+
end
|
167
|
+
tool_attributes
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def to_anthropic_system_message( system_message )
|
174
|
+
return nil if system_message.nil?
|
175
|
+
|
176
|
+
# note: the current version of the anthropic api simply takes a string as the
|
177
|
+
# system message but the beta version requires an array of objects akin
|
178
|
+
# to message contents.
|
179
|
+
result = ''
|
180
|
+
system_message[ :contents ].each do | content |
|
181
|
+
result += content[ :text ] if content[ :type ] == :text
|
182
|
+
end
|
183
|
+
|
184
|
+
result.empty? ? nil : result
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -1,112 +1,6 @@
|
|
1
|
-
require 'base64'
|
2
|
-
|
3
1
|
module Intelligence
|
4
2
|
module Anthropic
|
5
|
-
module
|
6
|
-
|
7
|
-
CHAT_REQUEST_URI = "https://api.anthropic.com/v1/messages"
|
8
|
-
|
9
|
-
def chat_request_uri( options )
|
10
|
-
CHAT_REQUEST_URI
|
11
|
-
end
|
12
|
-
|
13
|
-
def chat_request_headers( options = {} )
|
14
|
-
result = {}
|
15
|
-
|
16
|
-
key = options[ :key ] || self.key
|
17
|
-
version = options[ :version ] || self.version || "2023-06-01"
|
18
|
-
|
19
|
-
raise ArgumentError.new(
|
20
|
-
"An Anthropic key is required to build an Anthropic chat request."
|
21
|
-
) if key.nil?
|
22
|
-
|
23
|
-
result[ 'content-type' ] = 'application/json'
|
24
|
-
result[ 'x-api-key' ] = "#{key}"
|
25
|
-
result[ 'anthropic-version' ] = version unless version.nil?
|
26
|
-
|
27
|
-
result
|
28
|
-
end
|
29
|
-
|
30
|
-
def chat_request_body( conversation, options = {} )
|
31
|
-
options = self.class.configure( options ) unless options.empty?
|
32
|
-
result = self.chat_options.merge( options ).compact
|
33
|
-
|
34
|
-
system_message = translate_system_message( conversation[ :system_message ] )
|
35
|
-
result[ :system ] = system_message unless system_message.nil?
|
36
|
-
result[ :messages ] = []
|
37
|
-
|
38
|
-
messages = conversation[ :messages ]
|
39
|
-
length = messages&.length || 0
|
40
|
-
index = 0; while index < length
|
41
|
-
|
42
|
-
message = messages[ index ]
|
43
|
-
unless message.nil?
|
44
|
-
|
45
|
-
# The Anthropic API will not accept a sequence of messages where the role of two
|
46
|
-
# sequentian messages is the same.
|
47
|
-
#
|
48
|
-
# The purpose of this code is to identify such occurences and coalece them such
|
49
|
-
# that the first message in the sequence aggregates the contents of all subsequent
|
50
|
-
# messages with the same role.
|
51
|
-
look_ahead_index = index + 1; while look_ahead_index < length
|
52
|
-
ahead_message = messages[ look_ahead_index ]
|
53
|
-
unless ahead_message.nil?
|
54
|
-
if ahead_message[ :role ] == message[ :role ]
|
55
|
-
message[ :contents ] =
|
56
|
-
( message[ :contents ] || [] ) +
|
57
|
-
( ahead_message[ :contents ] || [] )
|
58
|
-
messages[ look_ahead_index ] = nil
|
59
|
-
look_ahead_index += 1
|
60
|
-
else
|
61
|
-
break
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
result_message = { role: message[ :role ] }
|
67
|
-
result_message_content = []
|
68
|
-
|
69
|
-
message[ :contents ]&.each do | content |
|
70
|
-
case content[ :type ]
|
71
|
-
when :text
|
72
|
-
result_message_content << { type: 'text', text: content[ :text ] }
|
73
|
-
when :binary
|
74
|
-
content_type = content[ :content_type ]
|
75
|
-
bytes = content[ :bytes ]
|
76
|
-
if content_type && bytes
|
77
|
-
mime_type = MIME::Types[ content_type ].first
|
78
|
-
if mime_type&.media_type == 'image'
|
79
|
-
result_message_content << {
|
80
|
-
type: 'image',
|
81
|
-
source: {
|
82
|
-
type: 'base64',
|
83
|
-
media_type: content_type,
|
84
|
-
data: Base64.strict_encode64( bytes )
|
85
|
-
}
|
86
|
-
}
|
87
|
-
else
|
88
|
-
raise UnsupportedContentError.new(
|
89
|
-
:anthropic,
|
90
|
-
'only support content of type image/*'
|
91
|
-
)
|
92
|
-
end
|
93
|
-
else
|
94
|
-
raise InvalidContentError.new( :anthropic )
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
result_message[ :content ] = result_message_content
|
100
|
-
result[ :messages ] << result_message
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
index += 1
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
JSON.generate( result )
|
109
|
-
end
|
3
|
+
module ChatResponseMethods
|
110
4
|
|
111
5
|
def chat_result_attributes( response )
|
112
6
|
return nil unless response.success?
|
@@ -129,6 +23,13 @@ module Intelligence
|
|
129
23
|
response_json[ :content ].each do | content |
|
130
24
|
if content[ :type ] == 'text'
|
131
25
|
result_content.push( { type: 'text', text: content[ :text ] } )
|
26
|
+
elsif content[ :type ] == 'tool_use'
|
27
|
+
result_content.push( {
|
28
|
+
type: :tool_call,
|
29
|
+
tool_call_id: content[ :id ],
|
30
|
+
tool_name: content[ :name ],
|
31
|
+
tool_parameters: content[ :input ]
|
32
|
+
} )
|
132
33
|
end
|
133
34
|
end
|
134
35
|
|
@@ -288,23 +189,6 @@ module Intelligence
|
|
288
189
|
|
289
190
|
private
|
290
191
|
|
291
|
-
def translate_system_message( system_message )
|
292
|
-
|
293
|
-
return nil if system_message.nil?
|
294
|
-
|
295
|
-
# note: the current version of the anthropic api simply takes a string as the
|
296
|
-
# system message but the beta version requires an array of objects akin
|
297
|
-
# to message contents.
|
298
|
-
|
299
|
-
result = ''
|
300
|
-
system_message[ :contents ].each do | content |
|
301
|
-
result += content[ :text ] if content[ :type ] == :text
|
302
|
-
end
|
303
|
-
|
304
|
-
result.empty? ? nil : result
|
305
|
-
|
306
|
-
end
|
307
|
-
|
308
192
|
def translate_end_result( end_result )
|
309
193
|
case end_result
|
310
194
|
when 'end_turn'
|
@@ -7,25 +7,25 @@ module Intelligence
|
|
7
7
|
|
8
8
|
chat_request_uri "https://api.cerebras.ai/v1/chat/completions"
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
schema do
|
11
|
+
key String
|
12
|
+
chat_options do
|
13
|
+
model String
|
14
|
+
max_tokens Integer
|
15
|
+
response_format do
|
16
|
+
type String, default: 'json_schema'
|
17
|
+
json_schema
|
18
18
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
seed Integer
|
20
|
+
stop array: true
|
21
|
+
stream [ TrueClass, FalseClass ]
|
22
|
+
temperature Float
|
23
|
+
top_p Float
|
24
|
+
tool_choice do
|
25
|
+
type String
|
26
|
+
mame String
|
27
27
|
end
|
28
|
-
|
28
|
+
user
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -4,18 +4,7 @@ require_relative 'chat_methods'
|
|
4
4
|
module Intelligence
|
5
5
|
module Generic
|
6
6
|
class Adapter < Adapter::Base
|
7
|
-
|
8
|
-
attr_reader :key
|
9
|
-
attr_reader :chat_options
|
10
|
-
|
11
|
-
def initialize( attributes = nil, &block )
|
12
|
-
configuration = self.class.configure( attributes, &block )
|
13
|
-
@key = configuration[ :key ]
|
14
|
-
@chat_options = configuration[ :chat_options ] || {}
|
15
|
-
end
|
16
|
-
|
17
7
|
include ChatMethods
|
18
|
-
|
19
8
|
end
|
20
9
|
end
|
21
|
-
end
|
10
|
+
end
|
@@ -20,10 +20,11 @@ module Intelligence
|
|
20
20
|
self.class.chat_request_uri
|
21
21
|
end
|
22
22
|
|
23
|
-
def chat_request_headers( options =
|
23
|
+
def chat_request_headers( options = nil )
|
24
|
+
options = @options.merge( build_options( options ) )
|
24
25
|
result = {}
|
25
26
|
|
26
|
-
key = options[ :key ]
|
27
|
+
key = options[ :key ]
|
27
28
|
|
28
29
|
raise ArgumentError.new( "An API key is required to build a chat request." ) \
|
29
30
|
if key.nil?
|
@@ -34,8 +35,10 @@ module Intelligence
|
|
34
35
|
result
|
35
36
|
end
|
36
37
|
|
37
|
-
def chat_request_body( conversation, options =
|
38
|
-
|
38
|
+
def chat_request_body( conversation, options = nil )
|
39
|
+
options = @options.merge( build_options( options ) )
|
40
|
+
|
41
|
+
result = options[ :chat_options ]
|
39
42
|
result[ :messages ] = []
|
40
43
|
|
41
44
|
system_message = system_message_to_s( conversation[ :system_message ] )
|
@@ -79,6 +82,28 @@ module Intelligence
|
|
79
82
|
'requires binary content to include content type and ( packed ) bytes'
|
80
83
|
)
|
81
84
|
end
|
85
|
+
when :file
|
86
|
+
content_type = content[ :content_type ]
|
87
|
+
uri = content[ :uri ]
|
88
|
+
if content_type && uri
|
89
|
+
mime_type = MIME::Types[ content_type ].first
|
90
|
+
if mime_type&.media_type == 'image'
|
91
|
+
result_message_content << {
|
92
|
+
type: 'image_url',
|
93
|
+
image_url: { url: uri }
|
94
|
+
}
|
95
|
+
else
|
96
|
+
raise UnsupportedContentError.new(
|
97
|
+
:generic,
|
98
|
+
'only support content of type image/*'
|
99
|
+
)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
raise UnsupportedContentError.new(
|
103
|
+
:generic,
|
104
|
+
'requires binary content to include content type and ( packed ) bytes'
|
105
|
+
)
|
106
|
+
end
|
82
107
|
end
|
83
108
|
end
|
84
109
|
result_message[ :content ] = result_message_content
|
@@ -124,7 +149,7 @@ module Intelligence
|
|
124
149
|
end
|
125
150
|
|
126
151
|
def chat_result_error_attributes( response )
|
127
|
-
|
152
|
+
|
128
153
|
error_type, error_description = translate_error_response_status( response.status )
|
129
154
|
result = {
|
130
155
|
error_type: error_type.to_s,
|
@@ -178,7 +203,6 @@ module Intelligence
|
|
178
203
|
|
179
204
|
next if line.end_with?( '[DONE]' )
|
180
205
|
data = JSON.parse( line )
|
181
|
-
|
182
206
|
if data.is_a?( Hash )
|
183
207
|
|
184
208
|
data[ 'choices' ]&.each do | data_choice |
|
@@ -196,10 +220,8 @@ module Intelligence
|
|
196
220
|
data_choice_content = data_choice_delta[ 'content' ] || ''
|
197
221
|
if last_content.nil? || last_content[ :type ] == :tool_call
|
198
222
|
contents.push( { type: :text, text: data_choice_content } )
|
199
|
-
elsif last_content[ :type ].nil?
|
223
|
+
elsif last_content[ :type ] == :text || last_content[ :type ].nil?
|
200
224
|
last_content[ :type ] = :text
|
201
|
-
last_content[ :text ] = data_choice_content
|
202
|
-
elsif last_content[ :type ] == :text
|
203
225
|
last_content[ :text ] = ( last_content[ :text ] || '' ) + data_choice_content
|
204
226
|
end
|
205
227
|
elsif data_choice_delta.include?( 'function_call' )
|
@@ -223,7 +245,7 @@ module Intelligence
|
|
223
245
|
end
|
224
246
|
end
|
225
247
|
choices[ data_choice_index ][ :message ][ :contents ] = contents
|
226
|
-
choices[ data_choice_index ][ :end_reason ]
|
248
|
+
choices[ data_choice_index ][ :end_reason ] ||=
|
227
249
|
translate_end_result( data_choice_finish_reason )
|
228
250
|
end
|
229
251
|
|
@@ -313,7 +335,16 @@ module Intelligence
|
|
313
335
|
end
|
314
336
|
end
|
315
337
|
|
316
|
-
|
338
|
+
private
|
339
|
+
|
340
|
+
def to_options( options, &block )
|
341
|
+
return {} unless options&.any?
|
342
|
+
@options_builder ||= DynamicSchema::Builder.new.define( &self.class.schema )
|
343
|
+
@options_builder.build( options, &block )
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
def system_message_to_s( system_message )
|
317
348
|
|
318
349
|
return nil if system_message.nil?
|
319
350
|
|
@@ -1,2 +1,2 @@
|
|
1
1
|
require_relative '../adapter'
|
2
|
-
require_relative 'generic/adapter'
|
2
|
+
require_relative 'generic/adapter'
|