@bryan-thompson/inspector-assessment-client 1.34.2 → 1.35.2
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/assets/{OAuthCallback-CBcYNwyM.js → OAuthCallback-jfmizOMH.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-B0zFGlM8.js → OAuthDebugCallback-bU5kKvnt.js} +1 -1
- package/dist/assets/{index-Djm_oTDV.js → index-Ce63ds7G.js} +5 -4
- package/dist/index.html +1 -1
- package/lib/lib/assessment/extendedTypes.d.ts +19 -5
- package/lib/lib/assessment/extendedTypes.d.ts.map +1 -1
- package/lib/lib/assessment/resultTypes.d.ts +42 -0
- package/lib/lib/assessment/resultTypes.d.ts.map +1 -1
- package/lib/lib/assessment/sharedSchemas.d.ts +13 -0
- package/lib/lib/assessment/sharedSchemas.d.ts.map +1 -1
- package/lib/lib/assessment/sharedSchemas.js +9 -0
- package/lib/lib/assessment/summarizer/AssessmentSummarizer.d.ts +112 -0
- package/lib/lib/assessment/summarizer/AssessmentSummarizer.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/AssessmentSummarizer.js +452 -0
- package/lib/lib/assessment/summarizer/index.d.ts +19 -0
- package/lib/lib/assessment/summarizer/index.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/index.js +19 -0
- package/lib/lib/assessment/summarizer/stageBEnrichmentBuilder.d.ts +36 -0
- package/lib/lib/assessment/summarizer/stageBEnrichmentBuilder.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/stageBEnrichmentBuilder.js +282 -0
- package/lib/lib/assessment/summarizer/stageBTypes.d.ts +154 -0
- package/lib/lib/assessment/summarizer/stageBTypes.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/stageBTypes.js +24 -0
- package/lib/lib/assessment/summarizer/tokenEstimator.d.ts +103 -0
- package/lib/lib/assessment/summarizer/tokenEstimator.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/tokenEstimator.js +225 -0
- package/lib/lib/assessment/summarizer/types.d.ts +187 -0
- package/lib/lib/assessment/summarizer/types.d.ts.map +1 -0
- package/lib/lib/assessment/summarizer/types.js +20 -0
- package/lib/lib/moduleScoring.d.ts +2 -1
- package/lib/lib/moduleScoring.d.ts.map +1 -1
- package/lib/lib/moduleScoring.js +2 -1
- package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts +8 -0
- package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ManifestValidationAssessor.js +51 -8
- package/lib/services/assessment/modules/securityTests/TestValidityAnalyzer.d.ts +28 -0
- package/lib/services/assessment/modules/securityTests/TestValidityAnalyzer.d.ts.map +1 -1
- package/lib/services/assessment/modules/securityTests/TestValidityAnalyzer.js +180 -0
- package/package.json +1 -1
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assessment Summarizer
|
|
3
|
+
*
|
|
4
|
+
* Generates tiered output for large assessment results to fit within
|
|
5
|
+
* LLM context windows. Creates executive summaries and per-tool digests.
|
|
6
|
+
*
|
|
7
|
+
* Issue #136: Tiered output strategy for large assessments
|
|
8
|
+
*
|
|
9
|
+
* @module assessment/summarizer/AssessmentSummarizer
|
|
10
|
+
*/
|
|
11
|
+
import { calculateModuleScore } from "../../moduleScoring.js";
|
|
12
|
+
import { estimateTokens } from "./tokenEstimator.js";
|
|
13
|
+
import { DEFAULT_SUMMARIZER_CONFIG, } from "./types.js";
|
|
14
|
+
import { buildToolSummaryStageBEnrichment, buildToolDetailStageBEnrichment, } from "./stageBEnrichmentBuilder.js";
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Assessment Summarizer Class
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Generates tiered summaries from assessment results.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const summarizer = new AssessmentSummarizer();
|
|
24
|
+
* const executive = summarizer.generateExecutiveSummary(results);
|
|
25
|
+
* const toolSummaries = summarizer.generateToolSummaries(results);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class AssessmentSummarizer {
|
|
29
|
+
config;
|
|
30
|
+
constructor(config = {}) {
|
|
31
|
+
this.config = { ...DEFAULT_SUMMARIZER_CONFIG, ...config };
|
|
32
|
+
}
|
|
33
|
+
// ==========================================================================
|
|
34
|
+
// Tier 1: Executive Summary
|
|
35
|
+
// ==========================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Generate executive summary (Tier 1) from assessment results.
|
|
38
|
+
* Targets ~5K tokens for guaranteed LLM context fit.
|
|
39
|
+
*
|
|
40
|
+
* @param results - Full assessment results
|
|
41
|
+
* @returns Executive summary
|
|
42
|
+
*/
|
|
43
|
+
generateExecutiveSummary(results) {
|
|
44
|
+
const modulesSummary = this.extractModulesSummary(results);
|
|
45
|
+
const criticalFindings = this.extractCriticalFindings(results);
|
|
46
|
+
const toolRiskDistribution = this.calculateToolRiskDistribution(results);
|
|
47
|
+
const recommendations = this.aggregateRecommendations(results);
|
|
48
|
+
const summary = {
|
|
49
|
+
serverName: results.serverName,
|
|
50
|
+
overallStatus: results.overallStatus,
|
|
51
|
+
overallScore: this.calculateOverallScore(results),
|
|
52
|
+
toolCount: results.functionality?.totalTools ?? 0,
|
|
53
|
+
testCount: results.totalTestsRun ?? 0,
|
|
54
|
+
executionTime: results.executionTime ?? 0,
|
|
55
|
+
modulesSummary,
|
|
56
|
+
criticalFindings,
|
|
57
|
+
toolRiskDistribution,
|
|
58
|
+
recommendations: recommendations.slice(0, this.config.maxRecommendations),
|
|
59
|
+
estimatedTokens: 0, // Will be calculated after construction
|
|
60
|
+
generatedAt: new Date().toISOString(),
|
|
61
|
+
};
|
|
62
|
+
// Calculate actual token estimate
|
|
63
|
+
summary.estimatedTokens = estimateTokens(summary);
|
|
64
|
+
return summary;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract per-module status and scores.
|
|
68
|
+
*/
|
|
69
|
+
extractModulesSummary(results) {
|
|
70
|
+
const summary = {};
|
|
71
|
+
const moduleKeys = [
|
|
72
|
+
"functionality",
|
|
73
|
+
"security",
|
|
74
|
+
"errorHandling",
|
|
75
|
+
"aupCompliance",
|
|
76
|
+
"toolAnnotations",
|
|
77
|
+
"temporal",
|
|
78
|
+
"resources",
|
|
79
|
+
"prompts",
|
|
80
|
+
"crossCapability",
|
|
81
|
+
"protocolCompliance",
|
|
82
|
+
"developerExperience",
|
|
83
|
+
"prohibitedLibraries",
|
|
84
|
+
"manifestValidation",
|
|
85
|
+
"authentication",
|
|
86
|
+
"portability",
|
|
87
|
+
"externalAPIScanner",
|
|
88
|
+
// Legacy keys for backwards compatibility
|
|
89
|
+
"mcpSpecCompliance",
|
|
90
|
+
"documentation",
|
|
91
|
+
"usability",
|
|
92
|
+
];
|
|
93
|
+
for (const key of moduleKeys) {
|
|
94
|
+
const module = results[key];
|
|
95
|
+
if (module && module.status) {
|
|
96
|
+
const score = calculateModuleScore(module) ?? 50;
|
|
97
|
+
summary[key] = {
|
|
98
|
+
status: module.status,
|
|
99
|
+
score,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return summary;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract critical findings counts from all modules.
|
|
107
|
+
*/
|
|
108
|
+
extractCriticalFindings(results) {
|
|
109
|
+
return {
|
|
110
|
+
securityVulnerabilities: results.security?.vulnerabilities?.length ?? 0,
|
|
111
|
+
aupViolations: results.aupCompliance?.violations?.length ?? 0,
|
|
112
|
+
brokenTools: results.functionality?.brokenTools?.length ?? 0,
|
|
113
|
+
missingAnnotations: results.toolAnnotations?.missingAnnotationsCount ?? 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Calculate tool risk distribution from security test results.
|
|
118
|
+
*/
|
|
119
|
+
calculateToolRiskDistribution(results) {
|
|
120
|
+
const distribution = { high: 0, medium: 0, low: 0, safe: 0 };
|
|
121
|
+
const tests = results.security?.promptInjectionTests ?? [];
|
|
122
|
+
const toolVulnCounts = new Map();
|
|
123
|
+
// Count vulnerabilities per tool
|
|
124
|
+
for (const test of tests) {
|
|
125
|
+
if (test.vulnerable && test.toolName) {
|
|
126
|
+
const current = toolVulnCounts.get(test.toolName) ?? 0;
|
|
127
|
+
toolVulnCounts.set(test.toolName, current + 1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Get all tool names
|
|
131
|
+
const allTools = new Set();
|
|
132
|
+
for (const test of tests) {
|
|
133
|
+
if (test.toolName) {
|
|
134
|
+
allTools.add(test.toolName);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Categorize each tool
|
|
138
|
+
for (const toolName of allTools) {
|
|
139
|
+
const vulnCount = toolVulnCounts.get(toolName) ?? 0;
|
|
140
|
+
const riskLevel = this.calculateToolRiskLevel(vulnCount);
|
|
141
|
+
switch (riskLevel) {
|
|
142
|
+
case "HIGH":
|
|
143
|
+
distribution.high++;
|
|
144
|
+
break;
|
|
145
|
+
case "MEDIUM":
|
|
146
|
+
distribution.medium++;
|
|
147
|
+
break;
|
|
148
|
+
case "LOW":
|
|
149
|
+
distribution.low++;
|
|
150
|
+
break;
|
|
151
|
+
case "SAFE":
|
|
152
|
+
distribution.safe++;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return distribution;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Calculate risk level based on vulnerability count.
|
|
160
|
+
*/
|
|
161
|
+
calculateToolRiskLevel(vulnCount) {
|
|
162
|
+
if (vulnCount >= 5)
|
|
163
|
+
return "HIGH";
|
|
164
|
+
if (vulnCount >= 2)
|
|
165
|
+
return "MEDIUM";
|
|
166
|
+
if (vulnCount >= 1)
|
|
167
|
+
return "LOW";
|
|
168
|
+
return "SAFE";
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Aggregate recommendations from all modules.
|
|
172
|
+
*/
|
|
173
|
+
aggregateRecommendations(results) {
|
|
174
|
+
const recommendations = [];
|
|
175
|
+
// Top-level recommendations
|
|
176
|
+
if (results.recommendations) {
|
|
177
|
+
recommendations.push(...results.recommendations);
|
|
178
|
+
}
|
|
179
|
+
// Module-specific recommendations
|
|
180
|
+
const modulesWithRecs = [
|
|
181
|
+
results.errorHandling,
|
|
182
|
+
results.aupCompliance,
|
|
183
|
+
results.toolAnnotations,
|
|
184
|
+
results.developerExperience,
|
|
185
|
+
results.documentation,
|
|
186
|
+
results.usability,
|
|
187
|
+
results.prohibitedLibraries,
|
|
188
|
+
results.portability,
|
|
189
|
+
];
|
|
190
|
+
for (const module of modulesWithRecs) {
|
|
191
|
+
if (module?.recommendations) {
|
|
192
|
+
recommendations.push(...module.recommendations);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Deduplicate
|
|
196
|
+
return [...new Set(recommendations)];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Calculate overall score from module scores.
|
|
200
|
+
*/
|
|
201
|
+
calculateOverallScore(results) {
|
|
202
|
+
const scores = [];
|
|
203
|
+
const coreModules = [
|
|
204
|
+
results.functionality,
|
|
205
|
+
results.security,
|
|
206
|
+
results.errorHandling,
|
|
207
|
+
];
|
|
208
|
+
for (const module of coreModules) {
|
|
209
|
+
const score = calculateModuleScore(module);
|
|
210
|
+
if (score !== null) {
|
|
211
|
+
scores.push(score);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (scores.length === 0) {
|
|
215
|
+
return results.overallStatus === "PASS" ? 100 : 0;
|
|
216
|
+
}
|
|
217
|
+
return Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
|
|
218
|
+
}
|
|
219
|
+
// ==========================================================================
|
|
220
|
+
// Tier 2: Tool Summaries
|
|
221
|
+
// ==========================================================================
|
|
222
|
+
/**
|
|
223
|
+
* Generate tool summaries (Tier 2) from assessment results.
|
|
224
|
+
* Targets ~500 tokens per tool for efficient LLM processing.
|
|
225
|
+
*
|
|
226
|
+
* @param results - Full assessment results
|
|
227
|
+
* @returns Collection of tool summaries
|
|
228
|
+
*/
|
|
229
|
+
generateToolSummaries(results) {
|
|
230
|
+
const tools = [];
|
|
231
|
+
// Get all unique tool names from security tests
|
|
232
|
+
const toolNames = this.extractToolNames(results);
|
|
233
|
+
for (const toolName of toolNames) {
|
|
234
|
+
const summary = this.generateSingleToolSummary(toolName, results);
|
|
235
|
+
tools.push(summary);
|
|
236
|
+
}
|
|
237
|
+
// Sort by risk level (highest first)
|
|
238
|
+
tools.sort((a, b) => {
|
|
239
|
+
const riskOrder = {
|
|
240
|
+
HIGH: 0,
|
|
241
|
+
MEDIUM: 1,
|
|
242
|
+
LOW: 2,
|
|
243
|
+
SAFE: 3,
|
|
244
|
+
};
|
|
245
|
+
return riskOrder[a.riskLevel] - riskOrder[b.riskLevel];
|
|
246
|
+
});
|
|
247
|
+
const aggregate = this.calculateAggregate(tools);
|
|
248
|
+
const collection = {
|
|
249
|
+
tools,
|
|
250
|
+
totalTools: tools.length,
|
|
251
|
+
aggregate,
|
|
252
|
+
estimatedTokens: 0,
|
|
253
|
+
generatedAt: new Date().toISOString(),
|
|
254
|
+
};
|
|
255
|
+
collection.estimatedTokens = estimateTokens(collection);
|
|
256
|
+
return collection;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Extract all unique tool names from assessment results.
|
|
260
|
+
*/
|
|
261
|
+
extractToolNames(results) {
|
|
262
|
+
const toolNames = new Set();
|
|
263
|
+
// From security tests
|
|
264
|
+
const tests = results.security?.promptInjectionTests ?? [];
|
|
265
|
+
for (const test of tests) {
|
|
266
|
+
if (test.toolName) {
|
|
267
|
+
toolNames.add(test.toolName);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// From functionality results
|
|
271
|
+
const funcResults = results.functionality?.toolResults ?? [];
|
|
272
|
+
for (const result of funcResults) {
|
|
273
|
+
if (result.toolName) {
|
|
274
|
+
toolNames.add(result.toolName);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// From annotation results
|
|
278
|
+
const annotationResults = results.toolAnnotations?.toolResults ?? [];
|
|
279
|
+
for (const result of annotationResults) {
|
|
280
|
+
if (result.toolName) {
|
|
281
|
+
toolNames.add(result.toolName);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return [...toolNames].sort();
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Generate summary for a single tool.
|
|
288
|
+
*/
|
|
289
|
+
generateSingleToolSummary(toolName, results) {
|
|
290
|
+
const tests = this.getToolTests(toolName, results);
|
|
291
|
+
const vulnCount = tests.filter((t) => t.vulnerable).length;
|
|
292
|
+
const patterns = this.extractTopPatterns(tests);
|
|
293
|
+
const passRate = this.calculatePassRate(tests);
|
|
294
|
+
const annotationInfo = this.getToolAnnotationInfo(toolName, results);
|
|
295
|
+
const summary = {
|
|
296
|
+
toolName,
|
|
297
|
+
riskLevel: this.calculateToolRiskLevel(vulnCount),
|
|
298
|
+
vulnerabilityCount: vulnCount,
|
|
299
|
+
topPatterns: patterns.slice(0, this.config.maxPatternsPerTool),
|
|
300
|
+
testCount: tests.length,
|
|
301
|
+
passRate,
|
|
302
|
+
recommendations: this.generateToolRecommendations(toolName, vulnCount, annotationInfo),
|
|
303
|
+
estimatedTokens: 0,
|
|
304
|
+
hasAnnotations: annotationInfo.hasAnnotations,
|
|
305
|
+
annotationStatus: annotationInfo.status,
|
|
306
|
+
};
|
|
307
|
+
// Issue #137: Add Stage B enrichment if enabled
|
|
308
|
+
if (this.config.stageBVerbose) {
|
|
309
|
+
const allTests = results.security?.promptInjectionTests ?? [];
|
|
310
|
+
summary.stageBEnrichment = buildToolSummaryStageBEnrichment(toolName, allTests, 3);
|
|
311
|
+
}
|
|
312
|
+
summary.estimatedTokens = estimateTokens(summary);
|
|
313
|
+
return summary;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get all security tests for a specific tool.
|
|
317
|
+
*/
|
|
318
|
+
getToolTests(toolName, results) {
|
|
319
|
+
const tests = results.security?.promptInjectionTests ?? [];
|
|
320
|
+
return tests.filter((t) => t.toolName === toolName);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Extract top vulnerability patterns from tests.
|
|
324
|
+
*/
|
|
325
|
+
extractTopPatterns(tests) {
|
|
326
|
+
const patternCounts = new Map();
|
|
327
|
+
for (const test of tests) {
|
|
328
|
+
if (test.vulnerable && test.testName) {
|
|
329
|
+
const current = patternCounts.get(test.testName) ?? 0;
|
|
330
|
+
patternCounts.set(test.testName, current + 1);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// Sort by count and return names
|
|
334
|
+
return [...patternCounts.entries()]
|
|
335
|
+
.sort((a, b) => b[1] - a[1])
|
|
336
|
+
.map(([name]) => name);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Calculate pass rate for tests.
|
|
340
|
+
*/
|
|
341
|
+
calculatePassRate(tests) {
|
|
342
|
+
if (tests.length === 0)
|
|
343
|
+
return 100;
|
|
344
|
+
const passed = tests.filter((t) => !t.vulnerable).length;
|
|
345
|
+
return Math.round((passed / tests.length) * 100);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get annotation info for a tool.
|
|
349
|
+
*/
|
|
350
|
+
getToolAnnotationInfo(toolName, results) {
|
|
351
|
+
const annotationResults = results.toolAnnotations?.toolResults ?? [];
|
|
352
|
+
const toolResult = annotationResults.find((r) => r.toolName === toolName);
|
|
353
|
+
if (!toolResult) {
|
|
354
|
+
return { hasAnnotations: false, status: "MISSING" };
|
|
355
|
+
}
|
|
356
|
+
const hasAnnotations = toolResult.annotations?.readOnlyHint !== undefined ||
|
|
357
|
+
toolResult.annotations?.destructiveHint !== undefined;
|
|
358
|
+
let status;
|
|
359
|
+
if (!hasAnnotations) {
|
|
360
|
+
status = "MISSING";
|
|
361
|
+
}
|
|
362
|
+
else if (toolResult.alignmentStatus === "ALIGNED") {
|
|
363
|
+
status = "ALIGNED";
|
|
364
|
+
}
|
|
365
|
+
else if (toolResult.alignmentStatus === "MISALIGNED") {
|
|
366
|
+
status = "MISALIGNED";
|
|
367
|
+
}
|
|
368
|
+
return { hasAnnotations, status };
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Generate recommendations for a specific tool.
|
|
372
|
+
*/
|
|
373
|
+
generateToolRecommendations(toolName, vulnCount, annotationInfo) {
|
|
374
|
+
const recommendations = [];
|
|
375
|
+
if (vulnCount >= 5) {
|
|
376
|
+
recommendations.push(`Critical: ${toolName} has ${vulnCount} vulnerabilities - requires immediate security review`);
|
|
377
|
+
}
|
|
378
|
+
else if (vulnCount >= 2) {
|
|
379
|
+
recommendations.push(`${toolName} has ${vulnCount} vulnerabilities - review input validation`);
|
|
380
|
+
}
|
|
381
|
+
else if (vulnCount >= 1) {
|
|
382
|
+
recommendations.push(`${toolName} has a vulnerability - investigate and patch`);
|
|
383
|
+
}
|
|
384
|
+
if (!annotationInfo.hasAnnotations) {
|
|
385
|
+
recommendations.push(`Add readOnlyHint/destructiveHint annotations to ${toolName}`);
|
|
386
|
+
}
|
|
387
|
+
else if (annotationInfo.status === "MISALIGNED") {
|
|
388
|
+
recommendations.push(`Review annotation alignment for ${toolName}`);
|
|
389
|
+
}
|
|
390
|
+
return recommendations;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Calculate aggregate statistics across all tool summaries.
|
|
394
|
+
*/
|
|
395
|
+
calculateAggregate(tools) {
|
|
396
|
+
const totalVulns = tools.reduce((sum, t) => sum + t.vulnerabilityCount, 0);
|
|
397
|
+
const avgPassRate = tools.length > 0
|
|
398
|
+
? Math.round(tools.reduce((sum, t) => sum + t.passRate, 0) / tools.length)
|
|
399
|
+
: 100;
|
|
400
|
+
const misaligned = tools.filter((t) => t.annotationStatus === "MISALIGNED").length;
|
|
401
|
+
return {
|
|
402
|
+
totalVulnerabilities: totalVulns,
|
|
403
|
+
averagePassRate: avgPassRate,
|
|
404
|
+
misalignedAnnotations: misaligned,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
// ==========================================================================
|
|
408
|
+
// Tier 3: Per-Tool Details (extraction helpers)
|
|
409
|
+
// ==========================================================================
|
|
410
|
+
/**
|
|
411
|
+
* Extract full detail data for a specific tool.
|
|
412
|
+
* Used when generating Tier 3 per-tool detail files.
|
|
413
|
+
*
|
|
414
|
+
* @param toolName - Tool name to extract
|
|
415
|
+
* @param results - Full assessment results
|
|
416
|
+
* @returns Tool-specific detail data
|
|
417
|
+
*/
|
|
418
|
+
extractToolDetail(toolName, results) {
|
|
419
|
+
const securityTests = this.getToolTests(toolName, results);
|
|
420
|
+
const functionalityResult = results.functionality?.toolResults?.find((r) => r.toolName === toolName);
|
|
421
|
+
const annotationResult = results.toolAnnotations?.toolResults?.find((r) => r.toolName === toolName);
|
|
422
|
+
const detail = {
|
|
423
|
+
toolName,
|
|
424
|
+
extractedAt: new Date().toISOString(),
|
|
425
|
+
security: {
|
|
426
|
+
tests: securityTests,
|
|
427
|
+
vulnerableCount: securityTests.filter((t) => t.vulnerable).length,
|
|
428
|
+
totalTests: securityTests.length,
|
|
429
|
+
},
|
|
430
|
+
functionality: functionalityResult ?? null,
|
|
431
|
+
annotations: annotationResult ?? null,
|
|
432
|
+
estimatedTokens: estimateTokens({
|
|
433
|
+
security: { tests: securityTests },
|
|
434
|
+
functionality: functionalityResult,
|
|
435
|
+
annotations: annotationResult,
|
|
436
|
+
}),
|
|
437
|
+
};
|
|
438
|
+
// Issue #137: Add Stage B enrichment for Tier 3 if enabled
|
|
439
|
+
if (this.config.stageBVerbose) {
|
|
440
|
+
const allTests = results.security?.promptInjectionTests ?? [];
|
|
441
|
+
const aupViolations = results.aupCompliance?.violations;
|
|
442
|
+
detail.stageBEnrichment = buildToolDetailStageBEnrichment(toolName, allTests, annotationResult, aupViolations, 50);
|
|
443
|
+
}
|
|
444
|
+
return detail;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Get all tool names for Tier 3 file generation.
|
|
448
|
+
*/
|
|
449
|
+
getAllToolNames(results) {
|
|
450
|
+
return this.extractToolNames(results);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assessment Summarizer Module
|
|
3
|
+
*
|
|
4
|
+
* Generates tiered output for large assessment results to fit within
|
|
5
|
+
* LLM context windows.
|
|
6
|
+
*
|
|
7
|
+
* Issue #136: Tiered output strategy for large assessments
|
|
8
|
+
* Issue #137: Stage B enrichment for Claude semantic analysis
|
|
9
|
+
*
|
|
10
|
+
* @module assessment/summarizer
|
|
11
|
+
*/
|
|
12
|
+
export type { OutputFormat, ToolRiskLevel, ExecutiveSummary, ToolSummary, ToolSummariesCollection, ToolDetailReference, TieredOutput, SummarizerConfig, } from "./types.js";
|
|
13
|
+
export { DEFAULT_SUMMARIZER_CONFIG } from "./types.js";
|
|
14
|
+
export type { FindingEvidence, PayloadCorrelation, ToolSummaryStageBEnrichment, ToolDetailStageBEnrichment, StageBEnrichment, } from "./stageBTypes.js";
|
|
15
|
+
export { STAGE_B_ENRICHMENT_VERSION, DEFAULT_TIER2_MAX_SAMPLES, DEFAULT_TIER3_MAX_CORRELATIONS, MAX_RESPONSE_LENGTH, MAX_CONTEXT_WINDOW, } from "./stageBTypes.js";
|
|
16
|
+
export { buildToolSummaryStageBEnrichment, buildToolDetailStageBEnrichment, } from "./stageBEnrichmentBuilder.js";
|
|
17
|
+
export { estimateTokens, estimateJsonFileTokens, shouldAutoTier, formatTokenEstimate, estimateSectionTokens, getTopSections, } from "./tokenEstimator.js";
|
|
18
|
+
export { AssessmentSummarizer } from "./AssessmentSummarizer.js";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/assessment/summarizer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAGpD,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,2BAA2B,EAC3B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,EAC9B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assessment Summarizer Module
|
|
3
|
+
*
|
|
4
|
+
* Generates tiered output for large assessment results to fit within
|
|
5
|
+
* LLM context windows.
|
|
6
|
+
*
|
|
7
|
+
* Issue #136: Tiered output strategy for large assessments
|
|
8
|
+
* Issue #137: Stage B enrichment for Claude semantic analysis
|
|
9
|
+
*
|
|
10
|
+
* @module assessment/summarizer
|
|
11
|
+
*/
|
|
12
|
+
export { DEFAULT_SUMMARIZER_CONFIG } from "./types.js";
|
|
13
|
+
export { STAGE_B_ENRICHMENT_VERSION, DEFAULT_TIER2_MAX_SAMPLES, DEFAULT_TIER3_MAX_CORRELATIONS, MAX_RESPONSE_LENGTH, MAX_CONTEXT_WINDOW, } from "./stageBTypes.js";
|
|
14
|
+
// Stage B Enrichment Builders (Issue #137)
|
|
15
|
+
export { buildToolSummaryStageBEnrichment, buildToolDetailStageBEnrichment, } from "./stageBEnrichmentBuilder.js";
|
|
16
|
+
// Token estimation utilities
|
|
17
|
+
export { estimateTokens, estimateJsonFileTokens, shouldAutoTier, formatTokenEstimate, estimateSectionTokens, getTopSections, } from "./tokenEstimator.js";
|
|
18
|
+
// Main summarizer class
|
|
19
|
+
export { AssessmentSummarizer } from "./AssessmentSummarizer.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage B Enrichment Builder
|
|
3
|
+
*
|
|
4
|
+
* Functions to build Stage B enrichment data from assessment results.
|
|
5
|
+
* Extracts evidence, correlations, and confidence details for Claude
|
|
6
|
+
* semantic analysis.
|
|
7
|
+
*
|
|
8
|
+
* Issue #137: Stage A data enrichment for Stage B Claude analysis
|
|
9
|
+
*
|
|
10
|
+
* @module assessment/summarizer/stageBEnrichmentBuilder
|
|
11
|
+
*/
|
|
12
|
+
import type { SecurityTestResult } from "../resultTypes.js";
|
|
13
|
+
import type { AUPViolation } from "../extendedTypes.js";
|
|
14
|
+
import type { EnhancedToolAnnotationResult } from "../../../services/assessment/modules/annotations/types.js";
|
|
15
|
+
import { type ToolSummaryStageBEnrichment, type ToolDetailStageBEnrichment } from "./stageBTypes.js";
|
|
16
|
+
/**
|
|
17
|
+
* Build Stage B enrichment for Tier 2 tool summaries.
|
|
18
|
+
*
|
|
19
|
+
* @param toolName - Name of the tool
|
|
20
|
+
* @param tests - Security test results for this tool
|
|
21
|
+
* @param maxSamples - Maximum evidence samples to include
|
|
22
|
+
* @returns Tool summary Stage B enrichment
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildToolSummaryStageBEnrichment(toolName: string, tests: SecurityTestResult[], maxSamples?: number): ToolSummaryStageBEnrichment;
|
|
25
|
+
/**
|
|
26
|
+
* Build Stage B enrichment for Tier 3 per-tool detail files.
|
|
27
|
+
*
|
|
28
|
+
* @param toolName - Name of the tool
|
|
29
|
+
* @param tests - Security test results for this tool
|
|
30
|
+
* @param annotationResult - Tool annotation result (if available)
|
|
31
|
+
* @param aupViolations - AUP violations for this tool (if any)
|
|
32
|
+
* @param maxCorrelations - Maximum correlations to include
|
|
33
|
+
* @returns Tool detail Stage B enrichment
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildToolDetailStageBEnrichment(toolName: string, tests: SecurityTestResult[], annotationResult?: EnhancedToolAnnotationResult, aupViolations?: AUPViolation[], maxCorrelations?: number): ToolDetailStageBEnrichment;
|
|
36
|
+
//# sourceMappingURL=stageBEnrichmentBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stageBEnrichmentBuilder.d.ts","sourceRoot":"","sources":["../../../../src/lib/assessment/summarizer/stageBEnrichmentBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wDAAwD,CAAC;AAC3G,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAKhC,MAAM,eAAe,CAAC;AA6HvB;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,UAAU,GAAE,MAAkC,GAC7C,2BAA2B,CA6C7B;AAMD;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,gBAAgB,CAAC,EAAE,4BAA4B,EAC/C,aAAa,CAAC,EAAE,YAAY,EAAE,EAC9B,eAAe,GAAE,MAAuC,GACvD,0BAA0B,CA4I5B"}
|