xgae 0.1.5__py3-none-any.whl → 0.1.6__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} +5 -5
- xgae/engine/{xga_prompt_builder.py → prompt_builder.py} +3 -2
- xgae/engine/responser/non_stream_responser.py +110 -0
- xgae/engine/responser/{xga_responser_base.py → responser_base.py} +102 -186
- xgae/engine/responser/{xga_stream_responser.py → stream_responser.py} +51 -55
- xgae/engine/{xga_engine.py → task_engine.py} +86 -73
- xgae/utils/__init__.py +13 -0
- xgae/utils/{utils.py → misc.py} +0 -8
- xgae/utils/setup_env.py +51 -66
- xgae/utils/xml_tool_parser.py +4 -7
- {xgae-0.1.5.dist-info → xgae-0.1.6.dist-info}/METADATA +1 -1
- xgae-0.1.6.dist-info/RECORD +17 -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.6.dist-info}/WHEEL +0 -0
|
@@ -5,9 +5,10 @@ import uuid
|
|
|
5
5
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from datetime import datetime, timezone
|
|
8
|
-
from typing import List, Dict, Any, Optional, AsyncGenerator, override
|
|
8
|
+
from typing import List, Dict, Any, Optional, AsyncGenerator, override, Literal
|
|
9
9
|
|
|
10
|
-
from xgae.
|
|
10
|
+
from xgae.utils import langfuse
|
|
11
|
+
from xgae.engine.responser.responser_base import TaskResponseProcessor, TaskResponserContext,TaskRunContinuousState,XmlAddingStrategy,ToolExecutionStrategy
|
|
11
12
|
from xgae.utils.json_helpers import (
|
|
12
13
|
ensure_dict, safe_json_parse,
|
|
13
14
|
to_json_string, format_for_yield
|
|
@@ -55,7 +56,7 @@ class ProcessorConfig:
|
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
class StreamTaskResponser(TaskResponseProcessor):
|
|
58
|
-
def __init__(self, response_context:
|
|
59
|
+
def __init__(self, response_context: TaskResponserContext):
|
|
59
60
|
super().__init__(response_context)
|
|
60
61
|
|
|
61
62
|
@override
|
|
@@ -129,14 +130,14 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
129
130
|
# --- Save and Yield Start Events (only if not auto-continuing) ---
|
|
130
131
|
if auto_continue_count == 0:
|
|
131
132
|
start_content = {"status_type": "thread_run_start", "thread_run_id": thread_run_id}
|
|
132
|
-
start_msg_obj = await self.
|
|
133
|
+
start_msg_obj = await self.add_response_message(
|
|
133
134
|
type="status", content=start_content,
|
|
134
135
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
135
136
|
)
|
|
136
137
|
if start_msg_obj: yield format_for_yield(start_msg_obj)
|
|
137
138
|
|
|
138
139
|
assist_start_content = {"status_type": "assistant_response_start"}
|
|
139
|
-
assist_start_msg_obj = await self.
|
|
140
|
+
assist_start_msg_obj = await self.add_response_message(
|
|
140
141
|
type="status", content=assist_start_content,
|
|
141
142
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
142
143
|
)
|
|
@@ -204,7 +205,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
204
205
|
__sequence += 1
|
|
205
206
|
else:
|
|
206
207
|
logging.info("XML tool call limit reached - not yielding more content chunks")
|
|
207
|
-
self.
|
|
208
|
+
langfuse.create_event(trace_context=self.trace_context, name="xml_tool_call_limit_reached", level="DEFAULT", status_message=(
|
|
208
209
|
f"XML tool call limit reached - not yielding more content chunks"))
|
|
209
210
|
|
|
210
211
|
# --- Process XML Tool Calls (if enabled and limit not reached) ---
|
|
@@ -226,8 +227,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
226
227
|
|
|
227
228
|
if config.execute_tools and config.execute_on_stream:
|
|
228
229
|
# Save and Yield tool_started status
|
|
229
|
-
started_msg_obj = await self.
|
|
230
|
-
thread_run_id)
|
|
230
|
+
started_msg_obj = await self._add_tool_start_message(context)
|
|
231
231
|
if started_msg_obj: yield format_for_yield(started_msg_obj)
|
|
232
232
|
yielded_tool_indices.add(tool_index) # Mark status as yielded
|
|
233
233
|
|
|
@@ -304,8 +304,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
304
304
|
)
|
|
305
305
|
|
|
306
306
|
# Save and Yield tool_started status
|
|
307
|
-
started_msg_obj = await self.
|
|
308
|
-
thread_run_id)
|
|
307
|
+
started_msg_obj = await self._add_tool_start_message(context)
|
|
309
308
|
if started_msg_obj: yield format_for_yield(started_msg_obj)
|
|
310
309
|
yielded_tool_indices.add(tool_index) # Mark status as yielded
|
|
311
310
|
|
|
@@ -318,7 +317,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
318
317
|
|
|
319
318
|
if finish_reason == "xml_tool_limit_reached":
|
|
320
319
|
logging.info("Stopping stream processing after loop due to XML tool call limit")
|
|
321
|
-
self.
|
|
320
|
+
langfuse.create_event(trace_context=self.trace_context, name="stopping_stream_processing_after_loop_due_to_xml_tool_call_limit",
|
|
322
321
|
level="DEFAULT", status_message=(
|
|
323
322
|
f"Stopping stream processing after loop due to XML tool call limit"))
|
|
324
323
|
break
|
|
@@ -353,18 +352,18 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
353
352
|
# f"🔥 Estimated tokens – prompt: {prompt_tokens}, "
|
|
354
353
|
# f"completion: {completion_tokens}, total: {prompt_tokens + completion_tokens}"
|
|
355
354
|
# )
|
|
356
|
-
self.
|
|
355
|
+
langfuse.create_event(trace_context=self.trace_context, name="usage_calculated_with_litellm_token_counter", level="DEFAULT",
|
|
357
356
|
status_message=(f"Usage calculated with litellm.token_counter"))
|
|
358
357
|
except Exception as e:
|
|
359
358
|
logging.warning(f"Failed to calculate usage: {str(e)}")
|
|
360
|
-
self.
|
|
359
|
+
langfuse.create_event(trace_context=self.trace_context, name="failed_to_calculate_usage", level="WARNING",
|
|
361
360
|
status_message=(f"Failed to calculate usage: {str(e)}"))
|
|
362
361
|
|
|
363
362
|
# Wait for pending tool executions from streaming phase
|
|
364
363
|
tool_results_buffer = [] # Stores (tool_call, result, tool_index, context)
|
|
365
364
|
if pending_tool_executions:
|
|
366
365
|
logging.info(f"Waiting for {len(pending_tool_executions)} pending streamed tool executions")
|
|
367
|
-
self.
|
|
366
|
+
langfuse.create_event(trace_context=self.trace_context, name="waiting_for_pending_streamed_tool_executions", level="DEFAULT", status_message=(
|
|
368
367
|
f"Waiting for {len(pending_tool_executions)} pending streamed tool executions"))
|
|
369
368
|
# ... (asyncio.wait logic) ...
|
|
370
369
|
pending_tasks = [execution["task"] for execution in pending_tool_executions]
|
|
@@ -388,24 +387,24 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
388
387
|
if tool_name in ['ask', 'complete']:
|
|
389
388
|
logging.info(
|
|
390
389
|
f"Terminating tool '{tool_name}' completed during streaming. Setting termination flag.")
|
|
391
|
-
self.
|
|
390
|
+
langfuse.create_event(trace_context=self.trace_context, name="terminating_tool_completed_during_streaming",
|
|
392
391
|
level="DEFAULT", status_message=(
|
|
393
392
|
f"Terminating tool '{tool_name}' completed during streaming. Setting termination flag."))
|
|
394
393
|
agent_should_terminate = True
|
|
395
394
|
|
|
396
395
|
else: # Should not happen with asyncio.wait
|
|
397
396
|
logging.warning(f"Task for tool index {tool_idx} not done after wait.")
|
|
398
|
-
self.
|
|
397
|
+
langfuse.create_event(trace_context=self.trace_context, name="task_for_tool_index_not_done_after_wait", level="WARNING",
|
|
399
398
|
status_message=(
|
|
400
399
|
f"Task for tool index {tool_idx} not done after wait."))
|
|
401
400
|
except Exception as e:
|
|
402
401
|
logging.error(f"Error getting result for pending tool execution {tool_idx}: {str(e)}")
|
|
403
|
-
self.
|
|
402
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_getting_result_for_pending_tool_execution", level="ERROR",
|
|
404
403
|
status_message=(
|
|
405
404
|
f"Error getting result for pending tool execution {tool_idx}: {str(e)}"))
|
|
406
405
|
context.error = e
|
|
407
406
|
# Save and Yield tool error status message (even if started was yielded)
|
|
408
|
-
error_msg_obj = await self.
|
|
407
|
+
error_msg_obj = await self._add_tool_error_message(context)
|
|
409
408
|
if error_msg_obj: yield format_for_yield(error_msg_obj)
|
|
410
409
|
continue # Skip further status yielding for this tool index
|
|
411
410
|
|
|
@@ -420,40 +419,39 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
420
419
|
if tool_name in ['ask', 'complete']:
|
|
421
420
|
logging.info(
|
|
422
421
|
f"Terminating tool '{tool_name}' completed during streaming. Setting termination flag.")
|
|
423
|
-
self.
|
|
422
|
+
langfuse.create_event(trace_context=self.trace_context, name="terminating_tool_completed_during_streaming", level="DEFAULT",
|
|
424
423
|
status_message=(
|
|
425
424
|
f"Terminating tool '{tool_name}' completed during streaming. Setting termination flag."))
|
|
426
425
|
agent_should_terminate = True
|
|
427
426
|
|
|
428
427
|
# Save and Yield tool completed/failed status
|
|
429
|
-
completed_msg_obj = await self.
|
|
430
|
-
context, None
|
|
431
|
-
)
|
|
428
|
+
completed_msg_obj = await self._add_tool_completed_message(
|
|
429
|
+
context, None)
|
|
432
430
|
if completed_msg_obj: yield format_for_yield(completed_msg_obj)
|
|
433
431
|
yielded_tool_indices.add(tool_idx)
|
|
434
432
|
except Exception as e:
|
|
435
433
|
logging.error(
|
|
436
434
|
f"Error getting result/yielding status for pending tool execution {tool_idx}: {str(e)}")
|
|
437
|
-
self.
|
|
435
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_getting_result_yielding_status_for_pending_tool_execution",
|
|
438
436
|
level="ERROR", status_message=(
|
|
439
437
|
f"Error getting result/yielding status for pending tool execution {tool_idx}: {str(e)}"))
|
|
440
438
|
context.error = e
|
|
441
439
|
# Save and Yield tool error status
|
|
442
|
-
error_msg_obj = await self.
|
|
440
|
+
error_msg_obj = await self._add_tool_error_message(context)
|
|
443
441
|
if error_msg_obj: yield format_for_yield(error_msg_obj)
|
|
444
442
|
yielded_tool_indices.add(tool_idx)
|
|
445
443
|
|
|
446
444
|
# Save and yield finish status if limit was reached
|
|
447
445
|
if finish_reason == "xml_tool_limit_reached":
|
|
448
446
|
finish_content = {"status_type": "finish", "finish_reason": "xml_tool_limit_reached"}
|
|
449
|
-
finish_msg_obj = await self.
|
|
447
|
+
finish_msg_obj = await self.add_response_message(
|
|
450
448
|
type="status", content=finish_content,
|
|
451
449
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
452
450
|
)
|
|
453
451
|
if finish_msg_obj: yield format_for_yield(finish_msg_obj)
|
|
454
452
|
logging.info(
|
|
455
453
|
f"Stream finished with reason: xml_tool_limit_reached after {xml_tool_call_count} XML tool calls")
|
|
456
|
-
self.
|
|
454
|
+
langfuse.create_event(trace_context=self.trace_context, name="stream_finished_with_reason_xml_tool_limit_reached_after_xml_tool_calls",
|
|
457
455
|
level="DEFAULT", status_message=(
|
|
458
456
|
f"Stream finished with reason: xml_tool_limit_reached after {xml_tool_call_count} XML tool calls"))
|
|
459
457
|
|
|
@@ -489,7 +487,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
489
487
|
"tool_calls": complete_native_tool_calls or None
|
|
490
488
|
}
|
|
491
489
|
|
|
492
|
-
last_assistant_message_object = await self.
|
|
490
|
+
last_assistant_message_object = await self.add_response_message(type="assistant", content=message_data,
|
|
493
491
|
is_llm_message=True, metadata={"thread_run_id": thread_run_id}
|
|
494
492
|
)
|
|
495
493
|
|
|
@@ -503,12 +501,12 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
503
501
|
yield format_for_yield(yield_message)
|
|
504
502
|
else:
|
|
505
503
|
logging.error(f"Failed to save final assistant message for thread {thread_id}")
|
|
506
|
-
self.
|
|
504
|
+
langfuse.create_event(trace_context=self.trace_context, name="failed_to_save_final_assistant_message_for_thread", level="ERROR",
|
|
507
505
|
status_message=(f"Failed to save final assistant message for thread {thread_id}"))
|
|
508
506
|
# Save and yield an error status
|
|
509
507
|
err_content = {"role": "system", "status_type": "error",
|
|
510
508
|
"message": "Failed to save final assistant message"}
|
|
511
|
-
err_msg_obj = await self.
|
|
509
|
+
err_msg_obj = await self.add_response_message(
|
|
512
510
|
type="status", content=err_content,
|
|
513
511
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
514
512
|
)
|
|
@@ -571,7 +569,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
571
569
|
# Populate from buffer if executed on stream
|
|
572
570
|
if config.execute_on_stream and tool_results_buffer:
|
|
573
571
|
logging.info(f"Processing {len(tool_results_buffer)} buffered tool results")
|
|
574
|
-
self.
|
|
572
|
+
langfuse.create_event(trace_context=self.trace_context, name="processing_buffered_tool_results", level="DEFAULT",
|
|
575
573
|
status_message=(f"Processing {len(tool_results_buffer)} buffered tool results"))
|
|
576
574
|
for tool_call, result, tool_idx, context in tool_results_buffer:
|
|
577
575
|
if last_assistant_message_object: context.assistant_message_id = last_assistant_message_object[
|
|
@@ -582,7 +580,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
582
580
|
elif final_tool_calls_to_process and not config.execute_on_stream:
|
|
583
581
|
logging.info(
|
|
584
582
|
f"Executing {len(final_tool_calls_to_process)} tools ({config.tool_execution_strategy}) after stream")
|
|
585
|
-
self.
|
|
583
|
+
langfuse.create_event(trace_context=self.trace_context, name="executing_tools_after_stream", level="DEFAULT", status_message=(
|
|
586
584
|
f"Executing {len(final_tool_calls_to_process)} tools ({config.tool_execution_strategy}) after stream"))
|
|
587
585
|
results_list = await self._execute_tools(final_tool_calls_to_process,
|
|
588
586
|
config.tool_execution_strategy)
|
|
@@ -600,14 +598,14 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
600
598
|
tool_results_map[current_tool_idx] = (tc, res, context)
|
|
601
599
|
else:
|
|
602
600
|
logging.warning(f"Could not map result for tool index {current_tool_idx}")
|
|
603
|
-
self.
|
|
601
|
+
langfuse.create_event(trace_context=self.trace_context, name="could_not_map_result_for_tool_index", level="WARNING",
|
|
604
602
|
status_message=(f"Could not map result for tool index {current_tool_idx}"))
|
|
605
603
|
current_tool_idx += 1
|
|
606
604
|
|
|
607
605
|
# Save and Yield each result message
|
|
608
606
|
if tool_results_map:
|
|
609
607
|
logging.info(f"Saving and yielding {len(tool_results_map)} final tool result messages")
|
|
610
|
-
self.
|
|
608
|
+
langfuse.create_event(trace_context=self.trace_context, name="saving_and_yielding_final_tool_result_messages", level="DEFAULT",
|
|
611
609
|
status_message=(
|
|
612
610
|
f"Saving and yielding {len(tool_results_map)} final tool result messages"))
|
|
613
611
|
for tool_idx in sorted(tool_results_map.keys()):
|
|
@@ -618,21 +616,19 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
618
616
|
|
|
619
617
|
# Yield start status ONLY IF executing non-streamed (already yielded if streamed)
|
|
620
618
|
if not config.execute_on_stream and tool_idx not in yielded_tool_indices:
|
|
621
|
-
started_msg_obj = await self.
|
|
619
|
+
started_msg_obj = await self._add_tool_start_message(context)
|
|
622
620
|
if started_msg_obj: yield format_for_yield(started_msg_obj)
|
|
623
621
|
yielded_tool_indices.add(tool_idx) # Mark status yielded
|
|
624
622
|
|
|
625
623
|
# Save the tool result message to DB
|
|
626
|
-
saved_tool_result_object = await self.
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
)
|
|
624
|
+
saved_tool_result_object = await self._add_tool_messsage(tool_call, result, config.xml_adding_strategy,
|
|
625
|
+
context.assistant_message_id, context.parsing_details
|
|
626
|
+
)
|
|
630
627
|
|
|
631
628
|
# Yield completed/failed status (linked to saved result ID if available)
|
|
632
|
-
completed_msg_obj = await self.
|
|
629
|
+
completed_msg_obj = await self._add_tool_completed_message(
|
|
633
630
|
context,
|
|
634
|
-
saved_tool_result_object['message_id'] if saved_tool_result_object else None
|
|
635
|
-
thread_id, thread_run_id
|
|
631
|
+
saved_tool_result_object['message_id'] if saved_tool_result_object else None
|
|
636
632
|
)
|
|
637
633
|
if completed_msg_obj: yield format_for_yield(completed_msg_obj)
|
|
638
634
|
# Don't add to yielded_tool_indices here, completion status is separate yield
|
|
@@ -644,7 +640,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
644
640
|
else:
|
|
645
641
|
logging.error(
|
|
646
642
|
f"Failed to save tool result for index {tool_idx}, not yielding result message.")
|
|
647
|
-
self.
|
|
643
|
+
langfuse.create_event(trace_context=self.trace_context, name="failed_to_save_tool_result_for_index", level="ERROR",
|
|
648
644
|
status_message=(
|
|
649
645
|
f"Failed to save tool result for index {tool_idx}, not yielding result message."))
|
|
650
646
|
# Optionally yield error status for saving failure?
|
|
@@ -652,7 +648,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
652
648
|
# --- Final Finish Status ---
|
|
653
649
|
if finish_reason and finish_reason != "xml_tool_limit_reached":
|
|
654
650
|
finish_content = {"status_type": "finish", "finish_reason": finish_reason}
|
|
655
|
-
finish_msg_obj = await self.
|
|
651
|
+
finish_msg_obj = await self.add_response_message(
|
|
656
652
|
type="status", content=finish_content,
|
|
657
653
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
658
654
|
)
|
|
@@ -662,7 +658,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
662
658
|
if agent_should_terminate:
|
|
663
659
|
logging.info(
|
|
664
660
|
"Agent termination requested after executing ask/complete tool. Stopping further processing.")
|
|
665
|
-
self.
|
|
661
|
+
langfuse.create_event(trace_context=self.trace_context, name="agent_termination_requested", level="DEFAULT",
|
|
666
662
|
status_message="Agent termination requested after executing ask/complete tool. Stopping further processing.")
|
|
667
663
|
|
|
668
664
|
# Set finish reason to indicate termination
|
|
@@ -670,7 +666,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
670
666
|
|
|
671
667
|
# Save and yield termination status
|
|
672
668
|
finish_content = {"status_type": "finish", "finish_reason": "agent_terminated"}
|
|
673
|
-
finish_msg_obj = await self.
|
|
669
|
+
finish_msg_obj = await self.add_response_message(
|
|
674
670
|
type="status", content=finish_content,
|
|
675
671
|
is_llm_message=False, metadata={"thread_run_id": thread_run_id}
|
|
676
672
|
)
|
|
@@ -714,7 +710,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
714
710
|
if streaming_metadata.get("response_ms"):
|
|
715
711
|
assistant_end_content["response_ms"] = streaming_metadata["response_ms"]
|
|
716
712
|
|
|
717
|
-
await self.
|
|
713
|
+
await self.add_response_message(
|
|
718
714
|
type="assistant_response_end",
|
|
719
715
|
content=assistant_end_content,
|
|
720
716
|
is_llm_message=False,
|
|
@@ -723,7 +719,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
723
719
|
logging.info("Assistant response end saved for stream (before termination)")
|
|
724
720
|
except Exception as e:
|
|
725
721
|
logging.error(f"Error saving assistant response end for stream (before termination): {str(e)}")
|
|
726
|
-
self.
|
|
722
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_saving_assistant_response_end_for_stream_before_termination",
|
|
727
723
|
level="ERROR", status_message=(
|
|
728
724
|
f"Error saving assistant response end for stream (before termination): {str(e)}"))
|
|
729
725
|
|
|
@@ -770,7 +766,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
770
766
|
if streaming_metadata.get("response_ms"):
|
|
771
767
|
assistant_end_content["response_ms"] = streaming_metadata["response_ms"]
|
|
772
768
|
|
|
773
|
-
await self.
|
|
769
|
+
await self.add_response_message(
|
|
774
770
|
type="assistant_response_end",
|
|
775
771
|
content=assistant_end_content,
|
|
776
772
|
is_llm_message=False,
|
|
@@ -779,18 +775,18 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
779
775
|
logging.info("Assistant response end saved for stream")
|
|
780
776
|
except Exception as e:
|
|
781
777
|
logging.error(f"Error saving assistant response end for stream: {str(e)}")
|
|
782
|
-
self.
|
|
778
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_saving_assistant_response_end_for_stream", level="ERROR",
|
|
783
779
|
status_message=(f"Error saving assistant response end for stream: {str(e)}"))
|
|
784
780
|
|
|
785
781
|
except Exception as e:
|
|
786
782
|
logging.error(f"Error processing stream: {str(e)}", exc_info=True)
|
|
787
|
-
self.
|
|
783
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_processing_stream", level="ERROR",
|
|
788
784
|
status_message=(f"Error processing stream: {str(e)}"))
|
|
789
785
|
# Save and yield error status message
|
|
790
786
|
|
|
791
787
|
err_content = {"role": "system", "status_type": "error", "message": str(e)}
|
|
792
788
|
if (not "AnthropicException - Overloaded" in str(e)):
|
|
793
|
-
err_msg_obj = await self.
|
|
789
|
+
err_msg_obj = await self.add_response_message(
|
|
794
790
|
type="status", content=err_content,
|
|
795
791
|
is_llm_message=False,
|
|
796
792
|
metadata={"thread_run_id": thread_run_id if 'thread_run_id' in locals() else None}
|
|
@@ -798,12 +794,12 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
798
794
|
if err_msg_obj: yield format_for_yield(err_msg_obj) # Yield the saved error message
|
|
799
795
|
# Re-raise the same exception (not a new one) to ensure proper error propagation
|
|
800
796
|
logging.critical(f"Re-raising error to stop further processing: {str(e)}")
|
|
801
|
-
self.
|
|
797
|
+
langfuse.create_event(trace_context=self.trace_context, name="re_raising_error_to_stop_further_processing", level="ERROR",
|
|
802
798
|
status_message=(f"Re-raising error to stop further processing: {str(e)}"))
|
|
803
799
|
else:
|
|
804
800
|
logging.error(f"AnthropicException - Overloaded detected - Falling back to OpenRouter: {str(e)}",
|
|
805
801
|
exc_info=True)
|
|
806
|
-
self.
|
|
802
|
+
langfuse.create_event(trace_context=self.trace_context, name="anthropic_exception_overloaded_detected", level="ERROR", status_message=(
|
|
807
803
|
f"AnthropicException - Overloaded detected - Falling back to OpenRouter: {str(e)}"))
|
|
808
804
|
raise # Use bare 'raise' to preserve the original exception with its traceback
|
|
809
805
|
|
|
@@ -818,7 +814,7 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
818
814
|
# Save and Yield the final thread_run_end status (only if not auto-continuing and finish_reason is not 'length')
|
|
819
815
|
try:
|
|
820
816
|
end_content = {"status_type": "thread_run_end"}
|
|
821
|
-
end_msg_obj = await self.
|
|
817
|
+
end_msg_obj = await self.add_response_message(
|
|
822
818
|
type="status", content=end_content,
|
|
823
819
|
is_llm_message=False,
|
|
824
820
|
metadata={"thread_run_id": thread_run_id if 'thread_run_id' in locals() else None}
|
|
@@ -826,5 +822,5 @@ class StreamTaskResponser(TaskResponseProcessor):
|
|
|
826
822
|
if end_msg_obj: yield format_for_yield(end_msg_obj)
|
|
827
823
|
except Exception as final_e:
|
|
828
824
|
logging.error(f"Error in finally block: {str(final_e)}", exc_info=True)
|
|
829
|
-
self.
|
|
825
|
+
langfuse.create_event(trace_context=self.trace_context, name="error_in_finally_block", level="ERROR",
|
|
830
826
|
status_message=(f"Error in finally block: {str(final_e)}"))
|