agent99 0.0.2 → 0.0.3

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: eeb28a9ea8730c5ff33d5722f4dad0d0bcec6a54d58784203d1c147b64b17223
4
- data.tar.gz: c27cb24f7ee720f758b94a32bd5d33e1ea5a92dc490022122cc40eaaa736620e
3
+ metadata.gz: e269eac0e8a38fef70f8db9d0487fb3b723d5b928350f396cb8eae852f446897
4
+ data.tar.gz: e13090c1235e35de5c8665d7a7f6e6f0aee3a9aae999b82b1d925bdc07efcb4c
5
5
  SHA512:
6
- metadata.gz: dc796885c649aa669f77954eb25c5a9e8667d5aff6958054b53ca589fd3e620bb03ba3fce5a4b707bc6d2bd67ee2672291d1e4a0e0ff32b5d1d06912766492b0
7
- data.tar.gz: f01c4e6d5a3353c722f87c965faaa6abede17ed57861a9b4fc82829e0c5a33d4bb483eb47420b9cef22bd697fb17d2e7e437bf9a2e5314fc07ab208bfb9d374d
6
+ metadata.gz: 3546e420df4bb94fa6ec09cbbc4b6e735b6ceebb937f9a6438d69b7fecdeea39fa38108620d9327ca6053218e303ed77284de02886f18dce367f4b6ecb10e588
7
+ data.tar.gz: 5fb72619e4321a2db1cfcee0d959cdd7206efb21eead25dba81381008c6d893eb39fbb6205857851f34275a01a421c1c193694c874e21a12b1876de0da2e1ce9
data/CHANGELOG.md CHANGED
@@ -1,8 +1,25 @@
1
- ## [Unreleased]
1
+ # The Changelog
2
2
 
3
+ ## [Unreleased]
3
4
 
4
5
  ## Released
5
6
 
7
+ ### [0.0.3] - 2024-12-08
8
+
9
+ - Document advanced features and update examples
10
+ - Add AgentWatcher and ExampleAgent implementations
11
+ - Update control actions documentation for Agent99
12
+ - Add request flow diagram and update messaging docs
13
+ - Update schema documentation for improved clarity
14
+ - Reorganize documentation and update architecture details
15
+ - Update API reference with detailed implementation guidelines
16
+ - Extend agent lifecycle documentation
17
+ - Enhance agent discovery documentation and registry logic
18
+ - Add KaosSpy example agent
19
+ - Update README links to lowercase for consistency
20
+ - Add documentation for Agent99 framework
21
+ - Add Sinatra dependency and document registry processes
22
+
6
23
  ### [0.0.2] - 2024-12-07
7
24
 
8
25
  - Added examples/control.rb
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent99 Framework (AFW)
2
2
 
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.
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
5
  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
6
 
@@ -55,6 +55,8 @@ Whether you’re a seasoned Ruby developer or just getting started, Agent99 prov
55
55
  - Registry Integration: Register and discover agents through a central registry
56
56
  - Error Handling and Logging: Built-in error management and logging capabilities
57
57
  - Control Actions: Pause, resume, update configuration, and request status of agents
58
+ - Dynamic Agent Loading: Support for runtime loading and deployment of new agents
59
+ - Multi-Agent Processing: Run multiple agents within the same process using thread isolation
58
60
 
59
61
  ## Installation
60
62
 
@@ -138,4 +140,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/MadBom
138
140
 
139
141
  ## License
140
142
 
