intelligence 1.0.0.beta02 → 1.0.0.beta04

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: e92ea1646a9ec5f91a9a8e991c838896c415a94715aeeccd7013363e34009b1b
4
- data.tar.gz: 67b7fcb6020325d405e463ab2efbc18b44c772e94b76d3ce622fc652de7b4c18
3
+ metadata.gz: df9c6c9d4ecd7c8adde5eb20067ceef7f9f88ab5602c862b50635039fad13e81
4
+ data.tar.gz: 4af029c32fba747acd6a1fff0daa3e6de6ab049e20240e9dfbcbf4b5c454a867
5
5
  SHA512:
6
- metadata.gz: 107cb5ddec885d6700b88742474e2948e2abc94da6500b0b1fb39d039c8292fbd648efe4e67b2866d918107759ac111a15de949b3256dc8d2049df52af6cd792
7
- data.tar.gz: 5052f6057fafd04bd1c310f67de4a89dbbea32f8c279ec5e2bdbd397378629e1cff17ce853774881c0736ee0f9407a5dfd25b63aab9750955737885f8829c489
6
+ metadata.gz: 7cfdef5d95d37a78f73ad283565f74e706fdcff384c224ff9a92012ee0888179f536f93d34580fd49ee0663800da3066d6174231a5536e917cabde04b1c72ae8
7
+ data.tar.gz: 54b476462cf87767cc7b10c95bdc6e149a1b1b4de59ef1795c70761813594d971e8d6690aeeee22756caf8fce8d107edfd97d78b07b7c9db4c2ee7f2981b0ad4
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?
@@ -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
@@ -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 )
@@ -21,6 +21,7 @@ module Intelligence
21
21
  stream [ TrueClass, FalseClass ]
22
22
  temperature Float
23
23
  top_p Float
24
+ tool array: true, as: :tools, &Tool.schema
24
25
  tool_choice do
25
26
  type String
26
27
  mame String
@@ -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
@@ -21,7 +21,7 @@ module Intelligence
21
21
  end
22
22
 
23
23
  def chat_request_headers( options = nil )
24
- options = @options.merge( build_options( options ) )
24
+ options = merge_options( @options, build_options( options ) )
25
25
  result = {}
26
26
 
27
27
  key = options[ :key ]
@@ -36,7 +36,9 @@ module Intelligence
36
36
  end
37
37
 
38
38
  def chat_request_body( conversation, options = nil )
39
- options = @options.merge( build_options( options ) )
39
+ tools = options.delete( :tools ) || []
40
+
41
+ options = merge_options( @options, build_options( options ) )
40
42
 
41
43
  result = options[ :chat_options ]
42
44
  result[ :messages ] = []
@@ -102,7 +104,9 @@ module Intelligence
102
104
  end
103
105
  end
104
106
 
105
- tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
107
+ tools_attributes = chat_request_tools_attributes(
108
+ ( result[ :tools ] || [] ).concat( tools )
109
+ )
106
110
  result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
107
111
 
108
112
  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
 
@@ -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
- gc = options[ :generationConfig ]
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
@@ -30,6 +30,7 @@ module Intelligence
30
30
  include_usage [ TrueClass, FalseClass ]
31
31
  end
32
32
  temperature Float
33
+ tool array: true, as: :tools, &Tool.schema
33
34
  tool_choice do
34
35
  # one of 'auto', 'none' or 'function'
35
36
  type Symbol, in: [ :auto, :none, :function ]
@@ -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
@@ -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 )
@@ -21,6 +21,24 @@ module Intelligence
21
21
  frequency_penalty Float
22
22
  presence_penalty Float
23
23
  repetition_penalty Float
24
+
25
+ # together ai tools
26
+ tool array: true, as: :tools, &Tool.schema
27
+ # together ai tool choice configuration
28
+ #
29
+ # `tool_choice :auto`
30
+ # or
31
+ # ```
32
+ # tool_choice :function do
33
+ # function :my_function
34
+ # end
35
+ # ```
36
+ tool_choice arguments: :type do
37
+ type Symbol, in: [ :none, :auto, :function ]
38
+ function arguments: :name do
39
+ name Symbol
40
+ end
41
+ end
24
42
  user String
25
43
  end
26
44
  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
93
  headers = @adapter.chat_request_headers( @options.merge( options ) )
89
- payload = @adapter.chat_request_body(
90
- conversation.to_h,
91
- options
92
- )
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.beta02"
2
+ VERSION = "1.0.0.beta04"
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.beta02
4
+ version: 1.0.0.beta04
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-04 00:00:00.000000000 Z
10
+ date: 2025-01-21 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -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
@@ -180,7 +180,6 @@ licenses:
180
180
  metadata:
181
181
  source_code_uri: https://github.com/EndlessInternational/intelligence
182
182
  bug_tracker_uri: https://github.com/EndlessInternational/intelligence/issues
183
- post_install_message:
184
183
  rdoc_options: []
185
184
  require_paths:
186
185
  - lib
@@ -195,8 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
194
  - !ruby/object:Gem::Version
196
195
  version: '0'
197
196
  requirements: []
198
- rubygems_version: 3.5.19
199
- signing_key:
197
+ rubygems_version: 3.6.2
200
198
  specification_version: 4
201
199
  summary: A Ruby gem for seamlessly and uniformly interacting with large languge and
202
200
  vision model (LLM) API's served by numerous services, including those of OpenAI,