惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
MyScale Blog
MyScale Blog
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
B
Blog
F
Fortinet All Blogs
D
DataBreaches.Net
博客园 - Franky
博客园 - 三生石上(FineUI控件)
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
IT之家
IT之家
人人都是产品经理
人人都是产品经理
博客园_首页
量子位
美团技术团队
Jina AI
Jina AI
博客园 - 叶小钗
博客园 - 聂微东

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
feat(ui): display agent identities in session list · open...
BunsDev · 2026-04-27 · via Recent Commits to openclaw:main

@@ -1,12 +1,13 @@

11

import { html, nothing } from "lit";

22

import { t } from "../../i18n/index.ts";

3-

import { formatRelativeTimestamp } from "../format.ts";

3+

import { formatRelativeTimestamp, parseSessionKeyParts } from "../format.ts";

44

import { icons } from "../icons.ts";

55

import { pathForTab } from "../navigation.ts";

66

import { formatSessionTokens } from "../presenter.ts";

77

import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../string-coerce.ts";

88

import { normalizeThinkLevel } from "../thinking.ts";

99

import type {

10+

AgentIdentityResult,

1011

GatewaySessionRow,

1112

GatewayThinkingLevelOption,

1213

SessionCompactionCheckpoint,

@@ -23,6 +24,7 @@ export type SessionsProps = {

2324

includeUnknown: boolean;

2425

basePath: string;

2526

searchQuery: string;

27+

agentIdentityById: Record<string, AgentIdentityResult>;

2628

sortColumn: "key" | "kind" | "updated" | "tokens";

2729

sortDir: "asc" | "desc";

2830

page: number;

@@ -80,6 +82,15 @@ const FAST_LEVELS = [

8082

const REASONING_LEVELS = ["", "off", "on", "stream"] as const;

8183

const PAGE_SIZES = [10, 25, 50, 100] as const;

828485+

function getAgentIdentity(

86+

agentIdentityById: Record<string, AgentIdentityResult>,

87+

agentId: string,

88+

): AgentIdentityResult | null {

89+

return Object.prototype.hasOwnProperty.call(agentIdentityById, agentId)

90+

? (agentIdentityById[agentId] ?? null)

91+

: null;

92+

}

93+8394

function normalizeThinkingOptionValue(raw: string): string {

8495

return normalizeThinkLevel(raw) ?? normalizeLowercaseStringOrEmpty(raw);

8596

}

@@ -133,7 +144,11 @@ function resolveThinkLevelPatchValue(value: string): string | null {

133144

return value;

134145

}

135146136-

function filterRows(rows: GatewaySessionRow[], query: string): GatewaySessionRow[] {

147+

function filterRows(

148+

rows: GatewaySessionRow[],

149+

query: string,

150+

agentIdentityById: Record<string, AgentIdentityResult>,

151+

): GatewaySessionRow[] {

137152

const q = normalizeLowercaseStringOrEmpty(query);

138153

if (!q) {

139154

return rows;

@@ -143,7 +158,14 @@ function filterRows(rows: GatewaySessionRow[], query: string): GatewaySessionRow

143158

const label = normalizeLowercaseStringOrEmpty(row.label);

144159

const kind = normalizeLowercaseStringOrEmpty(row.kind);

145160

const displayName = normalizeLowercaseStringOrEmpty(row.displayName);

146-

return key.includes(q) || label.includes(q) || kind.includes(q) || displayName.includes(q);

161+

if (key.includes(q) || label.includes(q) || kind.includes(q) || displayName.includes(q)) {

162+

return true;

163+

}

164+

const keyParts = parseSessionKeyParts(row.key);

165+

const identityName = keyParts

166+

? normalizeLowercaseStringOrEmpty(getAgentIdentity(agentIdentityById, keyParts.agentId)?.name)

167+

: "";

168+

return identityName.includes(q);

147169

});

148170

}

149171

@@ -216,7 +238,7 @@ function formatCheckpointDelta(checkpoint: SessionCompactionCheckpoint): string

216238217239

export function renderSessions(props: SessionsProps) {

218240

const rawRows = props.result?.sessions ?? [];

219-

const filtered = filterRows(rawRows, props.searchQuery);

241+

const filtered = filterRows(rawRows, props.searchQuery, props.agentIdentityById);

220242

const sorted = sortRows(filtered, props.sortColumn, props.sortDir);

221243

const totalRows = sorted.length;

222244

const totalPages = Math.max(1, Math.ceil(totalRows / props.pageSize));

@@ -328,7 +350,7 @@ export function renderSessions(props: SessionsProps) {

328350

<div class="data-table-search">

329351

<input

330352

type="text"

331-

placeholder="Filter by key, label, kind…"

353+

placeholder="Filter by key, agent, label, kind…"

332354

.value=${props.searchQuery}

333355

@input=${(e: Event) => props.onSearchChange((e.target as HTMLInputElement).value)}

334356

/>

@@ -460,6 +482,17 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {

460482

const showDisplayName = Boolean(

461483

displayName && displayName !== row.key && displayName !== trimmedLabel,

462484

);

485+

const keyParts = parseSessionKeyParts(row.key);

486+

const agentIdentity = keyParts

487+

? getAgentIdentity(props.agentIdentityById, keyParts.agentId)

488+

: null;

489+

const identityEmoji = normalizeOptionalString(agentIdentity?.emoji) ?? "";

490+

const identityName = normalizeOptionalString(agentIdentity?.name) ?? "";

491+

const friendlyKeyLabel =

492+

identityName && keyParts

493+

? `${identityEmoji ? `${identityEmoji} ` : ""}${identityName} (${keyParts.channel})`

494+

: null;

495+

const keyCellTitle = friendlyKeyLabel ?? row.key;

463496

const canLink = row.kind !== "global";

464497

const chatUrl = canLink

465498

? `${pathForTab("chat", props.basePath)}?session=${encodeURIComponent(row.key)}`

@@ -484,7 +517,10 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {

484517

/>

485518

</td>

486519

<td class="data-table-key-col">

487-

<div class="mono session-key-cell">

520+

<div

521+

class=${friendlyKeyLabel ? "session-key-cell" : "mono session-key-cell"}

522+

title=${keyCellTitle}

523+

>

488524

${canLink

489525

? html`<a

490526

href=${chatUrl}

@@ -505,9 +541,9 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {

505541

props.onNavigateToChat(row.key);

506542

}

507543

}}

508-

>${row.key}</a

544+

>${friendlyKeyLabel ?? row.key}</a

509545

>`

510-

: row.key}

546+

: (friendlyKeyLabel ?? row.key)}

511547

${showDisplayName

512548

? html`<span class="muted session-key-display-name">${displayName}</span>`

513549

: nothing}