langchainrb 0.19.1 → 0.19.2

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: 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