intelligence 1.0.0.beta03 → 1.0.0.beta05

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: 77033342b73065a73acde0156a288f66fb0ef7413a939292d23886b353397fd3
4
- data.tar.gz: 6a8c7131991c0af60d9e30c000048ae9cb7e562e7c7dbb9ca519febe486d8491
3
+ metadata.gz: c0a3f15cdc1061405db03b0b8039b4867b16e70458d1a896a3d7cec542870cf5
4
+ data.tar.gz: 2914681b64f2295b7fbd9a4e4edb3425f53d23ec3a3dd3da0639df101a2fe31f
5
5
  SHA512:
6
- metadata.gz: 65050bd8d219f8348a0fe6c5b6cbc951a8de190572c01ecdc7e947aa2fa207f4fb65ae0e6afc2658ecf1fbe50ca0fd5b58c5fcf2651cc416fb9e6aeff73c97df
7
- data.tar.gz: 17ef75ad141fc8f25f0a62a32c1b677785340b0bd15c8f907c455a10b5d7e35532728e7f36cb62b3ccb3ebe0c835b8facd6777832dda955bb09aabae1802975b
6
+ metadata.gz: 181c33085c1c608f8d35b39332514e0a4028124e85309f4e95fddb5913b43490333298ffa8d935f3cc447d682968e04816c7d5497967d1700daa4d575dbd6425
7
+ data.tar.gz: abf03a55cf8c5f1ff5d0c97bc4d6918327f240cbc1f2137338726611c447fdd32cabf2cc15ba7f0f40b6cb122d35f9e0dec092add65c10b40044f248c2535d97
data/README.md CHANGED
@@ -405,9 +405,6 @@ conversation = Intelligence::Conversation.build do
405
405
  content text: "You can help users check weather conditions."
406
406
  end
407
407
 
408
- # Add the tool to the conversation
409
- tools << weather_tool
410
-
411
408
  message do
412
409
  role :user
413
410
  content text: "What's the weather like in Paris, France?"
@@ -415,7 +412,7 @@ conversation = Intelligence::Conversation.build do
415
412
  end
416
413
 
417
414
  request = Intelligence::ChatRequest.new( adapter: adapter )
418
- response = request.chat( conversation )
415
+ response = request.chat( conversation, tools: [ weather_tool ] )
419
416
 
420
417
  # Handle tool calls in the response
421
418
  if response.success?
data/intelligence.gemspec CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do | spec |
37
37
  spec.require_paths = [ "lib" ]
38
38
 
39
39
  spec.add_runtime_dependency 'faraday', '~> 2.7'
40
- spec.add_runtime_dependency 'dynamicschema', '~> 1.0.0.beta03'
40
+ spec.add_runtime_dependency 'dynamicschema', '~> 1.0'
41
41
  spec.add_runtime_dependency 'mime-types', '~> 3.6'
42
42
  spec.add_runtime_dependency 'json-repair', '~> 0.2'
43
43
 
@@ -21,6 +21,20 @@ module Intelligence
21
21
  self.class.builder.build( options )
22
22
  end
23
23
 
24
+ def merge_options( options, other_options )
25
+ merged_options = options.dup
26
+
27
+ other_options.each do | key, value |
28
+ if merged_options[ key].is_a?( Hash ) && value.is_a?( Hash )
29
+ merged_options[ key ] = merge_options( merged_options[ key ], value )
30
+ else
31
+ merged_options[ key ] = value
32
+ end
33
+ end
34
+
35
+ merged_options
36
+ end
37
+
24
38
  end
25
39
  end
26
40
  end
@@ -2,7 +2,7 @@ module Intelligence
2
2
  class AdapterError < Error;
3
3
  def initialize( adapter_type, text )
4
4
  adapter_class_name = adapter_type.to_s.split( '_' ).map( &:capitalize ).join
5
- super( "The #{adapter_class_name} #{text}." )
5
+ super( "The #{adapter_class_name} adapter #{text}." )
6
6
  end
7
7
  end
8
8
  end
@@ -28,11 +28,23 @@ module Intelligence
28
28
  stop_sequences String, array: true
29
29
 
30
30
  # anthropic specific properties for anthropic generative text endpoints
