@ryuenn3123/agentic-senior-core 4.3.15 → 4.4.0
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/.agent-context/review-checklists/pr-checklist.md +1 -3
- package/.agent-context/rules/architecture.md +5 -0
- package/AGENTS.md +68 -120
- package/bin/agentic-senior-core.js +2 -5
- package/lib/cli/adaptive-context/catalog.mjs +4 -0
- package/lib/cli/adaptive-context.mjs +87 -301
- package/lib/cli/compiler.mjs +6 -389
- package/lib/cli/token-optimization.mjs +4 -89
- package/package.json +2 -9
- package/scripts/context-triggered-audit.mjs +1 -1
- package/scripts/{audit-cache-layer-contract.mjs → validate/audits/cache-layer-contract.mjs} +4 -37
- package/scripts/{audit-caching-scope-hygiene.mjs → validate/audits/caching-scope-hygiene.mjs} +1 -34
- package/scripts/{audit-file-size.mjs → validate/audits/file-size.mjs} +1 -62
- package/scripts/{audit-reflection-citations.mjs → validate/audits/reflection-citations.mjs} +2 -35
- package/scripts/{audit-release-bundle.mjs → validate/audits/release-bundle.mjs} +1 -36
- package/scripts/{audit-rule-id-uniqueness.mjs → validate/audits/rule-id-uniqueness.mjs} +1 -36
- package/scripts/validate/config.mjs +0 -18
- package/scripts/validate/file-structure.mjs +0 -4
- package/scripts/validate/utils.mjs +52 -0
- package/scripts/validate.mjs +10 -81
- package/lib/cli/audits/typography-palette-anti-repeat-audit.mjs +0 -239
- package/lib/cli/commands/audit-design-anti-repeat.mjs +0 -39
- package/scripts/audit-typography-palette-anti-repeat.mjs +0 -120
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DOCS_BY_LABEL,
|
|
3
|
-
PROMPT_CATALOG,
|
|
4
|
-
RULE_FAMILY_CATALOG,
|
|
5
|
-
STATE_BY_LABEL,
|
|
6
|
-
} from './adaptive-context/catalog.mjs';
|
|
1
|
+
import { DOCS_BY_LABEL, PROMPT_CATALOG, RULE_FAMILY_CATALOG, STATE_BY_LABEL } from './adaptive-context/catalog.mjs';
|
|
7
2
|
import { CONTEXT_FILE_CATALOG } from './adaptive-context/file-signals.mjs';
|
|
8
3
|
import { IMPLICATION_CATALOG } from './adaptive-context/implications.mjs';
|
|
9
4
|
|
|
@@ -17,217 +12,33 @@ export function getRuleFamilyCatalog() {
|
|
|
17
12
|
}
|
|
18
13
|
|
|
19
14
|
export function normalizeRequestText(requestText) {
|
|
20
|
-
return String(requestText || '')
|
|
21
|
-
.trim()
|
|
22
|
-
.toLowerCase()
|
|
23
|
-
.replace(/\s+/g, ' ');
|
|
15
|
+
return String(requestText || '').trim().toLowerCase().replace(/\s+/g, ' ');
|
|
24
16
|
}
|
|
25
17
|
|
|
26
|
-
function
|
|
27
|
-
|
|
18
|
+
function triggerMatchesRequest(text, trigger) {
|
|
19
|
+
if (!text || !trigger) return false;
|
|
20
|
+
return /^[a-z0-9 ]+$/.test(trigger)
|
|
21
|
+
? new RegExp(`(^|[^a-z0-9])${trigger.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}([^a-z0-9]|$)`).test(text)
|
|
22
|
+
: text.includes(trigger);
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
return rawText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function triggerMatchesRequest(normalizedRequestText, triggerText) {
|
|
35
|
-
if (!normalizedRequestText || !triggerText) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (/^[a-z0-9 ]+$/.test(triggerText)) {
|
|
40
|
-
const triggerPattern = new RegExp(`(^|[^a-z0-9])${escapeRegExp(triggerText)}([^a-z0-9]|$)`);
|
|
41
|
-
return triggerPattern.test(normalizedRequestText);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return normalizedRequestText.includes(triggerText);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function compareCatalogEntries(leftEntry, rightEntry) {
|
|
48
|
-
return leftEntry.priority - rightEntry.priority || leftEntry.label.localeCompare(rightEntry.label);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function normalizeContextFilePath(contextFilePath) {
|
|
52
|
-
return String(contextFilePath || '')
|
|
53
|
-
.trim()
|
|
54
|
-
.replace(/\\/g, '/')
|
|
55
|
-
.replace(/\/+/g, '/')
|
|
56
|
-
.toLowerCase();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function normalizeContextFiles(contextFiles) {
|
|
60
|
-
if (!Array.isArray(contextFiles)) {
|
|
61
|
-
return [];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return contextFiles
|
|
65
|
-
.map(normalizeContextFilePath)
|
|
66
|
-
.filter(Boolean);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function uniqueSortedValues(values) {
|
|
70
|
-
return Array.from(new Set(values)).sort((leftValue, rightValue) => leftValue.localeCompare(rightValue));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function collectDocsForLabels(labels) {
|
|
74
|
-
const selectedDocs = ['docs/doc-index.md'];
|
|
75
|
-
|
|
76
|
-
for (const label of labels) {
|
|
77
|
-
selectedDocs.push(...(DOCS_BY_LABEL[label] || []));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return uniqueSortedValues(selectedDocs);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function collectStateForLabels(labels) {
|
|
84
|
-
const selectedState = ['.agent-context/state/onboarding-report.json'];
|
|
85
|
-
|
|
86
|
-
for (const label of labels) {
|
|
87
|
-
selectedState.push(...(STATE_BY_LABEL[label] || []));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return uniqueSortedValues(selectedState);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function collectPromptsForRequest(normalizedRequestText, labels) {
|
|
94
|
-
const selectedPrompts = [];
|
|
95
|
-
|
|
96
|
-
for (const promptEntry of PROMPT_CATALOG) {
|
|
97
|
-
const labelMatched = Array.isArray(promptEntry.labels)
|
|
98
|
-
&& promptEntry.labels.some((label) => labels.includes(label));
|
|
99
|
-
const triggerMatched = findMatchedTriggers(normalizedRequestText, promptEntry.triggers).length > 0;
|
|
100
|
-
|
|
101
|
-
if (labelMatched || triggerMatched) {
|
|
102
|
-
selectedPrompts.push(promptEntry.promptPath);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return uniqueSortedValues(selectedPrompts);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function createRuleEntryMap() {
|
|
110
|
-
const ruleEntryMap = new Map();
|
|
111
|
-
|
|
112
|
-
for (const ruleFamily of RULE_FAMILY_CATALOG) {
|
|
113
|
-
ruleEntryMap.set(ruleFamily.label, {
|
|
114
|
-
...ruleFamily,
|
|
115
|
-
matchedTriggers: [],
|
|
116
|
-
matchedFiles: [],
|
|
117
|
-
matchedImplications: [],
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return ruleEntryMap;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function getMatchedRuleEntries(ruleEntryMap) {
|
|
125
|
-
return Array.from(ruleEntryMap.values())
|
|
126
|
-
.filter((ruleFamily) => {
|
|
127
|
-
return ruleFamily.matchedTriggers.length > 0
|
|
128
|
-
|| ruleFamily.matchedFiles.length > 0
|
|
129
|
-
|| ruleFamily.matchedImplications.length > 0;
|
|
130
|
-
})
|
|
131
|
-
.sort(compareCatalogEntries);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function pushUniqueSignal(values, nextValue) {
|
|
135
|
-
if (nextValue && !values.includes(nextValue)) {
|
|
136
|
-
values.push(nextValue);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
25
|
+
const uniqueSorted = (arr) => Array.from(new Set(arr)).sort((a, b) => a.localeCompare(b));
|
|
139
26
|
|
|
140
|
-
function
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
for (const matchedTrigger of matchedTriggers) {
|
|
146
|
-
pushUniqueSignal(targetRuleEntry.matchedTriggers, matchedTrigger);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function applyContextFileSignals(ruleEntryMap, normalizedContextFiles) {
|
|
152
|
-
for (const contextFilePath of normalizedContextFiles) {
|
|
153
|
-
for (const fileSignal of CONTEXT_FILE_CATALOG) {
|
|
154
|
-
if (!fileSignal.patterns.some((filePattern) => filePattern.test(contextFilePath))) {
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const targetRuleEntry = ruleEntryMap.get(fileSignal.label);
|
|
159
|
-
pushUniqueSignal(targetRuleEntry.matchedFiles, contextFilePath);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
27
|
+
function resolveUncertainty(labels, evidence, text) {
|
|
28
|
+
if (!text || !labels.length) return 'high';
|
|
29
|
+
const hasSparseEvidence = evidence.some(e => (e.matchedTriggers.length + e.matchedFiles.length + e.matchedImplications.length) === 1);
|
|
30
|
+
return (labels.length >= 6 || hasSparseEvidence) ? 'medium' : 'low';
|
|
162
31
|
}
|
|
163
32
|
|
|
164
|
-
function
|
|
165
|
-
const matchedLabelSet = new Set(getMatchedRuleEntries(ruleEntryMap).map((ruleFamily) => ruleFamily.label));
|
|
166
|
-
|
|
167
|
-
for (const implicationRule of IMPLICATION_CATALOG) {
|
|
168
|
-
const hasRequiredLabel = implicationRule.requiresAnyLabel.some((label) => matchedLabelSet.has(label));
|
|
169
|
-
if (!hasRequiredLabel) {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const matchedTriggers = findMatchedTriggers(normalizedRequestText, implicationRule.triggers);
|
|
174
|
-
if (matchedTriggers.length === 0) {
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const targetRuleEntry = ruleEntryMap.get(implicationRule.label);
|
|
179
|
-
const implicationDetail = `${implicationRule.reason}: ${matchedTriggers.join(', ')}`;
|
|
180
|
-
pushUniqueSignal(targetRuleEntry.matchedImplications, implicationDetail);
|
|
181
|
-
matchedLabelSet.add(implicationRule.label);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function countEvidenceSignals(evidenceEntry) {
|
|
186
|
-
return evidenceEntry.matchedTriggers.length
|
|
187
|
-
+ evidenceEntry.matchedFiles.length
|
|
188
|
-
+ evidenceEntry.matchedImplications.length;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function resolveUncertainty(labels, evidenceEntries, normalizedRequestText) {
|
|
192
|
-
if (!normalizedRequestText) {
|
|
193
|
-
return 'high';
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (labels.length === 0) {
|
|
197
|
-
return 'high';
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const hasSparseEvidence = evidenceEntries.some((evidenceEntry) => countEvidenceSignals(evidenceEntry) === 1);
|
|
201
|
-
const hasManyLabels = labels.length >= 6;
|
|
202
|
-
|
|
203
|
-
if (hasManyLabels || hasSparseEvidence) {
|
|
204
|
-
return 'medium';
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return 'low';
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function buildContextBudget(labels, evidenceEntries) {
|
|
33
|
+
function buildContextBudget(labels, evidence) {
|
|
211
34
|
const selectedRuleCount = labels.length;
|
|
212
|
-
const evidenceSignalCount =
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const overRecommendedRuleCount = Math.max(
|
|
217
|
-
0,
|
|
218
|
-
selectedRuleCount - CONTEXT_BUDGET_POLICY.maxRecommendedRuleCount
|
|
219
|
-
);
|
|
220
|
-
const overFallbackRuleCount = Math.max(
|
|
221
|
-
0,
|
|
222
|
-
selectedRuleCount - CONTEXT_BUDGET_POLICY.maxFallbackRuleCount
|
|
223
|
-
);
|
|
35
|
+
const evidenceSignalCount = evidence.reduce((sum, e) => sum + e.matchedTriggers.length + e.matchedFiles.length + e.matchedImplications.length, 0);
|
|
36
|
+
const overRecommendedRuleCount = Math.max(0, selectedRuleCount - CONTEXT_BUDGET_POLICY.maxRecommendedRuleCount);
|
|
37
|
+
const overFallbackRuleCount = Math.max(0, selectedRuleCount - CONTEXT_BUDGET_POLICY.maxFallbackRuleCount);
|
|
38
|
+
|
|
224
39
|
let status = 'within-budget';
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
status = 'fallback-required';
|
|
228
|
-
} else if (overRecommendedRuleCount > 0) {
|
|
229
|
-
status = 'wide-context';
|
|
230
|
-
}
|
|
40
|
+
if (overFallbackRuleCount > 0) status = 'fallback-required';
|
|
41
|
+
else if (overRecommendedRuleCount > 0) status = 'wide-context';
|
|
231
42
|
|
|
232
43
|
return {
|
|
233
44
|
status,
|
|
@@ -240,126 +51,101 @@ function buildContextBudget(labels, evidenceEntries) {
|
|
|
240
51
|
};
|
|
241
52
|
}
|
|
242
53
|
|
|
243
|
-
export function buildSelectedContextManifest(
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
54
|
+
export function buildSelectedContextManifest({ contextFiles = [], requestId = 'adhoc-request', requestText = '' } = {}) {
|
|
55
|
+
const normText = normalizeRequestText(requestText);
|
|
56
|
+
const normFiles = (Array.isArray(contextFiles) ? contextFiles : [])
|
|
57
|
+
.map(f => String(f || '').trim().replace(/\\/g, '/').replace(/\/+/g, '/').toLowerCase())
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
|
|
60
|
+
const matchedEntries = RULE_FAMILY_CATALOG.map(rule => {
|
|
61
|
+
const matchedTriggers = rule.triggers.filter(t => triggerMatchesRequest(normText, t));
|
|
62
|
+
const filePatterns = CONTEXT_FILE_CATALOG.find(c => c.label === rule.label)?.patterns || [];
|
|
63
|
+
const matchedFiles = normFiles.filter(f => filePatterns.some(p => p.test(f)));
|
|
64
|
+
return { ...rule, matchedTriggers, matchedFiles, matchedImplications: [] };
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const matchedLabelSet = new Set(matchedEntries.filter(e => e.matchedTriggers.length || e.matchedFiles.length).map(e => e.label));
|
|
68
|
+
|
|
69
|
+
for (const imp of IMPLICATION_CATALOG) {
|
|
70
|
+
if (imp.requiresAnyLabel.some(l => matchedLabelSet.has(l))) {
|
|
71
|
+
const triggers = imp.triggers.filter(t => triggerMatchesRequest(normText, t));
|
|
72
|
+
if (triggers.length) {
|
|
73
|
+
const target = matchedEntries.find(e => e.label === imp.label);
|
|
74
|
+
if (target) {
|
|
75
|
+
const detail = `${imp.reason}: ${triggers.join(', ')}`;
|
|
76
|
+
if (!target.matchedImplications.includes(detail)) target.matchedImplications.push(detail);
|
|
77
|
+
matchedLabelSet.add(imp.label);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
249
82
|
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
83
|
+
const matchedRuleEntries = matchedEntries
|
|
84
|
+
.filter(e => e.matchedTriggers.length || e.matchedFiles.length || e.matchedImplications.length)
|
|
85
|
+
.sort((a, b) => a.priority - b.priority || a.label.localeCompare(b.label));
|
|
253
86
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
87
|
+
const labels = matchedRuleEntries.map(e => e.label);
|
|
88
|
+
const evidence = matchedRuleEntries.map(({ label, matchedTriggers, matchedFiles, matchedImplications }) => ({ label, matchedTriggers, matchedFiles, matchedImplications }));
|
|
89
|
+
const uncertainty = resolveUncertainty(labels, evidence, normText);
|
|
90
|
+
const budget = buildContextBudget(labels, evidence);
|
|
257
91
|
|
|
258
|
-
const
|
|
92
|
+
const selectedRuleSet = new Set(matchedRuleEntries.map(e => e.rulePath));
|
|
259
93
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const skippedRules = RULE_FAMILY_CATALOG
|
|
264
|
-
.map((ruleFamily) => ruleFamily.rulePath)
|
|
265
|
-
.filter((rulePath) => !selectedRuleSet.has(rulePath))
|
|
266
|
-
.sort((leftPath, rightPath) => leftPath.localeCompare(rightPath));
|
|
267
|
-
const evidenceEntries = matchedRuleEntries.map((ruleFamily) => ({
|
|
268
|
-
label: ruleFamily.label,
|
|
269
|
-
matchedTriggers: ruleFamily.matchedTriggers,
|
|
270
|
-
matchedFiles: ruleFamily.matchedFiles,
|
|
271
|
-
matchedImplications: ruleFamily.matchedImplications,
|
|
272
|
-
}));
|
|
273
|
-
const uncertainty = resolveUncertainty(labels, evidenceEntries, normalizedRequestText);
|
|
274
|
-
const budget = buildContextBudget(labels, evidenceEntries);
|
|
94
|
+
const selectedPrompts = PROMPT_CATALOG
|
|
95
|
+
.filter(p => (Array.isArray(p.labels) && p.labels.some(l => labels.includes(l))) || p.triggers.some(t => triggerMatchesRequest(normText, t)))
|
|
96
|
+
.map(p => p.promptPath);
|
|
275
97
|
|
|
276
98
|
return {
|
|
277
99
|
schemaVersion: 'adaptive-context-manifest-v1',
|
|
278
100
|
requestId,
|
|
279
|
-
contextFiles:
|
|
101
|
+
contextFiles: normFiles,
|
|
280
102
|
labels,
|
|
281
|
-
selectedRules,
|
|
282
|
-
selectedPrompts:
|
|
283
|
-
selectedDocs:
|
|
284
|
-
selectedState:
|
|
285
|
-
skippedRules,
|
|
103
|
+
selectedRules: matchedRuleEntries.map(e => e.rulePath),
|
|
104
|
+
selectedPrompts: uniqueSorted(selectedPrompts),
|
|
105
|
+
selectedDocs: uniqueSorted(['docs/doc-index.md', ...labels.flatMap(l => DOCS_BY_LABEL[l] || [])]),
|
|
106
|
+
selectedState: uniqueSorted(['.agent-context/state/onboarding-report.json', ...labels.flatMap(l => STATE_BY_LABEL[l] || [])]),
|
|
107
|
+
skippedRules: RULE_FAMILY_CATALOG.map(r => r.rulePath).filter(r => !selectedRuleSet.has(r)).sort((a, b) => a.localeCompare(b)),
|
|
286
108
|
uncertainty,
|
|
287
109
|
budget,
|
|
288
110
|
fallbackRequired: uncertainty === 'high' || budget.status === 'fallback-required',
|
|
289
|
-
evidence
|
|
111
|
+
evidence,
|
|
290
112
|
};
|
|
291
113
|
}
|
|
292
114
|
|
|
293
|
-
function compareRequiredLabels(requiredLabels, actualLabels) {
|
|
294
|
-
const actualLabelSet = new Set(actualLabels);
|
|
295
|
-
|
|
296
|
-
return requiredLabels.filter((requiredLabel) => !actualLabelSet.has(requiredLabel));
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
function compareExtraLabels(expectedLabels, actualLabels) {
|
|
300
|
-
const expectedLabelSet = new Set(expectedLabels);
|
|
301
|
-
|
|
302
|
-
return actualLabels.filter((actualLabel) => !expectedLabelSet.has(actualLabel));
|
|
303
|
-
}
|
|
304
|
-
|
|
305
115
|
export function evaluateAdaptiveContextFixtures(fixtures) {
|
|
306
|
-
const
|
|
307
|
-
const manifest = buildSelectedContextManifest({
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
});
|
|
311
|
-
const missedRequiredLabels = compareRequiredLabels(fixtureEntry.requiredLabels, manifest.labels);
|
|
312
|
-
const extraLabels = compareExtraLabels(fixtureEntry.allowedLabels || fixtureEntry.requiredLabels, manifest.labels);
|
|
313
|
-
|
|
116
|
+
const results = fixtures.map(fixture => {
|
|
117
|
+
const manifest = buildSelectedContextManifest({ requestId: fixture.id, requestText: fixture.requestText });
|
|
118
|
+
const reqSet = new Set(fixture.requiredLabels);
|
|
119
|
+
const allowSet = new Set(fixture.allowedLabels || fixture.requiredLabels);
|
|
314
120
|
return {
|
|
315
|
-
id:
|
|
316
|
-
passed:
|
|
317
|
-
missedRequiredLabels,
|
|
318
|
-
extraLabels,
|
|
121
|
+
id: fixture.id,
|
|
122
|
+
passed: fixture.requiredLabels.every(l => manifest.labels.includes(l)),
|
|
123
|
+
missedRequiredLabels: fixture.requiredLabels.filter(l => !manifest.labels.includes(l)),
|
|
124
|
+
extraLabels: manifest.labels.filter(l => !allowSet.has(l)),
|
|
319
125
|
manifest,
|
|
320
126
|
};
|
|
321
127
|
});
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
0
|
|
326
|
-
);
|
|
327
|
-
const extraLabelCount = fixtureResults.reduce(
|
|
328
|
-
(totalCount, fixtureResult) => totalCount + fixtureResult.extraLabels.length,
|
|
329
|
-
0
|
|
330
|
-
);
|
|
331
|
-
const selectedRuleCounts = fixtureResults.map((fixtureResult) => fixtureResult.manifest.budget.selectedRuleCount);
|
|
332
|
-
const maxSelectedRuleCount = Math.max(...selectedRuleCounts, 0);
|
|
333
|
-
const totalSelectedRuleCount = selectedRuleCounts.reduce(
|
|
334
|
-
(totalCount, selectedRuleCount) => totalCount + selectedRuleCount,
|
|
335
|
-
0
|
|
336
|
-
);
|
|
337
|
-
const overRecommendedFixtureCount = fixtureResults.filter((fixtureResult) => {
|
|
338
|
-
return fixtureResult.manifest.budget.status !== 'within-budget';
|
|
339
|
-
}).length;
|
|
340
|
-
const fallbackFixtureCount = fixtureResults.filter((fixtureResult) => {
|
|
341
|
-
return fixtureResult.manifest.fallbackRequired;
|
|
342
|
-
}).length;
|
|
128
|
+
|
|
129
|
+
const failed = results.filter(r => !r.passed);
|
|
130
|
+
const selectedRuleCounts = results.map(r => r.manifest.budget.selectedRuleCount);
|
|
343
131
|
|
|
344
132
|
return {
|
|
345
133
|
reportName: 'adaptive-context-benchmark',
|
|
346
134
|
generatedAt: new Date().toISOString(),
|
|
347
|
-
fixtureCount:
|
|
348
|
-
passed:
|
|
349
|
-
passedCount:
|
|
350
|
-
failedCount:
|
|
351
|
-
missedRequiredLabelCount,
|
|
352
|
-
extraLabelCount,
|
|
135
|
+
fixtureCount: results.length,
|
|
136
|
+
passed: failed.length === 0,
|
|
137
|
+
passedCount: results.length - failed.length,
|
|
138
|
+
failedCount: failed.length,
|
|
139
|
+
missedRequiredLabelCount: results.reduce((sum, r) => sum + r.missedRequiredLabels.length, 0),
|
|
140
|
+
extraLabelCount: results.reduce((sum, r) => sum + r.extraLabels.length, 0),
|
|
353
141
|
budgetSummary: {
|
|
354
|
-
maxSelectedRuleCount,
|
|
355
|
-
averageSelectedRuleCount:
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
overRecommendedFixtureCount,
|
|
359
|
-
fallbackFixtureCount,
|
|
142
|
+
maxSelectedRuleCount: Math.max(0, ...selectedRuleCounts),
|
|
143
|
+
averageSelectedRuleCount: results.length ? Number((selectedRuleCounts.reduce((a, b) => a + b, 0) / results.length).toFixed(2)) : 0,
|
|
144
|
+
overRecommendedFixtureCount: results.filter(r => r.manifest.budget.status !== 'within-budget').length,
|
|
145
|
+
fallbackFixtureCount: results.filter(r => r.manifest.fallbackRequired).length,
|
|
360
146
|
maxRecommendedRuleCount: CONTEXT_BUDGET_POLICY.maxRecommendedRuleCount,
|
|
361
147
|
maxFallbackRuleCount: CONTEXT_BUDGET_POLICY.maxFallbackRuleCount,
|
|
362
148
|
},
|
|
363
|
-
results
|
|
149
|
+
results,
|
|
364
150
|
};
|
|
365
151
|
}
|