Skip to content

Commit 3126aaa

Browse files
committed
feature: 提升codeexcute的执行稳定性
1 parent 1f39974 commit 3126aaa

4 files changed

Lines changed: 18 additions & 29 deletions

File tree

trpc_agent_sdk/agents/_llm_agent.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -517,20 +517,31 @@ def accumulate_content(event: Event) -> None:
517517
if event.is_final_response():
518518
self._save_output_to_state(ctx, event)
519519

520-
# Process code execution responses if code executor is configured
520+
# Process code execution responses if code executor is configured.
521+
# We collect code execution events first (this mutates event.content in place,
522+
# stripping executable_code parts but keeping text/function_call), then yield
523+
# the main event BEFORE the code execution events so the causal order in
524+
# session is preserved: assistant declaration → code execution → result.
525+
pending_code_events: list[Event] = []
521526
if self.code_executor and event.content:
522527
async for code_event in CodeExecutionResponseProcessor.run_async(ctx, event):
523-
# Check if this is a code execution result event
524528
if code_event.content and code_event.content.parts:
525529
for part in code_event.content.parts:
526530
if part.code_execution_result or part.executable_code:
527531
code_was_executed = True
528532
break
529-
yield code_event
530-
531-
# Yield LLM response events directly
532-
yield event
533-
accumulate_content(event)
533+
pending_code_events.append(code_event)
534+
535+
# Yield the main LLM response event first (now stripped of executable_code
536+
# but still carrying text and function_call parts).
537+
# Skip empty events (content became None after all parts were consumed).
538+
if event.content is not None:
539+
yield event
540+
accumulate_content(event)
541+
542+
# Then yield code execution events in order.
543+
for code_event in pending_code_events:
544+
yield code_event
534545
else:
535546
# Yield other events directly
536547
yield event

trpc_agent_sdk/agents/core/_code_execution_processor.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,6 @@ async def _run_post_processor(
249249
return
250250

251251
code_executor_context = CodeExecutorContext(invocation_context.session.state)
252-
if (code_executor.execute_once_per_invocation
253-
and code_executor_context.has_executed_in_invocation(invocation_context.invocation_id)):
254-
return
255-
256252
# Skip if the error count exceeds the max retry attempts.
257253
if code_executor_context.get_error_count(invocation_context.invocation_id) >= code_executor.error_retry_attempts:
258254
return
@@ -285,7 +281,6 @@ async def _run_post_processor(
285281
code_blocks,
286282
code_execution_result,
287283
)
288-
code_executor_context.mark_executed_in_invocation(invocation_context.invocation_id)
289284

290285
# Generate events for code execution results
291286
# Event 1: Code execution event

trpc_agent_sdk/code_executors/_base_code_executor.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,6 @@ class BaseCodeExecutor(BaseModel):
5959
error_retry_attempts: int = 2
6060
"""The number of attempts to retry on consecutive code execution errors. Default to 2."""
6161

62-
execute_once_per_invocation: bool = False
63-
"""Whether to execute model-extracted code at most once per invocation.
64-
65-
When enabled, post-processing code execution runs only for the first
66-
detected code block in a single ``invocation_id`` and skips subsequent
67-
auto-execution attempts for that invocation.
68-
"""
69-
7062
code_block_delimiters: list[CodeBlockDelimiter] = [
7163
CodeBlockDelimiter(start="```tool_code\n", end="\n```"),
7264
CodeBlockDelimiter(start="```python\n", end="\n```"),

trpc_agent_sdk/code_executors/_code_executor_context.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def _ensure_code_execution_state(self) -> None:
3939
"execution_id": None,
4040
"error_counts": {},
4141
"code_execution_results": {},
42-
"executed_invocations": {},
4342
}
4443

4544
def get_input_files(self) -> List[CodeFile]:
@@ -139,14 +138,6 @@ def update_code_execution_result(self, invocation_id: str, code_blocks: List[Cod
139138
code_execution_result.model_dump(),
140139
})
141140

142-
def has_executed_in_invocation(self, invocation_id: str) -> bool:
143-
"""Whether code has already been executed in a given invocation."""
144-
return bool(self.session_state["code_execution"]["executed_invocations"].get(invocation_id, False))
145-
146-
def mark_executed_in_invocation(self, invocation_id: str) -> None:
147-
"""Mark that code execution has happened in a given invocation."""
148-
self.session_state["code_execution"]["executed_invocations"][invocation_id] = True
149-
150141
def get_state_delta(self) -> Dict:
151142
"""Get state delta for the current execution.
152143

0 commit comments

Comments
 (0)