feat(web): improve Mermaid diagram styling
This commit is contained in:
parent
a1068f0ec1
commit
aa8ccec738
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
- Mermaid 图表采用更清晰的科研配色与更精致的图框,新生成的流程图还会按数据、处理、判断、结果等角色使用协调的语义色,减少单调的灰白图。
|
||||
|
||||
- 管理后台总览按“当前运行”和“运营资源”重新组织,执行容量改为精简摘要并可从右侧详情面板查看队列、容器、用户占用与宿主资源,异常状态和近期指标也更容易识别。
|
||||
|
||||
## 0.70.0 — 2026-09-02
|
||||
|
|
@ -20,8 +22,6 @@
|
|||
|
||||
- 专业软件节点启用完整的新管理界面,节点状态、首次注册、软件环境、本机任务、ANSYS 验收和数据目录迁移均可直接管理;应用图标、导航、状态提示和窄窗口布局也更清晰,关闭窗口后仍会继续在托盘运行。
|
||||
|
||||
- 删除已发布文件后会释放个人存储配额;管理员可分别查看用户当前文件、隐藏回收站及物理总占用。
|
||||
|
||||
## 0.69.1 — 2026-08-27
|
||||
|
||||
- 专业软件任务的进度与结果改为在当前对话左侧集中堆叠,不再用多条结果消息打断正文;可直接打开 Blender 等软件的多张预览,手机端从“软件结果”入口统一查看。
|
||||
|
|
|
|||
|
|
@ -161,6 +161,14 @@ _HOST_ENV_BLOCK = """\
|
|||
## 运行环境(本地 host)
|
||||
`shell` 走的是 **Windows cmd.exe**(非 bash):避免 unix-only flag,`mkdir -p` 不识别 → 用 `run_python` 的 `os.makedirs(..., exist_ok=True)` 建目录;复杂管道/重定向用 run_python 更稳。"""
|
||||
|
||||
_MERMAID_STYLE_BLOCK = """\
|
||||
|
||||
## Mermaid 视觉规范
|
||||
生成 Mermaid 图时默认采用**克制的语义配色**,不要输出全灰单色图,也不要随机彩虹色:
|
||||
- 流程图 / 架构图用 `classDef` 按角色分组,通常 3–5 色足够:输入/数据用蓝色,处理/模块用青绿色,判断/风险用橙色,结果/成功用绿色,异常用红色;同类节点保持同色。
|
||||
- 使用浅色填充、较深描边与高对比深色文字,线条颜色统一;分组框比节点更淡,避免大面积高饱和背景。
|
||||
- 颜色服务于信息层级;若用户指定品牌色、黑白打印或已有 `classDef` / `style` 规则,优先遵循用户设置,不要覆盖。"""
|
||||
|
||||
|
||||
def load_config() -> dict:
|
||||
return yaml.safe_load((ROOT / "config" / "agent.yaml").read_text(encoding="utf-8")) or {}
|
||||
|
|
@ -363,6 +371,7 @@ def _build_system_prompt(
|
|||
is_docker = os.getenv("ZCBOT_SANDBOX_BACKEND", "host").lower() == "docker"
|
||||
# 运行环境段紧跟模板(平台/网络是基础事实,放前面);general_v1 的「平台」段指向这里。
|
||||
prompt += _CONTAINER_ENV_BLOCK if is_docker else _HOST_ENV_BLOCK
|
||||
prompt += _MERMAID_STYLE_BLOCK
|
||||
if skills.skills:
|
||||
prompt += f"\n\n## 可用 skill (用 load_skill 加载完整指引)\n{skills.discovery_block()}"
|
||||
# .memory/ 在 agent 视角下的可写路径:docker 给容器路径,host 给宿主绝对路径。
|
||||
|
|
|
|||
|
|
@ -78,6 +78,11 @@ test("renders completed mermaid blocks with strict local configuration", async (
|
|||
assert.equal(calls.initialize.length, 1);
|
||||
assert.equal(calls.initialize[0].securityLevel, "strict");
|
||||
assert.equal(calls.initialize[0].startOnLoad, false);
|
||||
assert.equal(calls.initialize[0].theme, "base");
|
||||
assert.equal(calls.initialize[0].themeVariables.primaryColor, "#eaf2ff");
|
||||
assert.equal(calls.initialize[0].themeVariables.secondaryColor, "#e8f7f3");
|
||||
assert.equal(calls.initialize[0].themeVariables.tertiaryColor, "#fff4df");
|
||||
assert.equal(calls.initialize[0].themeVariables.pie5, "#d96c75");
|
||||
assert.equal(calls.render[0].source, "flowchart LR\nA --> B");
|
||||
assert.equal(fixture.pre.replacement.className, "mermaid-diagram");
|
||||
assert.equal(fixture.pre.replacement.children[0].innerHTML, "<svg viewBox='0 0 10 10'></svg>");
|
||||
|
|
|
|||
|
|
@ -75,6 +75,15 @@ class TestSystemPromptPaths(unittest.TestCase):
|
|||
self.assertIn(str(wd), prompt)
|
||||
self.assertNotIn("/workspace/数据资源展示", prompt)
|
||||
|
||||
def test_mermaid_visual_guidance_is_backend_independent(self):
|
||||
for backend in ("docker", "host"):
|
||||
with self.subTest(backend=backend):
|
||||
prompt, _, _ = _build(backend)
|
||||
self.assertIn("## Mermaid 视觉规范", prompt)
|
||||
self.assertIn("`classDef` 按角色分组", prompt)
|
||||
self.assertIn("不要输出全灰单色图", prompt)
|
||||
self.assertIn("用户指定品牌色", prompt)
|
||||
|
||||
def test_rename_guard_only_when_tool_is_available(self):
|
||||
interactive, _, _ = _build("docker", allow_rename=True)
|
||||
scheduled, _, _ = _build("docker", allow_rename=False)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,53 @@ const MERMAID_CONFIG = Object.freeze({
|
|||
startOnLoad: false,
|
||||
securityLevel: "strict",
|
||||
suppressErrorRendering: true,
|
||||
theme: "neutral",
|
||||
// A restrained scientific palette. Author-defined classDef/style rules still
|
||||
// take precedence, while unstyled diagrams get a consistent visual baseline.
|
||||
theme: "base",
|
||||
themeVariables: Object.freeze({
|
||||
background: "#ffffff",
|
||||
primaryColor: "#eaf2ff",
|
||||
primaryTextColor: "#17324d",
|
||||
primaryBorderColor: "#5b8fc9",
|
||||
secondaryColor: "#e8f7f3",
|
||||
secondaryTextColor: "#163c35",
|
||||
secondaryBorderColor: "#4f9f8d",
|
||||
tertiaryColor: "#fff4df",
|
||||
tertiaryTextColor: "#594018",
|
||||
tertiaryBorderColor: "#d79a3b",
|
||||
lineColor: "#60758a",
|
||||
textColor: "#25384a",
|
||||
mainBkg: "#eaf2ff",
|
||||
secondBkg: "#e8f7f3",
|
||||
border1: "#5b8fc9",
|
||||
border2: "#4f9f8d",
|
||||
arrowheadColor: "#60758a",
|
||||
clusterBkg: "#f7f9fc",
|
||||
clusterBorder: "#b9c8d8",
|
||||
actorBkg: "#eaf2ff",
|
||||
actorBorder: "#5b8fc9",
|
||||
actorTextColor: "#17324d",
|
||||
actorLineColor: "#8ca0b3",
|
||||
signalColor: "#536b82",
|
||||
signalTextColor: "#25384a",
|
||||
labelBoxBkgColor: "#f7f9fc",
|
||||
labelBoxBorderColor: "#b9c8d8",
|
||||
labelTextColor: "#25384a",
|
||||
loopTextColor: "#25384a",
|
||||
noteBkgColor: "#fff4df",
|
||||
noteBorderColor: "#d79a3b",
|
||||
noteTextColor: "#594018",
|
||||
activationBkgColor: "#d9eee9",
|
||||
activationBorderColor: "#4f9f8d",
|
||||
pie1: "#4f7cac",
|
||||
pie2: "#5ca89a",
|
||||
pie3: "#e4a64a",
|
||||
pie4: "#a879b2",
|
||||
pie5: "#d96c75",
|
||||
pie6: "#6d9dc5",
|
||||
pie7: "#84b59f",
|
||||
pie8: "#d8b365",
|
||||
}),
|
||||
maxTextSize: 50000,
|
||||
maxEdges: 500,
|
||||
fontFamily: '-apple-system, "Segoe UI", "Microsoft YaHei", sans-serif',
|
||||
|
|
|
|||
|
|
@ -442,11 +442,12 @@ header .who {
|
|||
|
||||
.mermaid-diagram {
|
||||
margin: 14px 0;
|
||||
padding: 14px;
|
||||
padding: 18px;
|
||||
overflow-x: auto;
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: var(--r-lg);
|
||||
background: #ffffff;
|
||||
border: 1px solid #dce6f2;
|
||||
border-radius: var(--r-xl);
|
||||
background: linear-gradient(145deg, #ffffff 0%, #f8fbff 100%);
|
||||
box-shadow: 0 6px 22px rgba(50, 79, 108, 0.08);
|
||||
}
|
||||
|
||||
.mermaid-viewport {
|
||||
|
|
@ -458,6 +459,7 @@ header .who {
|
|||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
filter: drop-shadow(0 2px 3px rgba(38, 61, 82, 0.06));
|
||||
}
|
||||
|
||||
.mermaid-notice {
|
||||
|
|
|
|||
Loading…
Reference in New Issue