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
129 lines
4.0 KiB
Python
129 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from rich.text import Text
|
|
|
|
from platform.terminal.theme import (
|
|
BRAND,
|
|
DIM,
|
|
ERROR,
|
|
HIGHLIGHT,
|
|
SECONDARY,
|
|
TEXT,
|
|
)
|
|
from surfaces.interactive_shell.ui.components.time_format import _elapsed_hms, _fmt_timing
|
|
from tools.registry import resolve_tool_display_name
|
|
|
|
# (padded_label, text_color) -- all labels are 6 chars wide. Every badge draws
|
|
# from the theme's accent tokens (HIGHLIGHT / BRAND) so the whole phase strip
|
|
# stays within the active palette (e.g. all blue shades under the blue theme),
|
|
# alternating the two accents for light per-phase distinction.
|
|
BADGE_STYLES: dict[str, tuple[str, str]] = {
|
|
"READ": ("READ ", HIGHLIGHT),
|
|
"PLAN": ("PLAN ", BRAND),
|
|
"INVEST": ("INVEST", HIGHLIGHT),
|
|
"DIAG": ("DIAG ", BRAND),
|
|
"MERGE": ("MERGE ", HIGHLIGHT),
|
|
}
|
|
|
|
_NODE_EVENT_TYPE: dict[str, str] = {
|
|
"extract_alert": "READ",
|
|
"resolve_integrations": "READ",
|
|
"plan_actions": "PLAN",
|
|
"merge_hypotheses": "MERGE",
|
|
"investigation_agent": "INVEST",
|
|
"diagnose_root_cause": "DIAG",
|
|
"opensre_llm_eval": "DIAG",
|
|
"publish_findings": "DIAG",
|
|
}
|
|
|
|
_NODE_PHASE: dict[str, str] = {
|
|
"extract_alert": "LOAD",
|
|
"resolve_integrations": "LOAD",
|
|
"plan_actions": "PLAN",
|
|
"merge_hypotheses": "DIAGNOSE",
|
|
"investigation_agent": "INVESTIGATE",
|
|
"diagnose_root_cause": "DIAGNOSE",
|
|
"opensre_llm_eval": "DIAGNOSE",
|
|
"publish_findings": "PUBLISH",
|
|
}
|
|
|
|
_NODE_LABELS: dict[str, str] = {
|
|
"extract_alert": "Reading alert",
|
|
"resolve_integrations": "Loading integrations",
|
|
"plan_actions": "Planning",
|
|
"investigate": "Gathering evidence",
|
|
"investigation_agent": "Investigation",
|
|
"diagnose_root_cause": "Diagnosing",
|
|
"publish_findings": "Publishing",
|
|
}
|
|
|
|
|
|
def _node_event_type(node_name: str) -> str:
|
|
if node_name.startswith("investigate"):
|
|
return "INVEST"
|
|
return _NODE_EVENT_TYPE.get(node_name, "DIAG")
|
|
|
|
|
|
def _node_phase_label(node_name: str) -> str:
|
|
if node_name.startswith("investigate"):
|
|
return "INVESTIGATE"
|
|
return _NODE_PHASE.get(node_name, node_name.upper()[:12])
|
|
|
|
|
|
def _node_label(node_name: str) -> str:
|
|
if node_name.startswith("investigate_"):
|
|
action = node_name[len("investigate_") :]
|
|
return f"Investigate · {action.replace('_', ' ').title()}"
|
|
return _NODE_LABELS.get(node_name, node_name.replace("_", " ").title())
|
|
|
|
|
|
def _humanise_message(message: str) -> str:
|
|
if not message:
|
|
return ""
|
|
m = re.match(r"Planned actions:\s*\[(.+)\]", message)
|
|
if m:
|
|
raw = re.findall(r"'([^']+)'", m.group(1))
|
|
return ", ".join(resolve_tool_display_name(action) for action in raw)
|
|
if "No new actions" in message:
|
|
return ""
|
|
if "integrations" in message.lower() or "resolved" in message.lower():
|
|
m2 = re.search(r"\[(.+)\]", message)
|
|
if m2 and (services := re.findall(r"'([^']+)'", m2.group(1))):
|
|
return ", ".join(services)
|
|
m3 = re.match(r"validity:(\d+%)", message)
|
|
if m3:
|
|
return f"confidence {m3.group(1)}"
|
|
return re.sub(r"^datadog:", "", message)
|
|
|
|
|
|
def build_progress_step_text(
|
|
*,
|
|
node_name: str,
|
|
elapsed_total: float,
|
|
elapsed_step_ms: int | None = None,
|
|
status: str = "active",
|
|
message: str | None = None,
|
|
) -> Text:
|
|
ev_type = _node_event_type(node_name)
|
|
badge_label, badge_color = BADGE_STYLES.get(ev_type, BADGE_STYLES["DIAG"])
|
|
label = _node_label(node_name)
|
|
err = status == "error"
|
|
timing = _fmt_timing(elapsed_step_ms) if elapsed_step_ms is not None else ""
|
|
|
|
t = Text()
|
|
t.append(f"{_elapsed_hms(elapsed_total)} ", style=SECONDARY)
|
|
if status == "active":
|
|
t.append("· ", style=SECONDARY)
|
|
else:
|
|
t.append("✗ " if err else "✓ ", style=f"bold {ERROR if err else HIGHLIGHT}")
|
|
t.append(badge_label, style=f"bold {badge_color}")
|
|
t.append(" · ", style=DIM)
|
|
t.append(label, style=f"bold {TEXT}")
|
|
if msg := _humanise_message(message or ""):
|
|
t.append(f" {msg}", style=BRAND)
|
|
if timing:
|
|
t.append(f" {timing}", style=SECONDARY)
|
|
return t
|