141
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
143
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/docs/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Agent99 Framework Documentation
2
+
3
+ Welcome to the Agent99 Framework documentation! Below is a table of contents and brief summaries of each markdown file available in this directory. Explore each document for more detailed information on the Agent99 Framework and how to effectively utilize it in your projects!
4
+
5
+ ## Table of Contents
6
+
7
+ 1. **[Agent Discovery](agent_discovery.md)**
8
+ - This document explains how agents within the Agent99 framework discover each other based on their declared capabilities, including the registration and querying processes involved.
9
+
10
+ 2. **[Agent Lifecycle](agent_lifecycle.md)**
11
+ - Learn about the various stages an agent undergoes during its lifetime, from creation and initialization to running and graceful shutdown.
12
+
13
+ 3. **[Agent Registry Processes](agent_registry_processes.md)**
14
+ - This file details the processes handled by the Agent registry, including registration, discovery, and withdrawal of agents, along with example code to illustrate these concepts.
15
+
16
+ 4. **[API Reference](api_reference.md)**
17
+ - The API Reference provides comprehensive details about public methods and classes within Agent99, ensuring developers can leverage its full capabilities.
18
+
19
+ 5. **[Architecture Overview](architecture_overview.md)**
20
+ - An overview of the architecture of Agent99, describing its microservices-oriented structure, communication workflows, and how agents operate within the system.
21
+
22
+ 6. **[Configuration](configuration.md)**
23
+ - Discover how to configure agents using environment variables, including important settings such as the registry base URL.
24
+
25
+ 7. **[Control Actions](control_actions.md)**
26
+ - This document lists the control actions available to agents, such as shutdown, pause, and resume, along with instructions on how to create custom actions.
27
+
28
+ 8. **[Custom Agent Implementation](custom_agent_implementation.md)**
29
+ - Guidelines on creating custom agents, including subclassing, defining schemas, and implementing request and response handling.
30
+
31
+ 9. **[Error Handling and Logging](error_handling_and_logging.md)**
32
+ - Understanding the error handling mechanisms in Agent99, as well as how to configure logging for better monitoring and debugging.
33
+
34
+ 10. **[Extending the Framework](extending_the_framework.md)**
35
+ - Instructions on how to extend Agent99 by implementing custom modules, defining new message types, and using hooks for additional functionality.
36
+
37
+ 11. **[Message Processing](message_processing.md)**
38
+ - This document outlines the different message types supported by Agent99, how they are processed, and the importance of schema validation.
39
+
40
+ 12. **[Messaging Systems](messaging_systems.md)**
41
+ - Overview of the messaging protocols supported by Agent99, including AMQP and NATS, and guidance on how to switch between them.
42
+
43
+ 13. **[Advanced Features](advanced_features.md)**
44
+ - Learn about dynamic agent loading, multi-agent processing, and best practices for running multiple agents within the same process.
45
+
46
+ 14. **[Performance Considerations](performance_considerations.md)**
47
+ - Best practices for ensuring optimal performance within the framework, including optimization techniques and profiling performance.
48
+
49
+ 15. **[Schema Definition](schema_definition.md)**
50
+ - Detailed instructions on how to define schemas using `SimpleJsonSchemaBuilder`, with examples to guide you through the process.
51
+
52
+ 16. **[Security](security.md)**
53
+ - Recommendations on implementing security measures within Agent99, focusing on message encryption and access control.
54
+
55
+ 17. **[Troubleshooting](troubleshooting.md)**
56
+ - Common issues encountered while using Agent99 and suggested steps for debugging, including examining logs and configuration settings.
57
+
@@ -0,0 +1,110 @@
1
+ # Agent99 Framework
2
+
3
+ ## Advanced Features
4
+
5
+ Ruby supports dynamic loading and deployment of libraries at runtime. Agent99 takes advantage of this ability through the `AgentWatcher` system. This powerful feature allows you to:
6
+
7
+ - Monitor a directory for new agent files
8
+ - Automatically load and instantiate new agents when detected
9
+ - Run multiple agents within the same process
10
+ - Manage agent lifecycle independently
11
+
12
+ ### Using AgentWatcher
13
+
14
+ The `AgentWatcher` (found in `examples/agent_watcher.rb`) provides a framework for dynamically loading and running agents:
15
+
16
+ 1. Start the AgentWatcher:
17
+ ```ruby
18
+ watcher = AgentWatcher.new
19
+ watcher.run
20
+ ```
21
+
22
+ 2. Deploy new agents by copying their .rb files to the watched directory (default: './agents'):
23
+ ```bash
24
+ cp my_new_agent.rb agents/
25
+ ```
26
+
27
+ The AgentWatcher will:
28
+ - Detect the new file
29
+ - Load the agent class
30
+ - Instantiate the agent
31
+ - Run it in a separate thread
32
+
33
+ ### Example Implementation
34
+
35
+ ```ruby
36
+ class MyDynamicAgent < Agent99::Base
37
+ TYPE = :server
38
+
39
+ def capabilities = ['my_capability']
40
+
41
+ def receive_request
42
+ # Handle requests
43
+ send_response(status: 'success')
44
+ end
45
+ end
46
+ ```
47
+
48
+ ## Multi-Agent Processing
49
+
50
+ Agent99 supports running multiple agents within the same process, with each agent running in its own thread. This approach:
51
+
52
+ - Reduces resource overhead compared to separate processes
53
+ - Maintains isolation between agents
54
+ - Allows efficient inter-agent communication
55
+ - Simplifies agent management
56
+
57
+ ### Benefits
58
+
59
+ 1. **Resource Efficiency**: Share common resources while maintaining agent isolation
60
+ 2. **Simplified Deployment**: Manage multiple agents through a single process
61
+ 3. **Enhanced Communication**: Direct inter-agent communication within the same process
62
+ 4. **Centralized Management**: Monitor and control multiple agents from a single point
63
+
64
+ ### Implementation Considerations
65
+
66
+ When running multiple agents in the same process:
67
+
68
+ 1. Each agent runs in its own thread for isolation
69
+ 2. Agents can still communicate through the standard messaging system
70
+ 3. Errors in one agent won't affect others
71
+ 4. Resource sharing is handled automatically by the framework
72
+
73
+ ### Example Setup
74
+
75
+ Using AgentWatcher to manage multiple agents:
76
+
77
+ ```ruby
78
+ # Start the watcher
79
+ watcher = AgentWatcher.new
80
+ watcher.run
81
+
82
+ # Deploy multiple agents
83
+ cp agent1.rb agents/
84
+ cp agent2.rb agents/
85
+ cp agent3.rb agents/
86
+ ```
87
+
88
+ Each agent will run independently in its own thread while sharing the same process space.
89
+
90
+ ## Best Practices
91
+
92
+ 1. **Error Handling**
93
+ - Implement proper error handling in each agent
94
+ - Use the built-in logging system
95
+ - Monitor agent health through status checks
96
+
97
+ 2. **Resource Management**
98
+ - Monitor memory usage when running many agents
99
+ - Implement proper cleanup in the `fini` method
100
+ - Use appropriate thread pool sizes
101
+
102
+ 3. **Deployment**
103
+ - Use meaningful file names for easy identification
104
+ - Maintain clear separation of concerns between agents
105
+ - Document agent dependencies and requirements
106
+
107
+ 4. **Monitoring**
108
+ - Implement health checks in your agents
109
+ - Use logging for debugging and monitoring
110
+ - Set up appropriate alerting for critical agents
@@ -0,0 +1,62 @@
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
16
+
17
+ Each agent must implement the `capabilities` method to declare its capabilities as an array of strings:
18
+
19
+ ```ruby
20
+ def capabilities
21
+ ['process_image', 'face_detection']
22
+ end
23
+ ```
24
+
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.
26
+
27
+ ### Discovery API
28
+
29
+ To find other agents, use the `discover_agent` method. Here are some usage examples:
30
+
31
+ ```ruby
32
+ # Find a single agent with a specific capability
33
+ agent = discover_agent(capability: 'face_detection')
34
+
35
+ # Find multiple agents
36
+ agents = discover_agent(capability: 'process_image', how_many: 3)
37
+
38
+ # Find all agents with a specific capability
39
+ all_agents = discover_agent(capability: 'process_image', all: true)
40
+ ```
41
+
42
+ ### Important Note on Capabilities
43
+
44
+ - **Single Capability**: A seeking agent can only request one kind of capability at a time.
45
+ - **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.
46
+
47
+ ### Registry Configuration
48
+
49
+ The registry client comes with default settings, which you can override as needed:
50
+
51
+ - **URL**: Default is `http://localhost:4567` (you can override this using the `REGISTRY_BASE_URL` environment variable).
52
+ - **Interface**: Supports a standard HTTP REST interface.
53
+ - **Reconnection**: Automatic reconnection handling is provided to ensure reliable communication.
54
+
55
+ ### Best Practices
56
+
57
+ 1. **Check Discovery Success**: Always verify if agent discovery succeeded before attempting to establish communication with the discovered agent.
58
+ 2. **Use Specific Capability Names**: This ensures that the correct agents are matched during the discovery process, avoiding ambiguity.
59
+ 3. **Implement Multiple Capabilities**: Consider declaring multiple capabilities per agent to enhance its versatility and improve interaction possibilities.
60
+
61
+ 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.
62
+
@@ -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,102 @@
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
+ REQUEST_SCHEMA = MyAgentRequest.schema
42
+ def capabilities = %w[ greeter hello_world ]
43
+ end
44
+
45
+ # You may create multiple instances of the agent if needed
46
+
47
+ my_agent = MyAgent.new
48
+
49
+ I, [2024-12-07T14:42:08.140286 #36471] INFO -- : Registered Agent MyAgent with ID: 9e735449-582f-46e2-8f11-371e584d0f08
50
+ I, [2024-12-07T14:42:08.141978 #36471] INFO -- : Created queue for agent_id: 9e735449-582f-46e2-8f11-371e584d0f08
51
+ #=>
52
+ #<MyAgent:0x000000011d4d2e48
53
+ ...
54
+
55
+ # The agent as an ID and an address in the peer-to-peer network
56
+
57
+ my_agent.id
58
+ #=> "9e735449-582f-46e2-8f11-371e584d0f08"
59
+ ```
60
+
61
+ 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.
62
+
63
+ ![Agent Register, Discover and Withdraw Processes](diagrams/agent_registry_processes.png)
64
+
65
+ The above image also show the other services provided via the RegistryClient class.
66
+
67
+ The example centralized regristry service provides three processes:
68
+
69
+ 1. Registration Process:
70
+ - MyAgent initializes the RegistryClient
71
+ - RegistryClient sends a POST request to the Central Registry
72
+ - Central Registry responds with a UUID
73
+ - RegistryClient returns the UUID to MyAgent
74
+ 2. Discovery Process:
75
+ - MyAgent requests discovery of agents with a specific capability
76
+ - RegistryClient sends a GET request to the Central Registry
77
+ - Central Registry responds with matching agents
78
+ - RegistryClient returns the matching agents to MyAgent
79
+ 3. Withdrawal Process:
80
+ - MyAgent requests withdrawal using its UUID
81
+ - RegistryClient sends a DELETE request to the Central Registry
82
+ - Central Registry responds with a 204 No Content
83
+ - RegistryClient confirms the withdrawal to MyAgent
84
+
85
+ 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.
86
+
87
+ 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.
88
+
89
+ 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.
90
+
91
+ ```ruby
92
+ class MyAgent < Agent99::Base
93
+ def init
94
+ @agnet_1 = discover_agent(capability: 'one')
95
+ @agnet_2 = discover_agent(capability: 'two')
96
+ @agnet_3 = discover_agent(capability: 'three')
97
+ end
98
+ end
99
+ ```
100
+
101
+ `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.
102
+
@@ -0,0 +1,136 @@
1
+ # Agent99 Framework API Reference
2
+
3
+ ## Agent Implementation Requirements
4
+
5
+ When creating a new agent by subclassing `Agent99::Base`, you must implement certain methods and may optionally override others.
6
+
7
+ ### Required Methods
8
+
9
+ #### `capabilities`
10
+ Returns an array of strings describing the agent's capabilities.
11
+ ```ruby
12
+ def capabilities
13
+ ['process_image', 'face_detection']
14
+ end
15
+ ```
16
+
17
+ #### `receive_request`
18
+ Handles incoming request messages. Must be implemented if the agent accepts requests.
19
+ ```ruby
20
+ def receive_request
21
+ # Process the request message in @payload
22
+ # Access message data via @payload[:data]
23
+ # Send response using send_response(response_data)
24
+ end
25
+ ```
26
+
27
+ ### Optional Methods
28
+
29
+ #### `init`
30
+ Called after registration but before message processing begins. Use for additional setup.
31
+ ```ruby
32
+ def init
33
+ @state = initialize_state
34
+ @resources = setup_resources
35
+ end
36
+ ```
37
+
38
+ #### `fini`
39
+ Called during shutdown. Override to add custom cleanup.
40
+ ```ruby
41
+ def fini
42
+ cleanup_resources
43
+ save_state if @state
44
+ super # Always call super last
45
+ end
46
+ ```
47
+
48
+ #### `receive_response`
49
+ Handles incoming response messages. Override if the agent processes responses.
50
+ ```ruby
51
+ def receive_response
52
+ # Process the response message in @payload
53
+ end
54
+ ```
55
+
56
+ ## Message Client Interface
57
+
58
+ To implement a custom message client, create a class that implements these methods:
59
+
60
+ ### Required Methods
61
+
62
+ #### `initialize(logger: Logger.new($stdout))`
63
+ Sets up the messaging connection.
64
+
65
+ #### `setup(agent_id:, logger:)`
66
+ Initializes message queues/topics for the agent.
67
+ - Returns: queue/topic identifier
68
+
69
+ #### `listen_for_messages(queue, request_handler:, response_handler:, control_handler:)`
70
+ Starts listening for messages.
71
+ - `queue`: Queue/topic to listen on
72
+ - `request_handler`: Lambda for handling requests
73
+ - `response_handler`: Lambda for handling responses
74
+ - `control_handler`: Lambda for handling control messages
75
+
76
+ #### `publish(message)`
77
+ Publishes a message.
78
+ - `message`: Hash containing the message with :header and payload
79
+ - Returns: Hash with :success and optional :error
80
+
81
+ #### `delete_queue(queue_name)`
82
+ Cleans up agent's message queue/topic.
83
+
84
+ ## Registry Client Interface
85
+
86
+ To implement a custom registry client, create a class that implements these methods:
87
+
88
+ ### Required Methods
89
+
90
+ #### `initialize(base_url: ENV.fetch('REGISTRY_BASE_URL', 'http://localhost:4567'), logger: Logger.new($stdout))`
91
+ Sets up the registry connection.
92
+
93
+ #### `register(name:, capabilities:)`
94
+ Registers an agent with the registry.
95
+ - Returns: UUID string for the agent
96
+
97
+ #### `withdraw(id)`
98
+ Removes an agent from the registry.
99
+
100
+ ## Base Class Public Methods
101
+
102
+ The `Agent99::Base` class provides these public methods:
103
+
104
+ #### `run`
105
+ Starts the agent's message processing loop.
106
+
107
+ #### `discover_agent(capability:, how_many: 1, all: false)`
108
+ Finds other agents by capability.
109
+ - Returns: Array of agent information hashes
110
+
111
+ #### `send_response(response)`
112
+ Sends a response message.
113
+ - `response`: Hash containing the response data
114
+
115
+ ## Message Types
116
+
117
+ Messages in Agent99 must include a `:header` with:
118
+ - `:type`: One of "request", "response", or "control"
119
+ - `:to_uuid`: Destination agent's UUID
120
+ - `:from_uuid`: Sending agent's UUID
121
+ - `:event_uuid`: UUID to link request to response
122
+ - `:timestamp`: Integer (`Agent99::Timestamp.new.to_i`)
123
+
124
+ Example request message structure:
125
+ ```ruby
126
+ {
127
+ header: {
128
+ type: 'request',
129
+ to_uuid: ,
130
+ from_uuid: ,
131
+ event_uuid: ,
132
+ timestamp: ,
133
+ },
134
+ # agent specific parameters
135
+ }
136
+ ```