redbotu 5021c8c2ea feat: 补齐任务执行指标与结构化结果摘要
- 补齐 tool_call 和 edge 验证链路的 duration_ms 计算与返回
- 任务详情和任务报告新增 result_summary_detail 结构化摘要
- 摘要中补充最终状态、失败原因、software-a 摘要、审批摘要、验证摘要
- 软件A层术语统一为“最小能力实现”
- 同步更新 README、当前进度总结和相关设计文档
- 补充并通过对应自动化测试
2026-04-08 22:35:25 +08:00

43 lines
1.2 KiB
Python

from __future__ import annotations
from datetime import UTC, datetime, timedelta, timezone
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f"
def resolve_timezone(timezone_name: str):
try:
return ZoneInfo(timezone_name)
except ZoneInfoNotFoundError:
fallback_mapping = {
"Asia/Shanghai": timezone(timedelta(hours=8)),
"Asia/Hong_Kong": timezone(timedelta(hours=8)),
"UTC": UTC,
}
return fallback_mapping.get(timezone_name, UTC)
def format_now(timezone_name: str) -> str:
current = datetime.now(resolve_timezone(timezone_name))
return current.strftime(TIME_FORMAT)[:-3]
def parse_timestamp(value: str | None) -> datetime | None:
if not value:
return None
try:
return datetime.strptime(value, TIME_FORMAT)
except ValueError:
return None
def compute_duration_ms(started_at: str | None, finished_at: str | None) -> int | None:
started = parse_timestamp(started_at)
finished = parse_timestamp(finished_at)
if not started or not finished:
return None
duration_ms = int((finished - started).total_seconds() * 1000)
return max(duration_ms, 0)