fix(web): 巡检目标模板的占位符显示成名称(FIX-7)

执行时 renderGoal 已正确替换(补单测);界面显示的是模板本身,{{now}} 等改成「当前时间」标签。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 00:00:03 +08:00
1 parent 417af9f253
commit 23bd8cfe45
5 files changed
+97 -6

No files matched your search

@@ -15,7 +15,7 @@ import { agentRunLabel, formatRelative } from "~/lib/labels.ts";
import { cn } from "~/lib/utils.ts";
import { NextRun, useJobActions } from "./auto-task-list.tsx";
import { IntervalSelect } from "./interval-select.tsx";
import { CHECK_TRIGGER_LABEL, formatUsd, RUN_STATUS } from "./labels.ts";
import { CHECK_TRIGGER_LABEL, formatUsd, goalTemplateParts, RUN_STATUS } from "./labels.ts";
// 计划页「智能体巡检」:到点按目标模板发起一次智能体会话(kind=agent_check),一个巡检一张卡片。
// 卡片默认只显示名称、开关、间隔、上次结果与费用;目标、能力、预算、模型、最近会话收进「详情」。
@@ -43,6 +43,27 @@ export type DefaultUpstream = {
const modelsTitle = (models: { provider: string | null; model: string; count: number }[]) =>
models.map((m) => `${m.provider ? `${m.provider} · ` : ""}${m.model}:${m.count} 次`).join("\n");
/** 目标模板:占位符显示成名称标签(执行时替换成实际值),不露 `{{now}}` */
function GoalTemplate({ template }: { template: string }) {
return (
<>
{goalTemplateParts(template).map((p, i) =>
"text" in p ? (
<span key={i}>{p.text}</span>
) : (
<span
key={i}
title="执行时替换成实际值"
className="mx-0.5 rounded-tight bg-foreground/[0.07] px-1 text-muted-foreground"
>
{p.label}
</span>
),
)}
</>
);
}
function Field({ label, children }: { label: string; children: ReactNode }) {
return (
<>
@@ -151,8 +172,8 @@ export function AgentCheckCard({
<TechInfo title="详情" columns={1}>
<dl className="grid grid-cols-[4.5rem_minmax(0,1fr)] items-baseline gap-x-3 gap-y-1.5">
<Field label="目标">
<span className="line-clamp-4 break-words" title={c.goalTemplate}>
{c.goalTemplate ?? "—"}
<span className="line-clamp-4 break-words">
{c.goalTemplate ? <GoalTemplate template={c.goalTemplate} /> : "—"}
</span>
</Field>
<Field label="能力">