xgae 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
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.
- xgae/engine/engine_base.py +5 -1
- xgae/engine/mcp_tool_box.py +22 -14
- xgae/engine/prompt_builder.py +3 -2
- xgae/engine/responser/non_stream_responser.py +2 -1
- xgae/engine/responser/stream_responser.py +3 -2
- xgae/engine/task_engine.py +7 -5
- xgae/gaia2/are_engine.py +4 -3
- xgae/utils/llm_client.py +3 -0
- xgae-0.3.2.dist-info/METADATA +36 -0
- xgae-0.3.2.dist-info/RECORD +22 -0
- xgae-0.3.0.dist-info/METADATA +0 -14
- xgae-0.3.0.dist-info/RECORD +0 -22
- {xgae-0.3.0.dist-info → xgae-0.3.2.dist-info}/WHEEL +0 -0
- {xgae-0.3.0.dist-info → xgae-0.3.2.dist-info}/entry_points.txt +0 -0
xgae/engine/engine_base.py
CHANGED
|
@@ -6,7 +6,7 @@ class XGAError(Exception):
|
|
|
6
6
|
"""Custom exception for errors in the XGA system."""
|
|
7
7
|
pass
|
|
8
8
|
|
|
9
|
-
XGAMsgStatusType = Literal["error", "finish", "tool_started", "tool_completed", "tool_error", "tool_failed"]
|
|
9
|
+
XGAMsgStatusType = Literal["error", "stop", "finish", "tool_started", "tool_completed", "tool_error", "tool_failed"]
|
|
10
10
|
XGAResponseMsgType = Literal["user", "status", "tool", "assistant", "assistant_chunk"]
|
|
11
11
|
|
|
12
12
|
class XGAResponseMessage(TypedDict, total=False):
|
|
@@ -40,6 +40,10 @@ class XGAToolResult:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
class XGAToolBox(ABC):
|
|
43
|
+
@abstractmethod
|
|
44
|
+
async def init_tool_schemas(self):
|
|
45
|
+
pass
|
|
46
|
+
|
|
43
47
|
@abstractmethod
|
|
44
48
|
async def creat_task_tool_box(self, task_id: str, general_tools: List[str], custom_tools: List[str]):
|
|
45
49
|
pass
|
xgae/engine/mcp_tool_box.py
CHANGED
|
@@ -2,7 +2,8 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
from typing import List, Any, Dict, Optional, Literal
|
|
5
|
+
from typing import List, Any, Dict, Optional, Literal
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
8
|
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
8
9
|
from langchain_mcp_adapters.tools import load_mcp_tools
|
|
@@ -33,7 +34,11 @@ class XGAMcpToolBox(XGAToolBox):
|
|
|
33
34
|
self.mcp_tool_schemas: Dict[str, List[XGAToolSchema]] = {}
|
|
34
35
|
self.task_tool_schemas: Dict[str, Dict[str,XGAToolSchema]] = {}
|
|
35
36
|
|
|
36
|
-
self.
|
|
37
|
+
self._is_loaded_mcp_tool_schemas = False
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
async def init_tool_schemas(self):
|
|
41
|
+
await self._load_mcp_tools_schema()
|
|
37
42
|
|
|
38
43
|
@override
|
|
39
44
|
async def creat_task_tool_box(self, task_id: str, general_tools: List[str], custom_tools: List[str]):
|
|
@@ -139,8 +144,8 @@ class XGAMcpToolBox(XGAToolBox):
|
|
|
139
144
|
return result
|
|
140
145
|
|
|
141
146
|
|
|
142
|
-
async def
|
|
143
|
-
if not self.
|
|
147
|
+
async def _load_mcp_tools_schema(self)-> None:
|
|
148
|
+
if not self._is_loaded_mcp_tool_schemas:
|
|
144
149
|
for server_name in self.mcp_server_names:
|
|
145
150
|
self.mcp_tool_schemas[server_name] = []
|
|
146
151
|
try:
|
|
@@ -162,18 +167,21 @@ class XGAMcpToolBox(XGAToolBox):
|
|
|
162
167
|
param_properties.pop('title', None)
|
|
163
168
|
|
|
164
169
|
metadata = tool.metadata or {}
|
|
165
|
-
tool_schema = XGAToolSchema(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
tool_schema = XGAToolSchema(
|
|
171
|
+
tool_name = tool.name,
|
|
172
|
+
tool_type = tool_type,
|
|
173
|
+
server_name = server_name,
|
|
174
|
+
description = tool.description,
|
|
175
|
+
input_schema = input_schema,
|
|
176
|
+
metadata = metadata
|
|
177
|
+
)
|
|
171
178
|
self.mcp_tool_schemas[server_name].append(tool_schema)
|
|
172
|
-
|
|
179
|
+
|
|
180
|
+
self._is_loaded_mcp_tool_schemas = True
|
|
173
181
|
|
|
174
182
|
async def reload_mcp_tools_schema(self) -> None:
|
|
175
|
-
self.
|
|
176
|
-
await self.
|
|
183
|
+
self._is_loaded_mcp_tool_schemas = False
|
|
184
|
+
await self.init_tool_schemas()
|
|
177
185
|
|
|
178
186
|
|
|
179
187
|
def _load_mcp_servers_config(self, mcp_config_path: str) -> Dict[str, Any]:
|
|
@@ -219,7 +227,7 @@ if __name__ == "__main__":
|
|
|
219
227
|
#mcp_tool_box = XGAMcpToolBox()
|
|
220
228
|
|
|
221
229
|
task_id = "task1"
|
|
222
|
-
await mcp_tool_box.
|
|
230
|
+
await mcp_tool_box.init_tool_schemas()
|
|
223
231
|
await mcp_tool_box.creat_task_tool_box(task_id=task_id, general_tools=["*"], custom_tools=["*"])
|
|
224
232
|
tool_schemas = mcp_tool_box.get_task_tool_schemas(task_id, "general")
|
|
225
233
|
print("general_tools_schemas" + "*"*50)
|
xgae/engine/prompt_builder.py
CHANGED
|
@@ -83,9 +83,10 @@ class XGAPromptBuilder():
|
|
|
83
83
|
tool_info = ""
|
|
84
84
|
for tool_schema in tool_schemas:
|
|
85
85
|
description = tool_schema.description if tool_schema.description else 'No description available'
|
|
86
|
-
tool_info += f"-
|
|
86
|
+
tool_info += f"- {tool_schema.tool_name}: {description}\n"
|
|
87
87
|
parameters = tool_schema.input_schema.get('properties', {})
|
|
88
|
-
tool_info += f"
|
|
88
|
+
tool_info += f" Parameters: {parameters}\n"
|
|
89
|
+
tool_info += "\n"
|
|
89
90
|
tool_prompt = tool_prompt.replace("{tool_schemas}", tool_info)
|
|
90
91
|
|
|
91
92
|
return tool_prompt
|
xgae/engine/task_engine.py
CHANGED
|
@@ -116,8 +116,7 @@ class XGATaskEngine:
|
|
|
116
116
|
general_tools.append("ask")
|
|
117
117
|
|
|
118
118
|
custom_tools = self.custom_tools or []
|
|
119
|
-
|
|
120
|
-
await self.tool_box.load_mcp_tools_schema()
|
|
119
|
+
await self.tool_box.init_tool_schemas()
|
|
121
120
|
|
|
122
121
|
await self.tool_box.creat_task_tool_box(self.task_id, general_tools, custom_tools)
|
|
123
122
|
general_tool_schemas = self.tool_box.get_task_tool_schemas(self.task_id, "general")
|
|
@@ -201,6 +200,9 @@ class XGATaskEngine:
|
|
|
201
200
|
yield error_msg
|
|
202
201
|
finally:
|
|
203
202
|
if not self.running_task_checkpoint("termination_check", iterations):
|
|
203
|
+
status_content = {'status_type': "stop", 'role': "system", 'message': "Task is termiated by Stop Command"}
|
|
204
|
+
error_msg = self.add_response_message(type="status", content=status_content, is_llm_message=False)
|
|
205
|
+
yield error_msg
|
|
204
206
|
break
|
|
205
207
|
|
|
206
208
|
async def _run_task_once(self, continuous_state: TaskRunContinuousState) -> AsyncGenerator[Dict[str, Any], None]:
|
|
@@ -239,8 +241,8 @@ class XGATaskEngine:
|
|
|
239
241
|
reverse_chunks = reversed(chunks)
|
|
240
242
|
chunk = None
|
|
241
243
|
|
|
242
|
-
if self.terminate_task:
|
|
243
|
-
|
|
244
|
+
# if self.terminate_task:
|
|
245
|
+
# return XGATaskResult(type="error", content="LLM Task is terminated !")
|
|
244
246
|
|
|
245
247
|
try:
|
|
246
248
|
finish_reason = ''
|
|
@@ -249,7 +251,7 @@ class XGATaskEngine:
|
|
|
249
251
|
if chunk_type == "status":
|
|
250
252
|
status_content = chunk['content']
|
|
251
253
|
status_type = status_content['status_type']
|
|
252
|
-
if status_type == "error":
|
|
254
|
+
if status_type == "error" or status_type == "stop":
|
|
253
255
|
error = status_content['message']
|
|
254
256
|
final_result = XGATaskResult(type="error", content=error)
|
|
255
257
|
elif status_type == "finish":
|
xgae/gaia2/are_engine.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any, Optional,
|
|
2
|
+
from typing import Any, Optional, Callable, Literal, Dict, List
|
|
3
|
+
from typing_extensions import override
|
|
3
4
|
|
|
4
5
|
from xgae.engine.engine_base import XGAToolBox
|
|
5
6
|
from xgae.engine.task_engine import XGATaskEngine
|
|
@@ -81,12 +82,12 @@ if __name__ == "__main__":
|
|
|
81
82
|
|
|
82
83
|
def terminate_task(agent, iterations: int) -> bool:
|
|
83
84
|
logging.info(f"terminate_task: iterations={iterations}")
|
|
84
|
-
return iterations >
|
|
85
|
+
return iterations > 3 # can test terminate by > 3
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
async def main():
|
|
88
89
|
# Before Run Exec: uv run example-fault-tools
|
|
89
|
-
# LLAMA_API_KEY ,
|
|
90
|
+
# LLAMA_API_KEY , LLAMA_API_BASE
|
|
90
91
|
tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
|
|
91
92
|
system_prompt = read_file("templates/example/fault_user_prompt.txt")
|
|
92
93
|
llm_config = LLMConfig(
|
xgae/utils/llm_client.py
CHANGED
|
@@ -51,6 +51,9 @@ class LLMClient:
|
|
|
51
51
|
self._init_langfuse()
|
|
52
52
|
|
|
53
53
|
llm_config = llm_config or LLMConfig()
|
|
54
|
+
if llm_config.get('model') and llm_config.get('model_name') is None:
|
|
55
|
+
llm_config['model_name'] = llm_config.get('model')
|
|
56
|
+
|
|
54
57
|
self.max_retries = int(os.getenv('LLM_MAX_RETRIES', 1))
|
|
55
58
|
|
|
56
59
|
env_llm_model = os.getenv('LLM_MODEL', "openai/qwen3-235b-a22b")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xgae
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Extreme General Agent Engine
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: colorlog>=6.9.0
|
|
7
|
+
Requires-Dist: langchain-mcp-adapters>=0.1.9
|
|
8
|
+
Requires-Dist: langfuse==2.60.9
|
|
9
|
+
Requires-Dist: litellm>=1.71.1
|
|
10
|
+
Requires-Dist: mcp>=1.11.0
|
|
11
|
+
Provides-Extra: examples
|
|
12
|
+
Requires-Dist: chromadb==1.1.0; extra == 'examples'
|
|
13
|
+
Requires-Dist: langchain-community==0.3.29; extra == 'examples'
|
|
14
|
+
Requires-Dist: langgraph==0.6.5; extra == 'examples'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
## XGAE: Extreme General Agent Engine
|
|
18
|
+
### Functional Features
|
|
19
|
+
- Support Custom prompt and external MCP Tools
|
|
20
|
+
- Support Langfuse
|
|
21
|
+
- Support Langgraph
|
|
22
|
+
- Support GAIA2 ARE agent
|
|
23
|
+
- Support Human-in-Loop in agent
|
|
24
|
+
- Can Use A2A protocol call A2A Agent as tool by 'xgaproxy' project
|
|
25
|
+
- Can Use E2B or Daytona Sandbox of 'xgatools' project
|
|
26
|
+
|
|
27
|
+
### Non-Functional Features
|
|
28
|
+
- Faster than SUNA Engine's speed
|
|
29
|
+
- Architecture is lighter than SUNA Engine
|
|
30
|
+
- Separate tools from Agent Engine
|
|
31
|
+
|
|
32
|
+
### Examples
|
|
33
|
+
- langgraph: Build React mode Langgraph Agent by XGA Engine
|
|
34
|
+
- are: Build GAIA2 ARE Agent by XGA Engine
|
|
35
|
+
- engine: Use XGA Engine in various scenarios
|
|
36
|
+
- tools: Simulation tools for example and test
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
xgae/__init__.py,sha256=oBX_YzTliM-343BAlR-sD7BUZmsCJ7PY2oYrGBhsdLM,79
|
|
2
|
+
xgae/engine_cli_app.py,sha256=FdmIpq8KDsgyZNfwCDgNX7FEZFeRFyGOt_H1oZF8aKs,2890
|
|
3
|
+
xgae/engine/engine_base.py,sha256=bXwLxli7CK7JndAcOu-Rx4uTuy0pJDh_ZOGyhym76WY,1796
|
|
4
|
+
xgae/engine/mcp_tool_box.py,sha256=vIVF-tDEqAkMkjexqjUTlJwS5q11MNGeNtcog3ww-SE,11012
|
|
5
|
+
xgae/engine/prompt_builder.py,sha256=wA1R4Be7Plg3TRnRK2ZfoMR9DNCMFVNLx1BwmsSIOQI,5076
|
|
6
|
+
xgae/engine/task_engine.py,sha256=QhjTPQ_aREsT19QfT1nQwNLKUMwWdSgqlfjfCNq_dho,23470
|
|
7
|
+
xgae/engine/task_langfuse.py,sha256=ifkGrPBv2daLTKE-fCfEtOoI0n4Pd-lCwhyRRL0h308,2850
|
|
8
|
+
xgae/engine/responser/non_stream_responser.py,sha256=WFzrT0tHGVLi_AR1IrIPPvpQ94ne7slwbFyXaoTpCQc,5318
|
|
9
|
+
xgae/engine/responser/responser_base.py,sha256=jhl1Bdz1Fs3KofGEymThNXlQuCORFTTkTAR_U47krds,24403
|
|
10
|
+
xgae/engine/responser/stream_responser.py,sha256=5n7i2QnE_u7RP1bcJFky8sFPjYMjfYY9NcR5TeFxl9Y,7642
|
|
11
|
+
xgae/gaia2/are_engine.py,sha256=QPvyWEydeiOECQ7WfxjMIurQHD_ET7uWQCnXVCh_ZQk,5094
|
|
12
|
+
xgae/tools/without_general_tools_app.py,sha256=KqsdhxD3hvTpiygaGUVHysRFjvv_1A8zOwMKN1J0J0U,3821
|
|
13
|
+
xgae/utils/__init__.py,sha256=ElaGS-zdeZeu6is41u3Ny7lkvhg7BDSK-jMNg9j6K5A,499
|
|
14
|
+
xgae/utils/json_helpers.py,sha256=WD4G5U9Dh8N6J9O0L5wGyqj-NHi09kcXHGdLD_26nlc,3607
|
|
15
|
+
xgae/utils/llm_client.py,sha256=Mr5XUexGzNcbsqjn5Vfgin0Rm9jeR3cEPCIm79q46EM,15196
|
|
16
|
+
xgae/utils/misc.py,sha256=aMWOvJ9VW52q-L9Lkjl1hvXqLwpJAmyxA-Z8jzqFG0U,907
|
|
17
|
+
xgae/utils/setup_env.py,sha256=MqNG0c2QQBDFU1kI8frxr9kB5d08Mmi3QZ1OoorgIa0,2662
|
|
18
|
+
xgae/utils/xml_tool_parser.py,sha256=Mb0d8kBrfyAEvUwW1Nqir-3BgxZRr0ZX3WymQouuFSo,4859
|
|
19
|
+
xgae-0.3.2.dist-info/METADATA,sha256=fISH_3RDhy23BvVjZFzxrv3B71Jbo24sjO5xTqEu2cg,1193
|
|
20
|
+
xgae-0.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
21
|
+
xgae-0.3.2.dist-info/entry_points.txt,sha256=wmvgtMQbtzTbDPETS-tbQJD7jVlcs4hp0w6wOB0ooCc,229
|
|
22
|
+
xgae-0.3.2.dist-info/RECORD,,
|
xgae-0.3.0.dist-info/METADATA
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: xgae
|
|
3
|
-
Version: 0.3.0
|
|
4
|
-
Summary: Extreme General Agent Engine
|
|
5
|
-
Requires-Python: >=3.11
|
|
6
|
-
Requires-Dist: colorlog==6.9.0
|
|
7
|
-
Requires-Dist: langchain-mcp-adapters==0.1.9
|
|
8
|
-
Requires-Dist: langfuse==2.60.9
|
|
9
|
-
Requires-Dist: litellm==1.74.15
|
|
10
|
-
Requires-Dist: mcp==1.13.0
|
|
11
|
-
Provides-Extra: examples
|
|
12
|
-
Requires-Dist: chromadb==1.1.0; extra == 'examples'
|
|
13
|
-
Requires-Dist: langchain-community==0.3.29; extra == 'examples'
|
|
14
|
-
Requires-Dist: langgraph==0.6.5; extra == 'examples'
|
xgae-0.3.0.dist-info/RECORD
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
xgae/__init__.py,sha256=oBX_YzTliM-343BAlR-sD7BUZmsCJ7PY2oYrGBhsdLM,79
|
|
2
|
-
xgae/engine_cli_app.py,sha256=FdmIpq8KDsgyZNfwCDgNX7FEZFeRFyGOt_H1oZF8aKs,2890
|
|
3
|
-
xgae/engine/engine_base.py,sha256=RR1em2wHiM2jP-peHt77SKdHWjnYOjdIIzN93zT61cA,1715
|
|
4
|
-
xgae/engine/mcp_tool_box.py,sha256=G4hKIMguwg1cO4Us2NMfdloYim8kuikVyVTIPucJr7o,10903
|
|
5
|
-
xgae/engine/prompt_builder.py,sha256=6I5rjgvNJ27QJ8DDuBTplutoPZdGs9LYFv3TSgT7zmc,5045
|
|
6
|
-
xgae/engine/task_engine.py,sha256=1YgkcsX8LAAIIp1DsVbphwOVO9xA0FioABxzaRvers8,23223
|
|
7
|
-
xgae/engine/task_langfuse.py,sha256=ifkGrPBv2daLTKE-fCfEtOoI0n4Pd-lCwhyRRL0h308,2850
|
|
8
|
-
xgae/engine/responser/non_stream_responser.py,sha256=zEJjqCgZVe2B8gkHYRFU7tmBV834f7w2a4Ws25P1N-c,5289
|
|
9
|
-
xgae/engine/responser/responser_base.py,sha256=jhl1Bdz1Fs3KofGEymThNXlQuCORFTTkTAR_U47krds,24403
|
|
10
|
-
xgae/engine/responser/stream_responser.py,sha256=cv4UGcxj8OksEogW7DUGTCvSJabu-DF6GceFyUwaXI4,7627
|
|
11
|
-
xgae/gaia2/are_engine.py,sha256=GPs6c94CN8jJjmNNsE7XHxdskPJ31p4Ds9QCST7BiI4,5050
|
|
12
|
-
xgae/tools/without_general_tools_app.py,sha256=KqsdhxD3hvTpiygaGUVHysRFjvv_1A8zOwMKN1J0J0U,3821
|
|
13
|
-
xgae/utils/__init__.py,sha256=ElaGS-zdeZeu6is41u3Ny7lkvhg7BDSK-jMNg9j6K5A,499
|
|
14
|
-
xgae/utils/json_helpers.py,sha256=WD4G5U9Dh8N6J9O0L5wGyqj-NHi09kcXHGdLD_26nlc,3607
|
|
15
|
-
xgae/utils/llm_client.py,sha256=rqnu_NYXBC0hl4aozP5UOSyf0q-ONB5ywtnrXzA88OE,15055
|
|
16
|
-
xgae/utils/misc.py,sha256=aMWOvJ9VW52q-L9Lkjl1hvXqLwpJAmyxA-Z8jzqFG0U,907
|
|
17
|
-
xgae/utils/setup_env.py,sha256=MqNG0c2QQBDFU1kI8frxr9kB5d08Mmi3QZ1OoorgIa0,2662
|
|
18
|
-
xgae/utils/xml_tool_parser.py,sha256=Mb0d8kBrfyAEvUwW1Nqir-3BgxZRr0ZX3WymQouuFSo,4859
|
|
19
|
-
xgae-0.3.0.dist-info/METADATA,sha256=OAdIkEtp1xWqtU2MrOBRJfPyu7TLJk6m5EPYh9WYNdQ,471
|
|
20
|
-
xgae-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
21
|
-
xgae-0.3.0.dist-info/entry_points.txt,sha256=wmvgtMQbtzTbDPETS-tbQJD7jVlcs4hp0w6wOB0ooCc,229
|
|
22
|
-
xgae-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|