@higher.archi/boe 1.0.26 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engines/decay/compiler.d.ts +11 -0
- package/dist/engines/decay/compiler.d.ts.map +1 -0
- package/dist/engines/decay/compiler.js +216 -0
- package/dist/engines/decay/compiler.js.map +1 -0
- package/dist/engines/decay/engine.d.ts +48 -0
- package/dist/engines/decay/engine.d.ts.map +1 -0
- package/dist/engines/decay/engine.js +90 -0
- package/dist/engines/decay/engine.js.map +1 -0
- package/dist/engines/decay/index.d.ts +9 -0
- package/dist/engines/decay/index.d.ts.map +1 -0
- package/dist/engines/decay/index.js +21 -0
- package/dist/engines/decay/index.js.map +1 -0
- package/dist/engines/decay/strategy.d.ts +19 -0
- package/dist/engines/decay/strategy.d.ts.map +1 -0
- package/dist/engines/decay/strategy.js +284 -0
- package/dist/engines/decay/strategy.js.map +1 -0
- package/dist/engines/decay/types.d.ts +148 -0
- package/dist/engines/decay/types.d.ts.map +1 -0
- package/dist/engines/decay/types.js +39 -0
- package/dist/engines/decay/types.js.map +1 -0
- package/dist/engines/negotiation/compiler.d.ts +11 -0
- package/dist/engines/negotiation/compiler.d.ts.map +1 -0
- package/dist/engines/negotiation/compiler.js +177 -0
- package/dist/engines/negotiation/compiler.js.map +1 -0
- package/dist/engines/negotiation/engine.d.ts +46 -0
- package/dist/engines/negotiation/engine.d.ts.map +1 -0
- package/dist/engines/negotiation/engine.js +88 -0
- package/dist/engines/negotiation/engine.js.map +1 -0
- package/dist/engines/negotiation/index.d.ts +8 -0
- package/dist/engines/negotiation/index.d.ts.map +1 -0
- package/dist/engines/negotiation/index.js +17 -0
- package/dist/engines/negotiation/index.js.map +1 -0
- package/dist/engines/negotiation/strategy.d.ts +18 -0
- package/dist/engines/negotiation/strategy.d.ts.map +1 -0
- package/dist/engines/negotiation/strategy.js +439 -0
- package/dist/engines/negotiation/strategy.js.map +1 -0
- package/dist/engines/negotiation/types.d.ts +179 -0
- package/dist/engines/negotiation/types.d.ts.map +1 -0
- package/dist/engines/negotiation/types.js +10 -0
- package/dist/engines/negotiation/types.js.map +1 -0
- package/dist/engines/sentiment/engine.d.ts +25 -1
- package/dist/engines/sentiment/engine.d.ts.map +1 -1
- package/dist/engines/sentiment/engine.js +119 -0
- package/dist/engines/sentiment/engine.js.map +1 -1
- package/dist/engines/sentiment/index.d.ts +1 -1
- package/dist/engines/sentiment/index.d.ts.map +1 -1
- package/dist/engines/sentiment/index.js.map +1 -1
- package/dist/engines/sentiment/strategy.d.ts +2 -0
- package/dist/engines/sentiment/strategy.d.ts.map +1 -1
- package/dist/engines/sentiment/strategy.js +7 -8
- package/dist/engines/sentiment/strategy.js.map +1 -1
- package/dist/engines/sentiment/types.d.ts +9 -0
- package/dist/engines/sentiment/types.d.ts.map +1 -1
- package/dist/engines/sentiment/types.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engines/decay/compiler.ts +276 -0
- package/src/engines/decay/engine.ts +119 -0
- package/src/engines/decay/index.ts +42 -0
- package/src/engines/decay/strategy.ts +400 -0
- package/src/engines/decay/types.ts +221 -0
- package/src/engines/negotiation/compiler.ts +229 -0
- package/src/engines/negotiation/engine.ts +117 -0
- package/src/engines/negotiation/index.ts +42 -0
- package/src/engines/negotiation/strategy.ts +587 -0
- package/src/engines/negotiation/types.ts +244 -0
- package/src/engines/sentiment/engine.ts +157 -1
- package/src/engines/sentiment/index.ts +2 -1
- package/src/engines/sentiment/strategy.ts +12 -9
- package/src/engines/sentiment/types.ts +10 -0
- package/src/index.ts +70 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decay Engine Compiler
|
|
3
|
+
*
|
|
4
|
+
* Validates decay rulesets and resolves defaults.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CompilationError } from '../../core/errors';
|
|
8
|
+
import { SEMANTIC_PRIORITY_VALUES, isSemanticPriority, type SemanticPriority } from '../utility/types';
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
DecayRuleSet,
|
|
12
|
+
CompiledDecayRuleSet,
|
|
13
|
+
CompiledSingleDimensionDecayRuleSet,
|
|
14
|
+
CompiledMultiDimensionDecayRuleSet,
|
|
15
|
+
CompiledEventDrivenDecayRuleSet,
|
|
16
|
+
CompiledDecayDimension,
|
|
17
|
+
DecayDimension,
|
|
18
|
+
ReEngagementRule,
|
|
19
|
+
UrgencyTier
|
|
20
|
+
} from './types';
|
|
21
|
+
import { URGENCY_THRESHOLDS } from './types';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Compile and validate a decay ruleset.
|
|
25
|
+
*/
|
|
26
|
+
export function compileDecayRuleSet(
|
|
27
|
+
ruleSet: DecayRuleSet
|
|
28
|
+
): CompiledDecayRuleSet {
|
|
29
|
+
if (!ruleSet.id) {
|
|
30
|
+
throw new CompilationError('Decay ruleset requires an id');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (ruleSet.mode !== 'decay') {
|
|
34
|
+
throw new CompilationError(`Expected mode 'decay', got '${ruleSet.mode}'`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!ruleSet.entityType || ruleSet.entityType.trim() === '') {
|
|
38
|
+
throw new CompilationError('entityType is required and must be non-empty');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const entityIdField = ruleSet.entityIdField ?? 'id';
|
|
42
|
+
const urgencyThresholds = resolveUrgencyThresholds(ruleSet.urgencyThresholds);
|
|
43
|
+
|
|
44
|
+
switch (ruleSet.strategy) {
|
|
45
|
+
case 'single-dimension':
|
|
46
|
+
return compileSingleDimension(ruleSet, entityIdField, urgencyThresholds);
|
|
47
|
+
case 'multi-dimension':
|
|
48
|
+
return compileMultiDimension(ruleSet, entityIdField, urgencyThresholds);
|
|
49
|
+
case 'event-driven':
|
|
50
|
+
return compileEventDriven(ruleSet, entityIdField, urgencyThresholds);
|
|
51
|
+
default:
|
|
52
|
+
throw new CompilationError(`Unknown decay strategy: '${(ruleSet as any).strategy}'`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ========================================
|
|
57
|
+
// Strategy-Specific Compilers
|
|
58
|
+
// ========================================
|
|
59
|
+
|
|
60
|
+
function compileSingleDimension(
|
|
61
|
+
ruleSet: DecayRuleSet & { strategy: 'single-dimension' },
|
|
62
|
+
entityIdField: string,
|
|
63
|
+
urgencyThresholds: Record<UrgencyTier, number>
|
|
64
|
+
): CompiledSingleDimensionDecayRuleSet {
|
|
65
|
+
const dimension = ruleSet.dimension;
|
|
66
|
+
if (!dimension) {
|
|
67
|
+
throw new CompilationError('Single-dimension strategy requires a dimension');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
validateDimension(dimension);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
id: ruleSet.id,
|
|
74
|
+
name: ruleSet.name,
|
|
75
|
+
mode: 'decay',
|
|
76
|
+
strategy: 'single-dimension',
|
|
77
|
+
entityType: ruleSet.entityType,
|
|
78
|
+
entityIdField,
|
|
79
|
+
urgencyThresholds,
|
|
80
|
+
dimension: compileDimension(dimension, 1.0)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function compileMultiDimension(
|
|
85
|
+
ruleSet: DecayRuleSet & { strategy: 'multi-dimension' },
|
|
86
|
+
entityIdField: string,
|
|
87
|
+
urgencyThresholds: Record<UrgencyTier, number>
|
|
88
|
+
): CompiledMultiDimensionDecayRuleSet {
|
|
89
|
+
const { dimensions } = ruleSet;
|
|
90
|
+
|
|
91
|
+
if (!dimensions || !Array.isArray(dimensions) || dimensions.length === 0) {
|
|
92
|
+
throw new CompilationError('Multi-dimension strategy requires at least one dimension');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
validateDimensionIds(dimensions);
|
|
96
|
+
for (const dim of dimensions) {
|
|
97
|
+
validateDimension(dim);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const compiledDimensions = compileDimensions(dimensions);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
id: ruleSet.id,
|
|
104
|
+
name: ruleSet.name,
|
|
105
|
+
mode: 'decay',
|
|
106
|
+
strategy: 'multi-dimension',
|
|
107
|
+
entityType: ruleSet.entityType,
|
|
108
|
+
entityIdField,
|
|
109
|
+
urgencyThresholds,
|
|
110
|
+
dimensions: compiledDimensions,
|
|
111
|
+
aggregation: ruleSet.aggregation ?? 'weighted-average'
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function compileEventDriven(
|
|
116
|
+
ruleSet: DecayRuleSet & { strategy: 'event-driven' },
|
|
117
|
+
entityIdField: string,
|
|
118
|
+
urgencyThresholds: Record<UrgencyTier, number>
|
|
119
|
+
): CompiledEventDrivenDecayRuleSet {
|
|
120
|
+
const { dimensions, reEngagementRules } = ruleSet;
|
|
121
|
+
|
|
122
|
+
if (!dimensions || !Array.isArray(dimensions) || dimensions.length === 0) {
|
|
123
|
+
throw new CompilationError('Event-driven strategy requires at least one dimension');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
validateDimensionIds(dimensions);
|
|
127
|
+
for (const dim of dimensions) {
|
|
128
|
+
validateDimension(dim);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!reEngagementRules || !Array.isArray(reEngagementRules) || reEngagementRules.length === 0) {
|
|
132
|
+
throw new CompilationError('Event-driven strategy requires at least one re-engagement rule');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
validateReEngagementRules(reEngagementRules);
|
|
136
|
+
|
|
137
|
+
const compiledDimensions = compileDimensions(dimensions);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
id: ruleSet.id,
|
|
141
|
+
name: ruleSet.name,
|
|
142
|
+
mode: 'decay',
|
|
143
|
+
strategy: 'event-driven',
|
|
144
|
+
entityType: ruleSet.entityType,
|
|
145
|
+
entityIdField,
|
|
146
|
+
urgencyThresholds,
|
|
147
|
+
dimensions: compiledDimensions,
|
|
148
|
+
aggregation: ruleSet.aggregation ?? 'weighted-average',
|
|
149
|
+
reEngagementRules
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ========================================
|
|
154
|
+
// Validation Helpers
|
|
155
|
+
// ========================================
|
|
156
|
+
|
|
157
|
+
function validateDimension(dim: DecayDimension): void {
|
|
158
|
+
if (!dim.id) {
|
|
159
|
+
throw new CompilationError('Each dimension requires an id');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!dim.timestampField) {
|
|
163
|
+
throw new CompilationError(`Dimension '${dim.id}' requires a timestampField`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
switch (dim.curve) {
|
|
167
|
+
case 'exponential':
|
|
168
|
+
if (dim.halfLife === undefined || dim.halfLife <= 0) {
|
|
169
|
+
throw new CompilationError(`Dimension '${dim.id}' with exponential curve requires a positive halfLife`);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
case 'linear':
|
|
173
|
+
if (dim.maxAge === undefined || dim.maxAge <= 0) {
|
|
174
|
+
throw new CompilationError(`Dimension '${dim.id}' with linear curve requires a positive maxAge`);
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
case 'step':
|
|
178
|
+
if (dim.threshold === undefined || dim.threshold <= 0) {
|
|
179
|
+
throw new CompilationError(`Dimension '${dim.id}' with step curve requires a positive threshold`);
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
throw new CompilationError(`Dimension '${dim.id}' has unknown curve: '${dim.curve}'`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function validateDimensionIds(dimensions: DecayDimension[]): void {
|
|
188
|
+
const ids = new Set<string>();
|
|
189
|
+
for (const dim of dimensions) {
|
|
190
|
+
if (!dim.id) {
|
|
191
|
+
throw new CompilationError('Each dimension requires an id');
|
|
192
|
+
}
|
|
193
|
+
if (ids.has(dim.id)) {
|
|
194
|
+
throw new CompilationError(`Duplicate dimension id: '${dim.id}'`);
|
|
195
|
+
}
|
|
196
|
+
ids.add(dim.id);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function validateReEngagementRules(rules: ReEngagementRule[]): void {
|
|
201
|
+
const ids = new Set<string>();
|
|
202
|
+
for (const rule of rules) {
|
|
203
|
+
if (!rule.id) {
|
|
204
|
+
throw new CompilationError('Each re-engagement rule requires an id');
|
|
205
|
+
}
|
|
206
|
+
if (ids.has(rule.id)) {
|
|
207
|
+
throw new CompilationError(`Duplicate re-engagement rule id: '${rule.id}'`);
|
|
208
|
+
}
|
|
209
|
+
ids.add(rule.id);
|
|
210
|
+
|
|
211
|
+
if (!rule.eventType || rule.eventType.trim() === '') {
|
|
212
|
+
throw new CompilationError(`Re-engagement rule '${rule.id}' requires a non-empty eventType`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const validEffects = ['reset', 'boost', 'extend'];
|
|
216
|
+
if (!validEffects.includes(rule.effect)) {
|
|
217
|
+
throw new CompilationError(`Re-engagement rule '${rule.id}' has invalid effect: '${rule.effect}'`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (rule.effect === 'boost' && (rule.boostAmount === undefined || rule.boostAmount <= 0)) {
|
|
221
|
+
throw new CompilationError(`Re-engagement rule '${rule.id}' with boost effect requires a positive boostAmount`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (rule.effect === 'extend' && (rule.extensionDays === undefined || rule.extensionDays <= 0)) {
|
|
225
|
+
throw new CompilationError(`Re-engagement rule '${rule.id}' with extend effect requires a positive extensionDays`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ========================================
|
|
231
|
+
// Compilation Helpers
|
|
232
|
+
// ========================================
|
|
233
|
+
|
|
234
|
+
function compileDimension(dim: DecayDimension, weight: number): CompiledDecayDimension {
|
|
235
|
+
return {
|
|
236
|
+
id: dim.id,
|
|
237
|
+
name: dim.name,
|
|
238
|
+
timestampField: dim.timestampField,
|
|
239
|
+
curve: dim.curve,
|
|
240
|
+
timeUnit: dim.timeUnit,
|
|
241
|
+
halfLife: dim.halfLife,
|
|
242
|
+
maxAge: dim.maxAge,
|
|
243
|
+
threshold: dim.threshold,
|
|
244
|
+
floor: dim.floor,
|
|
245
|
+
weight
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function compileDimensions(dimensions: DecayDimension[]): CompiledDecayDimension[] {
|
|
250
|
+
// Resolve semantic weights to numeric
|
|
251
|
+
const resolved: { dim: DecayDimension; weight: number }[] = dimensions.map(dim => {
|
|
252
|
+
let weight: number;
|
|
253
|
+
if (isSemanticPriority(dim.weight)) {
|
|
254
|
+
weight = SEMANTIC_PRIORITY_VALUES[dim.weight as SemanticPriority];
|
|
255
|
+
} else if (typeof dim.weight === 'number') {
|
|
256
|
+
weight = dim.weight;
|
|
257
|
+
} else {
|
|
258
|
+
throw new CompilationError(`Invalid weight for dimension '${dim.id}': '${dim.weight}'`);
|
|
259
|
+
}
|
|
260
|
+
return { dim, weight };
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Normalize weights to sum to 1.0
|
|
264
|
+
const totalWeight = resolved.reduce((sum, r) => sum + r.weight, 0);
|
|
265
|
+
if (totalWeight === 0) {
|
|
266
|
+
throw new CompilationError('Dimension weights must not all be zero');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return resolved.map(r => compileDimension(r.dim, r.weight / totalWeight));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function resolveUrgencyThresholds(
|
|
273
|
+
overrides?: Partial<Record<UrgencyTier, number>>
|
|
274
|
+
): Record<UrgencyTier, number> {
|
|
275
|
+
return { ...URGENCY_THRESHOLDS, ...overrides };
|
|
276
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decay Engine
|
|
3
|
+
*
|
|
4
|
+
* Temporal decay engine that computes freshness scores for entities based
|
|
5
|
+
* on how recently their data was updated. Supports single-dimension,
|
|
6
|
+
* multi-dimension, and event-driven decay strategies.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const engine = new DecayEngine();
|
|
11
|
+
* engine.add({ type: 'Lead', data: { id: 'l1', lastContact: '2024-01-15' } });
|
|
12
|
+
* engine.add({ type: 'Lead', data: { id: 'l2', lastContact: '2024-03-01' } });
|
|
13
|
+
*
|
|
14
|
+
* const result = engine.execute(compiledDecay);
|
|
15
|
+
* console.log(result.entities[0]); // { entityId: 'l1', compositeFreshness: 0.42, urgencyTier: 'medium', ... }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
WorkingMemory,
|
|
21
|
+
Fact,
|
|
22
|
+
FactInput,
|
|
23
|
+
FactChange
|
|
24
|
+
} from '../../core';
|
|
25
|
+
|
|
26
|
+
import type {
|
|
27
|
+
CompiledDecayRuleSet,
|
|
28
|
+
DecayOptions,
|
|
29
|
+
DecayResult
|
|
30
|
+
} from './types';
|
|
31
|
+
|
|
32
|
+
import { DecayExecutor } from './strategy';
|
|
33
|
+
|
|
34
|
+
export class DecayEngine {
|
|
35
|
+
private wm: WorkingMemory;
|
|
36
|
+
private strategy: DecayExecutor;
|
|
37
|
+
|
|
38
|
+
constructor(workingMemory?: WorkingMemory) {
|
|
39
|
+
this.wm = workingMemory ?? new WorkingMemory();
|
|
40
|
+
this.strategy = new DecayExecutor();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ========================================
|
|
44
|
+
// IWorkingMemory Implementation
|
|
45
|
+
// ========================================
|
|
46
|
+
|
|
47
|
+
add<T = Record<string, any>>(input: FactInput<T>): Fact<T> {
|
|
48
|
+
return this.wm.add(input);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
remove(factId: string): Fact | undefined {
|
|
52
|
+
return this.wm.remove(factId);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
update<T = Record<string, any>>(input: FactInput<T>): Fact<T> {
|
|
56
|
+
return this.wm.update(input);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get(factId: string): Fact | undefined {
|
|
60
|
+
return this.wm.get(factId);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getByType(type: string): Fact[] {
|
|
64
|
+
return this.wm.getByType(type);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getAll(): Fact[] {
|
|
68
|
+
return this.wm.getAll();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
has(factId: string): boolean {
|
|
72
|
+
return this.wm.has(factId);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
size(): number {
|
|
76
|
+
return this.wm.size();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
clear(): void {
|
|
80
|
+
this.wm.clear();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getChanges(): FactChange[] {
|
|
84
|
+
return this.wm.getChanges();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
clearChanges(): void {
|
|
88
|
+
this.wm.clearChanges();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ========================================
|
|
92
|
+
// Engine Execution
|
|
93
|
+
// ========================================
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Execute a decay ruleset.
|
|
97
|
+
*
|
|
98
|
+
* Computes freshness scores for all entities of the configured type
|
|
99
|
+
* and maps each to an urgency tier.
|
|
100
|
+
*
|
|
101
|
+
* @param ruleSet - Compiled decay ruleset
|
|
102
|
+
* @param options - Runtime options (asOf date, onEntity callback)
|
|
103
|
+
* @returns Decay result with per-entity freshness and tier distribution
|
|
104
|
+
*/
|
|
105
|
+
execute(
|
|
106
|
+
ruleSet: CompiledDecayRuleSet,
|
|
107
|
+
options: DecayOptions = {}
|
|
108
|
+
): DecayResult {
|
|
109
|
+
return this.strategy.run(ruleSet, this.wm, options);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ========================================
|
|
113
|
+
// Utility Methods
|
|
114
|
+
// ========================================
|
|
115
|
+
|
|
116
|
+
getWorkingMemory(): WorkingMemory {
|
|
117
|
+
return this.wm;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decay Engine -- Temporal Freshness Scoring
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Types
|
|
6
|
+
export type {
|
|
7
|
+
DecayStrategy,
|
|
8
|
+
UrgencyTier,
|
|
9
|
+
ReEngagementEffect,
|
|
10
|
+
DecayAggregation,
|
|
11
|
+
DecayDimension,
|
|
12
|
+
CompiledDecayDimension,
|
|
13
|
+
ReEngagementRule,
|
|
14
|
+
SingleDimensionDecayRuleSet,
|
|
15
|
+
MultiDimensionDecayRuleSet,
|
|
16
|
+
EventDrivenDecayRuleSet,
|
|
17
|
+
DecayRuleSet,
|
|
18
|
+
CompiledSingleDimensionDecayRuleSet,
|
|
19
|
+
CompiledMultiDimensionDecayRuleSet,
|
|
20
|
+
CompiledEventDrivenDecayRuleSet,
|
|
21
|
+
CompiledDecayRuleSet,
|
|
22
|
+
DimensionDecayResult,
|
|
23
|
+
ReEngagementEvent,
|
|
24
|
+
EntityDecayResult,
|
|
25
|
+
DecayResult,
|
|
26
|
+
DecayOptions
|
|
27
|
+
} from './types';
|
|
28
|
+
|
|
29
|
+
// Constants & utilities
|
|
30
|
+
export {
|
|
31
|
+
URGENCY_THRESHOLDS,
|
|
32
|
+
resolveUrgencyTier
|
|
33
|
+
} from './types';
|
|
34
|
+
|
|
35
|
+
// Compiler
|
|
36
|
+
export { compileDecayRuleSet } from './compiler';
|
|
37
|
+
|
|
38
|
+
// Strategy
|
|
39
|
+
export { DecayExecutor, decayStrategy } from './strategy';
|
|
40
|
+
|
|
41
|
+
// Engine
|
|
42
|
+
export { DecayEngine } from './engine';
|