31
- tool_choice do
32
- type String
31
+ tool array: true, as: :tools, &Tool.schema
32
+ # anthropic tool choice configuration; note that there is no 'none' option so if
33
+ # tools are provided :auto will be the default
34
+ #
35
+ # `tool_choice :any`
36
+ # or
37
+ # ```
38
+ # tool_choice :tool do
39
+ # function :my_tool
40
+ # end
41
+ # ```
42
+ tool_choice arguments: :type do
43
+ type Symbol, in: [ :any, :auto, :tool ]
33
44
  # the name parameter should only be set if type = 'tool'
34
45
  name String
35
46
  end
47
+
36
48
  metadata do
37
49
  user_id String
38
50
  end
@@ -9,7 +9,7 @@ module Intelligence
9
9
  end
10
10
 
11
11
  def chat_request_headers( options = nil )
12
- options = @options.merge( build_options( options ) )
12
+ options = merge_options( @options, build_options( options ) )
13
13
  result = {}
14
14
 
15
15
  key = options[ :key ]
@@ -27,7 +27,9 @@ module Intelligence
27
27
  end
28
28
 
29
29
  def chat_request_body( conversation, options = nil )
30
- options = @options.merge( build_options( options ) )
30
+ tools = options.delete( :tools ) || []
31
+
32
+ options = merge_options( @options, build_options( options ) )
31
33
  result = options[ :chat_options ]&.compact || {}
32
34
 
33
35
  system_message = to_anthropic_system_message( conversation[ :system_message ] )
@@ -122,7 +124,9 @@ module Intelligence
122
124
 
123
125
  end
124
126
 
125
- tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
127
+ tools_attributes = chat_request_tools_attributes(
128
+ ( result[ :tools ] || [] ).concat( tools )
129
+ )
126
130
  result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
127
131
 
128
132
  JSON.generate( result )
@@ -5,10 +5,13 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri "https://api.cerebras.ai/v1/chat/completions"
8
+ DEFAULT_BASE_URI = 'https://api.cerebras.ai/v1'
9
9
 
10
10
  schema do
11
+
12
+ base_uri String, default: DEFAULT_BASE_URI
11
13
  key String
14
+
12
15
  chat_options do
13
16
  model String
14
17
  max_tokens Integer
@@ -21,12 +24,14 @@ module Intelligence
21
24
  stream [ TrueClass, FalseClass ]
22
25
  temperature Float
23
26
  top_p Float
27
+ tool array: true, as: :tools, &Tool.schema
24
28
  tool_choice do
25
29
  type String
26
30
  mame String
27
31
  end
28
- user
32
+ user String
29
33
  end
34
+
30
35
  end
31
36
 
32
37
  end
@@ -0,0 +1,44 @@
1
+ require_relative 'generic/adapter'
2
+
3
+ module Intelligence
4
+ module Deepseek
5
+ class Adapter < Generic::Adapter
6
+
7
+ chat_request_uri 'https://api.deepseek.com/v1/chat/completions'
8
+
9
+ schema do
10
+ key String
11
+ chat_options do
12
+ frequency_penalty Float
13
+ logprobs [ TrueClass, FalseClass ]
14
+ max_tokens Integer
15
+ model String
16
+ presence_penalty Float, in: [ -2..2 ]
17
+ response_format do
18
+ # 'text' and 'json_object' are the only supported types; you must also instruct
19
+ # the model to output json
20
+ type Symbol, in: [ :text, :json_object ]
21
+ end
22
+ stop String, array: true
23
+ stream [ TrueClass, FalseClass ]
24
+ stream_options do
25
+ include_usage [ TrueClass, FalseClass ]
26
+ end
27
+ temperature Float, in: [ 0..2 ]
28
+ tool array: true, as: :tools, &Tool.schema
29
+ tool_choice do
30
+ # one of 'auto', 'none' or 'function'
31
+ type Symbol, in: [ :auto, :none, :required ]
32
+ # the function parameters is required if you specify a type of 'function'
33
+ function do
34
+ name String
35
+ end
36
+ end
37
+ top_logprobs Integer
38
+ top_p Float
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -12,31 +12,40 @@ module Intelligence
12
12
  end
13
13
  end
14
14
 
15
+ CHAT_COMPLETIONS_PATH = 'chat/completions'
16
+
15
17
  def self.included( base )
16
18
  base.extend( ClassMethods )
17
19
  end
18
20
 
