Skip to content

Commit e346eaa

Browse files
committed
fix(ui): 调整实体头像与消息活动热力图样式
智能体默认 Lorelei 与 soft 背景,人物脸色、头发和线条保留原作颜色。 用户默认 Notionists,预设背景在浅深主题下保持一致;会话树、协作结果与 标签使用透明 Gaze,沿用原有尺寸。保留自定义图片优先、稳定身份及失败恢复。 消息活动热力图改为 10px 行高及单元格高度,星期标签使用 16px+7×10px。 同步预设、第三方许可、设计约定及决策记录。 验证:前端完整 unit 990 passed,lint、build、工程契约和文档构建通过。 头像原作对照、背景/人物着色负控及真实页面浅深主题、768/1024/1440px 验证通过;热力图回读实际 DOM 行高与高度为 10px,且无横向溢出。
1 parent 6af483f commit e346eaa

14 files changed

Lines changed: 282 additions & 41 deletions

File tree

‎docs/develop-guides/decisions/implemented/2026-10-06-agent-user-avatar-system.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
类型:feature
55
Owner:frontend/src/shared/ui/FallbackAvatar.vue
66

7+
默认风格、会话身份与人物背景策略由[按实体区分头像](2026-10-31-avatar-entity-styles.md)取代;本记录保留本地生成、自定义图片优先与错误恢复的决定。
8+
79
## 问题
810

911
Agent 与 User 的默认头像需要共享风格、完整色卡、明暗版本和图标备用语义,并在列表、选择器、账户、统计及子智能体面板中保持实体身份一致。外部默认头像 API 会使头像展示依赖网络。

‎docs/develop-guides/decisions/implemented/2026-10-11-theme-auto-avatar-colors.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
类型:feature
55
Owner:frontend/src/shared/model/theme.js
66

7+
Lorelei 与 Notionists 的主题配色遵循[按实体区分头像](2026-10-31-avatar-entity-styles.md),主题轮换与其他风格配色沿用本记录。
8+
79
## 问题
810

911
用户需要在浅色、深色、跟随浏览器之间连续切换,同时保持头像的主体配色。二态主题与点击即关闭的菜单无法完成这个操作;夜间统一套用另一组颜色会让官方原色的不同风格与同一身份明显变色。
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# 按智能体、会话与用户区分头像
2+
3+
状态:implemented
4+
类型:feature
5+
Owner:frontend/src/shared/lib/avatar/generator.js
6+
7+
## 问题
8+
9+
智能体定义与对话中创建的会话共用头像风格,用户难以区分两种对象。用户头像需要彩色背景,并在深浅主题下保持一致。
10+
11+
## 决策
12+
13+
### 实现方案
14+
15+
共享生成器把 agent、session、user 默认映射到 Lorelei、Gaze、Notionists。`FallbackAvatar` 接收 session 类型,会话树、工具结果和面板标签传入会话身份。智能体目录、选择器及提及继续使用智能体身份,缺省采用 soft 背景预设;Lorelei 只替换背景,脸色、头发和线条保留原作颜色。显式 preset 继续覆盖缺省选择。Gaze 不设置背景;会话树、工具结果与面板标签保持 18px;输入框、正文和候选列表的会话引用使用描边对话气泡加标题,直接复用普通引用图标。Notionists 的背景进入现有四套色卡,整张头像不随主题变化。保留自定义图片优先、稳定 seed、现有显式风格和失败恢复。
16+
17+
不修改持久化、线程生命周期、权限、上传接口或主题选择行为,不增加依赖和设置入口。
18+
19+
## 替代方案
20+
21+
只在目录显式指定 Lorelei 会使同一智能体在选择器与目录的头像不一致。将会话继续标成 agent 并覆盖 style 会保留错误的身份和备用图标语义,因此增加一个对应现有会话实体的 kind。
22+
23+
## 后果
24+
25+
默认头像发生视觉变化,本地包体积增加;已有显式风格与自定义图片继续有效。人物风格使用预设淡彩背景,保证线条在深色界面可辨认;Lorelei 的脸色与线条不随背景预设改变。Gaze 使用会话身份生成,与智能体定义分开。背景颜色属于生成预设,不增加用户设置或持久配置。
26+
27+
本决定取代[本地头像系统](2026-10-06-agent-user-avatar-system.md)中的默认风格和会话身份规则,并补充[头像主题配色](2026-10-11-theme-auto-avatar-colors.md)中的人物风格策略。
28+
29+
## 验证
30+
31+
- 头像 unit 5 项通过:覆盖六种风格与四套预设的原生几何、稳定身份、透明 Gaze、人物背景和深浅主题相同输出,保留作者与许可元数据;Lorelei 各套预设与仅设置背景的上游原生输出完全相同。
32+
- 在临时副本恢复旧默认映射,身份断言失败;删除 Notionists 背景配置,原生输出及用户背景断言失败;恢复 Lorelei 纯色底纸或人物着色覆盖,背景与原作颜色断言失败。
33+
- [浏览器探针](../../../../frontend/test/browser/avatarEntityStyles.js)在当前 checkout 的真实 Vite 页面验证智能体目录 Lorelei,并用合成会话数据装配会话树、协作工具、面板标签、提及与候选五个入口。回读已解码 SVG、透明像素、同一会话的图片来源、四套用户背景、主题一致性、备用图标与空状态;1440、1024、768px 无横向溢出,保存浅深色截图。DOM 断言确认会话引用使用描边气泡且没有头像图片,会话树、协作结果和面板标签仍为 18px。
34+
- 当前 checkout 的 Compose 一次性前端容器执行 `pnpm run lint:check`、`pnpm run build` 通过。相关 `pnpm exec node --test test/unit/avatar.test.js test/unit/mention_utils.test.js` 为 9 passed、0 failed、0 skipped。`python3 scripts/ci/verify_engineering_contracts.py`、`python3 -m unittest scripts.ci.test_verify_engineering_contracts`(56 项)、`pnpm --dir docs run build` 与 `git diff --check` 通过。
35+
36+
浏览器使用 Chromium。会话使用合成数据,没有创建模型任务;上传持久化、权限和 worker 不属于头像展示验证范围。主开发前端在 25173 端口挂载当前 checkout;5173 前端挂载其他 checkout,不作为当前源码证据。

