Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

139 lines
5.0 KiB
Python

from __future__ import annotations
from typing import Any
from rich.text import Text
from platform.observability.trace.redaction import format_json_preview
from platform.terminal.theme import BRAND, DIM, HIGHLIGHT, SECONDARY, TEXT
from surfaces.interactive_shell.ui.components.time_format import _elapsed_hms, _fmt_timing
from surfaces.shared.tool_labels import tool_short_label, tool_source_label
__all__ = [
"build_live_tool_detail_rows",
"build_tool_call_line",
"build_tool_detail_text",
"format_tool_summary",
"make_tool_detail_record",
"record_tool_summary",
"tool_detail_body",
"tool_short_label",
"tool_source_label",
]
def record_tool_summary(
tool_name: str,
summary_counts: dict[str, dict[str, int]],
summary_order: list[tuple[str, str]],
) -> None:
source = tool_source_label(tool_name)
label = tool_short_label(tool_name, source)
source_counts = summary_counts.setdefault(source, {})
if label not in source_counts:
summary_order.append((source, label))
source_counts[label] = source_counts.get(label, 0) + 1
def format_tool_summary(
summary_counts: dict[str, dict[str, int]],
summary_order: list[tuple[str, str]],
) -> str:
source_labels: dict[str, list[str]] = {}
for source, label in summary_order:
count = summary_counts.get(source, {}).get(label, 0)
if count <= 0:
continue
rendered = f"{label} x{count}" if count > 1 else label
source_labels.setdefault(source, []).append(rendered)
parts = [
f"{source}: {', '.join(labels[:4])}{', ...' if len(labels) > 4 else ''}"
for source, labels in source_labels.items()
]
summary = " | ".join(parts[:2])
return summary[:117] + "..." if len(summary) > 120 else summary
def build_tool_call_line(tool_name: str, elapsed_ms: int, elapsed_total: float) -> Text:
source = tool_source_label(tool_name)
label = tool_short_label(tool_name, source)
call_display = f"{source} · {label}" if label else source
t = Text()
t.append(f"{_elapsed_hms(elapsed_total)} ", style=SECONDARY)
t.append(" ↳ ", style=DIM)
t.append(call_display, style=BRAND)
t.append(f" {_fmt_timing(elapsed_ms)}", style=SECONDARY)
return t
def make_tool_detail_record(
display: str,
tool_input: Any,
output: Any,
*,
elapsed: str = "",
) -> dict[str, Any] | None:
if tool_input in ({}, None) and output in ({}, None, ""):
return None
return {"display": display, "input": tool_input, "output": output, "elapsed": elapsed}
def build_tool_detail_text(record: dict[str, Any]) -> Text:
display = str(record.get("display") or "tool")
elapsed = str(record.get("elapsed") or "")
suffix = f" {elapsed}" if elapsed else ""
detail = Text()
detail.append(f" Tool details: {display}{suffix}\n", style=f"bold {TEXT}")
for line in tool_detail_body(record).splitlines():
detail.append(f" {line}\n", style=DIM)
return detail
def tool_detail_body(record: dict[str, Any]) -> str:
body_parts: list[str] = []
if (tool_input := record.get("input")) not in ({}, None):
body_parts.append(f"Input:\n{format_json_preview(tool_input, max_chars=1600)}")
if (output := record.get("output")) not in ({}, None, ""):
body_parts.append(f"Output:\n{format_json_preview(output, max_chars=3000)}")
return "\n\n".join(body_parts)
def build_live_tool_detail_rows(
records: list[dict[str, Any]], max_width: int, now: float
) -> list[Text]:
rows: list[Text] = []
rows.append(Text(" Tool Details", style=f"bold {TEXT}"))
hidden_count = max(0, len(records) - 6)
if hidden_count:
rows.append(Text(f" {hidden_count} older tool call(s) hidden", style=DIM))
if not records:
rows.append(Text(" No tool calls have finished yet.", style=DIM))
for record in records[-6:]:
elapsed = str(record.get("elapsed") or "")
suffix = f" {elapsed}" if elapsed else ""
row = Text()
row.append(" ● ", style=f"bold {HIGHLIGHT}")
row.append(str(record.get("display") or "tool"), style=f"bold {TEXT}")
row.append(suffix, style=SECONDARY)
rows.extend([row, *_detail_preview_rows(record), Text("")])
rows.append(Text("┄" * (max_width - 1), style=DIM))
rows.append(Text(f" ● TOOL DETAILS {_elapsed_hms(now)}", style=SECONDARY))
return rows
def _detail_preview_rows(record: dict[str, Any]) -> list[Text]:
rows: list[Text] = []
if (tool_input := record.get("input")) not in ({}, None):
rows.append(Text(" Input:", style=SECONDARY))
rows.extend(
Text(f" {line}", style=DIM)
for line in format_json_preview(tool_input, max_chars=1200).splitlines()
)
if (output := record.get("output")) not in ({}, None, ""):
rows.append(Text(" Output:", style=SECONDARY))
rows.extend(
Text(f" {line}", style=DIM)
for line in format_json_preview(output, max_chars=2200).splitlines()
)
return rows