smart_agent 0.1.2 → 0.1.4

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: f34059e0f8389ab46e42221507a17545c3e5baf0ae63c5d7273018168f608d30
4
- data.tar.gz: cf815b9c79556577b56328ef992dfa5f522871c4c805b8d7d1e8c24d24a45947
3
+ metadata.gz: aad42cabbf228718122054fac2c219a4dac68e2b4cd0314160a2929972eb9583
4
+ data.tar.gz: 177428d5673d9529d7fded1abac348e8168b0186995ef581e5addaf54bef9355
5
5
  SHA512:
6
- metadata.gz: 0a5ee8bc0ac6af2c198ba15d855b5fcdf181fb27cce922e7f0f649018e3aaa8ed3836723fa4cd2b41d3b1afa2806b679980a5e64a3fdecc33cddd596287ad861
7
- data.tar.gz: 9da300c1c13c8c0828d92ccd2ae7caa3bb228be51439bab7dc6ab4211f22686d76f91a4c11fab56bd67d62b412dd375fb6ab294e4805b8fffd62105d95a25670
6
+ metadata.gz: 3cdbda0be5802a5bdcb52b3c5bfc92e075824803a0f4e5cbac13bda79180f099d19d4c8d4fe1adaf14c2a6e0c2c8a20892f1e1554de0bc30ab57d0c2acb7c6a0
7
+ data.tar.gz: 29c74e9f6dd2839c139d37f05c0ba309e8d2e0f11e7120badb5ca6d988984d2e382b63c6572168e3ec3403ca8e58e390258e39f86b5d1c99c9bef9f2540a6068
@@ -65,13 +65,12 @@ module SmartAgent
65
65
  @agent = agent
66
66
  end
67
67
 
68
- def call_worker(name, params, result: nil, with_tools: true)
69
- if result
70
- params[:result] = result
71
- end
68
+ def call_worker(name, params, with_tools: true, with_history: false)
69
+ SmartAgent.logger.info ("Call Worker name is: #{name}")
72
70
  if with_tools
71
+ simple_tools = []
73
72
  if @agent.tools
74
- simple_tools = @agent.tools.map { |tool_name| Tool.new(tool_name).to_json }
73
+ simple_tools = @agent.tools.map { |tool_name| Tool.find_tool(tool_name).to_json }
75
74
  end
76
75
  if @agent.servers
77
76
  mcp_tools = @agent.servers.map { |mcp_name| MCPClient.new(mcp_name).to_json }
@@ -83,21 +82,51 @@ module SmartAgent
83
82
  end
84
83
  params[:tools] = simple_tools
85
84
  end
85
+ params[:with_history] = with_history
86
86
  ret = nil
87
- if @agent.on_event && with_tools == false
88
- SmartAgent.prompt_engine.call_worker_by_stream(name, params) do |chunk, _bytesize|
87
+ if @agent.on_event
88
+ tool_result = {}
89
+ tool_calls = []
90
+ result = SmartAgent.prompt_engine.call_worker_by_stream(name, params) do |chunk, _bytesize|
91
+ if tool_result.empty?
92
+ tool_result["id"] = chunk["id"]
93
+ tool_result["object"] = chunk["object"]
94
+ tool_result["created"] = chunk["created"]
95
+ tool_result["model"] = chunk["model"]
96
+ tool_result["choices"] = [{
97
+ "index" => 0,
98
+ "message" => {
99
+ "role" => "assistant",
100
+ "content" => "",
101
+ "tool_calls" => [],
102
+ },
103
+ }]
104
+ tool_result["usage"] = chunk["usage"]
105
+ tool_result["system_fingerprint"] = chunk["system_fingerprint"]
106
+ end
89
107
  if chunk.dig("choices", 0, "delta", "reasoning_content")
90
108
  @agent.processor(:reasoning).call(chunk) if @agent.processor(:reasoning)
91
109
  end
92
110
  if chunk.dig("choices", 0, "delta", "content")
93
111
  @agent.processor(:content).call(chunk) if @agent.processor(:content)
94
112
  end
113
+ if chunk_tool_calls = chunk.dig("choices", 0, "delta", "tool_calls")
114
+ chunk_tool_calls.each do |tool_call|
115
+ if tool_calls.size > tool_call["index"]
116
+ tool_calls[tool_call["index"]]["function"]["arguments"] += tool_call["function"]["arguments"]
117
+ else
118
+ tool_calls << tool_call
119
+ end
120
+ end
121
+ end
95
122
  end
123
+ tool_result["choices"][0]["message"]["tool_calls"] = tool_calls
124
+ result = tool_result
96
125
  else
97
126
  result = SmartAgent.prompt_engine.call_worker(name, params)
98
- ret = Result.new(result)
99
- return ret
100
127
  end
128
+ ret = Result.new(result)
129
+ return ret
101
130
  end
102
131
 
103
132
  def call_tools(result)
@@ -105,15 +134,24 @@ module SmartAgent
105
134
  SmartAgent.logger.info("call tools: " + result.to_s)
106
135
  results = []
107
136
  result.call_tools.each do |tool|
137
+ tool_call_id = tool["id"]
108
138
  tool_name = tool["function"]["name"].to_sym
109
139
  params = JSON.parse(tool["function"]["arguments"])
