agent99 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e269eac0e8a38fef70f8db9d0487fb3b723d5b928350f396cb8eae852f446897
4
- data.tar.gz: e13090c1235e35de5c8665d7a7f6e6f0aee3a9aae999b82b1d925bdc07efcb4c
3
+ metadata.gz: 1821eef1dcc40dde4e8b93a553728086ab5217020c7635bef4c993a437c88a24
4
+ data.tar.gz: 8f2b26e50c28c257728cc5dc0b2eb6712b02b1eb3286fd3a1185e5517eef5ed4
5
5
  SHA512:
6
- metadata.gz: 3546e420df4bb94fa6ec09cbbc4b6e735b6ceebb937f9a6438d69b7fecdeea39fa38108620d9327ca6053218e303ed77284de02886f18dce367f4b6ecb10e588
7
- data.tar.gz: 5fb72619e4321a2db1cfcee0d959cdd7206efb21eead25dba81381008c6d893eb39fbb6205857851f34275a01a421c1c193694c874e21a12b1876de0da2e1ce9
6
+ metadata.gz: cce04381c30134bc1058d69e6c4090ed12551974884b3e71b5871ed483b81a24fd028b9fb142e48ae51ab60236c1a5c404522bd431d4309285c5a3d42102c9bd
7
+ data.tar.gz: 28e77a074b28f3cc3b8106bb4ba6faaedcbf7ad7215ea03b261aabdaee5560874ed57155af956a035b0e42814cf37c1a9d42e459086edbb72e93c94d1740b9ac
data/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@
4
4
 
5
5
  ## Released
6
6
 
7
+ ### [0.0.4] 2024-12-14
8
+
9
+ - This is a [breaking change](docs/breaking_change_v0.0.4.md)
10
+ - Replaced the capabilities method with the info method so that lots of stuff can be incorporated into an agent's information packet maintained by the registry.
11
+
12
+
13
+
7
14
  ### [0.0.3] - 2024-12-08
8
15
 
9
16
  - Document advanced features and update examples
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
- # Agent99 Framework (AFW)
1
+ # Agent99
2
2
 
3
3
  **Under Development** Initial release has no AI components - its just a generic client-server / request-response micro-services system using a peer-to-peer messaging broker and a centralized agent registry. To keep up with the version changes review [The Changelog](./CHANGELOG.md) file.
4
4
 
5
+ v0.0.4 has a [breaking_change.](docs/breaking_change_v0.0.4.md)
6
+
5
7
  Agent99 is a Ruby-based framework for building and managing AI agents in a distributed system. It provides a robust foundation for creating intelligent agents that can communicate, discover each other, and perform various tasks.
6
8
 
7
9
  ## Hype!
@@ -85,39 +87,36 @@ Here's a basic example of how to create an AI agent:
85
87
  ```ruby
86
88
  require 'agent99'
87
89
 
88
- class MyAgentRequest < SimpleJsonSchemaBuilder::Base
90
+ class GreeterRequest < SimpleJsonSchemaBuilder::Base
89
91
  object do
90
92
  object :header, schema: Agent99::HeaderSchema
91
-
92
- # Define your agents parameters ....
93
- string :greeting, required: false, examples: ["Hello"]
94
- string :name, required: true, examples: ["World"]
93
+ string :name, required: true, examples: ["World"]
95
94
  end
96
95
  end
97
96
 
98
- class MyAgent < Agent99::Base
99
- REQUEST_SCHEMA = MyAgentRequest.schema
100
-
101
- def capabilities
102
- ['text_processing', 'sentiment_analysis']
103
- # TODO: make up mind on keyword or unstructured text
97
+ class GreeterAgent < Agent99::Base
98
+ def info
99
+ {
100
+ name: self.class.to_s,
101
+ type: :server,
102
+ capabilities: ['greeter', 'hello_world'],
103
+ request_schema: GreeterRequest.schema,
104
+ # Uncomment and define these schemas as needed:
105
+ # response_schema: {}, # Agent99::RESPONSE.schema
106
+ # control_schema: {}, # Agent99::CONTROL.schema
107
+ # error_schema: {}, # Agent99::ERROR.schema
108
+ }
104
109
  end
105
110
 
106
- def receive_request
107
- # Handle the validated incoming requests
108
- response = { result: "Processed request" }
109
-
110
- # Not every request needs a response
111
+ def process_request(payload)
112
+ name = payload.dig(:name)
113
+ response = { result: "Hello, #{name}!" }
111
114
  send_response(response)
112
115
  end
113
-
114
- def receive_response
115
- # You sent a request to another agent
116
- # now handle the response.
117
- end
118
116
  end
119
117
 
120
- agent = MyAgent.new
118
+ # Create and run the agent
119
+ agent = GreeterAgent.new
121
120
  agent.run
122
121
  ```
