agent99 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -1
  3. data/README.md +46 -2
  4. data/docs/README.md +57 -0
  5. data/docs/advanced_features.md +110 -0
  6. data/docs/agent_discovery.md +62 -0
  7. data/docs/agent_lifecycle.md +137 -0
  8. data/docs/agent_registry_processes.md +102 -0
  9. data/docs/api_reference.md +136 -0
  10. data/docs/architecture.md +77 -0
  11. data/docs/configuration.md +17 -0
  12. data/docs/control_actions.md +179 -0
  13. data/docs/custom_agent_implementation.md +30 -0
  14. data/docs/diagrams/agent_registry_processes.dot +42 -0
  15. data/docs/diagrams/agent_registry_processes.png +0 -0
  16. data/docs/diagrams/high_level_architecture.dot +26 -0
  17. data/docs/diagrams/high_level_architecture.png +0 -0
  18. data/docs/diagrams/request_flow.dot +42 -0
  19. data/docs/diagrams/request_flow.png +0 -0
  20. data/docs/error_handling_and_logging.md +13 -0
  21. data/docs/extending_the_framework.md +11 -0
  22. data/docs/message_processing.md +165 -0
  23. data/docs/messaging_system.md +129 -0
  24. data/docs/preformance_considerations.md +9 -0
  25. data/docs/schema_definition.md +78 -0
  26. data/docs/security.md +9 -0
  27. data/docs/troubleshooting.md +11 -0
  28. data/examples/README.md +65 -35
  29. data/examples/agent_watcher.rb +102 -0
  30. data/examples/agents/.keep +0 -0
  31. data/examples/chief_agent.rb +96 -0
  32. data/examples/control.rb +136 -0
  33. data/examples/diagram.dot +22 -0
  34. data/examples/diagram.png +0 -0
  35. data/examples/example_agent.rb +26 -0
  36. data/examples/kaos_spy.rb +63 -0
  37. data/examples/{hello_world.rb → maxwell_agent86.rb} +38 -18
  38. data/examples/{hello_world_request.rb → maxwell_request.rb} +2 -2
  39. data/examples/registry.rb +8 -7
  40. data/examples/start_rabbitmq_and_registry.sh +29 -0
  41. data/lib/agent99/agent_lifecycle.rb +14 -15
  42. data/lib/agent99/amqp_message_client.rb +41 -10
  43. data/lib/agent99/base.rb +6 -8
  44. data/lib/agent99/control_actions.rb +80 -47
  45. data/lib/agent99/header_management.rb +6 -4
  46. data/lib/agent99/header_schema.rb +5 -0
  47. data/lib/agent99/message_processing.rb +21 -13
  48. data/lib/agent99/registry_client.rb +8 -0
  49. data/lib/agent99/version.rb +1 -1
  50. data/lib/agent99.rb +4 -0
  51. metadata +41 -11
  52. data/docs/todo.md +0 -66
  53. data/examples/hello_world_client.rb +0 -70
  54. data/examples/start_agents.sh +0 -20
