feat: add CLI Apps settings MVP
This commit is contained in:
@@ -116,6 +116,55 @@ def tool_trace_lines_from_events(events: Any) -> list[str]:
|
||||
return lines
|
||||
|
||||
|
||||
_PHASE_RANK = {"start": 1, "end": 2, "error": 3}
|
||||
|
||||
|
||||
def _normalize_tool_events(events: Any) -> list[dict[str, Any]]:
|
||||
if not isinstance(events, list):
|
||||
return []
|
||||
out: list[dict[str, Any]] = []
|
||||
for event in events:
|
||||
if not event or not isinstance(event, dict):
|
||||
continue
|
||||
if event.get("phase") not in {"start", "end", "error"}:
|
||||
continue
|
||||
if not isinstance(event.get("name"), str):
|
||||
fn = event.get("function")
|
||||
if not (isinstance(fn, dict) and isinstance(fn.get("name"), str)):
|
||||
continue
|
||||
out.append(dict(event))
|
||||
return out
|
||||
|
||||
|
||||
def _tool_event_key(event: dict[str, Any]) -> str:
|
||||
call_id = event.get("call_id")
|
||||
if isinstance(call_id, str) and call_id:
|
||||
return f"call:{call_id}"
|
||||
return _format_tool_call_trace(event) or json.dumps(event, sort_keys=True, ensure_ascii=False)
|
||||
|
||||
|
||||
def _merge_tool_events(previous: Any, incoming: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
if not isinstance(previous, list) or not previous:
|
||||
return incoming
|
||||
if not incoming:
|
||||
return [dict(event) for event in previous if isinstance(event, dict)]
|
||||
merged = [dict(event) for event in previous if isinstance(event, dict)]
|
||||
index_by_key = {_tool_event_key(event): idx for idx, event in enumerate(merged)}
|
||||
for event in incoming:
|
||||
key = _tool_event_key(event)
|
||||
existing_index = index_by_key.get(key)
|
||||
if existing_index is None:
|
||||
index_by_key[key] = len(merged)
|
||||
merged.append(event)
|
||||
continue
|
||||
existing = merged[existing_index]
|
||||
incoming_rank = _PHASE_RANK.get(str(event.get("phase")), 0)
|
||||
existing_rank = _PHASE_RANK.get(str(existing.get("phase")), 0)
|
||||
if incoming_rank >= existing_rank:
|
||||
merged[existing_index] = {**existing, **event}
|
||||
return merged
|
||||
|
||||
|
||||
def _merge_unique_tool_trace_lines(
|
||||
previous_traces: list[str],
|
||||
lines: list[str],
|
||||
@@ -405,6 +454,9 @@ def replay_transcript_to_ui_messages(
|
||||
row["media"] = media_att
|
||||
if all(m.get("kind") == "image" for m in media_att):
|
||||
row["images"] = [{"url": m.get("url"), "name": m.get("name")} for m in media_att]
|
||||
cli_apps = rec.get("cli_apps")
|
||||
if isinstance(cli_apps, list) and cli_apps:
|
||||
row["cliApps"] = [dict(app) for app in cli_apps if isinstance(app, dict)]
|
||||
messages.append(row)
|
||||
continue
|
||||
|
||||
@@ -486,6 +538,7 @@ def replay_transcript_to_ui_messages(
|
||||
close_reasoning(messages)
|
||||
continue
|
||||
if kind in ("tool_hint", "progress"):
|
||||
structured_events = _normalize_tool_events(rec.get("tool_events"))
|
||||
structured = tool_trace_lines_from_events(rec.get("tool_events"))
|
||||
text = rec.get("text")
|
||||
trace_lines = structured if structured else ([text] if isinstance(text, str) and text else [])
|
||||
@@ -502,7 +555,7 @@ def replay_transcript_to_ui_messages(
|
||||
prev_traces = list(last.get("traces") or [last.get("content")])
|
||||
if structured:
|
||||
merged_traces, added = _merge_unique_tool_trace_lines(prev_traces, structured)
|
||||
if not added:
|
||||
if not added and not structured_events:
|
||||
continue
|
||||
else:
|
||||
merged_traces = prev_traces + trace_lines
|
||||
@@ -510,6 +563,9 @@ def replay_transcript_to_ui_messages(
|
||||
**last,
|
||||
"traces": merged_traces,
|
||||
"content": merged_traces[-1],
|
||||
"toolEvents": _merge_tool_events(last.get("toolEvents"), structured_events)
|
||||
if structured_events
|
||||
else last.get("toolEvents"),
|
||||
"activitySegmentId": last.get("activitySegmentId") or segment,
|
||||
}
|
||||
messages[-1] = merged
|
||||
@@ -521,6 +577,7 @@ def replay_transcript_to_ui_messages(
|
||||
"kind": "trace",
|
||||
"content": trace_lines[-1],
|
||||
"traces": trace_lines,
|
||||
**({"toolEvents": structured_events} if structured_events else {}),
|
||||
"activitySegmentId": segment,
|
||||
"createdAt": _ts_base + idx,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user