From 04b38a4a25a038ae94c86f5331d7d9360fa2005f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=89=E9=91=AB=E5=8D=87?= Date: Thu, 25 Jun 2026 15:57:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(task-buttons):=20append=5Fauth=20?= =?UTF-8?q?=E6=98=BE=E5=BC=8F=20server=5Fdefault=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=97=A7=E5=BA=93=20/api/task-buttons=20=E6=8A=A5=20500?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 旧库已存在 task_buttons 表时,启动期自动补列 _ensure_orm_columns_sync 会跳过 「NOT NULL 且无 server_default」的列,导致 2026-06-25 新增的 append_auth 永远补不上, GET /api/task-buttons 查询报 Unknown column → 500。给该列加 server_default="0" 后, 重启即自动 ALTER TABLE 补列,与迁移 20260625_01 保持一致。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../harness/deerflow/persistence/task_buttons/model.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_buttons/model.py b/offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_buttons/model.py index 838eadc0..be18d180 100644 --- a/offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_buttons/model.py +++ b/offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_buttons/model.py @@ -50,7 +50,10 @@ class TaskButtonRow(Base): open_mode: Mapped[str | None] = mapped_column(String(16), default="blank") # ``url`` 跳转是否追加登录态(token 登录的上游 token + 登录用户名),供外链所在的外部系统 # 校验当前登录用户。仅 token 登录(前端存有 token1)时实际拼上;非 token 登录自动跳过。 - append_auth: Mapped[bool] = mapped_column(Boolean, default=False) + # ``server_default`` 必须显式声明:否则在已存在 ``task_buttons`` 表的旧库上, + # 启动期自动补列 ``_ensure_orm_columns_sync`` 会跳过「NOT NULL 且无 server_default」 + # 的列(见 engine.py),导致该列永远补不上 → GET 查询报 Unknown column → 500。 + append_auth: Mapped[bool] = mapped_column(Boolean, default=False, server_default="0") # 追加 token / 用户名的查询参数名。可空,读时归一化为 ``token`` / ``username``。 auth_token_param: Mapped[str | None] = mapped_column(String(64), default="token") auth_name_param: Mapped[str | None] = mapped_column(String(64), default="username") From 864224e07c7ed347f08ec10503e1fea50e608dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=89=E9=91=AB=E5=8D=87?= Date: Thu, 25 Jun 2026 16:07:54 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(message-token-usage):=20=E9=80=9F?= =?UTF-8?q?=E5=BA=A6=E6=9D=A1=E4=B8=8B=E6=96=B9=E5=B8=B8=E9=A9=BB=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E5=90=AB=E4=B9=89=E5=9B=BE=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生成结束后在速度条下方展示一行图例(SpeedLegend),把进度条配色归并为用户视角的 延迟正常/微长/长 + 无响应四类说明,帮助用户理解速度条颜色代表的模型生成延迟状态。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../messages/message-token-usage.tsx | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/frontend-web/src/components/workspace/messages/message-token-usage.tsx b/frontend-web/src/components/workspace/messages/message-token-usage.tsx index f45b2ef0..21cf508b 100644 --- a/frontend-web/src/components/workspace/messages/message-token-usage.tsx +++ b/frontend-web/src/components/workspace/messages/message-token-usage.tsx @@ -31,6 +31,44 @@ export function formatDuration(ms: number): string { return `${mins}m ${secs}s`; } +/** + * 速度条颜色含义图例 —— 生成结束后常驻在速度条下方一行,向用户解释进度条 + * 颜色代表的「模型生成延迟」状态。进度条本身仍是 5 档(极快/流畅/一般/偏慢/ + * 缓慢)的连续配色;这里把它归并成用户视角的 3 类延迟 + 「无响应」来说明: + * 绿(#16a34a,极快/流畅) → 延迟正常 + * 黄(#eab308,一般) → 延迟微长 + * 红(#ef4444,偏慢/缓慢) → 延迟长,可能失败 + * 灰(#9ca3af) → 无响应(无进度条/0 tok/s),任务失败,请重试 + */ +const SPEED_LEGEND: { color: string; label: string }[] = [ + { color: "#16a34a", label: "延迟正常" }, + { color: "#eab308", label: "延迟微长" }, + { color: "#ef4444", label: "延迟长,可能失败" }, + { color: "#9ca3af", label: "无响应,任务失败,请重试" }, +]; + +export function SpeedLegend({ className }: { className?: string }) { + return ( + + {SPEED_LEGEND.map((item) => ( + + + {item.label} + + ))} + + ); +} + export function SpeedPill({ metric }: { metric: MessageMetric }) { const fill = Math.max(0, Math.min(1, metric.tokensPerSec / FULL_SCALE_TOKENS_PER_SEC)); const { color, label } = classifySpeed(metric.tokensPerSec); @@ -132,6 +170,8 @@ export function MessageTokenUsage({ {formatDuration(resolvedMetric.durationMs)} )} + {/* 生成结束(非流式中)后常驻一行颜色含义说明。 */} + {!resolvedMetric.isActive && } ) : null}