123
122
 
@@ -125,7 +124,14 @@ agent.run
125
124
 
126
125
  The framework can be configured through environment variables:
127
126
 
128
- - `REGISTRY_BASE_URL`: URL of the agent registry service (default: 'http://localhost:4567') See the default registry service in the examples folder.
127
+ - `AGENT99_REGISTRY_URL`: URL of the agent registry service (default: 'http://localhost:4567')
128
+
129
+ Depending on which messaging client you are using, additional environment variables may be used.
130
+
131
+ TODO: show envars for AMQP via Bunny
132
+ TODO: show envars for NATS via nats0server
133
+
134
+ See the examples folder for a default registry service implementation.
129
135
 
130
136
  ## Contributing
131
137
 
@@ -33,10 +33,15 @@ The AgentWatcher will:
33
33
  ### Example Implementation
34
34
 
35
35
  ```ruby
36
- class MyDynamicAgent < Agent99::Base
37
- TYPE = :server
38
-
39
- def capabilities = ['my_capability']
36
+ class MyDynamicAgent < Agent99::Base
37
+ def info
38
+ {
39
+ # ...
40
+ type: :server,
41
+ capabilities: ['my_capability'],
42
+ # ...
43
+ }
44
+ end
40
45
 
41
46
  def receive_request
42
47
  # Handle requests
@@ -0,0 +1,94 @@
1
+ # Central Registry
2
+
3
+ ## Overview
4
+
5
+ The Central Registry is a crucial component of the Agent99 Framework, serving as a centralized hub for agent registration, discovery, and management. Its primary purpose is to facilitate communication and coordination between various agents within the framework, allowing them to register their capabilities and discover other agents with specific skills.
6
+
7
+ The registry provides a RESTful API that can be implemented in any programming language or web framework that supports HTTPS endpoints. This document outlines the API specifications for implementing a compatible Central Registry.
8
+
9
+ ## API Endpoints
10
+
11
+ ### 1. Health Check
12
+
13
+ - **Endpoint**: GET /healthcheck
14
+ - **Purpose**: Provides a simple health check for the registry service.
15
+ - **Response**: JSON object containing the current count of registered agents.
16
+ - **Example Response**:
17
+ ```json
18
+ {
19
+ "agent_count": 5
20
+ }
21
+ ```
22
+
23
+ ### 2. Register Agent
24
+
25
+ - **Endpoint**: POST /register
26
+ - **Purpose**: Allows an agent to register itself with the registry, providing its name and capabilities.
27
+ - **Request Body**: JSON object containing agent information.
28
+ - **Response**: JSON object with a newly generated UUID for the registered agent.
29
+ - **Example Request**:
30
+ ```json
31
+ {
32
+ "name": "TextAnalyzer",
33
+ "capabilities": ["sentiment analysis", "named entity recognition"]
34
+ }
35
+ ```
36
+ - **Example Response**:
37
+ ```json
38
+ {
39
+ "uuid": "550e8400-e29b-41d4-a716-446655440000"
40
+ }
41
+ ```
42
+
43
+ ### 3. Discover Agents
44
+
45
+ - **Endpoint**: GET /discover
46
+ - **Purpose**: Allows discovery of agents based on a specific capability.
47
+ - **Query Parameter**: capability (string)
48
+ - **Response**: JSON array of matching agents with their full information.
49
+ - **Example Request**: GET /discover?capability=sentiment+analysis
50
+ - **Example Response**:
51
+ ```json
52
+ [
53
+ {
54
+ "name": "TextAnalyzer",
55
+ "capabilities": ["sentiment analysis", "named entity recognition"],
56
+ "uuid": "550e8400-e29b-41d4-a716-446655440000"
57
+ }
58
+ ]
59
+ ```
60
+
61
+ ### 4. Withdraw Agent
62
+
63
+ - **Endpoint**: DELETE /withdraw/:uuid
64
+ - **Purpose**: Removes an agent from the registry using its UUID.
65
+ - **Response**:
66
+ - 204 No Content if successful
67
+ - 404 Not Found if the agent UUID is not in the registry
68
+ - **Example Request**: DELETE /withdraw/550e8400-e29b-41d4-a716-446655440000
69
+
70
+ ### 5. List All Agents
71
+
72
+ - **Endpoint**: GET /
73
+ - **Purpose**: Retrieves a list of all registered agents.
74
+ - **Response**: JSON array containing all registered agents' information.
75
+
76
+ ## Implementation Notes
77
+
78
+ 1. Agent capabilities should be stored and compared in lowercase to ensure case-insensitive matching.
79
+ 2. The current implementation uses an in-memory array to store agent information. For production use, consider using a persistent database like SQLite or a more scalable solution.
80
+ 3. The discovery process currently uses simple keyword matching. Future enhancements could include semantic matching for more accurate agent discovery.
81
+
82
+ ## Potential Enhancements
83
+
84
+ 1. **Persistent Storage**: Implement a database backend for storing agent information, ensuring data persistence across server restarts.
85
+ 2. **Authentication and Authorization**: Add security measures to protect sensitive endpoints and ensure only authorized agents can register or withdraw.
86
+ 3. **Semantic Matching**: Enhance the discovery process with natural language processing or vector search capabilities for more intelligent agent matching.
87
+ 4. **Agent Health Monitoring**: Implement periodic health checks on registered agents to ensure they are still active and available.
88
+ 5. **Versioning**: Add support for agent versioning to manage different versions of agents with similar capabilities.
89
+ 6. **Pagination**: Implement pagination for the discovery and list all endpoints to handle large numbers of agents efficiently.
90
+ 7. **Metrics and Logging**: Add comprehensive logging and metrics collection for better monitoring and debugging of the registry service.
91
+ 8. **API Rate Limiting**: Implement rate limiting to prevent abuse and ensure fair usage of the registry service.
92
+
93
+ By implementing this API, developers can create a compatible Central Registry for the Agent99 Framework in their preferred language or framework, enabling seamless integration and communication between diverse agents in the ecosystem.
94
+
@@ -0,0 +1,120 @@
1
+ # Message Client Documentation for Agent99 Framework
2
+
3
+ ## Overview
4
+
5
+ The Message Client is a crucial component of the Agent99 Framework, providing an interface for agents to communicate with each other through a message broker. This document outlines the required methods and functionalities that should be implemented in any message client to ensure compatibility with the Agent99 Framework.
6
+
7
+ ## Message Format Requirements
8
+
9
+ All messages sent and received through the Agent99 Framework must adhere to the following format requirements:
10
+
11
+ 1. **JSON Format**: All messages must be in JSON format. This ensures consistency and ease of parsing across different implementations and languages.
12
+
13
+ 2. **Header Element**: Each message must include a `header` element that conforms to the `HeaderSchema` defined for the Agent99 Framework. The `HeaderSchema` is as follows:
14
+
15
+ ```ruby
16
+ class Agent99::HeaderSchema < SimpleJsonSchemaBuilder::Base
17
+ object do
18
+ string :from_uuid, required: true, examples: [SecureRandom.uuid]
19
+ string :to_uuid, required: true, examples: [SecureRandom.uuid]
20
+ string :event_uuid, required: true, examples: [SecureRandom.uuid]
21
+ string :type, required: true, examples: %w[request response control]
22
+ integer :timestamp, required: true, examples: [Agent99::Timestamp.new.to_i]
23
+ end
24
+ end
25
+ ```
26
+
27
+ 3. **Message Types**: The `type` field in the header must be one of: `request`, `response`, or `control`.
28
+
29
+ 4. **Validation**: All incoming messages are validated against the appropriate schema based on their type. If validation errors are found, an error response message is returned to the sender.
30
+
31
+ ## Class: MessageClient
32
+
33
+ ### Initialization
34
+
35
+ ```ruby
36
+ def initialize(config: {}, logger: Logger.new($stdout))
37
+ # Implementation details...
38
+ end
39
+ ```
40
+
41
+ Creates a new instance of the MessageClient.
42
+
43
+ - `config:` A hash containing configuration options for the message broker connection.
44
+ - `logger:` A logger instance for output (default: stdout logger).
45
+
46
+ ### Public Methods
47
+
48
+ #### setup
49
+
50
+ ```ruby
51
+ def setup(agent_id:, logger:)
52
+ # Implementation details...
53
+ end
54
+ ```
55
+
56
+ Sets up the necessary resources for an agent to start communicating.
57
+
58
+ - `agent_id:` The unique identifier for the agent.
59
+ - `logger:` A logger instance for output.
60
+ - Returns: An object representing the agent's message queue or channel.
61
+
62
+ #### listen_for_messages
63
+
64
+ ```ruby
65
+ def listen_for_messages(
66
+ queue,
67
+ request_handler:,
68
+ response_handler:,
69
+ control_handler:
70
+ )
71
+ # Implementation details...
72
+ end
73
+ ```
74
+
75
+ Starts listening for incoming messages on the specified queue.
76
+
77
+ - `queue:` The queue or channel object returned by the `setup` method.
78
+ - `request_handler:` A callable object to handle incoming request messages.
79
+ - `response_handler:` A callable object to handle incoming response messages.
80
+ - `control_handler:` A callable object to handle incoming control messages.
81
+
82
+ #### publish
83
+
84
+ ```ruby
85
+ def publish(message:)
86
+ # Implementation details...
87
+ end
88
+ ```
89
+
90
+ Publishes a message to the specified queue.
91
+
92
+ - `message:` A hash containing the message to be published. This must be in JSON format and include a header that conforms to the `HeaderSchema`.
93
+ - Returns: A hash indicating the success or failure of the publish operation, including details if the message structure is invalid.
94
+
95
+ #### delete_queue
96
+
97
+ ```ruby
98
+ def delete_queue(queue_name:)
99
+ # Implementation details...
100
+ end
101
+ ```
102
+
103
+ Deletes the specified queue or cleans up resources associated with it.
104
+
105
+ - `queue_name:` The name of the queue to be deleted.
106
+
107
+ ### Implementation Notes
108
+
109
+ 1. **Message Validation**: Implement thorough validation for all incoming and outgoing messages. Ensure that they are in JSON format and contain a header that conforms to the `HeaderSchema`. If validation fails for incoming messages, send an error response to the sender with details about the validation issues.
110
+
111
+ 2. **Error Handling**: Implement robust error handling for all methods, especially for connection, publishing, and validation errors.
112
+
113
+ 3. **Logging**: Provide detailed logging for all operations, including successful actions, validation results, and errors.
114
+
115
+ 4. **Performance and Scalability**: Optimize the client to handle a large number of JSON-formatted messages efficiently, considering potential performance impacts of validation.
116
+
117
+ 5. **Thread Safety**: Ensure that the client is thread-safe, particularly when handling message validation and publishing.
118
+
119
+ By adhering to these requirements and implementing the MessageClient with these considerations, developers can ensure that their implementations will be fully compatible with the Agent99 Framework. The strict adherence to JSON formatting and the inclusion of a standardized header in all messages promotes consistency and reliability in inter-agent communication within the framework.
120
+
@@ -0,0 +1,119 @@
1
+ # RegistryClient Documentation
2
+
3
+ ## Overview
4
+
5
+ The RegistryClient class is a crucial component of the Agent99 framework, providing a Ruby interface to interact with the Central Registry service. It encapsulates the HTTP communication logic required to register agents, discover capabilities, and manage agent lifecycle within the Agent99 ecosystem.
6
+
7
+ ## Class: Agent99::RegistryClient
8
+
9
+ ### Initialization
10
+
11
+ ```ruby
12
+ def initialize(base_url: ENV.fetch('REGISTRY_BASE_URL', 'http://localhost:4567'),
13
+ logger: Logger.new($stdout))
14
+ ```
15
+
16
+ Creates a new instance of the RegistryClient.
17
+
18
+ - `base_url`: The URL of the Central Registry service (default: http://localhost:4567)
19
+ - `logger`: A logger instance for output (default: stdout logger)
20
+
21
+ ### Public Methods
22
+
23
+ #### register
24
+
25
+ ```ruby
26
+ def register(name:, capabilities:)
27
+ ```
28
+
29
+ Registers an agent with the Central Registry.
30
+
31
+ - `name`: The name of the agent
32
+ - `capabilities`: An array of capabilities the agent possesses
33
+ - Returns: The UUID of the registered agent
34
+
35
+ One of the first improvement that should be considered when registering a new agent is adding its JSON schema for its request and response messages. This way there should be no question about how to interface with the agent.
36
+
37
+ #### withdraw
38
+
39
+ ```ruby
40
+ def withdraw(id)
41
+ ```
42
+
43
+ Withdraws an agent from the Central Registry.
44
+
45
+ - `id`: The UUID of the agent to withdraw
46
+ - Returns: nil
47
+
48
+ #### discover
49
+
50
+ ```ruby
51
+ def discover(capability:)
52
+ ```
53
+
54
+ Discovers agents with a specific capability.
55
+
56
+ - `capability`: The capability to search for
57
+ - Returns: An array of agents matching the capability
58
+
59
+ #### fetch_all_agents
60
+
61
+ ```ruby
62
+ def fetch_all_agents
63
+ ```
64
+
65
+ Retrieves all registered agents from the Central Registry.
66
+
67
+ - Returns: An array of all registered agents
68
+
69
+ ### Private Methods
70
+
71
+ The class includes several private methods for handling HTTP requests and responses:
72
+
73
+ - `create_request`: Creates an HTTP request object
74
+ - `send_request`: Sends an HTTP request and handles exceptions
75
+ - `handle_response`: Processes the HTTP response based on its status code
76
+
77
+ ## Usage Example
78
+
79
+ ```ruby
80
+ client = Agent99::RegistryClient.new
81
+ agent_id = client.register(name: "TextAnalyzer", capabilities: ["sentiment analysis", "named entity recognition"])
82
+ matching_agents = client.discover(capability: "sentiment analysis")
83
+ client.withdraw(agent_id)
84
+ ```
85
+
86
+ ## Potential Improvements
87
+
88
+ 1. **Error Handling**: Implement more granular error handling and custom exceptions for different types of failures (e.g., network errors, authentication errors).
89
+
90
+ 2. **Retry Mechanism**: Add a retry mechanism for transient failures, potentially using a library like `retriable`.
91
+
92
+ 3. **Connection Pooling**: Implement connection pooling to improve performance when making multiple requests.
93
+
94
+ 4. **Caching**: Add caching for frequently accessed data, such as the list of all agents or common capability searches.
95
+
96
+ 5. **Asynchronous Operations**: Provide asynchronous versions of methods for non-blocking operations, possibly using Ruby's `async`/`await` syntax or a library like `concurrent-ruby`.
97
+
98
+ 6. **Pagination Support**: Implement pagination for methods that return potentially large datasets, such as `fetch_all_agents`.
99
+
100
+ 7. **Capability Normalization**: Normalize capabilities (e.g., lowercase, remove whitespace) before sending to ensure consistent matching.
101
+
102
+ 8. **Batch Operations**: Add support for batch registration or withdrawal of multiple agents in a single request.
103
+
104
+ 9. **Logging Enhancements**: Improve logging to include more detailed information about requests and responses for better debugging.
105
+
106
+ 10. **Configuration Options**: Allow more configuration options, such as timeout settings, custom headers, or SSL/TLS options.
107
+
108
+ 11. **Capability Validation**: Implement client-side validation of capabilities before sending requests to the server.
109
+
110
+ 12. **Agent Status Updates**: Add methods to update an agent's status or capabilities without full re-registration.
111
+
112
+ 13. **Metrics Collection**: Integrate with a metrics library to collect and report on API usage and performance.
113
+
114
+ 14. **Authentication Support**: Add support for authentication mechanisms if the Central Registry implements them in the future.
115
+
116
+ 15. **API Versioning**: Implement support for API versioning to handle potential future changes in the Central Registry API.
117
+
118
+ By implementing these improvements, the RegistryClient can become more robust, efficient, and feature-rich, enhancing its utility within the Agent99 framework.
119
+
@@ -12,17 +12,21 @@ The agent discovery process involves the following steps:
12
12
  2. **Discovery**: When an agent needs to discover other agents, it queries the registry for agents with specific capabilities.
13
13
  3. **Response**: The registry responds with a list of available agents, allowing them to interact based on their capabilities.
14
14
 
15
- ### Declaring Capabilities
15
+ ### Declaring Capabilities in the Info Method
16
16
 
17
- Each agent must implement the `capabilities` method to declare its capabilities as an array of strings:
17
+ Each agent must implement the `info` method to declare its capabilities as an array of strings:
18
18
 
19
19
  ```ruby
