This is an automated email from the ASF dual-hosted git repository. wu-sheng pushed a commit to branch feat/ai-history-and-enhancement in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git
commit 609f439b4eb7a8311f01cf2381b5d64d7eb809df Author: Wu Sheng <[email protected]> AuthorDate: Wed Jul 8 18:41:07 2026 +0800 docs(ai): changelog + skills contract for triage capture-replay & replay badge Record the operator-visible triage capture-replay (traces/zipkin/logs/browser freeze + replay offline, per-flavor caps) and the shared replay badge across all captured blocks. Refresh the AI resources/CLAUDE.md static-reload contract: render replay data LOCALLY (never vue-query initialData — it leaks into live views), the four list blocks + profiling now covered, the trace caps, and that every AI data block is an always-replay snapshot. --- CHANGELOG.md | 2 ++ apps/bff/src/ai/resources/CLAUDE.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b66da5e..347ebe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ The version line is shared by every package in the monorepo (apps + shared packa - **Your question stays in view while the answer streams.** The message you just sent pins to the top of the chat and stays there as a sticky header — while its answer streams in and as you scroll through it — so you never lose sight of what you asked; opening or switching to a past conversation pins that chat's last question the same way. Each turn now carries a timestamp: when you sent the question, and when its answer finished. - **The assistant orients on a layer's template before reading it — so it answers in the layer's own terms.** A new capability lookup surfaces, per layer: what a Service / Instance / Endpoint is CALLED there (a K8S_SERVICE instance is a Pod, a mesh instance a Sidecar, a K8S service a Cluster), which components the layer carries, whether its traces are native or Zipkin (so the assistant picks the right trace tool instead of guessing from the layer name), and each relationship's metric leg [...] - **Embedded maps are captured evidence now — they replay exactly on reload, offline, with their edge sparklines.** When the assistant draws a **topology**, **deployment**, **instance map**, **API-dependency chain** or **cross-layer hierarchy**, it now captures the whole graph the moment it reads it — every node and edge WITH its metric values and the per-edge trend series — and the chat block carries that snapshot. So reopening the conversation later re-renders the identical point-in-ti [...] +- **Embedded traces, logs and browser errors are captured evidence too — the list AND its detail replay offline on reload.** When the assistant shows a service's **traces**, **Zipkin traces**, **logs** or **browser errors**, it now freezes the list the moment it reads it and the chat block carries that snapshot — so reopening the conversation replays the exact same rows (each stamped **"captured <time>"**) with no fresh query, and clicking a row opens its detail (the span **waterfa [...] +- **Every captured block now wears a replay badge.** Each frozen point-in-time block — figures, maps, the profiling flame, traces/logs/browser errors, and pod logs — carries a small **replay icon** next to its "captured <time>" stamp, so it's unmistakable at a glance that you're looking at a snapshot the assistant took, not live data. Because the assistant captures every answer's data server-side and feeds the UI that snapshot, these blocks are *always* replaying — the badge shows [...] - **A charted metric is the real dashboard widget — with its explanation, exact MQE and capture time.** When the assistant shows a metric from a layer's catalog it now renders that dashboard widget directly, carrying its full configuration (unit, number formatting, value thresholds and legends) instead of a rebuilt approximation — so the chart in the chat matches the dashboard exactly. Each figure documents what it is: the metric's plain-language explanation, the precise MQE expression t [...] - **Conversation history now persists per user in your browser, with controls.** Past chats move to the browser's IndexedDB — far larger than before, so long conversations with embedded charts survive — and are scoped to your username, so a shared browser keeps each person's history separate. A **Save history** toggle (on by default) turns persistence off entirely; a usage meter shows how much of the client budget (default 500 MB, `HORIZON_AI_HISTORY_MAX_MB`) is in use; **Clear all** (wi [...] diff --git a/apps/bff/src/ai/resources/CLAUDE.md b/apps/bff/src/ai/resources/CLAUDE.md index 3feebf0..57dbbf2 100644 --- a/apps/bff/src/ai/resources/CLAUDE.md +++ b/apps/bff/src/ai/resources/CLAUDE.md @@ -55,7 +55,7 @@ The metric-vs-record and sampled-vs-topN split is IMPLICIT in the type + the out A persisted conversation must re-render on reload from what was captured — not a fresh live query. Because the components above are code-STATIC, a reloaded block seeds the SAME renderer with the captured (template/OAP-resolved) data and draws identically. So: rich reads capture the WHOLE component response (nodes+edges WITH metrics), and static-reload seeds the real view from it — never a bespoke second renderer. Any new component/tool must be seedable the same way (its data-in path take [...] -This is IMPLEMENTED for figures AND all five MAP components under ONE consistent vocabulary: **`replay` (boolean) + `replayData` (the captured payload) + `capturedAt`**, and every disabled/gated thing is gated by `replay`. The five map tools resolve the full `*Response` through a shared `logic/oap/` builder (the same fan-out the layer route uses) and attach it as `spec.replayData`; the chat block mounts the embedded `Layer*View` with `replay=true`, and in replay mode the view renders fro [...] +This is IMPLEMENTED for figures, all five MAP components, the profiling-result flame, AND the four triage LIST blocks (traces / zipkin-traces / logs / browser-errors) under ONE consistent vocabulary: **`replay` (boolean) + `replayData` (the captured payload) + `capturedAt`**, and every disabled/gated thing is gated by `replay`. Each tool resolves the full `*Response` and attaches it as `spec.replayData`; the chat block mounts the embedded `Layer*View` with `replay=true`, and in replay mo [...] ## Maintaining the skills
