agent99 0.0.3 → 0.0.5
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/A2A_SPEC-dev.md +1829 -0
- data/CHANGELOG.md +38 -0
- data/COMMITS.md +196 -0
- data/DOCS.md +96 -0
- data/README.md +212 -84
- data/Rakefile +62 -0
- data/docs/AI/htm.md +215 -0
- data/docs/AI/htm.rb +141 -0
- data/docs/AI/htm_demo.db +0 -0
- data/docs/AI/notes_on_htm_implementation.md +1319 -0
- data/docs/AI/some_code.rb +692 -0
- data/docs/advanced-topics/a2a-protocol.md +13 -0
- data/docs/{advanced_features.md → advanced-topics/advanced-features.md} +9 -4
- data/docs/{control_actions.md → advanced-topics/control-actions.md} +2 -0
- data/docs/advanced-topics/model-context-protocol.md +4 -0
- data/docs/advanced-topics/multi-agent-processing.md +674 -0
- data/docs/agent-development/request-response-handling.md +512 -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/api-reference/agent99-base.md +463 -0
- data/docs/api-reference/message-clients.md +495 -0
- data/docs/{api_reference.md → api-reference/overview.md} +14 -4
- data/docs/api-reference/registry-client.md +470 -0
- data/docs/api-reference/schemas.md +518 -0
- data/docs/assets/css/custom.css +27 -0
- data/docs/assets/images/agent-lifecycle.svg +73 -0
- data/docs/assets/images/agent-registry-process.svg +86 -0
- data/docs/assets/images/agent-registry-processes.svg +114 -0
- data/docs/assets/images/agent-types-overview.svg +51 -0
- data/docs/assets/images/agent99-architecture.svg +85 -0
- data/docs/assets/images/agent99_logo.png +0 -0
- data/docs/assets/images/control-actions-state.svg +83 -0
- data/docs/assets/images/knowledge-graph.svg +77 -0
- data/docs/assets/images/message-processing-flow.svg +148 -0
- data/docs/assets/images/multi-agent-system.svg +66 -0
- data/docs/assets/images/proxy-pattern-sequence.svg +48 -0
- data/docs/assets/images/request-flow.svg +97 -0
- data/docs/assets/images/request-processing-lifecycle.svg +50 -0
- data/docs/assets/images/request-response-sequence.svg +39 -0
- data/docs/{agent_lifecycle.md → core-concepts/agent-lifecycle.md} +2 -0
- data/docs/core-concepts/agent-types.md +255 -0
- data/docs/{architecture.md → core-concepts/architecture.md} +5 -5
- data/docs/core-concepts/what-is-an-agent.md +293 -0
- data/docs/diagrams/message-flow-sequence.svg +198 -0
- data/docs/diagrams/p2p-network-topology.svg +181 -0
- data/docs/diagrams/smart-transport-routing.svg +165 -0
- data/docs/diagrams/three-layer-architecture.svg +77 -0
- data/docs/diagrams/transport-extension-api.svg +309 -0
- data/docs/diagrams/transport-extension-architecture.svg +234 -0
- data/docs/diagrams/transport-selection-flowchart.svg +264 -0
- data/docs/examples/advanced-examples.md +951 -0
- data/docs/examples/basic-examples.md +268 -0
- data/docs/{agent_discovery.md → framework-components/agent-discovery.md} +9 -5
- data/docs/{agent_registry_processes.md → framework-components/agent-registry.md} +9 -3
- data/docs/{message_processing.md → framework-components/message-processing.md} +3 -1
- data/docs/getting-started/basic-example.md +306 -0
- data/docs/getting-started/installation.md +160 -0
- data/docs/getting-started/overview.md +64 -0
- data/docs/getting-started/quick-start.md +179 -0
- data/docs/index.md +97 -0
- data/docs/operations/breaking-changes.md +26 -0
- data/examples/DEMO.md +148 -0
- data/examples/README.md +50 -0
- data/examples/agent_watcher.rb +5 -1
- data/examples/bad_agent.rb +32 -0
- data/examples/chief_agent.rb +17 -6
- data/examples/control.rb +16 -7
- data/examples/example_agent.rb +16 -3
- data/examples/maxwell_agent86.rb +15 -26
- data/examples/registry.rb +10 -9
- data/examples/run_demo.rb +433 -0
- data/lib/agent99/agent_discovery.rb +4 -0
- data/lib/agent99/agent_lifecycle.rb +34 -10
- data/lib/agent99/amqp_message_client.rb +2 -2
- data/lib/agent99/base.rb +6 -2
- data/lib/agent99/message_processing.rb +6 -10
- data/lib/agent99/registry_client.rb +15 -11
- data/lib/agent99/tcp_message_client.rb +183 -0
- data/lib/agent99/version.rb +1 -1
- data/lib/agent99.rb +1 -1
- data/mkdocs.yml +195 -0
- data/p2p_plan.md +533 -0
- data/p2p_roadmap.md +299 -0
- data/registry_plan.md +1818 -0
- metadata +93 -30
- data/docs/README.md +0 -57
- data/docs/diagrams/agent_registry_processes.dot +0 -42
- data/docs/diagrams/agent_registry_processes.png +0 -0
- data/docs/diagrams/high_level_architecture.dot +0 -26
- data/docs/diagrams/high_level_architecture.png +0 -0
- data/docs/diagrams/request_flow.dot +0 -42
- data/docs/diagrams/request_flow.png +0 -0
- /data/docs/{extending_the_framework.md → advanced-topics/extending-the-framework.md} +0 -0
- /data/docs/{custom_agent_implementation.md → agent-development/custom-agent-implementation.md} +0 -0
- /data/docs/{error_handling_and_logging.md → agent-development/error-handling-and-logging.md} +0 -0
- /data/docs/{schema_definition.md → agent-development/schema-definition.md} +0 -0
- /data/docs/{messaging_system.md → framework-components/messaging-system.md} +0 -0
- /data/docs/{configuration.md → operations/configuration.md} +0 -0
- /data/docs/{preformance_considerations.md → operations/performance-considerations.md} +0 -0
- /data/docs/{security.md → operations/security.md} +0 -0
- /data/docs/{troubleshooting.md → operations/troubleshooting.md} +0 -0
data/examples/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Agent99 Framework Examples - 86 and the Chief
|
2
2
|
|
3
|
+
FYI ... I am in the process of extracting this examples directory out into its own repository: [MadBomber/agent99_examples](https://github.com/MadBomber/agent99_examples)
|
4
|
+
|
3
5
|
This folder contains example implementations using the Agent99 framework. The framework provides a foundation for building AI agents that can communicate with each other through a message-based system.
|
4
6
|
|
5
7
|
## Files
|
@@ -90,6 +92,40 @@ Note: To use the example_agent.rb, first run the AgentWatcher, then copy example
|
|
90
92
|
|
91
93
|
## Usage
|
92
94
|
|
95
|
+
There are two ways to run the Agent99 examples:
|
96
|
+
|
97
|
+
### 🚀 Automated Demo Runner (Recommended)
|
98
|
+
|
99
|
+
The easiest way to run examples is with the comprehensive demo runner:
|
100
|
+
|
101
|
+
```bash
|
102
|
+
./run_demo.rb --list # List all available scenarios
|
103
|
+
./run_demo.rb # Run default 'basic' scenario
|
104
|
+
./run_demo.rb -s basic # Basic Maxwell/Chief interaction
|
105
|
+
./run_demo.rb -s control # Control agent demonstration
|
106
|
+
./run_demo.rb -s watcher # Dynamic agent loading demo
|
107
|
+
./run_demo.rb -s security # Security demonstration (KAOS spy)
|
108
|
+
./run_demo.rb -s all # Run multiple scenarios in sequence
|
109
|
+
./run_demo.rb -v -s basic # Verbose output
|
110
|
+
./run_demo.rb --help # Show all options
|
111
|
+
```
|
112
|
+
|
113
|
+
The demo runner automatically:
|
114
|
+
- ✅ Checks dependencies (RabbitMQ, boxes command, etc.)
|
115
|
+
- 🏗️ Starts infrastructure (registry service, RabbitMQ if available)
|
116
|
+
- 🎬 Orchestrates multiple agents with proper timing
|
117
|
+
- 🧹 Handles cleanup on exit or interrupt
|
118
|
+
- 📊 Provides progress feedback and duration estimates
|
119
|
+
|
120
|
+
**Available Scenarios:**
|
121
|
+
- **basic** (~10s): Maxwell Agent86 and Chief interaction
|
122
|
+
- **control** (~15s): Control agent managing other agents
|
123
|
+
- **watcher** (~20s): Agent watcher dynamically loading new agents
|
124
|
+
- **security** (~10s): KAOS spy demonstration (educational security example)
|
125
|
+
- **all** (~60s): Run multiple scenarios in sequence
|
126
|
+
|
127
|
+
### 📋 Manual Setup (Original Method)
|
128
|
+
|
93
129
|
From the examples directory you will need to start three different processes. You will want to keep them all in the forgound so it would be best to start them in different terminal windows.
|
94
130
|
|
95
131
|
Start the sample registry first: `./registry.rb`
|
@@ -104,6 +140,20 @@ But first the Chief asks the registry for the UUIDs of all agents who can handle
|
|
104
140
|
|
105
141
|
Run the chief a few times in a roll. Some times the agent to whom the Chief issues his requests does not always respond the you would expect.
|
106
142
|
|
143
|
+
### 🔧 Optional Dependencies
|
144
|
+
|
145
|
+
For the best experience, install these optional dependencies:
|
146
|
+
|
147
|
+
```bash
|
148
|
+
# For message broker (recommended)
|
149
|
+
brew install rabbitmq-server
|
150
|
+
|
151
|
+
# For enhanced chief agent output
|
152
|
+
brew install boxes
|
153
|
+
```
|
154
|
+
|
155
|
+
**Note:** The framework works without these dependencies using fallback implementations.
|
156
|
+
|
107
157
|

|
108
158
|
|
109
159
|
|
data/examples/agent_watcher.rb
CHANGED
@@ -28,7 +28,11 @@ require_relative '../lib/agent99'
|
|
28
28
|
class AgentWatcher < Agent99::Base
|
29
29
|
TYPE = :client
|
30
30
|
|
31
|
-
def capabilities =
|
31
|
+
def capabilities = {
|
32
|
+
info: {
|
33
|
+
capabilities: %w[ launch_agents watcher launcher ]
|
34
|
+
}
|
35
|
+
}
|
32
36
|
|
33
37
|
def init
|
34
38
|
@watch_path = ENV.fetch('AGENT_WATCH_PATH', './agents')
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# examples/bad_agent.rb
|
3
|
+
#
|
4
|
+
# This agent is meant to cause errors.
|
5
|
+
|
6
|
+
require_relative '../lib/agent99'
|
7
|
+
|
8
|
+
class BadAgent < Agent99::Base
|
9
|
+
# this information is made available when the agent
|
10
|
+
# registers with the central registry service. It is
|
11
|
+
# made available during the discovery process.
|
12
|
+
#
|
13
|
+
def info
|
14
|
+
{
|
15
|
+
name: self.class.to_s,
|
16
|
+
type: :server,
|
17
|
+
kapabilities: %w[ rubber_stamp yes_man example ],
|
18
|
+
# request_schema: {}, # ExampleRequest.schema,
|
19
|
+
# response_schema: {}, # Agent99::RESPONSE.schema
|
20
|
+
# control_schema: {}, # Agent99::CONTROL.schema
|
21
|
+
# error_schema: {}, # Agent99::ERROR.schema
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def receive_request
|
27
|
+
logger.info "Example agent received request: #{payload}"
|
28
|
+
send_response(status: 'success')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
BadAgent.new.run
|
data/examples/chief_agent.rb
CHANGED
@@ -14,7 +14,23 @@
|
|
14
14
|
require_relative '../lib/agent99'
|
15
15
|
|
16
16
|
class ChiefAgent < Agent99::Base
|
17
|
-
|
17
|
+
# this information is made available when the agent
|
18
|
+
# registers with the central registry service. It is
|
19
|
+
# made available during the discovery process.
|
20
|
+
#
|
21
|
+
def info
|
22
|
+
{
|
23
|
+
name: self.class.to_s,
|
24
|
+
type: :client,
|
25
|
+
capabilities: ['Chief of Control'],
|
26
|
+
# request_schema: ChiefRequest.schema,
|
27
|
+
# response_schema: {}, # Agent99::RESPONSE.schema
|
28
|
+
# control_schema: {}, # Agent99::CONTROL.schema
|
29
|
+
# error_schema: {}, # Agent99::ERROR.schema
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
|
18
34
|
|
19
35
|
# init is called at the end of the initialization process.
|
20
36
|
# It may be only something that a :client type agent would do.
|
@@ -82,11 +98,6 @@ class ChiefAgent < Agent99::Base
|
|
82
98
|
|
83
99
|
exit(0)
|
84
100
|
end
|
85
|
-
|
86
|
-
|
87
|
-
def capabilities
|
88
|
-
['Chief of Control']
|
89
|
-
end
|
90
101
|
end
|
91
102
|
|
92
103
|
|
data/examples/control.rb
CHANGED
@@ -4,7 +4,21 @@
|
|
4
4
|
require_relative '../lib/agent99'
|
5
5
|
|
6
6
|
class Control < Agent99::Base
|
7
|
-
|
7
|
+
# this information is made available when the agent
|
8
|
+
# registers with the central registry service. It is
|
9
|
+
# made available during the discovery process.
|
10
|
+
#
|
11
|
+
def info
|
12
|
+
{
|
13
|
+
name: self.class.to_s,
|
14
|
+
type: :hybrid,
|
15
|
+
capabilities: ['control', 'headquarters', 'secret underground base'],
|
16
|
+
# request_schema: ControlRequest.schema,
|
17
|
+
# response_schema: {}, # Agent99::RESPONSE.schema
|
18
|
+
# control_schema: {}, # Agent99::CONTROL.schema
|
19
|
+
# error_schema: {}, # Agent99::ERROR.schema
|
20
|
+
}
|
21
|
+
end
|
8
22
|
|
9
23
|
attr_accessor :statuses
|
10
24
|
|
@@ -14,11 +28,6 @@ class Control < Agent99::Base
|
|
14
28
|
end
|
15
29
|
|
16
30
|
|
17
|
-
def capabilities
|
18
|
-
['control', 'headquarters', 'secret underground base']
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
31
|
def send_control_message(message:, payload: {})
|
23
32
|
@agents.each do |agent|
|
24
33
|
response = @message_client.publish(
|
@@ -48,7 +57,7 @@ class Control < Agent99::Base
|
|
48
57
|
|
49
58
|
|
50
59
|
def stop_all
|
51
|
-
send_control_message(message: '
|
60
|
+
send_control_message(message: 'shutdown')
|
52
61
|
end
|
53
62
|
|
54
63
|
def get_all_status
|
data/examples/example_agent.rb
CHANGED
@@ -15,9 +15,22 @@
|
|
15
15
|
require_relative '../../lib/agent99'
|
16
16
|
|
17
17
|
class ExampleAgent < Agent99::Base
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
# this information is made available when the agent
|
19
|
+
# registers with the central registry service. It is
|
20
|
+
# made available during the discovery process.
|
21
|
+
#
|
22
|
+
def info
|
23
|
+
{
|
24
|
+
name: self.class.to_s,
|
25
|
+
type: :server,
|
26
|
+
capabilities: %w[ rubber_stamp yes_man example ],
|
27
|
+
# request_schema: {}, # ExampleRequest.schema,
|
28
|
+
# response_schema: {}, # Agent99::RESPONSE.schema
|
29
|
+
# control_schema: {}, # Agent99::CONTROL.schema
|
30
|
+
# error_schema: {}, # Agent99::ERROR.schema
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
21
34
|
|
22
35
|
def receive_request
|
23
36
|
logger.info "Example agent received request: #{payload}"
|
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
@@ -27,13 +27,14 @@ end
|
|
27
27
|
# Endpoint to register an agent
|
28
28
|
post '/register' do
|
29
29
|
request.body.rewind
|
30
|
-
|
31
|
-
agent_name
|
32
|
-
agent_uuid
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
request_data = JSON.parse(request.body.read, symbolize_names: true)
|
31
|
+
agent_name = request_data[:name]
|
32
|
+
agent_uuid = SecureRandom.uuid
|
33
|
+
|
34
|
+
# Ensure capabilities are lowercase
|
35
|
+
request_data[:capabilities].map!{|c| c.downcase}
|
36
|
+
|
37
|
+
AGENT_REGISTRY << request_data.merge({uuid: agent_uuid})
|
37
38
|
|
38
39
|
status 201
|
39
40
|
content_type :json
|
@@ -47,7 +48,7 @@ get '/discover' do
|
|
47
48
|
capability = params['capability'].downcase
|
48
49
|
|
49
50
|
matching_agents = AGENT_REGISTRY.select do |agent|
|
50
|
-
agent[:capabilities]
|
51
|
+
agent[:capabilities]&.include?(capability)
|
51
52
|
end
|
52
53
|
|
53
54
|
content_type :json
|
@@ -79,4 +80,4 @@ end
|
|
79
80
|
# Start the Sinatra server
|
80
81
|
if __FILE__ == $PROGRAM_NAME
|
81
82
|
Sinatra::Application.run!
|
82
|
-
end
|
83
|
+
end
|