Skip to content

Commit a5b8d92

Browse files
committed
feat: multiagent session interface
1 parent f5e2070 commit a5b8d92

File tree

5 files changed

+542
-0
lines changed

5 files changed

+542
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""Multi-agent session management for persistent execution.
2+
3+
This package provides session persistence capabilities for multi-agent orchestrators,
4+
enabling resumable execution after interruptions or failures.
5+
"""
6+
7+
from .multiagent_events import (
8+
AfterGraphInvocationEvent,
9+
AfterNodeInvocationEvent,
10+
BeforeGraphInvocationEvent,
11+
BeforeNodeInvocationEvent,
12+
MultiAgentInitializationEvent,
13+
)
14+
from .multiagent_state import MultiAgentState, MultiAgentType
15+
from .multiagent_state_adapter import MultiAgentAdapter
16+
17+
__all__ = [
18+
"BeforeGraphInvocationEvent",
19+
"AfterGraphInvocationEvent",
20+
"MultiAgentInitializationEvent",
21+
"BeforeNodeInvocationEvent",
22+
"AfterNodeInvocationEvent",
23+
"MultiAgentState",
24+
"MultiAgentAdapter",
25+
"MultiAgentType",
26+
]
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""Multi-agent execution lifecycle events for hook system integration.
2+
3+
This module defines event classes that are triggered at key points during
4+
multi-agent orchestrator execution, enabling hooks to respond to lifecycle
5+
events for purposes like persistence, monitoring, and debugging.
6+
7+
Event Types:
8+
- Initialization: When orchestrator starts up
9+
- Before/After Graph: Start/end of overall execution
10+
- Before/After Node: Start/end of individual node execution
11+
"""
12+
13+
from dataclasses import dataclass
14+
from typing import TYPE_CHECKING
15+
16+
from ...hooks.registry import HookEvent
17+
from .multiagent_state import MultiAgentState
18+
19+
if TYPE_CHECKING:
20+
from ...multiagent.base import MultiAgentBase
21+
22+
23+
@dataclass
24+
class MultiAgentInitializationEvent(HookEvent):
25+
"""Event triggered when multi-agent orchestrator initializes.
26+
27+
Attributes:
28+
orchestrator: The multi-agent orchestrator instance
29+
state: Current state of the orchestrator
30+
"""
31+
32+
orchestrator: "MultiAgentBase"
33+
state: MultiAgentState
34+
35+
36+
@dataclass
37+
class BeforeGraphInvocationEvent(HookEvent):
38+
"""Event triggered before orchestrator execution begins.
39+
40+
Attributes:
41+
orchestrator: The multi-agent orchestrator instance
42+
state: Current state before execution starts
43+
"""
44+
45+
orchestrator: "MultiAgentBase"
46+
state: MultiAgentState
47+
48+
49+
@dataclass
50+
class BeforeNodeInvocationEvent(HookEvent):
51+
"""Event triggered before individual node execution.
52+
53+
Attributes:
54+
orchestrator: The multi-agent orchestrator instance
55+
next_node_to_execute: ID of the node about to be executed
56+
"""
57+
58+
orchestrator: "MultiAgentBase"
59+
next_node_to_execute: str
60+
61+
62+
@dataclass
63+
class AfterNodeInvocationEvent(HookEvent):
64+
"""Event triggered after individual node execution completes.
65+
66+
Attributes:
67+
orchestrator: The multi-agent orchestrator instance
68+
executed_node: ID of the node that just completed execution
69+
state: Updated state after node execution
70+
"""
71+
72+
orchestrator: "MultiAgentBase"
73+
executed_node: str
74+
state: MultiAgentState
75+
76+
77+
@dataclass
78+
class AfterGraphInvocationEvent(HookEvent):
79+
"""Event triggered after orchestrator execution completes.
80+
81+
Attributes:
82+
orchestrator: The multi-agent orchestrator instance
83+
state: Final state after execution completes
84+
"""
85+
86+
orchestrator: "MultiAgentBase"
87+
state: MultiAgentState
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""Multi-agent state data structures for session persistence.
2+
3+
This module defines the core data structures used to represent the state
4+
of multi-agent orchestrators in a serializable format for session persistence.
5+
6+
Key Components:
7+
- MultiAgentType: Enum for orchestrator types (Graph/Swarm)
8+
- MultiAgentState: Serializable state container with conversion methods
9+
"""
10+
11+
from dataclasses import dataclass, field
12+
from enum import Enum
13+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
14+
15+
from ...types.content import ContentBlock
16+
17+
if TYPE_CHECKING:
18+
from ...multiagent.base import Status
19+
20+
21+
# TODO: Move to Base after experimental
22+
class MultiAgentType(Enum):
23+
"""Enumeration of supported multi-agent orchestrator types.
24+
25+
Attributes:
26+
SWARM: Collaborative agent swarm orchestrator
27+
GRAPH: Directed graph-based agent orchestrator
28+
"""
29+
30+
SWARM = "swarm"
31+
GRAPH = "graph"
32+
33+
34+
@dataclass
35+
class MultiAgentState:
36+
"""Serializable state container for multi-agent orchestrators.
37+
38+
This class represents the complete execution state of a multi-agent
39+
orchestrator (Graph or Swarm) in a format suitable for persistence
40+
and restoration across sessions.
41+
42+
Attributes:
43+
completed_nodes: Set of node IDs that have completed execution
44+
node_results: Dictionary mapping node IDs to their execution results
45+
status: Current execution status of the orchestrator
46+
next_node_to_execute: List of node IDs ready for execution
47+
current_task: The original task being executed
48+
execution_order: Ordered list of executed node IDs
49+
error_message: Optional error message if execution failed
50+
type: Type of orchestrator (Graph or Swarm)
51+
context: Additional context data (primarily for Swarm)
52+
"""
53+
54+
# Mutual
55+
completed_nodes: Set[str] = field(default_factory=set)
56+
node_results: Dict[str, Any] = field(default_factory=dict)
57+
status: "Status" = "pending"
58+
next_node_to_execute: Optional[List[str]] = None
59+
current_task: Optional[str | List[ContentBlock]] = None
60+
execution_order: list[str] = field(default_factory=list)
61+
error_message: Optional[str] = None
62+
type: Optional[MultiAgentType] = field(default=MultiAgentType.GRAPH)
63+
# Swarm
64+
context: Optional[dict] = field(default_factory=dict)
65+
66+
def to_dict(self) -> dict[str, Any]:
67+
"""Convert MultiAgentState to JSON-serializable dictionary.
68+
69+
Returns:
70+
Dictionary representation suitable for JSON serialization
71+
"""
72+
73+
def _serialize(v: Any) -> Any:
74+
if isinstance(v, (str, int, float, bool)) or v is None:
75+
return v
76+
if isinstance(v, set):
77+
return list(v)
78+
if isinstance(v, dict):
79+
return {str(k): _serialize(val) for k, val in v.items()}
80+
if isinstance(v, (list, tuple)):
81+
return [_serialize(x) for x in v]
82+
if hasattr(v, "to_dict"):
83+
return v.to_dict()
84+
# last resort: stringize anything non-serializable (locks, objects, etc.)
85+
return str(v)
86+
87+
return {
88+
"status": self.status,
89+
"completed_nodes": list(self.completed_nodes),
90+
"next_node_to_execute": list(self.next_node_to_execute) if self.next_node_to_execute else [],
91+
"node_results": _serialize(self.node_results),
92+
"current_task": self.current_task,
93+
"error_message": self.error_message,
94+
"execution_order": self.execution_order,
95+
"type": self.type,
96+
"context": _serialize(self.context),
97+
}
98+
99+
@classmethod
100+
def from_dict(cls, data: dict):
101+
"""Create MultiAgentState from dictionary data.
102+
103+
Args:
104+
data: Dictionary containing state data
105+
106+
Returns:
107+
MultiAgentState instance
108+
"""
109+
data["completed_nodes"] = set(data.get("completed_nodes", []))
110+
return cls(**data)

0 commit comments

Comments
 (0)