@umituz/react-native-ai-generation-content 1.20.6 → 1.20.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/domain/entities/index.ts +1 -0
- package/src/features/text-to-image/index.ts +1 -1
- package/src/features/text-to-image/presentation/hooks/index.ts +1 -1
- package/src/features/text-to-image/presentation/hooks/useGeneration.ts +2 -2
- package/src/features/text-to-image/presentation/hooks/useTextToImageForm.ts +2 -2
- package/src/infrastructure/utils/index.ts +1 -0
- package/src/domains/flashcard-generation/FlashcardGenerationService.ts +0 -104
- package/src/domains/flashcard-generation/builders/flashcard-prompt.builder.ts +0 -55
- package/src/domains/flashcard-generation/parsers/flashcard-response.parser.ts +0 -68
- package/src/domains/flashcard-generation/types/flashcard.types.ts +0 -56
- package/src/domains/flashcard-generation/validators/flashcard.validator.ts +0 -67
- package/src/presentation/hooks/useFlashcardGeneration.ts +0 -155
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.8",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -10,7 +10,7 @@ export type { UseFormStateOptions, UseFormStateReturn } from "./useFormState";
|
|
|
10
10
|
// Generation Hook
|
|
11
11
|
export { useGeneration } from "./useGeneration";
|
|
12
12
|
export type {
|
|
13
|
-
|
|
13
|
+
TextToImageGenerationState,
|
|
14
14
|
UseGenerationOptions,
|
|
15
15
|
UseGenerationReturn,
|
|
16
16
|
} from "./useGeneration";
|
|
@@ -25,14 +25,14 @@ export interface UseGenerationOptions {
|
|
|
25
25
|
onPromptCleared?: () => void;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export interface
|
|
28
|
+
export interface TextToImageGenerationState {
|
|
29
29
|
isGenerating: boolean;
|
|
30
30
|
progress: number;
|
|
31
31
|
error: string | null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface UseGenerationReturn {
|
|
35
|
-
generationState:
|
|
35
|
+
generationState: TextToImageGenerationState;
|
|
36
36
|
totalCost: number;
|
|
37
37
|
handleGenerate: () => Promise<TextToImageGenerationResult | null>;
|
|
38
38
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import { useFormState, type UseFormStateOptions } from "./useFormState";
|
|
8
|
-
import { useGeneration, type
|
|
8
|
+
import { useGeneration, type TextToImageGenerationState } from "./useGeneration";
|
|
9
9
|
import type {
|
|
10
10
|
TextToImageFormState,
|
|
11
11
|
TextToImageFormActions,
|
|
@@ -19,7 +19,7 @@ export interface UseTextToImageFormOptions extends UseFormStateOptions {
|
|
|
19
19
|
export interface UseTextToImageFormReturn {
|
|
20
20
|
state: TextToImageFormState;
|
|
21
21
|
actions: TextToImageFormActions;
|
|
22
|
-
generationState:
|
|
22
|
+
generationState: TextToImageGenerationState;
|
|
23
23
|
totalCost: number;
|
|
24
24
|
handleGenerate: () => Promise<void>;
|
|
25
25
|
isReady: boolean;
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Generation Service
|
|
3
|
-
* AI-powered flashcard generation for educational content
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
FlashcardGenerationRequest,
|
|
8
|
-
FlashcardGenerationResult,
|
|
9
|
-
FlashcardGenerationResponse,
|
|
10
|
-
FlashcardValidationResult,
|
|
11
|
-
} from "./types/flashcard.types";
|
|
12
|
-
import { buildFlashcardPrompt, calculateMaxTokens } from "./builders/flashcard-prompt.builder";
|
|
13
|
-
import { parseFlashcardsFromResponse } from "./parsers/flashcard-response.parser";
|
|
14
|
-
import { validateFlashcard } from "./validators/flashcard.validator";
|
|
15
|
-
|
|
16
|
-
// Re-export types for backward compatibility
|
|
17
|
-
export type {
|
|
18
|
-
FlashcardGenerationRequest,
|
|
19
|
-
FlashcardGenerationResult,
|
|
20
|
-
FlashcardValidationResult,
|
|
21
|
-
GeneratedFlashcard,
|
|
22
|
-
} from "./types/flashcard.types";
|
|
23
|
-
|
|
24
|
-
const CREDITS_PER_FLASHCARD = 2;
|
|
25
|
-
const MOCK_DELAY_MS = 2000;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generate flashcards using AI
|
|
29
|
-
*/
|
|
30
|
-
export async function generateFlashcards(
|
|
31
|
-
request: FlashcardGenerationRequest,
|
|
32
|
-
): Promise<FlashcardGenerationResult> {
|
|
33
|
-
const startTime = Date.now();
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const prompt = buildFlashcardPrompt(request);
|
|
37
|
-
const response = await executeGeneration(prompt, request.count);
|
|
38
|
-
const flashcards = parseFlashcardsFromResponse(response, request);
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
success: true,
|
|
42
|
-
flashcards,
|
|
43
|
-
creditsUsed: request.count * CREDITS_PER_FLASHCARD,
|
|
44
|
-
tokensUsed: response.metadata?.tokensUsed ?? 0,
|
|
45
|
-
processingTime: Date.now() - startTime,
|
|
46
|
-
requestId: response.jobId ?? `req_${Date.now()}`,
|
|
47
|
-
};
|
|
48
|
-
} catch (error) {
|
|
49
|
-
return {
|
|
50
|
-
success: false,
|
|
51
|
-
flashcards: [],
|
|
52
|
-
creditsUsed: 0,
|
|
53
|
-
tokensUsed: 0,
|
|
54
|
-
processingTime: 0,
|
|
55
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
56
|
-
requestId: "",
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Validate flashcard content quality
|
|
63
|
-
*/
|
|
64
|
-
export function validateFlashcardContent(
|
|
65
|
-
front: string,
|
|
66
|
-
back: string,
|
|
67
|
-
): FlashcardValidationResult {
|
|
68
|
-
return validateFlashcard(front, back);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function executeGeneration(
|
|
72
|
-
_prompt: string,
|
|
73
|
-
count: number,
|
|
74
|
-
): Promise<FlashcardGenerationResponse> {
|
|
75
|
-
// Mock implementation - integrate with actual AI orchestrator
|
|
76
|
-
await new Promise((resolve) => setTimeout(resolve, MOCK_DELAY_MS));
|
|
77
|
-
|
|
78
|
-
const maxTokens = calculateMaxTokens(count);
|
|
79
|
-
return {
|
|
80
|
-
success: true,
|
|
81
|
-
result: generateMockContent(count),
|
|
82
|
-
metadata: { tokensUsed: maxTokens, processingTime: MOCK_DELAY_MS },
|
|
83
|
-
jobId: `job_${Date.now()}`,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function generateMockContent(count: number): string {
|
|
88
|
-
const mockFlashcards = [
|
|
89
|
-
{
|
|
90
|
-
front: "What is photosynthesis?",
|
|
91
|
-
back: "The process by which plants convert sunlight into glucose.",
|
|
92
|
-
difficulty: "medium",
|
|
93
|
-
tags: ["biology", "science"],
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
front: "Define gravity",
|
|
97
|
-
back: "A force that attracts objects with mass toward each other.",
|
|
98
|
-
difficulty: "easy",
|
|
99
|
-
tags: ["physics", "science"],
|
|
100
|
-
},
|
|
101
|
-
];
|
|
102
|
-
|
|
103
|
-
return JSON.stringify(mockFlashcards.slice(0, count));
|
|
104
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Prompt Builder
|
|
3
|
-
* Builds AI prompts for flashcard generation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { FlashcardGenerationRequest, FlashcardDifficulty, FlashcardFormat } from "../types/flashcard.types";
|
|
7
|
-
|
|
8
|
-
const QUALITY_MAP: Record<FlashcardDifficulty, string> = {
|
|
9
|
-
beginner: "simple, clear language appropriate for learners just starting out",
|
|
10
|
-
intermediate: "moderate complexity with some technical terms expected to be known",
|
|
11
|
-
advanced: "complex content with specialized terminology and nuanced concepts",
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const FORMAT_INSTRUCTIONS: Record<FlashcardFormat, string> = {
|
|
15
|
-
qa: "Format as Question-Answer pairs",
|
|
16
|
-
definition: "Format as Term-Definition pairs",
|
|
17
|
-
fill_blank: "Format as Fill-in-the-blank exercises",
|
|
18
|
-
multiple_choice: "Format as Multiple Choice questions with one correct answer",
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export function buildFlashcardPrompt(request: FlashcardGenerationRequest): string {
|
|
22
|
-
const format = request.format ?? "qa";
|
|
23
|
-
const language = request.language ?? "English";
|
|
24
|
-
const tags = request.tags?.join(", ") ?? "auto-generated";
|
|
25
|
-
const context = request.context ?? "General learning";
|
|
26
|
-
|
|
27
|
-
return `Generate ${request.count} educational flashcards about "${request.topic}".
|
|
28
|
-
|
|
29
|
-
Topic Context: ${context}
|
|
30
|
-
Difficulty Level: ${request.difficulty} - ${QUALITY_MAP[request.difficulty]}
|
|
31
|
-
Format: ${format} - ${FORMAT_INSTRUCTIONS[format]}
|
|
32
|
-
Language: ${language}
|
|
33
|
-
Tags to include: ${tags}
|
|
34
|
-
|
|
35
|
-
Requirements:
|
|
36
|
-
- Questions should be clear and concise
|
|
37
|
-
- Answers should be accurate and comprehensive
|
|
38
|
-
- Content should be age and difficulty appropriate
|
|
39
|
-
- Include relevant educational context
|
|
40
|
-
- Make it engaging and memorable
|
|
41
|
-
|
|
42
|
-
Output format: JSON array with structure:
|
|
43
|
-
[
|
|
44
|
-
{
|
|
45
|
-
"front": "Question text here",
|
|
46
|
-
"back": "Answer text here",
|
|
47
|
-
"difficulty": "easy|medium|hard",
|
|
48
|
-
"tags": ["tag1", "tag2"]
|
|
49
|
-
}
|
|
50
|
-
]`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function calculateMaxTokens(count: number): number {
|
|
54
|
-
return Math.max(count * 50, 200);
|
|
55
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Response Parser
|
|
3
|
-
* Parses AI responses into structured flashcard data
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
FlashcardGenerationRequest,
|
|
8
|
-
FlashcardGenerationResponse,
|
|
9
|
-
GeneratedFlashcard,
|
|
10
|
-
FlashcardDifficultyLevel,
|
|
11
|
-
} from "../types/flashcard.types";
|
|
12
|
-
|
|
13
|
-
interface RawFlashcard {
|
|
14
|
-
front?: string;
|
|
15
|
-
back?: string;
|
|
16
|
-
difficulty?: FlashcardDifficultyLevel;
|
|
17
|
-
tags?: string | string[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function parseFlashcardsFromResponse(
|
|
21
|
-
response: FlashcardGenerationResponse,
|
|
22
|
-
request: FlashcardGenerationRequest,
|
|
23
|
-
): GeneratedFlashcard[] {
|
|
24
|
-
try {
|
|
25
|
-
const rawFlashcards = extractRawFlashcards(response.result);
|
|
26
|
-
return rawFlashcards.map((item, index) => mapToGeneratedFlashcard(item, request, index));
|
|
27
|
-
} catch (error) {
|
|
28
|
-
if (__DEV__) {
|
|
29
|
-
|
|
30
|
-
console.error("Failed to parse AI response:", error);
|
|
31
|
-
}
|
|
32
|
-
return [];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function extractRawFlashcards(result: string | unknown[]): RawFlashcard[] {
|
|
37
|
-
if (typeof result === "string") {
|
|
38
|
-
return JSON.parse(result) as RawFlashcard[];
|
|
39
|
-
}
|
|
40
|
-
if (Array.isArray(result)) {
|
|
41
|
-
return result as RawFlashcard[];
|
|
42
|
-
}
|
|
43
|
-
throw new Error("Invalid AI response format");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function mapToGeneratedFlashcard(
|
|
47
|
-
raw: RawFlashcard,
|
|
48
|
-
request: FlashcardGenerationRequest,
|
|
49
|
-
index: number,
|
|
50
|
-
): GeneratedFlashcard {
|
|
51
|
-
return {
|
|
52
|
-
id: `generated_${Date.now()}_${index}`,
|
|
53
|
-
front: raw.front ?? "",
|
|
54
|
-
back: raw.back ?? "",
|
|
55
|
-
difficulty: raw.difficulty ?? "medium",
|
|
56
|
-
tags: normalizeTags(raw.tags),
|
|
57
|
-
source: "ai_generated",
|
|
58
|
-
generationRequest: request,
|
|
59
|
-
confidence: 0.8 + Math.random() * 0.2,
|
|
60
|
-
createdAt: new Date().toISOString(),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function normalizeTags(tags: string | string[] | undefined): string[] {
|
|
65
|
-
if (Array.isArray(tags)) return tags;
|
|
66
|
-
if (typeof tags === "string") return [tags];
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Types
|
|
3
|
-
* Type definitions for flashcard generation feature
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export type FlashcardDifficulty = "beginner" | "intermediate" | "advanced";
|
|
7
|
-
export type FlashcardDifficultyLevel = "easy" | "medium" | "hard";
|
|
8
|
-
export type FlashcardFormat = "qa" | "definition" | "fill_blank" | "multiple_choice";
|
|
9
|
-
|
|
10
|
-
export interface FlashcardGenerationRequest {
|
|
11
|
-
topic: string;
|
|
12
|
-
difficulty: FlashcardDifficulty;
|
|
13
|
-
count: number;
|
|
14
|
-
language?: string;
|
|
15
|
-
format?: FlashcardFormat;
|
|
16
|
-
context?: string;
|
|
17
|
-
tags?: string[];
|
|
18
|
-
includeImages?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface GeneratedFlashcard {
|
|
22
|
-
id: string;
|
|
23
|
-
front: string;
|
|
24
|
-
back: string;
|
|
25
|
-
difficulty: FlashcardDifficultyLevel;
|
|
26
|
-
tags: string[];
|
|
27
|
-
source: "ai_generated";
|
|
28
|
-
generationRequest: FlashcardGenerationRequest;
|
|
29
|
-
confidence: number;
|
|
30
|
-
createdAt?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface FlashcardGenerationResult {
|
|
34
|
-
success: boolean;
|
|
35
|
-
flashcards: GeneratedFlashcard[];
|
|
36
|
-
creditsUsed: number;
|
|
37
|
-
tokensUsed: number;
|
|
38
|
-
processingTime: number;
|
|
39
|
-
error?: string;
|
|
40
|
-
requestId: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface FlashcardValidationResult {
|
|
44
|
-
accuracy: number;
|
|
45
|
-
relevance: number;
|
|
46
|
-
clarity: number;
|
|
47
|
-
completeness: number;
|
|
48
|
-
overall: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface FlashcardGenerationResponse {
|
|
52
|
-
success: boolean;
|
|
53
|
-
result: string | unknown[];
|
|
54
|
-
metadata: { tokensUsed: number; processingTime: number };
|
|
55
|
-
jobId: string;
|
|
56
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Validator
|
|
3
|
-
* Validates and scores generated flashcard content
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { FlashcardValidationResult } from "../types/flashcard.types";
|
|
7
|
-
|
|
8
|
-
const EDUCATIONAL_TERMS = [
|
|
9
|
-
"define", "explain", "describe", "what is",
|
|
10
|
-
"how does", "formula", "process", "function",
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
export function validateFlashcard(front: string, back: string): FlashcardValidationResult {
|
|
14
|
-
const accuracy = calculateAccuracy(front, back);
|
|
15
|
-
const relevance = calculateRelevance(front, back);
|
|
16
|
-
const clarity = calculateClarity(front, back);
|
|
17
|
-
const completeness = calculateCompleteness(front, back);
|
|
18
|
-
const overall = (accuracy + relevance + clarity + completeness) / 4;
|
|
19
|
-
|
|
20
|
-
return { accuracy, relevance, clarity, completeness, overall };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function calculateAccuracy(front: string, back: string): number {
|
|
24
|
-
let score = 0.5;
|
|
25
|
-
|
|
26
|
-
if (front.length >= 5 && front.length <= 200) score += 0.2;
|
|
27
|
-
if (back.length >= 10 && back.length <= 500) score += 0.2;
|
|
28
|
-
|
|
29
|
-
const frontWords = front.split(/\s+/).length;
|
|
30
|
-
const backWords = back.split(/\s+/).length;
|
|
31
|
-
if (backWords >= frontWords * 0.5 && backWords <= frontWords * 3) {
|
|
32
|
-
score += 0.1;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return Math.min(score, 1.0);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function calculateRelevance(front: string, back: string): number {
|
|
39
|
-
let score = 0.6;
|
|
40
|
-
|
|
41
|
-
const hasEducationalTerms = EDUCATIONAL_TERMS.some(
|
|
42
|
-
(term) => front.toLowerCase().includes(term) || back.toLowerCase().includes(term),
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
if (hasEducationalTerms) score += 0.3;
|
|
46
|
-
if (front.includes("?") || front.toLowerCase().includes("what is")) {
|
|
47
|
-
score += 0.1;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return Math.min(score, 1.0);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function calculateClarity(front: string, back: string): number {
|
|
54
|
-
let score = 0.5;
|
|
55
|
-
|
|
56
|
-
if (front.trim().endsWith("?")) score += 0.2;
|
|
57
|
-
if (!front.includes("...") && !back.includes("...")) score += 0.2;
|
|
58
|
-
if (!/[A-Z]{2,}/.test(front)) score += 0.1;
|
|
59
|
-
|
|
60
|
-
return Math.min(score, 1.0);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function calculateCompleteness(front: string, back: string): number {
|
|
64
|
-
const frontScore = Math.min(front.length / 20, 1.0);
|
|
65
|
-
const backScore = Math.min(back.length / 50, 1.0);
|
|
66
|
-
return (frontScore + backScore) / 2;
|
|
67
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flashcard Generation Hooks
|
|
3
|
-
* React hooks for AI-powered flashcard generation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React from "react";
|
|
7
|
-
import type {
|
|
8
|
-
FlashcardGenerationRequest,
|
|
9
|
-
GeneratedFlashcard,
|
|
10
|
-
FlashcardGenerationResult,
|
|
11
|
-
} from "../../domains/flashcard-generation/FlashcardGenerationService";
|
|
12
|
-
|
|
13
|
-
export interface UseFlashcardGenerationResult {
|
|
14
|
-
generateFlashcards: (
|
|
15
|
-
request: FlashcardGenerationRequest,
|
|
16
|
-
) => Promise<FlashcardGenerationResult>;
|
|
17
|
-
isGenerating: boolean;
|
|
18
|
-
result: FlashcardGenerationResult | null;
|
|
19
|
-
error: string | null;
|
|
20
|
-
reset: () => void;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const useFlashcardGeneration = (): UseFlashcardGenerationResult => {
|
|
24
|
-
const [isGenerating, setIsGenerating] = React.useState(false);
|
|
25
|
-
const [result, setResult] = React.useState<FlashcardGenerationResult | null>(
|
|
26
|
-
null,
|
|
27
|
-
);
|
|
28
|
-
const [error, setError] = React.useState<string | null>(null);
|
|
29
|
-
|
|
30
|
-
const generateFlashcards = React.useCallback(
|
|
31
|
-
async (
|
|
32
|
-
request: FlashcardGenerationRequest,
|
|
33
|
-
): Promise<FlashcardGenerationResult> => {
|
|
34
|
-
try {
|
|
35
|
-
setIsGenerating(true);
|
|
36
|
-
setError(null);
|
|
37
|
-
|
|
38
|
-
// This would use the actual FlashcardGenerationService
|
|
39
|
-
// For now, mock the implementation
|
|
40
|
-
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
41
|
-
|
|
42
|
-
const flashcards: GeneratedFlashcard[] = [];
|
|
43
|
-
for (let i = 0; i < request.count; i++) {
|
|
44
|
-
flashcards.push({
|
|
45
|
-
id: `generated_${Date.now()}_${i}`,
|
|
46
|
-
front: `Mock question ${i + 1} about ${request.topic}`,
|
|
47
|
-
back: `Mock answer ${i + 1} for ${request.topic}`,
|
|
48
|
-
difficulty: i % 3 === 0 ? "easy" : i % 3 === 1 ? "medium" : "hard",
|
|
49
|
-
tags: [
|
|
50
|
-
...(request.tags || []),
|
|
51
|
-
request.topic.toLowerCase().replace(/\s+/g, "_"),
|
|
52
|
-
],
|
|
53
|
-
source: "ai_generated",
|
|
54
|
-
generationRequest: request,
|
|
55
|
-
confidence: 0.8 + Math.random() * 0.2,
|
|
56
|
-
createdAt: new Date().toISOString(),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const generationResult: FlashcardGenerationResult = {
|
|
61
|
-
success: true,
|
|
62
|
-
flashcards,
|
|
63
|
-
creditsUsed: request.count * 2,
|
|
64
|
-
tokensUsed: request.count * 100,
|
|
65
|
-
processingTime: 2000,
|
|
66
|
-
requestId: `req_${Date.now()}`,
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
setResult(generationResult);
|
|
70
|
-
return generationResult;
|
|
71
|
-
} catch (err) {
|
|
72
|
-
const errorMessage =
|
|
73
|
-
err instanceof Error ? err.message : "Generation failed";
|
|
74
|
-
setError(errorMessage);
|
|
75
|
-
setIsGenerating(false);
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
success: false,
|
|
79
|
-
flashcards: [],
|
|
80
|
-
creditsUsed: 0,
|
|
81
|
-
tokensUsed: 0,
|
|
82
|
-
processingTime: 0,
|
|
83
|
-
error: errorMessage,
|
|
84
|
-
requestId: `req_${Date.now()}`,
|
|
85
|
-
};
|
|
86
|
-
} finally {
|
|
87
|
-
setIsGenerating(false);
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
[],
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
const reset = React.useCallback(() => {
|
|
94
|
-
setResult(null);
|
|
95
|
-
setError(null);
|
|
96
|
-
setIsGenerating(false);
|
|
97
|
-
}, []);
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
generateFlashcards,
|
|
101
|
-
isGenerating,
|
|
102
|
-
result,
|
|
103
|
-
error,
|
|
104
|
-
reset,
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export interface UseFlashcardValidationResult {
|
|
109
|
-
validateFlashcard: (
|
|
110
|
-
front: string,
|
|
111
|
-
back: string,
|
|
112
|
-
) => Promise<{
|
|
113
|
-
accuracy: number;
|
|
114
|
-
relevance: number;
|
|
115
|
-
clarity: number;
|
|
116
|
-
completeness: number;
|
|
117
|
-
overall: number;
|
|
118
|
-
}>;
|
|
119
|
-
isValidating: boolean;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const useFlashcardValidation = (): UseFlashcardValidationResult => {
|
|
123
|
-
const [isValidating, setIsValidating] = React.useState(false);
|
|
124
|
-
|
|
125
|
-
const validateFlashcard = React.useCallback(
|
|
126
|
-
async (front: string, back: string) => {
|
|
127
|
-
setIsValidating(true);
|
|
128
|
-
|
|
129
|
-
// Mock validation - in production would use actual service
|
|
130
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
131
|
-
|
|
132
|
-
const accuracy = Math.min(1, front.length / 10);
|
|
133
|
-
const relevance = Math.min(1, back.length / 25);
|
|
134
|
-
const clarity = Math.min(1, 1 - front.split(/\s+/).length / 20);
|
|
135
|
-
const completeness = Math.min(1, back.length / 50);
|
|
136
|
-
const overall = (accuracy + relevance + clarity + completeness) / 4;
|
|
137
|
-
|
|
138
|
-
setIsValidating(false);
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
accuracy,
|
|
142
|
-
relevance,
|
|
143
|
-
clarity,
|
|
144
|
-
completeness,
|
|
145
|
-
overall,
|
|
146
|
-
};
|
|
147
|
-
},
|
|
148
|
-
[],
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
validateFlashcard,
|
|
153
|
-
isValidating,
|
|
154
|
-
};
|
|
155
|
-
};
|