52 lines
1.9 KiB
Python
52 lines
1.9 KiB
Python
"""Gateway 执行与本地 Agent Run 持久化之间的编排服务。"""
|
|
|
|
import logging
|
|
|
|
from common.logging import sanitize_summary
|
|
|
|
from .gateway import AgentExecutionRequest, AgentRunnerGateway
|
|
from .models import AgentRun, RunStatus
|
|
from .services import transition_run
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def execute_run(run_id, gateway: AgentRunnerGateway) -> AgentRun:
|
|
"""使用注入的 Gateway 驱动一次运行,并确保所有结果都进入稳定终态。
|
|
|
|
外部调用发生在两个短事务之间:开始状态先提交,Gateway 返回或抛错后再用
|
|
独立事务保存成功或失败结果。该函数不重试,避免第一阶段产生重复外部副作用。
|
|
"""
|
|
|
|
running = transition_run(run_id, RunStatus.RUNNING)
|
|
request = AgentExecutionRequest(
|
|
agent_run_id=str(running.id),
|
|
user_id=running.owner_id,
|
|
input_summary=sanitize_summary(running.input_summary),
|
|
)
|
|
try:
|
|
result = gateway.run(request)
|
|
except Exception as exc: # Gateway 是外部边界,必须把未知异常转换为可审计失败。
|
|
# 外部异常消息可能夹带请求参数或认证信息,因此日志和数据库只保留异常类型。
|
|
error_type = type(exc).__name__
|
|
logger.error(
|
|
"Agent Gateway 执行异常,异常类型=%s",
|
|
error_type,
|
|
extra={"agent_run_id": str(running.id)},
|
|
)
|
|
return transition_run(
|
|
running.id,
|
|
RunStatus.FAILED,
|
|
error_code="gateway_error",
|
|
error_summary=f"Agent Gateway 执行异常:{error_type}",
|
|
)
|
|
|
|
if result.succeeded:
|
|
return transition_run(running.id, RunStatus.SUCCEEDED, output=result.output_summary)
|
|
return transition_run(
|
|
running.id,
|
|
RunStatus.FAILED,
|
|
error_code=result.error_code or "agent_failed",
|
|
error_summary=result.error_summary,
|
|
)
|