agent99 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -1
- data/README.md +34 -26
- data/docs/README.md +57 -0
- data/docs/advanced_features.md +115 -0
- data/docs/agent99_framework/central_registry.md +94 -0
- data/docs/agent99_framework/message_client.md +120 -0
- data/docs/agent99_framework/registry_client.md +119 -0
- data/docs/agent_discovery.md +66 -0
- data/docs/agent_lifecycle.md +137 -0
- data/docs/agent_registry_processes.md +108 -0
- data/docs/api_reference.md +146 -0
- data/docs/architecture.md +77 -0
- data/docs/breaking_change_v0.0.4.md +26 -0
- data/docs/configuration.md +17 -0
- data/docs/control_actions.md +179 -0
- data/docs/custom_agent_implementation.md +30 -0
- data/docs/diagrams/agent_registry_processes.dot +42 -0
- data/docs/diagrams/agent_registry_processes.png +0 -0
- data/docs/diagrams/high_level_architecture.dot +26 -0
- data/docs/diagrams/high_level_architecture.png +0 -0
- data/docs/diagrams/request_flow.dot +42 -0
- data/docs/diagrams/request_flow.png +0 -0
- data/docs/error_handling_and_logging.md +13 -0
- data/docs/extending_the_framework.md +11 -0
- data/docs/message_processing.md +165 -0
- data/docs/messaging_system.md +129 -0
- data/docs/preformance_considerations.md +9 -0
- data/docs/schema_definition.md +78 -0
- data/docs/security.md +9 -0
- data/docs/troubleshooting.md +11 -0
- data/docs/what_is_an_agent.md +293 -0
- data/examples/README.md +43 -0
- data/examples/agent_watcher.rb +106 -0
- data/examples/agents/.keep +0 -0
- data/examples/chief_agent.rb +17 -6
- data/examples/control.rb +16 -7
- data/examples/example_agent.rb +39 -0
- data/examples/kaos_spy.rb +63 -0
- data/examples/maxwell_agent86.rb +15 -26
- data/examples/registry.rb +24 -13
- data/lib/agent99/agent_discovery.rb +4 -0
- data/lib/agent99/agent_lifecycle.rb +34 -10
- data/lib/agent99/base.rb +5 -1
- data/lib/agent99/header_schema.rb +5 -0
- data/lib/agent99/message_processing.rb +3 -1
- data/lib/agent99/registry_client.rb +12 -11
- data/lib/agent99/tcp_message_client.rb +183 -0
- data/lib/agent99/version.rb +1 -1
- metadata +50 -3
- data/docs/todo.md +0 -66
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/kaos_spy.rb
|
3
|
+
#
|
4
|
+
# KAOS stood for "Kreatively Akting Out Simultaneously."
|
5
|
+
|
6
|
+
require 'agent99'
|
7
|
+
|
8
|
+
# Kaos captured Agent99 and forced her to reveal the
|
9
|
+
# secrets of the centralized registry and the communication
|
10
|
+
# network used by Control. Max was not there to save her.
|
11
|
+
|
12
|
+
require 'tty-table'
|
13
|
+
|
14
|
+
class KaosSpy
|
15
|
+
# TODO: spread some choas!
|
16
|
+
|
17
|
+
attr_reader :registry, :comms, :agents
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@registry = Agent99::RegistryClient.new
|
21
|
+
@agents = registry.fetch_all_agents
|
22
|
+
dox_control_agents
|
23
|
+
|
24
|
+
@comms = Agent99::AmqpMessageClient.new
|
25
|
+
take_out_communications
|
26
|
+
end
|
27
|
+
|
28
|
+
def dox_control_agents
|
29
|
+
if agents.empty?
|
30
|
+
puts "\nKAOS won! There are no Control agents in the field."
|
31
|
+
else
|
32
|
+
report = [ %w[Name Address Capabilities] ]
|
33
|
+
|
34
|
+
agents.each{|agent|
|
35
|
+
report << [
|
36
|
+
agent[:name],
|
37
|
+
agent[:uuid],
|
38
|
+
agent[:capabilities].join(', ')
|
39
|
+
]
|
40
|
+
}
|
41
|
+
|
42
|
+
table = TTY::Table.new(report[0], report[1..])
|
43
|
+
puts table.render(:unicode)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def take_out_communications
|
48
|
+
puts
|
49
|
+
puts "Destroy Control's Comms Network ..."
|
50
|
+
puts
|
51
|
+
|
52
|
+
agents.each do |agent|
|
53
|
+
comms.delete_queue(agent[:uuid])
|
54
|
+
puts " Agent #{agent[:name]} cannot make or receive calls@"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
KaosSpy.new
|
60
|
+
puts
|
61
|
+
puts "That's all it takes - Get Smart; get security!"
|
62
|
+
puts
|
63
|
+
|
data/examples/maxwell_agent86.rb
CHANGED
@@ -10,12 +10,21 @@ require_relative '../lib/agent99'
|
|
10
10
|
require_relative 'maxwell_request'
|
11
11
|
|
12
12
|
class MaxwellAgent86 < Agent99::Base
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
#
|
17
|
-
|
18
|
-
|
13
|
+
# this information is made available when the agent
|
14
|
+
# registers with the central registry service. It is
|
15
|
+
# made available during the discovery process.
|
16
|
+
#
|
17
|
+
def info
|
18
|
+
{
|
19
|
+
name: self.class.to_s,
|
20
|
+
type: :server,
|
21
|
+
capabilities: %w[ greeter hello_world hello-world hello],
|
22
|
+
request_schema: MaxwellRequest.schema,
|
23
|
+
# response_schema: {}, # Agent99::RESPONSE.schema
|
24
|
+
# control_schema: {}, # Agent99::CONTROL.schema
|
25
|
+
# error_schema: {}, # Agent99::ERROR.schema
|
26
|
+
}
|
27
|
+
end
|
19
28
|
|
20
29
|
#######################################
|
21
30
|
private
|
@@ -90,26 +99,6 @@ class MaxwellAgent86 < Agent99::Base
|
|
90
99
|
def receive_response(response)
|
91
100
|
loger.warn("Unexpected response type message: response.inspect")
|
92
101
|
end
|
93
|
-
|
94
|
-
|
95
|
-
# Phase One Implementation is to do a search
|
96
|
-
# using the String#include? and the Array#include?
|
97
|
-
# methods. If you want discrete word-based selection
|
98
|
-
# then use an Array of Strings to define the different
|
99
|
-
# things this agent can do.
|
100
|
-
#
|
101
|
-
# If you want to match on sub-strings then define the
|
102
|
-
# the capabilities as a String.
|
103
|
-
#
|
104
|
-
# Subsequent implementations may use a semantic search
|
105
|
-
# to find the agents to use in which case capabilities may
|
106
|
-
# be constrained to be a String.
|
107
|
-
#
|
108
|
-
# For now, lets just go with the Array of Strings.
|
109
|
-
#
|
110
|
-
def capabilities
|
111
|
-
%w[ greeter hello_world hello-world hello]
|
112
|
-
end
|
113
102
|
end
|
114
103
|
|
115
104
|
# Example usage
|
data/examples/registry.rb
CHANGED
@@ -8,8 +8,11 @@ require 'sinatra'
|
|
8
8
|
require 'json'
|
9
9
|
require 'securerandom'
|
10
10
|
|
11
|
-
# In-memory registry to store agent
|
12
|
-
#
|
11
|
+
# In-memory registry to store agent Array(Hash)
|
12
|
+
#
|
13
|
+
# Agent capabilities are save as lower case. The
|
14
|
+
# discovery process also compares content as lower case.
|
15
|
+
#
|
13
16
|
# TODO: change this data store to a sqlite database
|
14
17
|
# maybe with a vector search capability.
|
15
18
|
#
|
@@ -24,14 +27,22 @@ end
|
|
24
27
|
# Endpoint to register an agent
|
25
28
|
post '/register' do
|
26
29
|
request.body.rewind
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
agent_uuid
|
33
|
-
|
34
|
-
|
30
|
+
request_data = JSON.parse(request.body.read, symbolize_names: true)
|
31
|
+
debug_me{[
|
32
|
+
:request_data
|
33
|
+
]}
|
34
|
+
agent_name = request_data[:name]
|
35
|
+
agent_uuid = SecureRandom.uuid
|
36
|
+
|
37
|
+
debug_me{[
|
38
|
+
:agent_name,
|
39
|
+
:agent_uuid
|
40
|
+
]}
|
41
|
+
|
42
|
+
# Ensure capabilities are lowercase
|
43
|
+
request_data[:capabilities].map!{|c| c.downcase}
|
44
|
+
|
45
|
+
AGENT_REGISTRY << request_data.merge({uuid: agent_uuid})
|
35
46
|
|
36
47
|
status 201
|
37
48
|
content_type :json
|
@@ -42,10 +53,10 @@ end
|
|
42
53
|
# TODO: This is a simple keyword matcher. Looking
|
43
54
|
# => for a semantic match process.
|
44
55
|
get '/discover' do
|
45
|
-
capability = params['capability']
|
56
|
+
capability = params['capability'].downcase
|
46
57
|
|
47
58
|
matching_agents = AGENT_REGISTRY.select do |agent|
|
48
|
-
agent[:capabilities]
|
59
|
+
agent[:capabilities]&.include?(capability)
|
49
60
|
end
|
50
61
|
|
51
62
|
content_type :json
|
@@ -77,4 +88,4 @@ end
|
|
77
88
|
# Start the Sinatra server
|
78
89
|
if __FILE__ == $PROGRAM_NAME
|
79
90
|
Sinatra::Application.run!
|
80
|
-
end
|
91
|
+
end
|
@@ -11,16 +11,19 @@ module Agent99::AgentLifecycle
|
|
11
11
|
def initialize(registry_client: Agent99::RegistryClient.new,
|
12
12
|
message_client: Agent99::AmqpMessageClient.new,
|
13
13
|
logger: Logger.new($stdout))
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
14
|
+
@agents = {}
|
15
|
+
@payload = nil
|
16
|
+
@name = self.class.name
|
17
|
+
@capabilities = capabilities
|
18
|
+
@id = nil
|
19
|
+
@registry_client = registry_client
|
20
|
+
@message_client = message_client
|
21
|
+
@logger = logger
|
22
|
+
|
23
|
+
validate_info_keys
|
21
24
|
|
22
25
|
@registry_client.logger = logger
|
23
|
-
register
|
26
|
+
register(info)
|
24
27
|
|
25
28
|
@queue = message_client.setup(agent_id: id, logger:)
|
26
29
|
|
@@ -29,12 +32,33 @@ module Agent99::AgentLifecycle
|
|
29
32
|
setup_signal_handlers
|
30
33
|
end
|
31
34
|
|
35
|
+
|
36
|
+
def validate_info_keys
|
37
|
+
required_keys = [:name, :capabilities]
|
38
|
+
if respond_to? :info
|
39
|
+
missing_keys = required_keys - info.keys
|
40
|
+
unless missing_keys.empty?
|
41
|
+
logger.error <<~MESSAGE
|
42
|
+
This agent's info method is missing
|
43
|
+
#{1 == missing_keys.size ? 'a required key' : 'some required keys'}:
|
44
|
+
#{missing_keys}
|
45
|
+
MESSAGE
|
46
|
+
.split("\n").join
|
47
|
+
exit(1)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
logger.error "An agent must implement the info method"
|
51
|
+
exit(1)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
32
56
|
# Registers the agent with the registry service.
|
33
57
|
#
|
34
58
|
# @raise [StandardError] If registration fails
|
35
59
|
#
|
36
|
-
def register
|
37
|
-
@id = registry_client.register(
|
60
|
+
def register(agent_info)
|
61
|
+
@id = registry_client.register(info: agent_info)
|
38
62
|
logger.info "Registered Agent #{name} with ID: #{id}"
|
39
63
|
rescue StandardError => e
|
40
64
|
handle_error("Error during registration", e)
|
data/lib/agent99/base.rb
CHANGED
@@ -37,7 +37,11 @@ class Agent99::Base
|
|
37
37
|
|
38
38
|
MESSAGE_TYPES = %w[request response control]
|
39
39
|
|
40
|
-
attr_reader :id, :capabilities, :name
|
40
|
+
attr_reader :id, :capabilities, :name
|
41
|
+
attr_reader :payload, :header, :queue
|
42
|
+
attr_reader :logger
|
43
|
+
attr_reader :agents
|
44
|
+
|
41
45
|
attr_accessor :registry_client, :message_client
|
42
46
|
|
43
47
|
|
@@ -128,7 +128,9 @@ module Agent99::MessageProcessing
|
|
128
128
|
# @return [Array] An array of validation errors, empty if validation succeeds
|
129
129
|
#
|
130
130
|
def validate_schema
|
131
|
-
|
131
|
+
return unless info[:request_schema]
|
132
|
+
|
133
|
+
schema = JsonSchema.parse!(info[:request_schema])
|
132
134
|
schema.expand_references!
|
133
135
|
validator = JsonSchema::Validator.new(schema)
|
134
136
|
|
@@ -8,17 +8,18 @@ class Agent99::RegistryClient
|
|
8
8
|
attr_accessor :logger
|
9
9
|
|
10
10
|
def initialize(
|
11
|
-
base_url: ENV.fetch('
|
11
|
+
base_url: ENV.fetch('AGENT99_REGISTRY_URL', 'http://localhost:4567'),
|
12
12
|
logger: Logger.new($stdout)
|
13
13
|
)
|
14
|
-
@base_url
|
15
|
-
@logger
|
16
|
-
@http_client
|
14
|
+
@base_url = base_url
|
15
|
+
@logger = logger
|
16
|
+
@http_client = Net::HTTP.new(URI.parse(base_url).host, URI.parse(base_url).port)
|
17
17
|
end
|
18
18
|
|
19
|
-
def register(
|
20
|
-
|
21
|
-
|
19
|
+
def register(info:)
|
20
|
+
payload = info
|
21
|
+
request = create_request(:post, "/register", payload)
|
22
|
+
@id = send_request(request)
|
22
23
|
end
|
23
24
|
|
24
25
|
def withdraw(id)
|
@@ -37,16 +38,16 @@ class Agent99::RegistryClient
|
|
37
38
|
|
38
39
|
|
39
40
|
def fetch_all_agents
|
40
|
-
request
|
41
|
-
response
|
41
|
+
request = create_request(:get, "/")
|
42
|
+
response = send_request(request)
|
42
43
|
end
|
43
44
|
|
44
45
|
################################################
|
45
46
|
private
|
46
47
|
|
47
48
|
def create_request(method, path, body = nil)
|
48
|
-
request
|
49
|
-
request.body
|
49
|
+
request = Object.const_get("Net::HTTP::#{method.capitalize}").new(path, { "Content-Type" => "application/json" })
|
50
|
+
request.body = body.to_json if body
|
50
51
|
request
|
51
52
|
end
|
52
53
|
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# lib/agent99/tcp_message_client.rb
|
2
|
+
#
|
3
|
+
# NOTE: This is an early attempt at a true
|
4
|
+
# peer-to-peer messaging platform. Its not
|
5
|
+
# not ready for prime time.
|
6
|
+
|
7
|
+
require 'socket'
|
8
|
+
require 'json'
|
9
|
+
require 'logger'
|
10
|
+
|
11
|
+
class Agent99::TcpMessageClient
|
12
|
+
attr_accessor :agents
|
13
|
+
|
14
|
+
def initialize(
|
15
|
+
agents: {},
|
16
|
+
logger: Logger.new($stdout)
|
17
|
+
)
|
18
|
+
@agents = agents
|
19
|
+
@logger = logger
|
20
|
+
@server_socket = nil
|
21
|
+
@client_connections = {}
|
22
|
+
@handlers = {}
|
23
|
+
@running = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def listen_for_messages(queue, request_handler:, response_handler:, control_handler:)
|
27
|
+
@handlers = {
|
28
|
+
request: request_handler,
|
29
|
+
response: response_handler,
|
30
|
+
control: control_handler
|
31
|
+
}
|
32
|
+
|
33
|
+
start_server(queue[:port])
|
34
|
+
end
|
35
|
+
|
36
|
+
def publish(message)
|
37
|
+
target = message.dig(:header, :to_uuid)
|
38
|
+
return unless target
|
39
|
+
|
40
|
+
agent_info = agents(target)
|
41
|
+
return unless agent_info
|
42
|
+
|
43
|
+
socket = connect_to_agent(agent_info[:ip], agent_info[:port])
|
44
|
+
return unless socket
|
45
|
+
|
46
|
+
begin
|
47
|
+
socket.puts(message.to_json)
|
48
|
+
true
|
49
|
+
|
50
|
+
rescue StandardError => e
|
51
|
+
@logger.error("Failed to send message: #{e.message}")
|
52
|
+
false
|
53
|
+
|
54
|
+
ensure
|
55
|
+
socket.close unless socket.closed?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def stop
|
60
|
+
@running = false
|
61
|
+
@server_socket&.close
|
62
|
+
@client_connections.each_value(&:close)
|
63
|
+
@client_connections.clear
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def start_server(port)
|
69
|
+
@server_socket = TCPServer.new(port)
|
70
|
+
@running = true
|
71
|
+
|
72
|
+
Thread.new do
|
73
|
+
while @running
|
74
|
+
begin
|
75
|
+
client = @server_socket.accept
|
76
|
+
handle_client(client)
|
77
|
+
rescue StandardError => e
|
78
|
+
@logger.error("Server error: #{e.message}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def handle_client(client)
|
85
|
+
Thread.new do
|
86
|
+
while @running
|
87
|
+
begin
|
88
|
+
message = client.gets
|
89
|
+
break if message.nil?
|
90
|
+
|
91
|
+
parsed_message = JSON.parse(message, symbolize_names: true)
|
92
|
+
route_message(parsed_message)
|
93
|
+
|
94
|
+
rescue JSON::ParserError => e
|
95
|
+
@logger.error("Invalid JSON received: #{e.message}")
|
96
|
+
|
97
|
+
rescue StandardError => e
|
98
|
+
@logger.error("Error handling client: #{e.message}")
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
client.close unless client.closed?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def route_message(message)
|
108
|
+
type = message.dig(:header, :type)&.to_sym
|
109
|
+
handler = @handlers[type]
|
110
|
+
|
111
|
+
if handler
|
112
|
+
handler.call(message)
|
113
|
+
else
|
114
|
+
@logger.warn("No handler for message type: #{type}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def connect_to_agent(ip, port)
|
119
|
+
TCPSocket.new(ip, port)
|
120
|
+
|
121
|
+
rescue StandardError => e
|
122
|
+
@logger.error("Failed to connect to #{ip}:#{port}: #{e.message}")
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
__END__
|
129
|
+
|
130
|
+
Based on the provided code for the `Agent99::TcpMessageClient` class, here's an analysis of your questions:
|
131
|
+
|
132
|
+
1. Does this class queue up JSON messages while a previous message is being processed?
|
133
|
+
|
134
|
+
No, this class does not explicitly queue up JSON messages while a previous message is being processed. The class processes messages as they are received, without maintaining an internal queue. Each incoming message is handled in its own thread (see the `handle_client` method), which allows for concurrent processing of messages from multiple clients.
|
135
|
+
|
136
|
+
2. Does it present a complete JSON message at once or does it only provide part of one?
|
137
|
+
|
138
|
+
The class attempts to present complete JSON messages at once. Here's why:
|
139
|
+
|
140
|
+
- In the `handle_client` method, messages are read using `client.gets`, which typically reads a full line of input (up to a newline character).
|
141
|
+
- The received message is then parsed as JSON using `JSON.parse(message, symbolize_names: true)`.
|
142
|
+
- If the parsing is successful, the entire parsed message is passed to the `route_message` method.
|
143
|
+
|
144
|
+
However, there are a few potential issues to consider:
|
145
|
+
|
146
|
+
- If a JSON message spans multiple lines, `client.gets` might not capture the entire message in one read.
|
147
|
+
- There's no explicit handling for partial messages or message boundaries.
|
148
|
+
- Large messages might be split across multiple TCP packets, and the current implementation doesn't account for reassembling these.
|
149
|
+
|
150
|
+
To ensure complete message handling, you might want to consider implementing a more robust message framing protocol, such as using message length prefixes or delimiter-based framing.
|
151
|
+
|
152
|
+
For example, you could modify the `handle_client` method to use a delimiter-based approach:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
def handle_client(client)
|
156
|
+
Thread.new do
|
157
|
+
buffer = ""
|
158
|
+
while @running
|
159
|
+
begin
|
160
|
+
chunk = client.readpartial(1024)
|
161
|
+
buffer += chunk
|
162
|
+
while (message_end = buffer.index("\n"))
|
163
|
+
message = buffer[0...message_end]
|
164
|
+
buffer = buffer[(message_end + 1)..]
|
165
|
+
parsed_message = JSON.parse(message, symbolize_names: true)
|
166
|
+
route_message(parsed_message)
|
167
|
+
end
|
168
|
+
rescue EOFError
|
169
|
+
break
|
170
|
+
rescue JSON::ParserError => e
|
171
|
+
@logger.error("Invalid JSON received: #{e.message}")
|
172
|
+
rescue StandardError => e
|
173
|
+
@logger.error("Error handling client: #{e.message}")
|
174
|
+
break
|
175
|
+
end
|
176
|
+
end
|
177
|
+
client.close unless client.closed?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
This modification would allow for handling of messages that might be split across multiple reads, ensuring that complete JSON messages are processed.
|
183
|
+
|
data/lib/agent99/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agent99
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sinatra
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: amazing_print
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,12 +152,44 @@ files:
|
|
138
152
|
- LICENSE
|
139
153
|
- README.md
|
140
154
|
- Rakefile
|
141
|
-
- docs/
|
155
|
+
- docs/README.md
|
156
|
+
- docs/advanced_features.md
|
157
|
+
- docs/agent99_framework/central_registry.md
|
158
|
+
- docs/agent99_framework/message_client.md
|
159
|
+
- docs/agent99_framework/registry_client.md
|
160
|
+
- docs/agent_discovery.md
|
161
|
+
- docs/agent_lifecycle.md
|
162
|
+
- docs/agent_registry_processes.md
|
163
|
+
- docs/api_reference.md
|
164
|
+
- docs/architecture.md
|
165
|
+
- docs/breaking_change_v0.0.4.md
|
166
|
+
- docs/configuration.md
|
167
|
+
- docs/control_actions.md
|
168
|
+
- docs/custom_agent_implementation.md
|
169
|
+
- docs/diagrams/agent_registry_processes.dot
|
170
|
+
- docs/diagrams/agent_registry_processes.png
|
171
|
+
- docs/diagrams/high_level_architecture.dot
|
172
|
+
- docs/diagrams/high_level_architecture.png
|
173
|
+
- docs/diagrams/request_flow.dot
|
174
|
+
- docs/diagrams/request_flow.png
|
175
|
+
- docs/error_handling_and_logging.md
|
176
|
+
- docs/extending_the_framework.md
|
177
|
+
- docs/message_processing.md
|
178
|
+
- docs/messaging_system.md
|
179
|
+
- docs/preformance_considerations.md
|
180
|
+
- docs/schema_definition.md
|
181
|
+
- docs/security.md
|
182
|
+
- docs/troubleshooting.md
|
183
|
+
- docs/what_is_an_agent.md
|
142
184
|
- examples/README.md
|
185
|
+
- examples/agent_watcher.rb
|
186
|
+
- examples/agents/.keep
|
143
187
|
- examples/chief_agent.rb
|
144
188
|
- examples/control.rb
|
145
189
|
- examples/diagram.dot
|
146
190
|
- examples/diagram.png
|
191
|
+
- examples/example_agent.rb
|
192
|
+
- examples/kaos_spy.rb
|
147
193
|
- examples/maxwell_agent86.rb
|
148
194
|
- examples/maxwell_request.rb
|
149
195
|
- examples/registry.rb
|
@@ -160,6 +206,7 @@ files:
|
|
160
206
|
- lib/agent99/message_processing.rb
|
161
207
|
- lib/agent99/nats_message_client.rb
|
162
208
|
- lib/agent99/registry_client.rb
|
209
|
+
- lib/agent99/tcp_message_client.rb
|
163
210
|
- lib/agent99/timestamp.rb
|
164
211
|
- lib/agent99/version.rb
|
165
212
|
- sig/ai_agent.rbs
|
data/docs/todo.md
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# Documentation
|
2
|
-
|
3
|
-
TODO: Lets get some more detailed documentation underway that can be linked to from the main README.md file.
|
4
|
-
|
5
|
-
Here are some key areas that should be covered in comprehensive documentation files:
|
6
|
-
|
7
|
-
1. Architecture Overview:
|
8
|
-
- Explain the overall structure of the AiAgent framework
|
9
|
-
- Describe the roles of different components (Base, MessageClient, RegistryClient, etc.)
|
10
|
-
- Illustrate how agents communicate and interact within the system
|
11
|
-
|
12
|
-
2. Agent Lifecycle:
|
13
|
-
- Detail the process of creating, initializing, running, and shutting down an agent
|
14
|
-
- Explain the registration and withdrawal process with the registry service
|
15
|
-
|
16
|
-
3. Message Processing:
|
17
|
-
- Describe the different types of messages (request, response, control)
|
18
|
-
- Explain how messages are routed and processed
|
19
|
-
- Detail the schema validation process for incoming messages
|
20
|
-
|
21
|
-
4. Agent Discovery:
|
22
|
-
- Explain how agents can discover other agents based on capabilities
|
23
|
-
- Describe the process of querying the registry for available agents
|
24
|
-
|
25
|
-
5. Control Actions:
|
26
|
-
- List and explain all available control actions (shutdown, pause, resume, etc.)
|
27
|
-
- Describe how to implement custom control actions
|
28
|
-
|
29
|
-
6. Configuration:
|
30
|
-
- Detail all configuration options available for agents
|
31
|
-
- Explain how to use environment variables for configuration
|
32
|
-
|
33
|
-
7. Error Handling and Logging:
|
34
|
-
- Describe the error handling mechanisms in place
|
35
|
-
- Explain how to configure and use the logging system effectively
|
36
|
-
|
37
|
-
8. Messaging Systems:
|
38
|
-
- Provide details on both AMQP and NATS messaging systems
|
39
|
-
- Explain how to switch between different messaging backends
|
40
|
-
|
41
|
-
9. Custom Agent Implementation:
|
42
|
-
- Provide a step-by-step guide on creating a custom agent
|
43
|
-
- Explain how to define capabilities, handle requests, and send responses
|
44
|
-
|
45
|
-
10. Schema Definition:
|
46
|
-
- Explain how to define and use request and response schemas
|
47
|
-
- Provide examples of complex schema definitions
|
48
|
-
|
49
|
-
11. Performance Considerations:
|
50
|
-
- Discuss any performance optimizations in the framework
|
51
|
-
- Provide guidelines for writing efficient agents
|
52
|
-
|
53
|
-
12. Security:
|
54
|
-
- Explain any security measures in place (if any)
|
55
|
-
- Provide best practices for securing agent communications
|
56
|
-
|
57
|
-
13. Extending the Framework:
|
58
|
-
- Describe how to add new features or modify existing functionality
|
59
|
-
- Explain the plugin system (if one exists)
|
60
|
-
|
61
|
-
14. Troubleshooting:
|
62
|
-
- Provide a list of common issues and their solutions
|
63
|
-
- Explain how to debug agents effectively
|
64
|
-
|
65
|
-
15. API Reference:
|
66
|
-
- Provide a comprehensive API reference for all public methods and classes
|