@@ -0,0 +1,136 @@
1
+ # Agent99 Framework API Reference
2
+
3
+ ## Agent Implementation Requirements
4
+
5
+ When creating a new agent by subclassing `Agent99::Base`, you must implement certain methods and may optionally override others.
6
+
7
+ ### Required Methods
8
+
9
+ #### `capabilities`
10
+ Returns an array of strings describing the agent's capabilities.
11
+ ```ruby
12
+ def capabilities
13
+ ['process_image', 'face_detection']
14
+ end
15
+ ```
16
+
17
+ #### `receive_request`
18
+ Handles incoming request messages. Must be implemented if the agent accepts requests.
19
+ ```ruby
20
+ def receive_request
21
+ # Process the request message in @payload
22
+ # Access message data via @payload[:data]
23
+ # Send response using send_response(response_data)
24
+ end
25
+ ```
26
+
27
+ ### Optional Methods
28
+
29
+ #### `init`
30
+ Called after registration but before message processing begins. Use for additional setup.
31
+ ```ruby
32
+ def init
33
+ @state = initialize_state
34
+ @resources = setup_resources
35
+ end
36
+ ```
37
+
38
+ #### `fini`
39
+ Called during shutdown. Override to add custom cleanup.
40
+ ```ruby
41
+ def fini
42
+ cleanup_resources
43
+ save_state if @state
44
+ super # Always call super last
45
+ end
46
+ ```
47
+
48
+ #### `receive_response`
49
+ Handles incoming response messages. Override if the agent processes responses.
50
+ ```ruby
51
+ def receive_response
52
+ # Process the response message in @payload
53
+ end
54
+ ```
55
+
56
+ ## Message Client Interface
57
+
58
+ To implement a custom message client, create a class that implements these methods:
59
+
60
+ ### Required Methods
61
+
62
+ #### `initialize(logger: Logger.new($stdout))`
63
+ Sets up the messaging connection.
64
+
65
+ #### `setup(agent_id:, logger:)`
66
+ Initializes message queues/topics for the agent.
67
+ - Returns: queue/topic identifier
68
+
69
+ #### `listen_for_messages(queue, request_handler:, response_handler:, control_handler:)`
70
+ Starts listening for messages.
71
+ - `queue`: Queue/topic to listen on
72
+ - `request_handler`: Lambda for handling requests
73
+ - `response_handler`: Lambda for handling responses
74
+ - `control_handler`: Lambda for handling control messages
75
+
76
+ #### `publish(message)`
77
+ Publishes a message.
78
+ - `message`: Hash containing the message with :header and payload
79
+ - Returns: Hash with :success and optional :error
80
+
81
+ #### `delete_queue(queue_name)`
82
+ Cleans up agent's message queue/topic.
83
+
84
+ ## Registry Client Interface
85
+
86
+ To implement a custom registry client, create a class that implements these methods:
87
+
88
+ ### Required Methods
89
+
90
+ #### `initialize(base_url: ENV.fetch('REGISTRY_BASE_URL', 'http://localhost:4567'), logger: Logger.new($stdout))`
91
+ Sets up the registry connection.
92
+
93
+ #### `register(name:, capabilities:)`
94
+ Registers an agent with the registry.
95
+ - Returns: UUID string for the agent
96
+
97
+ #### `withdraw(id)`
98
+ Removes an agent from the registry.
99
+
100
+ ## Base Class Public Methods
101
+
102
+ The `Agent99::Base` class provides these public methods:
103
+
104
+ #### `run`
105
+ Starts the agent's message processing loop.
106
+
107
+ #### `discover_agent(capability:, how_many: 1, all: false)`
108
+ Finds other agents by capability.
109
+ - Returns: Array of agent information hashes
110
+
111
+ #### `send_response(response)`
112
+ Sends a response message.
113
+ - `response`: Hash containing the response data
114
+
115
+ ## Message Types
116
+
117
+ Messages in Agent99 must include a `:header` with:
118
+ - `:type`: One of "request", "response", or "control"
119
+ - `:to_uuid`: Destination agent's UUID
120
+ - `:from_uuid`: Sending agent's UUID
121
+ - `:event_uuid`: UUID to link request to response
122
+ - `:timestamp`: Integer (`Agent99::Timestamp.new.to_i`)
123
+
124
+ Example request message structure:
125
+ ```ruby
126
+ {
127
+ header: {
128
+ type: 'request',
129
+ to_uuid: ,
130
+ from_uuid: ,
131
+ event_uuid: ,
132
+ timestamp: ,
133
+ },
134
+ # agent specific parameters
135
+ }
136
+ ```
@@ -0,0 +1,77 @@
1
+ # Agent99 Framework Architecture
2
+
3
+ ## High-Level Architecture Overview
4
+
5
+ Agent99 is a Ruby-based framework designed for building and managing software agents in a distributed system environment. The architecture follows a service-oriented approach with three main components:
6
+
7
+ 1. **Agents**: Independent services that can register, discover, and communicate with each other
8
+ 2. **Registry Service**: Central registration and discovery system
9
+ 3. **Message Broker**: Communication backbone (supports AMQP or NATS)
10
+
11
+ ### System Components Diagram
12
+
13
+ ![High Level Architecture](diagrams/high_level_architecture.png)
14
+
15
+ The diagram above (generated from `diagrams/high_level_architecture.dot`) illustrates the key components and their interactions:
16
+
17
+ - **Agents**: Come in three types:
18
+ - Client Agents: Only make requests
19
+ - Server Agents: Only respond to requests
20
+ - Hybrid Agents: Both make and respond to requests
21
+
22
+ - **Registry Service**:
23
+ - Maintains agent registrations
24
+ - Handles capability-based discovery
25
+ - Issues unique UUIDs to agents
26
+
27
+ - **Message Broker**:
28
+ - Supports both AMQP and NATS protocols
29
+ - Handles message routing between agents
30
+ - Provides reliable message delivery
31
+
32
+ ### Communication Patterns
33
+
34
+ 1. **Registration Flow**:
35
+ - New agent instantiated
36
+ - Agent registers with Registry Service
37
+ - Receives unique UUID for identification
38
+ - Sets up message queue/topic
39
+
40
+ 2. **Discovery Flow**:
41
+ - Agent queries Registry for specific capabilities
42
+ - Registry returns matching agent information
43
+ - Requesting agent caches discovery results
44
+
45
+ 3. **Messaging Flow**:
46
+ - Agent creates message with recipient UUID
47
+ - Message routed through Message Broker
48
+ - Recipient processes message based on type:
49
+ - Requests: Handled by receive_request
50
+ - Responses: Handled by receive_response
51
+ - Control: Handled by control handlers
52
+
53
+ ### Message Types
54
+
55
+ The framework supports three primary message types:
56
+
57
+ 1. **Request Messages**:
58
+ - Used to request services from other agents
59
+ - Must include capability requirements
60
+ - Can contain arbitrary payload data
61
+
62
+ 2. **Response Messages**:
63
+ - Sent in reply to requests
64
+ - Include original request reference
65
+ - Contain result data or error information
66
+
67
+ 3. **Control Messages**:
68
+ - System-level communication
69
+ - Handle agent lifecycle events
70
+ - Support configuration updates
71
+
72
+ ## Implementation Details
73
+
74
+ For detailed implementation information, see:
75
+ - [API Reference](api_reference.md) for method specifications
76
+ - [Agent Lifecycle](agent_lifecycle.md) for lifecycle management
77
+ - [Agent Discovery](agent_discovery.md) for discovery mechanisms
@@ -0,0 +1,17 @@
1
+ # Agent99 Framework
2
+
3
+ ## Configuration
4
+
5
+ Agents can be configured using environment variables. Key configuration options include:
6
+
7
+ - `REGISTRY_BASE_URL`: Specifies the URL of the agent registry service (default: 'http://localhost:4567').
8
+
9
+
10
+ ### Environment Variables
11
+
12
+ To set an environment variable, use the following command in your terminal before running your application:
13
+
14
+ ```bash
15
+ export REGISTRY_BASE_URL=http://my-registry-url
16
+ ```
17
+
@@ -0,0 +1,179 @@
1
+ # Agent99 Framework
2
+
3
+ ## Control Actions
4
+
5
+ Agent99 provides a robust control system that allows for dynamic management of agents during runtime. Control actions enable administrative operations and state management without requiring agent restarts or redeployment.
6
+
7
+ ### Built-in Control Actions
8
+
9
+ The framework includes several built-in control actions:
10
+
11
+ #### shutdown
12
+ - Gracefully stops the agent
13
+ - Withdraws registration from the registry
14
+ - Cleans up resources and connections
15
+ - Triggers the `fini` method
16
+ - Example usage:
17
+ ```ruby
18
+ {
19
+ header: {
20
+ type: "control",
21
+ to_uuid: "target_agent_id",
22
+ from_uuid: "control_agent_id",
23
+ event_uuid: "evt_123",
24
+ timestamp: 1638360000000000
25
+ },
26
+ action: "shutdown"
27
+ }
28
+ ```
29
+
30
+ #### pause
31
+ TODO: haven't decided whether messages are left in the messaging network or whether they should be queued within the agent. TBD
32
+
33
+ - Temporarily halts message processing
34
+ - Maintains agent registration
35
+ - Continues to accept control messages
36
+ - Queues other messages for later processing
37
+ - Example usage:
38
+ ```ruby
39
+ {
40
+ header: {
41
+ type: "control",
42
+ to_uuid: "target_agent_id",
43
+ from_uuid: "control_agent_id",
44
+ event_uuid: "evt_456",
45
+ timestamp: 1638360000000000
46
+ },
47
+ action: "pause"
48
+ }
49
+ ```
50
+
51
+ #### resume
52
+ - Reactivates a paused agent
53
+ - Processes any queued messages
54
+ - Restores normal operation
55
+ - Example usage:
56
+ ```ruby
57
+ {
58
+ header: {
59
+ type: "control",
60
+ to_uuid: "target_agent_id",
61
+ from_uuid: "control_agent_id",
62
+ event_uuid: "evt_789",
63
+ timestamp: 1638360000000000
64
+ },
65
+ action: "resume"
66
+ }
67
+ ```
68
+
69
+ #### update_config
70
+
71
+ TODO: This is still TBD waiting for the design of the overall configuration class.
72
+
73
+ - Updates agent configuration at runtime
74
+ - Allows dynamic behavior modification
75
+ - Example usage:
76
+ ```ruby
77
+ {
78
+ header: {
79
+ type: "control",
80
+ to_uuid: "target_agent_id",
81
+ from_uuid: "control_agent_id",
82
+ event_uuid: "evt_101",
83
+ timestamp: 1638360000000000
84
+ },
85
+ action: "update_config",
86
+ config: {
87
+ "log_level": "DEBUG",
88
+ "timeout": 30
89
+ }
90
+ }
91
+ ```
92
+
93
+ #### status
94
+ - Requests current agent status
95
+ - Returns operational statistics
96
+ - Example usage:
97
+ ```ruby
98
+ {
99
+ header: {
100
+ type: "control",
101
+ to_uuid: "target_agent_id",
102
+ from_uuid: "control_agent_id",
103
+ event_uuid: "evt_102",
104
+ timestamp: 1638360000000000
105
+ },
106
+ action: "status"
107
+ }
108
+ ```
109
+
110
+ ### Implementing Custom Control Actions
111
+
112
+ You can implement custom control actions by:
113
+
114
+ 1. Adding a handler method to your agent class:
115
+ ```ruby
116
+ def handle_custom_action
117
+ # Implementation
118
+ send_control_response(status: "custom action completed")
119
+ end
120
+ ```
121
+
122
+ 2. Registering the handler in CONTROL_HANDLERS:
123
+ ```ruby
124
+ CONTROL_HANDLERS.merge!({
125
+ 'custom_action' => :handle_custom_action
126
+ })
127
+ ```
128
+
129
+ ### Best Practices
130
+
131
+ 1. **Response Handling**
132
+ - Always send a control response
133
+ - Include relevant status information
134
+ - Handle errors gracefully
135
+
136
+ 2. **State Management**
137
+ - Maintain consistent state transitions
138
+ - Document state dependencies
139
+ - Handle edge cases (e.g., pause while paused)
140
+
141
+ 3. **Security Considerations**
142
+ - Validate control message sources
143
+ - Implement appropriate authorization
144
+ - Log all control actions
145
+
146
+ 4. **Error Recovery**
147
+ - Implement timeout mechanisms
148
+ - Handle partial failures
149
+ - Provide status feedback
150
+
151
+ ### Control Flow Example
152
+
153
+ ```ruby
154
+ class MyAgent < Agent99::Base
155
+ def handle_custom_restart
156
+ begin
157
+ cleanup_resources
158
+ reinitialize_state
159
+ send_control_response(status: "restart completed")
160
+ rescue StandardError => e
161
+ send_control_response(
162
+ status: "restart failed",
163
+ error: e.message
164
+ )
165
+ end
166
+ end
167
+ end
168
+ ```
169
+
170
+ ### Monitoring Control Actions
171
+
172
+ All control actions are automatically logged with:
173
+ * Timestamp
174
+ * Action type
175
+ * Source agent
176
+ * Result status
177
+ * Error information (if any)
178
+
179
+ This enables effective monitoring and troubleshooting of agent behavior and system state.
@@ -0,0 +1,30 @@
1
+ # Agent99 Framework
2
+
3
+ ## Custom Agent Implementation
4
+
5
+ ### Creating a Custom Agent
6
+
7
+ To create a custom agent:
8
+
9
+ 1. Subclass `Agent99::Base`.
10
+ 2. Define the request and response schemas.
11
+ 3. Implement the `receive_request` and `receive_response` methods.
12
+
13
+ Example:
14
+
15
+ ```ruby
16
+ class MyCustomAgent < Agent99::Base
17
+ REQUEST_SCHEMA = MyAgentRequest.schema
18
+
19
+ def receive_request
20
+ # Handle incoming request
21
+ response = { result: "Handled request" }
22
+ send_response(response)
23
+ end
24
+
25
+ def receive_response
26
+ # Handle incoming response from another agent
27
+ end
28
+ end
29
+ ```
30
+
@@ -0,0 +1,42 @@
1
+ digraph AgentRegistration {
2
+ rankdir=LR;
3
+ node [shape=box, style=rounded];
4
+ edge [fontsize=10];
5
+
6
+ MyAgent [label="MyAgent"];
7
+ RegistryClient [label="RegistryClient"];
8
+ CentralRegistry [label="Central Registry\n(Sinatra Server)"];
9
+
10
+ subgraph cluster_registration {
11
+ label="Registration Process";
12
+ color=lightgrey;
13
+ style=filled;
14
+
15
+ MyAgent -> RegistryClient [label="1. initialize"];
16
+ RegistryClient -> CentralRegistry [label="2. POST /register\n{name, capabilities}"];
17
+ CentralRegistry -> RegistryClient [label="3. 201 Created\n{uuid}"];
18
+ RegistryClient -> MyAgent [label="4. Return uuid"];
19
+ }
20
+
21
+ subgraph cluster_discovery {
22
+ label="Discovery Process";
23
+ color=lightblue;
24
+ style=filled;
25
+
26
+ MyAgent -> RegistryClient [label="5. discover(capability)"];
27
+ RegistryClient -> CentralRegistry [label="6. GET /discover?capability=..."];
28
+ CentralRegistry -> RegistryClient [label="7. 200 OK\n[matching agents]"];
29
+ RegistryClient -> MyAgent [label="8. Return matching agents"];
30
+ }
31
+
32
+ subgraph cluster_withdrawal {
33
+ label="Withdrawal Process";
34
+ color=lightpink;
35
+ style=filled;
36
+
37
+ MyAgent -> RegistryClient [label="9. withdraw(uuid)"];
38
+ RegistryClient -> CentralRegistry [label="10. DELETE /withdraw/:uuid"];
39
+ CentralRegistry -> RegistryClient [label="11. 204 No Content"];
40
+ RegistryClient -> MyAgent [label="12. Confirm withdrawal"];
41
+ }
42
+ }
@@ -0,0 +1,26 @@
1
+ digraph Agent99Architecture {
2
+ rankdir=LR;
3
+ node [shape=box, style=rounded];
4
+
5
+ subgraph cluster_0 {
6
+ label="Agent99 Framework";
7
+ style=dashed;
8
+
9
+ Agent1 [label="Agent 1\n(Client)"];
10
+ Agent2 [label="Agent 2\n(Server)"];
11
+ Agent3 [label="Agent 3\n(Hybrid)"];
12
+ }
13
+
14
+ Registry [shape=cylinder, label="Registry\nService"];
15
+ MessageBroker [shape=diamond, label="Message Broker\n(AMQP/NATS)"];
16
+
17
+ // Registration flows
18
+ Agent1 -> Registry [label="register/discover", style=dashed];
19
+ Agent2 -> Registry [label="register/discover", style=dashed];
20
+ Agent3 -> Registry [label="register/discover", style=dashed];
21
+
22
+ // Message flows
23
+ Agent1 -> MessageBroker [dir=both, label="publish/subscribe"];
24
+ Agent2 -> MessageBroker [dir=both, label="publish/subscribe"];
25
+ Agent3 -> MessageBroker [dir=both, label="publish/subscribe"];
26
+ }
@@ -0,0 +1,42 @@
1
+ digraph RequestFlow {
2
+ rankdir=TB;
3
+ node [shape=box, style=rounded];
4
+
5
+ // Message arrival and initial processing
6
+ start [shape=oval, label="Message Arrives"];
7
+ dispatch [label="dispatcher()\nMessage Processing Loop"];
8
+ process [label="process_request(message)"];
9
+ validate [label="validate_schema()"];
10
+
11
+ // Main processing branch
12
+ receive [label="receive_request()\nAgent Implementation"];
13
+ send [label="send_response()\nOptional Response"];
14
+
15
+ // Error handling branch
16
+ error [label="Error Handler"];
17
+ error_response [label="Send Error Response"];
18
+
19
+ // Flow connections
20
+ start -> dispatch;
21
+ dispatch -> process;
22
+ process -> validate;
23
+
24
+ // Success path
25
+ validate -> receive [label="Valid"];
26
+ receive -> send [style=dashed];
27
+
28
+ // Error path
29
+ validate -> error [label="Invalid"];
30
+ error -> error_response;
31
+
32
+ // Styling
33
+ {
34
+ node [shape=note, style=filled, fillcolor=lightyellow];
35
+ note1 [label="Schema validation\nensures message\nintegrity"];
36
+ note2 [label="Custom processing\nin agent subclass"];
37
+ }
38
+
39
+ // Connect notes
40
+ validate -> note1 [style=dotted, arrowhead=none];
41
+ receive -> note2 [style=dotted, arrowhead=none];
42
+ }
Binary file
@@ -0,0 +1,13 @@
1
+ # Agent99 Framework
2
+
3
+ ## Error Handling and Logging
4
+
5
+ Agent99 incorporates robust error handling mechanisms, with error messages being captured and logged. The logging system is configured through environment variables to define the logging level and output destination.
6
+
7
+ Example:
8
+
9
+ ```bash
10
+ export LOG_LEVEL=DEBUG
11
+ ```
12
+
13
+ Logs provide insights into agent activities, including errors encountered during message processing and system events.
@@ -0,0 +1,11 @@
1
+ # Agent99 Framework
2
+
3
+ ## Extending the Framework
4
+
5
+ To extend Agent99:
6
+
7
+ 1. Implement custom modules and include them in your agents.
8
+ 2. Define new message types or schemas as needed.
9
+ 3. Use hooks to add functionality or override existing behavior.
10
+
11
+ If a plugin system is developed in the future, it would allow for additional features without modifying the core framework.