Stabilize product data export flow

This commit is contained in:
wuyang6
2026-05-11 11:46:09 +08:00
parent 1752c81913
commit 0e2a00990f
19 changed files with 659 additions and 31 deletions
+48 -3
View File
@@ -832,8 +832,15 @@ class LocalCodingAgent:
return result
# fall through to the normal tool-call branch below
# normal error path if not recovered
final_output = str(exc)
session.append_assistant(
final_output,
message_id=f'assistant_{len(session.messages)}',
stop_reason='backend_error',
)
_append_final_text_stream_events(stream_events, final_output)
result = AgentRunResult(
final_output=str(exc),
final_output=final_output,
turns=max(turn_index - 1, 0),
tool_calls=tool_calls,
transcript=session.transcript(),
@@ -1535,15 +1542,42 @@ class LocalCodingAgent:
usage=usage,
)
assistant_message = session.messages[assistant_index]
try:
parsed_tool_calls = self._tool_calls_from_message(assistant_message.tool_calls)
except OpenAICompatError:
self._scrub_malformed_assistant_tool_calls(session, assistant_index)
raise
turn = AssistantTurn(
content=assistant_message.content,
tool_calls=self._tool_calls_from_message(assistant_message.tool_calls),
tool_calls=parsed_tool_calls,
finish_reason=finish_reason,
raw_message=assistant_message.to_openai_message(),
usage=usage,
)
return turn, tuple(events)
def _scrub_malformed_assistant_tool_calls(
self,
session: AgentSessionState,
assistant_index: int,
) -> None:
message = session.messages[assistant_index]
filtered_blocks = tuple(
block
for block in message.blocks
if block.get('type') not in {'tool_use', 'tool_call'}
)
session.messages[assistant_index] = replace(
message,
tool_calls=(),
blocks=filtered_blocks,
stop_reason='malformed_tool_arguments',
metadata={
**message.metadata,
'malformed_tool_arguments': True,
},
)
def _tool_calls_from_message(
self,
tool_calls: tuple[dict[str, object], ...],
@@ -1558,7 +1592,18 @@ class LocalCodingAgent:
continue
raw_arguments = function_block.get('arguments', '')
if isinstance(raw_arguments, str) and raw_arguments.strip():
arguments = json.loads(raw_arguments)
try:
arguments = json.loads(raw_arguments)
except json.JSONDecodeError as exc:
preview = raw_arguments[:240].replace('\n', '\\n')
raise OpenAICompatError(
'模型返回的工具参数不是合法 JSON,已停止本轮以避免执行错误工具。'
f'工具:{name};位置:line {exc.lineno} column {exc.colno}'
f'原因:{exc.msg};参数片段:{preview!r}'
'请回复“继续”,我会要求模型重新生成合法 JSON 参数;'
'对于大段 dataset draft,应分批或使用 draft_path/records_path'
'不要把大量带引号的文本一次性塞进工具参数。'
) from exc
if not isinstance(arguments, dict):
raise OpenAICompatError(
f'Tool arguments must decode to an object, got {type(arguments).__name__}'