mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:10:44 +00:00
fix(ui): show session runtime in sessions table
This commit is contained in:
@@ -87,6 +87,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Agents/generated media: treat attachment-style message tool actions as completed chat sends, preventing duplicate fallback media posts when generated files were already uploaded.
|
||||
- Control UI/sessions: show each session's agent runtime in the Sessions table and allow filtering by runtime labels, matching the Agents panel runtime wording. Thanks @vincentkoc.
|
||||
- Discord/streaming: show live reasoning text in progress drafts instead of a bare `Reasoning` status line.
|
||||
- Doctor/status: warn when `OPENCLAW_GATEWAY_TOKEN` would shadow a different active `gateway.auth.token` source for local CLI commands, while avoiding false positives when config points at the same env token. Fixes #74271. Thanks @yelog.
|
||||
- Gateway/HTTP: avoid loading managed outgoing-image media handlers for unrelated requests, so disabled OpenAI-compatible routes return 404 without waiting on lazy media sidecars. Thanks @vincentkoc.
|
||||
|
||||
@@ -367,6 +367,41 @@ describe("sessions view", () => {
|
||||
expect(badge?.textContent?.trim()).toBe("cron");
|
||||
});
|
||||
|
||||
it("renders and filters the session runtime", async () => {
|
||||
const container = document.createElement("div");
|
||||
render(
|
||||
renderSessions({
|
||||
...buildProps(
|
||||
buildMultiResult([
|
||||
{
|
||||
key: "agent:main:claude",
|
||||
kind: "direct",
|
||||
updatedAt: 20,
|
||||
agentRuntime: { id: "claude-cli", fallback: "none", source: "agent" },
|
||||
},
|
||||
{
|
||||
key: "agent:main:pi",
|
||||
kind: "direct",
|
||||
updatedAt: 10,
|
||||
agentRuntime: { id: "pi", source: "implicit" },
|
||||
},
|
||||
]),
|
||||
),
|
||||
searchQuery: "fallback none",
|
||||
}),
|
||||
container,
|
||||
);
|
||||
await Promise.resolve();
|
||||
|
||||
expect(
|
||||
Array.from(container.querySelectorAll("thead th")).map((cell) => cell.textContent?.trim()),
|
||||
).toContain("Runtime");
|
||||
expect(container.querySelector(".session-runtime-cell")?.textContent?.trim()).toBe(
|
||||
"claude-cli (fallback none)",
|
||||
);
|
||||
expect(container.textContent).not.toContain("agent:main:pi");
|
||||
});
|
||||
|
||||
it("keeps raw keys for inherited identity object properties", async () => {
|
||||
const container = document.createElement("div");
|
||||
render(
|
||||
|
||||
@@ -13,6 +13,7 @@ import type {
|
||||
SessionCompactionCheckpoint,
|
||||
SessionsListResult,
|
||||
} from "../types.ts";
|
||||
import { resolveAgentRuntimeLabel } from "./agents-utils.ts";
|
||||
|
||||
export type SessionsProps = {
|
||||
loading: boolean;
|
||||
@@ -178,7 +179,14 @@ function filterRows(
|
||||
const label = normalizeLowercaseStringOrEmpty(row.label);
|
||||
const kind = normalizeLowercaseStringOrEmpty(row.kind);
|
||||
const displayName = normalizeLowercaseStringOrEmpty(row.displayName);
|
||||
if (key.includes(q) || label.includes(q) || kind.includes(q) || displayName.includes(q)) {
|
||||
const runtime = normalizeLowercaseStringOrEmpty(resolveAgentRuntimeLabel(row.agentRuntime));
|
||||
if (
|
||||
key.includes(q) ||
|
||||
label.includes(q) ||
|
||||
kind.includes(q) ||
|
||||
displayName.includes(q) ||
|
||||
runtime.includes(q)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
const keyParts = parseSessionKeyParts(row.key);
|
||||
@@ -543,6 +551,7 @@ export function renderSessions(props: SessionsProps) {
|
||||
${sortHeader("key", t("sessionsView.key"), "data-table-key-col")}
|
||||
<th>${t("sessionsView.label")}</th>
|
||||
${sortHeader("kind", t("sessionsView.kind"))}
|
||||
<th>${t("agents.context.runtime")}</th>
|
||||
${sortHeader("updated", t("sessionsView.updated"))}
|
||||
${sortHeader("tokens", t("sessionsView.tokens"))}
|
||||
<th>${t("sessionsView.compaction")}</th>
|
||||
@@ -556,7 +565,7 @@ export function renderSessions(props: SessionsProps) {
|
||||
${paginated.length === 0
|
||||
? html`
|
||||
<tr>
|
||||
<td colspan="11" class="data-table-empty-cell">
|
||||
<td colspan="12" class="data-table-empty-cell">
|
||||
${emptyBecauseFiltered
|
||||
? html`
|
||||
<div class="data-table-empty-state" role="status" aria-live="polite">
|
||||
@@ -748,6 +757,9 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {
|
||||
<td>
|
||||
<span class="data-table-badge ${badgeClass}">${row.kind}</span>
|
||||
</td>
|
||||
<td class="session-runtime-cell">
|
||||
<span class="mono">${resolveAgentRuntimeLabel(row.agentRuntime)}</span>
|
||||
</td>
|
||||
<td>${updated}</td>
|
||||
<td class="session-token-cell">${formatSessionTokens(row)}</td>
|
||||
<td>
|
||||
@@ -858,7 +870,7 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {
|
||||
...(isExpanded && hasCheckpoints
|
||||
? [
|
||||
html`<tr id=${detailsId} class="session-checkpoint-details-row">
|
||||
<td colspan="11" style="padding: 0;">
|
||||
<td colspan="12" style="padding: 0;">
|
||||
<div
|
||||
style="padding: 14px 16px; border-top: 1px solid var(--border); background: var(--surface-2, rgba(127, 127, 127, 0.05));"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user