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); }