agent99 0.0.2 → 0.0.3
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/CHANGELOG.md +18 -1
- data/README.md +4 -2
- data/docs/README.md +57 -0
- data/docs/advanced_features.md +110 -0
- data/docs/agent_discovery.md +62 -0
- data/docs/agent_lifecycle.md +137 -0
- data/docs/agent_registry_processes.md +102 -0
- data/docs/api_reference.md +136 -0
- data/docs/architecture.md +77 -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/examples/README.md +43 -0
- data/examples/agent_watcher.rb +102 -0
- data/examples/agents/.keep +0 -0
- data/examples/example_agent.rb +26 -0
- data/examples/kaos_spy.rb +63 -0
- data/examples/registry.rb +8 -6
- data/lib/agent99/header_schema.rb +5 -0
- data/lib/agent99/version.rb +1 -1
- metadata +44 -3
- data/docs/todo.md +0 -66
@@ -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
|
+

|
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
|
+
}
|
Binary file
|
@@ -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
|
+
}
|
Binary file
|
@@ -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
|
+

|
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
|
+
|