@brainpilot/web 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,17 @@ import { ChatMessage } from "../contracts/backend";
2
2
 
3
3
  /**
4
4
  * A unit of rendering in the chat stream. Either a single standalone message
5
- * (user prompt, assistant text, error, hook note) or an "activity" group that
6
- * folds adjacent reasoning and tool calls/results into one collapsible block.
5
+ * (user prompt, assistant text, error, hook note), an "activity" group that
6
+ * folds adjacent reasoning and tool calls/results into one collapsible block,
7
+ * or (#219) an "expertGroup" that folds a run of non-PI (specialist) agent
8
+ * render items behind one more level of disclosure so the PI narrative reads
9
+ * cleanly by default. An expertGroup nests already-built single/activity items
10
+ * so the reasoning/tool folds inside it are preserved when expanded.
7
11
  */
8
12
  export type RenderItem =
9
13
  | { type: "single"; message: ChatMessage }
10
- | { type: "activity"; id: string; steps: ChatMessage[]; streaming: boolean };
14
+ | { type: "activity"; id: string; steps: ChatMessage[]; streaming: boolean }
15
+ | { type: "expertGroup"; id: string; agents: string[]; items: RenderItem[]; streaming: boolean };
11
16
 
12
17
  /**
13
18
  * #134 — tool visibility model. Internal tools are part of the agent's plumbing
@@ -101,6 +106,7 @@ function isStandalone(message: ChatMessage): boolean {
101
106
  export function buildRenderItems(
102
107
  messages: ChatMessage[],
103
108
  runningAgents?: ReadonlySet<string>,
109
+ groupExpert = false,
104
110
  ): RenderItem[] {
105
111
  const items: RenderItem[] = [];
106
112
  // #134 — internal tools (trace bookkeeping) are hidden from the chat UI.
@@ -129,5 +135,105 @@ export function buildRenderItems(
129
135
  }
130
136
  }
131
137
  flush();
132
- return items;
138
+ // #219 — second pass: fold consecutive specialist (non-PI) items into
139
+ // collapsible expert groups. Off by default (demo replay / legacy callers).
140
+ return groupExpert ? groupExpertItems(items, runningAgents) : items;
141
+ }
142
+
143
+ /* -------------------------------------------------------------------------- *
144
+ * #219 — expert-agent activity grouping.
145
+ * -------------------------------------------------------------------------- */
146
+
147
+ /** The principal (PI) agent name; unattributed items default to it. */
148
+ const PRINCIPAL = "principal";
149
+
150
+ /**
151
+ * Important events stay visible even when they come from a specialist agent —
152
+ * they must never be buried inside a collapsed group (issue #219 UX goal:
153
+ * "avoid hiding important failures, blockers, or user-action-required events").
154
+ * Errors, approval/user-input requests, and warning+ system messages / hooks
155
+ * escape grouping and render standalone.
156
+ */
157
+ function isImportantEvent(message: ChatMessage): boolean {
158
+ if (message.kind === "error" || message.kind === "ask_user") return true;
159
+ if (message.kind === "system_message") {
160
+ const level = message.systemMessage?.level;
161
+ return level === "warning" || level === "error" || level === "fatal";
162
+ }
163
+ if (message.kind === "hook") {
164
+ return message.hookLevel === "warning" || message.hookLevel === "error";
165
+ }
166
+ return false;
167
+ }
168
+
169
+ /** Owning agent of a render item: the message's agent, or the activity's first step. */
170
+ function itemAgent(item: RenderItem): string {
171
+ if (item.type === "single") return item.message.agent ?? PRINCIPAL;
172
+ if (item.type === "activity") return item.steps[0]?.agent ?? PRINCIPAL;
173
+ return PRINCIPAL;
174
+ }
175
+
176
+ /**
177
+ * A render item is a foldable specialist item when it belongs to a non-PI agent
178
+ * AND (for singles) is not an important event that must stay surfaced. User
179
+ * prompts and PI/unattributed items always break the run.
180
+ */
181
+ function isFoldableExpertItem(item: RenderItem): boolean {
182
+ if (itemAgent(item) === PRINCIPAL) return false;
183
+ if (item.type === "single") {
184
+ if (item.message.role === "user") return false;
185
+ if (isImportantEvent(item.message)) return false;
186
+ }
187
+ return true;
188
+ }
189
+
190
+ function itemStreaming(item: RenderItem, runningAgents?: ReadonlySet<string>): boolean {
191
+ if (item.type === "activity") return item.streaming;
192
+ if (item.type === "single") {
193
+ return !!item.message.streaming || (runningAgents?.has(itemAgent(item)) ?? false);
194
+ }
195
+ return false;
196
+ }
197
+
198
+ /** Fold consecutive foldable specialist items into one expertGroup each. */
199
+ function groupExpertItems(items: RenderItem[], runningAgents?: ReadonlySet<string>): RenderItem[] {
200
+ const out: RenderItem[] = [];
201
+ let run: RenderItem[] = [];
202
+ const flushRun = () => {
203
+ if (run.length === 0) return;
204
+ // A lone expert `activity` item is already collapsed on its own — wrapping
205
+ // it in a second disclosure level just makes the user click twice. Leave it.
206
+ // A lone expert `single` (standalone text) still gets grouped so specialist
207
+ // chatter is collapsed by default (issue #219 acceptance criteria).
208
+ if (run.length === 1 && run[0].type === "activity") {
209
+ out.push(run[0]);
210
+ run = [];
211
+ return;
212
+ }
213
+ const agents = Array.from(new Set(run.map(itemAgent)));
214
+ out.push({
215
+ type: "expertGroup",
216
+ id: `expert-${idOf(run[0])}`,
217
+ agents,
218
+ items: run,
219
+ streaming: run.some((it) => itemStreaming(it, runningAgents)),
220
+ });
221
+ run = [];
222
+ };
223
+ for (const item of items) {
224
+ if (isFoldableExpertItem(item)) {
225
+ run.push(item);
226
+ } else {
227
+ flushRun();
228
+ out.push(item);
229
+ }
230
+ }
231
+ flushRun();
232
+ return out;
233
+ }
234
+
235
+ /** Stable id for a render item (drives <details> DOM reuse across re-renders). */
236
+ function idOf(item: RenderItem): string {
237
+ if (item.type === "single") return item.message.id;
238
+ return item.id;
133
239
  }
