"""把 predictions.steps_json 转成 RunLog.get_traces 的行形。

infer_adhoc 的 traces 表为空，轨迹存于 steps_json（{thought, tool_call, tool_output}）。
诊断管线经 get_traces 消费轨迹，故需此确定性转换适配。
"""

from __future__ import annotations

import json
from typing import Any


def steps_json_to_trace_rows(
    video_id: str, question_id: str, steps_json: str
) -> list[dict[str, Any]]:
    """将单题 steps_json 解析为 trace 行列表（step 从 0 递增）。

    参数:
        video_id: 视频 ID。
        question_id: 题 ID。
        steps_json: predictions.steps_json 原文（JSON 数组字符串）。

    返回:
        行字典列表，字段对齐 traces 表 schema；空/空数组返回 []。

    关键实现细节:
        - 工具名读 tool_call.tool（infer_adhoc 真实字段），对极少数历史
          数据的 name 做 back-compat 回退。
        - steps_json 非 JSON 数组时直接报错，不做兜底掩盖。
    """
    if not steps_json or not steps_json.strip():
        return []
    steps = json.loads(steps_json)
    if not isinstance(steps, list):
        raise ValueError(f"steps_json 非数组: {question_id}")
    rows: list[dict[str, Any]] = []
    for i, s in enumerate(steps):
        call = s.get("tool_call") or {}
        rows.append(
            {
                "video_id": video_id,
                "question_id": question_id,
                "step": i,
                # infer_adhoc 用 "tool"；back-compat 兼容极少数 "name"
                "tool_name": call.get("tool", call.get("name")),
                "tool_args": call.get("args", {}),
                "tool_output": s.get("tool_output"),
                "thought": s.get("thought"),
            }
        )
    return rows
