agent99 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -1
  3. data/README.md +34 -26
  4. data/docs/README.md +57 -0
  5. data/docs/advanced_features.md +115 -0
  6. data/docs/agent99_framework/central_registry.md +94 -0
  7. data/docs/agent99_framework/message_client.md +120 -0
  8. data/docs/agent99_framework/registry_client.md +119 -0
  9. data/docs/agent_discovery.md +66 -0
  10. data/docs/agent_lifecycle.md +137 -0
  11. data/docs/agent_registry_processes.md +108 -0
  12. data/docs/api_reference.md +146 -0
  13. data/docs/architecture.md +77 -0
  14. data/docs/breaking_change_v0.0.4.md +26 -0
  15. data/docs/configuration.md +17 -0
  16. data/docs/control_actions.md +179 -0
  17. data/docs/custom_agent_implementation.md +30 -0
  18. data/docs/diagrams/agent_registry_processes.dot +42 -0
  19. data/docs/diagrams/agent_registry_processes.png +0 -0
  20. data/docs/diagrams/high_level_architecture.dot +26 -0
  21. data/docs/diagrams/high_level_architecture.png +0 -0
  22. data/docs/diagrams/request_flow.dot +42 -0
  23. data/docs/diagrams/request_flow.png +0 -0
  24. data/docs/error_handling_and_logging.md +13 -0
  25. data/docs/extending_the_framework.md +11 -0
  26. data/docs/message_processing.md +165 -0
  27. data/docs/messaging_system.md +129 -0
  28. data/docs/preformance_considerations.md +9 -0
  29. data/docs/schema_definition.md +78 -0
  30. data/docs/security.md +9 -0
  31. data/docs/troubleshooting.md +11 -0
  32. data/docs/what_is_an_agent.md +293 -0
  33. data/examples/README.md +43 -0
  34. data/examples/agent_watcher.rb +106 -0
  35. data/examples/agents/.keep +0 -0
  36. data/examples/chief_agent.rb +17 -6
  37. data/examples/control.rb +16 -7
  38. data/examples/example_agent.rb +39 -0
  39. data/examples/kaos_spy.rb +63 -0
  40. data/examples/maxwell_agent86.rb +15 -26
  41. data/examples/registry.rb +24 -13
  42. data/lib/agent99/agent_discovery.rb +4 -0
  43. data/lib/agent99/agent_lifecycle.rb +34 -10
  44. data/lib/agent99/base.rb +5 -1
  45. data/lib/agent99/header_schema.rb +5 -0
  46. data/lib/agent99/message_processing.rb +3 -1
  47. data/lib/agent99/registry_client.rb +12 -11
  48. data/lib/agent99/tcp_message_client.rb +183 -0
  49. data/lib/agent99/version.rb +1 -1
  50. metadata +50 -3
  51. data/docs/todo.md +0 -66