@@ -338,7 +338,17 @@ export function reduceMessagesForEvent(existing: ChatMessage[], event: WebSocket
338
338
 
339
339
  // 修正6 — system_message: 4-level styled bubble in the conversation stream.
340
340
  case "system_message": {
341
- return [...existing, systemMessageToChatMessage(event)];
341
+ const msg = systemMessageToChatMessage(event);
342
+ // #167: coalesce by stable id — a repeated system_message carrying an id
343
+ // that already exists (e.g. an agent's retry warning ticking n/N) updates
344
+ // the existing bubble in place instead of stacking a new one. Messages
345
+ // without a stable id (random-id path) always append, as before.
346
+ const e = event as Record<string, unknown>;
347
+ const hasStableId = typeof (e.id ?? e.messageId) === "string";
348
+ if (hasStableId && existing.some((m) => m.id === msg.id)) {
349
+ return existing.map((m) => (m.id === msg.id ? msg : m));
350
+ }
351
+ return [...existing, msg];
342
352
  }
343
353
 
344
354
  // 修正6 — user_input_request (ask_user): interactive card. Keyed by
@@ -18,11 +18,18 @@ export default defineMessages(
18
18
  "chat.aria.messages": "对话消息",
19
19
  "chat.messageCount": "{count} 条消息",
20
20
  "chat.aria.expandThinking": "展开思考过程",
21
+ "chat.expertGroup.summary": "{agent} 的活动 · {count} 项",
22
+ "chat.expertGroup.summaryMulti": "{n} 位专家 Agent · {count} 项活动",
23
+ "chat.expertGroup.expandAll": "展开全部活动",
24
+ "chat.expertGroup.collapseAll": "收起专家活动",
25
+ "chat.aria.expandExpert": "展开专家 Agent 活动",
21
26
  "chat.agentThinking": "智能体思考中",
22
27
  "chat.agentWorking": "{name} 正在工作",
23
28
  "chat.agentsWorking": "{names} 正在工作",
24
29
  "chat.aria.stop": "停止生成",
25
30
  "chat.stop": "停止",
31
+ "chat.runningScripts.count": "{count} 个脚本正在运行",
32
+ "chat.runningScripts.pending": "参数传输中…",
26
33
  "chat.aria.newPrompt": "新的研究提问",
27
34
  "chat.srAsk": "提出一个研究问题",
28
35
  "chat.placeholder": "向 MAS 提问。输入 @ 使用插件或提及文件",
@@ -81,11 +88,18 @@ export default defineMessages(
81
88
  "chat.aria.messages": "Conversation messages",
82
89
  "chat.messageCount": "{count} messages",
83
90
  "chat.aria.expandThinking": "Expand thinking process",
91
+ "chat.expertGroup.summary": "{agent} activity · {count} items",
92
+ "chat.expertGroup.summaryMulti": "{n} specialist agents · {count} activity items",
93
+ "chat.expertGroup.expandAll": "Expand all activity",
94
+ "chat.expertGroup.collapseAll": "Collapse specialist activity",
95
+ "chat.aria.expandExpert": "Expand specialist agent activity",
84
96
  "chat.agentThinking": "Agent is thinking",
85
97
  "chat.agentWorking": "{name} is working",
86
98
  "chat.agentsWorking": "{names} are working",
87
99
  "chat.aria.stop": "Stop generating",
88
100
  "chat.stop": "stop",
101
+ "chat.runningScripts.count": "{count} script(s) running",
102
+ "chat.runningScripts.pending": "receiving args…",
89
103
  "chat.aria.newPrompt": "New research prompt",
90
104
  "chat.srAsk": "Ask a research question",
91
105
  "chat.placeholder": "Ask MAS. Type @ to use plugins or mention files",
@@ -45,6 +45,8 @@ export default defineMessages(
45
45
  "sandbox.logs.loading": "正在加载日志…",
46
46
  "sandbox.logs.empty": "尚未加载沙盒日志。",
47
47
  "sandbox.logs.failed": "加载沙盒详情失败。",
48
+ // details
49
+ "sandbox.details.more": "更多详情",
48
50
  // actions
49
51
  "sandbox.action.rebuild": "重建",
50
52
  "sandbox.action.refresh": "刷新",
@@ -100,6 +102,7 @@ export default defineMessages(
100
102
  "sandbox.logs.loading": "Loading logs...",
101
103
  "sandbox.logs.empty": "No sandbox logs loaded.",
102
104
  "sandbox.logs.failed": "Failed to load sandbox details.",
105
+ "sandbox.details.more": "More details",
103
106
  "sandbox.action.rebuild": "Rebuild",
104
107
  "sandbox.action.refresh": "Refresh",
105
108
  "sandbox.action.logs": "Logs",
@@ -12,7 +12,42 @@ export default defineMessages(
12
12
  "settings.tab.account": "账户",
13
13
  "settings.tab.providers": "服务商",
14
14
  "settings.tab.mcp": "MCP",
15
+ "settings.tab.knowledgeBase": "知识库",
15
16
  "settings.tab.preferences": "偏好",
17
+ // knowledge base
18
+ "settings.kb.title": "本地知识库",
19
+ "settings.kb.desc": "将 PDF 放入 KnowledgeBase/source/pdf/,然后构建本地 RAG 索引。嵌入模型在本机运行;仅 OCR 与元数据抽取阶段需要联网。",
20
+ "settings.kb.ocrKey": "SiliconFlow OCR API Key",
21
+ "settings.kb.metaKey": "元数据抽取 API Key",
22
+ "settings.kb.metaBaseUrl": "元数据抽取 Base URL",
23
+ "settings.kb.metaModel": "元数据抽取模型",
24
+ "settings.kb.reuseAgentKey": "复用 agent 当前的 LLM key 进行元数据抽取",
25
+ "settings.kb.useHfMirror": "使用 HuggingFace 镜像下载模型(推荐国内用户开启)",
26
+ "settings.kb.useHfMirrorHint": "首次构建将自动下载 bge-m3 + bge-reranker-v2-m3 模型权重(约 2.5 GB)。国内用户开启此选项可切换到 hf-mirror.com 显著提升下载速度。",
27
+ "settings.kb.stages": "要运行的阶段",
28
+ "settings.kb.start": "构建知识库",
29
+ "settings.kb.cancel": "取消构建",
30
+ "settings.kb.progress": "阶段进度",
31
+ "settings.kb.log": "实时日志",
32
+ "settings.kb.logEmpty": "尚无构建事件 — 点击「构建知识库」开始。",
33
+ "settings.kb.error.missingOcrKey": "缺少 SiliconFlow OCR API Key",
34
+ "settings.kb.error.missingMetaKey": "缺少元数据抽取 API Key(或勾选「复用 agent LLM key」)",
35
+ "settings.kb.env.title": "Python 运行环境",
36
+ "settings.kb.env.venvMissing": "尚未为 KnowledgeBase 创建 Python 虚拟环境。点下面按钮一次性配置 Python 环境 + 下载模型:",
37
+ "settings.kb.env.setupButton": "一键配置 Python 环境",
38
+ "settings.kb.env.setupHint": "在 KnowledgeBase/.venv 里创建 venv 并安装 requirements.txt 中的所有依赖(约 2-5 分钟,需联网下载 PyTorch / FlagEmbedding)",
39
+ "settings.kb.env.setupFullButton": "一键配置环境 + 下载模型",
40
+ "settings.kb.env.setupFullHint": "同时执行:① 创建 .venv 并安装 Python 依赖(2-5 分钟)② 下载 bge-m3 + bge-reranker 模型权重(约 2.5 GB,5-30 分钟)。两步进度会分别显示。",
41
+ "settings.kb.env.reinstallButton": "重建虚拟环境",
42
+ "settings.kb.env.reinstallHint": "删除现有 .venv 并从头重装所有依赖",
43
+ "settings.kb.env.cliFallback": "或者也可以在终端手动执行",
44
+ "settings.kb.env.venvHint": "venv 创建后无需任何额外环境变量配置 —— 构建按钮会自动发现它。如果你想用别的解释器,把绝对路径写到 BP_KB_PYTHON 环境变量里再启动 BrainPilot。",
45
+ "settings.kb.env.needSetupFirst": "请先点击「一键配置环境 + 下载模型」",
46
+ "settings.kb.env.busy": "Python 环境配置正在进行中…",
47
+ "settings.kb.env.venvProgressLabel": "① Python 虚拟环境",
48
+ "settings.kb.env.modelProgressLabel": "② 嵌入 / 重排序模型",
49
+ "settings.kb.ocrKeySaved": "已保存",
50
+ "settings.kb.ocrKeyChange": "更改",
16
51
  // account
17
52
  "settings.account.title": "账户",
18
53
  "settings.account.username": "用户名",
@@ -38,6 +73,8 @@ export default defineMessages(
38
73
  "settings.providers.activeSwitched": "已切换活动服务商为 “{name}”。新会话将使用该服务商。",
39
74
  "settings.providers.saveFailed": "保存服务商失败",
40
75
  "settings.providers.modelRequired": "至少需要配置一个模型",
76
+ "settings.providers.empty": "还没有服务商",
77
+ "settings.providers.emptyHint": "添加一个服务商,配置 API 接入与可用模型后即可开始新会话。",
41
78
  // mcp
42
79
  "settings.mcp.title": "MCP 服务器",
43
80
  "settings.mcp.desc": "MCP 服务器配置定义了智能体会话可用的外部工具。",
@@ -47,15 +84,23 @@ export default defineMessages(
47
84
  "settings.mcp.updated": "MCP 服务器已更新",
48
85
  "settings.mcp.added": "MCP 服务器已添加",
49
86
  "settings.mcp.saveFailed": "保存 MCP 服务器失败",
87
+ "settings.mcp.empty": "还没有 MCP 服务器",
88
+ "settings.mcp.emptyHint": "添加一个 MCP 服务器,把外部工具接入你的智能体会话。",
50
89
  // preferences
51
90
  "settings.prefs.title": "偏好设置",
91
+ "settings.prefs.groupAppearance": "外观",
92
+ "settings.prefs.groupBehavior": "行为",
52
93
  "settings.prefs.theme": "主题",
94
+ "settings.prefs.themeDesc": "选择浅色、深色,或跟随系统设置。",
53
95
  "settings.prefs.themeLight": "浅色",
54
96
  "settings.prefs.themeDark": "深色",
55
97
  "settings.prefs.themeSystem": "跟随系统",
56
98
  "settings.prefs.language": "语言",
99
+ "settings.prefs.languageDesc": "界面显示语言。",
57
100
  "settings.prefs.confirmDangerous": "危险操作前确认",
101
+ "settings.prefs.confirmDangerousDesc": "执行删除、重建等不可撤销操作前先弹窗确认。",
58
102
  "settings.prefs.notifyDone": "智能体任务完成时通知",
103
+ "settings.prefs.notifyDoneDesc": "智能体完成任务后发送桌面通知。",
59
104
  // provider form
60
105
  "settings.providerForm.editAria": "编辑服务商",
61
106
  "settings.providerForm.addAria": "添加服务商",
@@ -76,6 +121,8 @@ export default defineMessages(
76
121
  "settings.providerForm.models": "模型",
77
122
  "settings.providerForm.addModel": "添加模型",
78
123
  "settings.providerForm.removeModel": "移除模型",
124
+ "settings.providerForm.modelsHint":
125
+ "示例模型仅作占位,保存前请改成你的网关支持的模型,否则发消息时才会报模型不可用。",
79
126
  "settings.providerForm.useColor": "使用颜色 {color}",
80
127
  "settings.providerForm.color": "颜色",
81
128
  "settings.providerForm.cancel": "取消",
@@ -107,7 +154,41 @@ export default defineMessages(
107
154
  "settings.tab.account": "Account",
108
155
  "settings.tab.providers": "Providers",
109
156
  "settings.tab.mcp": "MCP",
157
+ "settings.tab.knowledgeBase": "Knowledge Base",
110
158
  "settings.tab.preferences": "Preferences",
159
+ "settings.kb.title": "Local Knowledge Base",
160
+ "settings.kb.desc": "Drop PDFs into KnowledgeBase/source/pdf/, then build a local RAG index. Embedding models run on your machine; only the OCR and metadata-extraction stages call out.",
161
+ "settings.kb.ocrKey": "SiliconFlow OCR API key",
162
+ "settings.kb.metaKey": "Metadata-extract API key",
163
+ "settings.kb.metaBaseUrl": "Metadata-extract base URL",
164
+ "settings.kb.metaModel": "Metadata-extract model",
165
+ "settings.kb.reuseAgentKey": "Reuse the agent's active LLM key for metadata extraction",
166
+ "settings.kb.useHfMirror": "Use HuggingFace mirror for model download (recommended for users in China)",
167
+ "settings.kb.useHfMirrorHint": "First build auto-downloads bge-m3 + bge-reranker-v2-m3 weights (~2.5 GB). Users in China can enable this to switch to hf-mirror.com for much faster downloads.",
168
+ "settings.kb.stages": "Stages to run",
169
+ "settings.kb.start": "Build Knowledge Base",
170
+ "settings.kb.cancel": "Cancel build",
171
+ "settings.kb.progress": "Stage progress",
172
+ "settings.kb.log": "Live log",
173
+ "settings.kb.logEmpty": "No build events yet — press \"Build Knowledge Base\" to start.",
174
+ "settings.kb.error.missingOcrKey": "SiliconFlow OCR API key required",
175
+ "settings.kb.error.missingMetaKey": "Metadata-extract API key required (or check \"reuse agent LLM key\")",
176
+ "settings.kb.env.title": "Python environment",
177
+ "settings.kb.env.venvMissing": "No Python venv set up for KnowledgeBase yet. Click below to set up the Python env and download models in one go:",
178
+ "settings.kb.env.setupButton": "Set up Python environment",
179
+ "settings.kb.env.setupHint": "Creates KnowledgeBase/.venv and installs everything in requirements.txt (2-5 min; downloads PyTorch + FlagEmbedding)",
180
+ "settings.kb.env.setupFullButton": "Set up environment + download models",
181
+ "settings.kb.env.setupFullHint": "Runs in sequence: ① create .venv and install Python dependencies (2-5 min) ② download bge-m3 + bge-reranker weights (~2.5 GB, 5-30 min). Progress for each step is shown separately.",
182
+ "settings.kb.env.reinstallButton": "Reinstall venv",
183
+ "settings.kb.env.reinstallHint": "Remove the existing .venv and reinstall every dependency from scratch",
184
+ "settings.kb.env.cliFallback": "Or run this in a terminal yourself",
185
+ "settings.kb.env.venvHint": "Once the venv exists no env vars are needed — the build button auto-detects it. To use a different interpreter, set BP_KB_PYTHON to its absolute path before launching BrainPilot.",
186
+ "settings.kb.env.needSetupFirst": "Click \"Set up environment + download models\" first",
187
+ "settings.kb.env.venvProgressLabel": "① Python virtual environment",
188
+ "settings.kb.env.modelProgressLabel": "② Embedding + reranker models",
189
+ "settings.kb.ocrKeySaved": "Saved",
190
+ "settings.kb.ocrKeyChange": "Change",
191
+ "settings.kb.env.busy": "Python environment setup is currently running…",
111
192
  "settings.account.title": "Account",
112
193
  "settings.account.username": "Username",
113
194
  "settings.account.userId": "User ID",
@@ -131,6 +212,8 @@ export default defineMessages(
131
212
  "settings.providers.activeSwitched": "Active provider switched to \"{name}\". New sessions will use this provider.",
132
213
  "settings.providers.saveFailed": "Failed to save provider",
133
214
  "settings.providers.modelRequired": "At least one model is required",
215
+ "settings.providers.empty": "No providers yet",
216
+ "settings.providers.emptyHint": "Add a provider with its API connection and models to start new sessions.",
134
217
  "settings.mcp.title": "MCP Servers",
135
218
  "settings.mcp.desc": "MCP server profiles define external tools available to agent sessions.",
136
219
  "settings.mcp.addServer": "Add Server",
@@ -139,14 +222,22 @@ export default defineMessages(
139
222
  "settings.mcp.updated": "MCP server updated",
140
223
  "settings.mcp.added": "MCP server added",
141
224
  "settings.mcp.saveFailed": "Failed to save MCP server",
225
+ "settings.mcp.empty": "No MCP servers yet",
226
+ "settings.mcp.emptyHint": "Add an MCP server to connect external tools to your agent sessions.",
142
227
  "settings.prefs.title": "Preferences",
228
+ "settings.prefs.groupAppearance": "Appearance",
229
+ "settings.prefs.groupBehavior": "Behavior",
143
230
  "settings.prefs.theme": "Theme",
231
+ "settings.prefs.themeDesc": "Choose light, dark, or follow your system setting.",
144
232
  "settings.prefs.themeLight": "Light",
145
233
  "settings.prefs.themeDark": "Dark",
146
234
  "settings.prefs.themeSystem": "System",
147
235
  "settings.prefs.language": "Language",
236
+ "settings.prefs.languageDesc": "Display language for the interface.",
148
237
  "settings.prefs.confirmDangerous": "Confirm dangerous actions",
238
+ "settings.prefs.confirmDangerousDesc": "Ask before irreversible actions like deleting or rebuilding.",
149
239
  "settings.prefs.notifyDone": "Notify when agent work completes",
240
+ "settings.prefs.notifyDoneDesc": "Send a desktop notification when an agent finishes its task.",
150
241
  "settings.providerForm.editAria": "Edit provider",
151
242
  "settings.providerForm.addAria": "Add provider",
152
243
  "settings.providerForm.eyebrow": "Provider",
@@ -166,6 +257,8 @@ export default defineMessages(
166
257
  "settings.providerForm.models": "Models",
167
258
  "settings.providerForm.addModel": "Add model",
168
259
  "settings.providerForm.removeModel": "Remove model",
260
+ "settings.providerForm.modelsHint":
261
+ "The example model is only a placeholder — replace it with one your gateway supports before saving, or the model will be rejected when you send a message.",
169
262
  "settings.providerForm.useColor": "Use color {color}",
170
263
  "settings.providerForm.color": "Color",
171
264
  "settings.providerForm.cancel": "Cancel",
@@ -4,7 +4,6 @@ export default defineMessages(
4
4
  {
5
5
  // AgentsPanel
6
6
  "trace.agents.eyebrow": "实时 Agent 网络",
7
- "trace.agents.title": "Agents",
8
7
  "trace.agents.emptyNoSession": "创建或选择会话后,这里会显示参与当前任务的 Agent 与它们之间的消息流。",
9
8
  "trace.agents.emptyNoEvents": "当前会话还没有 Agent 状态事件。",
10
9
  // TracePanel
@@ -70,7 +69,6 @@ export default defineMessages(
70
69
  },
71
70
  {
72
71
  "trace.agents.eyebrow": "Live agent network",
73
- "trace.agents.title": "Agents",
74
72
  "trace.agents.emptyNoSession": "Once you create or select a session, the agents involved in the current task and the message flow between them will appear here.",
75
73
  "trace.agents.emptyNoEvents": "No agent status events in this session yet.",
76
74
  "trace.eyebrow": "Reasoning trace",