xgae 0.1.7__tar.gz → 0.1.9__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.
- {xgae-0.1.7 → xgae-0.1.9}/.env +2 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/workspace.xml +17 -6
- xgae-0.1.9/PKG-INFO +11 -0
- {xgae-0.1.7 → xgae-0.1.9}/pyproject.toml +8 -7
- {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_human_in_loop.py +15 -2
- {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_simple.py +5 -1
- {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_user_prompt.py +2 -0
- xgae-0.1.9/src/examples/tools/custom_fault_tools_app.py +104 -0
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/engine_base.py +2 -2
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/mcp_tool_box.py +7 -6
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/prompt_builder.py +1 -1
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/non_stream_responser.py +8 -7
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/responser_base.py +54 -56
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/stream_responser.py +24 -25
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/task_engine.py +64 -61
- xgae-0.1.9/src/xgae/engine/task_langfuse.py +63 -0
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/tools/without_general_tools_app.py +1 -1
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/__init__.py +7 -5
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/json_helpers.py +7 -13
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/llm_client.py +62 -39
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/misc.py +3 -1
- xgae-0.1.9/src/xgae/utils/setup_env.py +83 -0
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/xml_tool_parser.py +4 -80
- {xgae-0.1.7 → xgae-0.1.9}/templates/example_user_prompt.txt +2 -2
- xgae-0.1.9/test/test_langfuse.py +30 -0
- xgae-0.1.9/test/test_litellm_langfuse.py +58 -0
- {xgae-0.1.7 → xgae-0.1.9}/uv.lock +18 -127
- xgae-0.1.7/PKG-INFO +0 -11
- xgae-0.1.7/src/xgae/utils/setup_env.py +0 -80
- {xgae-0.1.7 → xgae-0.1.9}/.idea/.gitignore +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/inspectionProfiles/Project_Default.xml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/misc.xml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/modules.xml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/vcs.xml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.idea/xgae.iml +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/.python-version +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/README.md +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/mcpservers/custom_servers.json +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/mcpservers/xga_server.json +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/mcpservers/xga_server_sse.json +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/src/xgae/__init__.py +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/templates/custom_tool_prompt_template.txt +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/templates/gemini_system_prompt_template.txt +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/templates/general_tool_prompt_template.txt +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/templates/system_prompt_response_sample.txt +0 -0
- {xgae-0.1.7 → xgae-0.1.9}/templates/system_prompt_template.txt +0 -0
{xgae-0.1.7 → xgae-0.1.9}/.env
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# LOG
|
|
2
2
|
LOG_LEVEL=INFO
|
|
3
3
|
LOG_FILE=log/xgae.log
|
|
4
|
+
LOG_ENABLE=True
|
|
4
5
|
|
|
5
6
|
# LANGFUSE
|
|
6
7
|
LANGFUSE_PUBLIC_KEY=
|
|
@@ -9,6 +10,7 @@ LANGFUSE_HOST=https://cloud.langfuse.com
|
|
|
9
10
|
|
|
10
11
|
# LLM
|
|
11
12
|
LLM_MODEL=openai/qwen3-235b-a22b
|
|
13
|
+
#LLM_MODEL=openai/qwen-plus
|
|
12
14
|
LLM_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
13
15
|
LLM_API_KEY=
|
|
14
16
|
LLM_MAX_TOKENS=16384
|
|
@@ -29,15 +29,19 @@
|
|
|
29
29
|
"keyToString": {
|
|
30
30
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
|
31
31
|
"Python.llm_client.executor": "Run",
|
|
32
|
+
"Python.mcp_tool_box.executor": "Run",
|
|
32
33
|
"Python.message_tools_app.executor": "Run",
|
|
33
34
|
"Python.responser_base.executor": "Run",
|
|
34
35
|
"Python.run_engine_with_human_in_loop.executor": "Run",
|
|
36
|
+
"Python.run_human_in_loop.executor": "Run",
|
|
35
37
|
"Python.run_simple.executor": "Run",
|
|
36
38
|
"Python.run_task_engine.executor": "Run",
|
|
37
39
|
"Python.run_user_prompt.executor": "Run",
|
|
38
40
|
"Python.run_xga_engine.executor": "Run",
|
|
39
41
|
"Python.setup_env.executor": "Run",
|
|
40
42
|
"Python.task_engine.executor": "Run",
|
|
43
|
+
"Python.test_langfuse.executor": "Run",
|
|
44
|
+
"Python.test_litellm_langfuse.executor": "Run",
|
|
41
45
|
"Python.utils.executor": "Run",
|
|
42
46
|
"Python.xga_engine.executor": "Run",
|
|
43
47
|
"Python.xga_mcp_tool_box.executor": "Debug",
|
|
@@ -55,6 +59,7 @@
|
|
|
55
59
|
}]]></component>
|
|
56
60
|
<component name="RecentsManager">
|
|
57
61
|
<key name="MoveFile.RECENT_KEYS">
|
|
62
|
+
<recent name="$PROJECT_DIR$/src/examples/engine" />
|
|
58
63
|
<recent name="$PROJECT_DIR$/src/xgae/engine/responser" />
|
|
59
64
|
</key>
|
|
60
65
|
</component>
|
|
@@ -160,7 +165,8 @@
|
|
|
160
165
|
<workItem from="1755700523844" duration="24000" />
|
|
161
166
|
<workItem from="1755737435202" duration="48139000" />
|
|
162
167
|
<workItem from="1756044658912" duration="1248000" />
|
|
163
|
-
<workItem from="1756082326044" duration="
|
|
168
|
+
<workItem from="1756082326044" duration="23657000" />
|
|
169
|
+
<workItem from="1756168626188" duration="45746000" />
|
|
164
170
|
</task>
|
|
165
171
|
<servers />
|
|
166
172
|
</component>
|
|
@@ -179,18 +185,23 @@
|
|
|
179
185
|
</breakpoint-manager>
|
|
180
186
|
</component>
|
|
181
187
|
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
|
188
|
+
<SUITE FILE_PATH="coverage/xgae$test_litellm_langfuse.coverage" NAME="test_litellm_langfuse Coverage Results" MODIFIED="1756196476262" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
182
189
|
<SUITE FILE_PATH="coverage/xgae$xga_engine.coverage" NAME="xga_engine Coverage Results" MODIFIED="1755580277172" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
183
|
-
<SUITE FILE_PATH="coverage/xgae$run_simple.coverage" NAME="run_simple Coverage Results" MODIFIED="
|
|
190
|
+
<SUITE FILE_PATH="coverage/xgae$run_simple.coverage" NAME="run_simple Coverage Results" MODIFIED="1756280626870" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
191
|
+
<SUITE FILE_PATH="coverage/xgae$run_human_in_loop.coverage" NAME="run_human_in_loop Coverage Results" MODIFIED="1756279131815" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
184
192
|
<SUITE FILE_PATH="coverage/xgae$run_xga_engine.coverage" NAME="run_task_engine Coverage Results" MODIFIED="1756111613459" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
185
193
|
<SUITE FILE_PATH="coverage/xgae$message_tools_app.coverage" NAME="message_tools_app Coverage Results" MODIFIED="1756094157566" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
186
194
|
<SUITE FILE_PATH="coverage/xgae$run_engine_with_human_in_loop.coverage" NAME="run_engine_with_human_in_loop Coverage Results" MODIFIED="1756089269027" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
187
195
|
<SUITE FILE_PATH="coverage/xgae$xga_prompt_builder.coverage" NAME="xga_prompt_builder Coverage Results" MODIFIED="1755587456555" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
196
|
+
<SUITE FILE_PATH="coverage/xgae$test_langfuse.coverage" NAME="test_langfuse Coverage Results" MODIFIED="1756196410142" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
197
|
+
<SUITE FILE_PATH="coverage/xgae$run_task_engine.coverage" NAME="run_task_engine Coverage Results" MODIFIED="1756280748615" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
188
198
|
<SUITE FILE_PATH="coverage/xgae$responser_base.coverage" NAME="responser_base Coverage Results" MODIFIED="1756103040764" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
199
|
+
<SUITE FILE_PATH="coverage/xgae$mcp_tool_box.coverage" NAME="mcp_tool_box Coverage Results" MODIFIED="1756274403389" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
189
200
|
<SUITE FILE_PATH="coverage/xgae$utils.coverage" NAME="utils Coverage Results" MODIFIED="1755226923439" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
190
|
-
<SUITE FILE_PATH="coverage/xgae$setup_env.coverage" NAME="setup_env Coverage Results" MODIFIED="
|
|
191
|
-
<SUITE FILE_PATH="coverage/xgae$run_user_prompt.coverage" NAME="run_user_prompt Coverage Results" MODIFIED="
|
|
201
|
+
<SUITE FILE_PATH="coverage/xgae$setup_env.coverage" NAME="setup_env Coverage Results" MODIFIED="1756273791782" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
202
|
+
<SUITE FILE_PATH="coverage/xgae$run_user_prompt.coverage" NAME="run_user_prompt Coverage Results" MODIFIED="1756279512361" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
192
203
|
<SUITE FILE_PATH="coverage/xgae$xga_mcp_tool_box.coverage" NAME="xga_mcp_tool_box Coverage Results" MODIFIED="1755583099719" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
193
|
-
<SUITE FILE_PATH="coverage/xgae$
|
|
194
|
-
<SUITE FILE_PATH="coverage/xgae$
|
|
204
|
+
<SUITE FILE_PATH="coverage/xgae$llm_client.coverage" NAME="llm_client Coverage Results" MODIFIED="1756261767854" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
205
|
+
<SUITE FILE_PATH="coverage/xgae$task_engine.coverage" NAME="task_engine Coverage Results" MODIFIED="1756269353871" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
|
195
206
|
</component>
|
|
196
207
|
</project>
|
xgae-0.1.9/PKG-INFO
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xgae
|
|
3
|
+
Version: 0.1.9
|
|
4
|
+
Summary: Extreme General Agent Engine
|
|
5
|
+
Requires-Python: >=3.13
|
|
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: langgraph==0.6.5
|
|
10
|
+
Requires-Dist: litellm==1.74.15
|
|
11
|
+
Requires-Dist: mcp==1.13.0
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "xgae"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.9"
|
|
4
4
|
description = "Extreme General Agent Engine"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"colorlog
|
|
9
|
-
"langchain-mcp-adapters
|
|
10
|
-
"langgraph
|
|
11
|
-
"litellm
|
|
12
|
-
"mcp
|
|
13
|
-
"langfuse
|
|
8
|
+
"colorlog==6.9.0",
|
|
9
|
+
"langchain-mcp-adapters==0.1.9",
|
|
10
|
+
"langgraph==0.6.5",
|
|
11
|
+
"litellm==1.74.15",
|
|
12
|
+
"mcp==1.13.0",
|
|
13
|
+
"langfuse==2.60.9",
|
|
14
14
|
]
|
|
15
15
|
|
|
16
16
|
[build-system]
|
|
@@ -22,3 +22,4 @@ exclude = ["log/*"]
|
|
|
22
22
|
|
|
23
23
|
[project.scripts]
|
|
24
24
|
xgae-tools = "xgae.tools.without_general_tools_app:main"
|
|
25
|
+
custom_fault_tools = "examples.tools.custom_fault_tools_app:main"
|
|
@@ -5,10 +5,13 @@ from xgae.engine.task_engine import XGATaskEngine
|
|
|
5
5
|
from xgae.utils.llm_client import LLMConfig
|
|
6
6
|
from xgae.utils.misc import read_file
|
|
7
7
|
|
|
8
|
+
from xgae.utils.setup_env import setup_langfuse
|
|
8
9
|
|
|
9
10
|
async def main() -> None:
|
|
11
|
+
# Before Run Exec: uv run custom_fault_tools
|
|
10
12
|
tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
|
|
11
13
|
system_prompt = read_file("templates/example_user_prompt.txt")
|
|
14
|
+
|
|
12
15
|
engine = XGATaskEngine(tool_box=tool_box,
|
|
13
16
|
general_tools=[],
|
|
14
17
|
custom_tools=["*"],
|
|
@@ -16,14 +19,24 @@ async def main() -> None:
|
|
|
16
19
|
system_prompt=system_prompt,
|
|
17
20
|
max_auto_run=8)
|
|
18
21
|
|
|
22
|
+
langfuse = setup_langfuse()
|
|
23
|
+
# Two task run in same langfuse trace
|
|
24
|
+
trace_id = langfuse.trace(name="xgae_example_run_human_in_loop").trace_id
|
|
25
|
+
|
|
19
26
|
user_input = "locate fault and solution"
|
|
20
|
-
final_result = await engine.run_task_with_final_answer(
|
|
27
|
+
final_result = await engine.run_task_with_final_answer(
|
|
28
|
+
task_message={"role": "user", "content": user_input},
|
|
29
|
+
trace_id=trace_id
|
|
30
|
+
)
|
|
21
31
|
print("FINAL RESULT:", final_result)
|
|
22
32
|
|
|
23
33
|
if final_result["type"] == "ask":
|
|
24
34
|
print("====== Wait for user input ... ======")
|
|
25
35
|
user_input = "ip=10.0.1.1"
|
|
26
|
-
final_result = await engine.run_task_with_final_answer(
|
|
36
|
+
final_result = await engine.run_task_with_final_answer(
|
|
37
|
+
task_message={"role": "user", "content": user_input},
|
|
38
|
+
trace_id=trace_id
|
|
39
|
+
)
|
|
27
40
|
print("FINAL RESULT:", final_result)
|
|
28
41
|
|
|
29
42
|
asyncio.run(main())
|
|
@@ -6,7 +6,11 @@ from xgae.utils.llm_client import LLMConfig
|
|
|
6
6
|
|
|
7
7
|
async def main() -> None:
|
|
8
8
|
engine = XGATaskEngine(llm_config=LLMConfig(stream=False), max_auto_run=1)
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
final_result = await engine.run_task_with_final_answer(
|
|
11
|
+
task_message={"role": "user", "content": "1+1"}
|
|
12
|
+
)
|
|
13
|
+
|
|
10
14
|
print("FINAL RESULT:", final_result)
|
|
11
15
|
|
|
12
16
|
asyncio.run(main())
|
|
@@ -7,8 +7,10 @@ from xgae.utils.misc import read_file
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
async def main() -> None:
|
|
10
|
+
# Before Run Exec: uv run custom_fault_tools
|
|
10
11
|
tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
|
|
11
12
|
system_prompt = read_file("templates/example_user_prompt.txt")
|
|
13
|
+
|
|
12
14
|
engine = XGATaskEngine(tool_box=tool_box,
|
|
13
15
|
general_tools=[],
|
|
14
16
|
custom_tools=["*"],
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from mcp.server.fastmcp import FastMCP
|
|
9
|
+
|
|
10
|
+
mcp = FastMCP(name="Fault Location Tools")
|
|
11
|
+
alarm_type = 0
|
|
12
|
+
|
|
13
|
+
@mcp.tool(
|
|
14
|
+
description="Get Alarm Object",
|
|
15
|
+
)
|
|
16
|
+
def get_alarm(ip: Annotated[str, Field(description="Alarm Object IP Address")]) -> Dict[str, str]:
|
|
17
|
+
logging.info(f"get_alarm: ip={ip}")
|
|
18
|
+
return {"alarmId":"alm0123", "objId": "obj567"}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@mcp.tool(
|
|
22
|
+
description="Get alarm type, return result enum: 1: Business Type Alarm; 2: Equipment Type Alarm; 3: Middleware Type Alarm",
|
|
23
|
+
)
|
|
24
|
+
def get_alarm_type(alarm_id: Annotated[str, Field(description="Alarm Object Id")]) -> str:
|
|
25
|
+
logging.info(f"get_alarm_type: alarm_id={alarm_id}, alarm_type={alarm_type}")
|
|
26
|
+
return f"{alarm_type}"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@mcp.tool(
|
|
30
|
+
description="Locate Business Type Fault",
|
|
31
|
+
)
|
|
32
|
+
def get_busi_fault(obj_id: Annotated[str, Field(description="Alarm Object Id")]) -> Dict[str, Any]:
|
|
33
|
+
logging.info(f"get_busi_fault: obj_id={obj_id}")
|
|
34
|
+
return {"fault_code": "F01", "fault_desc": "Business Recharge Fault"}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@mcp.tool(
|
|
38
|
+
description="Locate Equipment Type Fault",
|
|
39
|
+
)
|
|
40
|
+
def get_equip_fault(obj_id: Annotated[str, Field(description="Alarm Object Id")]) -> Dict[str, Any]:
|
|
41
|
+
logging.info(f"get_equip_fault: obj_id={obj_id}")
|
|
42
|
+
return {"fault_code": "F02", "fault_desc": "Host Disk Fault"}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@mcp.tool(
|
|
46
|
+
description="Locate Middleware Type Fault",
|
|
47
|
+
)
|
|
48
|
+
def get_middle_fault(obj_id: Annotated[str, Field(description="Alarm Object Id")]) -> Dict[str, Any]:
|
|
49
|
+
logging.info(f"get_middle_fault: obj_id={obj_id}")
|
|
50
|
+
return {"fault_code": "F03", "fault_desc": "Redis Fault"}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@mcp.tool(
|
|
54
|
+
description="Get Business Type Fault Solution and Cause",
|
|
55
|
+
)
|
|
56
|
+
async def get_busi_fault_cause(fault_code: Annotated[str, Field(description="Fault Code")]) -> str:
|
|
57
|
+
logging.info(f"get_busi_fault_cause: faultCode={fault_code}")
|
|
58
|
+
|
|
59
|
+
fault_cause = ""
|
|
60
|
+
if (fault_code == 'F01'):
|
|
61
|
+
fault_cause = "Business Recharge Fault, Fault Cause is 'Phone Recharge Application Crash' ,Solution is 'Restart Phone Recharge Application'"
|
|
62
|
+
else:
|
|
63
|
+
fault_cause = f"FaultCode '{fault_code}' is not Business Type"
|
|
64
|
+
|
|
65
|
+
return fault_cause
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@mcp.tool(
|
|
69
|
+
description="Get Equipment Type Fault Solution and Cause",
|
|
70
|
+
)
|
|
71
|
+
async def get_equip_fault_cause(fault_code: Annotated[str, Field(description="Fault Code")]) -> str:
|
|
72
|
+
logging.info(f"get_equip_fault_cause: faultCode={fault_code}")
|
|
73
|
+
|
|
74
|
+
fault_cause = ""
|
|
75
|
+
if (fault_code == 'F01'):
|
|
76
|
+
fault_cause = "Host Fault, Fault Cause is 'Host Disk is Damaged' ,Solution is 'Change Host Disk'"
|
|
77
|
+
else:
|
|
78
|
+
fault_cause = f"FaultCode '{fault_code}' is not Equipment Type"
|
|
79
|
+
|
|
80
|
+
return fault_cause
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@click.command()
|
|
84
|
+
@click.option("--transport", type=click.Choice(["stdio", "sse"]), default="sse", help="Transport type")
|
|
85
|
+
@click.option("--host", default="0.0.0.0", help="Host to listen on for SSE")
|
|
86
|
+
@click.option("--port", default=17070, help="Port to listen on for SSE")
|
|
87
|
+
@click.option("--alarmtype", default=1, help="AlarmType Set")
|
|
88
|
+
def main(transport: str, host: str, port: int, alarmtype:int):
|
|
89
|
+
if transport != "stdio":
|
|
90
|
+
from xgae.utils.setup_env import setup_logging
|
|
91
|
+
setup_logging()
|
|
92
|
+
logging.info("=" * 20 + f" Custom Fault Tools Sever Started in {transport} mode " + "=" * 20)
|
|
93
|
+
|
|
94
|
+
global alarm_type
|
|
95
|
+
alarm_type = alarmtype
|
|
96
|
+
|
|
97
|
+
mcp.settings.host = host
|
|
98
|
+
mcp.settings.port = port
|
|
99
|
+
|
|
100
|
+
mcp.run(transport=transport)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if __name__ == '__main__':
|
|
104
|
+
main()
|
|
@@ -7,7 +7,7 @@ class XGAError(Exception):
|
|
|
7
7
|
pass
|
|
8
8
|
|
|
9
9
|
XGAMsgStatusType = Literal["error", "finish", "tool_error", "tool_started", "tool_completed", "tool_failed", "thread_run_start", "thread_run_end", "assistant_response_start", "assistant_response_end"]
|
|
10
|
-
XGAResponseMsgType = Literal["user", "status", "tool", "assistant"]
|
|
10
|
+
XGAResponseMsgType = Literal["user", "status", "tool", "assistant", "assistant_complete"]
|
|
11
11
|
|
|
12
12
|
class XGAResponseMessage(TypedDict, total=False):
|
|
13
13
|
message_id: str
|
|
@@ -55,4 +55,4 @@ class XGAToolBox(ABC):
|
|
|
55
55
|
|
|
56
56
|
@abstractmethod
|
|
57
57
|
async def call_tool(self, task_id: str, tool_name: str, args: Optional[Dict[str, Any]] = None) -> XGAToolResult:
|
|
58
|
-
pass
|
|
58
|
+
pass
|
|
@@ -8,7 +8,6 @@ from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
|
8
8
|
from langchain_mcp_adapters.tools import load_mcp_tools
|
|
9
9
|
|
|
10
10
|
from xgae.engine.engine_base import XGAError, XGAToolSchema, XGAToolBox, XGAToolResult
|
|
11
|
-
from xgae.utils import langfuse
|
|
12
11
|
|
|
13
12
|
class XGAMcpToolBox(XGAToolBox):
|
|
14
13
|
GENERAL_MCP_SERVER_NAME = "xga_general"
|
|
@@ -191,11 +190,16 @@ class XGAMcpToolBox(XGAToolBox):
|
|
|
191
190
|
if __name__ == "__main__":
|
|
192
191
|
import asyncio
|
|
193
192
|
from dataclasses import asdict
|
|
193
|
+
from xgae.utils.setup_env import setup_logging
|
|
194
|
+
|
|
195
|
+
setup_logging()
|
|
194
196
|
|
|
195
197
|
async def main():
|
|
198
|
+
## Before Run Exec: uv run custom_fault_tools
|
|
199
|
+
mcp_tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
|
|
200
|
+
#mcp_tool_box = XGAMcpToolBox()
|
|
201
|
+
|
|
196
202
|
task_id = "task1"
|
|
197
|
-
#mcp_tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
|
|
198
|
-
mcp_tool_box = XGAMcpToolBox()
|
|
199
203
|
await mcp_tool_box.load_mcp_tools_schema()
|
|
200
204
|
await mcp_tool_box.creat_task_tool_box(task_id=task_id, general_tools=["*"], custom_tools=["bomc_fault.*"])
|
|
201
205
|
tool_schemas = mcp_tool_box.get_task_tool_schemas(task_id, "general_tool")
|
|
@@ -210,9 +214,6 @@ if __name__ == "__main__":
|
|
|
210
214
|
print(asdict(tool_schema))
|
|
211
215
|
print()
|
|
212
216
|
|
|
213
|
-
result = await mcp_tool_box.call_tool(task_id=task_id, tool_name="web_search", args={"task_id": task_id, "query": "查询天津天气"})
|
|
214
|
-
print(f"call web_search result: {result}")
|
|
215
|
-
|
|
216
217
|
result = await mcp_tool_box.call_tool(task_id=task_id, tool_name="complete", args={"task_id": task_id})
|
|
217
218
|
print(f"call complete result: {result}")
|
|
218
219
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
from typing import List, Dict, Any, AsyncGenerator, override,Optional
|
|
4
|
+
from xgae.utils.json_helpers import format_for_yield
|
|
4
5
|
|
|
5
6
|
from xgae.engine.responser.responser_base import TaskResponseProcessor, TaskResponserContext, TaskRunContinuousState
|
|
6
|
-
|
|
7
|
-
from xgae.utils.json_helpers import format_for_yield
|
|
7
|
+
|
|
8
8
|
|
|
9
9
|
class NonStreamTaskResponser(TaskResponseProcessor):
|
|
10
10
|
def __init__(self, response_context: TaskResponserContext):
|
|
@@ -16,6 +16,7 @@ class NonStreamTaskResponser(TaskResponseProcessor):
|
|
|
16
16
|
llm_content = ""
|
|
17
17
|
parsed_xml_data = []
|
|
18
18
|
finish_reason = None
|
|
19
|
+
llm_count = continuous_state.get("auto_continue_count")
|
|
19
20
|
|
|
20
21
|
try:
|
|
21
22
|
# Extract finish_reason, content, tool calls
|
|
@@ -24,7 +25,7 @@ class NonStreamTaskResponser(TaskResponseProcessor):
|
|
|
24
25
|
finish_reason = llm_response.choices[0].finish_reason
|
|
25
26
|
logging.info(f"NonStreamTask:LLM response finish_reason={finish_reason}")
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
self.root_span.event(name=f"non_stream_processor_start[{self.task_no}]({llm_count})", level="DEFAULT",
|
|
28
29
|
status_message=(f"finish_reason={finish_reason}, tool_exec_strategy={self.tool_execution_strategy}"))
|
|
29
30
|
|
|
30
31
|
response_message = llm_response.choices[0].message if hasattr(llm_response.choices[0], 'message') else None
|
|
@@ -47,8 +48,8 @@ class NonStreamTaskResponser(TaskResponseProcessor):
|
|
|
47
48
|
else:
|
|
48
49
|
logging.warning(f"NonStreamTask:LLM response_message is empty")
|
|
49
50
|
|
|
50
|
-
message_data = {"role": "assistant", "content": llm_content
|
|
51
|
-
assistant_msg = self.add_response_message(type="
|
|
51
|
+
message_data = {"role": "assistant", "content": llm_content} # index=-1, full llm_content
|
|
52
|
+
assistant_msg = self.add_response_message(type="assistant_complete", content=message_data, is_llm_message=True)
|
|
52
53
|
yield assistant_msg
|
|
53
54
|
|
|
54
55
|
tool_calls_to_execute = [item['tool_call'] for item in parsed_xml_data]
|
|
@@ -90,7 +91,7 @@ class NonStreamTaskResponser(TaskResponseProcessor):
|
|
|
90
91
|
|
|
91
92
|
except Exception as e:
|
|
92
93
|
logging.error(f"NonStreamTask: Error processing non-streaming response: {llm_content}")
|
|
93
|
-
|
|
94
|
+
self.root_span.event(name="error_processing_non_streaming_response", level="ERROR",
|
|
94
95
|
status_message=(f"Error processing non-streaming response: {str(e)}"))
|
|
95
96
|
|
|
96
97
|
content = {"role": "system", "status_type": "error", "message": str(e)}
|
|
@@ -100,7 +101,7 @@ class NonStreamTaskResponser(TaskResponseProcessor):
|
|
|
100
101
|
|
|
101
102
|
# Re-raise the same exception (not a new one) to ensure proper error propagation
|
|
102
103
|
logging.critical(f"NonStreamTask: Re-raising error to stop further processing: {str(e)}")
|
|
103
|
-
|
|
104
|
+
self.root_span.event(name="re_raising_error_to_stop_further_processing", level="CRITICAL",
|
|
104
105
|
status_message=(f"Re-raising error to stop further processing: {str(e)}"))
|
|
105
106
|
raise # Use bare 'raise' to preserve the original exception with its traceback
|
|
106
107
|
|