19
- def chat_request_uri( options )
20
- self.class.chat_request_uri
21
+ def chat_request_uri( options = nil )
22
+ options = merge_options( @options, build_options( options ) )
23
+ self.class.chat_request_uri || begin
24
+ base_uri = options[ :base_uri ]
25
+ if base_uri
26
+ # because URI join is dumb
27
+ base_uri = ( base_uri.end_with?( '/' ) ? base_uri : base_uri + '/' )
28
+ URI.join( base_uri, CHAT_COMPLETIONS_PATH )
29
+ else
30
+ nil
31
+ end
32
+ end
21
33
  end
22
34
 
23
35
  def chat_request_headers( options = nil )
24
- options = @options.merge( build_options( options ) )
25
- result = {}
36
+ options = merge_options( @options, build_options( options ) )
37
+ result = { 'Content-Type': 'application/json' }
26
38
 
27
39
  key = options[ :key ]
28
-
29
- raise ArgumentError.new( "An API key is required to build a chat request." ) \
30
- if key.nil?
31
-
32
- result[ 'Content-Type' ] = 'application/json'
33
- result[ 'Authorization' ] = "Bearer #{key}"
40
+ result[ 'Authorization' ] = "Bearer #{key}" if key
34
41
 
35
42
  result
36
43
  end
37
44
 
38
45
  def chat_request_body( conversation, options = nil )
39
- options = @options.merge( build_options( options ) )
46
+ tools = options.delete( :tools ) || []
47
+
48
+ options = merge_options( @options, build_options( options ) )
40
49
 
41
50
  result = options[ :chat_options ]
42
51
  result[ :messages ] = []
@@ -102,7 +111,9 @@ module Intelligence
102
111
  end
103
112
  end
104
113
 
105
- tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
114
+ tools_attributes = chat_request_tools_attributes(
115
+ ( result[ :tools ] || [] ).concat( tools )
116
+ )
106
117
  result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
107
118
 
108
119
  JSON.generate( result )
@@ -10,7 +10,7 @@ module Intelligence
10
10
  # normalized properties for all endpoints
11
11
  key String
12
12
 
13
- chat_options as: :generationConfig do
13
+ chat_options as: :generationConfig do
14
14
 
15
15
  # normalized properties for google generative text endpoint
16
16
  model String
@@ -35,20 +35,8 @@ 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
-
51
38
  # google specific tool configuration
39
+ tool array: true, as: :tools, &Tool.schema
52
40
  tool_configuration as: :tool_config do
53
41
  function_calling as: :function_calling_config do
54
42
  mode Symbol, in: [ :auto, :any, :none ]
@@ -56,6 +44,25 @@ module Intelligence
56
44
  end
57
45
  end
58
46
 
47
+ # build-in tools are called 'abilities' in Intelligence so as not to conflic with the
48
+ # caller defined tools
49
+ abilities do
50
+ # this appears to be a ( now ) legacy argument and is no longer supported
51
+ # with the 2.0 models
52
+ google_search_retrieval do
53
+ dynamic_retrieval as: :dynamic_retrieval_config, default: {} do
54
+ mode String, default: 'MODE_DYNAMIC'
55
+ threshold Float, as: :dynamic_threshold, in: 0..1, default: 0.3
56
+ end
57
+ end
58
+
59
+ # this argument and is only supported with the 2.0 or later models
60
+ google_search do
61
+ end
62
+
63
+ code_execution do
64
+ end
65
+ end
59
66
 
60
67
  end
61
68
 
@@ -17,7 +17,7 @@ module Intelligence
17
17
 
18
18
  SUPPORTED_FILE_MEDIA_TYPES = %w[ text ]
19
19
 
