Merge branch 'deai2'
Co-Authored-By: Claude Fable 5.1 <[email protected]> # Conflicts: # apps/server/src/modules/acquisition-organize/services/organize.ts # apps/web/app/routes/console/sites.$siteId.tsx
This commit is contained in:
commit
12bc4664b6
247 files changed
+2658
-2148
No files matched your search
@@ -15,7 +15,7 @@ class MemStore {
|
||||
}
|
||||
|
||||
// 验收 S7:生产构建里 ?mock=1 不得把演示数据当真实运行展示
|
||||
describe("Agent 演示开关", () => {
|
||||
describe("智能体演示开关", () => {
|
||||
it("只在开发构建或后端 provider=fake 时允许", () => {
|
||||
expect(agentMockAllowed({ dev: true })).toBe(true);
|
||||
expect(agentMockAllowed({ dev: false, provider: "fake" })).toBe(true);
|
||||
|
||||
@@ -155,9 +155,9 @@ export const DOWNLOAD_STATUS_TONE: Record<DownloadStatus, "success" | "warning"
|
||||
|
||||
export const PAUSE_REASON_LABEL = {
|
||||
user: "用户暂停",
|
||||
threshold: "阈值暂停",
|
||||
threshold: "下载盘满暂停",
|
||||
policy: "策略暂停",
|
||||
agent: "Agent 暂停",
|
||||
agent: "智能体暂停",
|
||||
} as const;
|
||||
|
||||
export const PLAN_STATUS_LABEL: Record<PlanStatus, string> = {
|
||||
|
||||
@@ -106,7 +106,7 @@ export function useFetchFeedNow() {
|
||||
export function feedGapHint(f: FeedSource, now = Date.now()): string | null {
|
||||
if (f.possibleGap) {
|
||||
const at = new Date(f.possibleGap.detectedAt).toLocaleString("zh-CN", { hour12: false });
|
||||
return `疑似缺口(${at} 检测,${f.possibleGap.backfillQueued ? "已排补漏" : "Feed 未关联站点,无法自动补漏"})`;
|
||||
return `疑似缺口(${at} 检测,${f.possibleGap.backfillQueued ? "已排补漏" : "RSS 未关联站点,无法自动补漏"})`;
|
||||
}
|
||||
if (!f.enabled || !f.lastSuccessAt) return null;
|
||||
const gapMs = now - new Date(f.lastSuccessAt).getTime();
|
||||
|
||||
@@ -64,7 +64,7 @@ export function inventoryFlags(
|
||||
});
|
||||
}
|
||||
if (releaseResolution && releaseResolution === "resolved" && flags.length === 0) {
|
||||
flags.push({ key: "tracked", label: "已识别,无版本目标", tone: "neutral" });
|
||||
flags.push({ key: "tracked", label: "已识别,无收录版本", tone: "neutral" });
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export const RECORD_STATUS_TONE: Record<OrganizationStatus, "success" | "warning
|
||||
cancelled: "neutral",
|
||||
};
|
||||
|
||||
export const TRIGGER_LABEL: Record<OrganizationTrigger, string> = { auto: "自动", manual: "手动", agent: "Agent" };
|
||||
export const TRIGGER_LABEL: Record<OrganizationTrigger, string> = { auto: "自动", manual: "手动", agent: "智能体" };
|
||||
|
||||
/** dryRun 生成的整理计划冻结为 artifact(kind=plan),GET /artifacts/{id} 读取逐文件预览 */
|
||||
export function useArtifact(id: string | null | undefined) {
|
||||
|
||||
@@ -99,14 +99,14 @@ export function useRuleSuppressions() {
|
||||
export type RuleRefs = {
|
||||
/** 规则组 id → 引用它的订阅(params.ruleGroupIds 或私有组) */
|
||||
subscriptions: Map<string, { id: string; title: string }[]>;
|
||||
/** 规则组 id → 引用它的版本目标 */
|
||||
/** 规则组 id → 引用它的收录版本 */
|
||||
slots: Map<string, { id: string; name: string }[]>;
|
||||
};
|
||||
|
||||
const SubPage = cursorPage(Subscription);
|
||||
const SlotPage = cursorPage(AcquisitionSlot);
|
||||
|
||||
/** 引用关系:列表接口不带引用计数,前端从订阅与版本目标反查(各取前 200 条) */
|
||||
/** 引用关系:列表接口不带引用计数,前端从订阅与收录版本反查(各取前 200 条) */
|
||||
export function useRuleRefs() {
|
||||
return useQuery({
|
||||
queryKey: ruleKeys.refs,
|
||||
@@ -150,7 +150,7 @@ function useInvalidate() {
|
||||
const qc = useQueryClient();
|
||||
return () => {
|
||||
void qc.invalidateQueries({ queryKey: ruleKeys.all });
|
||||
// 旧偏好标签页与订阅/版本目标的规则组显示同源
|
||||
// 旧偏好标签页与订阅/收录版本的规则组显示同源
|
||||
void qc.invalidateQueries({ queryKey: ["preferences"] });
|
||||
};
|
||||
}
|
||||
@@ -175,7 +175,7 @@ export function useUpdateRuleGroup() {
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除:标记删除并写抑制记录;被版本目标/订阅引用时 409 */
|
||||
/** 删除:标记删除并写抑制记录;被收录版本/订阅引用时 409 */
|
||||
export function useDeleteRuleGroup() {
|
||||
const done = useInvalidate();
|
||||
return useMutation({
|
||||
|
||||
@@ -105,7 +105,7 @@ export function useSiteRequestStats(siteId: string | undefined) {
|
||||
export function accessSummary(s: SiteRequestStats): string {
|
||||
const dur = (sec: number) => (sec % 3600 === 0 ? `${sec / 3600} 小时` : `${Math.round(sec / 60)} 分钟`);
|
||||
const parts = [
|
||||
`快照每 ${dur(s.snapshotIntervalSec)} ${s.access.snapshotMaxPages} 页`,
|
||||
`抓取每 ${dur(s.snapshotIntervalSec)} ${s.access.snapshotMaxPages} 页`,
|
||||
`健康检测每 ${dur(s.access.healthCheckIntervalSec)}`,
|
||||
];
|
||||
if (s.access.detailCacheSec > 0) parts.push(`详情缓存 ${dur(s.access.detailCacheSec)}`);
|
||||
|
||||
@@ -77,7 +77,7 @@ export function useUpdateSubscription() {
|
||||
api.patch<unknown>(`/subscriptions/${id}`, body).then((d) => parseOrThrow(Subscription, d, "/subscriptions")),
|
||||
onSuccess: () => {
|
||||
void qc.invalidateQueries({ queryKey: subscriptionKeys.all });
|
||||
// best_version 写到版本目标的升级策略
|
||||
// best_version 写到收录版本的升级策略
|
||||
void qc.invalidateQueries({ queryKey: ["slots"] });
|
||||
},
|
||||
});
|
||||
@@ -246,7 +246,7 @@ export function useFillSlot() {
|
||||
});
|
||||
}
|
||||
|
||||
/** 版本目标排序:第一个成为主版本 */
|
||||
/** 收录版本排序:第一个成为主版本 */
|
||||
export function useSetSlotOrder() {
|
||||
const done = useInvalidateSubs();
|
||||
return useMutation({
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
type TaskStatus,
|
||||
} from "@umt/contracts";
|
||||
import { organizationActionLabel, organizationLabel } from "~/lib/labels.ts";
|
||||
import { PLAN_STATUS_LABEL } from "./downloads.ts";
|
||||
import { humanizeReason, reasonLine } from "~/lib/reasons.ts";
|
||||
import { PAUSE_REASON_LABEL, PLAN_STATUS_LABEL } from "./downloads.ts";
|
||||
import { apiParsed } from "./parse.ts";
|
||||
|
||||
// 业务任务视图:按 trace 汇总的业务时间线(参考 MovieClaw task-activity)
|
||||
@@ -23,7 +24,7 @@ const RecordPage = cursorPage(PublicOrganizationRecord);
|
||||
const DecisionPage = cursorPage(Decision);
|
||||
|
||||
const RESOLUTION_LABEL = {
|
||||
unresolved: "待识别",
|
||||
unresolved: "未识别",
|
||||
resolved: "已识别",
|
||||
ambiguous: "有歧义,待确认",
|
||||
unidentifiable: "无法识别",
|
||||
@@ -173,7 +174,7 @@ export function buildTimeline(input: {
|
||||
stage: "plan",
|
||||
at: plan.createdAt,
|
||||
title: `创建下载计划(${plan.purpose === "fill" ? "补缺" : plan.purpose === "upgrade" ? "升级" : "换源"})`,
|
||||
detail: plan.statusReason,
|
||||
detail: humanizeReason(plan.statusReason),
|
||||
tone: "neutral",
|
||||
});
|
||||
if (plan.updatedAt !== plan.createdAt)
|
||||
@@ -182,7 +183,7 @@ export function buildTimeline(input: {
|
||||
stage: "plan",
|
||||
at: plan.updatedAt,
|
||||
title: `计划状态:${PLAN_STATUS_LABEL[plan.status]}`,
|
||||
detail: plan.statusReason,
|
||||
detail: humanizeReason(plan.statusReason),
|
||||
tone: plan.status === "failed" ? "destructive" : plan.status === "expired" ? "warning" : "neutral",
|
||||
});
|
||||
}
|
||||
@@ -199,7 +200,7 @@ export function buildTimeline(input: {
|
||||
key: "dl-pause",
|
||||
stage: "download",
|
||||
at: task.updatedAt,
|
||||
title: task.pauseReason === "threshold" ? "缓存达到硬阈值,已暂停" : `已暂停(${task.pauseReason})`,
|
||||
title: task.pauseReason === "threshold" ? "下载盘超过暂停线,已暂停" : PAUSE_REASON_LABEL[task.pauseReason],
|
||||
tone: "warning",
|
||||
ongoing: task.status === "paused",
|
||||
});
|
||||
@@ -239,7 +240,15 @@ export function buildTimeline(input: {
|
||||
stage: "organization",
|
||||
at: r.startedAt ?? r.createdAt,
|
||||
title: `整理 ${organizationActionLabel(r.action)}:${organizationLabel(r.status).label}`,
|
||||
detail: `${c.succeeded}/${c.total} 文件成功${c.failed ? `,${c.failed} 失败` : ""}${c.skipped ? `,${c.skipped} 跳过` : ""}${r.reason ? ` · ${r.reason.message}` : ""}`,
|
||||
detail:
|
||||
[
|
||||
c.total ? `${c.succeeded}/${c.total} 个文件成功` : null,
|
||||
c.failed ? `${c.failed} 个失败` : null,
|
||||
c.skipped ? `${c.skipped} 个跳过` : null,
|
||||
r.reason ? reasonLine(r.reason) : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" · ") || null,
|
||||
tone: RECORD_TONE[r.status],
|
||||
href: `/console/organize/${r.id}`,
|
||||
ongoing: r.status === "running" || r.status === "queued",
|
||||
@@ -260,7 +269,7 @@ export function buildTimeline(input: {
|
||||
key: `agent-${d.id}`,
|
||||
stage: "agent",
|
||||
at: d.updatedAt,
|
||||
title: "Agent 已介入调查",
|
||||
title: "智能体已介入调查",
|
||||
tone: "neutral",
|
||||
href: `/console/agent/${d.agentRunId}`,
|
||||
});
|
||||
@@ -275,7 +284,9 @@ export function buildTimeline(input: {
|
||||
at: t.startedAt ?? t.createdAt,
|
||||
title: `任务 ${TASK_KIND_LABEL[t.kind] ?? t.kind}:${TASK_STATUS_TEXT[t.status] ?? t.status}`,
|
||||
detail:
|
||||
[t.attempts > 1 ? `第 ${t.attempts} 次尝试` : null, t.waitReason, err].filter(Boolean).join(" · ") || null,
|
||||
[t.attempts > 1 ? `第 ${t.attempts} 次尝试` : null, humanizeReason(t.waitReason), humanizeReason(err)]
|
||||
.filter(Boolean)
|
||||
.join(" · ") || null,
|
||||
tone: TASK_STATUS_TONE[t.status],
|
||||
href: `/console/tasks/${encodeURIComponent(t.id)}`,
|
||||
ongoing: ACTIVE_TASK.includes(t.status),
|
||||
|
||||
Reference in new issue
Block a user