Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Has been cancelled
CI / Lint, Typecheck & Unit Tests (push) Has been cancelled
Docs Build / Build docs site (push) Has been cancelled
Publish @openmaic packages / Build, validate & publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

136 lines
4.1 KiB
TypeScript

import { ScanLine, Search, Bot, FileText, LayoutPanelLeft, Clapperboard } from 'lucide-react';
import { useSettingsStore } from '@/lib/store/settings';
import type {
SceneOutline,
UserRequirements,
PdfImage,
ImageMapping,
} from '@/lib/types/generation';
// Session state stored in sessionStorage
export interface GenerationSessionState {
sessionId: string;
requirements: UserRequirements;
pdfText: string;
pdfImages?: PdfImage[];
imageStorageIds?: string[];
imageMapping?: ImageMapping;
sceneOutlines?: SceneOutline[] | null;
currentStep: 'generating' | 'complete';
previewPhase?: 'preparing' | 'outline-ready' | 'review' | 'generating-content';
// PDF deferred parsing fields
pdfStorageKey?: string;
pdfFileName?: string;
documentMimeType?: string;
pdfProviderId?: string;
pdfProviderConfig?: { apiKey?: string; baseUrl?: string };
// Web search context
researchContext?: string;
researchSources?: Array<{ title: string; url: string }>;
// Language directive inferred from outline generation
languageDirective?: string;
// Concise course title inferred from outline generation (used as the stage name)
courseTitle?: string;
// Server-effective vocational mode from the outline generation done event.
taskEngineMode?: boolean;
}
export type GenerationStep = {
id: string;
title: string;
description: string;
icon: React.ElementType;
type: 'analysis' | 'writing' | 'visual';
};
function getDocumentTypeLabel(session: GenerationSessionState | null): string {
const mimeType = session?.documentMimeType;
if (mimeType) {
if (mimeType === 'application/pdf') return 'PDF';
if (mimeType.includes('wordprocessingml')) return 'DOCX';
if (mimeType.includes('presentationml')) return 'PPTX';
if (mimeType === 'text/plain') return 'TXT';
if (mimeType.includes('markdown')) return 'Markdown';
}
const extension = session?.pdfFileName?.split('.').pop()?.trim().toLowerCase();
if (extension === 'pdf') return 'PDF';
if (extension === 'docx') return 'DOCX';
if (extension === 'pptx') return 'PPTX';
if (extension === 'txt') return 'TXT';
if (extension === 'md' || extension === 'markdown') return 'Markdown';
return 'document';
}
export function getGenerationStepText(
step: GenerationStep,
session: GenerationSessionState | null,
) {
if (step.id === 'pdf-analysis') {
const documentType = getDocumentTypeLabel(session);
return {
title: 'generation.analyzingCourseMaterial',
titleValues: { type: documentType },
description: 'generation.analyzingCourseMaterialDesc',
};
}
return {
title: step.title,
titleValues: undefined,
description: step.description,
};
}
export const ALL_STEPS: GenerationStep[] = [
{
id: 'pdf-analysis',
title: 'generation.analyzingCourseMaterial',
description: 'generation.analyzingCourseMaterialDesc',
icon: ScanLine,
type: 'analysis',
},
{
id: 'web-search',
title: 'generation.webSearching',
description: 'generation.webSearchingDesc',
icon: Search,
type: 'analysis',
},
{
id: 'outline',
title: 'generation.generatingOutlines',
description: 'generation.generatingOutlinesDesc',
icon: FileText,
type: 'writing',
},
{
id: 'agent-generation',
title: 'generation.agentGeneration',
description: 'generation.agentGenerationDesc',
icon: Bot,
type: 'writing',
},
{
id: 'slide-content',
title: 'generation.generatingSlideContent',
description: 'generation.generatingSlideContentDesc',
icon: LayoutPanelLeft,
type: 'visual',
},
{
id: 'actions',
title: 'generation.generatingActions',
description: 'generation.generatingActionsDesc',
icon: Clapperboard,
type: 'visual',
},
];
export const getActiveSteps = (session: GenerationSessionState | null) => {
return ALL_STEPS.filter((step) => {
if (step.id === 'pdf-analysis') return !!session?.pdfStorageKey;
if (step.id === 'web-search') return !!session?.requirements?.webSearch;
if (step.id === 'agent-generation') return useSettingsStore.getState().agentMode === 'auto';
return true;
});
};