110
140
  if Tool.find_tool(tool_name)
111
- @agent.processor(:tool).call({ :content => "ToolName is `#{tool_name}`" }) if @agent.processor(:tool)
112
- results << Tool.new(tool_name).call(params)
141
+ @agent.processor(:tool).call({ :content => "ToolName is `#{tool_name}`\n" }) if @agent.processor(:tool)
142
+ @agent.processor(:tool).call({ :content => "params is `#{params}`\n" }) if @agent.processor(:tool)
143
+ tool_result = Tool.find_tool(tool_name).call(params)
144
+ SmartAgent.prompt_engine.history_messages << result.response.dig("choices", 0, "message")
145
+ SmartAgent.prompt_engine.history_messages << { "role" => "tool", "tool_call_id" => tool_call_id, "content" => tool_result.to_s.force_encoding("UTF-8") }
146
+ results << result
113
147
  end
114
148
  if server_name = MCPClient.find_server_by_tool_name(tool_name)
115
- @agent.processor(:tool).call({ :content => "MCP Server is `#{server_name}`, ToolName is `#{tool_name}`" }) if @agent.processor(:tool)
116
- results << MCPClient.new(server_name).call(tool_name, params)
149
+ @agent.processor(:tool).call({ :content => "MCP Server is `#{server_name}`, ToolName is `#{tool_name}`\n" }) if @agent.processor(:tool)
150
+ @agent.processor(:tool).call({ :content => "params is `#{params}`\n" }) if @agent.processor(:tool)
151
+ tool_result = MCPClient.new(server_name).call(tool_name, params)
152
+ SmartAgent.prompt_engine.history_messages << result.response.dig("choices", 0, "message")
153
+ SmartAgent.prompt_engine.history_messages << { "role" => "tool", "tool_call_id" => tool_call_id, "content" => tool_result.to_s }
154
+ results << result
117
155
  end
118
156
  @agent.processor(:tool).call({ :content => " ... done\n" }) if @agent.processor(:tool)
119
157
  end
@@ -7,9 +7,14 @@ module SmartAgent
7
7
 
8
8
  def call_tools
9
9
  if @response.class == String
10
- return nil
10
+ return false
11
11
  else
12
- @response.dig("choices", 0, "message", "tool_calls")
12
+ tool_calls = @response.dig("choices", 0, "message", "tool_calls")
13
+ if tool_calls.empty?
14
+ return false
15
+ else
16
+ return tool_calls
17
+ end
13
18
  end
14
19
  end
15
20
 
@@ -1,22 +1,20 @@
1
1
  module SmartAgent
2
2
  class Tool
3
+ attr_accessor :context, :tool_proc
4
+
3
5
  def initialize(name)
4
6
  SmartAgent.logger.info "Create tool's name is #{name}"
5
7
  @name = name
6
- @code = self.class.tools[name]
8
+ @context = ToolContext.new(self)
7
9
  end
8
10
 
9
11
  def call(params)
10
- @context = ToolContext.new
11
12
  @context.input_params = params
12
- @context.instance_eval(&@code)
13
+ @context.instance_eval(&@context.proc)
13
14
  end
14
15
 
15
16
  def to_json
16
- @context = ToolContext.new
17
- @context.instance_eval(&@code)
18
17
  params = @context.params
19
-
20
18
  properties = params.each_with_object({}) do |(name, details), hash|
21
19
  hash[name] = {
22
20
  type: details[:type],
@@ -28,7 +26,7 @@ module SmartAgent
28
26
  type: "function",
29
27
  function: {
30
28
  name: @name,
31
- description: "",
29
+ description: @context.description,
32
30
  parameters: {
33
31
  type: "object",
34
32
  properties: properties,
@@ -44,7 +42,9 @@ module SmartAgent
44
42
  end
45
43
 
46
44
  def define(name, &block)
47
- tools[name] = block
45
+ tool = Tool.new(name)
46
+ tools[name] = tool
47
+ tool.context.instance_eval(&block)
48
48
  end
49
49
 
50
50
  def find_tool(name)
@@ -54,7 +54,11 @@ module SmartAgent
54
54
  end
55
55
 
56
56
  class ToolContext
57
- attr_accessor :input_params
57
+ attr_accessor :input_params, :description, :proc
58
+
59
+ def initialize(tool)
60
+ @tool = tool
61
+ end
58
62
 
59
63
  def params
60
64
  @params ||= {}
@@ -64,8 +68,17 @@ module SmartAgent
64
68
  params[name] = { description: description, type: type }
65
69
  end
66
70
 
71
+ def desc(description)
72
+ @description = description
73
+ end
74
+
67
75
  def call_worker(name, params)
76
+ params[:with_history] = false
68
77
  SmartAgent.prompt_engine.call_worker(name, params)
69
78
  end
79
+
80
+ def tool_proc(&block)
81
+ @proc = block
82
+ end
70
83
  end
71
84
  end
@@ -1,3 +1,3 @@
1
1
  module SmartAgent
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Your Name
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-30 00:00:00.000000000 Z
10
+ date: 2025-04-09 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: smart_prompt
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.0'
18
+ version: 0.2.7
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.0'
25
+ version: 0.2.7
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
28
  requirement: !ruby/object:Gem::Requirement