xgae 0.1.10__tar.gz → 0.1.14__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 (54) hide show
  1. {xgae-0.1.10 → xgae-0.1.14}/.env +11 -4
  2. {xgae-0.1.10 → xgae-0.1.14}/.idea/misc.xml +1 -1
  3. xgae-0.1.14/.idea/workspace.xml +200 -0
  4. {xgae-0.1.10 → xgae-0.1.14}/.idea/xgae.iml +1 -1
  5. {xgae-0.1.10 → xgae-0.1.14}/PKG-INFO +1 -1
  6. {xgae-0.1.10 → xgae-0.1.14}/pyproject.toml +2 -2
  7. {xgae-0.1.10 → xgae-0.1.14}/src/examples/agent/langgraph/react/react_agent.py +76 -48
  8. xgae-0.1.14/src/examples/engine/run_general_tools.py +16 -0
  9. {xgae-0.1.10 → xgae-0.1.14}/src/examples/engine/run_human_in_loop.py +3 -5
  10. {xgae-0.1.10 → xgae-0.1.14}/src/examples/engine/run_simple.py +1 -2
  11. xgae-0.1.14/src/examples/engine/run_user_prompt.py +30 -0
  12. {xgae-0.1.10 → xgae-0.1.14}/src/examples/tools/custom_fault_tools_app.py +2 -1
  13. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/cli_app.py +2 -4
  14. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/engine_base.py +3 -3
  15. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/mcp_tool_box.py +12 -7
  16. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/responser/non_stream_responser.py +31 -41
  17. xgae-0.1.14/src/xgae/engine/responser/responser_base.py +545 -0
  18. xgae-0.1.14/src/xgae/engine/responser/stream_responser.py +249 -0
  19. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/task_engine.py +80 -50
  20. xgae-0.1.14/src/xgae/utils/__init__.py +27 -0
  21. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/utils/json_helpers.py +2 -2
  22. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/utils/llm_client.py +21 -19
  23. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/utils/misc.py +1 -2
  24. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/utils/setup_env.py +1 -0
  25. {xgae-0.1.10 → xgae-0.1.14}/uv.lock +1 -1
  26. xgae-0.1.10/.idea/workspace.xml +0 -216
  27. xgae-0.1.10/src/examples/engine/run_user_prompt.py +0 -35
  28. xgae-0.1.10/src/xgae/engine/responser/responser_base.py +0 -614
  29. xgae-0.1.10/src/xgae/engine/responser/stream_responser.py +0 -825
  30. xgae-0.1.10/src/xgae/utils/__init__.py +0 -15
  31. {xgae-0.1.10 → xgae-0.1.14}/.idea/.gitignore +0 -0
  32. {xgae-0.1.10 → xgae-0.1.14}/.idea/ai_toolkit.xml +0 -0
  33. {xgae-0.1.10 → xgae-0.1.14}/.idea/inspectionProfiles/Project_Default.xml +0 -0
  34. {xgae-0.1.10 → xgae-0.1.14}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  35. {xgae-0.1.10 → xgae-0.1.14}/.idea/modules.xml +0 -0
  36. {xgae-0.1.10 → xgae-0.1.14}/.idea/vcs.xml +0 -0
  37. {xgae-0.1.10 → xgae-0.1.14}/.python-version +0 -0
  38. {xgae-0.1.10 → xgae-0.1.14}/README.md +0 -0
  39. {xgae-0.1.10 → xgae-0.1.14}/mcpservers/custom_servers.json +0 -0
  40. /xgae-0.1.10/mcpservers/xga_server_sse.json → /xgae-0.1.14/mcpservers/xga_server.json +0 -0
  41. /xgae-0.1.10/mcpservers/xga_server.json → /xgae-0.1.14/mcpservers/xga_server_stdio.json +0 -0
  42. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/__init__.py +0 -0
  43. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/prompt_builder.py +0 -0
  44. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/engine/task_langfuse.py +0 -0
  45. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/tools/without_general_tools_app.py +0 -0
  46. {xgae-0.1.10 → xgae-0.1.14}/src/xgae/utils/xml_tool_parser.py +0 -0
  47. {xgae-0.1.10 → xgae-0.1.14}/templates/custom_tool_prompt_template.txt +0 -0
  48. {xgae-0.1.10 → xgae-0.1.14}/templates/example/fault_user_prompt.txt +0 -0
  49. {xgae-0.1.10 → xgae-0.1.14}/templates/gemini_system_prompt_template.txt +0 -0
  50. {xgae-0.1.10 → xgae-0.1.14}/templates/general_tool_prompt_template.txt +0 -0
  51. {xgae-0.1.10 → xgae-0.1.14}/templates/system_prompt_response_sample.txt +0 -0
  52. {xgae-0.1.10 → xgae-0.1.14}/templates/system_prompt_template.txt +0 -0
  53. {xgae-0.1.10 → xgae-0.1.14}/test/test_langfuse.py +0 -0
  54. {xgae-0.1.10 → xgae-0.1.14}/test/test_litellm_langfuse.py +0 -0