20
- SUPPORTED_CONTENT_TYPES = %w[
20
+ SUPPORTED_FILE_CONTENT_TYPES = %w[
21
21
  image/png image/jpeg image/webp image/heic image/heif
22
22
  video/x-flv video/quicktime video/mpeg video/mpegps video/mpg video/mp4 video/webm
23
23
  video/wmv video/3gpp
@@ -27,7 +27,7 @@ module Intelligence
27
27
  ]
28
28
 
29
29
  def chat_request_uri( options )
30
- options = @options.merge( build_options( options ) )
30
+ options = merge_options( @options, build_options( options ) )
31
31
 
32
32
  key = options[ :key ]
33
33
  gc = options[ :generationConfig ] || {}
@@ -55,27 +55,22 @@ module Intelligence
55
55
  end
56
56
 
57
57
  def chat_request_body( conversation, options = {} )
58
- options = @options.merge( build_options( options ) )
58
+ tools = options.delete( :tools ) || []
59
+ options = merge_options( @options, build_options( options ) )
59
60
 
60
61
  gc = options[ :generationConfig ]&.dup || {}
61
62
  # discard properties not part of the google generationConfig schema
62
63
  gc.delete( :model )
63
64
  gc.delete( :stream )
64
65
 
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 ] )
66
+ # googlify tools
67
+ tools_object = gc.delete( :abilities )
68
+ tool_functions = to_google_tools( ( gc.delete( :tools ) || [] ).concat( tools ) )
69
+
75
70
  if tool_functions&.any?
76
- tools ||= {}
77
- tools[ :function_declarations ] ||= []
78
- tools[ :function_declarations ].concat( tool_functions )
71
+ tools_object ||= {}
72
+ tools_object[ :function_declarations ] ||= []
73
+ tools_object[ :function_declarations ].concat( tool_functions )
79
74
  end
80
75
 
81
76
  # googlify tool configuration
@@ -86,7 +81,7 @@ module Intelligence
86
81
 
87
82
  result = {}
88
83
  result[ :generationConfig ] = gc
89
- result[ :tools ] = tools if tools
84
+ result[ :tools ] = tools_object if tools_object
90
85
  result[ :tool_config ] = tool_config if tools && tool_config
91
86
 
92
87
  # construct the system prompt in the form of the google schema
@@ -5,11 +5,15 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri 'https://api.groq.com/openai/v1/chat/completions'
8
+ DEFAULT_BASE_URI = 'https://api.groq.com/openai/v1'
9
9
 
10
10
  schema do
11
+
12
+ base_uri String, default: DEFAULT_BASE_URI
11
13
  key String
14
+
12
15
  chat_options do
16
+
13
17
  frequency_penalty Float
14
18
  logit_bias
15
19
  logprobs [ TrueClass, FalseClass ]
@@ -25,11 +29,14 @@ module Intelligence
25
29
  end
26
30
  seed Integer
27
31
  stop String, array: true
32
+
28
33
  stream [ TrueClass, FalseClass ]
29
34
  stream_options do
30
35
  include_usage [ TrueClass, FalseClass ]
31
36
  end
37
+
32
38
  temperature Float
39
+ tool array: true, as: :tools, &Tool.schema
33
40
  tool_choice do
34
41
  # one of 'auto', 'none' or 'function'
35
42
  type Symbol, in: [ :auto, :none, :function ]
@@ -38,10 +45,13 @@ module Intelligence
38
45
  name String
39
46
  end
40
47
  end
48
+
41
49
  top_logprobs Integer
42
50
  top_p Float
43
51
  user String
52
+
44
53
  end
54
+
45
55
  end
46
56
 
47
57
  end
@@ -5,9 +5,10 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri "https://api.hyperbolic.xyz/v1/chat/completions"
8
+ DEFAULT_BASE_URI = 'https://api.hyperbolic.xyz/v1'
9
9
 
10
10
  schema do
11
+ base_uri String, default: DEFAULT_BASE_URI
11
12
  key String
12
13
  chat_options do
13
14
  model String
@@ -15,7 +16,7 @@ module Intelligence
15
16
  top_p Float
16
17
  n Integer
17
18
  max_tokens Integer
18
- stop String, array: true
19
+ stop String, array: true
19
20
  stream [ TrueClass, FalseClass ]
20
21
  frequency_penalty Float
21
22
  presence_penalty Float
@@ -22,6 +22,8 @@ module Intelligence
22
22
  response_format do
23
23
  type String
24
24
  end
25
+
26
+ tool array: true, as: :tools, &Tool.schema
25
27
  tool_choice do
26
28
  type String
27
29
  function do
@@ -0,0 +1,28 @@
1
+ require_relative 'generic/adapter'
2
+
3
+ module Intelligence
4
+ module Ollama
5
+
6
+ class Adapter < Generic::Adapter
7
+
8
+ DEFAULT_BASE_URI = 'http://localhost:11435/v1'
9
+
10
+ schema do
11
+
12
+ base_uri String, default: DEFAULT_BASE_URI
13
+ key String
14
+
15
+ chat_options do
16
+ max_tokens Integer
17
+ model String
18
+ stop String, array: true
19
+ stream [ TrueClass, FalseClass ]
20
+ temperature Float
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
@@ -8,11 +8,11 @@ module Intelligence
8
8
  schema do
