UNPKG

minimax-mcp-tools

Version:

Async MCP server with Minimax API integration for image generation and text-to-speech

162 lines 5.44 kB
import { AdaptiveRateLimiter } from './rate-limiter.js'; import { RATE_LIMITS } from '../config/constants.js'; import { MinimaxError, ErrorHandler } from '../utils/error-handler.js'; export class TaskManager { tasks; completedTasks; taskCounter; constructor() { this.tasks = new Map(); this.completedTasks = new Map(); this.taskCounter = 0; } generateTaskId() { return `task_${++this.taskCounter}`; } async submit(fn, taskId = null) { taskId = taskId || this.generateTaskId(); const taskPromise = Promise.resolve() .then(fn) .then(result => { this.completedTasks.set(taskId, { success: true, result, completedAt: Date.now() }); return result; }) .catch(error => { const processedError = ErrorHandler.handleAPIError(error); this.completedTasks.set(taskId, { success: false, error: processedError, completedAt: Date.now() }); throw processedError; }) .finally(() => { this.tasks.delete(taskId); }); this.tasks.set(taskId, taskPromise); return { taskId, promise: taskPromise }; } async barrier() { const activeTasks = Array.from(this.tasks.values()); if (activeTasks.length > 0) { await Promise.allSettled(activeTasks); } const results = Array.from(this.completedTasks.entries()).map(([taskId, taskResult]) => ({ taskId, ...taskResult })); return { completed: results.length, results }; } getTaskStatus(taskId) { if (this.tasks.has(taskId)) { return { status: 'running', taskId }; } if (this.completedTasks.has(taskId)) { return { status: 'completed', taskId, ...this.completedTasks.get(taskId) }; } return { status: 'not_found', taskId }; } getAllTasksStatus() { const running = Array.from(this.tasks.keys()).map(taskId => ({ taskId, status: 'running' })); const completed = Array.from(this.completedTasks.entries()).map(([taskId, result]) => ({ taskId, status: 'completed', ...result })); return { running, completed, total: running.length + completed.length }; } clearCompletedTasks() { const count = this.completedTasks.size; this.completedTasks.clear(); return count; } getStats() { return { activeTasks: this.tasks.size, completedTasks: this.completedTasks.size, totalProcessed: this.taskCounter }; } } export class RateLimitedTaskManager extends TaskManager { rateLimiters; metrics; taskCounters; constructor(options = {}) { super(); this.rateLimiters = { image: new AdaptiveRateLimiter({ ...RATE_LIMITS.IMAGE, backoffFactor: options.backoffFactor || 0.7, recoveryFactor: options.recoveryFactor || 1.05 }), tts: new AdaptiveRateLimiter({ ...RATE_LIMITS.TTS, backoffFactor: options.backoffFactor || 0.7, recoveryFactor: options.recoveryFactor || 1.05 }) }; this.metrics = { image: { requests: 0, successes: 0, errors: 0 }, tts: { requests: 0, successes: 0, errors: 0 } }; this.taskCounters = { image: 0, tts: 0 }; } async submitImageTask(fn, taskId = null) { if (!taskId) { taskId = `img-${++this.taskCounters.image}`; } return this.submitRateLimitedTask('image', fn, taskId); } async submitTTSTask(fn, taskId = null) { if (!taskId) { taskId = `tts-${++this.taskCounters.tts}`; } return this.submitRateLimitedTask('tts', fn, taskId); } async submitRateLimitedTask(type, fn, taskId = null) { const rateLimiter = this.rateLimiters[type]; if (!rateLimiter) { throw new MinimaxError(`Unknown task type: ${type}`); } const wrappedFn = async () => { await rateLimiter.acquire(); this.metrics[type].requests++; try { const result = await fn(); this.metrics[type].successes++; rateLimiter.onSuccess(); return result; } catch (error) { this.metrics[type].errors++; rateLimiter.onError(error); throw error; } }; return this.submit(wrappedFn, taskId); } getRateLimiterStatus() { return { image: this.rateLimiters.image.getAdaptiveStatus(), tts: this.rateLimiters.tts.getAdaptiveStatus() }; } getMetrics() { return { ...this.metrics, rateLimiters: this.getRateLimiterStatus() }; } resetMetrics() { this.metrics = { image: { requests: 0, successes: 0, errors: 0 }, tts: { requests: 0, successes: 0, errors: 0 } }; this.taskCounters = { image: 0, tts: 0 }; Object.values(this.rateLimiters).forEach(limiter => limiter.reset()); } } //# sourceMappingURL=task-manager.js.map