intelligence 1.0.0.beta03 → 1.0.0.beta04

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: 77033342b73065a73acde0156a288f66fb0ef7413a939292d23886b353397fd3
4
- data.tar.gz: 6a8c7131991c0af60d9e30c000048ae9cb7e562e7c7dbb9ca519febe486d8491
3
+ metadata.gz: df9c6c9d4ecd7c8adde5eb20067ceef7f9f88ab5602c862b50635039fad13e81
4
+ data.tar.gz: 4af029c32fba747acd6a1fff0daa3e6de6ab049e20240e9dfbcbf4b5c454a867
5
5
  SHA512:
6
- metadata.gz: 65050bd8d219f8348a0fe6c5b6cbc951a8de190572c01ecdc7e947aa2fa207f4fb65ae0e6afc2658ecf1fbe50ca0fd5b58c5fcf2651cc416fb9e6aeff73c97df
7
- data.tar.gz: 17ef75ad141fc8f25f0a62a32c1b677785340b0bd15c8f907c455a10b5d7e35532728e7f36cb62b3ccb3ebe0c835b8facd6777832dda955bb09aabae1802975b
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
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.beta03"
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.beta03
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-12 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,