Files
boss/src/lib/dispatch-plan-ui.ts
2026-04-04 03:00:34 +08:00

102 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export type DispatchPlanUiTarget = {
projectId: string;
threadDisplayName: string;
};
export type DispatchPlanUiPayload = {
planId: string;
status?: string;
summary?: string;
targets?: DispatchPlanUiTarget[];
};
export function latestPendingDispatchPlan(plans: DispatchPlanUiPayload[] | null | undefined) {
return (plans ?? []).find((plan) => plan.status === "pending_user_confirmation") ?? null;
}
export function latestRejectedDispatchPlan(plans: DispatchPlanUiPayload[] | null | undefined) {
return (plans ?? []).find((plan) => plan.status === "rejected") ?? null;
}
export type DispatchPlanComposerState = {
pendingDispatchPlan: DispatchPlanUiPayload | null;
rejectedDispatchPlan: DispatchPlanUiPayload | null;
recoveryHint: string | null;
recoveryActionLabel: string | null;
};
export function resolveDispatchPlanComposerState(
plans: DispatchPlanUiPayload[] | null | undefined,
): DispatchPlanComposerState {
const pendingDispatchPlan = latestPendingDispatchPlan(plans);
const rejectedDispatchPlan = pendingDispatchPlan ? null : latestRejectedDispatchPlan(plans);
if (rejectedDispatchPlan) {
return {
pendingDispatchPlan,
rejectedDispatchPlan,
recoveryHint: "上次推荐已拒绝。直接点击“重新生成新的推荐”即可继续协作,不用重新发送整条消息。",
recoveryActionLabel: "重新生成新的推荐",
};
}
if (pendingDispatchPlan) {
return {
pendingDispatchPlan,
rejectedDispatchPlan: null,
recoveryHint: "当前有待确认推荐,已折叠旧的拒绝状态。",
recoveryActionLabel: null,
};
}
return {
pendingDispatchPlan: null,
rejectedDispatchPlan: null,
recoveryHint: null,
recoveryActionLabel: null,
};
}
export function summarizeDispatchPlan(plan: DispatchPlanUiPayload | null | undefined) {
if (!plan) {
return "主 Agent 暂未生成推荐线程。";
}
const summary = plan.summary?.trim() || "主 Agent 已生成推荐线程。";
const titles = (plan.targets ?? [])
.map((target) => target.threadDisplayName?.trim() || "")
.filter(Boolean);
if (!titles.length) {
return summary;
}
return `${summary}\n推荐线程${titles.join("、")}`;
}
export function summarizeDispatchPlanCompact(plan: DispatchPlanUiPayload | null | undefined) {
if (!plan) {
return "主 Agent 暂未生成推荐线程。";
}
const summary = plan.summary?.trim() || "主 Agent 已生成推荐线程。";
const titles = (plan.targets ?? [])
.map((target) => target.threadDisplayName?.trim() || "")
.filter(Boolean);
if (!titles.length) {
return truncateDispatchSummary(summary);
}
return `推荐给:${titles.join("、")}\n${truncateDispatchSummary(summary)}`;
}
export function summarizeDispatchPlanLightTitle(plan: DispatchPlanUiPayload | null | undefined) {
const count = (plan?.targets ?? []).length;
return count > 0 ? `主 Agent 已推荐 ${count} 个线程` : "主 Agent 已推荐线程";
}
function truncateDispatchSummary(summary: string) {
return summary.length > 32 ? `${summary.slice(0, 32)}` : summary;
}
export function extractApprovedTargetProjectIds(plan: DispatchPlanUiPayload | null | undefined) {
return (plan?.targets ?? [])
.map((target) => target.projectId?.trim() || "")
.filter(Boolean);
}