Merge pull request #625 from pikasTech/fix-v02-device-pod-ui
fix: 修复 v0.2 Device Pod 右栏与助手消息
This commit is contained in:
@@ -332,7 +332,7 @@ function normalizeTraceEvent(event, { traceId, seq, now, fallbackRunnerKind } =
|
||||
stdoutSummary: safeText(event.stdoutSummary, 600),
|
||||
stderrSummary: safeText(event.stderrSummary, 600),
|
||||
chunk: safeText(event.chunk, 400),
|
||||
message: safeText(event.message, 500),
|
||||
message: safeText(event.message, 1200),
|
||||
errorCode: safeText(event.errorCode, 120),
|
||||
waitingFor: safeText(event.waitingFor, 220),
|
||||
timeoutMs: typeof event.timeoutMs === "number" ? Math.trunc(event.timeoutMs) : undefined,
|
||||
|
||||
@@ -161,11 +161,14 @@ export function createAppServerTurnState({ traceRecorder, session } = {}) {
|
||||
return;
|
||||
}
|
||||
if (method === "item/completed" && item?.type === "agentMessage") {
|
||||
if (typeof item.text === "string") finalResponse = item.text;
|
||||
const completedText = typeof item.text === "string" ? item.text : "";
|
||||
if (completedText) finalResponse = completedText;
|
||||
appendTrace({
|
||||
type: "assistant_message",
|
||||
status: "completed",
|
||||
label: "assistant:item_completed",
|
||||
itemId: optionalId(item.id),
|
||||
message: redactText(completedText),
|
||||
sessionId: session?.sessionId,
|
||||
sessionStatus: session?.status,
|
||||
turn: session?.turn,
|
||||
|
||||
@@ -32,6 +32,41 @@ test("trace display rows render completion when no terminal assistant event exis
|
||||
assert.equal(rows.some((row) => /轮次完成/u.test(row.header)), true);
|
||||
});
|
||||
|
||||
test("trace display rows render assistant item text when stream snapshot is absent", () => {
|
||||
const events = [
|
||||
event(1, "request:accepted", { promptSummary: "请列出 device-pod" }),
|
||||
event(2, "assistant:item_completed", {
|
||||
type: "assistant_message",
|
||||
status: "completed",
|
||||
itemId: "msg_item_0",
|
||||
message: "当前有以下 **5 个 device-pod** 可用。"
|
||||
}),
|
||||
commandEvent(3, "item/commandExecution:completed", {
|
||||
itemId: "cmd-trace-2",
|
||||
command: "grep -rn device-pod /workspace/hwlab",
|
||||
status: "completed",
|
||||
exitCode: 0,
|
||||
stdoutSummary: "success=true"
|
||||
}),
|
||||
event(4, "assistant:completed", {
|
||||
type: "assistant_message",
|
||||
terminal: true,
|
||||
status: "completed",
|
||||
itemId: "assistant-final",
|
||||
message: "可以继续指定要操作的 device-pod。"
|
||||
})
|
||||
];
|
||||
|
||||
const rows = traceDisplayRows({ traceId: "trc_assistant_item_text", events }, events);
|
||||
const text = rows.map((row) => `${row.header}\n${row.body ?? ""}`).join("\n---\n");
|
||||
|
||||
assert.match(text, /🤖 助手消息(第一条)/u);
|
||||
assert.match(text, /当前有以下 \*\*5 个 device-pod\*\* 可用/u);
|
||||
assert.match(text, /工具调用/u);
|
||||
assert.match(text, /助手最后一条消息/u);
|
||||
assert.match(text, /可以继续指定要操作的 device-pod/u);
|
||||
});
|
||||
|
||||
function traceEvents() {
|
||||
return [
|
||||
event(1, "request:accepted", { promptSummary: "请检查 trace" }),
|
||||
|
||||
@@ -314,10 +314,6 @@
|
||||
<pre id="device-event-text">等待 /v1/device-pods 事件流。</pre>
|
||||
</div>
|
||||
</section>
|
||||
<div class="readonly-rpc sidebar-note">
|
||||
<h3>复核入口</h3>
|
||||
<p class="panel-copy">技术复核保留在二级页面;默认右栏只显示 Device Pod 摘要和纯文本事件流。</p>
|
||||
</div>
|
||||
</section>
|
||||
<dialog class="device-detail-dialog" id="device-detail-dialog" aria-labelledby="device-detail-title">
|
||||
<form method="dialog" class="device-detail-shell">
|
||||
|
||||
@@ -82,9 +82,12 @@ for (const term of [
|
||||
}
|
||||
|
||||
assert.doesNotMatch(rightSidebar, /<details\b/iu, "right sidebar must not use internal expand/collapse details");
|
||||
assert.doesNotMatch(rightSidebar, /readonly-rpc|复核入口/iu, "right sidebar must not render the readonly RPC review note");
|
||||
assert.doesNotMatch(rightSidebar, /data-hardware-tab|m3-control|hardware-list|wiring-body|records-list/iu, "right sidebar must not keep legacy hardware panels");
|
||||
assert.match(rightSidebar, /class="summary-tile"[^>]*role="button"[^>]*tabindex="0"/u, "Pod summary is a click/keyboard summary tile");
|
||||
assert.match(rightSidebar, /<dialog\b[\s\S]*id="device-detail-dialog"/u, "summary details must open in a dialog");
|
||||
assert.match(cssRule(styles, ".right-sidebar"), /grid-auto-rows:\s*max-content;/u, "right sidebar rows must keep Device Pod workspace from being squeezed by the status area");
|
||||
assert.doesNotMatch(cssRule(styles, ".device-pod-workspace"), /minmax\(180px,\s*1fr\)/u, "Device Pod workspace must not use a 1fr event row inside the sidebar scroll column");
|
||||
|
||||
for (const selector of [
|
||||
".device-pod-status",
|
||||
@@ -265,6 +268,14 @@ function sectionById(source, tagName, id) {
|
||||
return source.slice(start);
|
||||
}
|
||||
|
||||
function cssRule(source, selector) {
|
||||
const match = new RegExp(`${escapeRegExp(selector)}\\s*\\{`, "u").exec(source);
|
||||
if (!match) return "";
|
||||
const bodyStart = match.index + match[0].length;
|
||||
const bodyEnd = source.indexOf("}", bodyStart);
|
||||
return bodyEnd >= 0 ? source.slice(match.index, bodyEnd + 1) : source.slice(match.index);
|
||||
}
|
||||
|
||||
function functionBody(source, name) {
|
||||
const match = new RegExp(`function\\s+${escapeRegExp(name)}\\s*\\([^)]*\\)\\s*\\{`, "u").exec(source);
|
||||
if (!match) return "";
|
||||
|
||||
@@ -1797,7 +1797,7 @@ h3 {
|
||||
.right-sidebar {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-rows: auto auto auto minmax(0, 1fr);
|
||||
grid-auto-rows: max-content;
|
||||
gap: 8px;
|
||||
padding: 10px 10px 10px 16px;
|
||||
background: rgba(18, 20, 18, 0.98);
|
||||
@@ -2465,7 +2465,7 @@ tbody tr:last-child td {
|
||||
}
|
||||
|
||||
.device-pod-workspace {
|
||||
grid-template-rows: auto minmax(180px, 1fr) auto;
|
||||
grid-template-rows: auto auto;
|
||||
}
|
||||
|
||||
.device-pod-selector-row {
|
||||
@@ -2567,9 +2567,9 @@ tbody tr:last-child td {
|
||||
|
||||
.device-event-panel {
|
||||
min-width: 0;
|
||||
min-height: 180px;
|
||||
min-height: 240px;
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
grid-template-rows: auto minmax(180px, 1fr);
|
||||
border: 1px solid var(--line);
|
||||
background: #101310;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user