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,66 @@
1
+ # Agent99 Framework
2
+
3
+ ## Agent Discovery
4
+
5
+ Agents within the Agent99 Framework can efficiently discover one another based on their declared capabilities. This feature fosters dynamic interactions that enhance the collaborative functionality of the agents.
6
+
7
+ ### Overview
8
+
9
+ The agent discovery process involves the following steps:
10
+
11
+ 1. **Registration**: Agents register their capabilities with a central registry upon startup.
12
+ 2. **Discovery**: When an agent needs to discover other agents, it queries the registry for agents with specific capabilities.
13
+ 3. **Response**: The registry responds with a list of available agents, allowing them to interact based on their capabilities.
14
+
15
+ ### Declaring Capabilities in the Info Method
16
+
17
+ Each agent must implement the `info` method to declare its capabilities as an array of strings:
18
+
19
+ ```ruby
20
+ def info
21
+ {
22
+ # ...
23
+ capabilities: ['process_image', 'face_detection'],
24
+ # ...
25
+ }
26
+ end
27
+ ```
28
+
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.
30
+
31
+ ### Discovery API
32
+
33
+ To find other agents, use the `discover_agent` method. Here are some usage examples:
34
+
35
+ ```ruby
36
+ # Find a single agent with a specific capability
37
+ agent = discover_agent(capability: 'face_detection')
38
+
39
+ # Find multiple agents
40
+ agents = discover_agent(capability: 'process_image', how_many: 3)
41
+
42
+ # Find all agents with a specific capability
43
+ all_agents = discover_agent(capability: 'process_image', all: true)
44
+ ```
45
+
46
+ ### Important Note on Capabilities
47
+
48
+ - **Single Capability**: A seeking agent can only request one kind of capability at a time.
49
+ - **Semantics-Based Capabilities**: The development roadmap includes enhancements towards semantic-based capabilities that could allow for more complex interactions between agents in the future. This would be a change from the current Array of Strings to a single String that is a description of the services the agent provides. This would be consistent with the way in which LLMs currently find Tools for augmented generation.
50
+
51
+ ### Registry Configuration
52
+
53
+ The registry client comes with default settings, which you can override as needed:
54
+
55
+ - **URL**: Default is `http://localhost:4567` (you can override this using the `REGISTRY_BASE_URL` environment variable).
56
+ - **Interface**: Supports a standard HTTP REST interface.
57
+ - **Reconnection**: Automatic reconnection handling is provided to ensure reliable communication.
58
+
59
+ ### Best Practices
60
+
61
+ 1. **Check Discovery Success**: Always verify if agent discovery succeeded before attempting to establish communication with the discovered agent.
62
+ 2. **Use Specific Capability Names**: This ensures that the correct agents are matched during the discovery process, avoiding ambiguity.
63
+ 3. **Implement Multiple Capabilities**: Consider declaring multiple capabilities per agent to enhance its versatility and improve interaction possibilities.
64
+
65
+ With these guidelines, you can effectively implement and utilize the agent discovery feature within the Agent99 Framework, ensuring robust and dynamic interactions among agents based on their declared capabilities.
66
+
@@ -0,0 +1,137 @@
1
+ # Agent99 Framework
2
+
3
+ ## Agent Lifecycle
4
+
5
+ The lifecycle of an agent within Agent99 consists of several key stages that are managed through dedicated lifecycle methods. Understanding these stages and their corresponding methods is crucial for proper agent implementation.
6
+
7
+ ### Lifecycle Stages
8
+
9
+ 1. **Creation**: An agent is instantiated through the `Agent99::Base` class.
10
+ 2. **Initialization**: The agent sets up resources and establishes connections.
11
+ 3. **Running**: The agent processes messages and performs its designated tasks.
12
+ 4. **Shutdown**: The agent performs cleanup and gracefully terminates.
13
+
14
+ ### Core Lifecycle Methods
15
+
16
+ #### The `init` Method
17
+
18
+ The `init` method is called automatically after the agent has been registered but before it starts processing messages. Its primary purpose is to perform any additional setup required for the agent following the default initialization provided by the `Agent99::Base` class. This may include:
19
+
20
+ - Setting up initial state
21
+ - Establishing connections to other agents or resources
22
+ - Discovering dependencies or agents to communicate with
23
+ - Sending initial messages to specific agents
24
+
25
+ Here’s an example implementation:
26
+
27
+ ```ruby
28
+ def init
29
+ @state = initialize_state
30
+ @resources = setup_resources
31
+ end
32
+ ```
33
+
34
+ #### Custom Initialization
35
+
36
+ Agents can choose to either use the default behavior provided by the `Agent99::Base` class or implement their own `initialize` method to customize the `logger`, `message_client`, and `registry_client` attributes. For instance:
37
+
38
+ 1. **Using Defaults**: If you do not define an `initialize` method in your agent class, it will inherit the defaults:
39
+
40
+ ```ruby
41
+ class MyAgent < Agent99::Base
42
+ # Inherits default logger, message_client, and registry_client
43
+ end
44
+ ```
45
+
46
+ 2. **Customizing Initialization**: If you need custom initialization, you can ignore the `init` method and override the `initialize` method:
47
+
48
+ ```ruby
49
+ class MyCustomAgent < Agent99::Base
50
+ def initialize(
51
+ registry_client: CustomRegistryClient.new,
52
+ message_client: CustomMessageClient.new,
53
+ logger: Logger.new('custom_agent.log')
54
+ )
55
+ super # Registers the Agent and setups its message queue
56
+
57
+ # Additional state or resource initialization required
58
+ # by the new agent
59
+ end
60
+ end
61
+ ```
62
+
63
+ In this case, the custom agent not need the `init` method to perform any additional setup.
64
+
65
+ #### The `fini` Method
66
+
67
+ The `fini` method is setup to be invoked when the `exit` method is called within `initialize` method by the `on_exit { fini }` hook.
68
+
69
+ The `fini` method ensures proper cleanup during agent shutdown:
70
+
71
+ The default `fini` method does:
72
+ - Withdrawing from the registry
73
+ - Closing message queue connections
74
+
75
+ If your agent requires additional cleanup or state presistence you should implement a custom `fini` method to do things like:
76
+ - Cleaning up resources
77
+ - Saving state (if required)
78
+ - Releasing system resources
79
+
80
+ Example implementation:
81
+
82
+ ```ruby
83
+ def fini
84
+ save_state if @state
85
+ cleanup_resources
86
+ deregister_from_registry
87
+
88
+ super # Always call super last for proper framework cleanup
89
+ end
90
+ ```
91
+
92
+ ### Best Practices
93
+
94
+ 1. **Proper Method Ordering**:
95
+ - Always call `super` first in `initialize`.
96
+ - Always call `super` last in `fini`.
97
+ - This order ensures proper framework initialization and cleanup.
98
+
99
+ 2. **Resource Management**:
100
+ - Initialize all resources in `init` or `initialize`.
101
+ - Clean up all resources in `fini`.
102
+ - Handle cleanup idempotently.
103
+
104
+ 3. **Error Handling**:
105
+ - Implement robust error handling in all methods.
106
+ - Ensure `fini` can handle partial initialization states.
107
+ - Log all significant lifecycle events.
108
+
109
+ 4. **State Management**:
110
+ - Initialize state clearly.
111
+ - Save or cleanup state properly in `fini`.
112
+ - Consider persistence needs.
113
+
114
+ ### Important Considerations
115
+
116
+ - Agents can be implemented as stand-alone processes.
117
+ - When an agent is implemented within the context of a larger application process, the agent should be "run" within its own thread.
118
+ ```ruby
119
+ begin
120
+ my_agent = MyAgent.new
121
+ Thread.new { my_agent.run }
122
+ end
123
+ ```
124
+ - Agents handle only one request message at a time.
125
+ - The `fini` method is called automatically during graceful shutdowns.
126
+
127
+ ### Framework Integration
128
+
129
+ The Agent99 framework automatically manages the lifecycle of agents:
130
+
131
+ 1. Calls `init` (if present) after agent creation.
132
+ 2. Monitors agent health during operation.
133
+ 3. Calls `fini` during shutdown (`on_exit {fini}`).
134
+ 4. Handles cleanup if initialization fails.
135
+
136
+ This automated lifecycle management ensures reliable agent operation within the framework.
137
+
@@ -0,0 +1,108 @@
1
+ # Agent99 Framework
2
+
3
+ ## Agent Registry Processes
4
+
5
+ In the Agent99 framework, an instance of the `Agent99::RegistryClient` class is responsible for registering agent capabilities with a centralized registry. `examples/registry.rb` is a Sinatra web-app example of what a centralized regristry service should be.
6
+
7
+ The registration process is transparent to a new instance of an `Agent99::Base` class.
8
+
9
+ First thing: start the registry.rb Sinatra app and the peer-to-peer messaging network. The default is the `AmqpMessageClient` class.
10
+
11
+ If you do not have the RabbitMQ server installed on your Macthen then grab it using `brew install rabbitmq-server` and while you are installing software do `brew install boxes` as well since the `chief_agent.rb` example uses that little CLI tool to highlight some text in the terminal.
12
+
13
+ ```bash
14
+ git clone ssh://git@github.com/MadBomber/agent99
15
+ brew install rabbitmq-server boxes
16
+ gem install agent99
17
+
18
+ cd agent99/examples
19
+ ./start_rabbitmq_and_registry.sh
20
+ ```
21
+
22
+ Now go into `irb` in a different terminal window and try this code ...
23
+
24
+ ```ruby
25
+ require 'agent99'
26
+
27
+ # Define the Schema for the Agent's request payload
28
+
29
+ class MyAgentRequest < SimpleJsonSchemaBuilder::Base
30
+ object do
31
+ object :header, schema: Agent99::HeaderSchema
32
+
33
+ string :greeting, required: false, examples: ["Hello"]
34
+ string :name, required: true, examples: ["World"]
35
+ end
36
+ end
37
+
38
+ # Define the new Agent ....
39
+
40
+ class MyAgent < Agent99::Base
41
+ def info
42
+ {
43
+ # ...
44
+ request_schema: MyAgentRequest.schema
45
+ capabilities: %w[ greeter hello_world ],
46
+ # ...
47
+ }
48
+ end
49
+ end
50
+
51
+ # You may create multiple instances of the agent if needed
52
+
53
+ my_agent = MyAgent.new
54
+
55
+ I, [2024-12-07T14:42:08.140286 #36471] INFO -- : Registered Agent MyAgent with ID: 9e735449-582f-46e2-8f11-371e584d0f08
56
+ I, [2024-12-07T14:42:08.141978 #36471] INFO -- : Created queue for agent_id: 9e735449-582f-46e2-8f11-371e584d0f08
57
+ #=>
58
+ #<MyAgent:0x000000011d4d2e48
59
+ ...
60
+
61
+ # The agent as an ID and an address in the peer-to-peer network
62
+
63
+ my_agent.id
64
+ #=> "9e735449-582f-46e2-8f11-371e584d0f08"
65
+ ```
66
+
67
+ The image below shows how the `Agent99::Base` class uses dependency injection in its constructor method to bring in an instance of the `RegristryClient` class to provide an interface to the centralized regristery service.
68
+
69
+ ![Agent Register, Discover and Withdraw Processes](diagrams/agent_registry_processes.png)
70
+
71
+ The above image also show the other services provided via the RegistryClient class.
72
+
73
+ The example centralized regristry service provides three processes:
74
+
75
+ 1. Registration Process:
76
+ - MyAgent initializes the RegistryClient
77
+ - RegistryClient sends a POST request to the Central Registry
78
+ - Central Registry responds with a UUID
79
+ - RegistryClient returns the UUID to MyAgent
80
+ 2. Discovery Process:
81
+ - MyAgent requests discovery of agents with a specific capability
82
+ - RegistryClient sends a GET request to the Central Registry
83
+ - Central Registry responds with matching agents
84
+ - RegistryClient returns the matching agents to MyAgent
85
+ 3. Withdrawal Process:
86
+ - MyAgent requests withdrawal using its UUID
87
+ - RegistryClient sends a DELETE request to the Central Registry
88
+ - Central Registry responds with a 204 No Content
89
+ - RegistryClient confirms the withdrawal to MyAgent
90
+
91
+ Like the register process, the withdraw process is also transparent. Its executed on any exit via the public method `fini` in the base class' `on_exit {...}` handler. Calling `exit` for any reason within your agent class will withdraw it from the central registry and remove its message queue from peer-to-peer messaging network.
92
+
93
+ The discover process is primary business logic for your agent class. You must call the `@registry_client.discover(capability: "whatever")` method directly within the agents process.
94
+
95
+ For example suppose your agent needs to work with other agents that provide the "pne", "twp" and "three" services. That is 3 outside agents. You can do this in the `init` method for you agent.
96
+
97
+ ```ruby
98
+ class MyAgent < Agent99::Base
99
+ def init
100
+ @agnet_1 = discover_agent(capability: 'one')
101
+ @agnet_2 = discover_agent(capability: 'two')
102
+ @agnet_3 = discover_agent(capability: 'three')
103
+ end
104
+ end
105
+ ```
106
+
107
+ `discover_agent` is the `Agent99::Base` method that links to the registry client's instance to do the discovery via the central registry. Other parameters to `discover_agent` allow's you agent to specify `how_many` agents having the specify capability you want returned. The default is 1. If you want all the agents capable of providing the requested service use the `all: true` parameter with the `discover_agent` method.
108
+
@@ -0,0 +1,146 @@
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
+ #### `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
+ ```ruby
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
+ }
22
+ end
23
+ ```
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
+
27
+ #### `receive_request`
28
+ Handles incoming request messages. Must be implemented if the agent accepts requests.
29
+ ```ruby
30
+ def receive_request
31
+ # Process the request message in @payload
32
+ # Access message data via @payload[:data]
33
+ # Send response using send_response(response_data)
34
+ end
35
+ ```
36
+
37
+ ### Optional Methods
38
+
39
+ #### `init`
40
+ Called after registration but before message processing begins. Use for additional setup.
41
+ ```ruby
42
+ def init
43
+ @state = initialize_state
44
+ @resources = setup_resources
45
+ end
46
+ ```
47
+
48
+ #### `fini`
49
+ Called during shutdown. Override to add custom cleanup.
50
+ ```ruby
51
+ def fini
52
+ cleanup_resources
53
+ save_state if @state
54
+ super # Always call super last
55
+ end
56
+ ```
57
+
58
+ #### `receive_response`
59
+ Handles incoming response messages. Override if the agent processes responses.
60
+ ```ruby
61
+ def receive_response
62
+ # Process the response message in @payload
63
+ end
64
+ ```
65
+
66
+ ## Message Client Interface
67
+
68
+ To implement a custom message client, create a class that implements these methods:
69
+
70
+ ### Required Methods
71
+
72
+ #### `initialize(logger: Logger.new($stdout))`
73
+ Sets up the messaging connection.
74
+
75
+ #### `setup(agent_id:, logger:)`
76
+ Initializes message queues/topics for the agent.
77
+ - Returns: queue/topic identifier
78
+
79
+ #### `listen_for_messages(queue, request_handler:, response_handler:, control_handler:)`
80
+ Starts listening for messages.
81
+ - `queue`: Queue/topic to listen on
82
+ - `request_handler`: Lambda for handling requests
83
+ - `response_handler`: Lambda for handling responses
84
+ - `control_handler`: Lambda for handling control messages
85
+
86
+ #### `publish(message)`
87
+ Publishes a message.
88
+ - `message`: Hash containing the message with :header and payload
89
+ - Returns: Hash with :success and optional :error
90
+
91
+ #### `delete_queue(queue_name)`
92
+ Cleans up agent's message queue/topic.
93
+
94
+ ## Registry Client Interface
95
+
96
+ To implement a custom registry client, create a class that implements these methods:
97
+
98
+ ### Required Methods
99
+
100
+ #### `initialize(base_url: ENV.fetch('REGISTRY_BASE_URL', 'http://localhost:4567'), logger: Logger.new($stdout))`
101
+ Sets up the registry connection.
102
+
103
+ #### `register(name:, capabilities:)`
104
+ Registers an agent with the registry.
105
+ - Returns: UUID string for the agent
106
+
107
+ #### `withdraw(id)`
108
+ Removes an agent from the registry.
109
+
110
+ ## Base Class Public Methods
111
+
112
+ The `Agent99::Base` class provides these public methods:
113
+
114
+ #### `run`
115
+ Starts the agent's message processing loop.
116
+
117
+ #### `discover_agent(capability:, how_many: 1, all: false)`
118
+ Finds other agents by capability.
119
+ - Returns: Array of agent information hashes
120
+
121
+ #### `send_response(response)`
122
+ Sends a response message.
123
+ - `response`: Hash containing the response data
124
+
125
+ ## Message Types
126
+
127
+ Messages in Agent99 must include a `:header` with:
128
+ - `:type`: One of "request", "response", or "control"
129
+ - `:to_uuid`: Destination agent's UUID
130
+ - `:from_uuid`: Sending agent's UUID
131
+ - `:event_uuid`: UUID to link request to response
132
+ - `:timestamp`: Integer (`Agent99::Timestamp.new.to_i`)
133
+
134
+ Example request message structure:
135
+ ```ruby
136
+ {
137
+ header: {
138
+ type: 'request',
139
+ to_uuid: ,
140
+ from_uuid: ,
141
+ event_uuid: ,
142
+ timestamp: ,
143
+ },
144
+ # agent specific parameters
145
+ }
146
+ ```
@@ -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,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
+
@@ -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
+