( eventType: SimRuleEventType, config: SimSubscriptionConfig, context: ExecutionEventContext )
| 136 | * and is owned by the inactivity poller. |
| 137 | */ |
| 138 | export async function evaluateRule( |
| 139 | eventType: SimRuleEventType, |
| 140 | config: SimSubscriptionConfig, |
| 141 | context: ExecutionEventContext |
| 142 | ): Promise<boolean> { |
| 143 | switch (eventType) { |
| 144 | case 'consecutive_failures': |
| 145 | if (context.status !== 'error') return false |
| 146 | return checkConsecutiveFailures(context.workflowId, config.consecutiveFailures) |
| 147 | |
| 148 | case 'failure_rate': |
| 149 | if (context.status !== 'error') return false |
| 150 | return checkFailureRate(context.workflowId, config.failureRatePercent, config.windowHours) |
| 151 | |
| 152 | case 'latency_threshold': |
| 153 | return context.durationMs > config.durationThresholdMs |
| 154 | |
| 155 | case 'latency_spike': |
| 156 | return checkLatencySpike( |
| 157 | context.workflowId, |
| 158 | context.durationMs, |
| 159 | config.latencySpikePercent, |
| 160 | config.windowHours |
| 161 | ) |
| 162 | |
| 163 | case 'cost_threshold': |
| 164 | // The threshold is credit-denominated (the UI unit); run costs are |
| 165 | // stored in dollars, so convert the threshold for the comparison. |
| 166 | return context.cost > creditsToDollars(config.costThresholdCredits) |
| 167 | |
| 168 | case 'error_count': |
| 169 | if (context.status !== 'error') return false |
| 170 | return checkErrorCount(context.workflowId, config.errorCountThreshold, config.windowHours) |
| 171 | |
| 172 | case 'no_activity': |
| 173 | return false |
| 174 | |
| 175 | default: |
| 176 | logger.warn(`Unknown sim trigger rule: ${eventType}`) |
| 177 | return false |
| 178 | } |
| 179 | } |
no test coverage detected