-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathmultiagent_plugin.py
More file actions
119 lines (89 loc) · 4.27 KB
/
Copy pathmultiagent_plugin.py
File metadata and controls
119 lines (89 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""MultiAgentPlugin base class for extending multi-agent orchestrator functionality.
This module defines the MultiAgentPlugin base class, which provides a composable way to
add behavior changes to multi-agent orchestrators (Swarm, Graph) through automatic hook
registration and custom initialization.
MultiAgentPlugin is the orchestrator-level counterpart to Plugin (which targets individual agents).
A class can implement both Plugin and MultiAgentPlugin to provide functionality at both levels.
"""
from abc import ABC, abstractmethod
from collections.abc import Awaitable
from typing import TYPE_CHECKING
from ..hooks.registry import HookCallback
from ._discovery import discover_hooks
if TYPE_CHECKING:
from ..multiagent.base import MultiAgentBase
class MultiAgentPlugin(ABC):
"""Base class for objects that extend multi-agent orchestrator functionality.
MultiAgentPlugins provide a composable way to add behavior changes to orchestrators
(Swarm, Graph). They support automatic discovery and registration of methods decorated
with @hook.
Unlike agent-level Plugin, MultiAgentPlugin does not support @tool decorated methods
since orchestrators do not have tool registries.
Attributes:
name: A stable string identifier for the plugin (must be provided by subclass)
hooks: Hooks attached to the orchestrator, auto-discovered from @hook decorated methods
Example using decorators (recommended):
```python
from strands.plugins import MultiAgentPlugin, hook
from strands.hooks import BeforeNodeCallEvent, AfterNodeCallEvent
class MonitoringPlugin(MultiAgentPlugin):
name = "monitoring"
@hook
def on_before_node(self, event: BeforeNodeCallEvent):
print(f"Node {event.node_id} starting")
@hook
def on_after_node(self, event: AfterNodeCallEvent):
print(f"Node {event.node_id} completed")
```
Example with custom initialization:
```python
class MyPlugin(MultiAgentPlugin):
name = "my-plugin"
def init_multi_agent(self, orchestrator: MultiAgentBase) -> None:
# Custom initialization logic
pass
```
Dual-use example (both agent and orchestrator):
```python
from strands.plugins import Plugin, MultiAgentPlugin, hook
from strands.hooks import BeforeInvocationEvent, BeforeNodeCallEvent
class ObservabilityPlugin(Plugin, MultiAgentPlugin):
name = "observability"
@hook
def on_agent_invocation(self, event: BeforeInvocationEvent):
print("Agent invocation started")
@hook
def on_node_call(self, event: BeforeNodeCallEvent):
print(f"Node {event.node_id} starting")
def init_agent(self, agent):
pass # Agent-level setup
def init_multi_agent(self, orchestrator):
pass # Orchestrator-level setup
```
"""
@property
@abstractmethod
def name(self) -> str:
"""A stable string identifier for the plugin."""
...
def __init__(self) -> None:
"""Initialize the plugin and discover decorated hook methods.
Scans the class for methods decorated with @hook and stores references
for later registration when the plugin is attached to an orchestrator.
Uses a guard to prevent double-discovery when used with multiple inheritance
(e.g., a class that inherits from both Plugin and MultiAgentPlugin).
"""
if not hasattr(self, "_hooks"):
self._hooks: list[HookCallback] = discover_hooks(self, self.name)
@property
def hooks(self) -> list[HookCallback]:
"""List of hooks the plugin provides, auto-discovered from @hook decorated methods."""
return self._hooks
def init_multi_agent(self, orchestrator: "MultiAgentBase") -> None | Awaitable[None]:
"""Initialize the plugin with the orchestrator instance.
Override this method to add custom initialization logic. Decorated
hooks are automatically registered by the plugin registry.
Args:
orchestrator: The multi-agent orchestrator instance to initialize with.
"""
return None