9
9
 
10
10
  # normalized properties for all endpoints
11
- key String
11
+ key String
12
12
 
13
13
  # openai properties for all endpoints
14
- organization String
15
- project String
14
+ organization String
15
+ project String
16
16
 
17
17
  # properties for generative text endpoints
18
18
  chat_options do
@@ -53,15 +53,8 @@ module Intelligence
53
53
  end
54
54
  user
55
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
-
56
+ # open ai tools
57
+ tool array: true, as: :tools, &Tool.schema
65
58
  # open ai tool choice configuration
66
59
  #
67
60
  # `tool_choice :none`
@@ -11,7 +11,7 @@ module Intelligence
11
11
  end
12
12
 
13
13
  def chat_request_headers( options = {} )
14
- options = @options.merge( build_options( options ) )
14
+ options = merge_options( @options, build_options( options ) )
15
15
  result = {}
16
16
 
17
17
  key = options[ :key ]
@@ -30,7 +30,10 @@ module Intelligence
30
30
  end
31
31
 
32
32
  def chat_request_body( conversation, options = {} )
33
- options = @options.merge( build_options( options ) )
33
+
34
+ tools = options.delete( :tools ) || []
35
+
36
+ options = merge_options( @options, build_options( options ) )
34
37
  result = options[ :chat_options ]&.compact || {}
35
38
  result[ :messages ] = []
36
39
 
@@ -120,7 +123,9 @@ module Intelligence
120
123
 
121
124
  end
122
125
 
123
- tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
126
+ tools_attributes = chat_request_tools_attributes(
127
+ ( result[ :tools ] || [] ).concat( tools )
128
+ )
124
129
  result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
125
130
 
126
131
  JSON.generate( result )
@@ -5,11 +5,14 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri "https://openrouter.ai/api/v1/chat/completions"
8
+ DEFAULT_BASE_URI = 'https://openrouter.ai/api/v1'
9
9
 
10
10
  schema do
11
+ base_uri String, default: DEFAULT_BASE_URI
11
12
  key String
13
+
12
14
  chat_options do
15
+
13
16
  model String
14
17
  temperature Float
15
18
  top_k Integer
@@ -27,7 +30,9 @@ module Intelligence
27
30
  require_parameters [ TrueClass, FalseClass ]
28
31
  allow_fallbacks [ TrueClass, FalseClass ]
29
32
  end
33
+
30
34
  end
35
+
31
36
  end
32
37
 
33
38
  # def chat_result_error_attributes( response )
@@ -5,11 +5,12 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri "https://api.sambanova.ai/v1/chat/completions"
8
+ DEFAULT_BASE_URI = "https://api.sambanova.ai/v1"
9
9
 
10
10
  schema do
11
11
 
12
12
  # normalized properties for all endpoints
13
+ base_uri String, default: DEFAULT_BASE_URI
13
14
  key String
14
15
 
15
16
  # properties for generative text endpoints
@@ -42,12 +43,10 @@ module Intelligence
42
43
  }
43
44
 
44
45
  parsed_body = JSON.parse( response.body, symbolize_names: true ) rescue nil
45
- if parsed_body && parsed_body.respond_to?( :include? ) && parsed_body.include?( :error )
46
- result = {
47
- error_type: error_type.to_s,
48
- error: parsed_body[ :error ][ :code ] || error_type.to_s,
49
- error_description: parsed_body[ :error ][ :message ] || error_description
50
- }
46
+ if parsed_body &&
47
+ parsed_body.respond_to?( :include? ) && parsed_body.include?( :error ) &&
48
+ parsed_body[ :error ].is_a?( String )
49
+ result[ :error_description ] = parsed_body[ :error ]
51
50
  elsif response.headers[ 'content-type' ].start_with?( 'text/plain' ) &&
52
51
  response.body && response.body.length > 0
53
52
  result[ :error_description ] = response.body
@@ -5,9 +5,10 @@ module Intelligence
5
5
 
6
6
  class Adapter < Generic::Adapter
7
7
 
