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.

Files changed (47) hide show
  1. {xgae-0.1.7 → xgae-0.1.9}/.env +2 -0
  2. {xgae-0.1.7 → xgae-0.1.9}/.idea/workspace.xml +17 -6
  3. xgae-0.1.9/PKG-INFO +11 -0
  4. {xgae-0.1.7 → xgae-0.1.9}/pyproject.toml +8 -7
  5. {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_human_in_loop.py +15 -2
  6. {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_simple.py +5 -1
  7. {xgae-0.1.7/src/examples → xgae-0.1.9/src/examples/engine}/run_user_prompt.py +2 -0
  8. xgae-0.1.9/src/examples/tools/custom_fault_tools_app.py +104 -0
  9. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/engine_base.py +2 -2
  10. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/mcp_tool_box.py +7 -6
  11. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/prompt_builder.py +1 -1
  12. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/non_stream_responser.py +8 -7
  13. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/responser_base.py +54 -56
  14. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/responser/stream_responser.py +24 -25
  15. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/engine/task_engine.py +64 -61
  16. xgae-0.1.9/src/xgae/engine/task_langfuse.py +63 -0
  17. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/tools/without_general_tools_app.py +1 -1
  18. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/__init__.py +7 -5
  19. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/json_helpers.py +7 -13
  20. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/llm_client.py +62 -39
  21. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/misc.py +3 -1
  22. xgae-0.1.9/src/xgae/utils/setup_env.py +83 -0
  23. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/utils/xml_tool_parser.py +4 -80
  24. {xgae-0.1.7 → xgae-0.1.9}/templates/example_user_prompt.txt +2 -2
  25. xgae-0.1.9/test/test_langfuse.py +30 -0
  26. xgae-0.1.9/test/test_litellm_langfuse.py +58 -0
  27. {xgae-0.1.7 → xgae-0.1.9}/uv.lock +18 -127
  28. xgae-0.1.7/PKG-INFO +0 -11
  29. xgae-0.1.7/src/xgae/utils/setup_env.py +0 -80
  30. {xgae-0.1.7 → xgae-0.1.9}/.idea/.gitignore +0 -0
  31. {xgae-0.1.7 → xgae-0.1.9}/.idea/inspectionProfiles/Project_Default.xml +0 -0
  32. {xgae-0.1.7 → xgae-0.1.9}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  33. {xgae-0.1.7 → xgae-0.1.9}/.idea/misc.xml +0 -0
  34. {xgae-0.1.7 → xgae-0.1.9}/.idea/modules.xml +0 -0
  35. {xgae-0.1.7 → xgae-0.1.9}/.idea/vcs.xml +0 -0
  36. {xgae-0.1.7 → xgae-0.1.9}/.idea/xgae.iml +0 -0
  37. {xgae-0.1.7 → xgae-0.1.9}/.python-version +0 -0
  38. {xgae-0.1.7 → xgae-0.1.9}/README.md +0 -0
  39. {xgae-0.1.7 → xgae-0.1.9}/mcpservers/custom_servers.json +0 -0
  40. {xgae-0.1.7 → xgae-0.1.9}/mcpservers/xga_server.json +0 -0
  41. {xgae-0.1.7 → xgae-0.1.9}/mcpservers/xga_server_sse.json +0 -0
  42. {xgae-0.1.7 → xgae-0.1.9}/src/xgae/__init__.py +0 -0
  43. {xgae-0.1.7 → xgae-0.1.9}/templates/custom_tool_prompt_template.txt +0 -0
  44. {xgae-0.1.7 → xgae-0.1.9}/templates/gemini_system_prompt_template.txt +0 -0
  45. {xgae-0.1.7 → xgae-0.1.9}/templates/general_tool_prompt_template.txt +0 -0
  46. {xgae-0.1.7 → xgae-0.1.9}/templates/system_prompt_response_sample.txt +0 -0
  47. {xgae-0.1.7 → xgae-0.1.9}/templates/system_prompt_template.txt +0 -0
@@ -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="23338000" />
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="1756111714718" 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$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="1755657717310" 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_user_prompt.coverage" NAME="run_user_prompt Coverage Results" MODIFIED="1756089624828" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
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$task_engine.coverage" NAME="task_engine Coverage Results" MODIFIED="1756102942600" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
194
- <SUITE FILE_PATH="coverage/xgae$llm_client.coverage" NAME="llm_client Coverage Results" MODIFIED="1756112044142" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
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.7"
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>=6.9.0",
9
- "langchain-mcp-adapters>=0.1.4",
10
- "langgraph>=0.3.21",
11
- "litellm>=1.74.8",
12
- "mcp>=1.12.1",
13
- "langfuse>=2.60.5",
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(task_message={"role": "user", "content": user_input})
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(task_message={"role": "user", "content": user_input})
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
- final_result = await engine.run_task_with_final_answer(task_message={"role": "user", "content": "1+1"})
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
 
@@ -3,7 +3,7 @@ import datetime
3
3
 
4
4
  from typing import Optional, List
5
5
 
6
- from xgae.engine.engine_base import XGAToolSchema, XGAError
6
+ from xgae.engine.engine_base import XGAToolSchema
7
7
  from xgae.utils.misc import read_file, format_file_with_args
8
8
 
9
9
 
@@ -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
- from xgae.utils import langfuse
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
- langfuse.create_event(trace_context=self.trace_context, name="non_stream_processor_start", level="DEFAULT",
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, "index": -1} # index=-1, full llm_content
51
- assistant_msg = self.add_response_message(type="assistant", content=message_data, is_llm_message=True)
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
- langfuse.create_event(trace_context=self.trace_context, name="error_processing_non_streaming_response", level="ERROR",
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
- langfuse.create_event(trace_context=self.trace_context, name="re_raising_error_to_stop_further_processing", level="CRITICAL",
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