[x] Refactor sensor interface to return Operation instances
[x] Update agent runtime to report changes via Operation to the observer
[x] Fix state rollback for parallel branches in the plan
[x] Modify agent interface to receive a single trace logger, move human logging to mahler/utils
[x] Abort planning stage if it takes over some time (configurable)
Closes: #68
Release Notes
Breaking changes
Simplified Sensor interface
The ouput of a Sensor is now a Subscribable instance that emits Operation values. The sensor no longer modifies the agent state but only returns changes that are applied by the Agent runtime.
This makes state management more robust as state is only modified by the agent runtime, preventing non-determinism on state reporting because of concurrency.
Removed logger option when constructing an Agent
The option has been replaced by a single trace option, which expects a void function that will be called for each agent runtime event. The function can be used to generate human readable logs or to log agent progress on disk. The agent runtime events relate to each other according to the following diagram.
Note that this also means that the Agent runtime no longer produces human readable logs by default. In order to get a readable log a readableTrace function has now be added on mahler/utils. The function accepts a Logger instance.
import { readableTrace } from 'mahler/utils';
const agent = Agent.from({
initial: 0,
tasks: [/* task list */],
// readableTrace requires a Logger instance
opts: { trace: readableTrace(console) },
});
Minor improvements
Improved state management on the Agent runtime. Previously, the internal agent state could be modified by different operations within the runtime lifecycle, action execution, rollbacks, sensors, etc. While the generated plans ensure that two actions cannot modify the same part of the state at the same time, the Agent state could still be affected by concurrency, because of the need to clone the state for some of these operations. With this new version, state changes are propagated using Operation events, limiting the number of places where state changes are allowed. This reduces the need for state cloning and ensures the state remains consistent event if some actions of the plan fail.
A new plannerMaxWaitMs configuration option has been added to the Agent constructor. This value defaults to 60 seconds and allows the agent to interrupt planning if it's taking too long. A long planning time usually means that there is some scenario not being considered and that a Method should be added to the task knowledge databased to help prune the search tree. A planning timeout is reported to the trace function with the event name plan-timeout.
Other improvements
Other changes include refactoring, better linting, improved types and some updated dev dependencies.
Operation
instancesOperation
to the observertrace
logger, move human logging tomahler/utils
Closes: #68
Release Notes
Breaking changes
Simplified Sensor interface
The ouput of a Sensor is now a
Subscribable
instance that emitsOperation
values. The sensor no longer modifies the agent state but only returns changes that are applied by the Agent runtime.This makes state management more robust as state is only modified by the agent runtime, preventing non-determinism on state reporting because of concurrency.
Removed logger option when constructing an Agent
The option has been replaced by a single
trace
option, which expects a void function that will be called for each agent runtime event. The function can be used to generate human readable logs or to log agent progress on disk. The agent runtime events relate to each other according to the following diagram.Note that this also means that the Agent runtime no longer produces human readable logs by default. In order to get a readable log a
readableTrace
function has now be added onmahler/utils
. The function accepts a Logger instance.Minor improvements
plannerMaxWaitMs
configuration option has been added to the Agent constructor. This value defaults to 60 seconds and allows the agent to interrupt planning if it's taking too long. A long planning time usually means that there is some scenario not being considered and that a Method should be added to the task knowledge databased to help prune the search tree. A planning timeout is reported to the trace function with the event nameplan-timeout
.Other improvements
Other changes include refactoring, better linting, improved types and some updated dev dependencies.