@@ -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.
@@ -0,0 +1,165 @@
1
+ # Agent99 Framework
2
+
3
+ ## Message Processing
4
+
5
+ The Agent99 framework implements a robust message processing system that handles three main types of
6
+ messages: Request, Response, and Control messages. Each message type follows specific processing flows
7
+ and validation rules.
8
+
9
+ ### Message Types
10
+
11
+ 1. **Request Messages**
12
+ - Sent by clients to request services or actions
13
+ - Must include a valid schema definition
14
+ - Processed through the `receive_request` handler
15
+ - Automatically validated against REQUEST_SCHEMA
16
+ - Can trigger responses back to the sender
17
+
18
+ 2. **Response Messages**
19
+ - Sent in reply to requests
20
+ - Contain results or error information
21
+ - Processed through the `receive_response` handler
22
+ - Include original request reference
23
+ - May trigger additional processing flows
24
+
25
+ 3. **Control Messages**
26
+ - Manage agent lifecycle and behavior
27
+ - Include actions like shutdown, pause, resume
28
+ - Processed through dedicated control handlers
29
+ - Support configuration updates
30
+ - Enable status monitoring
31
+
32
+ ### Message Processing Flow
33
+
34
+ #### Request Processing
35
+ 1. Message arrives and is validated against schema
36
+ 2. If validation passes:
37
+ - `receive_request` is called
38
+ - Custom processing occurs
39
+ - Optional response is sent
40
+ 3. If validation fails:
41
+ - Error response is automatically sent
42
+ - Error is logged
43
+ - Request is not processed further
44
+
45
+ ![Request Message Processing Flow](diagrams/request_flow.png)
46
+
47
+ #### Response Processing
48
+ 1. Response message is received
49
+ 2. `receive_response` handler is called
50
+ 3. Response data is processed
51
+ 4. Any follow-up actions are triggered
52
+
53
+ #### Control Processing
54
+ 1. Control message is received
55
+ 2. Action is identified
56
+ 3. Appropriate handler is called:
57
+ - `handle_shutdown`
58
+ - `handle_pause`
59
+ - `handle_resume`
60
+ - `handle_update_config`
61
+ - `handle_status_request`
62
+ 4. Control response is sent if needed
63
+
64
+ ### Error Handling
65
+
66
+ The framework provides comprehensive error handling:
67
+
68
+ 1. **Validation Errors**
69
+ - Schema validation failures
70
+ - Missing required fields
71
+ - Invalid data types
72
+
73
+ 2. **Processing Errors**
74
+ - Handler exceptions
75
+ - Resource unavailability
76
+ - Timeout conditions
77
+
78
+ 3. **System Errors**
79
+ - Connection issues
80
+ - Resource constraints
81
+ - Framework-level problems
82
+
83
+ ### Best Practices
84
+
85
+ 1. **Message Validation**
86
+ - Always define REQUEST_SCHEMA for request-handling agents
87
+ - Include comprehensive examples in schema
88
+ - Validate message structure
89
+
90
+ 2. **Error Handling**
91
+ - Implement robust error handling in handlers
92
+ - Return meaningful error messages
93
+ - Log all significant events
94
+
95
+ 3. **Response Management**
96
+ - Send responses promptly
97
+ - Include relevant context
98
+ - Handle partial success cases
99
+
100
+ 4. **Control Messages**
101
+ - Respond to all control messages
102
+ - Implement graceful shutdown
103
+ - Maintain agent state properly
104
+
105
+ ### Implementation Example
106
+
107
+ ```ruby
108
+ class MyAgent < Agent99::Base
109
+ REQUEST_SCHEMA = {
110
+ type: "object",
111
+ properties: {
112
+ header: HEADER_SCHEMA,
113
+ data: {
114
+ type: "object",
115
+ required: ["action"],
116
+ properties: {
117
+ action: { type: "string" }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ def receive_request
124
+ action = payload.dig(:data, :action)
125
+ result = process_action(action)
126
+ send_response(result)
127
+ rescue StandardError => e
128
+ send_response(error: e.message)
129
+ end
130
+
131
+ private
132
+
133
+ def process_action(action)
134
+ # Custom processing logic
135
+ { status: "success", result: action }
136
+ end
137
+ end
138
+ ```
139
+
140
+ ### Message Structure
141
+
142
+ All messages must include a header with:
143
+ * `type`: Message type (request/response/control)
144
+ * `to_uuid`: Destination agent ID
145
+ * `from_uuid`: Sender agent ID
146
+ * `event_uuid`: Unique event identifier
147
+ * `timestamp`: Message creation time
148
+
149
+ Example message structure:
150
+ ```ruby
151
+ {
152
+ header: {
153
+ type: "request",
154
+ to_uuid: "agent_123",
155
+ from_uuid: "agent_456",
156
+ event_uuid: "evt_789",
157
+ timestamp: 1638360000000000
158
+ },
159
+ data: {
160
+ # Message-specific payload
161
+ }
162
+ }
163
+ ```
164
+
165
+
@@ -0,0 +1,129 @@
1
+ # Agent99 Framework
2
+
3
+ ## Messaging Systems
4
+
5
+ Agent99 supports both AMQP and NATS messaging systems, allowing you to choose the most appropriate messaging backend for your needs. The framework provides a consistent interface regardless of which messaging system you use.
6
+
7
+ ### Supported Message Brokers
8
+
9
+ #### AMQP (RabbitMQ)
10
+ The AMQP implementation uses RabbitMQ as the message broker and provides:
11
+
12
+ - **Durability**: Messages can persist across broker restarts
13
+ - **Queue TTL**: Queues automatically expire after 60 seconds of inactivity
14
+ - **Automatic Reconnection**: Handles connection drops gracefully
15
+ - **Default Configuration**:
16
+ ```ruby
17
+ {
18
+ host: "127.0.0.1",
19
+ port: 5672,
20
+ ssl: false,
21
+ vhost: "/",
22
+ user: "guest",
23
+ pass: "guest",
24
+ heartbeat: :server,
25
+ frame_max: 131072,
26
+ auth_mechanism: "PLAIN"
27
+ }
28
+ ```
29
+
30
+ #### NATS
31
+ The NATS implementation provides:
32
+
33
+ - **Lightweight**: Simple pub/sub with minimal overhead
34
+ - **Auto-Pruning**: Automatically cleans up unused subjects
35
+ - **High Performance**: Optimized for speed and throughput
36
+ - **Default Configuration**: Uses NATS default connection settings
37
+
38
+ ### Choosing a Message Client
39
+
40
+ You can select your messaging backend when initializing an agent:
41
+
42
+ ```ruby
43
+ # For AMQP
44
+ agent = MyAgent.new(message_client: Agent99::AmqpMessageClient.new)
45
+
46
+ # For NATS
47
+ agent = MyAgent.new(message_client: Agent99::NatsMessageClient.new)
48
+ ```
49
+
50
+ Or configure it via environment variables:
51
+
52
+ TODO: Need to add this to the configuration class which is still TBD
53
+
54
+ ```bash
55
+ # For AMQP
56
+ export MESSAGE_SYSTEM=amqp
57
+ export RABBITMQ_URL=amqp://guest:guest@localhost:5672
58
+
59
+ # For NATS
60
+ export MESSAGE_SYSTEM=nats
61
+ export NATS_URL=nats://localhost:4222
62
+ ```
63
+
64
+ ### Message Handling
65
+
66
+ Both implementations support these core operations:
67
+
68
+ 1. **Queue Setup**:
69
+ ```ruby
70
+ queue = message_client.setup(agent_id: id, logger: logger)
71
+ ```
72
+
73
+ 2. **Message Publishing**:
74
+ ```ruby
75
+ message_client.publish({
76
+ header: {
77
+ type: "request",
78
+ to_uuid: recipient_id,
79
+ from_uuid: sender_id,
80
+ event_uuid: event_id,
81
+ timestamp: Agent99::Timestamp.new.to_i
82
+ },
83
+ data: payload # or whatever for the agent.
84
+ })
85
+ ```
86
+
87
+ 3. **Message Subscription**:
88
+ ```ruby
89
+ message_client.listen_for_messages(
90
+ queue,
91
+ request_handler: ->(msg) { handle_request(msg) },
92
+ response_handler: ->(msg) { handle_response(msg) },
93
+ control_handler: ->(msg) { handle_control(msg) }
94
+ )
95
+ ```
96
+
97
+ ### Key Differences
98
+
99
+ 1. **Queue Management**:
100
+ - AMQP: Explicit queue creation and deletion
101
+ - NATS: Implicit subject-based routing
102
+
103
+ 2. **Message Persistence**:
104
+ - AMQP: Supports persistent messages and queues
105
+ - NATS: Ephemeral messaging by default
106
+
107
+ 3. **Error Handling**:
108
+ - AMQP: Provides detailed connection and channel errors
109
+ - NATS: Simplified error handling with auto-reconnect
110
+
111
+ ### Best Practices
112
+
113
+ 1. **Error Handling**: Always wrap message operations in begin/rescue blocks
114
+ 2. **Logging**: Use the provided logger for debugging and monitoring
115
+ 3. **Configuration**: Use environment variables for deployment flexibility
116
+ 4. **Testing**: Test your agents with both messaging systems to ensure compatibility
117
+
118
+ ### Monitoring
119
+
120
+ Both implementations provide logging for:
121
+ - Message publication success/failure
122
+ - Queue creation and deletion
123
+ - Connection status
124
+ - Error conditions
125
+
126
+ Use the logger to monitor your messaging system:
127
+ ```ruby
128
+ message_client.logger.level = Logger::DEBUG # For detailed logging
129
+ ```
@@ -0,0 +1,9 @@
1
+ # Agent99 Framework
2
+
3
+ ## Performance Considerations
4
+
5
+ To ensure optimal performance:
6
+
7
+ - Optimize message processing by minimizing complex logic in request handlers.
8
+ - Use asynchronous processing wherever possible to prevent blocking operations.
9
+ - Profile agent performance during development to identify bottlenecks.