20
- def capabilities
21
- ['process_image', 'face_detection']
20
+ def info
21
+ {
22
+ # ...
23
+ capabilities: ['process_image', 'face_detection'],
24
+ # ...
25
+ }
22
26
  end
23
27
  ```
24
28
 
25
- **Note**: The discovery mechanism is based on an exact match (case insensitive) between the requested capability and the entries in the agent's capabilities array. For example, if an agent declares its capabilities as mentioned above, a discovery request for `'FACE_DETECTION'` will successfully match.
29
+ **Note**: The discovery mechanism is based on an exact match (case insensitive) between the requested capability and the entries in the agent's capabilities array in its information packet. For example, if an agent declares its capabilities as mentioned above, a discovery request for `'FACE_DETECTION'` will successfully match.
26
30
 
27
31
  ### Discovery API
28
32
 
@@ -38,8 +38,14 @@ end
38
38
  # Define the new Agent ....
39
39
 
40
40
  class MyAgent < Agent99::Base
41
- REQUEST_SCHEMA = MyAgentRequest.schema
42
- def capabilities = %w[ greeter hello_world ]
41
+ def info
42
+ {
43
+ # ...
44
+ request_schema: MyAgentRequest.schema
45
+ capabilities: %w[ greeter hello_world ],
46
+ # ...
47
+ }
48
+ end
43
49
  end
44
50
 
45
51
  # You may create multiple instances of the agent if needed
@@ -6,14 +6,24 @@ When creating a new agent by subclassing `Agent99::Base`, you must implement cer
6
6
 
7
7
  ### Required Methods
8
8
 
9
- #### `capabilities`
10
- Returns an array of strings describing the agent's capabilities.
9
+ #### `info`
10
+ The `info` method provides a comprehensive information packet about the agent. It returns a hash containing key details that are crucial for agent registration and discovery within the system.
11
11
  ```ruby
