AIPredictor
Overview
AIPredictor learns from the store's dispatch history to predict what will happen next. It offers three prediction types: next action prediction (pattern-matched from action sequences), state change prediction (based on what previous identical actions changed), and performance forecasting (statistical range from historical latencies). It also runs anomaly detection on every recorded transition, flagging performance outliers and unexpected state key changes.
All analysis is local and statistical — no external model or API key is required.
Key Concepts
- Transition history —
recordTransitionadds aStateTransitionto the internal log. The predictor learns as more transitions accumulate; predictions improve with more data. - Confidence — predictions carry a
confidencevalue (0–1). Predictions belowminConfidenceThreshold(default 0.6) are suppressed andnullis returned. - Anomaly detection — each recorded transition is checked against statistical baselines. Performance deviations beyond
anomalyThresholdstandard deviations, and unexpected state key changes, produceAnomalyobjects. - History size —
historySizecaps the transition log (default 100). Older transitions are discarded in FIFO order.
API Reference
PredictorConfig
interface PredictorConfig {
enableStatePrediction?: boolean; // default true
enableAnomalyDetection?: boolean; // default true
enablePerformanceForecasting?: boolean; // default true
minConfidenceThreshold?: number; // 0–1, default 0.6
anomalyThreshold?: number; // standard deviations, default 2.5
historySize?: number; // default 100
}
StateTransition
interface StateTransition {
fromState: any;
toState: any;
action: { type: string; payload?: any };
timestamp: number;
duration?: number; // ms; required for performance anomaly detection
}
Prediction
interface Prediction {
type: 'state' | 'action' | 'performance';
confidence: number; // 0–1
prediction: any; // varies by type
reasoning: string; // human-readable explanation
timestamp: number;
}
For type: 'action', prediction is { type: string } (the predicted action type).
For type: 'state', prediction is a partial state snapshot.
For type: 'performance', prediction is { expectedDuration: number, range: [number, number], unit: 'ms' }.
Anomaly
interface Anomaly {
severity: 'low' | 'medium' | 'high' | 'critical';
type: string; // 'PERFORMANCE_ANOMALY' or 'STATE_ANOMALY'
description: string;
detectedAt: number;
affectedState?: string;
expectedValue?: any;
actualValue?: any;
recommendation?: string;
}
AIPredictor
class AIPredictor {
constructor(config?: PredictorConfig)
recordTransition(transition: StateTransition): void
predictNextAction(recentActions: any[]): Prediction | null
predictStateChange(currentState: any, action: any): Prediction | null
predictPerformance(actionType: string): Prediction | null
getAnomalies(since?: number): Anomaly[] // since: Unix timestamp ms
clearAnomalies(): void
getAccuracyStats(): {
totalPredictions: number;
actionPredictions: number;
statePredictions: number;
performancePredictions: number;
}
}
function createPredictor(config?: PredictorConfig): AIPredictor
Basic Usage
import { AIPredictor } from '@tagna/udiot';
const predictor = new AIPredictor({
minConfidenceThreshold: 0.7,
historySize: 200,
});
// Simulate recording transitions (normally done by @AIPowered)
const transitions = [
{ fromState: { cart: [] }, toState: { cart: [{ id: 1 }] }, action: { type: 'ADD_ITEM' }, timestamp: Date.now(), duration: 5 },
{ fromState: { cart: [{ id: 1 }] }, toState: { cart: [{ id: 1 }], loading: true }, action: { type: 'CHECKOUT_START' }, timestamp: Date.now(), duration: 8 },
{ fromState: { cart: [{ id: 1 }], loading: true }, toState: { cart: [], loading: false }, action: { type: 'CHECKOUT_COMPLETE' }, timestamp: Date.now(), duration: 250 },
];
transitions.forEach(t => predictor.recordTransition(t));
// Predict next action given recent history
const recentActions = [{ type: 'ADD_ITEM' }, { type: 'CHECKOUT_START' }];
const nextAction = predictor.predictNextAction(recentActions);
if (nextAction) {
console.log(`Predicted next: ${nextAction.prediction.type} (${(nextAction.confidence * 100).toFixed(0)}% confidence)`);
// Predicted next: CHECKOUT_COMPLETE (100% confidence)
}
// Check for anomalies in the last second
const anomalies = predictor.getAnomalies(Date.now() - 1000);
anomalies.forEach(a => console.log(`[${a.severity}] ${a.description}`));
Common Patterns
Enabling predictions on a store via @AIPowered
import { ReactiveStore, AIPowered, Store, getPredictor, Mutation } from '@tagna/udiot';
@ReactiveStore({ name: 'CheckoutStore' })
@AIPowered({
predictor: {
enableStatePrediction: true,
enableAnomalyDetection: true,
minConfidenceThreshold: 0.65,
historySize: 150,
},
onAnomaly: (anomaly) => {
console.error(`[Anomaly] ${anomaly.severity}: ${anomaly.description}`);
},
})
class CheckoutStore extends Store<CheckoutState> {
constructor(state: CheckoutState) { super(state); }
@Mutation()
addItem(item: CartItem): void {
this.dispatch({ type: 'ADD_ITEM', payload: item });
}
}
const store = new CheckoutStore({ cart: [], loading: false });
// After dispatches, access the predictor
const predictor = getPredictor(store);
const stats = predictor?.getAccuracyStats();
console.log('Stats:', stats);
Proactive data prefetching based on predictions
import { getPredictor } from '@tagna/udiot';
import { Injectable } from '@tagna/udiot';
@Injectable()
class PrefetchService {
constructor(private store: CheckoutStore, private api: ApiService) {}
watchAndPrefetch(): void {
const predictor = getPredictor(this.store);
if (!predictor) return;
this.store.subscribe(async () => {
const history = this.store.getActionHistory?.() ?? [];
const prediction = predictor.predictNextAction(history);
if (prediction && prediction.type === 'action') {
const { type } = prediction.prediction;
if (type === 'CHECKOUT_START' && prediction.confidence > 0.8) {
// Pre-load checkout data before user clicks checkout
await this.api.prefetchShippingOptions();
}
}
});
}
}
Manual anomaly monitoring
import { AIPredictor } from '@tagna/udiot';
const predictor = new AIPredictor({ anomalyThreshold: 2.0 });
// Feed 20+ transitions to establish a baseline
// ... recordTransition calls ...
// Poll for recent anomalies
setInterval(() => {
const recent = predictor.getAnomalies(Date.now() - 5000); // last 5 seconds
const critical = recent.filter(a => a.severity === 'critical');
if (critical.length > 0) {
alertingService.page('Critical state anomalies detected', critical);
}
}, 5000);
Integration Notes
@AIPoweredcallspredictor.recordTransition(transition)on every dispatch, providingdurationfrom the measured dispatch time. Anomaly detection on performance requires at least 10 samples for a given action type before baselines are established.predictNextActionrequires at least 2 recent actions and at least one matching pattern in the transition history. With a fresh store (few dispatches), it will returnnull.getAnomalies(since)filters bydetectedAttimestamp. Without thesinceparameter, all recorded anomalies are returned regardless of age.
Pitfalls
- Predictions are correlational, not causal. A high-confidence prediction means the pattern occurred frequently in history; it does not mean the predicted action is appropriate in the current context.
- Performance anomaly detection requires the
durationfield inStateTransition. If you record transitions manually withoutduration, only state anomalies (unexpected key changes) are checked. - The
anomalyThresholddefault of 2.5 standard deviations means roughly 1.2% of transitions will trigger an anomaly in a normal distribution. In applications with high natural variance, raise the threshold to reduce false positives. clearAnomalies()discards all historical anomaly records but does not reset performance baselines. New anomalies will still be detected against the same baselines going forward.