8
- chat_request_uri "https://api.together.xyz/v1/chat/completions"
9
-
8
+ DEFAULT_BASE_URI = "https://api.together.xyz/v1"
9
+
10
10
  schema do
11
+ base_uri String, default: DEFAULT_BASE_URI
11
12
  key String
12
13
  chat_options do
13
14
  model String
@@ -21,6 +22,24 @@ module Intelligence
21
22
  frequency_penalty Float
22
23
  presence_penalty Float
23
24
  repetition_penalty Float
25
+
26
+ # together ai tools
27
+ tool array: true, as: :tools, &Tool.schema
28
+ # together ai tool choice configuration
29
+ #
30
+ # `tool_choice :auto`
31
+ # or
32
+ # ```
33
+ # tool_choice :function do
34
+ # function :my_function
35
+ # end
36
+ # ```
37
+ tool_choice arguments: :type do
38
+ type Symbol, in: [ :none, :auto, :function ]
39
+ function arguments: :name do
40
+ name Symbol
41
+ end
42
+ end
24
43
  user String
25
44
  end
26
45
  end
@@ -23,9 +23,13 @@ module Intelligence
23
23
  stream [ TrueClass, FalseClass ]
24
24
  stream_options
25
25
  temperature Float, in: 0..2
26
+
27
+ tool array: true, as: :tools, &Tool.schema
26
28
  tool_choice
29
+
27
30
  top_logprobs Integer, in: 0..20
28
31
  top_p Float
32
+
29
33
  user String
30
34
  end
31
35
  end
@@ -75,21 +75,23 @@ module Intelligence
75
75
  # === arguments
76
76
  # * +conversation+ - an instance of +Intelligence::Conversation+ or String; this encapsulates
77
77
  # the content to be sent to the LLM
78
- # * +options+ - a Hash with options; these options overide any of the configuration
79
- # options used to configure the adapter; you can, for example, pass
80
- # +{ chat_options: { max_tokens: 1024 }+ to limit the response to 1024
81
- # tokens.
82
- def chat( conversation, options = {} )
78
+ # * +options+ - one or more Hashes with options; these options overide any of the
79
+ # configuration options used to configure the adapter; you can, for
80
+ # example, pass +{ chat_options: { max_tokens: 1024 }+ to limit the
81
+ # response to 1024 tokens.
82
+ def chat( conversation, *options )
83
83
 
84
84
  conversation = build_quick_conversation( conversation ) if conversation.is_a?( String )
85
+ options = options.compact.reduce( {} ) { | accumulator, o | accumulator.merge( o ) }
85
86
  options = @options.merge( options )
86
87
 
88
+ # conversation and tools are presented as simple Hashes to the adapter
89
+ conversation = conversation.to_h
90
+ options[ :tools ] = options[ :tools ].to_a.map!( &:to_h ) if options[ :tools ]
91
+
87
92
  uri = @adapter.chat_request_uri( options )
88
- headers = @adapter.chat_request_headers( @options.merge( options ) )
89
- payload = @adapter.chat_request_body(
90
- conversation.to_h,
91
- options
92
- )
93
+ headers = @adapter.chat_request_headers( options )
94
+ payload = @adapter.chat_request_body( conversation, options )
93
95
 
94
96
  result_callback = nil
95
97
  response = @connection.post( uri ) do | request |
@@ -100,6 +102,7 @@ module Intelligence
100
102
  end
101
103
 
102
104
  result = nil
105
+
103
106
  if response.success?
104
107
  chat_result_attributes = @adapter.chat_result_attributes( response )
105
108
  result = ChatResult.new( chat_result_attributes )
@@ -113,14 +116,19 @@ module Intelligence
113
116
 
114
117
  end
115
118
 
116
- def stream( conversation, options = {} )
119
+ def stream( conversation, *options )
117
120
 
118
121
  conversation = build_quick_conversation( conversation ) if conversation.is_a?( String )
122
+ options = options.compact.reduce( {} ) { | accumulator, o | accumulator.merge( o ) }
119
123
  options = @options.merge( options )
124
+
125
+ # conversation and tools are presented as simple Hashes to the adapter
126
+ conversation = conversation.to_h
127
+ options[ :tools ] = options[ :tools ].to_a.map!( &:to_h ) if options[ :tools ]
120
128
 
121
129
  uri = @adapter.chat_request_uri( options )