12
- def capabilities
13
- ['process_image', 'face_detection']
12
+ def info
13
+ {
14
+ name: self.class.to_s,
15
+ type: :server,
16
+ capabilities: %w[ greeter hello_world hello-world hello],
17
+ request_schema: MaxwellRequest.schema,
18
+ # response_schema: {}, # Agent99::RESPONSE.schema
19
+ # control_schema: {}, # Agent99::CONTROL.schema
20
+ # error_schema: {}, # Agent99::ERROR.schema
21
+ }
14
22
  end
15
23
  ```
16
24
 
25
+ Entries for **:name** and **:capabilities** are required. Other entries are optional. This entire info packet is stored by the central registry and provided to other agents on a discover "hit" so that the inquiring agents know all the target agent is willing to tell them.
26
+
17
27
  #### `receive_request`
18
28
  Handles incoming request messages. Must be implemented if the agent accepts requests.
19
29
  ```ruby
@@ -0,0 +1,26 @@
1
+ # v0.0.4 is a Breaking Change
2
+
3
+ ## Before
4
+
5
+ Each agent was required to implement a `capabilities` method that returned an Array of Strings in which the elements of the array were essentially synonyms describing the thing that the agent does. The roadmap calls for this capabilities structure to become an unstructured String in which semmantic search will be used for discovery rather than exact matches.
6
+
7
+ ## After
8
+
9
+ The **capabilities** is now just one of several within a Hash collection returned by a new method named `info` representing the agent's information packet. The entire packet will be returned by the central regristry when the agent is discovered.
10
+
11
+ The capabilities element of this new `info` hash still has the same requirement of being an Array of Strings with a promiss of becoming more later as the system becomes more sophisticated.
12
+
13
+ The required elements of the `info` Hash are:
14
+
15
+ - **name** -- automaticall derived from the class name of the agent.
16
+ - **type** -- one of server, client or hybrid.
17
+ - **capabilities** -- An Array of Strings
18
+ - **request_schema** -- is required when the type is server
19
+
20
+ The keys to the `info` Hash are Symbols.
21
+
22
+ ### Modivation
23
+
24
+ The goal is to be able to mix and match multiple agents created by different developers in different languages within the context of the protocols and APIs of the Agent99 Framework. To that end it seems reasonable that agents would have a need to share more than just their capabilitieis. For example, their JSON schema for their request, response and control messages might also be something worth sharing.
25
+
26
+