102 lines
3.3 KiB
TypeScript
102 lines
3.3 KiB
TypeScript
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);
|
||
}
|