Skip to content

Commit 10dc4a2

Browse files
committed
Merge branch 'develop'
2 parents bd70b08 + 1072eb1 commit 10dc4a2

12 files changed

Lines changed: 457 additions & 23 deletions

File tree

flo_ai/flo_ai/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
StartNode,
2424
EndNode,
2525
Edge,
26+
AriumBuilder,
2627
)
2728

2829
# Utils package - Utility functions
@@ -54,7 +55,6 @@
5455
# Arium
5556
'Arium',
5657
'BaseArium',
57-
'AriumBuilder',
5858
'create_arium',
5959
'MessageMemory',
6060
'BaseMemory',

flo_ai/flo_ai/arium/README.md

Lines changed: 148 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,154 @@ result = await (AriumBuilder()
2525
- **Easy Connections**: Simple `connect()` method for linear workflows
2626
- **Flexible Routing**: Full support for custom router functions
2727
- **🧠 LLM-Powered Routing**: Intelligent routing using Large Language Models
28+
- **📊 Event Monitoring**: Real-time workflow execution monitoring with customizable callbacks
2829
- **Visualization**: Built-in graph visualization support
2930
- **Reusable Workflows**: Build once, run multiple times
3031

32+
## 📊 Event Monitoring
33+
34+
Arium provides comprehensive event monitoring capabilities that allow you to track workflow execution in real-time. This is invaluable for debugging, performance monitoring, and understanding how your workflows behave.
35+
36+
### Key Features
37+
38+
- **Real-time Events**: Monitor workflow lifecycle, node execution, and routing decisions
39+
- **Custom Callbacks**: Write your own event handlers for logging, metrics, or debugging
40+
- **Event Filtering**: Choose which types of events to monitor
41+
- **Zero Configuration**: Works out of the box with sensible defaults
42+
- **Performance Tracking**: Automatic execution time measurement for nodes
43+
44+
### Available Event Types
45+
46+
| Event Type | Description |
47+
|------------|-------------|
48+
| `WORKFLOW_STARTED` | Fired when workflow execution begins |
49+
| `WORKFLOW_COMPLETED` | Fired when workflow completes successfully |
50+
| `WORKFLOW_FAILED` | Fired when workflow fails with an error |
51+
| `NODE_STARTED` | Fired when a node (agent/tool) begins execution |
52+
| `NODE_COMPLETED` | Fired when a node completes successfully |
53+
| `NODE_FAILED` | Fired when a node fails with an error |
54+
| `ROUTER_DECISION` | Fired when a router chooses the next node |
55+
| `EDGE_TRAVERSED` | Fired when moving from one node to another |
56+
57+
### Basic Usage
58+
59+
```python
60+
from flo_ai.arium import AriumBuilder, AriumEventType, default_event_callback
61+
62+
# Enable event monitoring with default callback (logs to console)
63+
arium = (AriumBuilder()
64+
.add_agent(my_agent)
65+
.add_tool(my_tool)
66+
.start_with(my_agent)
67+
.connect(my_agent, my_tool)
68+
.end_with(my_tool)
69+
.build())
70+
71+
result = await arium.run(
72+
inputs=["Process this"],
73+
event_callback=default_event_callback
74+
)
75+
```
76+
77+
### Custom Event Callbacks
78+
79+
```python
80+
def my_event_handler(event):
81+
"""Custom event handler for specialized logging"""
82+
print(f"🔔 {event.event_type.value}: {event.node_name}")
83+
if event.execution_time:
84+
print(f" ⏱️ Took {event.execution_time:.2f}s")
85+
if event.error:
86+
print(f" ❌ Error: {event.error}")
87+
88+
# Use your custom callback
89+
arium = (AriumBuilder()
90+
.add_agent(my_agent)
91+
.start_with(my_agent)
92+
.end_with(my_agent)
93+
.build())
94+
95+
result = await arium.run(
96+
inputs=["Hello world"],
97+
event_callback=my_event_handler
98+
)
99+
```
100+
101+
### Event Filtering
102+
103+
Monitor only specific types of events by providing an `events_filter`:
104+
105+
```python
106+
from flo_ai.arium import AriumEventType, default_event_callback
107+
108+
# Only monitor workflow lifecycle and node completions
109+
important_events = [
110+
AriumEventType.WORKFLOW_STARTED,
111+
AriumEventType.NODE_COMPLETED,
112+
AriumEventType.WORKFLOW_COMPLETED,
113+
AriumEventType.WORKFLOW_FAILED
114+
]
115+
116+
arium = (AriumBuilder()
117+
.add_agent(my_agent)
118+
.start_with(my_agent)
119+
.end_with(my_agent)
120+
.build())
121+
122+
result = await arium.run(
123+
inputs=["Process this"],
124+
event_callback=default_event_callback,
125+
events_filter=important_events
126+
)
127+
```
128+
129+
### Silent Execution
130+
131+
By default, workflows run silently. You can use either approach:
132+
133+
```python
134+
# Option 1: Use build_and_run() for convenience (no events)
135+
result = await (AriumBuilder()
136+
.add_agent(my_agent)
137+
.start_with(my_agent)
138+
.end_with(my_agent)
139+
.build_and_run(["Silent execution"]))
140+
141+
# Option 2: Use build() then run() (no events)
142+
arium = (AriumBuilder()
143+
.add_agent(my_agent)
144+
.start_with(my_agent)
145+
.end_with(my_agent)
146+
.build())
147+
148+
result = await arium.run(["Silent execution"])
149+
```
150+
151+
### Event Monitoring vs Build-and-Run
152+
153+
**Important**: Event monitoring is only available through the `Arium.run()` method. The AriumBuilder's `build_and_run()` convenience method does not support event parameters.
154+
155+
- **For event monitoring**: Use `.build()` then `arium.run(inputs, event_callback=...)`
156+
- **For simple execution**: Use `.build_and_run(inputs)` for convenience
157+
- **For reusable workflows**: Use `.build()` once, then call `arium.run()` multiple times
158+
159+
### Event Data Structure
160+
161+
Each event is an `AriumEvent` object with the following properties:
162+
163+
```python
164+
@dataclass
165+
class AriumEvent:
166+
event_type: AriumEventType # Type of event
167+
timestamp: float # Unix timestamp
168+
node_name: Optional[str] = None # Name of involved node
169+
node_type: Optional[str] = None # Type: 'agent', 'tool', 'start', 'end'
170+
execution_time: Optional[float] = None # Node execution time in seconds
171+
error: Optional[str] = None # Error message if applicable
172+
router_choice: Optional[str] = None # Node chosen by router
173+
metadata: Optional[dict] = None # Additional event data
174+
```
175+
31176
## API Reference
32177

33178
### AriumBuilder Methods
@@ -44,7 +189,7 @@ result = await (AriumBuilder()
44189
| `connect(from_node, to_node)` | Simple connection between nodes |
45190
| `add_edge(from_node, to_nodes, router)` | Add edge with optional router |
46191
| `build()` | Build the Arium instance |
47-
| `build_and_run(inputs)` | Build and run in one step |
192+
| `build_and_run(inputs, variables=None)` | Build and run in one step (no event monitoring support) |
48193
| `visualize(output_path, title)` | Generate workflow visualization |
49194
| `reset()` | Reset builder to start fresh |
50195

@@ -98,8 +243,8 @@ arium = (AriumBuilder()
98243
.end_with(my_agent)
99244
.build())
100245

101-
# Run multiple times
102-
result1 = await arium.run(["Input 1"])
246+
# Run multiple times (with optional event monitoring)
247+
result1 = await arium.run(["Input 1"], event_callback=default_event_callback)
103248
result2 = await arium.run(["Input 2"])
104249
```
105250

flo_ai/flo_ai/arium/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from .builder import AriumBuilder, create_arium
44
from .memory import MessageMemory, BaseMemory
55
from .models import StartNode, EndNode, Edge
6+
from .events import AriumEventType, AriumEvent, default_event_callback
67
from .llm_router import (
78
BaseLLMRouter,
89
SmartRouter,
@@ -22,6 +23,10 @@
2223
'StartNode',
2324
'EndNode',
2425
'Edge',
26+
# Event system
27+
'AriumEventType',
28+
'AriumEvent',
29+
'default_event_callback',
2530
# LLM Router functionality
2631
'BaseLLMRouter',
2732
'SmartRouter',

0 commit comments

Comments
 (0)