You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/09/17 01:44:49 UTC
(skywalking-ai-sessionizer) 01/01: Draw a compaction as a compaction in asz view
This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch horizon-compaction-wording
in repository https://gitbox.apache.org/repos/asf/skywalking-ai-sessionizer.git
commit fea9a9d2d42f50ed4a041614251923fbd66facd8
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Thu Sep 17 09:44:38 2026 +0800
Draw a compaction as a compaction in asz view
The embedded renderer moves to Horizon 53c1f63b (#166). The one before it
compared a message of one text block as two different messages depending on
whether it was the newest, since the runtime sends it as a list while it is and
as a plain string after. So it reported an ordinary growth step as a rewritten
history: on one real 94-call conversation, 60 of 62 of them.
The prompt tab now reads both spellings as one message, and says which of two
things happened when the history does change: the context was replaced by a
summary, with how many messages became how many, or, when the history changed
without getting shorter, a warning.
asz view and the SkyWalking UI draw a conversation from the same renderer, so
this keeps the page beside the storage root from warning where the UI does not.
---
internal/view/conversation-view/HORIZON_COMMIT | 2 +-
.../view/conversation-view/conversation-view.js | 24 +++++++++++++++++-----
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/internal/view/conversation-view/HORIZON_COMMIT b/internal/view/conversation-view/HORIZON_COMMIT
index 0fdf6e2..59fd670 100644
--- a/internal/view/conversation-view/HORIZON_COMMIT
+++ b/internal/view/conversation-view/HORIZON_COMMIT
@@ -1,3 +1,3 @@
-commit 0ce1f8d6a8484b127abf83897b0aa4f5f567f363
+commit 53c1f63b635bc8efbaec0e4bc28ec9539e526328
package @skywalking-horizon-ui/conversation-view 1.1.0-dev
source https://github.com/apache/skywalking-horizon-ui.git
diff --git a/internal/view/conversation-view/conversation-view.js b/internal/view/conversation-view/conversation-view.js
index 05efc8e..c91d01a 100644
--- a/internal/view/conversation-view/conversation-view.js
+++ b/internal/view/conversation-view/conversation-view.js
@@ -1187,7 +1187,8 @@ const ENGLISH = {
promptSettings: "Settings",
promptBlocks: "{count} block(s), {bytes} bytes",
promptShared: "The {count} message(s) before are as the call before sent them, {bytes} bytes.",
- promptRewritten: "The history was rewritten, which is what a compaction does.",
+ promptRewritten: "The history before this point was rewritten, and not by a compaction.",
+ promptCompacted: "The context was replaced by a summary here, so the list starts again: {before} message(s) became {after}.",
promptAlsoChanged: "Also changed: {what}.",
promptAdded: "Added by this call ({count})",
promptNothingAdded: "This request adds no message.",
@@ -1835,6 +1836,7 @@ function deltaOf(previous, current) {
const least = Math.min(previous.messages.length, current.messages.length);
while (shared < least && same(previous.messages[shared].raw, current.messages[shared].raw, MARKED_IN_MESSAGE)) shared++;
if (shared < least) rewritten = true;
+ const replaced = rewritten && current.messages.length < previous.messages.length;
const added = current.messages.slice(shared);
let sharedBytes = 0;
for (let i = 0; i < shared; i++) sharedBytes += size(current.messages[i].raw);
@@ -1843,6 +1845,7 @@ function deltaOf(previous, current) {
sharedMessages: shared,
sharedBytes,
rewritten,
+ replaced,
systemChanged: !same(previous.raw["system"], current.raw["system"], MARKED_IN_LIST),
toolsChanged: !same(previous.raw["tools"], current.raw["tools"], MARKED_IN_LIST),
settingsChanged: !same(settings(previous), settings(current), NOT_MARKED)
@@ -1866,10 +1869,18 @@ function canonical(value, markedTo, depth = 0) {
const parts = [];
for (const k of Object.keys(obj).sort()) {
if (depth <= markedTo && k === "cache_control") continue;
- parts.push(`${JSON.stringify(k)}:${canonical(obj[k], markedTo, depth + 1)}`);
+ const v = k === "content" && depth < markedTo ? plainContent(obj[k]) : obj[k];
+ parts.push(`${JSON.stringify(k)}:${canonical(v, markedTo, depth + 1)}`);
}
return `{${parts.join(",")}}`;
}
+function plainContent(content) {
+ if (typeof content === "string") return [{ type: "text", text: content }];
+ if (!Array.isArray(content) || content.length !== 1) return content;
+ const only = content[0];
+ if (!only || typeof only !== "object" || only["type"] !== "text" || typeof only["text"] !== "string") return content;
+ return [{ type: "text", text: only["text"] }];
+}
const LINE_DIFF_CAP = 400;
function lineDiff(before, after) {
const a = before.split("\n");
@@ -2277,7 +2288,7 @@ function drawRequest(ctx, e, read2, sides, store) {
</div>`;
if (!state.promptWhole) {
if (!previous) return `${modes}<div class="acv-empty">${esc(s.promptNoPrevious)}</div>`;
- return `${modes}${drawDelta(ctx, e, deltaOf(previous, read2), read2)}`;
+ return `${modes}${drawDelta(ctx, e, deltaOf(previous, read2), read2, previous.messages.length)}`;
}
const system = read2.system.length ? section(ctx, e, "system", s.promptSystem, blockSummary(ctx, read2.system), read2.system.map((b, i) => block(ctx, b, `${e.id}|req|sys|${i}`)).join("")) : "";
const tools = read2.tools.length ? section(
@@ -2324,7 +2335,7 @@ function previousRequest(ctx, e, sides, store) {
}
return null;
}
-function drawDelta(ctx, e, delta, read2) {
+function drawDelta(ctx, e, delta, read2, previousCount) {
const { s, f } = ctx;
const changed = [
delta.systemChanged ? s.promptSystem : "",
@@ -2333,7 +2344,10 @@ function drawDelta(ctx, e, delta, read2) {
].filter(Boolean);
const notes = [
`<div class="acv-faint">${esc(fill(s.promptShared, { count: String(delta.sharedMessages), bytes: f.number(delta.sharedBytes) }))}</div>`,
- delta.rewritten ? `<div class="acv-warning">${esc(s.promptRewritten)}</div>` : "",
+ // A compaction is not a fault: it is the runtime replacing the context with a summary, which the
+ // conversation records as its own step. Saying which of the two happened is the whole value of
+ // the note -- a warning on every ordinary growth would say nothing.
+ delta.replaced ? `<div class="acv-faint">${esc(fill(s.promptCompacted, { before: String(previousCount), after: String(read2.messages.length) }))}</div>` : delta.rewritten ? `<div class="acv-warning">${esc(s.promptRewritten)}</div>` : "",
changed.length ? `<div class="acv-faint">${esc(fill(s.promptAlsoChanged, { what: changed.join(", ") }))}</div>` : ""
].join("");
const added = delta.added.length ? delta.added.map((m, i) => message(ctx, m, delta.sharedMessages + i + 1, read2.messages.length, `${e.id}|req|msg|${delta.sharedMessages + i}`)).join("") : `<div class="acv-empty">${esc(s.promptNothingAdded)}</div>`;