Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/sherpa_ai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
__version__ = "0.1.0"
"""Visualization tools for Sherpa AI.

This package provides visualization utilities for inspecting agent behavior,
state machine execution, and decision trajectories.
"""

from sherpa_ai.visualization.state_machine_viewer import StateMachineViewer

__all__ = ["StateMachineViewer"]
28 changes: 28 additions & 0 deletions src/sherpa_ai/agents/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,34 @@ async def async_run(self) -> TaskResult:

result = await self.async_select_action()

# Record the decision: what was chosen and what was skipped
if result is not None and not isinstance(result, Exception):
chosen_name = result.action.name
alternative_names = [
a.name for a in actions if a.name != chosen_name
]
current_state = (
self.belief.get_state()
if self.belief.state_machine
else ""
)
self.belief.update_internal(
"decision",
self.name,
chosen=chosen_name,
alternatives=alternative_names,
state=current_state or "",
)
if self.shared_memory is not None:
await self.shared_memory.async_add(
"decision",
self.name,
sender=self.name,
chosen=chosen_name,
alternatives=alternative_names,
state=current_state or "",
)

if result is None:
# this means no action is selected
continue
Expand Down
29 changes: 28 additions & 1 deletion src/sherpa_ai/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,30 @@ class ActionFinishEvent(Event):
event_type: str = Field("action_finish", frozen=True)


class DecisionEvent(Event):
"""Event recording an action selection decision.

Captures which action was chosen from the available candidates,
along with the alternatives that were not taken. Used for
trajectory analysis and state machine visualization.

Attributes:
name (str): Name of the decision point.
chosen (str): Name of the action that was selected.
alternatives (list[str]): Names of actions that were available
but not selected.
state (str): The state machine state at decision time, or empty
string if no state machine is used.
event_type (str): Fixed to "decision".
"""

name: str
chosen: str
alternatives: list[str]
state: str = ""
event_type: str = Field("decision", frozen=True)


def build_event(event_type: str, name: str, **kwargs) -> Event:
"""Factory function to create appropriate Event objects based on event type.

Expand All @@ -193,6 +217,7 @@ def build_event(event_type: str, name: str, **kwargs) -> Event:
Event: An instance of the appropriate Event subclass:
- ActionStartEvent for "action_start" event_type
- ActionFinishEvent for "action_finish" event_type
- DecisionEvent for "decision" event_type
- GenericEvent for all other event_type values

Example:
Expand All @@ -206,10 +231,12 @@ def build_event(event_type: str, name: str, **kwargs) -> Event:
return ActionStartEvent(**kwargs, name=name)
elif event_type == "action_finish":
return ActionFinishEvent(**kwargs, name=name)
elif event_type == "decision":
return DecisionEvent(name=name, **kwargs)
elif event_type == "trigger":
if not kwargs.get("args"):
# Default to no args if not provided
kwargs["args"] = {}
return TriggerEvent(name=name, **kwargs)
else:
return GenericEvent(**kwargs, event_type=event_type, name=name)
return GenericEvent(**kwargs, event_type=event_type, name=name)
9 changes: 9 additions & 0 deletions src/sherpa_ai/visualization/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Visualization tools for Sherpa AI.

This package provides visualization utilities for inspecting agent behavior,
state machine execution, and decision trajectories.
"""

from sherpa_ai.visualization.state_machine_viewer import StateMachineViewer

__all__ = ["StateMachineViewer"]
Loading