rcc-virtual-model-rules
Version: 
RCC Virtual Model Rules Module - Claude Code Router rules implementation
864 lines • 32 kB
JavaScript
"use strict";
// Main Virtual Model Rules Module for RCC
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VirtualModelRulesModule = void 0;
const rcc_basemodule_1 = require("rcc-basemodule");
/**
 * Virtual Model Rules Module for RCC
 * Manages intelligent routing rules, model scheduling, and request processing
 * based on Claude Code Router patterns and virtual model capabilities
 */
class VirtualModelRulesModule extends rcc_basemodule_1.BaseModule {
    constructor() {
        const moduleInfo = {
            id: 'VirtualModelRulesModule',
            name: 'RCC Virtual Model Rules Module',
            version: '1.0.0',
            description: 'Virtual model routing rules and scheduling based on Claude Code Router patterns',
            type: 'virtual-model-rules',
            capabilities: ['rule-engine', 'model-scheduling', 'intelligent-routing', 'request-evaluation'],
            dependencies: ['rcc-basemodule'],
            config: {},
            metadata: {
                author: 'RCC Development Team',
                license: 'MIT',
                repository: 'https://github.com/rcc/rcc-virtual-model-rules'
            }
        };
        super(moduleInfo);
        this.rules = new Map();
        this.schedules = new Map();
        this.ruleMetrics = new Map();
        this.evaluationContext = null;
        this.isInitialized = false;
        this.ruleExecutionCache = new Map();
        this.cacheCleanupInterval = null;
    }
    /**
     * Configure the virtual model rules module
     */
    configure(config) {
        super.configure(config);
        this.logInfo('Virtual Model Rules module configured', 'configure');
    }
    /**
     * Initialize the virtual model rules module
     */
    async initialize() {
        if (this.isInitialized) {
            this.warn('Virtual Model Rules module is already initialized', 'initialize');
            return;
        }
        this.log('Initializing Virtual Model Rules Module', {}, 'initialize');
        try {
            // Call parent initialize first
            await super.initialize();
            // Initialize rule engine
            this.initializeRuleEngine();
            // Setup message handlers
            this.setupMessageHandlers();
            // Start cache cleanup
            this.startCacheCleanup();
            this.isInitialized = true;
            this.logInfo('Virtual Model Rules Module initialized successfully', 'initialize');
            // Notify initialization complete
            this.broadcastMessage('virtual-model-rules-initialized', {
                ruleCount: this.rules.size,
                scheduleCount: this.schedules.size
            });
        }
        catch (error) {
            this.error('Failed to initialize Virtual Model Rules Module [initialize]', error instanceof Error ? error.message : String(error));
            throw error;
        }
    }
    /**
     * Register a virtual model rule
     */
    async registerRule(rule) {
        this.log('Registering virtual model rule', { ruleId: rule.id }, 'registerRule');
        // Validate rule configuration
        this.validateRule(rule);
        // Add to rules registry
        this.rules.set(rule.id, rule);
        // Initialize metrics for the rule
        this.ruleMetrics.set(rule.id, {
            ruleId: rule.id,
            totalEvaluations: 0,
            successfulMatches: 0,
            failedMatches: 0,
            matchRate: 0,
            avgEvaluationTime: 0,
            avgConfidence: 0,
            lastEvaluation: 0,
            actionSuccessRate: 0,
            errorCount: 0
        });
        this.logInfo('Virtual model rule registered successfully', 'registerRule');
        // Notify rule registered
        this.broadcastMessage('virtual-model-rule-registered', { rule });
    }
    /**
     * Unregister a virtual model rule
     */
    async unregisterRule(ruleId) {
        this.log('Unregistering virtual model rule', { ruleId }, 'unregisterRule');
        if (!this.rules.has(ruleId)) {
            throw new Error(`Rule '${ruleId}' not found`);
        }
        // Remove from registries
        this.rules.delete(ruleId);
        this.ruleMetrics.delete(ruleId);
        // Clear cache entries for this rule
        this.clearRuleCache(ruleId);
        this.logInfo('Virtual model rule unregistered successfully', 'unregisterRule');
        // Notify rule unregistered
        this.broadcastMessage('virtual-model-rule-unregistered', { ruleId });
    }
    /**
     * Get a rule by ID
     */
    getRule(ruleId) {
        return this.rules.get(ruleId);
    }
    /**
     * Get all rules
     */
    getRules() {
        return Array.from(this.rules.values());
    }
    /**
     * Get rules for a specific model
     */
    getRulesForModel(modelId) {
        return Array.from(this.rules.values()).filter(rule => !rule.modelId || rule.modelId === modelId);
    }
    /**
     * Evaluate rules for a given context
     */
    async evaluateRules(context) {
        this.log('Evaluating rules', { requestId: context.requestId }, 'evaluateRules');
        const results = [];
        const applicableRules = this.getApplicableRules(context);
        for (const rule of applicableRules) {
            try {
                const startTime = Date.now();
                const result = await this.evaluateRule(rule, context);
                const evaluationTime = Date.now() - startTime;
                // Update metrics
                this.updateRuleMetrics(rule.id, result, evaluationTime);
                results.push(result);
            }
            catch (error) {
                this.error('Rule evaluation failed [evaluateRules]', `Rule ${rule.id} failed: ${error instanceof Error ? error.message : String(error)}`);
                // Create error result
                results.push({
                    ruleId: rule.id,
                    matched: false,
                    confidence: 0,
                    executionResults: {
                        actions: [],
                        totalExecutionTime: 0,
                        allSuccess: false
                    },
                    timestamp: Date.now(),
                    metrics: {
                        conditionEvalTime: 0,
                        conditionsEvaluated: 0,
                        conditionsMatched: 0
                    }
                });
            }
        }
        // Sort results by confidence (highest first)
        results.sort((a, b) => b.confidence - a.confidence);
        this.log('Rules evaluation completed', {
            requestId: context.requestId,
            resultCount: results.length
        }, 'evaluateRules');
        return results;
    }
    /**
     * Get rule metrics
     */
    getRuleMetrics(ruleId) {
        if (ruleId) {
            const metrics = this.ruleMetrics.get(ruleId);
            return metrics ? [metrics] : [];
        }
        return Array.from(this.ruleMetrics.values());
    }
    /**
     * Load rules from configuration file
     */
    async loadRules(rulesPath) {
        this.log('Loading rules from configuration file', { rulesPath }, 'loadRules');
        // Mark as under construction feature
        const underConstruction = new (await Promise.resolve().then(() => __importStar(require('rcc-underconstruction')))).UnderConstruction();
        await underConstruction.initialize();
        underConstruction.callUnderConstructionFeature('load-rules-from-config', {
            caller: 'VirtualModelRulesModule.loadRules',
            parameters: { rulesPath },
            purpose: '从配置文件加载规则'
        });
        // Placeholder implementation
        this.logInfo('Rules loading feature is under construction', 'loadRules');
    }
    /**
     * Add a new virtual model rule (alias for registerRule)
     */
    async addRule(rule) {
        return await this.registerRule(rule);
    }
    /**
     * Remove a virtual model rule (alias for unregisterRule)
     */
    async removeRule(ruleId) {
        return await this.unregisterRule(ruleId);
    }
    /**
     * Update an existing rule
     */
    async updateRule(ruleId, updates) {
        this.log('Updating virtual model rule', { ruleId }, 'updateRule');
        const existingRule = this.rules.get(ruleId);
        if (!existingRule) {
            throw new Error(`Rule '${ruleId}' not found`);
        }
        // Merge updates with existing rule
        const updatedRule = { ...existingRule, ...updates };
        // Remove and re-add the rule
        await this.unregisterRule(ruleId);
        await this.registerRule(updatedRule);
        this.logInfo('Virtual model rule updated successfully', 'updateRule');
    }
    /**
     * Get model schedule (alias for getSchedule)
     */
    getModelSchedule(modelId) {
        return this.getSchedule(modelId);
    }
    /**
     * Set model schedule (alias for registerSchedule)
     */
    async setModelSchedule(modelId, schedule) {
        // Ensure schedule has the correct modelId
        schedule.modelId = modelId;
        await this.registerSchedule(schedule);
    }
    /**
     * Get active rules for model
     */
    getActiveRules(modelId) {
        return this.getRulesForModel(modelId).filter(rule => rule.enabled);
    }
    /**
     * Enable/disable rule
     */
    async setRuleEnabled(ruleId, enabled) {
        this.log('Setting rule enabled state', { ruleId, enabled }, 'setRuleEnabled');
        const rule = this.rules.get(ruleId);
        if (!rule) {
            throw new Error(`Rule '${ruleId}' not found`);
        }
        rule.enabled = enabled;
        this.logInfo('Rule enabled state updated successfully', 'setRuleEnabled');
        // Notify rule state changed
        this.broadcastMessage('rule-state-changed', { ruleId, enabled });
    }
    /**
     * Register a model schedule
     */
    async registerSchedule(schedule) {
        this.log('Registering model schedule', { modelId: schedule.modelId }, 'registerSchedule');
        // Validate schedule configuration
        this.validateSchedule(schedule);
        // Add to schedules registry
        this.schedules.set(schedule.modelId, schedule);
        this.logInfo('Model schedule registered successfully', 'registerSchedule');
        // Notify schedule registered
        this.broadcastMessage('model-schedule-registered', { schedule });
    }
    /**
     * Unregister a model schedule
     */
    async unregisterSchedule(modelId) {
        this.log('Unregistering model schedule', { modelId }, 'unregisterSchedule');
        if (!this.schedules.has(modelId)) {
            throw new Error(`Schedule for model '${modelId}' not found`);
        }
        // Remove from schedules registry
        this.schedules.delete(modelId);
        this.logInfo('Model schedule unregistered successfully', 'unregisterSchedule');
        // Notify schedule unregistered
        this.broadcastMessage('model-schedule-unregistered', { modelId });
    }
    /**
     * Get schedule for a model
     */
    getSchedule(modelId) {
        return this.schedules.get(modelId);
    }
    /**
     * Get all schedules
     */
    getSchedules() {
        return Array.from(this.schedules.values());
    }
    /**
     * Check if a model is currently scheduled to run
     */
    async isModelScheduled(modelId) {
        const schedule = this.schedules.get(modelId);
        if (!schedule || !schedule.enabled) {
            return false;
        }
        // Check time windows and constraints
        return this.isScheduleActive(schedule);
    }
    /**
     * Get configuration
     */
    getConfig() {
        return super.getConfig();
    }
    /**
     * Update configuration
     */
    async updateConfig(config) {
        this.log('Updating virtual model rules configuration', config, 'updateConfig');
        // Call parent update
        super.configure(config);
        this.logInfo('Virtual model rules configuration updated successfully', 'updateConfig');
    }
    /**
     * Handle incoming messages
     */
    async handleMessage(message) {
        this.log('Handling message', { type: message?.type, source: message?.source }, 'handleMessage');
        switch (message?.type) {
            case 'rule-evaluation-request':
                return await this.handleRuleEvaluation(message);
            case 'schedule-status-request':
                return await this.handleScheduleStatus(message);
            case 'rule-metrics-request':
                return await this.handleRuleMetrics(message);
            default:
                return await super.handleMessage(message);
        }
    }
    /**
     * Cleanup resources
     */
    async destroy() {
        this.log('Cleaning up Virtual Model Rules Module', {}, 'destroy');
        try {
            // Clear registries
            this.rules.clear();
            this.schedules.clear();
            this.ruleMetrics.clear();
            this.ruleExecutionCache.clear();
            this.evaluationContext = null;
            this.isInitialized = false;
            // Clear cache cleanup interval
            if (this.cacheCleanupInterval) {
                clearInterval(this.cacheCleanupInterval);
                this.cacheCleanupInterval = null;
            }
            await super.destroy();
        }
        catch (error) {
            this.error('Error during cleanup [destroy]', error instanceof Error ? error.message : String(error));
            throw error;
        }
    }
    /**
     * Initialize rule engine
     */
    initializeRuleEngine() {
        this.log('Initializing rule engine', {}, 'initializeRuleEngine');
        // Initialize with default rules if needed
        // This could load rules from configuration files
        this.logInfo('Rule engine initialized successfully', 'initializeRuleEngine');
    }
    /**
     * Setup message handlers
     */
    setupMessageHandlers() {
        this.log('Setting up message handlers', {}, 'setupMessageHandlers');
        // Message handling is done in handleMessage method
    }
    /**
     * Start cache cleanup
     */
    startCacheCleanup() {
        // Clean up expired cache entries every minute
        const intervalId = setInterval(() => {
            this.cleanupCache();
        }, 60000);
        // Store interval ID for cleanup
        this.cacheCleanupInterval = intervalId;
        this.log('Cache cleanup started', {}, 'startCacheCleanup');
    }
    /**
     * Validate rule configuration
     */
    validateRule(rule) {
        if (!rule.id || !rule.name || !rule.priority) {
            throw new Error('Rule configuration missing required fields: id, name, priority');
        }
        if (!rule.conditions || rule.conditions.length === 0) {
            throw new Error('Rule must have at least one condition');
        }
        if (!rule.actions || rule.actions.length === 0) {
            throw new Error('Rule must have at least one action');
        }
        // Validate priority is one of the allowed values
        const validPriorities = ['low', 'medium', 'high', 'critical'];
        if (!validPriorities.includes(rule.priority)) {
            throw new Error('Rule priority must be one of: low, medium, high, critical');
        }
    }
    /**
     * Validate schedule configuration
     */
    validateSchedule(schedule) {
        if (!schedule.modelId || !schedule.priority) {
            throw new Error('Schedule configuration missing required fields: modelId, priority');
        }
        if (schedule.maxExecutionTime && schedule.maxExecutionTime < 1000) {
            throw new Error('Max execution time must be at least 1000ms');
        }
    }
    /**
     * Get applicable rules for a context
     */
    getApplicableRules(context) {
        const applicableRules = Array.from(this.rules.values())
            .filter(rule => rule.enabled)
            .filter(rule => !rule.modelId || rule.modelId === context.model?.modelId)
            .sort((a, b) => {
            // Sort by priority (higher priority first)
            const priorityOrder = { critical: 4, high: 3, medium: 2, low: 1 };
            return priorityOrder[b.priority] - priorityOrder[a.priority];
        });
        this.trace('Found applicable rules [getApplicableRules]', {
            requestId: context.requestId,
            ruleCount: applicableRules.length
        });
        return applicableRules;
    }
    /**
     * Evaluate a single rule
     */
    async evaluateRule(rule, context) {
        const startTime = Date.now();
        // Check cache first
        const cacheKey = this.getCacheKey(rule, context);
        const cachedResult = this.ruleExecutionCache.get(cacheKey);
        if (cachedResult && Date.now() - cachedResult.timestamp < cachedResult.ttl) {
            this.trace('Using cached rule result [evaluateRule]', { ruleId: rule.id });
            return this.createEvaluationResult(rule, true, cachedResult.result, 0.95);
        }
        // Evaluate conditions
        const conditionStartTime = Date.now();
        const { matched, confidence, conditionsEvaluated, conditionsMatched } = await this.evaluateConditions(rule, context);
        const conditionEvalTime = Date.now() - conditionStartTime;
        if (!matched) {
            // Cache negative result
            this.ruleExecutionCache.set(cacheKey, {
                result: false,
                timestamp: Date.now(),
                ttl: 30000 // 30 seconds for negative results
            });
            return this.createEvaluationResult(rule, false, false, 0, conditionEvalTime, conditionsEvaluated, conditionsMatched);
        }
        // Execute actions
        const executionResults = await this.executeActions(rule, context);
        // Cache positive result
        this.ruleExecutionCache.set(cacheKey, {
            result: true,
            timestamp: Date.now(),
            ttl: 60000 // 60 seconds for positive results
        });
        const totalExecutionTime = Date.now() - startTime;
        return this.createEvaluationResult(rule, true, true, confidence, conditionEvalTime, conditionsEvaluated, conditionsMatched, executionResults, totalExecutionTime);
    }
    /**
     * Evaluate rule conditions
     */
    async evaluateConditions(rule, context) {
        let conditionsEvaluated = 0;
        let conditionsMatched = 0;
        let totalWeight = 0;
        let matchedWeight = 0;
        for (const condition of rule.conditions) {
            conditionsEvaluated++;
            try {
                const result = await this.evaluateCondition(condition, context);
                const weight = condition.weight || 1;
                totalWeight += weight;
                if (result) {
                    conditionsMatched++;
                    matchedWeight += weight;
                }
            }
            catch (error) {
                this.warn('Condition evaluation failed [evaluateConditions]', `Rule ${rule.id}, field ${condition.field}: ${error instanceof Error ? error.message : String(error)}`);
            }
        }
        const matched = conditionsMatched > 0;
        const confidence = totalWeight > 0 ? matchedWeight / totalWeight : 0;
        return { matched, confidence, conditionsEvaluated, conditionsMatched };
    }
    /**
     * Evaluate a single condition
     */
    async evaluateCondition(condition, context) {
        const fieldValue = this.getFieldValue(context, condition.field);
        switch (condition.operator) {
            case 'equals':
                return fieldValue === condition.value;
            case 'not_equals':
                return fieldValue !== condition.value;
            case 'contains':
                return typeof fieldValue === 'string' && fieldValue.includes(condition.value);
            case 'not_contains':
                return typeof fieldValue === 'string' && !fieldValue.includes(condition.value);
            case 'greater_than':
                return typeof fieldValue === 'number' && fieldValue > condition.value;
            case 'less_than':
                return typeof fieldValue === 'number' && fieldValue < condition.value;
            case 'in':
                return Array.isArray(condition.value) && condition.value.includes(fieldValue);
            case 'not_in':
                return Array.isArray(condition.value) && !condition.value.includes(fieldValue);
            case 'regex':
                return typeof fieldValue === 'string' && new RegExp(condition.value).test(fieldValue);
            default:
                return false;
        }
    }
    /**
     * Get field value from context
     */
    getFieldValue(context, field) {
        const parts = field.split('.');
        let value = context;
        for (const part of parts) {
            if (value && typeof value === 'object') {
                value = value[part];
            }
            else {
                return undefined;
            }
        }
        return value;
    }
    /**
     * Execute rule actions
     */
    async executeActions(rule, context) {
        const actions = [];
        let totalExecutionTime = 0;
        let allSuccess = true;
        for (const action of rule.actions) {
            const startTime = Date.now();
            try {
                const result = await this.executeAction(action, context);
                const executionTime = Date.now() - startTime;
                actions.push({
                    actionId: action.id || 'unknown',
                    success: true,
                    result,
                    executionTime
                });
                totalExecutionTime += executionTime;
            }
            catch (error) {
                const executionTime = Date.now() - startTime;
                actions.push({
                    actionId: action.id || 'unknown',
                    success: false,
                    error: error instanceof Error ? error.message : String(error),
                    executionTime
                });
                totalExecutionTime += executionTime;
                allSuccess = false;
            }
        }
        return {
            actions,
            totalExecutionTime,
            allSuccess
        };
    }
    /**
     * Execute a single action
     */
    async executeAction(action, context) {
        this.trace('Executing action [executeAction]', { type: action.type });
        switch (action.type) {
            case 'route_to_model':
                return this.executeRouteToModel(action, context);
            case 'set_priority':
                return this.executeSetPriority(action, context);
            case 'add_tag':
                return this.executeAddTag(action, context);
            case 'remove_tag':
                return this.executeRemoveTag(action, context);
            case 'log_event':
                return this.executeLogEvent(action, context);
            default:
                throw new Error(`Unknown action type: ${action.type}`);
        }
    }
    /**
     * Execute route to model action
     */
    async executeRouteToModel(action, context) {
        this.trace('Routing to model [executeRouteToModel]', action.parameters);
        return { routed: true, modelId: action.parameters.modelId };
    }
    /**
     * Execute set priority action
     */
    async executeSetPriority(action, context) {
        this.trace('Setting priority [executeSetPriority]', action.parameters);
        return { priority: action.parameters.priority };
    }
    /**
     * Execute add tag action
     */
    async executeAddTag(action, context) {
        this.trace('Adding tag [executeAddTag]', action.parameters);
        return { tagAdded: true, tag: action.parameters.tag };
    }
    /**
     * Execute remove tag action
     */
    async executeRemoveTag(action, context) {
        this.trace('Removing tag [executeRemoveTag]', action.parameters);
        return { tagRemoved: true, tag: action.parameters.tag };
    }
    /**
     * Execute log event action
     */
    async executeLogEvent(action, context) {
        this.log('Event logged', { event: action.parameters.event }, 'executeLogEvent');
        return { logged: true };
    }
    /**
     * Create evaluation result
     */
    createEvaluationResult(rule, matched, result, confidence, conditionEvalTime = 0, conditionsEvaluated = 0, conditionsMatched = 0, executionResults, totalExecutionTime = 0) {
        return {
            ruleId: rule.id,
            matched,
            confidence,
            executionResults: executionResults || {
                actions: [],
                totalExecutionTime: 0,
                allSuccess: false
            },
            timestamp: Date.now(),
            metrics: {
                conditionEvalTime,
                conditionsEvaluated,
                conditionsMatched
            }
        };
    }
    /**
     * Update rule metrics
     */
    updateRuleMetrics(ruleId, result, evaluationTime) {
        const metrics = this.ruleMetrics.get(ruleId);
        if (!metrics)
            return;
        metrics.totalEvaluations++;
        metrics.lastEvaluation = Date.now();
        metrics.avgEvaluationTime = (metrics.avgEvaluationTime * (metrics.totalEvaluations - 1) + evaluationTime) / metrics.totalEvaluations;
        if (result.matched) {
            metrics.successfulMatches++;
            metrics.avgConfidence = (metrics.avgConfidence * (metrics.successfulMatches - 1) + result.confidence) / metrics.successfulMatches;
        }
        else {
            metrics.failedMatches++;
        }
        metrics.matchRate = metrics.successfulMatches / metrics.totalEvaluations;
        if (result.executionResults.allSuccess) {
            const successCount = metrics.actionSuccessRate * (metrics.totalEvaluations - 1);
            metrics.actionSuccessRate = (successCount + 1) / metrics.totalEvaluations;
        }
        if (!result.executionResults.allSuccess) {
            metrics.errorCount++;
        }
    }
    /**
     * Get cache key for rule evaluation
     */
    getCacheKey(rule, context) {
        return `${rule.id}_${context.requestId}_${context.model?.modelId || 'unknown'}_${JSON.stringify(context.request)}`;
    }
    /**
     * Clear cache entries for a rule
     */
    clearRuleCache(ruleId) {
        const keysToDelete = [];
        for (const [key, value] of this.ruleExecutionCache.entries()) {
            if (key.startsWith(`${ruleId}_`)) {
                keysToDelete.push(key);
            }
        }
        for (const key of keysToDelete) {
            this.ruleExecutionCache.delete(key);
        }
    }
    /**
     * Cleanup expired cache entries
     */
    cleanupCache() {
        const now = Date.now();
        const keysToDelete = [];
        for (const [key, value] of this.ruleExecutionCache.entries()) {
            if (now - value.timestamp > value.ttl) {
                keysToDelete.push(key);
            }
        }
        for (const key of keysToDelete) {
            this.ruleExecutionCache.delete(key);
        }
        if (keysToDelete.length > 0) {
            this.trace('Cache cleanup completed [cleanupCache]', {
                entriesRemoved: keysToDelete.length
            });
        }
    }
    /**
     * Check if schedule is currently active
     */
    isScheduleActive(schedule) {
        const now = new Date();
        const currentTime = now.getHours() * 60 + now.getMinutes();
        // Check time windows
        if (schedule.timeWindows) {
            const { startTime, endTime } = schedule.timeWindows;
            if (startTime && endTime) {
                const [startHour, startMinute] = startTime.split(':').map(Number);
                const [endHour, endMinute] = endTime.split(':').map(Number);
                const startTimeMinutes = startHour * 60 + startMinute;
                const endTimeMinutes = endHour * 60 + endMinute;
                if (currentTime < startTimeMinutes || currentTime > endTimeMinutes) {
                    return false;
                }
            }
            // Check days of week
            if (schedule.timeWindows.daysOfWeek) {
                const currentDay = now.getDay();
                if (!schedule.timeWindows.daysOfWeek.includes(currentDay)) {
                    return false;
                }
            }
        }
        return true;
    }
    /**
     * Handle rule evaluation message
     */
    async handleRuleEvaluation(message) {
        this.log('Handling rule evaluation request', {}, 'handleRuleEvaluation');
        const context = message.payload?.context;
        if (!context) {
            return {
                messageId: message.id,
                correlationId: message.correlationId || '',
                success: false,
                error: 'Missing evaluation context',
                timestamp: Date.now()
            };
        }
        try {
            const results = await this.evaluateRules(context);
            return {
                messageId: message.id,
                correlationId: message.correlationId || '',
                success: true,
                data: { results },
                timestamp: Date.now()
            };
        }
        catch (error) {
            return {
                messageId: message.id,
                correlationId: message.correlationId || '',
                success: false,
                error: error instanceof Error ? error.message : String(error),
                timestamp: Date.now()
            };
        }
    }
    /**
     * Handle schedule status message
     */
    async handleScheduleStatus(message) {
        this.log('Handling schedule status request', {}, 'handleScheduleStatus');
        const modelId = message.payload?.modelId;
        const scheduleStatus = {};
        if (modelId) {
            scheduleStatus[modelId] = await this.isModelScheduled(modelId);
        }
        else {
            for (const modelId of this.schedules.keys()) {
                scheduleStatus[modelId] = await this.isModelScheduled(modelId);
            }
        }
        return {
            messageId: message.id,
            correlationId: message.correlationId || '',
            success: true,
            data: { scheduleStatus },
            timestamp: Date.now()
        };
    }
    /**
     * Handle rule metrics message
     */
    async handleRuleMetrics(message) {
        this.log('Handling rule metrics request', {}, 'handleRuleMetrics');
        const ruleId = message.payload?.ruleId;
        const metrics = this.getRuleMetrics(ruleId);
        return {
            messageId: message.id,
            correlationId: message.correlationId || '',
            success: true,
            data: { metrics },
            timestamp: Date.now()
        };
    }
}
exports.VirtualModelRulesModule = VirtualModelRulesModule;
//# sourceMappingURL=VirtualModelRulesModule.js.map