refactor(copy): 术语统一——收录版本、模型服务、智能体等(DEAI-2)

- 版本目标 → 收录版本(前后端用户可见字符串、能力描述、给模型的提示)
- Agent 上游 / 上游 → 模型服务;界面上的 Agent / Agent 会话 → 智能体 / 智能体会话
- 身份歧义 / 识别有歧义 / 无法确定作品 → 没识别出作品;待识别(池) → 未识别
- 建档 → 加入媒体库;资产 → 文件;库根 → 媒体库目录;纳管 → 本工具 / 外部任务;
  哨兵 → 标记文件 / 检查目录;站点快照 → 抓取;Feed / RSS 订阅 / 来源健康 → RSS
- 代码标识符、API 字段名、迁移文件不改;glossary.md 同步;smoke 选择器跟随

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-29 20:35:43 +08:00
1 parent d282212a6b
commit 4480fc346d
212 files changed
+741 -715

No files matched your search

@@ -19,7 +19,7 @@ import { errorMessage } from "~/lib/api.ts";
import { formatBytes } from "~/lib/utils.ts";
const STEPS = [
"生成下载计划,预留版本目标和预算;每个版本目标同时只有一个在途计划",
"生成下载计划,预留收录版本和预算;每个收录版本同时只有一个在途计划",
"已有相同资源或相同 hash 的任务时直接接管,不重复提交",
"缓存卷超过硬阈值或读不到磁盘状态时无法提交",
"提交前复核免费、做种等易变字段",
@@ -93,7 +93,7 @@ export function DownloadDialog({
{slots.length ? (
<div className="flex flex-wrap items-center gap-2">
<FilterSelect
label="版本目标"
label="收录版本"
value={slotId}
onChange={setSlotId}
allLabel="自动匹配"
@@ -103,7 +103,7 @@ export function DownloadDialog({
) : (
<p className="text-meta text-muted-foreground">
{release.entity
? "这个作品没有版本目标。先在订阅里新建。"
? "这个作品没有收录版本。先在订阅里新建。"
: "资源未关联本地作品。先在「身份与元数据」指定。"}
</p>
)}
@@ -143,7 +143,7 @@ export function DownloadDialog({
}}
>
<Bot />
委托 Agent
委托智能体
</Button>
<Button onClick={go} disabled={submit.isPending || !!done || !release.entity}>
<Download />
@@ -122,14 +122,14 @@ export function FeedFormDialog({
if (!parsed.success) {
const e = zodFieldErrors(parsed.error.issues);
if (e.pollIntervalSec) e.pollMin = "轮询间隔至少 1 分钟";
if (e.url) e.url = feed ? "URL 格式不对" : "填写完整的 Feed URL";
if (e.url) e.url = feed ? "URL 格式不对" : "填写完整的 RSS 地址";
setErrors(e);
return;
}
setErrors({});
const done = {
onSuccess: () => {
toast.success(feed ? "已保存" : "Feed 已创建");
toast.success(feed ? "已保存" : "RSS 已创建");
onOpenChange(false);
},
onError: (e: unknown) => toast.error(errorMessage(e)),
@@ -142,7 +142,7 @@ export function FeedFormDialog({
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-lg">
<DialogHeader>
<DialogTitle>{feed ? "编辑 Feed" : "新建 Feed"}</DialogTitle>
<DialogTitle>{feed ? "编辑 RSS" : "新建 RSS"}</DialogTitle>
<DialogDescription>URL 加密保存,之后只显示脱敏地址。</DialogDescription>
</DialogHeader>
<form
@@ -208,8 +208,8 @@ export function FeedTable({
selectedKey={openId}
empty={{
icon: Rss,
title: filtered ? "没有符合筛选的 Feed" : "还没有 Feed",
description: filtered ? undefined : "新建 Feed 后按轮询间隔抓取,新资源进入识别和收录评估。",
title: filtered ? "没有符合筛选的 RSS" : "还没有 RSS",
description: filtered ? undefined : "新建 RSS 后按轮询间隔抓取,新资源进入识别和收录评估。",
}}
/>
@@ -67,7 +67,7 @@ function LocalInventory({ release, entry }: { release: WorkbenchRelease; entry:
) : (
<>
<p className="text-meta text-muted-foreground">
{slots.length ? `${slots.length} 个版本目标` : "没有版本目标"}
{slots.length ? `${slots.length} 个收录版本` : "没有收录版本"}
{entry ? (entry.subscribed ? " · 已订阅" : " · 未订阅") : ""}
</p>
{candidates.length ? (
@@ -79,7 +79,7 @@ function LocalInventory({ release, entry }: { release: WorkbenchRelease; entry:
<li key={c.slotId} className="rounded-lg border border-border/70 px-3 py-2">
<div className="flex flex-wrap items-center gap-2 text-caption">
<StatusBadge tone={d.tone}>{d.label}</StatusBadge>
<span className="text-foreground">{slot ? `目标 ${slot.name}` : "版本目标"}</span>
<span className="text-foreground">{slot ? `目标 ${slot.name}` : "收录版本"}</span>
<span className="text-muted-foreground">{relTime(c.evaluatedAt)}评估</span>
</div>
{c.reasons.length ? (
@@ -158,7 +158,8 @@ export function ReleaseDetailSheet({
})
}
>
<Bot />问 Agent
<Bot />
问智能体
</Button>
<Button size="sm" onClick={() => setDl(true)}>
<Download />
@@ -263,7 +264,7 @@ export function ReleaseDetailSheet({
</DetailSection>
{detail.data?.observations.length ? (
<DetailSection title="Feed 观察">
<DetailSection title="RSS 抓取记录">
<ul className="space-y-1 text-caption">
{detail.data.observations.map((o) => (
<li key={o.observationId} className="flex flex-wrap justify-between gap-2">
@@ -162,9 +162,9 @@ export function relTime(iso: string | null | undefined, now = Date.now()): strin
}
export const ORIGIN_LABEL: Record<WorkbenchRelease["origin"], string> = {
snapshot: "快照",
feed: "Feed",
live: "实时补查",
snapshot: "抓取",
feed: "RSS",
live: "去站点搜",
unknown: "来源未知",
};
@@ -66,7 +66,7 @@ export function SpecTags({ r }: { r: Pick<WorkbenchRelease, "parsed" | "title" |
/** 没有关联作品时的说明(明确写出,不猜) */
export function unresolvedLabel(release: Pick<WorkbenchRelease, "resolutionStatus">): string {
return release.resolutionStatus === "ambiguous"
? "识别有歧义"
? "没识别出作品"
: release.resolutionStatus === "unidentifiable"
? "无法识别"
: release.resolutionStatus === "rejected"
@@ -10,10 +10,10 @@ import { formatDateTime } from "~/lib/utils.ts";
import { relTime, SITE_HEALTH } from "./release-fields.ts";
const KIND: Record<SiteSnapshot["kind"], string> = {
periodic: "定期快照",
periodic: "定期抓取",
backfill: "缺口补漏",
live_search: "实时补查",
manual: "手动快照",
live_search: "去站点搜",
manual: "手动抓取",
};
const STATUS: Record<SiteSnapshot["status"], { label: string; tone: StatusTone }> = {
running: { label: "进行中", tone: "neutral" },
@@ -44,10 +44,10 @@ export function SnapshotPanel({ site }: { site: Site }) {
{!site.enabled ? <StatusBadge tone="warning">站点已停用</StatusBadge> : null}
{site.snapshotEnabled ? (
<StatusBadge tone={stale ? "warning" : "success"}>
{stale ? "快照过期" : "快照新鲜"} · {relTime(site.lastSnapshotAt)}
{stale ? "抓取已过期" : "已抓取"} · {relTime(site.lastSnapshotAt)}
</StatusBadge>
) : (
<StatusBadge>未开启定期快照</StatusBadge>
<StatusBadge>未开启定期抓取</StatusBadge>
)}
{site.snapshotIntervalSec ? (
<span className="text-meta text-muted-foreground">
@@ -64,14 +64,14 @@ export function SnapshotPanel({ site }: { site: Site }) {
snap.mutate(
{ id: site.id, maxPages: 2 },
{
onSuccess: () => toast.success(`${site.name}:快照已排队`),
onSuccess: () => toast.success(`${site.name}:已开始抓取`),
onError: (e) => toast.error(errorMessage(e)),
},
)
}
>
<Camera />
手动快照
手动抓取
</Button>
</div>
<div className="mt-3">
@@ -80,7 +80,7 @@ export function SnapshotPanel({ site }: { site: Site }) {
) : snaps.error ? (
<ErrorState plain error={snaps.error} onRetry={() => void snaps.refetch()} />
) : !snaps.data.items.length ? (
<p className="text-caption text-muted-foreground">还没有快照。</p>
<p className="text-caption text-muted-foreground">还没抓取过。</p>
) : (
<ul className="divide-y divide-border/60 text-caption">
{snaps.data.items.map((s) => (