xgae 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of xgae might be problematic. Click here for more details.

Files changed (59) hide show
  1. {xgae-0.3.2 → xgae-0.3.3}/CHANGELOG.md +6 -0
  2. {xgae-0.3.2 → xgae-0.3.3}/PKG-INFO +2 -2
  3. {xgae-0.3.2 → xgae-0.3.3}/README.md +1 -1
  4. xgae-0.3.3/examples/agent/are/example_mcp_apps.json +11 -0
  5. xgae-0.3.3/examples/agent/are/simulation/agents/xga/README.md +44 -0
  6. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/are/simulation/agents/xga/env.example +1 -0
  7. xgae-0.3.3/examples/agent/are/simulation/agents/xga/mcp_tool_executor.py +133 -0
  8. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/are/simulation/agents/xga/xga_agent.py +4 -3
  9. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/are/simulation/agents/xga/xga_tool_box.py +2 -1
  10. xgae-0.3.3/examples/agent/are/simulation/scenarios/scenario_bomc_fault/scenario.py +184 -0
  11. {xgae-0.3.2 → xgae-0.3.3}/pyproject.toml +1 -1
  12. {xgae-0.3.2 → xgae-0.3.3}/uv.lock +1 -1
  13. xgae-0.3.2/examples/agent/are/simulation/agents/xga/README.md +0 -30
  14. {xgae-0.3.2 → xgae-0.3.3}/.env +0 -0
  15. {xgae-0.3.2 → xgae-0.3.3}/.python-version +0 -0
  16. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/are/simulation/agents/xga/xga_agent_factory.py +0 -0
  17. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/langgraph/reflection/agent_base.py +0 -0
  18. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/langgraph/reflection/custom_prompt_rag.py +0 -0
  19. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/langgraph/reflection/reflection_agent.py +0 -0
  20. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/langgraph/reflection/result_eval_agent.py +0 -0
  21. {xgae-0.3.2 → xgae-0.3.3}/examples/agent/langgraph/reflection/run_agent_app.py +0 -0
  22. {xgae-0.3.2 → xgae-0.3.3}/examples/engine/run_custom_and_agent_tools.py +0 -0
  23. {xgae-0.3.2 → xgae-0.3.3}/examples/engine/run_general_tools.py +0 -0
  24. {xgae-0.3.2 → xgae-0.3.3}/examples/engine/run_human_in_loop.py +0 -0
  25. {xgae-0.3.2 → xgae-0.3.3}/examples/engine/run_simple.py +0 -0
  26. {xgae-0.3.2 → xgae-0.3.3}/examples/tools/custom_fault_tools_app.py +0 -0
  27. {xgae-0.3.2 → xgae-0.3.3}/examples/tools/simu_a2a_tools_app.py +0 -0
  28. {xgae-0.3.2 → xgae-0.3.3}/mcpservers/custom_servers.json +0 -0
  29. {xgae-0.3.2 → xgae-0.3.3}/mcpservers/xga_server.json +0 -0
  30. {xgae-0.3.2 → xgae-0.3.3}/mcpservers/xga_server_sse.json +0 -0
  31. {xgae-0.3.2 → xgae-0.3.3}/templates/agent_tool_prompt_template.txt +0 -0
  32. {xgae-0.3.2 → xgae-0.3.3}/templates/custom_tool_prompt_template.txt +0 -0
  33. {xgae-0.3.2 → xgae-0.3.3}/templates/example/fault_user_prompt.txt +0 -0
  34. {xgae-0.3.2 → xgae-0.3.3}/templates/example/result_eval_template.txt +0 -0
  35. {xgae-0.3.2 → xgae-0.3.3}/templates/gemini_system_prompt_template.txt +0 -0
  36. {xgae-0.3.2 → xgae-0.3.3}/templates/general_tool_prompt_template.txt +0 -0
  37. {xgae-0.3.2 → xgae-0.3.3}/templates/system_prompt_response_sample.txt +0 -0
  38. {xgae-0.3.2 → xgae-0.3.3}/templates/system_prompt_template.txt +0 -0
  39. {xgae-0.3.2 → xgae-0.3.3}/test/test_chroma.py +0 -0
  40. {xgae-0.3.2 → xgae-0.3.3}/test/test_langfuse.py +0 -0
  41. {xgae-0.3.2 → xgae-0.3.3}/test/test_litellm_langfuse.py +0 -0
  42. {xgae-0.3.2 → xgae-0.3.3}/xgae/__init__.py +0 -0
  43. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/engine_base.py +0 -0
  44. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/mcp_tool_box.py +0 -0
  45. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/prompt_builder.py +0 -0
  46. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/responser/non_stream_responser.py +0 -0
  47. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/responser/responser_base.py +0 -0
  48. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/responser/stream_responser.py +0 -0
  49. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/task_engine.py +0 -0
  50. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine/task_langfuse.py +0 -0
  51. {xgae-0.3.2 → xgae-0.3.3}/xgae/engine_cli_app.py +0 -0
  52. {xgae-0.3.2 → xgae-0.3.3}/xgae/gaia2/are_engine.py +0 -0
  53. {xgae-0.3.2 → xgae-0.3.3}/xgae/tools/without_general_tools_app.py +0 -0
  54. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/__init__.py +0 -0
  55. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/json_helpers.py +0 -0
  56. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/llm_client.py +0 -0
  57. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/misc.py +0 -0
  58. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/setup_env.py +0 -0
  59. {xgae-0.3.2 → xgae-0.3.3}/xgae/utils/xml_tool_parser.py +0 -0
