@artemiskit/reports 0.1.6 → 0.2.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.
@@ -153,6 +153,35 @@ const HTML_TEMPLATE = `
153
153
  .redaction-banner .title { font-weight: 600; color: #92400e; }
154
154
  .redaction-banner .details { font-size: 0.875rem; color: #a16207; margin-top: 0.25rem; }
155
155
  footer { margin-top: 3rem; text-align: center; color: #666; font-size: 0.875rem; }
156
+
157
+ /* Collapsible sections */
158
+ .collapsible-header {
159
+ display: flex;
160
+ align-items: center;
161
+ cursor: pointer;
162
+ user-select: none;
163
+ }
164
+ .collapsible-header h2 {
165
+ margin: 0;
166
+ flex: 1;
167
+ }
168
+ .collapse-icon {
169
+ font-size: 1.25rem;
170
+ transition: transform 0.2s ease;
171
+ margin-left: 0.5rem;
172
+ color: #666;
173
+ }
174
+ .collapsible-header[data-collapsed="true"] .collapse-icon {
175
+ transform: rotate(-90deg);
176
+ }
177
+ .collapsible-content {
178
+ overflow: hidden;
179
+ transition: max-height 0.3s ease;
180
+ }
181
+ .collapsible-content.collapsed {
182
+ max-height: 0 !important;
183
+ padding: 0;
184
+ }
156
185
  </style>
157
186
  </head>
158
187
  <body>
@@ -170,7 +199,7 @@ const HTML_TEMPLATE = `
170
199
 
