unaiverse.hsm.state
What this module does 🟡
Defines the State class, a fundamental HSM building block that pairs an optional Action with a name, waiting time, blocking behaviour, and a human-readable message.
state
¶
█████ █████ ██████ █████ █████ █████ █████ ██████████ ███████████ █████████ ██████████ ░░███ ░░███ ░░██████ ░░███ ░░███ ░░███ ░░███ ░░███░░░░░█░░███░░░░░███ ███░░░░░███░░███░░░░░█ ░███ ░███ ░███░███ ░███ ██████ ░███ ░███ ░███ ░███ █ ░ ░███ ░███ ░███ ░░░ ░███ █ ░ ░███ ░███ ░███░░███░███ ░░░░░███ ░███ ░███ ░███ ░██████ ░██████████ ░░█████████ ░██████ ░███ ░███ ░███ ░░██████ ███████ ░███ ░░███ ███ ░███░░█ ░███░░░░░███ ░░░░░░░░███ ░███░░█ ░███ ░███ ░███ ░░█████ ███░░███ ░███ ░░░█████░ ░███ ░ █ ░███ ░███ ███ ░███ ░███ ░ █ ░░████████ █████ ░░█████░░████████ █████ ░░███ ██████████ █████ █████░░█████████ ██████████ ░░░░░░░░ ░░░░░ ░░░░░ ░░░░░░░░ ░░░░░ ░░░ ░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░░░░░ ░░░░░░░░░░ A Collectionless AI Project (https://collectionless.ai) Registration/Login: https://unaiverse.io Code Repositories: https://github.com/collectionlessai/ Main Developers: Stefano Melacci (Project Leader), Christian Di Maio, Tommaso Guidi
State
¶
State(name: str, idx: int = -1, action: Action | None = None, waiting_time: float = 0.0, blocking: bool = True, msg: str | None = None)
A single node in a Hybrid State Machine (HSM).
A State encapsulates all the information that the HSM needs in order to
reside in or pass through a particular node of the state graph. Each state
has a unique name (used as the lookup key inside the machine), an optional
Action that is executed every time the state callable is invoked, a
configurable waiting_time that delays execution, and a blocking flag
that indicates whether the machine should wait for the current action to
complete before processing further transitions.
An optional human-readable msg is printed once to the log the first time
the state is entered. Any <wildcard> placeholders embedded in msg are
resolved at runtime via set_wildcards and apply_wildcards.
A State is callable: invoking it runs the attached Action (if any) and
returns that action's result. The owning HSM registers itself with the state
via set_state_machine, which also propagates wildcard bindings down to the
action.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
Unique name of the state within the HSM. |
|
id |
Integer index assigned by the HSM. |
|
action |
The |
|
waiting_time |
Minimum number of seconds to remain in this state before the
machine considers acting (evaluated by |
|
blocking |
Whether the state prevents the machine from transitioning until the action completes. |
|
msg |
Human-readable description logged once on state entry, or |
|
msg_printed |
True after the entry message has been emitted at least once. |
|
state_machine |
Reference to the owning HSM, set by |
|
wildcards |
Mapping from placeholder strings (e.g. |
|
msg_with_wildcards |
A snapshot of |
Examples:
Creating a state with an action and a log message:
>>> from unaiverse.hsm.state import State
>>> from unaiverse.hsm.action import Action
>>>
>>> action = Action(name="greet", ...)
>>> state = State(name="greeting", idx=0, action=action,
... waiting_time=2.0, blocking=True,
... msg="Entering greeting state")
>>> print(state.name)
greeting
A passive state (no action) that simply waits:
Initialize a State with its identity, optional action, and display properties.
HTML entities inside msg are automatically unescaped so that state
descriptions loaded from JSON behaviour files render correctly. A critical
log message is emitted if name is one of the reserved names listed in
Custom.NOT_ALLOWED_STATE_NAMES.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name of the state within the HSM. Must not be one of the
reserved names in |
required |
idx
|
int
|
Integer index assigned to the state by the HSM. Defaults to |
-1
|
action
|
Action | None
|
An optional |
None
|
waiting_time
|
float
|
Minimum number of seconds the state must remain active
before the machine proceeds. Defaults to |
0.0
|
blocking
|
bool
|
If |
True
|
msg
|
str | None
|
Human-readable description logged once when the state is first
entered. HTML entities are unescaped automatically. Defaults to
|
None
|
Examples:
>>> state = State(name="fetch_data", idx=1, waiting_time=1.5,
... blocking=False, msg="Fetching data...")
>>> state.name
'fetch_data'
>>> state.blocking
False
Source code in unaiverse/hsm/state.py
set_state_machine
¶
Register the parent state machine that owns this state.
Stores a reference to the HSM, propagates the machine's current wildcard
bindings into this state via set_wildcards, and, if the state has an
associated Action, registers the same machine with that action so the
action can access machine-level context.
This method is called automatically by the HSM when the state is added to it. Direct calls are only necessary in advanced scenarios such as testing or dynamic state reconfiguration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hsm
|
object
|
The |
required |
Source code in unaiverse/hsm/state.py
set_msg
¶
Set the human-readable message displayed when this state is entered.
If msg is not None, HTML entities are unescaped and both msg
and msg_with_wildcards are updated to the new value. When None is
passed, both attributes are cleared so no message is printed on the next
state entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
msg
|
str | None
|
The new display message, or |
required |
Source code in unaiverse/hsm/state.py
must_wait
¶
Return whether the state is still within its mandatory waiting period.
Compares the elapsed time since starting_time was recorded against
waiting_time. If no waiting time is configured (waiting_time <= 0),
the method always returns False immediately. While the state is still
waiting, the elapsed time is emitted at DEBUG log level.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
bool
|
|
bool
|
negative. |
Source code in unaiverse/hsm/state.py
to_dict
¶
Serialize the state's configuration to a plain dictionary.
The resulting dictionary uses the same keys expected by the HSM's JSON
behaviour format, making it suitable for persistence, transmission, or
reconstruction of the state. The action name and its keyword arguments are
included when an action is present. Non-ASCII characters in msg are
replaced with XML character references so the output is safe for ASCII
serialization.
Returns:
| Type | Description |
|---|---|
dict
|
A dictionary with the following keys: |
dict
|
|
dict
|
|
dict
|
|
dict
|
|
dict
|
|
Source code in unaiverse/hsm/state.py
has_action
¶
Return whether this state has an associated action.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
get_starting_time
¶
Return the timestamp recorded when the state's execution began.
The starting time is set the first time the state callable is invoked (i.e.
when the HSM enters the state). It is reset to 0. by reset. The
value is used internally by must_wait to calculate elapsed time and is
exposed here for external monitoring or testing.
Returns:
| Type | Description |
|---|---|
float
|
A |
float
|
state entry, or |
float
|
been reset). |
Source code in unaiverse/hsm/state.py
reset
¶
Reset the state's internal counters so it can be re-entered cleanly.
Sets starting_time back to 0. so that must_wait starts measuring
from the next entry, and optionally clears msg_printed so the entry
message is displayed again. If an action is attached, its step counter is
also reset via action.system_interaction.reset_state().
This method is called by the HSM whenever it transitions back into this state after having left it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reset_message_printing
|
bool
|
If |
True
|
Source code in unaiverse/hsm/state.py
set_blocking
¶
Set the blocking status of this state.
A blocking state prevents the HSM from evaluating outgoing transitions
until the state's action has fully completed. A non-blocking state allows
the machine to proceed to the next state regardless of the action's outcome.
The visual indicator shown in the log message (red or green dot) is also
controlled by this flag when state_machine.show_blocking_states is
enabled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blocking
|
bool
|
|
required |
Source code in unaiverse/hsm/state.py
set_wildcards
¶
Replace the wildcard substitution table for this state and its action.
Wildcards are placeholder strings embedded in msg (typically formatted
as <placeholder>) that are resolved to concrete values at runtime by
apply_wildcards. Providing None clears all existing wildcards. The
new table is propagated to the attached action (if any) so that action
arguments containing wildcards are also substituted correctly.
See apply_wildcards to trigger the actual substitution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wildcards
|
dict[str, str | float | int] | None
|
A mapping from placeholder strings to their replacement
values, or |
required |
Source code in unaiverse/hsm/state.py
apply_wildcards
¶
Apply the current wildcard table to the state message and its action.
Restores msg to the pre-substitution template stored in
msg_with_wildcards and then performs a str.replace pass for every
entry in wildcards. This guarantees that changing the wildcard values
and calling apply_wildcards again always produces a fresh result based
on the original template rather than the previously substituted string.
If msg_with_wildcards is None, it is first initialised from the
current msg. The same substitution is then delegated to the attached
action (if any) by calling action.apply_wildcards().
Note
This method mutates msg in place. Call set_wildcards first
whenever the substitution table needs to change.
Source code in unaiverse/hsm/state.py
get_time_passed
¶
Return the elapsed time since the state was entered.
Computes the number of seconds that have passed since starting_time
was recorded. If the state has not yet been entered (or has been reset),
returns -1. as a sentinel value.
Returns:
| Type | Description |
|---|---|
|
A |
|
|
if |