@@ -1,3 +1,9 @@
1
+ ## [0.3.3] - 2025-10-30
2
+ ### Added
3
+ - GAIA2 ARE Scenario: scenario_bomc_fault
4
+ - GAIA2 ARE MCP: Support Custom MCP Apps, example_mcp_apps.json
5
+
6
+
1
7
  ## [0.3.2] - 2025-10-24
2
8
  ### Added
3
9
  - GAIA2 ARE Example: XGAAreAgent, XGAAreToolBox
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xgae
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Extreme General Agent Engine
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: colorlog>=6.9.0
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
19
19
  - Support Custom prompt and external MCP Tools
20
20
  - Support Langfuse
21
21
  - Support Langgraph
22
- - Support GAIA2 ARE agent
22
+ - Support GAIA2 ARE agent and Custom MCP Apps
23
23
  - Support Human-in-Loop in agent
24
24
  - Can Use A2A protocol call A2A Agent as tool by 'xgaproxy' project
25
25
  - Can Use E2B or Daytona Sandbox of 'xgatools' project
@@ -3,7 +3,7 @@
3
3
  - Support Custom prompt and external MCP Tools
4
4
  - Support Langfuse
5
5
  - Support Langgraph
6
- - Support GAIA2 ARE agent
6
+ - Support GAIA2 ARE agent and Custom MCP Apps
7
7
  - Support Human-in-Loop in agent
8
8
  - Can Use A2A protocol call A2A Agent as tool by 'xgaproxy' project
