/** * Extracted from AI 数据复盘助手: src/stores/chat.ts, * isRunActive / canApplyAgentChange (2026-09-10). * Vue / Pinia state is passed explicitly; validation branches are preserved. * This frontend guard does not provide server authorization or idempotency. */ export interface Change { status: "pending" | "applied" | "undone"; sourceDocumentId: string; runId: string; } export interface Run { runId: string; sessionId: string; provider: string; model: string; } export interface Context { documentId?: string; activeRun: Run | null; activeRunId: string; activeSessionId: string; currentSessionDocumentId?: string; settings?: { aiProvider: string; modelName: string }; } export function canApplyAgentChange(change: Change | null, context: Context): boolean { if (!change || change.status !== "pending" || !context.documentId || change.sourceDocumentId !== context.documentId) return false; const run = context.activeRun; if (run) { const sameRun = context.activeRunId === run.runId; const sameSession = context.activeSessionId === run.sessionId; const sameModel = !context.settings || ( context.settings.aiProvider === run.provider && context.settings.modelName === run.model ); return sameRun && sameSession && sameModel && run.runId === change.runId; } return context.currentSessionDocumentId === context.documentId; }