Files
next-tjwater-drainage-frontend/features/workbench/utils/scheduled-condition-prompts.ts
T

143 lines
5.2 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.
import { getRunningWorkflowDefinition } from "@/features/workbench/data/running-workflows";
import type { ScheduledConditionItem, ScheduledConditionStatus, WorkbenchAlert } from "@/features/workbench/types";
const SCHEDULED_CONDITION_ALERT_ID_PREFIX = "scheduled-condition-alert-";
const statusLabels: Record<ScheduledConditionStatus, string> = {
completed: "完成",
running: "执行中",
warning: "关注",
error: "异常",
pending: "预约"
};
export function createConditionConversationPrompt(condition: ScheduledConditionItem) {
const workflow =
condition.kind === "condition"
? getRunningWorkflowDefinition(condition)
: null;
const evidence = condition.evidence?.map((item, index) => `${index + 1}. ${item}`).join("\n") || "无";
const kpis =
condition.kind === "condition" && condition.kpis?.length
? condition.kpis
.map((kpi, index) => {
const value = `${kpi.value}${kpi.unit ?? ""}`;
const threshold = kpi.threshold ? `,阈值:${kpi.threshold}` : "";
return `${index + 1}. ${kpi.label}${value},状态:${getRiskLabel(kpi.status)}${threshold}`;
})
.join("\n")
: "无";
const report =
condition.kind === "condition" && condition.report
? [
condition.report.conclusion,
...condition.report.sections.map(
(section) => `${section.title}${section.items.join("")}`
)
].join("\n")
: null;
return [
"请继续分析这条工况任务,并基于当前上下文给出下一步调度建议。",
"",
`时间:${formatTime(condition.scheduledAt)}`,
"类型:历史工况",
workflow ? `任务工作流:${workflow.title}` : null,
workflow ? `工作流步骤:${workflow.steps.map((step, index) => `${index + 1}. ${step.title}`).join("")}` : null,
`标题:${condition.title}`,
`状态:${statusLabels[condition.status]}`,
`风险:${getRiskLabel(condition.riskLevel)}`,
`摘要:${condition.summary}`,
condition.detail ? `详情:${condition.detail}` : null,
`关键证据:\n${evidence}`,
`关键指标:\n${kpis}`,
report ? `工况报告:\n${report}` : null,
condition.recommendation ? `已有建议:${condition.recommendation}` : null,
condition.sessionId ? `sessionId${condition.sessionId}` : null,
"",
"请先说明当前判断,再列出需要人工确认的事项和建议动作。"
]
.filter(Boolean)
.join("\n");
}
export function createAlertQueueConversationPrompt({
alerts,
conditions
}: {
alerts: WorkbenchAlert[];
conditions: ScheduledConditionItem[];
}) {
const alertSummaries = alerts.map((alert, index) => {
const condition = findConditionForAlert(alert, conditions);
const baseSummary = [
`${index + 1}. ${alert.title}`,
"状态:待复核",
`时间:${alert.time}`,
`描述:${alert.description}`
];
if (!condition) {
return baseSummary.join("\n");
}
return [
...baseSummary,
`关联工况:${condition.title}`,
`工况状态:${statusLabels[condition.status]}`,
`风险等级:${getRiskLabel(condition.riskLevel)}`,
condition.detail ? `工况详情:${condition.detail}` : null,
condition.evidence?.length ? `关键证据:\n${condition.evidence.map((item, evidenceIndex) => `${evidenceIndex + 1}. ${item}`).join("\n")}` : null,
condition.recommendation ? `已有建议:${condition.recommendation}` : null,
condition.kind === "condition" && condition.analysisInsight?.solutionOptions?.length
? `已有处置方案:\n${condition.analysisInsight.solutionOptions.map((option, optionIndex) => `${optionIndex + 1}. ${option.title}${option.action};代价:${option.tradeoff}`).join("\n")}`
: null
]
.filter(Boolean)
.join("\n");
});
return [
"请作为排水管网调度 Agent,汇总当前待复核工况队列。",
"",
"目标:",
"1. 汇总这一组待复核工况之间的关联关系和处理顺序。",
"2. 列出支撑判断的关键证据和不确定性。",
"3. 给出处置方案,包含建议动作、适用条件、影响范围和需要人工确认的事项。",
"4. 不要自动执行阀门、泵站或工单动作,先给调度员确认。",
"",
`待复核工况数量:${alerts.length}`,
"",
"待复核工况上下文:",
alertSummaries.join("\n\n"),
"",
"请先给出总体判断,再按工况列出处置建议,最后列出需要补充核查的数据。"
].join("\n");
}
function findConditionForAlert(alert: WorkbenchAlert, conditions: ScheduledConditionItem[]) {
if (!alert.id.startsWith(SCHEDULED_CONDITION_ALERT_ID_PREFIX)) {
return null;
}
const conditionId = alert.id.slice(SCHEDULED_CONDITION_ALERT_ID_PREFIX.length);
return conditions.find((condition) => condition.id === conditionId) ?? null;
}
function formatTime(value: string) {
const match = value.match(/T(\d{2}:\d{2})/);
return match?.[1] ?? value;
}
function getRiskLabel(riskLevel: ScheduledConditionItem["riskLevel"]) {
if (riskLevel === "critical") {
return "需重点复核";
}
if (riskLevel === "attention") {
return "关注";
}
return "正常";
}