‎docs/develop-guides/design.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,12 @@ AI agent 修改或生成 Yuxi UI 时,优先按这一节执行。
359359

360360
## 头像组件
361361

362-
Agent 与 User 使用共享 [FallbackAvatar](https://github.com/xerrors/Yuxi/blob/main/frontend/src/shared/ui/FallbackAvatar.vue)。调用方传入 kind、稳定实体 seed、自定义图片 src 与展示尺寸;自定义图片优先。Agent 默认 Clay,User 默认 Glyphs。生成器随前端本地交付,不请求外部头像 API,Gaze 保持透明背景。
362+
智能体、会话与用户使用共享 [FallbackAvatar](https://github.com/xerrors/Yuxi/blob/main/frontend/src/shared/ui/FallbackAvatar.vue)。调用方传入 kind、稳定实体 seed、自定义图片 src 与展示尺寸;自定义图片优先。agent 默认 Lorelei 配合 soft 背景预设,user 默认 Notionists;会话树、协作工具结果和会话面板标签使用 session 类型及 Gaze 风格,以会话 ID 作为 seed。输入框、正文与候选列表中的会话引用使用描边的对话气泡加标题,沿用普通引用图标尺寸;会话树、协作结果与面板标签保持 18px。生成器随前端本地交付,不请求外部头像 API,Gaze 保持透明背景。
363363

364-
组件支持 style 为 glyphs、clay、shape-grid、gaze;preset 默认为 default,也支持 studio、heritage、soft,每套色卡都有日间与夜间版本。明暗共用主体色,底纸与墨色可独立调整;default 保留各风格上游主体与对比色,夜间仅调整 Glyphs 与 Clay 的底纸,Shape Grid 保留彩色背景。dark 为 on、off、auto,auto 跟随 Yuxi 的主题 Store;circle、square、rounded 分别提供圆形、直角方形和圆角方形。颜色配置由 [共享色卡](https://github.com/xerrors/Yuxi/blob/main/frontend/src/shared/lib/avatar/presets.js) 拥有,几何与表情随稳定 seed 固定。
364+
组件支持 style 为 lorelei、notionists、gaze、glyphs、clay、shape-grid;preset 缺省时,智能体使用 soft,用户与会话使用 default;调用方可显式选择 default、studio、heritage、soft,每套色卡都有日间与夜间版本。Notionists 从预设背景色组中稳定选色,人物底纸、墨色与背景在深浅主题下保持一致;Lorelei 只应用预设背景色组,脸色、头发与线条保留上游黑白原色,深浅主题使用相同颜色。其他风格明暗共用主体色,底纸与墨色可独立调整;default 保留各风格上游主体与对比色,夜间仅调整 Glyphs 与 Clay 的底纸,Shape Grid 保留彩色背景。dark 为 on、off、auto,auto 跟随 Yuxi 的主题 Store;circle、square、rounded 分别提供圆形、直角方形和圆角方形。颜色配置由 [共享色卡](https://github.com/xerrors/Yuxi/blob/main/frontend/src/shared/lib/avatar/presets.js) 拥有,几何与表情随稳定 seed 固定。
365365

366-
图片加载或本地生成失败时,Agent 使用 Lucide Bot、User 使用 Lucide User,浅色背景 token 在深浅主题下保持相同。组件通过 fallback 事件提供 image 或 generation 原因。图片地址改变后重新加载;网络恢复只重试失败图片。装饰头像传 decorative,独立头像使用 alt 或 name 提供可访问名称。
366+
图片加载或本地生成失败时,智能体使用 Lucide Bot、用户使用 Lucide User、会话使用 Lucide Workflow,浅色背景 token 在深浅主题下保持相同。组件通过 fallback 事件提供 image 或 generation 原因。图片地址改变后重新加载;网络恢复只重试失败图片。装饰头像传 decorative,独立头像使用 alt 或 name 提供可访问名称。
367367

368-
Glyphs 使用 Matt Houser 原作的 CC BY 4.0 授权,组件保留 SVG 署名与许可元数据,应用配色、夜间底纸及画布裁切适配;发布包含 [头像第三方声明](https://github.com/xerrors/Yuxi/blob/main/frontend/public/avatar-licenses.txt)。Clay、Shape Grid、Gaze 美术为 CC0 1.0,DiceBear 核心为 MIT。固定依赖与色卡更新需要核验输出和许可。
368+
Glyphs 使用 Matt Houser 原作的 CC BY 4.0 授权,组件保留 SVG 署名与许可元数据,应用配色、夜间底纸及画布裁切适配;发布包含 [头像第三方声明](https://github.com/xerrors/Yuxi/blob/main/frontend/public/avatar-licenses.txt)。Lorelei、Notionists、Clay、Shape Grid、Gaze 美术为 CC0 1.0,DiceBear 核心为 MIT。固定依赖与色卡更新需要核验输出和许可。
369369

370370
知识库、Skill 和工具的图标色由 `shared/lib/extensionIconColor.js` 按稳定资源身份从预设色卡中选择;浅色底使用当前主题背景混色。知识库使用 `kb_id`,Skill 使用 `slug`,图标与颜色在目录卡片和 @ 候选中保持一致。飞书使用本地品牌图标。

‎frontend/public/avatar-licenses.txt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ Original: https://www.figma.com/community/file/1249154526125777853
77
License: CC BY 4.0 https://creativecommons.org/licenses/by/4.0/
88
Yuxi modifications: project color palettes, Glyphs night paper color, canvas clipping.
99
Clay, Shape Grid, Gaze artwork: DiceBear, CC0 1.0.
10+
Lorelei artwork: Lisa Wischofsky, CC0 1.0; DiceBear remix.
11+
Original: https://www.figma.com/community/file/1198749693280469639
12+
Notionists artwork: Zoish, CC0 1.0; DiceBear remix.
13+
Original: https://heyzoish.gumroad.com/l/notionists
14+
Yuxi modifications to Lorelei and Notionists: preset colors, backgrounds, canvas clipping.
1015
Generated SVGs retain original attribution and license metadata.
1116

1217
MIT License

‎frontend/src/modules/dashboard/ui/DashboardActivityHeatmap.vue‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ const totalValue = computed(() => normalizedDays.value.reduce((sum, item) => sum
183183
display: grid;
184184
width: 22px;
185185
flex: 0 0 22px;
186-
grid-template-rows: 18px repeat(7, 16px);
186+
grid-template-rows: 16px repeat(7, 10px);
187187
gap: 3px;
188188
color: var(--gray-500);
189189
font-size: 10px;
@@ -228,13 +228,13 @@ const totalValue = computed(() => normalizedDays.value.reduce((sum, item) => sum
228228
229229
.heatmap-week {
230230
display: grid;
231-
grid-template-rows: repeat(7, 16px);
231+
grid-template-rows: repeat(7, 10px);
232232
gap: 3px;
233233
}
234234
235235
.heatmap-cell {
236236
width: 100%;
237-
height: 16px;
237+
height: 10px;
238238
transition: filter 0.2s ease;
239239
240240
&:hover {

‎frontend/src/modules/session/ui/CooperationTree.vue‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
<FallbackAvatar
6969
:name="item.name"
7070
:seed="item.session.session_id"
71-
kind="agent"
71+
kind="session"
7272
:size="18"
7373
shape="rounded"
7474
decorative

‎frontend/src/modules/session/ui/tools/renderers/CooperationTool.vue‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
:title="target.name || '会话信息尚未返回'"
1818
@click="target.sessionId && cooperationView.openSession(target.sessionId)"
1919
>
20-
<FallbackAvatar v-if="target.sessionId" :name="target.name" :seed="target.sessionId" kind="agent" :size="18" shape="rounded" decorative />
20+
<FallbackAvatar v-if="target.sessionId" :name="target.name" :seed="target.sessionId" kind="session" :size="18" shape="rounded" decorative />
2121
<span>{{ target.name || '会话' }}</span>
2222
</component>
2323
</template>
@@ -30,7 +30,7 @@
3030
</div>
3131
<div v-if="isList && expanded" class="event-session-list">
3232
<button v-for="target in targets" :key="target.sessionId" type="button" class="event-target" @click="cooperationView.openSession(target.sessionId)">
33-
<FallbackAvatar :name="target.name" :seed="target.sessionId" kind="agent" :size="18" shape="rounded" decorative />
33+
<FallbackAvatar :name="target.name" :seed="target.sessionId" kind="session" :size="18" shape="rounded" decorative />
3434
<span>{{ target.name || '会话' }}</span>
3535
<ChevronRight :size="13" aria-hidden="true" />
3636
</button>

‎frontend/src/modules/session/ui/workspace/AgentPanel.vue‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
:src="section.avatar"
3333
:name="section.title"
3434
:seed="section.avatarSeed"
35-
kind="agent"
35+
kind="session"
3636
:size="18"
3737
shape="rounded"
3838
/>

‎frontend/src/shared/lib/avatar/generator.js‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import glyphs from '@dicebear/styles/glyphs.json' with { type: 'json' }
33
import clay from '@dicebear/styles/clay.json' with { type: 'json' }
44
import shapeGrid from '@dicebear/styles/shape-grid.json' with { type: 'json' }
55
import gaze from '@dicebear/styles/gaze.json' with { type: 'json' }
6+
import lorelei from '@dicebear/styles/lorelei.json' with { type: 'json' }
7+
import notionists from '@dicebear/styles/notionists.json' with { type: 'json' }
68
import { presets, paletteOptions } from './presets.js'
79

8-
export const defaultStyles = { user: 'glyphs', agent: 'clay' }
10+
export const defaultStyles = { user: 'notionists', agent: 'lorelei', session: 'gaze' }
911

1012
const definitions = new Map(
11-
Object.entries({ glyphs, clay, 'shape-grid': shapeGrid, gaze }).map(([name, definition]) => [
12-
name,
13-
new Style(definition)
14-
])
13+
Object.entries({ glyphs, clay, 'shape-grid': shapeGrid, gaze, lorelei, notionists }).map(
14+
([name, definition]) => [name, new Style(definition)]
15+
)
1516
)
1617

1718
// 只开放 Glyphs 的底纸颜色;蒙版与所有几何保持上游定义。

0 commit comments

Comments
 (0)