UNPKG

koishi-plugin-emojiluna

Version:

Smart emoji management plugin with AI categorization

179 lines (178 loc) 5.18 kB
import { Context } from 'koishi'; import { Config } from './config'; import { AITaskDetail } from './types'; interface AIAnalysisResult { name: string; category: string; tags: string[]; description?: string; newCategory?: string; } export interface AITask { id: string; emojiId: string; imagePath: string; imageHash: string; attempts: number; nextRetryAt?: number; } /** * Callback interface for AI task processing. * The service implements this to handle actual AI analysis and emoji updates. */ export interface AITaskProcessor { /** Run AI analysis on a base64-encoded image, returning the result. */ analyzeEmoji(imageBase64: string): Promise<AIAnalysisResult | null>; /** Update emoji metadata after successful AI analysis. */ updateEmojiInfo(id: string, updates: Partial<{ name: string; category: string; tags: string[]; }>): Promise<boolean>; /** Get emoji data by ID (returns null if not found). */ getEmojiById(id: string): Promise<{ id: string; name: string; category: string; tags: string[]; path: string; } | null>; } /** * UploadManager handles emoji upload orchestration, deduplication, * file management, and AI task queue management. Maintains in-memory caches * to avoid repeated database queries during bulk uploads. */ export declare class UploadManager { private ctx; private config; private emojiHashes; private emojiHashMap; private aiResultCache; private readonly MAX_CACHE_SIZE; private readonly CACHE_TTL_MS; private _aiPaused; private _aiTaskQueue; private _processingSet; private _localActiveCount; private _aiTasksMap; private _isDisposed; private _taskProcessor; constructor(ctx: Context, config: Config); /** * Set the AI task processor callback. * Must be called before starting the task processor loop. */ setTaskProcessor(processor: AITaskProcessor): void; /** * Load existing emoji hashes into memory cache. * Called during initialization to populate the hash set. */ loadExistingHashes(): Promise<void>; /** * Calculate SHA256 hash of buffer content. */ calculateHash(buffer: Buffer): string; /** * Validate a new emoji before upload. * Returns: null if valid, error message if invalid */ validateNewEmoji(imageData: Buffer, imageHash: string): Promise<string | null>; /** * Register an emoji after successful upload. */ registerEmoji(id: string, imageHash: string): void; /** * Prepare emoji file for upload. * Saves buffer to temporary location, returns path. */ prepareUploadFile(imageData: Buffer): Promise<{ path: string; id: string; extension: string; }>; /** * Move file from temporary location to final storage. * Handles cross-device issues (EXDEV). */ finalizeFile(sourcePath: string, destPath: string): Promise<void>; /** * Clean up temporary upload file. */ cleanupTempFile(tempPath: string): Promise<void>; /** * Batch validate multiple emojis. */ validateBatch(emojis: { buffer: Buffer; hash: string; }[]): Promise<{ valid: boolean; error?: string; }[]>; /** * Cache AI analysis result in memory. */ cacheAIResult(hash: string, result: AIAnalysisResult): void; /** * Retrieve cached AI analysis result if available and not expired. */ getCachedAIResult(hash: string): AIAnalysisResult | null; /** * Clear all memory caches. */ clearCache(): void; /** * Get cache statistics. */ getCacheStats(): { hashCount: number; aiResultCacheCount: number; }; /** * Queue an AI analysis task for background processing. */ queueAIAnalysis(emojiId: string, imagePath: string, imageHash: string): void; /** * Get current AI task statistics. */ getAITaskStats(): { pending: number; processing: number; succeeded: number; failed: number; paused: boolean; }; /** * Get list of emoji IDs that have failed AI analysis. */ getFailedAIEmojiIds(): string[]; getAiTasksAll(): Promise<AITaskDetail[]>; deleteAiTask(emojiId: string): void; retryAiTask(emojiId: string): Promise<void>; /** * Pause or resume AI task processing. */ setAIPaused(paused: boolean): void; /** * Retry all previously failed AI tasks. * Returns the number of tasks re-queued. */ retryFailedTasks(): Promise<number>; /** * Queue a batch of emojis for re-analysis. * Skips emojis that are already queued or processing. * Returns the number of tasks queued. */ reanalyzeBatch(ids: string[]): Promise<number>; /** * Process a single AI task. */ private processAITask; /** * Start the background AI task processor loop. * Runs until the context is disposed. */ startAITaskProcessor(): Promise<void>; } export {};