koishi-plugin-emojiluna
Version:
Smart emoji management plugin with AI categorization
179 lines (178 loc) • 5.18 kB
TypeScript
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>;
/**
* Validate a new emoji before upload.
* Returns: null if valid, error message if invalid
*/
validateNewEmoji(imageData: Buffer, imageHash: string): Promise<string | null>;
/**
* Check if a hash already exists in the tracked set.
*/
hasHash(hash: string): boolean;
/**
* 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 {};