122
130
  headers = @adapter.chat_request_headers( @options.merge( options ) )
123
- payload = @adapter.chat_request_body( conversation.to_h, options )
131
+ payload = @adapter.chat_request_body( conversation, options )
124
132
 
125
133
  context = nil
126
134
  response = @connection.post( uri ) do | request |
@@ -11,12 +11,10 @@ module Intelligence
11
11
 
12
12
  attr_reader :system_message
13
13
  attr_reader :messages
14
- attr_reader :tools
15
14
 
16
15
  def initialize( attributes = nil )
17
16
 
18
17
  @messages = []
19
- @tools = []
20
18
  if attributes
21
19
  if attributes[ :system_message ]&.any?
22
20
  system_message = Message.new(
@@ -41,10 +39,6 @@ module Intelligence
41
39
  !@messages.empty?
42
40
  end
43
41
 
44
- def has_tools?
45
- !@tools.empty?
46
- end
47
-
48
42
  def system_message=( message )
49
43
  raise ArgumentError, "The system message must be a Intelligence::Message." \
50
44
  unless message.is_a?( Intelligence::Message )
@@ -60,16 +54,10 @@ module Intelligence
60
54
 
61
55
  alias :<< :append_message
62
56
 
63
- def append_tool( *tools )
64
- @tools.concat( tools.flatten )
65
- self
66
- end
67
-
68
57
  def to_h
69
58
  result = {}
70
59
  result[ :system_message ] = @system_message.to_h if @system_message
71
60
  result[ :messages ] = @messages.map { | m | m.to_h }
72
- result[ :tools ] = @tools.map { | t | t.to_h }
73
61
  result
74
62
  end
75
63
 
@@ -26,6 +26,7 @@ module Intelligence
26
26
  tool_result: tool_result
27
27
  }.compact
28
28
  end
29
+
29
30
  end
30
31
 
31
32
  end
@@ -1,3 +1,3 @@
1
1
  module Intelligence
2
- VERSION = "1.0.0.beta03"
2
+ VERSION = "1.0.0.beta05"
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intelligence
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta03
4
+ version: 1.0.0.beta05
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristoph Cichocki-Romanov
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-11-12 00:00:00.000000000 Z
10
+ date: 2025-06-07 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -30,14 +29,14 @@ dependencies:
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: 1.0.0.beta03
32
+ version: '1.0'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: 1.0.0.beta03
39
+ version: '1.0'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: mime-types
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +134,7 @@ files:
135
134
  - lib/intelligence/adapters/anthropic/chat_request_methods.rb
136
135
  - lib/intelligence/adapters/anthropic/chat_response_methods.rb
137
136
  - lib/intelligence/adapters/cerebras.rb
137
+ - lib/intelligence/adapters/deepseek.rb
138
138
  - lib/intelligence/adapters/generic.rb
139
139
  - lib/intelligence/adapters/generic/adapter.rb
140
140
  - lib/intelligence/adapters/generic/chat_request_methods.rb
@@ -146,6 +146,7 @@ files:
146
146
  - lib/intelligence/adapters/groq.rb
147
147
  - lib/intelligence/adapters/hyperbolic.rb
148
148
  - lib/intelligence/adapters/mistral.rb
149
+ - lib/intelligence/adapters/ollama.rb
149
150
  - lib/intelligence/adapters/open_ai.rb
150
151
  - lib/intelligence/adapters/open_ai/adapter.rb
151
152
  - lib/intelligence/adapters/open_ai/chat_request_methods.rb
@@ -180,7 +181,6 @@ licenses:
180
181
  metadata:
181
182
  source_code_uri: https://github.com/EndlessInternational/intelligence
182
183
  bug_tracker_uri: https://github.com/EndlessInternational/intelligence/issues
183
- post_install_message:
184
184
  rdoc_options: []
185
185
  require_paths:
186
186
  - lib
@@ -195,8 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
195
  - !ruby/object:Gem::Version
196
196
  version: '0'
197
197
  requirements: []
198
- rubygems_version: 3.5.19
199
- signing_key:
198
+ rubygems_version: 3.6.2
200
199
  specification_version: 4
201
200
  summary: A Ruby gem for seamlessly and uniformly interacting with large languge and
202
201
  vision model (LLM) API's served by numerous services, including those of OpenAI,