Skip to content

Commit c5fb0ac

Browse files
husseinmozannarrysweet
authored andcommitted
Add MagenticOneGroupChat to AGS (#4595)
* add magenticonegroupchat to ags * fix termination condition * typing order check * format error * fix M1 orchestrator handle tool mesages * add filesurfer and coder
1 parent c532e8f commit c5fb0ac

File tree

8 files changed

+556
-114
lines changed

8 files changed

+556
-114
lines changed

python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_magentic_one/_magentic_one_orchestrator.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@
1212

1313
from .... import TRACE_LOGGER_NAME
1414
from ....base import Response, TerminationCondition
15-
from ....messages import AgentMessage, ChatMessage, MultiModalMessage, StopMessage, TextMessage
15+
from ....messages import (
16+
AgentMessage,
17+
ChatMessage,
18+
HandoffMessage,
19+
MultiModalMessage,
20+
StopMessage,
21+
TextMessage,
22+
ToolCallMessage,
23+
ToolCallResultMessage,
24+
)
25+
1626
from ....state import MagenticOneOrchestratorState
1727
from .._base_group_chat_manager import BaseGroupChatManager
1828
from .._events import (
@@ -418,7 +428,12 @@ def _thread_to_context(self) -> List[LLMMessage]:
418428
"""Convert the message thread to a context for the model."""
419429
context: List[LLMMessage] = []
420430
for m in self._message_thread:
421-
if m.source == self._name:
431+
if isinstance(m, ToolCallMessage | ToolCallResultMessage):
432+
# Ignore tool call messages.
433+
continue
434+
elif isinstance(m, StopMessage | HandoffMessage):
435+
context.append(UserMessage(content=m.content, source=m.source))
436+
elif m.source == self._name:
422437
assert isinstance(m, TextMessage)
423438
context.append(AssistantMessage(content=m.content, source=m.source))
424439
else:

python/packages/autogen-studio/autogenstudio/database/component_factory.py

+24-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import yaml
99
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
1010
from autogen_agentchat.conditions import MaxMessageTermination, StopMessageTermination, TextMentionTermination
11-
from autogen_agentchat.teams import RoundRobinGroupChat, SelectorGroupChat
11+
from autogen_agentchat.teams import RoundRobinGroupChat, SelectorGroupChat, MagenticOneGroupChat
1212
from autogen_core.components.tools import FunctionTool
1313
from autogen_ext.agents.web_surfer import MultimodalWebSurfer
14+
from autogen_ext.agents.file_surfer import FileSurfer
15+
from autogen_ext.agents.magentic_one import MagenticOneCoderAgent
1416
from autogen_ext.models import OpenAIChatCompletionClient
1517

1618
from ..datamodel.types import (
@@ -32,8 +34,8 @@
3234

3335
logger = logging.getLogger(__name__)
3436

35-
TeamComponent = Union[RoundRobinGroupChat, SelectorGroupChat]
36-
AgentComponent = Union[AssistantAgent, MultimodalWebSurfer]
37+
TeamComponent = Union[RoundRobinGroupChat, SelectorGroupChat, MagenticOneGroupChat]
38+
AgentComponent = Union[AssistantAgent, MultimodalWebSurfer, UserProxyAgent, FileSurfer, MagenticOneCoderAgent]
3739
ModelComponent = Union[OpenAIChatCompletionClient]
3840
ToolComponent = Union[FunctionTool] # Will grow with more tool types
3941
TerminationComponent = Union[MaxMessageTermination, StopMessageTermination, TextMentionTermination]
@@ -243,6 +245,15 @@ async def load_team(self, config: TeamConfig, input_func: Optional[Callable] = N
243245
termination_condition=termination,
244246
selector_prompt=selector_prompt,
245247
)
248+
elif config.team_type == TeamTypes.MAGENTIC_ONE:
249+
if not model_client:
250+
raise ValueError("MagenticOneGroupChat requires a model_client")
251+
return MagenticOneGroupChat(
252+
participants=participants,
253+
model_client=model_client,
254+
termination_condition=termination if termination is not None else None,
255+
max_turns=config.max_turns if config.max_turns is not None else 20,
256+
)
246257
else:
247258
raise ValueError(f"Unsupported team type: {config.team_type}")
248259

@@ -292,7 +303,16 @@ async def load_agent(self, config: AgentConfig, input_func: Optional[Callable] =
292303
use_ocr=config.use_ocr if config.use_ocr is not None else False,
293304
animate_actions=config.animate_actions if config.animate_actions is not None else False,
294305
)
295-
306+
elif config.agent_type == AgentTypes.FILE_SURFER:
307+
return FileSurfer(
308+
name=config.name,
309+
model_client=model_client,
310+
)
311+
elif config.agent_type == AgentTypes.MAGENTIC_ONE_CODER:
312+
return MagenticOneCoderAgent(
313+
name=config.name,
314+
model_client=model_client,
315+
)
296316
else:
297317
raise ValueError(f"Unsupported agent type: {config.agent_type}")
298318

python/packages/autogen-studio/autogenstudio/datamodel/types.py

+4
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ class AgentTypes(str, Enum):
1919
ASSISTANT = "AssistantAgent"
2020
USERPROXY = "UserProxyAgent"
2121
MULTIMODAL_WEBSURFER = "MultimodalWebSurfer"
22+
FILE_SURFER = "FileSurfer"
23+
MAGENTIC_ONE_CODER = "MagenticOneCoderAgent"
2224

2325

2426
class TeamTypes(str, Enum):
2527
ROUND_ROBIN = "RoundRobinGroupChat"
2628
SELECTOR = "SelectorGroupChat"
29+
MAGENTIC_ONE = "MagenticOneGroupChat"
2730

2831

2932
class TerminationTypes(str, Enum):
@@ -103,6 +106,7 @@ class TeamConfig(BaseConfig):
103106
selector_prompt: Optional[str] = None
104107
termination_condition: Optional[TerminationConfig] = None
105108
component_type: ComponentTypes = ComponentTypes.TEAM
109+
max_turns: Optional[int] = None
106110

107111

108112
class TeamResult(BaseModel):

python/packages/autogen-studio/autogenstudio/web/managers/connection.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,15 @@ async def start_stream(self, run_id: UUID, task: str, team_config: dict) -> None
9292
await self._send_message(run_id, formatted_message)
9393

9494
# Save message if it's a content message
95-
if isinstance(message, (AgentMessage, ChatMessage)):
95+
if isinstance(message, TextMessage):
96+
await self._save_message(run_id, message)
97+
elif isinstance(message, MultiModalMessage):
9698
await self._save_message(run_id, message)
9799
# Capture final result if it's a TeamResult
98100
elif isinstance(message, TeamResult):
99101
final_result = message.model_dump()
100-
102+
elif isinstance(message, (AgentMessage, ChatMessage)):
103+
await self._save_message(run_id, message)
101104
if not cancellation_token.is_cancelled() and run_id not in self._closed_connections:
102105
if final_result:
103106
await self._update_run(run_id, RunStatus.COMPLETE, team_result=final_result)
@@ -285,6 +288,7 @@ def _format_message(self, message: Any) -> Optional[dict]:
285288
Returns:
286289
Optional[dict]: Formatted message or None if formatting fails
287290
"""
291+
288292
try:
289293
if isinstance(message, MultiModalMessage):
290294
message_dump = message.model_dump()
@@ -296,7 +300,8 @@ def _format_message(self, message: Any) -> Optional[dict]:
296300
},
297301
]
298302
return {"type": "message", "data": message_dump}
299-
elif isinstance(message, (AgentMessage, ChatMessage)):
303+
304+
elif isinstance(message, TextMessage):
300305
return {"type": "message", "data": message.model_dump()}
301306

302307
elif isinstance(message, TeamResult):
@@ -305,6 +310,9 @@ def _format_message(self, message: Any) -> Optional[dict]:
305310
"data": message.model_dump(),
306311
"status": "complete",
307312
}
313+
elif isinstance(message, (AgentMessage, ChatMessage)):
314+
return {"type": "message", "data": message.model_dump()}
315+
308316
return None
309317
except Exception as e:
310318
logger.error(f"Message formatting error: {e}")

python/packages/autogen-studio/frontend/src/components/types/datamodel.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,11 @@ export type ModelTypes = "OpenAIChatCompletionClient";
114114
export type AgentTypes =
115115
| "AssistantAgent"
116116
| "CodingAssistantAgent"
117-
| "MultimodalWebSurfer";
117+
| "MultimodalWebSurfer"
118+
| "FileSurfer"
119+
| "MagenticOneCoderAgent";
118120

119-
export type TeamTypes = "RoundRobinGroupChat" | "SelectorGroupChat";
121+
export type TeamTypes = "RoundRobinGroupChat" | "SelectorGroupChat" | "MagenticOneGroupChat";
120122

121123
// class ComponentType(str, Enum):
122124
// TEAM = "team"

python/packages/autogen-studio/frontend/src/components/views/shared/team/editor.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export const TeamEditor: React.FC<TeamEditorProps> = ({
8585
throw new Error("Participants must be an array");
8686
}
8787
if (
88-
!["RoundRobinGroupChat", "SelectorGroupChat"].includes(parsed.team_type)
88+
!["RoundRobinGroupChat", "SelectorGroupChat", "MagenticOneGroupChat"].includes(parsed.team_type)
8989
) {
9090
throw new Error("Invalid team_type");
9191
}
@@ -169,7 +169,7 @@ export const TeamEditor: React.FC<TeamEditorProps> = ({
169169
>
170170
<div className="mb-2 text-xs text-gray-500">
171171
Required fields: name (string), team_type ("RoundRobinGroupChat" |
172-
"SelectorGroupChat"), participants (array)
172+
"SelectorGroupChat" | "MagenticOneGroupChat"), participants (array)
173173
</div>
174174

175175
<div className="h-[500px] mb-4">

0 commit comments

Comments
 (0)