@@ -1,24 +1,31 @@
1
1
  # LOG
2
- LOG_LEVEL=INFO
2
+ LOG_LEVEL=DEBUG
3
3
  LOG_FILE=log/xgae.log
4
4
  LOG_ENABLE=True
5
5
 
6
+
6
7
  # LANGFUSE
7
8
  LANGFUSE_PUBLIC_KEY=
8
9
  LANGFUSE_SECRET_KEY=
9
10
  LANGFUSE_HOST=https://cloud.langfuse.com
10
11
 
12
+
11
13
  # LLM
12
14
  LLM_MODEL=openai/qwen3-235b-a22b
13
15
  LLM_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1
14
16
  LLM_API_KEY=
15
17
  LLM_MAX_TOKENS=16384
16
- LLM_TEMPERATURE=0.7
18
+ LLM_TEMPERATURE=0
17
19
  LLM_MAX_RETRIES=2
20
+ LLM_STREAM=True
21
+ LLM_ENABLE_THINKING=False
22
+
18
23
  LLM_LANGFUSE_ENABLE=False
19
24
 
20
- # TASK
21
- MAX_AUTO_RUN = 15
25
+
26
+ # TASK_ENGINE
27
+ MAX_AUTO_RUN=15
28
+ USE_ASSISTANT_CHUNK_MSG=False
22
29
 
23
30
 
24
31
 
@@ -3,5 +3,5 @@
3
3
  <component name="Black">
4
4
  <option name="sdkName" value="Python 3.13 (xgae)" />
5
5
  </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 virtualenv at ~/DevProjects/xga/xgae/.venv" project-jdk-type="Python SDK" />
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 virtualenv at ~/DevelopSpace/xgae/.venv" project-jdk-type="Python SDK" />
7
7
  </project>
@@ -0,0 +1,200 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="0f1352ac-e106-4041-9704-6775ec0c7096" name="Changes" comment="" />
8
+ <option name="SHOW_DIALOG" value="false" />
9
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
11
+ <option name="LAST_RESOLUTION" value="IGNORE" />
12
+ </component>
13
+ <component name="FileTemplateManagerImpl">
14
+ <option name="RECENT_TEMPLATES">
15
+ <list>
16
+ <option value="Python Script" />
17
+ </list>
18
+ </option>
19
+ </component>
20
+ <component name="ProjectColorInfo">{
21
+ &quot;associatedIndex&quot;: 7
22
+ }</component>
23
+ <component name="ProjectId" id="31InXSONOzq9VTdmbkoD0F0ho9q" />
24
+ <component name="ProjectViewState">
25
+ <option name="hideEmptyMiddlePackages" value="true" />
26
+ <option name="showLibraryContents" value="true" />
27
+ </component>
28
+ <component name="PropertiesComponent">{
29
+ &quot;keyToString&quot;: {
30
+ &quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
31
+ &quot;Python.__init__.executor&quot;: &quot;Run&quot;,
32
+ &quot;Python.llm_client.executor&quot;: &quot;Run&quot;,
33
+ &quot;Python.run_general_tools.executor&quot;: &quot;Run&quot;,
34
+ &quot;Python.run_xga_engine.executor&quot;: &quot;Run&quot;,
35
+ &quot;Python.setup_env.executor&quot;: &quot;Run&quot;,
36
+ &quot;Python.utils.executor&quot;: &quot;Run&quot;,
37
+ &quot;Python.xga_engine.executor&quot;: &quot;Run&quot;,
38
+ &quot;Python.xga_mcp_tool_box.executor&quot;: &quot;Run&quot;,
39
+ &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
40
+ &quot;last_opened_file_path&quot;: &quot;/Users/goosezzy/DevelopSpace/xgae&quot;,
41
+ &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
42
+ &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
43
+ &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
44
+ &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
45
+ &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
46
+ &quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
47
+ &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
48
+ }
49
+ }</component>
50
+ <component name="RecentsManager">
51
+ <key name="MoveFile.RECENT_KEYS">
52
+ <recent name="$PROJECT_DIR$/src/xgae/engine/responser" />
53
+ </key>
54
+ </component>
55
+ <component name="RunManager">
56
+ <configuration default="true" type="PythonConfigurationType" factoryName="Python">
57
+ <module name="xgae" />
58
+ <option name="ENV_FILES" value="" />
59
+ <option name="INTERPRETER_OPTIONS" value="" />
60
+ <option name="PARENT_ENVS" value="true" />
61
+ <envs>
62
+ <env name="PYTHONUNBUFFERED" value="1" />
63
+ </envs>
64
+ <option name="SDK_HOME" value="" />
65
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
66
+ <option name="IS_MODULE_SDK" value="false" />
67
+ <option name="ADD_CONTENT_ROOTS" value="true" />
68
+ <option name="ADD_SOURCE_ROOTS" value="true" />
69
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
70
+ <EXTENSION ID="net.ashald.envfile">
71
+ <option name="IS_ENABLED" value="false" />
72
+ <option name="IS_SUBST" value="false" />
73
+ <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
74
+ <option name="IS_IGNORE_MISSING_FILES" value="false" />
75
+ <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
76
+ <ENTRIES>
77
+ <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
78
+ </ENTRIES>
79
+ </EXTENSION>
80
+ <option name="SCRIPT_NAME" value="" />
81
+ <option name="PARAMETERS" value="" />
82
+ <option name="SHOW_COMMAND_LINE" value="false" />
83
+ <option name="EMULATE_TERMINAL" value="false" />
84
+ <option name="MODULE_MODE" value="false" />
85
+ <option name="REDIRECT_INPUT" value="false" />
86
+ <option name="INPUT_FILE" value="" />
87
+ <method v="2" />
88
+ </configuration>
89
+ <configuration name="run_xga_engine" type="PythonConfigurationType" factoryName="Python" temporary="true">
90
+ <module name="xgae" />
91
+ <option name="ENV_FILES" value="" />
92
+ <option name="INTERPRETER_OPTIONS" value="" />
93
+ <option name="PARENT_ENVS" value="true" />
94
+ <envs>
95
+ <env name="PYTHONUNBUFFERED" value="1" />
96
+ </envs>
97
+ <option name="SDK_HOME" value="" />
98
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
99
+ <option name="IS_MODULE_SDK" value="true" />
100
+ <option name="ADD_CONTENT_ROOTS" value="true" />
101
+ <option name="ADD_SOURCE_ROOTS" value="true" />
102
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
103
+ <EXTENSION ID="net.ashald.envfile">
104
+ <option name="IS_ENABLED" value="false" />
105
+ <option name="IS_SUBST" value="false" />
106
+ <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
107
+ <option name="IS_IGNORE_MISSING_FILES" value="false" />
108
+ <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
109
+ <ENTRIES>
110
+ <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
111
+ </ENTRIES>
112
+ </EXTENSION>
113
+ <option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/xgae/engine/task_engine.py" />
114
+ <option name="PARAMETERS" value="" />
115
+ <option name="SHOW_COMMAND_LINE" value="false" />
116
+ <option name="EMULATE_TERMINAL" value="false" />
117
+ <option name="MODULE_MODE" value="false" />
118
+ <option name="REDIRECT_INPUT" value="false" />
119
+ <option name="INPUT_FILE" value="" />
120
+ <method v="2" />
121
+ </configuration>
122
+ <recent_temporary>
123
+ <list>
124
+ <item itemvalue="Python.run_xga_engine" />
125
+ </list>
126
+ </recent_temporary>
127
+ </component>
128
+ <component name="SharedIndexes">
129
+ <attachedChunks>
130
+ <set>
131
+ <option value="bundled-js-predefined-d6986cc7102b-09060db00ec0-JavaScript-PY-251.26927.90" />
132
+ <option value="bundled-python-sdk-41e8cd69c857-64d779b69b7a-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-251.26927.90" />
133
+ </set>
134
+ </attachedChunks>
135
+ </component>
136
+ <component name="TaskManager">
137
+ <task active="true" id="Default" summary="Default task">
138
+ <changelist id="0f1352ac-e106-4041-9704-6775ec0c7096" name="Changes" comment="" />
139
+ <created>1755220495138</created>
140
+ <option name="number" value="Default" />
141
+ <option name="presentableId" value="Default" />
142
+ <updated>1755220495138</updated>
143
+ <workItem from="1755220497295" duration="14755000" />
144
+ <workItem from="1755239458855" duration="4586000" />
145
+ <workItem from="1755244406907" duration="6284000" />
146
+ <workItem from="1755262332599" duration="306000" />
147
+ <workItem from="1755270285722" duration="12068000" />
148
+ <workItem from="1755283728206" duration="1511000" />
149
+ <workItem from="1755286552901" duration="3130000" />
150
+ <workItem from="1755307767865" duration="337000" />
151
+ <workItem from="1755308113420" duration="2825000" />
152
+ <workItem from="1755321931380" duration="8531000" />
153
+ <workItem from="1755330830188" duration="229000" />
154
+ <workItem from="1755396985976" duration="6435000" />
155
+ <workItem from="1755415614018" duration="461000" />
156
+ <workItem from="1755416476555" duration="256000" />
157
+ <workItem from="1755419142521" duration="150000" />
158
+ <workItem from="1755429851003" duration="290000" />
159
+ <workItem from="1755430331676" duration="21000" />
160
+ <workItem from="1755529583730" duration="1643000" />
161
+ <workItem from="1755609955702" duration="37000" />
162
+ <workItem from="1755612319869" duration="621000" />
163
+ <workItem from="1755690345086" duration="6847000" />
164
+ <workItem from="1755781193226" duration="485000" />
165
+ <workItem from="1755781685826" duration="38000" />
166
+ <workItem from="1755781735460" duration="170000" />
167
+ <workItem from="1755817545372" duration="285000" />
168
+ <workItem from="1755862006389" duration="1051000" />
169
+ <workItem from="1755863094184" duration="553000" />
170
+ <workItem from="1755863979826" duration="4236000" />
171
+ <workItem from="1755875255916" duration="2308000" />
172
+ <workItem from="1755877576514" duration="2000" />
173
+ <workItem from="1755878805800" duration="3590000" />
174
+ <workItem from="1755904284653" duration="7803000" />
175
+ <workItem from="1755912586948" duration="1553000" />
176
+ <workItem from="1755915353109" duration="5872000" />
177
+ <workItem from="1755997335603" duration="7717000" />
178
+ <workItem from="1756031865610" duration="2215000" />
179
+ <workItem from="1756297162586" duration="193000" />
180
+ <workItem from="1756297512397" duration="274000" />
181
+ <workItem from="1756481503906" duration="343000" />
182
+ <workItem from="1756482175678" duration="11417000" />
183
+ <workItem from="1756602064592" duration="9720000" />
184
+ </task>
185
+ <servers />
186
+ </component>
187
+ <component name="TypeScriptGeneratedFilesManager">
188
+ <option name="version" value="3" />
189
+ </component>
190
+ <component name="com.intellij.coverage.CoverageDataManagerImpl">
191
+ <SUITE FILE_PATH="coverage/xgae$xga_mcp_tool_box.coverage" NAME="xga_mcp_tool_box Coverage Results" MODIFIED="1755864064753" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
192
+ <SUITE FILE_PATH="coverage/xgae$llm_client.coverage" NAME="llm_client Coverage Results" MODIFIED="1755247632274" 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$setup_env.coverage" NAME="setup_env Coverage Results" MODIFIED="1755876041210" 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$run_general_tools.coverage" NAME="run_general_tools Coverage Results" MODIFIED="1756521020235" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
195
+ <SUITE FILE_PATH="coverage/xgae$run_xga_engine.coverage" NAME="run_xga_engine Coverage Results" MODIFIED="1756611961256" 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$__init__.coverage" NAME="__init__ Coverage Results" MODIFIED="1756483267122" 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$xga_engine.coverage" NAME="xga_engine Coverage Results" MODIFIED="1755876180376" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
198
+ <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$" />
199
+ </component>
200
+ </project>
@@ -5,7 +5,7 @@
5
5
  <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
6
6
  <excludeFolder url="file://$MODULE_DIR$/.venv" />
7
7
  </content>
8
- <orderEntry type="jdk" jdkName="Python 3.13 virtualenv at ~/DevProjects/xga/xgae/.venv" jdkType="Python SDK" />
8
+ <orderEntry type="jdk" jdkName="Python 3.13 virtualenv at ~/DevelopSpace/xgae/.venv" jdkType="Python SDK" />
9
9
  <orderEntry type="sourceFolder" forTests="false" />
10
10
  </component>
11
11
  </module>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xgae
3
- Version: 0.1.10
3
+ Version: 0.1.14
4
4
  Summary: Extreme General Agent Engine
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: colorlog==6.9.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xgae"
3
- version = "0.1.10"
3
+ version = "0.1.14"
4
4
  description = "Extreme General Agent Engine"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -23,4 +23,4 @@ exclude = ["log/*"]
23
23
  [project.scripts]
24
24
  xgae = "xgae.cli_app:main"
25
25
  xgae-tools = "xgae.tools.without_general_tools_app:main"
26
- custom_fault_tools = "examples.tools.custom_fault_tools_app:main"
26
+ example-fault-tools = "examples.tools.custom_fault_tools_app:main"
@@ -10,28 +10,30 @@ from langgraph.graph.message import add_messages
10
10
  from xgae.engine.engine_base import XGATaskResult, XGAResponseMessage
11
11
  from xgae.engine.mcp_tool_box import XGAMcpToolBox
12
12
  from xgae.utils.setup_env import setup_langfuse, setup_logging
13
- from xgae.utils import handle_error
13
+ from xgae.utils import log_trace
14
14
  from xgae.utils.misc import read_file
15
+ from xgae.engine.task_engine import XGATaskEngine
15
16
 
16
17
  class TaskState(TypedDict, total=False):
17
18
  """State definition for the agent orchestration graph"""
18
19
  messages: Annotated[Sequence[BaseMessage], add_messages]
19
20
  user_input: str
20
21
  next_node: str
21
- context: Dict[str, Any]
22
+ agent_context: Dict[str, Any]
22
23
  system_prompt: str
23
24
  custom_tools: List[str]
24
25
  general_tools: List[str]
25
26
  task_result: XGATaskResult
26
- formatted_result: XGATaskResult
27
27
  iteration_count: int
28
28
 
29
29
  langfuse = setup_langfuse()
30
30
 
31
31
  class XGAReactAgent:
32
32
  MAX_TASK_RETRY = 2
33
+
33
34
  def __init__(self):
34
- self.tool_box = XGAMcpToolBox()
35
+ self.tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
36
+ self.graph = None
35
37
 
36
38
  async def _create_graph(self) -> StateGraph:
37
39
  try:
@@ -41,8 +43,7 @@ class XGAReactAgent:
41
43
  graph_builder.add_node("supervisor", self._supervisor_node)
42
44
  graph_builder.add_node("select_tool", self._select_tool_node)
43
45
  graph_builder.add_node("exec_task", self._exec_task_node)
44
- graph_builder.add_node("eval_result", self._eval_result_node)
45
- graph_builder.add_node("format_result", self._format_result_node)
46
+ graph_builder.add_node("final_result", self._final_result_node)
46
47
 
47
48
  # Add edges
48
49
  graph_builder.add_edge(START, "supervisor")
@@ -52,69 +53,98 @@ class XGAReactAgent:
52
53
  {
53
54
  "select_tool": "select_tool",
54
55
  "exec_task": "exec_task",
55
- "format_result": "format_result"
56
+ "end": END
56
57
  }
57
58
  )
58
59
 
59
60
  graph_builder.add_edge("select_tool", "exec_task")
60
- graph_builder.add_edge("exec_task", "eval_result")
61
+ graph_builder.add_edge("exec_task", "final_result")
61
62
 
62
63
  graph_builder.add_conditional_edges(
63
- "eval_result",
64
+ "final_result",
64
65
  self._next_condition,
65
66
  {
66
- "retry": "supervisor",
67
- "format_result": "format_result",
67
+ "supervisor": "supervisor",
68
+ "end": END
68
69
  }
69
70
  )
70
71
 
71
- graph_builder.add_edge("format_result", END)
72
-
73
72
  graph = graph_builder.compile(checkpointer=MemorySaver())
74
- graph.name = "XGARectAgent"
73
+ graph.name = "XGARectAgentGraph"
75
74
 
76
75
  return graph
77
76
  except Exception as e:
78
- logging.error("Failed to create XGARectAgent graph: %s", str(e))
77
+ logging.error("Failed to create XGARectAgent Graph: %s", str(e))
79
78
  raise
80
79
 
80
+ def _search_system_prompt(self, user_input: str) -> str:
81
+ # You should search RAG use user_input, fetch COT or Prompt for your business
82
+ system_prompt = None if "fault" not in user_input else read_file("templates/example/fault_user_prompt.txt")
83
+ return system_prompt
81
84
 
82
85
  async def _supervisor_node(self, state: TaskState) -> Dict[str, Any]:
83
86
  user_input = state.get("user_input", "")
84
- system_prompt = None if "fault" in user_input else read_file("templates/example/fault_user_prompt.txt")
87
+ system_prompt = self._search_system_prompt(user_input)
88
+
89
+ general_tools = [] if system_prompt else ["*"]
90
+ custom_tools = ["*"] if system_prompt else []
91
+
92
+ next_node = "select_tool" if system_prompt else "exec_task"
85
93
  return {
86
94
  "system_prompt" : system_prompt,
87
- "next_node" : "select_tool",
95
+ "next_node" : next_node,
96
+ "general_tools": general_tools,
97
+ "custom_tools": custom_tools,
88
98
  }
89
99
 
100
+ def _select_custom_tools(self, system_prompt: str) -> list[str]:
101
+ custom_tools = ["*"] if system_prompt else []
102
+ return custom_tools
103
+
90
104
  async def _select_tool_node(self, state: TaskState) -> Dict[str, Any]:
91
105
  system_prompt = state.get("system_prompt",None)
92
- general_tools = ["*"] if system_prompt else []
93
- custom_tools = ["*"] if not system_prompt else []
106
+ general_tools = []
107
+ custom_tools = self._select_custom_tools(system_prompt)
94
108
  return {
95
109
  "general_tools" : general_tools,
96
110
  "custom_tools" : custom_tools,
97
111
  }
98
112
 
99
113
  async def _exec_task_node(self, state: TaskState) -> Dict[str, Any]:
100
- task_result = XGATaskResult(type="answer", content="test task result")
114
+ user_input = state.get("user_input", "")
115
+ system_prompt = state.get("system_prompt",None)
116
+ general_tools = state.get("general_tools",[])
117
+ custom_tools = state.get("custom_tools",[])
118
+ is_system_prompt = True if system_prompt is not None else False
119
+ try:
120
+ logging.info(f"🔥 XGATaskEngine: run_task_with_final_answer: user_input={user_input}, general_tools={general_tools}, custom_tools={custom_tools}, is_system_prompt={is_system_prompt}")
121
+ engine = XGATaskEngine(tool_box=self.tool_box,
122
+ general_tools=general_tools,
123
+ custom_tools=custom_tools,
124
+ system_prompt=system_prompt)
125
+ task_result = await engine.run_task_with_final_answer(
126
+ task_message={"role": "user", "content": user_input}
127
+ )
128
+ except Exception as e:
129
+ logging.error("Failed to execute task: %s", str(e))
130
+ task_result = XGATaskResult(type="error", content="Failed to execute task")
131
+
132
+ iteration_count = state.get("iteration_count", 0) + 1
101
133
  return {
102
- "task_result" : task_result
134
+ "task_result" : task_result,
135
+ "iteration_count": iteration_count,
103
136
  }
104
137
 
105
- async def _eval_result_node(self, state: TaskState) -> Dict[str, Any]:
138
+ async def _final_result_node(self, state: TaskState) -> Dict[str, Any]:
139
+ iteration_count = state.get("iteration_count")
140
+ task_result = state.get("task_result")
106
141
  next_node = "end"
142
+ if iteration_count < self.MAX_TASK_RETRY and task_result["type"] == "error":
143
+ next_node = "supervisor"
107
144
  return {
108
145
  "next_node" : next_node
109
146
  }
110
147
 
111
- async def _format_result_node(self, state: TaskState) -> Dict[str, Any]:
112
- formatted_result = state.get("task_result")
113
- return {
114
- "formatted_result" : formatted_result,
115
- "messages": state["messages"] + [AIMessage(content=f"")]
116
- }
117
-
118
148
  def _next_condition(self, state: TaskState) -> str:
119
149
  next_node = state.get("next_node")
120
150
  return next_node
@@ -134,13 +164,8 @@ class XGAReactAgent:
134
164
  "messages": [HumanMessage(content=f"information for: {user_input}")],
135
165
  "user_input": user_input,
136
166
  "next_node": None,
137
- "tasks": [],
138
- "context": "",
139
- "current_task": None,
140
- "next_task": None,
141
- "formatted_result": "",
142
- "final_error_info": "",
143
- "iteration_count": 1
167
+ "agent_context": {},
168
+ "iteration_count": 0
144
169
  }
145
170
 
146
171
  # Run the retrieval graph with proper configuration
@@ -149,7 +174,7 @@ class XGAReactAgent:
149
174
  final_state = await self.graph.ainvoke(initial_state, config=config)
150
175
 
151
176
  # Parse and return formatted results
152
- result = final_state["formatted_result"]
177
+ result = final_state["task_result"]
153
178
 
154
179
  logging.info("=" * 100)
155
180
  logging.info("User question: %s", user_input)
@@ -158,20 +183,23 @@ class XGAReactAgent:
158
183
 
159
184
  return result
160
185
  except Exception as e:
161
- logging.error("### Error ManagerAgent _agent_work for user_input '%s': %s ###", user_input, str(e))
162
- handle_error(e)
163
- result = XGATaskResult(type="error", content="Never get result, Unexpected Error")
186
+ log_trace(e, f"XReactAgent generate: user_input={user_input}")
187
+ result = XGATaskResult(type="error", content=f"React Agent error: {e}")
164
188
  return result
165
189
 
166
190
 
167
191
  if __name__ == "__main__":
168
192
  setup_logging()
169
193
 
170
- agent = XGAReactAgent()
171
- user_inputs = [
172
- "Create a function to sort a list of numbers, sort [6,8,7,5]"
173
- , "sort [3,2,7,5]"
174
- ]
175
- for user_input in user_inputs:
176
- result = agent.generate(user_input)
177
- print(result)
194
+ async def main():
195
+ agent = XGAReactAgent()
196
+ user_inputs = [
197
+ #"locate 10.2.3.4 fault and solution",
198
+ "5+5",
199
+ ]
200
+ for user_input in user_inputs:
201
+ result = await agent.generate(user_input)
202
+ await asyncio.sleep(1)
203
+ print(result)
204
+
205
+ asyncio.run(main())
@@ -0,0 +1,16 @@
1
+ import asyncio
2
+
3
+ from xgae.engine.task_engine import XGATaskEngine
4
+ from xgae.utils.setup_env import setup_logging
5
+
6
+
7
+ setup_logging()
8
+
9
+ async def main() -> None:
10
+ engine = XGATaskEngine(general_tools=["*"])
11
+
12
+ user_input = "This week's gold price"
13
+ final_result = await engine.run_task_with_final_answer(task_message={"role": "user", "content": user_input})
14
+ print("FINAL RESULT:", final_result)
15
+
16
+ asyncio.run(main())
@@ -2,7 +2,7 @@ import asyncio
2
2
 
3
3
  from xgae.engine.mcp_tool_box import XGAMcpToolBox
4
4
  from xgae.engine.task_engine import XGATaskEngine
5
- from xgae.utils.llm_client import LLMConfig
5
+
6
6
  from xgae.utils.misc import read_file
7
7
 
8
8
  from xgae.utils.setup_env import setup_langfuse, setup_logging
@@ -11,16 +11,14 @@ setup_logging()
11
11
  langfuse = setup_langfuse()
12
12
 
13
13
  async def main() -> None:
14
- # Before Run Exec: uv run custom_fault_tools
14
+ # Before Run Exec: uv run example-fault-tools
15
15
  tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
16
16
  system_prompt = read_file("templates/example/fault_user_prompt.txt")
17
17
 
18
18
  engine = XGATaskEngine(tool_box=tool_box,
19
19
  general_tools=[],
20
20
  custom_tools=["*"],
21
- llm_config=LLMConfig(stream=False),
22
- system_prompt=system_prompt,
23
- max_auto_run=8)
21
+ system_prompt=system_prompt)
24
22
 
25
23
  # Two task run in same langfuse trace
26
24
  trace_id = langfuse.trace(name="xgae_example_run_human_in_loop").trace_id
@@ -1,14 +1,13 @@
1
1
  import asyncio
2
2
 
3
3
  from xgae.engine.task_engine import XGATaskEngine
4
- from xgae.utils.llm_client import LLMConfig
5
4
 
6
5
  from xgae.utils.setup_env import setup_logging
7
6
 
8
7
  setup_logging()
9
8
 
10
9
  async def main() -> None:
11
- engine = XGATaskEngine(llm_config=LLMConfig(stream=False), max_auto_run=3)
10
+ engine = XGATaskEngine()
12
11
 
13
12
  final_result = await engine.run_task_with_final_answer(
14
13
  task_message={"role": "user", "content": "1+7"}
@@ -0,0 +1,30 @@
1
+ import asyncio
2
+
3
+ from xgae.engine.mcp_tool_box import XGAMcpToolBox
4
+ from xgae.engine.task_engine import XGATaskEngine
5
+ from xgae.utils.misc import read_file
6
+
7
+ from xgae.utils.setup_env import setup_logging
8
+
9
+ setup_logging(log_level="ERROR")
10
+
11
+ async def main() -> None:
12
+ # Before Run Exec: uv run example-fault-tools
13
+ tool_box = XGAMcpToolBox(custom_mcp_server_file="mcpservers/custom_servers.json")
14
+ system_prompt = read_file("templates/example/fault_user_prompt.txt")
15
+
16
+ engine = XGATaskEngine(tool_box=tool_box,
17
+ general_tools=[],
18
+ custom_tools=["*"],
19
+ system_prompt=system_prompt)
20
+
21
+ user_input = "locate 10.2.3.4 fault and solution"
22
+ chunks = []
23
+ async for chunk in engine.run_task(task_message={"role": "user", "content": user_input}):
24
+ chunks.append(chunk)
25
+ print(chunk)
26
+
27
+ final_result = engine.parse_final_result(chunks)
28
+ print(f"\n\nFINAL_RESULT: {final_result}")
29
+
30
+ asyncio.run(main())
@@ -89,7 +89,8 @@ def main(transport: str, host: str, port: int, alarmtype:int):
89
89
  if transport != "stdio":
90
90
  from xgae.utils.setup_env import setup_logging
91
91
  setup_logging()
92
- logging.info("=" * 20 + f" Custom Fault Tools Sever Started in {transport} mode " + "=" * 20)
92
+ logging.info("=" * 10 + f" Example Fault Tools Sever Started " + "=" * 10)
93
+ logging.info(f"=== transport={transport}, host={host}, port={port}, alarmtype={alarmtype}")
93
94
 
94
95
  global alarm_type
95
96
  alarm_type = alarmtype
@@ -3,7 +3,7 @@ import sys
3
3
 
4
4
  from xgae.engine.mcp_tool_box import XGAMcpToolBox
5
5
  from xgae.engine.task_engine import XGATaskEngine
6
- from xgae.utils.llm_client import LLMConfig
6
+
7
7
  from xgae.utils.misc import read_file
8
8
 
9
9
  from xgae.utils.setup_env import setup_langfuse, setup_env_logging
@@ -50,9 +50,7 @@ async def cli() -> None:
50
50
  engine = XGATaskEngine(tool_box=tool_box,
51
51
  general_tools=general_tools,
52
52
  custom_tools=custom_tools,
53
- llm_config=LLMConfig(stream=False),
54
- system_prompt=system_prompt,
55
- max_auto_run=8)
53
+ system_prompt=system_prompt)
56
54
 
57
55
  # Two task run in same langfuse trace
58
56
  trace_id = langfuse.trace(name="xgae_cli").trace_id
@@ -6,14 +6,14 @@ class XGAError(Exception):
6
6
  """Custom exception for errors in the XGA system."""
7
7
  pass
8
8
 
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", "assistant_complete"]
9
+ XGAMsgStatusType = Literal["error", "finish", "tool_started", "tool_completed", "tool_error", "tool_failed"]
10
+ XGAResponseMsgType = Literal["user", "status", "tool", "assistant", "assistant_chunk"]
11
11
 
12
12
  class XGAResponseMessage(TypedDict, total=False):
13
13
  message_id: str
14
14
  type: XGAResponseMsgType
15
15
  is_llm_message: bool
16
- content: Union[Dict[str, Any], List[Any], str]
16
+ content: Union[Dict[str, Any], str]
17
17
  metadata: Dict[str, Any]
18
18
 
19
19
  class XGATaskResult(TypedDict, total=False):