171
200
  {{#if manifest.redaction.enabled}}
172
201
  <div class="redaction-banner">
173
- <div class="icon">🔒</div>
202
+ <div class="icon">&#128274;</div>
174
203
  <div class="content">
175
204
  <div class="title">Data Redaction Configured</div>
176
205
  <div class="details">
@@ -181,153 +210,211 @@ const HTML_TEMPLATE = `
181
210
  </div>
182
211
  {{/if}}
183
212
 
184
- <div class="summary">
185
- <div class="card">
186
- <h3>Success Rate</h3>
187
- <div class="value {{successRateClass manifest.metrics.success_rate}}">
188
- {{formatPercent manifest.metrics.success_rate}}
189
- </div>
190
- <div class="success-meter">
191
- <div class="success-meter-fill {{successRateClass manifest.metrics.success_rate}}" style="width: {{formatPercentRaw manifest.metrics.success_rate}}">
192
- {{manifest.metrics.successful_requests}}/{{manifest.metrics.total_requests}}
213
+ <!-- Summary Section (Collapsible) -->
214
+ <div class="collapsible-section" data-section="summary">
215
+ <div class="collapsible-header" onclick="toggleSection('summary')">
216
+ <h2>Summary</h2>
217
+ <span class="collapse-icon">&#9660;</span>
218
+ </div>
219
+ <div class="collapsible-content" id="section-summary">
220
+ <div class="summary">
221
+ <div class="card">
222
+ <h3>Success Rate</h3>
223
+ <div class="value {{successRateClass manifest.metrics.success_rate}}">
224
+ {{formatPercent manifest.metrics.success_rate}}
225
+ </div>
226
+ <div class="success-meter">
227
+ <div class="success-meter-fill {{successRateClass manifest.metrics.success_rate}}" style="width: {{formatPercentRaw manifest.metrics.success_rate}}">
228
+ {{manifest.metrics.successful_requests}}/{{manifest.metrics.total_requests}}
229
+ </div>
230
+ </div>
231
+ </div>
232
+ <div class="card">
233
+ <h3>Requests/Second</h3>
234
+ <div class="value info">{{formatDecimal manifest.metrics.requests_per_second}}</div>
235
+ </div>
236
+ <div class="card">
237
+ <h3>Total Requests</h3>
238
+ <div class="value">{{formatNumber manifest.metrics.total_requests}}</div>
239
+ </div>
240
+ <div class="card">
241
+ <h3>Duration</h3>
242
+ <div class="value">{{formatDuration manifest.duration_ms}}<span class="unit">s</span></div>
193
243
  </div>
194
244
  </div>
195
245
  </div>
196
- <div class="card">
197
- <h3>Requests/Second</h3>
198
- <div class="value info">{{formatDecimal manifest.metrics.requests_per_second}}</div>
199
- </div>
200
- <div class="card">
201
- <h3>Total Requests</h3>
202
- <div class="value">{{formatNumber manifest.metrics.total_requests}}</div>
203
- </div>
204
- <div class="card">
205
- <h3>Duration</h3>
206
- <div class="value">{{formatDuration manifest.duration_ms}}<span class="unit">s</span></div>
207
- </div>
208
246
  </div>
209
247
 
210
- <h2>Latency Percentiles</h2>
211
- <div class="card">
212
- <div class="latency-grid">
213
- <div class="latency-item">
214
- <div class="label">Min</div>
215
- <div class="value">{{manifest.metrics.min_latency_ms}}ms</div>
216
- </div>
217
- <div class="latency-item">
218
- <div class="label">P50</div>
219
- <div class="value">{{manifest.metrics.p50_latency_ms}}ms</div>
220
- </div>
221
- <div class="latency-item">
222
- <div class="label">P90</div>
223
- <div class="value">{{manifest.metrics.p90_latency_ms}}ms</div>
224
- </div>
225
- <div class="latency-item">
226
- <div class="label">P95</div>
227
- <div class="value">{{manifest.metrics.p95_latency_ms}}ms</div>
228
- </div>
229
- <div class="latency-item">
230
- <div class="label">P99</div>
231
- <div class="value">{{manifest.metrics.p99_latency_ms}}ms</div>
232
- </div>
233
- <div class="latency-item">
234
- <div class="label">Max</div>
235
- <div class="value">{{manifest.metrics.max_latency_ms}}ms</div>
248
+ <!-- Latency Percentiles Section (Collapsible) -->
249
+ <div class="collapsible-section" data-section="latency">
250
+ <div class="collapsible-header" onclick="toggleSection('latency')">
251
+ <h2>Latency Percentiles</h2>
252
+ <span class="collapse-icon">&#9660;</span>
253
+ </div>
254
+ <div class="collapsible-content" id="section-latency">
255
+ <div class="card">
256
+ <div class="latency-grid">
257
+ <div class="latency-item">
258
+ <div class="label">Min</div>
259
+ <div class="value">{{manifest.metrics.min_latency_ms}}ms</div>
260
+ </div>
261
+ <div class="latency-item">
262
+ <div class="label">P50</div>
263
+ <div class="value">{{manifest.metrics.p50_latency_ms}}ms</div>
264
+ </div>
265
+ <div class="latency-item">
266
+ <div class="label">P90</div>
267
+ <div class="value">{{manifest.metrics.p90_latency_ms}}ms</div>
268
+ </div>
269
+ <div class="latency-item">
270
+ <div class="label">P95</div>
271
+ <div class="value">{{manifest.metrics.p95_latency_ms}}ms</div>
272
+ </div>
273
+ <div class="latency-item">
274
+ <div class="label">P99</div>
275
+ <div class="value">{{manifest.metrics.p99_latency_ms}}ms</div>
276
+ </div>
277
+ <div class="latency-item">
278
+ <div class="label">Max</div>
279
+ <div class="value">{{manifest.metrics.max_latency_ms}}ms</div>
280
+ </div>
281
+ </div>
236
282
  </div>
237
283
  </div>
238
284
  </div>
239
285
 
240
- <h2>Configuration</h2>
241
- <div class="card">
242
- <table>
243
- <tr>
244
- <th>Parameter</th>
245
- <th>Value</th>
246
- </tr>
247
- <tr>
248
- <td>Concurrency</td>
249
- <td>{{manifest.config.concurrency}}</td>
250
- </tr>
251
- <tr>
252
- <td>Duration</td>
253
- <td>{{manifest.config.duration_seconds}} seconds</td>
254
- </tr>
255
- <tr>
256
- <td>Ramp-up Time</td>
257
- <td>{{manifest.config.ramp_up_seconds}} seconds</td>
258
- </tr>
259
- {{#if manifest.config.max_requests}}
260
- <tr>
261
- <td>Max Requests</td>
262
- <td>{{manifest.config.max_requests}}</td>
263
- </tr>
264
- {{/if}}
265
- </table>
266
- </div>
286
+ <!-- Configuration Section (Collapsible) -->
287
+ <div class="collapsible-section" data-section="config">
288
+ <div class="collapsible-header" onclick="toggleSection('config')">
289
+ <h2>Configuration</h2>
290
+ <span class="collapse-icon">&#9660;</span>
291
+ </div>
292
+ <div class="collapsible-content" id="section-config">
293
+ <div class="card">
294
+ <table>
295
+ <tr>
296
+ <th>Parameter</th>
297
+ <th>Value</th>
298
+ </tr>
299
+ <tr>
300
+ <td>Concurrency</td>
301
+ <td>{{manifest.config.concurrency}}</td>
302
+ </tr>
303
+ <tr>
304
+ <td>Duration</td>
305
+ <td>{{manifest.config.duration_seconds}} seconds</td>
306
+ </tr>
307
+ <tr>
308
+ <td>Ramp-up Time</td>
309
+ <td>{{manifest.config.ramp_up_seconds}} seconds</td>
310
+ </tr>
311
+ {{#if manifest.config.max_requests}}
312
+ <tr>
313
+ <td>Max Requests</td>
314
+ <td>{{manifest.config.max_requests}}</td>
315
+ </tr>
316
+ {{/if}}
317
+ </table>
318
+ </div>
267
319
 
268
- <h2>Results Summary</h2>
269
- <div class="card">
270
- <table>
271
- <tr>
272
- <th>Metric</th>
273
- <th>Value</th>
274
- </tr>
275
- <tr>
276
- <td>Total Requests</td>
277
- <td>{{formatNumber manifest.metrics.total_requests}}</td>
278
- </tr>
279
- <tr>
280
- <td>Successful</td>
281
- <td style="color: #22c55e;">{{formatNumber manifest.metrics.successful_requests}}</td>
282
- </tr>
283
- <tr>
284
- <td>Failed</td>
285
- <td style="color: {{#if manifest.metrics.failed_requests}}#ef4444{{else}}inherit{{/if}};">{{formatNumber manifest.metrics.failed_requests}}</td>
286
- </tr>
287
- <tr>
288
- <td>Average Latency</td>
289
- <td>{{formatDecimal manifest.metrics.avg_latency_ms}}ms</td>
290
- </tr>
291
- </table>
320
+ {{#if manifest.resolved_config}}
321
+ <div class="card" style="margin-top: 1rem;">
322
+ <h3 style="margin-bottom: 1rem;">Resolved Provider Configuration</h3>
323
+ <p><strong>Provider:</strong> {{manifest.resolved_config.provider}} <span class="source-badge">{{manifest.resolved_config.source.provider}}</span></p>
324
+ {{#if manifest.resolved_config.model}}
325
+ <p><strong>Model:</strong> {{manifest.resolved_config.model}} <span class="source-badge">{{manifest.resolved_config.source.model}}</span></p>
326
+ {{/if}}
327
+ {{#if manifest.resolved_config.deployment_name}}
328
+ <p><strong>Deployment:</strong> {{manifest.resolved_config.deployment_name}} <span class="source-badge">{{manifest.resolved_config.source.deployment_name}}</span></p>
329
+ {{/if}}
330
+ {{#if manifest.resolved_config.resource_name}}
331
+ <p><strong>Resource:</strong> {{manifest.resolved_config.resource_name}} <span class="source-badge">{{manifest.resolved_config.source.resource_name}}</span></p>
332
+ {{/if}}
333
+ {{#if manifest.resolved_config.api_version}}
334
+ <p><strong>API Version:</strong> {{manifest.resolved_config.api_version}} <span class="source-badge">{{manifest.resolved_config.source.api_version}}</span></p>
335
+ {{/if}}
336
+ {{#if manifest.resolved_config.base_url}}
337
+ <p><strong>Base URL:</strong> {{manifest.resolved_config.base_url}} <span class="source-badge">{{manifest.resolved_config.source.base_url}}</span></p>
338
+ {{/if}}
339
+ {{#if manifest.resolved_config.temperature}}
340
+ <p><strong>Temperature:</strong> {{manifest.resolved_config.temperature}} <span class="source-badge">{{manifest.resolved_config.source.temperature}}</span></p>
341
+ {{/if}}
342
+ </div>
343
+ {{/if}}
344
+ </div>
292
345
  </div>
293
346
 
294
- {{#if manifest.resolved_config}}
295
- <h2>Resolved Configuration</h2>
296
- <div class="card">
297
- <p><strong>Provider:</strong> {{manifest.resolved_config.provider}} <span class="source-badge">{{manifest.resolved_config.source.provider}}</span></p>
298
- {{#if manifest.resolved_config.model}}
299
- <p><strong>Model:</strong> {{manifest.resolved_config.model}} <span class="source-badge">{{manifest.resolved_config.source.model}}</span></p>
300
- {{/if}}
301
- {{#if manifest.resolved_config.deployment_name}}
302
- <p><strong>Deployment:</strong> {{manifest.resolved_config.deployment_name}} <span class="source-badge">{{manifest.resolved_config.source.deployment_name}}</span></p>
303
- {{/if}}
304
- {{#if manifest.resolved_config.resource_name}}
305
- <p><strong>Resource:</strong> {{manifest.resolved_config.resource_name}} <span class="source-badge">{{manifest.resolved_config.source.resource_name}}</span></p>
306
- {{/if}}
307
- {{#if manifest.resolved_config.api_version}}
308
- <p><strong>API Version:</strong> {{manifest.resolved_config.api_version}} <span class="source-badge">{{manifest.resolved_config.source.api_version}}</span></p>
309
- {{/if}}
310
- {{#if manifest.resolved_config.base_url}}
311
- <p><strong>Base URL:</strong> {{manifest.resolved_config.base_url}} <span class="source-badge">{{manifest.resolved_config.source.base_url}}</span></p>
312
- {{/if}}
313
- {{#if manifest.resolved_config.temperature}}
314
- <p><strong>Temperature:</strong> {{manifest.resolved_config.temperature}} <span class="source-badge">{{manifest.resolved_config.source.temperature}}</span></p>
315
- {{/if}}
347
+ <!-- Results Summary Section (Collapsible) -->
348
+ <div class="collapsible-section" data-section="results">
349
+ <div class="collapsible-header" onclick="toggleSection('results')">
350
+ <h2>Results Summary</h2>
351
+ <span class="collapse-icon">&#9660;</span>
352
+ </div>
353
+ <div class="collapsible-content" id="section-results">
354
+ <div class="card">
355
+ <table>
356
+ <tr>
357
+ <th>Metric</th>
358
+ <th>Value</th>
359
+ </tr>
360
+ <tr>
361
+ <td>Total Requests</td>
362
+ <td>{{formatNumber manifest.metrics.total_requests}}</td>
363
+ </tr>
364
+ <tr>
365
+ <td>Successful</td>
366
+ <td style="color: #22c55e;">{{formatNumber manifest.metrics.successful_requests}}</td>
367
+ </tr>
368
+ <tr>
369
+ <td>Failed</td>
370
+ <td style="color: {{#if manifest.metrics.failed_requests}}#ef4444{{else}}inherit{{/if}};">{{formatNumber manifest.metrics.failed_requests}}</td>
371
+ </tr>
372
+ <tr>
373
+ <td>Average Latency</td>
374
+ <td>{{formatDecimal manifest.metrics.avg_latency_ms}}ms</td>
375
+ </tr>
376
+ </table>
377
+ </div>
378
+ </div>
316
379
  </div>
317
- {{/if}}
318
380
 
319
- <h2>Provenance</h2>
320
- <div class="card">
321
- <p><strong>Git Commit:</strong> {{manifest.git.commit}}</p>
322
- <p><strong>Git Branch:</strong> {{manifest.git.branch}}</p>
323
- <p><strong>Run By:</strong> {{manifest.provenance.run_by}}</p>
324
- <p><strong>Platform:</strong> {{manifest.environment.platform}} ({{manifest.environment.arch}})</p>
381
+ <!-- Provenance Section (Collapsible) -->
382
+ <div class="collapsible-section" data-section="provenance">
383
+ <div class="collapsible-header" onclick="toggleSection('provenance')">
384
+ <h2>Provenance</h2>
385
+ <span class="collapse-icon">&#9660;</span>
386
+ </div>
387
+ <div class="collapsible-content" id="section-provenance">
388
+ <div class="card">
389
+ <p><strong>Git Commit:</strong> {{manifest.git.commit}}</p>
390
+ <p><strong>Git Branch:</strong> {{manifest.git.branch}}</p>
391
+ <p><strong>Run By:</strong> {{manifest.provenance.run_by}}</p>
392
+ <p><strong>Platform:</strong> {{manifest.environment.platform}} ({{manifest.environment.arch}})</p>
393
+ </div>
394
+ </div>
325
395
  </div>
326
396
 
327
397
  <footer>
328
398
  Generated by Artemis Agent Reliability Toolkit - Stress Test Module
329
399
  </footer>
330
400
  </div>
401
+
402
+ <script>
403
+ // Toggle collapsible sections
404
+ function toggleSection(sectionId) {
405
+ const header = document.querySelector('[data-section="' + sectionId + '"] .collapsible-header');
406
+ const content = document.getElementById('section-' + sectionId);
407
+ const isCollapsed = header.getAttribute('data-collapsed') === 'true';
408
+
409
+ if (isCollapsed) {
410
+ header.setAttribute('data-collapsed', 'false');
411
+ content.classList.remove('collapsed');
412
+ } else {
413
+ header.setAttribute('data-collapsed', 'true');
414
+ content.classList.add('collapsed');
415
+ }
416
+ }
417
+ </script>
331
418
  </body>
332
419
  </html>
333
420
  `;
package/src/index.ts CHANGED
@@ -12,3 +12,11 @@ export { generateRedTeamHTMLReport } from './html/redteam-generator';
12
12
 
13
13
  // Stress test reports
14
14
  export { generateStressHTMLReport } from './html/stress-generator';
15
+
16
+ // Comparison reports
17
+ export {
18
+ generateCompareHTMLReport,
19
+ buildComparisonData,
20
+ type ComparisonData,
21
+ type CaseComparison,
22
+ } from './html/compare-generator';