xgae 0.1.5__py3-none-any.whl → 0.1.7__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/{xga_base.py → engine_base.py} +6 -9
- xgae/engine/{xga_mcp_tool_box.py → mcp_tool_box.py} +11 -5
- xgae/engine/{xga_prompt_builder.py → prompt_builder.py} +3 -2
- xgae/engine/responser/non_stream_responser.py +108 -0
- xgae/engine/responser/{xga_responser_base.py → responser_base.py} +124 -218
- xgae/engine/responser/{xga_stream_responser.py → stream_responser.py} +51 -55
- xgae/engine/{xga_engine.py → task_engine.py} +166 -146
- xgae/tools/without_general_tools_app.py +48 -0
- xgae/utils/__init__.py +13 -0
- xgae/utils/llm_client.py +8 -3
- xgae/utils/{utils.py → misc.py} +0 -8
- xgae/utils/setup_env.py +53 -66
- xgae/utils/xml_tool_parser.py +4 -7
- {xgae-0.1.5.dist-info → xgae-0.1.7.dist-info}/METADATA +1 -1
- xgae-0.1.7.dist-info/RECORD +19 -0
- xgae-0.1.7.dist-info/entry_points.txt +2 -0
- xgae/engine/responser/xga_non_stream_responser.py +0 -216
- xgae-0.1.5.dist-info/RECORD +0 -16
- {xgae-0.1.5.dist-info → xgae-0.1.7.dist-info}/WHEEL +0 -0
xgae/utils/setup_env.py
CHANGED
|
@@ -3,91 +3,78 @@ import os
|
|
|
3
3
|
|
|
4
4
|
from langfuse import Langfuse
|
|
5
5
|
|
|
6
|
-
_log_initialized = False
|
|
7
|
-
|
|
8
6
|
def setup_logging() -> None:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
from dotenv import load_dotenv
|
|
13
|
-
load_dotenv()
|
|
14
|
-
|
|
15
|
-
env_log_level = os.getenv("LOG_LEVEL", "INFO")
|
|
16
|
-
env_log_file = os.getenv("LOG_FILE", "log/xga.log")
|
|
17
|
-
log_level = getattr(logging, env_log_level.upper(), logging.INFO)
|
|
18
|
-
|
|
19
|
-
log_dir = os.path.dirname(env_log_file)
|
|
20
|
-
if log_dir and not os.path.exists(log_dir):
|
|
21
|
-
os.makedirs(log_dir, exist_ok=True)
|
|
22
|
-
else:
|
|
23
|
-
os.remove(env_log_file)
|
|
24
|
-
|
|
25
|
-
logger = logging.getLogger()
|
|
26
|
-
for handler in logger.handlers[:]:
|
|
27
|
-
logger.removeHandler(handler)
|
|
7
|
+
import colorlog
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
load_dotenv()
|
|
28
10
|
|
|
11
|
+
env_log_level = os.getenv("LOG_LEVEL", "INFO")
|
|
12
|
+
env_log_file = os.getenv("LOG_FILE", "log/xga.log")
|
|
13
|
+
log_level = getattr(logging, env_log_level.upper(), logging.INFO)
|
|
29
14
|
|
|
15
|
+
log_dir = os.path.dirname(env_log_file)
|
|
16
|
+
if log_dir and not os.path.exists(log_dir):
|
|
17
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
18
|
+
else:
|
|
19
|
+
os.remove(env_log_file)
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'WARNING': 'yellow',
|
|
35
|
-
'ERROR': 'red',
|
|
36
|
-
'CRITICAL': 'red,bg_white'
|
|
37
|
-
}
|
|
21
|
+
logger = logging.getLogger()
|
|
22
|
+
for handler in logger.handlers[:]:
|
|
23
|
+
logger.removeHandler(handler)
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
log_colors = {
|
|
26
|
+
'DEBUG': 'cyan',
|
|
27
|
+
'INFO': 'green',
|
|
28
|
+
'WARNING': 'yellow',
|
|
29
|
+
'ERROR': 'red',
|
|
30
|
+
'CRITICAL': 'red,bg_white'
|
|
31
|
+
}
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
console_formatter = colorlog.ColoredFormatter('%(log_color)s%(asctime)s - %(levelname)-8s%(reset)s %(white)s%(message)s',
|
|
34
|
+
log_colors=log_colors,
|
|
35
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
36
|
+
)
|
|
48
37
|
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
file_formatter = logging.Formatter(
|
|
39
|
+
'%(asctime)s -%(levelname)-8s %(message)s',
|
|
40
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
41
|
+
)
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
console_handler = logging.StreamHandler()
|
|
44
|
+
console_handler.setFormatter(console_formatter)
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
file_handler = logging.FileHandler(env_log_file, encoding='utf-8')
|
|
47
|
+
file_handler.setFormatter(file_formatter)
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
logger.addHandler(console_handler)
|
|
50
|
+
logger.addHandler(file_handler)
|
|
59
51
|
|
|
60
|
-
|
|
52
|
+
logger.setLevel(log_level)
|
|
61
53
|
|
|
62
|
-
|
|
54
|
+
logging.info(f"Logger is initialized, log_level={env_log_level}, log_file={env_log_file}")
|
|
63
55
|
|
|
64
|
-
setup_logging()
|
|
65
|
-
|
|
66
|
-
_langfuse_initialized = False
|
|
67
56
|
|
|
68
57
|
def setup_langfuse() -> Langfuse:
|
|
69
|
-
global _langfuse_initialized
|
|
70
58
|
_langfuse = None
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
_langfuse_initialized = True
|
|
86
|
-
return _langfuse
|
|
59
|
+
env_public_key = os.getenv("LANGFUSE_PUBLIC_KEY")
|
|
60
|
+
env_secret_key = os.getenv("LANGFUSE_SECRET_KEY")
|
|
61
|
+
env_host = os.getenv("LANGFUSE_HOST", "https://cloud.langfuse.com")
|
|
62
|
+
if env_public_key and env_secret_key:
|
|
63
|
+
_langfuse = Langfuse(tracing_enabled=True,
|
|
64
|
+
public_key=env_public_key,
|
|
65
|
+
secret_key=env_secret_key,
|
|
66
|
+
host=env_host)
|
|
67
|
+
|
|
68
|
+
logging.info("Langfuse initialized Successfully by Key !")
|
|
69
|
+
else:
|
|
70
|
+
_langfuse = Langfuse(tracing_enabled=False)
|
|
71
|
+
logging.warning("Not set key, Langfuse is disabled!")
|
|
87
72
|
|
|
88
|
-
|
|
73
|
+
return _langfuse
|
|
89
74
|
|
|
90
75
|
|
|
91
76
|
if __name__ == "__main__":
|
|
77
|
+
from xgae.utils import langfuse
|
|
78
|
+
|
|
92
79
|
trace_id = langfuse.create_trace_id()
|
|
93
80
|
logging.warning(f"trace_id={trace_id}")
|
xgae/utils/xml_tool_parser.py
CHANGED
|
@@ -5,14 +5,11 @@ This module provides a reliable XML tool call parsing system that supports
|
|
|
5
5
|
the XML format with structured function_calls blocks.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import re
|
|
9
|
-
import xml.etree.ElementTree as ET
|
|
10
|
-
from typing import List, Dict, Any, Optional, Tuple
|
|
11
|
-
from dataclasses import dataclass
|
|
12
8
|
import json
|
|
13
9
|
import logging
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
import re
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from typing import List, Dict, Any, Optional, Tuple
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
@dataclass
|
|
@@ -85,7 +82,7 @@ class XMLToolParser:
|
|
|
85
82
|
if tool_call:
|
|
86
83
|
tool_calls.append(tool_call)
|
|
87
84
|
except Exception as e:
|
|
88
|
-
|
|
85
|
+
logging.error(f"Error parsing invoke block for {function_name}: {e}")
|
|
89
86
|
|
|
90
87
|
return tool_calls
|
|
91
88
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
xgae/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
xgae/engine/engine_base.py,sha256=ySERuLy1YWsf-3s0NFKcyTnXQ4g69wR-cQhtnG0OFmU,1747
|
|
3
|
+
xgae/engine/mcp_tool_box.py,sha256=iBfCLWXvbkKWd1JnSgBLA1T1KdSdpEZCrROkC_cXp7g,10132
|
|
4
|
+
xgae/engine/prompt_builder.py,sha256=8_rNRJksn2QLV_K98S0x0qNeHcmxhU0kB_53IZJTGOU,4366
|
|
5
|
+
xgae/engine/task_engine.py,sha256=mjS7oDlJH-1wBohzz1FfFng2nE_K0xL-QaNZDuQss3A,17986
|
|
6
|
+
xgae/engine/responser/non_stream_responser.py,sha256=kOP9kDEhHtrDKMyVnBPWEx0yO-xTvVacfXGJJqFtONU,6395
|
|
7
|
+
xgae/engine/responser/responser_base.py,sha256=rn3-LkS_alZUwdIxPfDGC_zAH_CncSQ2I-euYA6a45w,30524
|
|
8
|
+
xgae/engine/responser/stream_responser.py,sha256=5KzCHApiPplZ-zN_sbbEbSvj2rtvKWBshJKe_-x7RDI,52927
|
|
9
|
+
xgae/tools/without_general_tools_app.py,sha256=QknIF4OW9xvOad8gx-F_sCBwQYXqMalnNFvYvZXkQ_I,3789
|
|
10
|
+
xgae/utils/__init__.py,sha256=jChvD-p_p5gsrCZUVYPUGJs4CS9gIdNFcSOpkRpcM4Y,317
|
|
11
|
+
xgae/utils/json_helpers.py,sha256=K1ja6GJCatrAheW9bEWAYSQbDI42__boBCZgtsv1gtk,4865
|
|
12
|
+
xgae/utils/llm_client.py,sha256=RvID4bL9yZon096uvuoFZPlqAPiHhET9-9qYp6sUERc,12605
|
|
13
|
+
xgae/utils/misc.py,sha256=EK94YesZp8AmRUqWfN-CjTxyEHPWdIIWpFNO17dzm9g,915
|
|
14
|
+
xgae/utils/setup_env.py,sha256=EVk0KG92Sk6ejBxXZbDDr_dc3KM8GFMofMA4HvXqSfM,2409
|
|
15
|
+
xgae/utils/xml_tool_parser.py,sha256=EJ6BjpD4CSdmS_LqViUJ6P8H9GY2R1e4Dh8rLCR6nSE,7474
|
|
16
|
+
xgae-0.1.7.dist-info/METADATA,sha256=AbGuJUOv4574WF9a2nQNaTxuOKEN2K_U7RaACci2PME,309
|
|
17
|
+
xgae-0.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
18
|
+
xgae-0.1.7.dist-info/entry_points.txt,sha256=rhQ9Vksnu8nA78lPTjiJxOCZ5k6sH6s5YNMR68y7C-A,73
|
|
19
|
+
xgae-0.1.7.dist-info/RECORD,,
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import uuid
|
|
2
|
-
import logging
|
|
3
|
-
|
|
4
|
-
from typing import List, Dict, Any, AsyncGenerator, override,Optional
|
|
5
|
-
|
|
6
|
-
from xgae.engine.responser.xga_responser_base import TaskResponseProcessor, TaskResponseContext, TaskRunContinuousState
|
|
7
|
-
|
|
8
|
-
from xgae.utils.json_helpers import (
|
|
9
|
-
safe_json_parse,
|
|
10
|
-
to_json_string, format_for_yield
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
class NonStreamTaskResponser(TaskResponseProcessor):
|
|
14
|
-
def __init__(self, response_context: TaskResponseContext):
|
|
15
|
-
super().__init__(response_context)
|
|
16
|
-
|
|
17
|
-
@override
|
|
18
|
-
async def process_response(self,
|
|
19
|
-
llm_response: Any,
|
|
20
|
-
prompt_messages: List[Dict[str, Any]],
|
|
21
|
-
continuous_state: Optional[TaskRunContinuousState] = None) -> AsyncGenerator[Dict[str, Any], None]:
|
|
22
|
-
content = ""
|
|
23
|
-
all_tool_data = [] # Stores {'tool_call': ..., 'parsing_details': ...}
|
|
24
|
-
tool_index = 0
|
|
25
|
-
assistant_message_object = None
|
|
26
|
-
tool_result_message_objects = {}
|
|
27
|
-
finish_reason = None
|
|
28
|
-
|
|
29
|
-
native_tool_calls_for_message = []
|
|
30
|
-
llm_model = self.response_context.get("model_name")
|
|
31
|
-
thread_id = self.response_context.get("task_id")
|
|
32
|
-
thread_run_id = self.response_context.get("task_run_id")
|
|
33
|
-
tool_execution_strategy = self.response_context.get("tool_execution_strategy", "parallel")
|
|
34
|
-
xml_adding_strategy = self.response_context.get("xml_adding_strategy", "user_message")
|
|
35
|
-
max_xml_tool_calls = self.response_context.get("max_xml_tool_calls", 0)
|
|
36
|
-
try:
|
|
37
|
-
# Save and Yield thread_run_start status message
|
|
38
|
-
start_content = {"status_type": "thread_run_start", "thread_run_id": thread_run_id}
|
|
39
|
-
start_msg_obj = self.add_message(
|
|
40
|
-
type="status", content=start_content,
|
|
41
|
-
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
42
|
-
)
|
|
43
|
-
# if start_msg_obj: yield format_for_yield(start_msg_obj)
|
|
44
|
-
|
|
45
|
-
# Extract finish_reason, content, tool calls
|
|
46
|
-
if hasattr(llm_response, 'choices') and llm_response.choices:
|
|
47
|
-
if hasattr(llm_response.choices[0], 'finish_reason'):
|
|
48
|
-
finish_reason = llm_response.choices[0].finish_reason
|
|
49
|
-
logging.info(f"Non-streaming finish_reason: {finish_reason}")
|
|
50
|
-
self.trace.event(name="non_streaming_finish_reason", level="DEFAULT",
|
|
51
|
-
status_message=(f"Non-streaming finish_reason: {finish_reason}"))
|
|
52
|
-
response_message = llm_response.choices[0].message if hasattr(llm_response.choices[0],
|
|
53
|
-
'message') else None
|
|
54
|
-
if response_message:
|
|
55
|
-
if hasattr(response_message, 'content') and response_message.content:
|
|
56
|
-
content = response_message.content
|
|
57
|
-
|
|
58
|
-
parsed_xml_data = self._parse_xml_tool_calls(content)
|
|
59
|
-
if max_xml_tool_calls > 0 and len(parsed_xml_data) > max_xml_tool_calls:
|
|
60
|
-
# Truncate content and tool data if limit exceeded
|
|
61
|
-
# ... (Truncation logic similar to streaming) ...
|
|
62
|
-
if parsed_xml_data:
|
|
63
|
-
xml_chunks = self._extract_xml_chunks(content)[:max_xml_tool_calls]
|
|
64
|
-
if xml_chunks:
|
|
65
|
-
last_chunk = xml_chunks[-1]
|
|
66
|
-
last_chunk_pos = content.find(last_chunk)
|
|
67
|
-
if last_chunk_pos >= 0: content = content[:last_chunk_pos + len(last_chunk)]
|
|
68
|
-
parsed_xml_data = parsed_xml_data[:max_xml_tool_calls]
|
|
69
|
-
finish_reason = "xml_tool_limit_reached"
|
|
70
|
-
all_tool_data.extend(parsed_xml_data)
|
|
71
|
-
|
|
72
|
-
# if config.native_tool_calling and hasattr(response_message,
|
|
73
|
-
# 'tool_calls') and response_message.tool_calls:
|
|
74
|
-
# for tool_call in response_message.tool_calls:
|
|
75
|
-
# if hasattr(tool_call, 'function'):
|
|
76
|
-
# exec_tool_call = {
|
|
77
|
-
# "function_name": tool_call.function.name,
|
|
78
|
-
# "arguments": safe_json_parse(tool_call.function.arguments) if isinstance(
|
|
79
|
-
# tool_call.function.arguments, str) else tool_call.function.arguments,
|
|
80
|
-
# "id": tool_call.id if hasattr(tool_call, 'id') else str(uuid.uuid4())
|
|
81
|
-
# }
|
|
82
|
-
# all_tool_data.append({"tool_call": exec_tool_call, "parsing_details": None})
|
|
83
|
-
# native_tool_calls_for_message.append({
|
|
84
|
-
# "id": exec_tool_call["id"], "type": "function",
|
|
85
|
-
# "function": {
|
|
86
|
-
# "name": tool_call.function.name,
|
|
87
|
-
# "arguments": tool_call.function.arguments if isinstance(
|
|
88
|
-
# tool_call.function.arguments, str) else to_json_string(
|
|
89
|
-
# tool_call.function.arguments)
|
|
90
|
-
# }
|
|
91
|
-
# })
|
|
92
|
-
|
|
93
|
-
# --- SAVE and YIELD Final Assistant Message ---
|
|
94
|
-
message_data = {"role": "assistant", "content": content,
|
|
95
|
-
"tool_calls": native_tool_calls_for_message or None}
|
|
96
|
-
assistant_message_object = self._add_message_with_agent_info(type="assistant", content=message_data,
|
|
97
|
-
is_llm_message=True, metadata={"thread_run_id": thread_run_id}
|
|
98
|
-
)
|
|
99
|
-
if assistant_message_object:
|
|
100
|
-
yield assistant_message_object
|
|
101
|
-
else:
|
|
102
|
-
logging.error(f"Failed to save non-streaming assistant message for thread {thread_id}")
|
|
103
|
-
self.trace.event(name="failed_to_save_non_streaming_assistant_message_for_thread", level="ERROR",
|
|
104
|
-
status_message=(
|
|
105
|
-
f"Failed to save non-streaming assistant message for thread {thread_id}"))
|
|
106
|
-
err_content = {"role": "system", "status_type": "error", "message": "Failed to save assistant message"}
|
|
107
|
-
err_msg_obj = self.add_message(
|
|
108
|
-
type="status", content=err_content,
|
|
109
|
-
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
110
|
-
)
|
|
111
|
-
if err_msg_obj: yield format_for_yield(err_msg_obj)
|
|
112
|
-
|
|
113
|
-
# --- Execute Tools and Yield Results ---
|
|
114
|
-
tool_calls_to_execute = [item['tool_call'] for item in all_tool_data]
|
|
115
|
-
if tool_calls_to_execute:
|
|
116
|
-
logging.info(
|
|
117
|
-
f"Executing {len(tool_calls_to_execute)} tools with strategy: {tool_execution_strategy}")
|
|
118
|
-
self.trace.event(name="executing_tools_with_strategy", level="DEFAULT", status_message=(
|
|
119
|
-
f"Executing {len(tool_calls_to_execute)} tools with strategy: {tool_execution_strategy}"))
|
|
120
|
-
tool_results = await self._execute_tools(tool_calls_to_execute, tool_execution_strategy)
|
|
121
|
-
|
|
122
|
-
for i, (returned_tool_call, result) in enumerate(tool_results):
|
|
123
|
-
original_data = all_tool_data[i]
|
|
124
|
-
tool_call_from_data = original_data['tool_call']
|
|
125
|
-
parsing_details = original_data['parsing_details']
|
|
126
|
-
current_assistant_id = assistant_message_object['message_id'] if assistant_message_object else None
|
|
127
|
-
|
|
128
|
-
context = self._create_tool_context(
|
|
129
|
-
tool_call_from_data, tool_index, current_assistant_id, parsing_details
|
|
130
|
-
)
|
|
131
|
-
context.result = result
|
|
132
|
-
|
|
133
|
-
# Save and Yield start status
|
|
134
|
-
started_msg_obj = self._yield_and_save_tool_started(context, thread_id, thread_run_id)
|
|
135
|
-
if started_msg_obj: yield format_for_yield(started_msg_obj)
|
|
136
|
-
|
|
137
|
-
# Save tool result
|
|
138
|
-
saved_tool_result_object = self._add_tool_result(
|
|
139
|
-
thread_id, tool_call_from_data, result, xml_adding_strategy,
|
|
140
|
-
current_assistant_id, parsing_details
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
# Save and Yield completed/failed status
|
|
144
|
-
completed_msg_obj = self._yield_and_save_tool_completed(
|
|
145
|
-
context,
|
|
146
|
-
saved_tool_result_object['message_id'] if saved_tool_result_object else None,
|
|
147
|
-
thread_id, thread_run_id
|
|
148
|
-
)
|
|
149
|
-
if completed_msg_obj: yield format_for_yield(completed_msg_obj)
|
|
150
|
-
|
|
151
|
-
# Yield the saved tool result object
|
|
152
|
-
if saved_tool_result_object:
|
|
153
|
-
tool_result_message_objects[tool_index] = saved_tool_result_object
|
|
154
|
-
yield format_for_yield(saved_tool_result_object)
|
|
155
|
-
else:
|
|
156
|
-
logging.error(f"Failed to save tool result for index {tool_index}")
|
|
157
|
-
self.trace.event(name="failed_to_save_tool_result_for_index", level="ERROR",
|
|
158
|
-
status_message=(f"Failed to save tool result for index {tool_index}"))
|
|
159
|
-
|
|
160
|
-
if completed_msg_obj["metadata"].get("agent_should_terminate") == "true":
|
|
161
|
-
finish_reason = "completed"
|
|
162
|
-
break
|
|
163
|
-
tool_index += 1
|
|
164
|
-
|
|
165
|
-
# --- Save and Yield Final Status ---
|
|
166
|
-
if finish_reason:
|
|
167
|
-
finish_content = {"status_type": "finish", "finish_reason": finish_reason}
|
|
168
|
-
finish_msg_obj = self.add_message(
|
|
169
|
-
type="status", content=finish_content,
|
|
170
|
-
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
171
|
-
)
|
|
172
|
-
if finish_msg_obj: yield format_for_yield(finish_msg_obj)
|
|
173
|
-
|
|
174
|
-
# --- Save and Yield assistant_response_end ---
|
|
175
|
-
if assistant_message_object: # Only save if assistant message was saved
|
|
176
|
-
try:
|
|
177
|
-
# Save the full LiteLLM response object directly in content
|
|
178
|
-
self.add_message(
|
|
179
|
-
type="assistant_response_end",
|
|
180
|
-
content=llm_response,
|
|
181
|
-
is_llm_message=False,
|
|
182
|
-
metadata={"thread_run_id": thread_run_id}
|
|
183
|
-
)
|
|
184
|
-
logging.info("Assistant response end saved for non-stream")
|
|
185
|
-
except Exception as e:
|
|
186
|
-
logging.error(f"Error saving assistant response end for non-stream: {str(e)}")
|
|
187
|
-
self.trace.event(name="error_saving_assistant_response_end_for_non_stream", level="ERROR",
|
|
188
|
-
status_message=(f"Error saving assistant response end for non-stream: {str(e)}"))
|
|
189
|
-
|
|
190
|
-
except Exception as e:
|
|
191
|
-
logging.error(f"Error processing non-streaming response: {str(e)}", exc_info=True)
|
|
192
|
-
self.trace.event(name="error_processing_non_streaming_response", level="ERROR",
|
|
193
|
-
status_message=(f"Error processing non-streaming response: {str(e)}"))
|
|
194
|
-
# Save and yield error status
|
|
195
|
-
err_content = {"role": "system", "status_type": "error", "message": str(e)}
|
|
196
|
-
err_msg_obj = self.add_message(
|
|
197
|
-
type="status", content=err_content,
|
|
198
|
-
is_llm_message=False, metadata={"thread_run_id": thread_run_id if 'thread_run_id' in locals() else None}
|
|
199
|
-
)
|
|
200
|
-
if err_msg_obj: yield format_for_yield(err_msg_obj)
|
|
201
|
-
|
|
202
|
-
# Re-raise the same exception (not a new one) to ensure proper error propagation
|
|
203
|
-
logging.critical(f"Re-raising error to stop further processing: {str(e)}")
|
|
204
|
-
self.trace.event(name="re_raising_error_to_stop_further_processing", level="CRITICAL",
|
|
205
|
-
status_message=(f"Re-raising error to stop further processing: {str(e)}"))
|
|
206
|
-
raise # Use bare 'raise' to preserve the original exception with its traceback
|
|
207
|
-
|
|
208
|
-
finally:
|
|
209
|
-
# Save and Yield the final thread_run_end status
|
|
210
|
-
end_content = {"status_type": "thread_run_end"}
|
|
211
|
-
end_msg_obj = self.add_message(
|
|
212
|
-
type="status", content=end_content,
|
|
213
|
-
is_llm_message=False, metadata={"thread_run_id": thread_run_id if 'thread_run_id' in locals() else None}
|
|
214
|
-
)
|
|
215
|
-
#if end_msg_obj: yield format_for_yield(end_msg_obj)
|
|
216
|
-
|
xgae-0.1.5.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
xgae/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
xgae/engine/xga_base.py,sha256=Es6OICHQ5h9gq5MGm0Mx-7ScyfP94_kVSuRCSFHTsxo,1642
|
|
3
|
-
xgae/engine/xga_engine.py,sha256=CVi9vhwI9kjlyqk_KF3AbpLpYcjCuWulZ8C2UD7242w,17501
|
|
4
|
-
xgae/engine/xga_mcp_tool_box.py,sha256=o0HpP22DA3VPn1CzuQR-r1ue9GIkWGxjLLphJqc7iHw,9883
|
|
5
|
-
xgae/engine/xga_prompt_builder.py,sha256=RuTvQCNufqxDwVvSOPXR0qxAc42cG7NuIaUy9amu66A,4351
|
|
6
|
-
xgae/engine/responser/xga_non_stream_responser.py,sha256=qAWQb8VUIiYjcnww4Eap5tLbigGeTc_DO4gskilbiV0,12882
|
|
7
|
-
xgae/engine/responser/xga_responser_base.py,sha256=RYaO4hn2EXiO--KgIgNmT-cBWPgTpHMAJT47bpMqdhE,34960
|
|
8
|
-
xgae/engine/responser/xga_stream_responser.py,sha256=1x-z1JDghs9SLfSPc1RTS-RMLvs8N3KebaB_l62YIgg,52285
|
|
9
|
-
xgae/utils/json_helpers.py,sha256=K1ja6GJCatrAheW9bEWAYSQbDI42__boBCZgtsv1gtk,4865
|
|
10
|
-
xgae/utils/llm_client.py,sha256=mgzn8heUyRm92HTLEYGdfsGEpFtD-xLFr39P98_JP0s,12402
|
|
11
|
-
xgae/utils/setup_env.py,sha256=-Ehv7_E9udHc8AjP66Y78E4X7_G6gpuNJkioCh5fn4A,2902
|
|
12
|
-
xgae/utils/utils.py,sha256=cCYmWjKFksZ8BRD1YYnaM_jTLVHAg1ibEdjsczEUO6k,1134
|
|
13
|
-
xgae/utils/xml_tool_parser.py,sha256=7Ei7X8zSgVct0fFCSmxDtknCLtdrUIwL9hy_0qSNlvs,7546
|
|
14
|
-
xgae-0.1.5.dist-info/METADATA,sha256=JdXLTZ7vw3S4EAA7heCS5j0Vg1-1mHDPCfskAPSsZjc,309
|
|
15
|
-
xgae-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
-
xgae-0.1.5.dist-info/RECORD,,
|
|
File without changes
|