9
9
  - Can Use E2B or Daytona Sandbox of 'xgatools' project
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "BomcFault": {
4
+ "type": "sse",
5
+ "url": "http://localhost:17070/sse",
6
+ "headers": {
7
+ "Authorization": "Bearer YOURLONGLIVEDTOKENS"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,44 @@
1
+ ## GAIA2 ARE Support
2
+ ### How to add XGAE to ARE Project
3
+ - add xgae==0.3.2 to ARE requirements.txt
4
+ - uv pip install -r requirements.txt
5
+ - modify ARE 'AgentBuilder' and 'AgentConfigBuilder' class, add "xga" type agent :
6
+ ```
7
+ File: agent_builder.py
8
+ class AgentBuilder:
9
+ def list_agents(self) -> list[str]:
10
+ return ["default", "xga"]
11
+
12
+ def build():
13
+ ...
14
+ agent_name = agent_config.get_agent_name()
15
+ if agent_name in ["default", "xga"]:
16
+ # add xga agent code
17
+
18
+ File: agent_config_builder.py
19
+ class AgentConfigBuilder:
20
+ def build():
21
+ if agent_name in["default", "xga"]:
22
+ ```
23
+ - modify ARE 'MCPApp' :
24
+ ```
25
+ File: mcp_app.py
26
+ class MCPApp:
27
+ def _call_tool(self, tool_name: str, **kwargs) -> str:
28
+ try:
29
+ ...
30
+ from are.simulation.agents.xga.mcp_tool_executor import call_mcp_tool
31
+ result = call_mcp_tool(self.server_url, tool_name, kwargs, 10)
32
+ return str(result)
33
+
34
+
35
+ ```
36
+
37
+
38
+ - modify ARE .env, add XGAE .env config, refer to env.example
39
+ - copy XGAE package 'mcpservers' and 'templates' directory to ARE project root
40
+
41
+ ### Run XGA Agent in ARE
42
+ ```
43
+ uv run are-run -e -s scenario_find_image_file -a xga --model openai/qwen3-235b-a22b --provider llama-api --output_dir ./output
44
+ ```
@@ -22,6 +22,7 @@ ALL_MODELS=""
22
22
 
23
23
  DEMO_FS_PATH="hf://datasets/meta-agents-research-environments/gaia2_filesystem/demo_filesystem"
24
24
 
25
+ MCP_APPS_JSON_PATH=/Users/sharkystar/DevProjects/are/mcpservers/example_mcp_apps.json
25
26
 
26
27
  ### XGA ENV ###
27
28
  # LOG
@@ -0,0 +1,133 @@
1
+ import asyncio
2
+ import json
3
+ import threading
4
+ import time
5
+
6
+ from concurrent.futures import Future as ConcurrentFuture
7
+ from typing import Any, Optional, Coroutine, List, Dict
8
+
9
+ from mcp.client.session import ClientSession
10
+ from mcp.client.sse import sse_client
11
+
12
+ from xgae.engine.engine_base import XGAToolResult
13
+
14
+
15
+ class AsyncToolExecutor:
16
+ _instance = None
17
+ _loop = None
18
+ _thread = None
19
+ _lock = threading.Lock()
20
+
21
+ def __new__(cls):
22
+ with cls._lock:
23
+ if cls._instance is None:
24
+ cls._instance = super().__new__(cls)
25
+ cls._init_event_loop()
26
+ return cls._instance
27
+
28
+
29
+ @classmethod
30
+ def _init_event_loop(cls):
31
+ if cls._loop is None or cls._loop.is_closed():
32
+ cls._loop = asyncio.new_event_loop()
33
+
34
+ def start_loop(loop):
35
+ asyncio.set_event_loop(loop)
36
+ try:
37
+ loop.run_forever()
38
+ finally:
39
+ if not loop.is_closed():
40
+ loop.close()
41
+
42
+ cls._thread = threading.Thread(target=start_loop, args=(cls._loop,), daemon=True)
43
+ cls._thread.start()
44
+
45
+ time.sleep(0.1)
46
+
47
+ @classmethod
48
+ def submit(cls, coro: Coroutine) -> ConcurrentFuture:
49
+ if cls._loop is None or cls._loop.is_closed():
50
+ cls._init_event_loop()
51
+
52
+ return asyncio.run_coroutine_threadsafe(coro, cls._loop)
53
+
54
+ @classmethod
55
+ def run_and_wait(cls, coro: Coroutine, timeout: Optional[float] = None) -> Any:
56
+ future = cls.submit(coro)
57
+ return future.result(timeout=timeout)
58
+
59
+ @classmethod
60
+ def get_loop(cls):
61
+ if cls._loop is None or cls._loop.is_closed():
62
+ cls._init_event_loop()
63
+ return cls._loop
64
+
65
+ @classmethod
66
+ def shutdown(cls):
67
+ if cls._loop is not None and not cls._loop.is_closed():
68
+ cls._loop.call_soon_threadsafe(cls._loop.stop)
69
+
70
+ from mcp.types import CallToolResult
71
+
72
+ async def _mcp_sse_tool_call(url: str, tool_name: str, arguments: dict[str, Any]) -> CallToolResult:
73
+ async with sse_client(url, sse_read_timeout=5) as streams:
74
+ async with ClientSession(*streams) as session:
75
+ await session.initialize()
76
+ return await session.call_tool(tool_name, arguments)
77
+
78
+
79
+ def call_mcp_tool(url: str, tool_name: str, arguments: dict[str, Any], timeout: Optional[float] = None) -> Any:
80
+ future = AsyncToolExecutor.submit(_mcp_sse_tool_call(url, tool_name, arguments))
81
+ mcp_result:CallToolResult = future.result(timeout=timeout)
82
+ result = {
83
+ 'success': not mcp_result.isError,
84
+ }
85
+ if mcp_result.isError:
86
+ result['output'] = mcp_result.content[0].text
87
+ else:
88
+ result['output'] = mcp_result.structuredContent['result']
89
+
90
+ return json.dumps(result)
91
+
92
+
93
+ def convert_mcp_tool_result(org_result: str)->XGAToolResult:
94
+ result = XGAToolResult(success=True, output=str(org_result))
95
+
96
+ if org_result and isinstance(org_result, str):
97
+ try:
98
+ _result:dict = json.loads(org_result)
99
+ output = _result.get('output', None)
100
+ success = _result.get('success', None)
101
+
102
+ if success and output:
103
+ result = XGAToolResult(success=bool(success), output=str(output))
104
+ except:
105
+ pass
106
+
107
+ return result
108
+
109
+
110
+ if __name__ == "__main__":
111
+ async def sample_task(name, duration):
112
+ print(f"Task '{name}' Begin,time = {duration} ")
113
+ await asyncio.sleep(duration)
114
+ return f"Task '{name}' Finished"
115
+
116
+ async def main():
117
+ try:
118
+ # result = AsyncToolExecutor.run_and_wait(sample_task("mytool", 1))
119
+ # print(f"Result1: {result}")
120
+
121
+ result = call_mcp_tool("http://localhost:17070/sse", "get_alarm", {"ip":"13.0.0.13"})
122
+ result = convert_mcp_tool_result(result)
123
+ print(f"Result2: {result}")
124
+
125
+ result = call_mcp_tool("http://localhost:17070/sse", "get_alarm1", {"ip":"13.0.0.13"})
126
+ result = convert_mcp_tool_result(result)
127
+ print(f"Result3: {result}")
128
+
129
+ except Exception as e:
130
+ print(f"Thread Fail: {e}")
131
+
132
+ with asyncio.Runner() as runner:
133
+ runner.run(main())
@@ -1,4 +1,5 @@
1
1
  import re
2
+ import asyncio
2
3
  from typing import List, Dict, Any
3
4
  from typing_extensions import override
4
5
 
@@ -23,7 +24,7 @@ from are.simulation.agents.default_agent.base_agent import (
23
24
 
24
25
  from xgae.utils.llm_client import LLMConfig
25
26
  from xgae.gaia2.are_engine import ARETaskEngine
26
- from agent.are.simulation.agents.xga.xga_tool_box import XGAAreToolBox
27
+ from are.simulation.agents.xga.xga_tool_box import XGAAreToolBox
27
28
 
28
29
 
29
30
  def pre_run_task_check(agent, iterations: int, llm_messages: List[Dict[str, Any]]):
@@ -205,8 +206,8 @@ class XGAAreAgent(BaseAgent):
205
206
 
206
207
  @override
207
208
  def execute_agent_loop(self) -> str | None | MMObservation:
208
- import asyncio
209
- asyncio.run(self.async_execute_agent_loop())
209
+ with asyncio.Runner() as runner:
210
+ runner.run(self.async_execute_agent_loop())
210
211
 
211
212
  # We have reached a termination condition, execute the termination method
212
213
  if self.termination_step.function is not None and not self.stop_event.is_set():
@@ -10,6 +10,7 @@ from xgae.engine.engine_base import XGAError, XGAToolSchema, XGAToolResult, XGAT
10
10
  from xgae.engine.mcp_tool_box import XGAMcpToolBox
11
11
 
12
12
  from are.simulation.tools import Tool
13
+ from are.simulation.agents.xga.mcp_tool_executor import convert_mcp_tool_result
13
14
 
14
15
  class XGAAreToolBox(XGAMcpToolBox):
15
16
  def __init__(self, are_tools: Dict[str, Tool]):
@@ -41,7 +42,7 @@ class XGAAreToolBox(XGAMcpToolBox):
41
42
 
42
43
  try:
43
44
  tool_result = self.are_tools[full_tool_name](**args)
44
- result = XGAToolResult(success=True, output=str(tool_result))
45
+ result = convert_mcp_tool_result(str(tool_result))
45
46
  except Exception as e:
46
47
  error = f"Call ARE Tool '{tool_name}' error: {str(e)}"
47
48
  logging.error(f"AreToolBox call_are_tool: {error}")
@@ -0,0 +1,184 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+
8
+ import datetime
9
+ import json
10
+ import logging
11
+ import os
12
+ from typing import Any
13
+
14
+ from dotenv import load_dotenv
15
+ from are.simulation.apps.agent_user_interface import AgentUserInterface
16
+ from are.simulation.apps.mcp.mcp_app import MCPApp
17
+ from are.simulation.scenarios.scenario import Scenario, ScenarioValidationResult
18
+ from are.simulation.scenarios.utils.env_utils import expand_env_vars
19
+
20
+ from are.simulation.scenarios.utils.registry import register_scenario
21
+ from are.simulation.types import EventRegisterer, event_registered
22
+
23
+ # Set up logger
24
+ logger = logging.getLogger(__name__)
25
+
26
+ # Load environment variables from .env file
27
+ load_dotenv()
28
+
29
+
30
+
31
+ @register_scenario("scenario_bomc_fault")
32
+ class ScenarioBomcFault(Scenario):
33
+ start_time: float | None = datetime.datetime.now().timestamp()
34
+ duration: float | None = None
35
+
36
+ def init_and_populate_apps(self, *args, **kwargs) -> None:
37
+
38
+ # get apps from the demo
39
+ agui = AgentUserInterface()
40
+ self.apps = [agui]
41
+
42
+ # form task from universe params
43
+ self.start_time = datetime.datetime.now().timestamp()
44
+
45
+ # Load additional MCP apps from JSON file if specified
46
+ self._load_mcp_apps_from_json()
47
+
48
+
49
+ def build_events_flow(self) -> None:
50
+ """Define the sequence of events that will occur during the scenario"""
51
+
52
+ agui = self.get_typed_app(AgentUserInterface)
53
+
54
+ with EventRegisterer.capture_mode():
55
+ # User event: User requests task creation
56
+ event1 = agui.send_message_to_agent(
57
+ content="locate 10.0.0.1 fault and solution",
58
+ ).depends_on(None, delay_seconds=2)
59
+
60
+ oracle1 = (
61
+ agui.send_message_to_user(
62
+ content="Fault Cause: Phone Recharge Application Crash; Solution: Restart Phone Recharge Application",
63
+ )
64
+ .oracle()
65
+ .depends_on(event1, delay_seconds=10)
66
+ )
67
+
68
+
69
+ self.events = [event1]
70
+
71
+
72
+ def validate(self, env) -> ScenarioValidationResult:
73
+ """
74
+ Validate that the scenario completed successfully.
75
+
76
+ Check that the agent properly interacted with our custom app.
77
+ """
78
+ try:
79
+ aui = env.get_app("AgentUserInterface")
80
+ msg = aui.get_last_message_from_agent()
81
+ content = msg.content
82
+ if "Phone Recharge Application Crash" in content:
83
+ return ScenarioValidationResult(success=True)
84
+ else:
85
+ return ScenarioValidationResult(success=False)
86
+ except Exception as e:
87
+ return ScenarioValidationResult(success=False, exception=e)
88
+
89
+
90
+ def _load_mcp_apps_from_json(self) -> None:
91
+ """
92
+ Load additional MCP apps from a JSON file specified in the environment variables.
93
+
94
+ The JSON file should follow the Claude MCP definition format with a ``mcpServers``
95
+ key containing server configurations. Environment variables in the JSON are
96
+ expanded using the current environment.
97
+
98
+ :return: None
99
+ """
100
+ # Get the JSON file path from environment variables
101
+ mcp_apps_json_path = os.environ.get("MCP_APPS_JSON_PATH")
102
+
103
+ if not mcp_apps_json_path:
104
+ return
105
+
106
+ # Ensure self.apps is initialized
107
+ if not hasattr(self, "apps") or self.apps is None:
108
+ self.apps = []
109
+
110
+ try:
111
+ with open(mcp_apps_json_path, "r") as f:
112
+ mcp_config = json.load(f)
113
+
114
+ if "mcpServers" not in mcp_config:
115
+ logger.warning(
116
+ f"No 'mcpServers' key found in MCP apps JSON file: {mcp_apps_json_path}"
117
+ )
118
+ return
119
+
120
+ # Create MCP apps from the JSON configuration
121
+ for server_name, server_config in mcp_config["mcpServers"].items():
122
+ mcp_app = self._create_mcp_app(server_name, server_config)
123
+ if mcp_app:
124
+ self.apps.append(mcp_app)
125
+ logger.info(f"Added MCP app: {server_name}")
126
+
127
+ except Exception as e:
128
+ logger.error(f"Error loading MCP apps from JSON: {e}", exc_info=True)
129
+
130
+ def _create_mcp_app(self, name: str, config: dict[str, Any]) -> MCPApp | None:
131
+ """
132
+ Create an MCPApp instance from a server configuration.
133
+
134
+ Supports two types of MCP servers:
135
+
136
+ 1. Local servers with command and arguments
137
+ 2. Remote SSE servers with URL and headers
138
+
139
+ Environment variables in the configuration are expanded before creating the app.
140
+
141
+ :param name: The name of the MCP app
142
+ :type name: str
143
+ :param config: The server configuration from the JSON file
144
+ :type config: dict[str, Any]
145
+ :return: An MCPApp instance or None if creation fails
146
+ :rtype: MCPApp | None
147
+ """
148
+ try:
149
+ # Expand environment variables in the configuration
150
+ expanded_config = expand_env_vars(config, allowed=["HF_TOKEN"])
151
+
152
+ # Handle SSE remote servers
153
+ if expanded_config.get("type") == "sse" or "url" in expanded_config:
154
+ return MCPApp(
155
+ name=name,
156
+ server_url=expanded_config.get("url"),
157
+ sse_headers=expanded_config.get("headers", {}),
158
+ )
159
+
160
+ # Handle local servers with command and args
161
+ elif "command" in expanded_config:
162
+ return MCPApp(
163
+ name=name,
164
+ server_command=expanded_config.get("command"),
165
+ server_args=expanded_config.get("args", []),
166
+ server_env=expanded_config.get("env", {}),
167
+ )
168
+
169
+ else:
170
+ logger.warning(f"Unsupported MCP server configuration for {name}")
171
+ return None
172
+
173
+ except Exception as e:
174
+ logger.error(f"Error creating MCP app {name}: {e}", exc_info=True)
175
+ return None
176
+
177
+
178
+ # Before Run Scenario, should xage project , execute command:
179
+ # 1. Vailid Success: uv run example-fault-tools
180
+ # 2. Vailid Fail: uv run example-fault-tools --alarmtype 2
181
+ if __name__ == "__main__":
182
+ from are.simulation.scenarios.utils.cli_utils import run_and_validate
183
+
184
+ run_and_validate(ScenarioBomcFault())
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xgae"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "Extreme General Agent Engine"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -3008,7 +3008,7 @@ wheels = [
3008
3008
 
3009
3009
  [[package]]
3010
3010
  name = "xgae"
3011
- version = "0.3.2"
3011
+ version = "0.3.3"
3012
3012
  source = { editable = "." }
3013
3013
  dependencies = [
3014
3014
  { name = "colorlog" },
@@ -1,30 +0,0 @@
1
- ## GAIA2 ARE Support
2
- ### How to add XGAE to ARE Project
3
- - add xgae==0.3.2 to ARE requirements.txt
4
- - uv pip install -r requirements.txt
5
- - modify ARE 'AgentBuilder' and 'AgentConfigBuilder' class, add "xga" type agent
6
- ```
7
- File: agent_builder.py
8
- class AgentBuilder:
9
- def list_agents(self) -> list[str]:
10
- return ["default", "xga"]
11
-
12
- def build():
13
- ...
14
- agent_name = agent_config.get_agent_name()
15
- if agent_name in ["default", "xga"]:
16
- # add xga agent code
17
-
18
- File: agent_config_builder.py
19
- class AgentConfigBuilder:
20
- def build():
21
- if agent_name in["default", "xga"]:
22
- ```
23
-
24
- - modify ARE .env, add XGAE .env config, refer to env.example
25
- - copy XGAE package 'mcpservers' and 'templates' directory to ARE project root
26
-
27
- ### Run XGA Agent in ARE
28
- ```
29
- uv run are-run -e -s scenario_find_image_file -a xga --model openai/qwen3-235b-a22b --provider llama-api --output_dir ./output
30
- ```
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes