Files
ln-bi/src/server/routes/asset-assistant/generated-action.ts
T
2026-09-23 17:52:33 +08:00

37 lines
2.0 KiB
TypeScript

import type { AssistantAction, AssistantResult, Dimension, QueryPlan, ResultPresentation } from "../../../shared/assets/assistant.js";
import { validatePlan } from "./model.js";
/** Execute the AI's stored interaction, binding the clicked data point to the actual result. */
export function applyGeneratedAction(
_base: QueryPlan,
action: Extract<AssistantAction, { type: "explore" }>,
result: AssistantResult,
presentation?: ResultPresentation,
): { plan: QueryPlan; label: string } {
const interaction = presentation?.interactions.find(item => item.id === action.interactionId);
if (!interaction) throw new Error("该分析入口已失效,请重新查询。");
// Generation already resolved inheritance and explicit clears. Re-merging the
// base here would silently restore filters the AI interaction intended to clear.
const next = structuredClone(interaction.plan);
let selection = "";
if (interaction.kind === "group") {
if (!action.keys || typeof action.keys !== "object" || Array.isArray(action.keys) || action.date)
throw new Error("请选择当前结果中的分组。");
const keys = Object.entries(action.keys);
const group = result.groups.find(item => keys.length > 0 && Object.keys(item.keys || {}).length === keys.length && keys.every(([key, value]) => item.keys?.[key as Dimension] === value));
if (!group) throw new Error("分组已变化,请重新查询。");
for (const [key, value] of keys) next.filters[key as Dimension] = [value];
selection = group.name;
} else if (interaction.kind === "point") {
if (action.keys || next.kind !== "flow" || !result.daily?.some(item => item.date === action.date))
throw new Error("请选择当前趋势中的日期。");
next.start = action.date;
next.end = action.date;
next.comparePrevious = false;
selection = action.date!;
} else if (action.keys || action.date) {
throw new Error("当前操作无需附加筛选点。");
}
return { plan: validatePlan(next), label: `${selection ? `${selection} · ` : ""}${interaction.label}` };
}