|
|
36b577bff8
|
fix(webui): 总览改静态骨架 + 图标 KPI,彻底去掉整页重建的闪烁
jianf:仍严重闪烁;应彻底摒弃增量重建,用动态图标 + api 数据展示;主页文字太多。
- renderOverview 从「每次 innerHTML 重建整页(含运行态面板)」改成**首帧建一次
静态骨架**,之后 renderAll(每 15s 一次)只 updateOverview —— 只写 textContent
与类名,一个节点都不重建。实测连续两次 renderAll 后 #ov-kpis / #ov-status /
#rt-panel 仍是同一批 DOM 节点,这是"不再闪"的直接判据。
- 主页文字大幅收缩:删掉「系统概览 / LLM 状态 / 记忆状态 / 运行时」四张 kv 文字卡,
改成一排 8 个图标 KPI(状态/运行/插件/版本/LLM/记忆/文档/运行时),状态用彩色
圆点表达,其余只留数字 + 两字标签。
- 运行态面板不再被 renderOverview 清空(去掉 _rtSig=null 与重建),保持连续更新。
|
2026-09-14 16:16:14 +08:00 |
|
|
|
f722498dba
|
feat(webui): 默认配色改黑白 + 设置页新增「外观」区
jianf:默认配色太花,且配色要能在设置页调。
- 新增 mono(黑白灰)配色并设为默认:未选过配色的 localStorage 一律
data-color=mono。黑白下连拓扑归属配色也走灰阶,不至于只剩一张彩图。
- accent 的所有硬编码 rgba(255,127,172,x) 收敛成语义变量 --accent-rgb,
各配色块(sakura/cyan/violet/emerald/amber/blue)各自声明自己的 rgb,
于是换配色时阴影/描边/阴影辉光一起换,不再残留粉色。
- 设置页新增「外观」区(侧栏最前):主题(浅/深)+ 7 个配色圆点 +
背景图 URL/模糊。原先只有侧栏底部一个调色盘图标,找不到。
- 切配色时强制重画运行态(置空 _rtSig),否则拓扑会停在旧色。
|
2026-09-14 15:44:17 +08:00 |
|
|
|
e4d69fa140
|
feat(webui): 总览改版 —— 阶段管道滑块 / per-agent 负载环 / 通道→agent 拓扑与光点
总览页此前是一堆数字与文字块,看不出「这一轮走到哪、谁忙、消息从哪进哪出」。
本次把运行态面板改成以图形为主:
- 阶段管道:七阶段滑块,由 SSE stage 事件驱动,当前阶段高亮、滑块滑过去;
一轮结束(after_output 或 2.5s 无事件)自动回到空闲,不做假动画。
- 队列与中断栈:沿用五条进度条(L1–L4 + 排队),中断栈补一条深度进度条。
- Agent 拓扑:改成「每 agent 一条横带」——左 inputch、中 agent 节点(圆环 = 负载)、
右 outputch,连线即路由;删掉旧的「归属框 + 单个内核盒」画法(看得出哪个子接了哪条输入)。
- 光点动画:channel_input(新增轻量 SSE 事件)沿 inputch→agent 连线跑;
agent_output 沿 agent→outputch 连线跑。用 SMIL animateMotion,不需要 rAF 循环。
- 负载:由该 agent **自己的**调度器积压(排队 / 四级中断 / 中断栈)按级别加权折算,
环形图展示。为此把驻留子的调度器积压透出到状态面(SDK 纯追加字段)。
后端:sdk.ResidentStatus / core.ResidentInfo 增加子 agent 调度器积压四项;
WebUI SSE 增加 channel_input 轻量事件(只带通道名与 agent id,不带正文)。
顺带收口对话区视觉(页签改分段控件、消息间距/气泡区分、输入区分隔线)。
|
2026-09-14 15:33:23 +08:00 |
|
|
|
0fda210e8b
|
feat(webui): 视觉重做第一轮 —— 侧栏图标化、顶栏标题化、卡片/行/按钮收口
反馈是「丑死了」,没有具体项,所以按「哪儿在制造廉价感」逐条改:
1. **侧栏只有文字**:6 个导航项各加 24×24 stroke 图标(currentColor,随选中/hover 变色),
10px 间距、13.5px/500 字重、圆角 10px 的药丸命中区;品牌字改 sakura→frost 渐变。
→ 空荡荡的 16rem 栏终于有了骨架。
2. **选中态把文字整体右推 + 发光文字**:原来用 `border-left: 3px` 画选中条,
hover 时整行抖 3px;还加了 text-shadow 光晕。改成 `box-shadow: inset 2px 0 0`
(不占布局)+ 取消光晕 + 选中加粗。这类「一像素级不稳」是廉价感的主要来源。
3. **顶栏只有一行灰字面包屑**:把当前页做成 15px/650 的标题色,面包屑碎片
压到 12.5px 且降透明度;顶栏 48→56px。页面总算有「入口」。
4. **卡片 hover 整页上下浮**:`.card:hover` 去掉 `translateY(-1px)`(十几张卡一起
浮,视线扫过像在抖),只提亮阴影与描边;padding 20→22、卡片间距 16→18。
5. **卡片标题没有章节信号**:`h2` 前加 3×14px 的 sakura→frost 渐变短竖。
6. **kv-row 是文字墙**:flex + 固定 180px 键列 → grid `minmax(110px,180px) 1fr`,
行高 8px、负外边距 hover 高亮、末行去分隔线、数值 `tabular-nums`(端口/计数上下对齐)。
7. **满屏药丸按钮**:`.btn` 圆角从 999px 收到 10px(与卡片同一套圆角),
padding/font 微调;`.btn-sm` 11→11.5px 提升可读性。
8. **内容区靠左铺满**:`.container` 居中 + `max-width: 1240px`(超宽屏摊满整个
屏幕是「后台模板」的典型观感)。
i18n 有个坑:切语言那段是 `el.textContent = …`,所以 `data-i18n` 必须从 `<a>` 挪到
内层 `<span>`,否则切一次语言图标就被抹掉。实测 ZH→EN→ZH 图标都在。
验证:go build/测试绿(webui + sdk + agent + plugin);真机 1440×900 六页截图对比
(侧栏图标、渐变品牌、标题竖条、grid 行、居中内容区均生效)。
|
2026-09-14 14:29:17 +08:00 |
|
|
|
e8d7bb4c06
|
feat(webui): 通道归属合并进拓扑图,整张图改 SVG(少文字、多图形)
上一版把「通道分配(按归属)」单开一段,等于把同一件事拆成两张表——
而通道属于谁是**拓扑的一部分**(左边这些输入口分别被谁接管),拆开反而
看不出关系。按用户要求合并,并整体改成图形化:
- 整张拓扑用 SVG:左侧按归属画出输入通道容器(根=青色虚线框,驻留子=彩色
实线框并标轮次/上下文满),→ 汇集母线 → 内核 → 输出母线 → 右侧输出通道。
**连线即路由**。
- 信息全部改用图形编码:归属=容器/配色、容量=节点内细条(默认容量不画填充)、
输出能力=五个彩色圆点(text/file/image/audio/structured)。
- 文字降到最少:去掉四个数字块的副标题、排队队列那行只留 "FIFO"、
通道行不再写"回程由来源决定"这类说明。
- 段名改为「通道拓扑(连线即路由;左框 = 归属)」。
验证:node --check 通过;go build ./... 干净;webui 测试全绿。
|
2026-09-14 11:22:20 +08:00 |
|
|
|
d502fc1bf5
|
fix(webui): 运行态面板逐段更新(真修「一闪一闪」)+ 补第五条排队队列
1) 上一版只做了整体签名缓存,实测仍会重建:设备通道列表本身就在来回变
(远程设备通道 11→9 条),签名一变就整块 innerHTML,没变的段落(含条
transition)也跟着推倒重来——视觉上仍是闪。改法:外壳只建一次,之后
**逐段**(tiles/levels/stack/owners/topo)比较 HTML,只替换真正变了的那段。
2) 设计是「四条中断队列(L1–L4)+ 一条排队队列」= 五个队列,面板只画了四条:
排队输入这条线在运行态里凭空消失。补第五行「排队(无级别)」,用中性色 +
虚线分隔(它不是优先级,而是另一**类别**),并把它计入条形归一化基准。
段标题从「中断队列(按级别)」改为「队列(四级中断 + 排队)」。
3) 顺带把累计计数(入队/执行/抢占/挂起恢复/拒绝/背压)显式列在数字块下方——
背压是新指标,之前只能看接口看不到面板。
验证:node --check 通过;go build ./... 干净;webui/core/sdk 测试全绿。
|
2026-09-14 11:03:37 +08:00 |
|
|
|
43536ba326
|
fix(webui): 运行态面板不再闪、通道分配带归属(含驻留子)、改图形化
三个用户可见问题,逐个说明根因与改法。
1) 首页「一闪一闪」——运行态每 3s 轮询一次,renderRuntime 无条件重建
#rt-panel 的 innerHTML:数据没变也把整块 DOM(含各级条的 transition)
推倒重来。改法:缓存数据签名(**不含 uptime**——它每秒都变,带上等于没缓存),
签名相同直接 return,一个字节都不动。另:renderOverview 会整块重建
#rt-panel(面板本身是空的),所以那里必须让签名失效,否则空面板填不上。
2) 通道分配只显示内核/根 agent,看不见驻留子——根因是状态面只暴露了设备能力
(KernelStatus.Channels,来自 iom.ListChannels),而「这条输入归谁」是
ChannelRegistry 的属性(InputChannel.Owner/Capacity/Output),从未出过内核。
而登记表本来就是根 agent 与驻留子**共用同一份**,所以数据一直都在,只是没画。
改法:KernelStatus 新增 InputChannels(+ sdk.InputChannelInfo),
/api/v1/runtime 带出 input_channels;前端把它按 owner 分进「归属容器」,
驻留子即使一条 inputch 都没划到也照样出现在图里(否则"子存在但看不见"
与"子不存在"无法区分),并显示其 allowed_outputs / 轮次 / 上下文满标记。
3) 「这些信息明明可以图形化」——四级中断的登记/抢占由纯文本改成并排迷你条;
通道分配用归属容器 + 容量滑块(轨道/填充/把手/读数),并把回程通道、
注册插件做成胶囊标签。设备能力拓扑(原有)保留。
验证:go build/vet 干净;go test ./internal/agent/... ./internal/plugin/...
./internal/sdk/... ./cmd/... 全绿;node --check dashboard.js 语法通过。
TestRuntimeEndpoint 扩展为同时钉住 input_channels 的归属与「驻留子划走的那条」。
|
2026-09-14 10:55:45 +08:00 |
|
|
|
1ce3a917a5
|
feat(status+webui): 运行态图形化 —— 排队/四级中断队列/中断栈/驻留子/通道拓扑
需求:首页不该只有文字,要能一眼看出内核在忙什么——排队消息数、各级中断
排队与中断栈、驻留子 agent 数量;这些要向**内部 SDK 暴露接口**,供 WebUI 等应用
展示;通道划分也要能画出来。
## 一、内核状态面(internal/sdk,内部 SDK,不受公开 SDK 冻结约束)
* SchedulerStatus 补:
- interrupt_queues[5]:**四级中断队列各自的深度**(下标即级别 1..4,下标 0 恒 0,
这样 level 能直接当数组下标用)。此前只有 pending_interrupts 总数,
看不出"堵在 L1 还是 L4"——四级是抢占优先级,堵在哪级是完全不同的运行状态。
- immediate:刚抢占成功、下一个安全点立即运行的那个中断(此前完全不可见)。
- suspend_frames:中断栈的帧(栈底→栈顶,只给任务标识),depth 之外还能看出
"谁被谁打断"。
- interrupts_by_level / preempts_by_level:各级累计登记数与抢占成功数。
* KernelStatus 补 residents(驻留子运行时视图:状态/轮次/上下文已满/输入通道/允许输出)。
刻意**不带**每个驻留子的 inputch 登记明细——状态面会被反复轮询,明细会让
每次 /status 背上几十 KB;只给表大小,要明细走专门接口。
* ChannelInfo 补 direction(in/out/io)、description、tools、output_caps、caps_text。
此前 collectKernelStatus 只透传 Name/Type,把描述/工具/能力**全丢了**,
前端只能画出一排光秃秃的名字。
## 二、WebUI
* 新增只读 `/api/v1/runtime`:只回运行态三件事(scheduler/residents/channels),
实测 **1.0KB**(/kernel 是 30KB 级)——所以能 3 秒轮询做"实时"感,
而不必反复拉全量状态。
* 首页新增「运行态」面板(纯 CSS + 内联 SVG,前端仍无构建链):
- 四个数字块:排队任务 / 待处理中断 / 中断栈(深度/上限) / 驻留子 Agent,带占比条;
- 四级中断队列条形图:每级"深度 · 登记/抢占",四级语义**照抄内核**
(L4 内核独占 / L3 交互 / L2 消息 / L1 后台),不自己起名字;
- 中断栈层叠图(栈顶在上)+ ⚡立即运行项;
- 通道拓扑:输入通道 → 内核 → 输出通道,双向通道两侧都出现,能力以胶囊标签显示。
* 3 秒轮询只在总览页可见时才发请求;切回总览时 renderAll 会立刻补一次。
## 验证
* 新增 TestSchedulerStatusExposesLevelsAndStack(四级队列/立即项/栈帧/各级计数映射,
并断言"未使用的级别必须为 0"与"下标 0 恒 0")、TestChannelInfoCarriesTopology、
TestRuntimeEndpoint(形状 + 不携带 tools/plugins + 无状态源时 503)。
* go build / vet / agent+core+sdk+plugin+webui 全量测试绿。
* 真实浏览器实测(CDP 驱动,注入运行态样本走真实渲染路径):
数字块 [3, 5, 2/4, 2];四级条 L4=1/L3=2/L2=1/L1=1 与数据一致;
栈帧按"栈底→栈顶"渲染且标出栈顶;通道左右分列、io 通道两侧都出现。
|
2026-09-14 09:05:14 +08:00 |
|
|
|
764939ed90
|
refactor(webui): dashboard.html 6637 行拆成「外壳 + 样式 + 脚本」
前端刻意没有构建链(纯 CSS + Vanilla JS,go:embed 进二进制),所以拆法是:
外壳 dashboard.html 留 {{DASHBOARD_CSS}} / {{DASHBOARD_JS}} 两个占位符,
init() 启动时把两份资产原样填回去 —— **发出的 HTML 与拆分前逐字节一致**,
但 6637 行的单文件变成三份,便于编辑与评审。
dashboard.html 168 行 外壳(head/body 结构 + 两个占位符)
dashboard.css 2099 行 样式
dashboard.js 4371 行 脚本
逐字节校验(三重):
* 组装结果 sha256 == git HEAD 里拆分前的 dashboard.html;
* 真实实例 GET /(带 API key)返回体 sha256 同上:0ef14b49…c053;
* 新增 TestDashboardAssetsSplit:占位符必须存在、样式/脚本不得再内联回外壳、
组装结果不得残留占位符且必须含样式与脚本特征串。
按行号切片时踩过一次坑并已修正:`</style>`/`</script>` 两个闭合标签被切掉
(正好少 27 字节)——正是因为当时少了逐字节校验,现在把它固化成断言。
|
2026-09-14 07:17:23 +08:00 |
|