#2869 - initial creation of how to section for the new extendable agents.

This commit is contained in:
Charlie Crane
2024-12-13 15:28:01 +00:00
parent 4ac90c3c10
commit 4c20cd4ac6
4 changed files with 84 additions and 12 deletions

View File

@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [4.0.0] = TBC
### Added
### Changed
- Agents now follow a common configuration format, simplifying the configuration of agents and their extensibilty.
## [3.3.0] - 2024-09-04 ## [3.3.0] - 2024-09-04
### Added ### Added

View File

@@ -0,0 +1,73 @@
.. only:: comment
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
.. _about:
Extensible Agents
*****************
Agents defined within PrimAITE have been updated to allow for easier creation of new bespoke agents.
Developing Agents for PrimAITE
==============================
Agents within PrimAITE, follow the shown inheritance structure, and
# TODO: Turn this into an inheritance diagram
AbstractAgent
|
| - AbstractScriptedAgent
| |
| | - AbstractTAPAgent
| | |
| | | - DataManipulationAgent
| |
| |
| | - RandomAgent
| |
| | - PeriodicAgent
| |
| | - RandomAgent
|
|
| - ProxyAgent
|
| - ControlledAgent
#. **ConfigSchema**:
Configurable items within a new agent within PrimAITE should contain a ``ConfigSchema`` which holds all configurable variables of the agent. This should not include parameters related to its *state*.
.. code-block:: python
class ExampleAgent(AbstractAgent, identifier = "example_agent"):
"""An example agent for demonstration purposes."""
config: "ExampleAgent.ConfigSchema"
"""Agent configuration"""
num_executions: int
"""Number of action executions by agent"""
class ConfigSchema(AbstractAgent.ConfigSchema):
"""ExampleAgent configuration schema"""
agent_name: str
"""Name of agent"""
action_interval: int
"""Number of steps between agent actions"""
#. **identifier**:
All agent classes should have a unique ``identifier`` attribute, for when they are added to the base ``AbstractAgent`` registry. PrimAITE notation is for these to be written in snake_case
Changes to YAML file
====================
Agent configurations specified within YAML files used for earlier versions of PrimAITE will need updating to be compatible with PrimAITE v4.0.0+.
# TODO: Show changes to YAML config needed here

View File

@@ -30,6 +30,7 @@ class AgentLog(BaseModel):
agent_name: str = "unnamed_agent" agent_name: str = "unnamed_agent"
current_episode: int = 1 current_episode: int = 1
current_timestep: int = 0 current_timestep: int = 0
logger: logging
def __init__(self, agent_name: Optional[str]): def __init__(self, agent_name: Optional[str]):
""" """

View File

@@ -53,16 +53,6 @@ class PeriodicAgent(AbstractScriptedAgent, identifier="Periodic_Agent"):
next_execution_timestep: int = 0 next_execution_timestep: int = 0
"""Timestep of the next action execution by the agent.""" """Timestep of the next action execution by the agent."""
@property
def num_executions(self) -> int:
"""Convenience method for accessing num_executions from config."""
return self.config.num_executions
@property
def next_execution_timestep(self) -> int:
"""Convenience method for accessing next_execution_timestep from config."""
return self.config.next_execution_timestep
def _set_next_execution_timestep(self, timestep: int, variance: int) -> None: def _set_next_execution_timestep(self, timestep: int, variance: int) -> None:
"""Set the next execution timestep with a configured random variance. """Set the next execution timestep with a configured random variance.
@@ -78,7 +68,8 @@ class PeriodicAgent(AbstractScriptedAgent, identifier="Periodic_Agent"):
"""Do nothing, unless the current timestep is the next execution timestep, in which case do the action.""" """Do nothing, unless the current timestep is the next execution timestep, in which case do the action."""
if timestep == self.next_execution_timestep and self.num_executions < self.config.max_executions: if timestep == self.next_execution_timestep and self.num_executions < self.config.max_executions:
self.num_executions += 1 self.num_executions += 1
self._set_next_execution_timestep(timestep + self.config.frequency, self.config.variance) self._set_next_execution_timestep(timestep + self.frequency, self.variance)
return "NODE_APPLICATION_EXECUTE", {"node_id": 0, "application_id": 0} self.target_node = self.action_manager.node_names[0]
return "node_application_execute", {"node_name": self.target_node, "application_name": 0}
return "DONOTHING", {} return "DONOTHING", {}