@higher.archi/boe 1.0.0 → 1.0.1
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/core/operators/examples.d.ts +1 -1
- package/dist/core/operators/examples.js +1 -1
- package/dist/engines/scoring/compiler.d.ts.map +1 -1
- package/dist/engines/scoring/compiler.js +24 -1
- package/dist/engines/scoring/compiler.js.map +1 -1
- package/dist/engines/scoring/index.d.ts +1 -1
- package/dist/engines/scoring/index.d.ts.map +1 -1
- package/dist/engines/scoring/index.js.map +1 -1
- package/dist/engines/scoring/strategy.d.ts.map +1 -1
- package/dist/engines/scoring/strategy.js +91 -2
- package/dist/engines/scoring/strategy.js.map +1 -1
- package/dist/engines/scoring/types.d.ts +31 -0
- package/dist/engines/scoring/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/operators/examples.ts +1 -1
- package/src/engines/scoring/compiler.ts +32 -1
- package/src/engines/scoring/index.ts +3 -0
- package/src/engines/scoring/strategy.ts +98 -3
- package/src/engines/scoring/types.ts +37 -0
- package/src/index.ts +3 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Operator Examples
|
|
3
3
|
*
|
|
4
4
|
* Demonstrates evaluation for each OperatorCategory.
|
|
5
|
-
* Run with: npx ts-node packages/
|
|
5
|
+
* Run with: npx ts-node packages/boe/src/core/operators/examples.ts
|
|
6
6
|
*/
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=examples.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Operator Examples
|
|
4
4
|
*
|
|
5
5
|
* Demonstrates evaluation for each OperatorCategory.
|
|
6
|
-
* Run with: npx ts-node packages/
|
|
6
|
+
* Run with: npx ts-node packages/boe/src/core/operators/examples.ts
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
const index_1 = require("./index");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/compiler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EACL,WAAW,EACX,cAAc,EAEd,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAmFjB,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,GAAE,MAAU,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/compiler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EACL,WAAW,EACX,cAAc,EAEd,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAmFjB,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,GAAE,MAAU,GAAG,mBAAmB,CAe5F;AAMD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,sBAAsB,CAgDrF"}
|
|
@@ -86,6 +86,7 @@ function compileScoringRule(rule, index = 0) {
|
|
|
86
86
|
index,
|
|
87
87
|
inputs,
|
|
88
88
|
when,
|
|
89
|
+
category: rule.category,
|
|
89
90
|
action: compileScoringAction(rule.then)
|
|
90
91
|
};
|
|
91
92
|
}
|
|
@@ -93,13 +94,35 @@ function compileScoringRule(rule, index = 0) {
|
|
|
93
94
|
// RuleSet Compilation
|
|
94
95
|
// ========================================
|
|
95
96
|
function compileScoringRuleSet(ruleSet) {
|
|
97
|
+
const categories = ruleSet.config?.categories;
|
|
98
|
+
// Validate categories if defined
|
|
99
|
+
if (categories?.length) {
|
|
100
|
+
const categoryIds = new Set(categories.map(c => c.id));
|
|
101
|
+
// Every rule must reference a valid category
|
|
102
|
+
for (const rule of ruleSet.rules) {
|
|
103
|
+
if (!rule.category) {
|
|
104
|
+
throw new Error(`Rule "${rule.id}" is missing a category. When categories are defined, every rule must have a category.`);
|
|
105
|
+
}
|
|
106
|
+
if (!categoryIds.has(rule.category)) {
|
|
107
|
+
throw new Error(`Rule "${rule.id}" references unknown category "${rule.category}". Valid categories: ${[...categoryIds].join(', ')}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Normalize category weights to sum to 1.0
|
|
111
|
+
const totalWeight = categories.reduce((sum, c) => sum + c.weight, 0);
|
|
112
|
+
if (totalWeight > 0 && Math.abs(totalWeight - 1.0) > 0.001) {
|
|
113
|
+
for (const cat of categories) {
|
|
114
|
+
cat.weight = cat.weight / totalWeight;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
96
118
|
const config = {
|
|
97
119
|
mode: 'scoring',
|
|
98
120
|
strategies: ruleSet.config?.strategies ?? ['raw'],
|
|
99
121
|
caps: ruleSet.config?.caps,
|
|
100
122
|
outputBounds: ruleSet.config?.outputBounds,
|
|
101
123
|
baseScore: ruleSet.config?.baseScore,
|
|
102
|
-
tiers: ruleSet.config?.tiers
|
|
124
|
+
tiers: ruleSet.config?.tiers,
|
|
125
|
+
categories
|
|
103
126
|
};
|
|
104
127
|
return {
|
|
105
128
|
id: ruleSet.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../src/engines/scoring/compiler.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAkGH,
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../src/engines/scoring/compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides scoring-based rule execution where rules contribute
|
|
5
5
|
* scores that are accumulated into a total score.
|
|
6
6
|
*/
|
|
7
|
-
export { ScoringMethod, ScoringCaps, OutputBounds, TierDefinition, ScoringTierMatch, ScoringAction, ScoringRule, ScoringRuleSet, ScoringConfig, CompiledScoringAction, CompiledScoringRule, CompiledScoringRuleSet, ScoreFunction, ScoreFunctionRegistry, ScoringOptions, ScoringResult } from './types';
|
|
7
|
+
export { ScoringMethod, ScoringCaps, OutputBounds, TierDefinition, ScoringTierMatch, ScoringCategory, CategoryResult, ScoringAction, ScoringRule, ScoringRuleSet, ScoringConfig, CompiledScoringAction, CompiledScoringRule, CompiledScoringRuleSet, ScoreFunction, ScoreFunctionRegistry, ScoringOptions, ScoringResult } from './types';
|
|
8
8
|
export { compileScoringRule, compileScoringRuleSet } from './compiler';
|
|
9
9
|
export { ScoringStrategy, scoringStrategy } from './strategy';
|
|
10
10
|
export { ScoringEngine } from './engine';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,aAAa,EACb,WAAW,EACX,YAAY,EAEZ,cAAc,EACd,gBAAgB,EAEhB,aAAa,EACb,WAAW,EACX,cAAc,EACd,aAAa,EAEb,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EAEtB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,aAAa,EACb,WAAW,EACX,YAAY,EAEZ,cAAc,EACd,gBAAgB,EAEhB,eAAe,EACf,cAAc,EAEd,aAAa,EACb,WAAW,EACX,cAAc,EACd,aAAa,EAEb,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EAEtB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engines/scoring/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engines/scoring/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA8BH,WAAW;AACX,uCAGoB;AAFlB,8GAAA,kBAAkB,OAAA;AAClB,iHAAA,qBAAqB,OAAA;AAGvB,WAAW;AACX,uCAGoB;AAFlB,2GAAA,eAAe,OAAA;AACf,2GAAA,eAAe,OAAA;AAGjB,SAAS;AACT,mCAAyC;AAAhC,uGAAA,aAAa,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/strategy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EACL,sBAAsB,EAEtB,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/strategy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EACL,sBAAsB,EAEtB,cAAc,EACd,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,qBAAa,eAAe;IAC1B,GAAG,CACD,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,cAAc,EAClB,OAAO,GAAE,cAAmB,GAC3B,aAAa;CA8PjB;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
|
|
@@ -95,8 +95,96 @@ class ScoringStrategy {
|
|
|
95
95
|
}
|
|
96
96
|
contributions[rule.id] = accumulatedScore;
|
|
97
97
|
}
|
|
98
|
-
// Phase 3: Apply global strategies
|
|
99
|
-
|
|
98
|
+
// Phase 3: Apply global strategies
|
|
99
|
+
let categoryBreakdown;
|
|
100
|
+
if (config.categories?.length) {
|
|
101
|
+
// Category-aware aggregation
|
|
102
|
+
const categories = config.categories;
|
|
103
|
+
// Group all rules (fired and unfired) by category
|
|
104
|
+
const rulesByCategory = new Map();
|
|
105
|
+
for (const cat of categories) {
|
|
106
|
+
rulesByCategory.set(cat.id, { fired: [], missing: [] });
|
|
107
|
+
}
|
|
108
|
+
for (const rule of ruleSet.rules) {
|
|
109
|
+
const catId = rule.category;
|
|
110
|
+
const group = rulesByCategory.get(catId);
|
|
111
|
+
if (fired.includes(rule.id)) {
|
|
112
|
+
group.fired.push(rule.id);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
group.missing.push(rule.id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Build category results
|
|
119
|
+
const catResults = [];
|
|
120
|
+
for (const cat of categories) {
|
|
121
|
+
const group = rulesByCategory.get(cat.id);
|
|
122
|
+
const totalSignals = group.fired.length + group.missing.length;
|
|
123
|
+
const minRatio = cat.minSignalRatio ?? 0.5;
|
|
124
|
+
const excluded = totalSignals > 0 && (group.fired.length / totalSignals) < minRatio;
|
|
125
|
+
let rawScore = 0;
|
|
126
|
+
if (!excluded && group.fired.length > 0) {
|
|
127
|
+
// Normalize signal weights within category to sum to 1.0 among fired signals
|
|
128
|
+
const firedWeights = {};
|
|
129
|
+
let totalFiredWeight = 0;
|
|
130
|
+
for (const ruleId of group.fired) {
|
|
131
|
+
const w = weights[ruleId] ?? 1;
|
|
132
|
+
firedWeights[ruleId] = w;
|
|
133
|
+
totalFiredWeight += w;
|
|
134
|
+
}
|
|
135
|
+
// Compute weighted average of fired signal scores
|
|
136
|
+
for (const ruleId of group.fired) {
|
|
137
|
+
const normalizedWeight = totalFiredWeight > 0 ? firedWeights[ruleId] / totalFiredWeight : 0;
|
|
138
|
+
rawScore += contributions[ruleId] * normalizedWeight;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catResults.push({
|
|
142
|
+
id: cat.id,
|
|
143
|
+
name: cat.name,
|
|
144
|
+
weight: cat.weight,
|
|
145
|
+
effectiveWeight: excluded ? 0 : cat.weight,
|
|
146
|
+
rawScore,
|
|
147
|
+
weightedContribution: 0, // computed after redistribution
|
|
148
|
+
signalsWithData: group.fired,
|
|
149
|
+
signalsMissing: group.missing,
|
|
150
|
+
excluded
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Redistribute excluded category weights proportionally to active categories
|
|
154
|
+
const excludedWeight = catResults.filter(c => c.excluded).reduce((sum, c) => sum + c.weight, 0);
|
|
155
|
+
const activeWeight = catResults.filter(c => !c.excluded).reduce((sum, c) => sum + c.weight, 0);
|
|
156
|
+
if (activeWeight > 0 && excludedWeight > 0) {
|
|
157
|
+
for (const cr of catResults) {
|
|
158
|
+
if (!cr.excluded) {
|
|
159
|
+
cr.effectiveWeight = cr.weight + (cr.weight / activeWeight) * excludedWeight;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Compute weighted contributions and update per-rule contributions
|
|
164
|
+
for (const cr of catResults) {
|
|
165
|
+
cr.weightedContribution = cr.effectiveWeight * cr.rawScore;
|
|
166
|
+
}
|
|
167
|
+
// Rewrite per-rule contributions to reflect category-weighted values
|
|
168
|
+
for (const cr of catResults) {
|
|
169
|
+
if (cr.excluded || cr.signalsWithData.length === 0)
|
|
170
|
+
continue;
|
|
171
|
+
const firedWeightsTotal = cr.signalsWithData.reduce((sum, id) => sum + (weights[id] ?? 1), 0);
|
|
172
|
+
for (const ruleId of cr.signalsWithData) {
|
|
173
|
+
const normalizedWeight = firedWeightsTotal > 0 ? (weights[ruleId] ?? 1) / firedWeightsTotal : 0;
|
|
174
|
+
contributions[ruleId] = contributions[ruleId] * normalizedWeight * cr.effectiveWeight;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Zero out contributions for excluded categories
|
|
178
|
+
for (const cr of catResults) {
|
|
179
|
+
if (cr.excluded) {
|
|
180
|
+
for (const ruleId of cr.signalsWithData) {
|
|
181
|
+
contributions[ruleId] = 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
categoryBreakdown = catResults;
|
|
186
|
+
}
|
|
187
|
+
else if (strategies.includes('weighted-percent')) {
|
|
100
188
|
const totalWeight = Object.values(weights).reduce((sum, w) => sum + w, 0);
|
|
101
189
|
if (totalWeight > 0) {
|
|
102
190
|
for (const ruleId in contributions) {
|
|
@@ -148,6 +236,7 @@ class ScoringStrategy {
|
|
|
148
236
|
fired,
|
|
149
237
|
iterations: 1,
|
|
150
238
|
tier,
|
|
239
|
+
categoryBreakdown,
|
|
151
240
|
executionTimeMs
|
|
152
241
|
};
|
|
153
242
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/engines/scoring/strategy.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAGoB;
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/engines/scoring/strategy.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,qCAGoB;AAYpB,MAAa,eAAe;IAC1B,GAAG,CACD,OAA+B,EAC/B,EAAkB,EAClB,UAA0B,EAAE;QAE5B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,EAAE,cAAc,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,CAAC;QAEhD,MAAM,aAAa,GAA2B,EAAE,CAAC;QACjD,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,SAAS,GAA6B,EAAE,CAAC,CAAC,gCAAgC;QAEhF,iCAAiC;QACjC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,WAAW,GAAG,IAAA,YAAK,EAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAEpC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACrC,MAAM,UAAU,GAAG,IAAI,CAAC,MAA+B,CAAC;gBACxD,IAAI,SAAiB,CAAC;gBAEtB,6BAA6B;gBAC7B,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACzC,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC;gBAC/B,CAAC;qBAAM,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAChD,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;oBACnD,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;oBACnE,CAAC;oBACD,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAC1C,CAAC;qBAAM,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;oBAC5E,MAAM,MAAM,GAAG,IAAA,wBAAiB,EAAC,UAAU,CAAC,KAAY,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;oBAC5E,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;gBACpE,CAAC;gBAED,yCAAyC;gBACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBACxB,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;gBAC1B,CAAC;gBACD,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEnC,yBAAyB;gBACzB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;gBAE1B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC7B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,IAAI,CAAC,MAA+B,CAAC;YACxD,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAC/C,IAAI,gBAAgB,GAAG,CAAC,CAAC;YAEzB,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;gBACtC,IAAI,cAAc,GAAG,SAAS,CAAC;gBAE/B,iCAAiC;gBACjC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;oBAC9D,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC;oBAC1C,cAAc,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;oBACtD,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,eAAe;gBAC5E,CAAC;qBAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC3C,+CAA+C;oBAC/C,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;wBACzB,sBAAsB;wBACtB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC;wBAC1C,cAAc,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;wBACtD,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;oBAC5D,CAAC;yBAAM,CAAC;wBACN,gCAAgC;wBAChC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;wBAC/C,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;4BACpB,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;wBAC3C,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,yBAAyB;gBACzB,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAClC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;wBACtB,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;oBACjD,CAAC;gBACH,CAAC;gBAED,gBAAgB,IAAI,cAAc,CAAC;YACrC,CAAC;YAED,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC;QAC5C,CAAC;QAED,mCAAmC;QACnC,IAAI,iBAA+C,CAAC;QAEpD,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;YAC9B,6BAA6B;YAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YACrC,kDAAkD;YAClD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkD,CAAC;YAClF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAS,CAAC;gBAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;gBAC1C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC5B,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;YAED,yBAAyB;YACzB,MAAM,UAAU,GAAqB,EAAE,CAAC;YACxC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;gBAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC;gBAC3C,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,QAAQ,CAAC;gBAEpF,IAAI,QAAQ,GAAG,CAAC,CAAC;gBACjB,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxC,6EAA6E;oBAC7E,MAAM,YAAY,GAA2B,EAAE,CAAC;oBAChD,IAAI,gBAAgB,GAAG,CAAC,CAAC;oBACzB,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBACjC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC/B,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBACzB,gBAAgB,IAAI,CAAC,CAAC;oBACxB,CAAC;oBACD,kDAAkD;oBAClD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBACjC,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC5F,QAAQ,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC;oBACvD,CAAC;gBACH,CAAC;gBAED,UAAU,CAAC,IAAI,CAAC;oBACd,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;oBAC1C,QAAQ;oBACR,oBAAoB,EAAE,CAAC,EAAE,gCAAgC;oBACzD,eAAe,EAAE,KAAK,CAAC,KAAK;oBAC5B,cAAc,EAAE,KAAK,CAAC,OAAO;oBAC7B,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;YAED,6EAA6E;YAC7E,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAChG,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC/F,IAAI,YAAY,GAAG,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;gBAC3C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;oBAC5B,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;wBACjB,EAAE,CAAC,eAAe,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,cAAc,CAAC;oBAC/E,CAAC;gBACH,CAAC;YACH,CAAC;YAED,mEAAmE;YACnE,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,EAAE,CAAC,oBAAoB,GAAG,EAAE,CAAC,eAAe,GAAG,EAAE,CAAC,QAAQ,CAAC;YAC7D,CAAC;YAED,qEAAqE;YACrE,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAC7D,MAAM,iBAAiB,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9F,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,eAAe,EAAE,CAAC;oBACxC,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;oBAChG,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,gBAAgB,GAAG,EAAE,CAAC,eAAe,CAAC;gBACxF,CAAC;YACH,CAAC;YACD,iDAAiD;YACjD,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAChB,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,eAAe,EAAE,CAAC;wBACxC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;YACH,CAAC;YAED,iBAAiB,GAAG,UAAU,CAAC;QACjC,CAAC;aAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1E,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;oBACnC,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC;oBACvD,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC;gBACnE,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,yBAAyB;YACzB,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;gBACnC,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;gBACzC,MAAM,CAAC,MAAM,EAAE,EAAS,EAAE,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QAEnG,qCAAqC;QACrC,IAAI,IAAkC,CAAC;QACvC,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,iEAAiE;YACjE,MAAM,gBAAgB,GAAG,CAAC,CAAuB,EAAU,EAAE,CAC3D,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnD,qDAAqD;YACrD,MAAM,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CACxE,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACtD,IAAI,UAAU,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,GAAG;wBACL,EAAE,EAAE,OAAO,CAAC,EAAE;wBACd,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,WAAW,EAAE,OAAO,CAAC,WAAW;wBAChC,SAAS;qBACV,CAAC;oBACF,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAEhF,OAAO;YACL,UAAU;YACV,aAAa;YACb,KAAK;YACL,UAAU,EAAE,CAAC;YACb,IAAI;YACJ,iBAAiB;YACjB,eAAe;SAChB,CAAC;IACJ,CAAC;CACF;AAnQD,0CAmQC;AAED,8CAA8C;AACjC,QAAA,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -66,6 +66,33 @@ export type ScoringTierMatch = {
|
|
|
66
66
|
description?: string;
|
|
67
67
|
threshold: number;
|
|
68
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* Category definition for grouping related scoring signals
|
|
71
|
+
*
|
|
72
|
+
* Categories provide a two-level weight hierarchy: category weights
|
|
73
|
+
* control how much each group contributes to the total, and signal
|
|
74
|
+
* weights within each category control relative importance of rules.
|
|
75
|
+
*/
|
|
76
|
+
export type ScoringCategory = {
|
|
77
|
+
id: string;
|
|
78
|
+
name?: string;
|
|
79
|
+
weight: number;
|
|
80
|
+
minSignalRatio?: number;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Per-category result breakdown showing how each category contributed
|
|
84
|
+
*/
|
|
85
|
+
export type CategoryResult = {
|
|
86
|
+
id: string;
|
|
87
|
+
name?: string;
|
|
88
|
+
weight: number;
|
|
89
|
+
effectiveWeight: number;
|
|
90
|
+
rawScore: number;
|
|
91
|
+
weightedContribution: number;
|
|
92
|
+
signalsWithData: string[];
|
|
93
|
+
signalsMissing: string[];
|
|
94
|
+
excluded: boolean;
|
|
95
|
+
};
|
|
69
96
|
/**
|
|
70
97
|
* Scoring action - contributes a score when rule matches
|
|
71
98
|
*/
|
|
@@ -82,6 +109,7 @@ export type ScoringAction = {
|
|
|
82
109
|
* Scoring rule - uses 'then' for scoring properties
|
|
83
110
|
*/
|
|
84
111
|
export type ScoringRule = BaseRule & {
|
|
112
|
+
category?: string;
|
|
85
113
|
then: ScoringAction;
|
|
86
114
|
};
|
|
87
115
|
/**
|
|
@@ -102,6 +130,7 @@ export type ScoringConfig = {
|
|
|
102
130
|
outputBounds?: OutputBounds;
|
|
103
131
|
baseScore?: number;
|
|
104
132
|
tiers?: TierDefinition[];
|
|
133
|
+
categories?: ScoringCategory[];
|
|
105
134
|
};
|
|
106
135
|
/**
|
|
107
136
|
* Compiled scoring action
|
|
@@ -120,6 +149,7 @@ export type CompiledScoringAction = {
|
|
|
120
149
|
* Compiled scoring rule
|
|
121
150
|
*/
|
|
122
151
|
export type CompiledScoringRule = CompiledBaseRule & {
|
|
152
|
+
category?: string;
|
|
123
153
|
action: CompiledScoringAction;
|
|
124
154
|
};
|
|
125
155
|
/**
|
|
@@ -154,6 +184,7 @@ export type ScoringResult = {
|
|
|
154
184
|
fired: string[];
|
|
155
185
|
iterations: 1;
|
|
156
186
|
tier?: ScoringTierMatch;
|
|
187
|
+
categoryBreakdown?: CategoryResult[];
|
|
157
188
|
executionTimeMs: number;
|
|
158
189
|
};
|
|
159
190
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;AAMpB;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,YAAY,GACZ,UAAU,GACV,kBAAkB,GAClB,QAAQ,CAAC;AAEb;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5B,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,YAAY,CAAC;AAEjB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAMF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG;IACnC,IAAI,EAAE,aAAa,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/engines/scoring/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export type { ForwardRule, ForwardRuleSet, ForwardConfig, CompiledForwardRuleSet
|
|
|
30
30
|
export { BackwardChainingStrategy, compileBackwardRuleSet, backwardStrategy } from './engines/backward';
|
|
31
31
|
export type { BackwardRule, BackwardRuleSet, BackwardConfig, CompiledBackwardRuleSet, BackwardOptions, BackwardResult, ProofStep, ProofResult } from './engines/backward';
|
|
32
32
|
export { ScoringStrategy, compileScoringRuleSet, scoringStrategy } from './engines/scoring';
|
|
33
|
-
export type { ScoringRule, ScoringRuleSet, ScoringConfig, CompiledScoringRuleSet, ScoringOptions, ScoringResult, ScoreFunctionRegistry, ScoringMethod, OutputBounds } from './engines/scoring';
|
|
33
|
+
export type { ScoringRule, ScoringRuleSet, ScoringConfig, CompiledScoringRuleSet, ScoringOptions, ScoringResult, ScoreFunctionRegistry, ScoringMethod, OutputBounds, ScoringCategory, CategoryResult } from './engines/scoring';
|
|
34
34
|
export { SequentialStrategy, compileSequentialRuleSet, sequentialStrategy } from './engines/sequential';
|
|
35
35
|
export type { SequentialRule, SequentialRuleSet, SequentialConfig, CompiledSequentialRuleSet, SequentialOptions, SequentialResult } from './engines/sequential';
|
|
36
36
|
export { FuzzyStrategy, compileFuzzyRuleSet, fuzzyStrategy, compileFuzzyVariable, analyzeCoverage, autoAdjustCoverage } from './engines/fuzzy';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMlD,cAAc,QAAQ,CAAC;AAOvB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,eAAe,EACf,cAAc,EACd,SAAS,EACT,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;AAEH,2CAA2C;AAC3C,UAAU;AACV,2CAA2C;AAE3C,iEAAiE;AACjE,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,+CAAoD;AAA3C,0GAAA,cAAc,OAAA;AACvB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,mDAAwD;AAA/C,8GAAA,gBAAgB,OAAA;AACzB,yCAA8C;AAArC,oGAAA,WAAW,OAAA;AACpB,+CAAoD;AAA3C,0GAAA,cAAc,OAAA;AACvB,qDAAyD;AAAhD,+GAAA,gBAAgB,OAAA;AACzB,yDAA6D;AAApD,mHAAA,kBAAkB,OAAA;AAC3B,mDAAwD;AAA/C,8GAAA,gBAAgB,OAAA;AACzB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AAEtB,2CAA2C;AAC3C,yBAAyB;AACzB,2CAA2C;AAE3C,yCAAuB;AAEvB,2CAA2C;AAC3C,UAAU;AACV,2CAA2C;AAE3C,mBAAmB;AACnB,6CAK2B;AAJzB,kHAAA,uBAAuB,OAAA;AACvB,gHAAA,qBAAqB,OAAA;AACrB,6GAAA,kBAAkB,OAAA;AAClB,0GAAA,eAAe,OAAA;AAcjB,oBAAoB;AACpB,+CAI4B;AAH1B,oHAAA,wBAAwB,OAAA;AACxB,kHAAA,sBAAsB,OAAA;AACtB,4GAAA,gBAAgB,OAAA;AAalB,UAAU;AACV,6CAI2B;AAHzB,0GAAA,eAAe,OAAA;AACf,gHAAA,qBAAqB,OAAA;AACrB,0GAAA,eAAe,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@higher.archi/boe",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A multi-strategy rule engine supporting forward chaining, backward chaining, scoring, sequential, fuzzy logic, and Bayesian inference",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Operator Examples
|
|
3
3
|
*
|
|
4
4
|
* Demonstrates evaluation for each OperatorCategory.
|
|
5
|
-
* Run with: npx ts-node packages/
|
|
5
|
+
* Run with: npx ts-node packages/boe/src/core/operators/examples.ts
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { createDefaultRegistry, createEvaluator } from './index';
|
|
@@ -110,6 +110,7 @@ export function compileScoringRule(rule: ScoringRule, index: number = 0): Compil
|
|
|
110
110
|
index,
|
|
111
111
|
inputs,
|
|
112
112
|
when,
|
|
113
|
+
category: rule.category,
|
|
113
114
|
action: compileScoringAction(rule.then)
|
|
114
115
|
};
|
|
115
116
|
}
|
|
@@ -119,13 +120,43 @@ export function compileScoringRule(rule: ScoringRule, index: number = 0): Compil
|
|
|
119
120
|
// ========================================
|
|
120
121
|
|
|
121
122
|
export function compileScoringRuleSet(ruleSet: ScoringRuleSet): CompiledScoringRuleSet {
|
|
123
|
+
const categories = ruleSet.config?.categories;
|
|
124
|
+
|
|
125
|
+
// Validate categories if defined
|
|
126
|
+
if (categories?.length) {
|
|
127
|
+
const categoryIds = new Set(categories.map(c => c.id));
|
|
128
|
+
|
|
129
|
+
// Every rule must reference a valid category
|
|
130
|
+
for (const rule of ruleSet.rules) {
|
|
131
|
+
if (!rule.category) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Rule "${rule.id}" is missing a category. When categories are defined, every rule must have a category.`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
if (!categoryIds.has(rule.category)) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
`Rule "${rule.id}" references unknown category "${rule.category}". Valid categories: ${[...categoryIds].join(', ')}`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Normalize category weights to sum to 1.0
|
|
144
|
+
const totalWeight = categories.reduce((sum, c) => sum + c.weight, 0);
|
|
145
|
+
if (totalWeight > 0 && Math.abs(totalWeight - 1.0) > 0.001) {
|
|
146
|
+
for (const cat of categories) {
|
|
147
|
+
cat.weight = cat.weight / totalWeight;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
122
152
|
const config: ScoringConfig = {
|
|
123
153
|
mode: 'scoring',
|
|
124
154
|
strategies: ruleSet.config?.strategies ?? ['raw'],
|
|
125
155
|
caps: ruleSet.config?.caps,
|
|
126
156
|
outputBounds: ruleSet.config?.outputBounds,
|
|
127
157
|
baseScore: ruleSet.config?.baseScore,
|
|
128
|
-
tiers: ruleSet.config?.tiers
|
|
158
|
+
tiers: ruleSet.config?.tiers,
|
|
159
|
+
categories
|
|
129
160
|
};
|
|
130
161
|
|
|
131
162
|
return {
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
CompiledScoringAction,
|
|
17
17
|
ScoringOptions,
|
|
18
18
|
ScoringResult,
|
|
19
|
-
ScoringTierMatch
|
|
19
|
+
ScoringTierMatch,
|
|
20
|
+
CategoryResult
|
|
20
21
|
} from './types';
|
|
21
22
|
|
|
22
23
|
export class ScoringStrategy {
|
|
@@ -119,8 +120,101 @@ export class ScoringStrategy {
|
|
|
119
120
|
contributions[rule.id] = accumulatedScore;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
// Phase 3: Apply global strategies
|
|
123
|
-
|
|
123
|
+
// Phase 3: Apply global strategies
|
|
124
|
+
let categoryBreakdown: CategoryResult[] | undefined;
|
|
125
|
+
|
|
126
|
+
if (config.categories?.length) {
|
|
127
|
+
// Category-aware aggregation
|
|
128
|
+
const categories = config.categories;
|
|
129
|
+
// Group all rules (fired and unfired) by category
|
|
130
|
+
const rulesByCategory = new Map<string, { fired: string[]; missing: string[] }>();
|
|
131
|
+
for (const cat of categories) {
|
|
132
|
+
rulesByCategory.set(cat.id, { fired: [], missing: [] });
|
|
133
|
+
}
|
|
134
|
+
for (const rule of ruleSet.rules) {
|
|
135
|
+
const catId = rule.category!;
|
|
136
|
+
const group = rulesByCategory.get(catId)!;
|
|
137
|
+
if (fired.includes(rule.id)) {
|
|
138
|
+
group.fired.push(rule.id);
|
|
139
|
+
} else {
|
|
140
|
+
group.missing.push(rule.id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Build category results
|
|
145
|
+
const catResults: CategoryResult[] = [];
|
|
146
|
+
for (const cat of categories) {
|
|
147
|
+
const group = rulesByCategory.get(cat.id)!;
|
|
148
|
+
const totalSignals = group.fired.length + group.missing.length;
|
|
149
|
+
const minRatio = cat.minSignalRatio ?? 0.5;
|
|
150
|
+
const excluded = totalSignals > 0 && (group.fired.length / totalSignals) < minRatio;
|
|
151
|
+
|
|
152
|
+
let rawScore = 0;
|
|
153
|
+
if (!excluded && group.fired.length > 0) {
|
|
154
|
+
// Normalize signal weights within category to sum to 1.0 among fired signals
|
|
155
|
+
const firedWeights: Record<string, number> = {};
|
|
156
|
+
let totalFiredWeight = 0;
|
|
157
|
+
for (const ruleId of group.fired) {
|
|
158
|
+
const w = weights[ruleId] ?? 1;
|
|
159
|
+
firedWeights[ruleId] = w;
|
|
160
|
+
totalFiredWeight += w;
|
|
161
|
+
}
|
|
162
|
+
// Compute weighted average of fired signal scores
|
|
163
|
+
for (const ruleId of group.fired) {
|
|
164
|
+
const normalizedWeight = totalFiredWeight > 0 ? firedWeights[ruleId] / totalFiredWeight : 0;
|
|
165
|
+
rawScore += contributions[ruleId] * normalizedWeight;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
catResults.push({
|
|
170
|
+
id: cat.id,
|
|
171
|
+
name: cat.name,
|
|
172
|
+
weight: cat.weight,
|
|
173
|
+
effectiveWeight: excluded ? 0 : cat.weight,
|
|
174
|
+
rawScore,
|
|
175
|
+
weightedContribution: 0, // computed after redistribution
|
|
176
|
+
signalsWithData: group.fired,
|
|
177
|
+
signalsMissing: group.missing,
|
|
178
|
+
excluded
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Redistribute excluded category weights proportionally to active categories
|
|
183
|
+
const excludedWeight = catResults.filter(c => c.excluded).reduce((sum, c) => sum + c.weight, 0);
|
|
184
|
+
const activeWeight = catResults.filter(c => !c.excluded).reduce((sum, c) => sum + c.weight, 0);
|
|
185
|
+
if (activeWeight > 0 && excludedWeight > 0) {
|
|
186
|
+
for (const cr of catResults) {
|
|
187
|
+
if (!cr.excluded) {
|
|
188
|
+
cr.effectiveWeight = cr.weight + (cr.weight / activeWeight) * excludedWeight;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Compute weighted contributions and update per-rule contributions
|
|
194
|
+
for (const cr of catResults) {
|
|
195
|
+
cr.weightedContribution = cr.effectiveWeight * cr.rawScore;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Rewrite per-rule contributions to reflect category-weighted values
|
|
199
|
+
for (const cr of catResults) {
|
|
200
|
+
if (cr.excluded || cr.signalsWithData.length === 0) continue;
|
|
201
|
+
const firedWeightsTotal = cr.signalsWithData.reduce((sum, id) => sum + (weights[id] ?? 1), 0);
|
|
202
|
+
for (const ruleId of cr.signalsWithData) {
|
|
203
|
+
const normalizedWeight = firedWeightsTotal > 0 ? (weights[ruleId] ?? 1) / firedWeightsTotal : 0;
|
|
204
|
+
contributions[ruleId] = contributions[ruleId] * normalizedWeight * cr.effectiveWeight;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Zero out contributions for excluded categories
|
|
208
|
+
for (const cr of catResults) {
|
|
209
|
+
if (cr.excluded) {
|
|
210
|
+
for (const ruleId of cr.signalsWithData) {
|
|
211
|
+
contributions[ruleId] = 0;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
categoryBreakdown = catResults;
|
|
217
|
+
} else if (strategies.includes('weighted-percent')) {
|
|
124
218
|
const totalWeight = Object.values(weights).reduce((sum, w) => sum + w, 0);
|
|
125
219
|
if (totalWeight > 0) {
|
|
126
220
|
for (const ruleId in contributions) {
|
|
@@ -181,6 +275,7 @@ export class ScoringStrategy {
|
|
|
181
275
|
fired,
|
|
182
276
|
iterations: 1,
|
|
183
277
|
tier,
|
|
278
|
+
categoryBreakdown,
|
|
184
279
|
executionTimeMs
|
|
185
280
|
};
|
|
186
281
|
}
|
|
@@ -93,6 +93,39 @@ export type ScoringTierMatch = {
|
|
|
93
93
|
threshold: number;
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
// ========================================
|
|
97
|
+
// Category Types
|
|
98
|
+
// ========================================
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Category definition for grouping related scoring signals
|
|
102
|
+
*
|
|
103
|
+
* Categories provide a two-level weight hierarchy: category weights
|
|
104
|
+
* control how much each group contributes to the total, and signal
|
|
105
|
+
* weights within each category control relative importance of rules.
|
|
106
|
+
*/
|
|
107
|
+
export type ScoringCategory = {
|
|
108
|
+
id: string;
|
|
109
|
+
name?: string;
|
|
110
|
+
weight: number; // 0-1, normalized internally
|
|
111
|
+
minSignalRatio?: number; // default 0.5 — below this, category is excluded
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Per-category result breakdown showing how each category contributed
|
|
116
|
+
*/
|
|
117
|
+
export type CategoryResult = {
|
|
118
|
+
id: string;
|
|
119
|
+
name?: string;
|
|
120
|
+
weight: number; // original configured weight
|
|
121
|
+
effectiveWeight: number; // after redistribution from excluded categories
|
|
122
|
+
rawScore: number; // weighted avg of signal scores within category
|
|
123
|
+
weightedContribution: number; // effectiveWeight × rawScore
|
|
124
|
+
signalsWithData: string[]; // rule IDs that fired
|
|
125
|
+
signalsMissing: string[]; // rule IDs that didn't fire
|
|
126
|
+
excluded: boolean;
|
|
127
|
+
};
|
|
128
|
+
|
|
96
129
|
// ========================================
|
|
97
130
|
// Source Types (User-Defined)
|
|
98
131
|
// ========================================
|
|
@@ -111,6 +144,7 @@ export type ScoringAction = {
|
|
|
111
144
|
* Scoring rule - uses 'then' for scoring properties
|
|
112
145
|
*/
|
|
113
146
|
export type ScoringRule = BaseRule & {
|
|
147
|
+
category?: string;
|
|
114
148
|
then: ScoringAction;
|
|
115
149
|
};
|
|
116
150
|
|
|
@@ -133,6 +167,7 @@ export type ScoringConfig = {
|
|
|
133
167
|
outputBounds?: OutputBounds; // Optional output scaling
|
|
134
168
|
baseScore?: number; // Starting score before rule contributions (default: 0)
|
|
135
169
|
tiers?: TierDefinition[]; // Optional tier definitions for score classification
|
|
170
|
+
categories?: ScoringCategory[]; // Optional category grouping for two-level weight hierarchy
|
|
136
171
|
};
|
|
137
172
|
|
|
138
173
|
// ========================================
|
|
@@ -154,6 +189,7 @@ export type CompiledScoringAction = {
|
|
|
154
189
|
* Compiled scoring rule
|
|
155
190
|
*/
|
|
156
191
|
export type CompiledScoringRule = CompiledBaseRule & {
|
|
192
|
+
category?: string;
|
|
157
193
|
action: CompiledScoringAction;
|
|
158
194
|
};
|
|
159
195
|
|
|
@@ -197,5 +233,6 @@ export type ScoringResult = {
|
|
|
197
233
|
fired: string[]; // Rules that matched and contributed
|
|
198
234
|
iterations: 1; // Scoring is always one-pass
|
|
199
235
|
tier?: ScoringTierMatch; // Matched tier (if tiers configured)
|
|
236
|
+
categoryBreakdown?: CategoryResult[]; // Per-category breakdown (if categories configured)
|
|
200
237
|
executionTimeMs: number; // Processing time in milliseconds
|
|
201
238
|
};
|