act_as_agent 0.1.0 → 0.3.0
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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +9 -1
- data/idea.rb +25 -0
- data/lib/act_as_agent/api_clients/anthropic_api_client.rb +18 -0
- data/lib/act_as_agent/base.rb +28 -3
- data/lib/act_as_agent/errors/providers/anthropic/authentication_error.rb +10 -0
- data/lib/act_as_agent/errors/tool_incorrect_args_error.rb +8 -0
- data/lib/act_as_agent/providers/anthropic.rb +18 -22
- data/lib/act_as_agent/tools/list_files.rb +45 -0
- data/lib/act_as_agent/tools/read_file.rb +45 -0
- data/lib/act_as_agent.rb +0 -1
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f0a2fea9ab22df1f6420509ac58b4e666fe2b935fa4a452a651f366a50b9201
|
|
4
|
+
data.tar.gz: 1b1b554adc81bbfbcb325fa7abbaf2b7b06e06428e61123aabbb264fc718bc2f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc8afbb5eb5106ca85c1fe5f65199fd21f25e0450064b8fd519d545ac88d92120c07b18ba4cdfc87b5c28ee33c326233ca6442305b95e0cab1c939d470f5367a
|
|
7
|
+
data.tar.gz: a8311e8f892629d8d8b51e62c322e77e1ab989ae45bedc41286c9805327ed3f892e5f66d6be77c75e96a17329d4651ca021a2e89c1d4e7048fc4a1f1b477c671
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
act_as_agent (0.
|
|
4
|
+
act_as_agent (0.2.0)
|
|
5
5
|
act_as_api_client (~> 1.3.1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -18,6 +18,7 @@ GEM
|
|
|
18
18
|
bigdecimal
|
|
19
19
|
rexml
|
|
20
20
|
diff-lcs (1.6.2)
|
|
21
|
+
docile (1.4.1)
|
|
21
22
|
event_stream_parser (1.0.0)
|
|
22
23
|
hashdiff (1.2.1)
|
|
23
24
|
json (2.16.0)
|
|
@@ -62,6 +63,12 @@ GEM
|
|
|
62
63
|
parser (>= 3.3.7.2)
|
|
63
64
|
prism (~> 1.4)
|
|
64
65
|
ruby-progressbar (1.13.0)
|
|
66
|
+
simplecov (0.22.0)
|
|
67
|
+
docile (~> 1.1)
|
|
68
|
+
simplecov-html (~> 0.11)
|
|
69
|
+
simplecov_json_formatter (~> 0.1)
|
|
70
|
+
simplecov-html (0.13.2)
|
|
71
|
+
simplecov_json_formatter (0.1.4)
|
|
65
72
|
unicode-display_width (3.2.0)
|
|
66
73
|
unicode-emoji (~> 4.1)
|
|
67
74
|
unicode-emoji (4.1.0)
|
|
@@ -81,6 +88,7 @@ DEPENDENCIES
|
|
|
81
88
|
rake (~> 13.0)
|
|
82
89
|
rspec (~> 3.0)
|
|
83
90
|
rubocop (~> 1.21)
|
|
91
|
+
simplecov (~> 0.22.0)
|
|
84
92
|
vcr (~> 6.3)
|
|
85
93
|
webmock (~> 3.26)
|
|
86
94
|
|
data/idea.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class MyCodingAgent
|
|
4
|
+
include ActAsAgent::Base
|
|
5
|
+
|
|
6
|
+
tools [edit_file, read_file, list_files, run_rspec]
|
|
7
|
+
|
|
8
|
+
def task_with; end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class BookAuthorAgent
|
|
12
|
+
include ActAsAgent::Base
|
|
13
|
+
|
|
14
|
+
tools [edit_file, read_file, list_files]
|
|
15
|
+
|
|
16
|
+
def task_with; end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class GameCreatorAgent
|
|
20
|
+
include ActAsAgent::Base
|
|
21
|
+
|
|
22
|
+
tools [edit_file, read_file, list_files]
|
|
23
|
+
|
|
24
|
+
def task_with; end
|
|
25
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "act_as_api_client"
|
|
4
|
+
|
|
5
|
+
module ActAsAgent
|
|
6
|
+
module ApiClients
|
|
7
|
+
class AnthropicClient < ApiClient
|
|
8
|
+
act_as_api_client for: %i[anthropic messages]
|
|
9
|
+
|
|
10
|
+
def initialize(key:, max_tokens:)
|
|
11
|
+
super()
|
|
12
|
+
|
|
13
|
+
options[:x_api_key] = key
|
|
14
|
+
options[:max_tokens] = max_tokens
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/act_as_agent/base.rb
CHANGED
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "act_as_agent/providers/anthropic"
|
|
4
|
+
|
|
3
5
|
module ActAsAgent
|
|
4
6
|
module Base
|
|
5
7
|
def self.included(base)
|
|
6
8
|
base.extend(ClassMethods)
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
def run()
|
|
11
|
+
def run(args)
|
|
12
|
+
llm_provider.request(content: args[:task])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tools
|
|
16
|
+
@tools ||= self.class.instance_variable_get("@tools") || []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def llm_provider
|
|
20
|
+
klass = self.class.instance_variable_get("@llm_provider")
|
|
21
|
+
@llm_provider ||= if klass == ActAsAgent::Providers::Anthropic
|
|
22
|
+
key = llm_provider_options.fetch(:key, nil)
|
|
23
|
+
ActAsAgent::Providers::Anthropic.new(tools: tools, key: key)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def llm_provider_options
|
|
28
|
+
@llm_provider_options ||= self.class.instance_variable_get("@llm_provider_options")
|
|
29
|
+
end
|
|
10
30
|
|
|
11
31
|
module ClassMethods
|
|
12
|
-
def tools(
|
|
13
|
-
|
|
32
|
+
def tools(tls)
|
|
33
|
+
instance_variable_set("@tools", tls)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def llm_provider(klass, args)
|
|
37
|
+
instance_variable_set("@llm_provider", klass)
|
|
38
|
+
instance_variable_set("@llm_provider_options", args.fetch(:with, {}))
|
|
14
39
|
end
|
|
15
40
|
end
|
|
16
41
|
end
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# https://docs.claude.com/en/api/messages#body-tools
|
|
4
4
|
# https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#tool-use-examples
|
|
5
|
+
require "act_as_agent/api_clients/anthropic_api_client"
|
|
6
|
+
require "act_as_agent/errors/providers/anthropic/authentication_error"
|
|
5
7
|
|
|
6
8
|
module ActAsAgent
|
|
7
9
|
module Providers
|
|
@@ -14,10 +16,10 @@ module ActAsAgent
|
|
|
14
16
|
@config = { key: key, max_tokens: max_tokens }
|
|
15
17
|
@tools = tools
|
|
16
18
|
@max_tokens = max_tokens
|
|
17
|
-
@client = AnthropicClient.new(key: key, max_tokens: max_tokens)
|
|
19
|
+
@client = ActAsAgent::ApiClients::AnthropicClient.new(key: key, max_tokens: max_tokens)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
22
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
21
23
|
def request(content:)
|
|
22
24
|
content = [{ role: "user", content: content }] unless content.is_a?(Array)
|
|
23
25
|
|
|
@@ -28,28 +30,35 @@ module ActAsAgent
|
|
|
28
30
|
max_tokens: max_tokens
|
|
29
31
|
)
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
if response["type"] == "error"
|
|
34
|
+
case response["error"]["type"]
|
|
35
|
+
when "authentication_error"
|
|
36
|
+
return ActAsAgent::Errors::Providers::AuthenticationError
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
return response if response["stop_reason"] == "end_turn"
|
|
32
41
|
|
|
33
|
-
response["content"].
|
|
34
|
-
next unless message["type"] == "tool_use"
|
|
42
|
+
tool_responses = response["content"].each_with_object([]) do |message, memo|
|
|
43
|
+
next memo unless message["type"] == "tool_use"
|
|
35
44
|
|
|
36
45
|
@tools.each do |tool|
|
|
37
46
|
next unless tool.name == message["name"]
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
memo << {
|
|
40
49
|
"role" => "assistant",
|
|
41
50
|
"content" => [
|
|
42
51
|
message
|
|
43
52
|
]
|
|
44
53
|
}
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
memo << {
|
|
47
56
|
role: "user",
|
|
48
57
|
content: [
|
|
49
58
|
{
|
|
50
59
|
type: "tool_result",
|
|
51
60
|
tool_use_id: message["id"],
|
|
52
|
-
content: tool.call(message["input"])
|
|
61
|
+
content: tool.call(message["input"]).to_s
|
|
53
62
|
}
|
|
54
63
|
]
|
|
55
64
|
}
|
|
@@ -57,10 +66,8 @@ module ActAsAgent
|
|
|
57
66
|
end
|
|
58
67
|
|
|
59
68
|
request(content: content + tool_responses) unless tool_responses.empty?
|
|
60
|
-
|
|
61
|
-
response["content"]
|
|
62
69
|
end
|
|
63
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
70
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
64
71
|
|
|
65
72
|
private
|
|
66
73
|
|
|
@@ -76,14 +83,3 @@ module ActAsAgent
|
|
|
76
83
|
end
|
|
77
84
|
end
|
|
78
85
|
end
|
|
79
|
-
|
|
80
|
-
class AnthropicClient < ApiClient
|
|
81
|
-
act_as_api_client for: %i[anthropic messages]
|
|
82
|
-
|
|
83
|
-
def initialize(key:, max_tokens:)
|
|
84
|
-
super()
|
|
85
|
-
|
|
86
|
-
options[:x_api_key] = key
|
|
87
|
-
options[:max_tokens] = max_tokens
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "act_as_agent/errors/tool_incorrect_args_error"
|
|
4
|
+
|
|
5
|
+
module ActAsAgent
|
|
6
|
+
module Tools
|
|
7
|
+
class ListFiles
|
|
8
|
+
ERROR = ActAsAgent::Errors::ToolIncorrectArgsError
|
|
9
|
+
|
|
10
|
+
attr_reader :root_folder
|
|
11
|
+
|
|
12
|
+
def initialize(root_folder: nil)
|
|
13
|
+
@root_folder = root_folder
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def name
|
|
17
|
+
self.class.to_s.gsub("::", "__")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def description
|
|
21
|
+
"List files in the directory and all subdirectories. Pass the path to lookup"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def input_schema
|
|
25
|
+
{
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
root_folder: { type: "string",
|
|
29
|
+
description: "The root folder of the list folder. By default it will use current folder." }
|
|
30
|
+
},
|
|
31
|
+
required: []
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def call(args = {})
|
|
36
|
+
path = args.fetch("path", nil)
|
|
37
|
+
|
|
38
|
+
return Dir.glob(path) unless path.nil? || path.chomp == ""
|
|
39
|
+
return Dir.glob(root_folder) unless root_folder.nil?
|
|
40
|
+
|
|
41
|
+
ERROR.new("Incorrect params have been given to list files tool")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "act_as_agent/errors/tool_incorrect_args_error"
|
|
4
|
+
|
|
5
|
+
module ActAsAgent
|
|
6
|
+
module Tools
|
|
7
|
+
class ReadFile
|
|
8
|
+
ERROR = ActAsAgent::Errors::ToolIncorrectArgsError
|
|
9
|
+
|
|
10
|
+
attr_reader :file_path
|
|
11
|
+
|
|
12
|
+
def initialize(file_path: nil)
|
|
13
|
+
@file_path = file_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def name
|
|
17
|
+
self.class.to_s.gsub("::", "__")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def description
|
|
21
|
+
"Read file by the given path"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def input_schema
|
|
25
|
+
{
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
file_path: { type: "string",
|
|
29
|
+
description: "File path to read" }
|
|
30
|
+
},
|
|
31
|
+
required: []
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def call(args = {})
|
|
36
|
+
path = args.fetch("file_path", nil)
|
|
37
|
+
|
|
38
|
+
return File.read(path) unless path.nil? || path.chomp == ""
|
|
39
|
+
return File.read(file_path) unless file_path.nil?
|
|
40
|
+
|
|
41
|
+
ERROR.new("Incorrect params have been given to list files tool")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/act_as_agent.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: act_as_agent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Max Rukomoynikov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: act_as_api_client
|
|
@@ -44,10 +44,16 @@ files:
|
|
|
44
44
|
- LICENSE.txt
|
|
45
45
|
- README.md
|
|
46
46
|
- Rakefile
|
|
47
|
+
- idea.rb
|
|
47
48
|
- idea.text
|
|
48
49
|
- lib/act_as_agent.rb
|
|
50
|
+
- lib/act_as_agent/api_clients/anthropic_api_client.rb
|
|
49
51
|
- lib/act_as_agent/base.rb
|
|
52
|
+
- lib/act_as_agent/errors/providers/anthropic/authentication_error.rb
|
|
53
|
+
- lib/act_as_agent/errors/tool_incorrect_args_error.rb
|
|
50
54
|
- lib/act_as_agent/providers/anthropic.rb
|
|
55
|
+
- lib/act_as_agent/tools/list_files.rb
|
|
56
|
+
- lib/act_as_agent/tools/read_file.rb
|
|
51
57
|
- sig/act_as_agent.rbs
|
|
52
58
|
homepage: https://github.com/Rukomoynikov/act_as_agent
|
|
53
59
|
licenses:
|