langchainrb 0.19.1 → 0.19.2

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: 6c33b1ac19c1cf4a3a7de8fbf5d2568899d05662cb7db0b96321186c255ef312
4
- data.tar.gz: 96bad2ff6f9b9a9cbac26699b525a8646482a0a77131d58fed84de3bafcb074e
3
+ metadata.gz: 86b8bd9a7b846fb7be528116984e3e6353ea36ee75f06ddae8872c9b70c8deee
4
+ data.tar.gz: 3cc860f9d448d5e7df4eef2ea7e136e2381f3aecee4ffd245ebd41df7b9bd650
5
5
  SHA512:
6
- metadata.gz: aef30f32cfbdba307372ab8b20a0a484d22bd72f68d614056c6abb016b16dbd5e7a51dc15fb26746fd7a88a429d6282848aace42076c41e4fb31d58be9fb27f6
7
- data.tar.gz: 3fd751a81f1121209ae2fac6bd25bb2e9d524b23dd5afe83967e10a78521e6994b7ca855e7e4343dded1117c5a7377d26cf15607f16247e9f220a27d17b91827
6
+ metadata.gz: 55128bb86766b2fb3e852764603df1786df971f736328f115581666eb7779249b0236058edf31a53a8197929496b2d1d5f667c26e04ff759a6763028d892735a
7
+ data.tar.gz: '028c8049dd2d2642d4652dfe1df94d7f94a4acfadb5cf61e46b2ac82a392022eafde5e5be8820f3919c1ffe1c73693d56b09bf60fbcdb1e207ae3abcec5abaaa'
data/CHANGELOG.md CHANGED
@@ -11,6 +11,9 @@
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.19.2] - 2024-11-26
15
+ - [FEATURE] [https://github.com/patterns-ai-core/langchainrb/pull/884] Add `tool_execution_callback` to `Langchain::Assistant`, a callback function (proc, lambda) that is called right before a tool is executed
16
+
14
17
  ## [0.19.1] - 2024-11-21
15
18
  - [FEATURE] [https://github.com/patterns-ai-core/langchainrb/pull/858] Assistant, when using Anthropic, now also accepts image_url in the message.
16
19
  - [FEATURE] [https://github.com/patterns-ai-core/langchainrb/pull/861] Clean up passing `max_tokens` to Anthropic constructor and chat method
data/README.md CHANGED
@@ -536,6 +536,13 @@ Note that streaming is not currently supported for all LLMs.
536
536
  * `tool_choice`: Specifies how tools should be selected. Default: "auto". A specific tool function name can be passed. This will force the Assistant to **always** use this function.
537
537
  * `parallel_tool_calls`: Whether to make multiple parallel tool calls. Default: true
538
538
  * `add_message_callback`: A callback function (proc, lambda) that is called when any message is added to the conversation (optional)
539
+ ```ruby
540
+ assistant.add_message_callback = -> (message) { puts "New message: #{message}" }
541
+ ```
542
+ * `tool_execution_callback`: A callback function (proc, lambda) that is called right before a tool is executed (optional)
543
+ ```ruby
544
+ assistant.tool_execution_callback = -> (tool_call_id, tool_name, method_name, tool_arguments) { puts "Executing tool_call_id: #{tool_call_id}, tool_name: #{tool_name}, method_name: #{method_name}, tool_arguments: #{tool_arguments}" }
545
+ ```
539
546
 
540
547
  ### Key Methods
541
548
  * `add_message`: Adds a user message to the messages array
@@ -24,6 +24,7 @@ module Langchain
24
24
 
25
25
  attr_accessor :tools,
26
26
  :add_message_callback,
27
+ :tool_execution_callback,
27
28
  :parallel_tool_calls
28
29
 
29
30
  # Create a new assistant
@@ -35,6 +36,7 @@ module Langchain
35
36
  # @param parallel_tool_calls [Boolean] Whether or not to run tools in parallel
36
37
  # @param messages [Array<Langchain::Assistant::Messages::Base>] The messages
37
38
  # @param add_message_callback [Proc] A callback function (Proc or lambda) that is called when any message is added to the conversation
39
+ # @param tool_execution_callback [Proc] A callback function (Proc or lambda) that is called right before a tool function is executed
38
40
  def initialize(
39
41
  llm:,
40
42
  tools: [],
@@ -42,7 +44,9 @@ module Langchain
42
44
  tool_choice: "auto",
43
45
  parallel_tool_calls: true,
44
46
  messages: [],
47
+ # Callbacks
45
48
  add_message_callback: nil,
49
+ tool_execution_callback: nil,
46
50
  &block
47
51
  )
48
52
  unless tools.is_a?(Array) && tools.all? { |tool| tool.class.singleton_class.included_modules.include?(Langchain::ToolDefinition) }
@@ -52,11 +56,8 @@ module Langchain
52
56
  @llm = llm
53
57
  @llm_adapter = LLM::Adapter.build(llm)
54
58
 
55
- # TODO: Validate that it is, indeed, a Proc or lambda
56
- if !add_message_callback.nil? && !add_message_callback.respond_to?(:call)
57
- raise ArgumentError, "add_message_callback must be a callable object, like Proc or lambda"
58
- end
59
- @add_message_callback = add_message_callback
59
+ @add_message_callback = add_message_callback if validate_callback!("add_message_callback", add_message_callback)
60
+ @tool_execution_callback = tool_execution_callback if validate_callback!("tool_execution_callback", tool_execution_callback)
60
61
 
61
62
  self.messages = messages
62
63
  @tools = tools
@@ -353,16 +354,26 @@ module Langchain
353
354
  def run_tools(tool_calls)
354
355
  # Iterate over each function invocation and submit tool output
355
356
  tool_calls.each do |tool_call|
356
- tool_call_id, tool_name, method_name, tool_arguments = @llm_adapter.extract_tool_call_args(tool_call: tool_call)
357
+ run_tool(tool_call)
358
+ end
359
+ end
357
360
 
358
- tool_instance = tools.find do |t|
359
- t.class.tool_name == tool_name
360
- end or raise ArgumentError, "Tool: #{tool_name} not found in assistant.tools"
361
+ # Run the tool call
362
+ #
363
+ # @param tool_call [Hash] The tool call to run
364
+ # @return [Object] The result of the tool call
365
+ def run_tool(tool_call)
366
+ tool_call_id, tool_name, method_name, tool_arguments = @llm_adapter.extract_tool_call_args(tool_call: tool_call)
361
367
 
362
- output = tool_instance.send(method_name, **tool_arguments)
368
+ tool_instance = tools.find do |t|
369
+ t.class.tool_name == tool_name
370
+ end or raise ArgumentError, "Tool: #{tool_name} not found in assistant.tools"
363
371
 
364
- submit_tool_output(tool_call_id: tool_call_id, output: output)
365
- end
372
+ # Call the callback if set
373
+ tool_execution_callback.call(tool_call_id, tool_name, method_name, tool_arguments) if tool_execution_callback # rubocop:disable Style/SafeNavigation
374
+ output = tool_instance.send(method_name, **tool_arguments)
375
+
376
+ submit_tool_output(tool_call_id: tool_call_id, output: output)
366
377
  end
367
378
 
368
379
  # Build a message
@@ -392,5 +403,13 @@ module Langchain
392
403
  def available_tool_names
393
404
  llm_adapter.available_tool_names(tools)
394
405
  end
406
+
407
+ def validate_callback!(attr_name, callback)
408
+ if !callback.nil? && !callback.respond_to?(:call)
409
+ raise ArgumentError, "#{attr_name} must be a callable object, like Proc or lambda"
410
+ end
411
+
412
+ true
413
+ end
395
414
  end
396
415
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Langchain
4
- VERSION = "0.19.1"
4
+ VERSION = "0.19.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langchainrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Bondarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-21 00:00:00.000000000 Z
11
+ date: 2024-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: baran