a1c00l commited on
Commit
5d28f7e
Β·
verified Β·
1 Parent(s): 8adece2

Update templates/result.html

Browse files
Files changed (1) hide show
  1. templates/result.html +711 -640
templates/result.html CHANGED
@@ -1,17 +1,41 @@
1
- <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
  <title>AI SBOM Generated</title>
6
  <style>
7
- body { font-family: Arial, sans-serif; margin: 20px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  table { border-collapse: collapse; width: 60%; margin-top: 15px; }
9
  th, td { border: 1px solid #ddd; padding: 8px; }
10
  th { background-color: #f4f4f4; }
 
11
  /* Fixed color styling for field checklist items */
12
- .missing { color: #e74c3c; } /* Red color for missing fields */
13
- .present { color: #27ae60; } /* Green color for present fields */
14
- .unknown { color: #f39c12; } /* Orange color for unknown status */
 
 
15
  .improvement { color: #2c3e50; background-color: #ecf0f1; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
16
  .improvement-value { color: #27ae60; font-weight: bold; }
17
  .ai-badge { background-color: #3498db; color: white; padding: 3px 8px; border-radius: 3px; font-size: 0.8em; margin-left: 10px; }
@@ -128,6 +152,9 @@
128
  line-height: 20px;
129
  color: white;
130
  font-size: 12px;
 
 
 
131
  }
132
  .progress-excellent {
133
  background-color: #4CAF50; /* Green */
@@ -165,18 +192,7 @@
165
  color: white;
166
  font-size: 0.8em;
167
  margin-left: 5px;
168
- }
169
- .label-excellent {
170
- background-color: #4CAF50;
171
- }
172
- .label-good {
173
- background-color: #2196F3;
174
- }
175
- .label-fair {
176
- background-color: #FF9800;
177
- }
178
- .label-poor {
179
- background-color: #f44336;
180
  }
181
  .total-score-container {
182
  display: flex;
@@ -190,7 +206,6 @@
190
  }
191
  .total-progress {
192
  flex: 1;
193
- max-width: 300px;
194
  }
195
 
196
  /* New styles for improved user understanding */
@@ -367,702 +382,758 @@
367
  margin-top: 0;
368
  color: #e65100;
369
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  </style>
371
  </head>
372
  <body>
373
- <a href="/">Generate another AI SBOM</a>
374
- <h2>AI SBOM Generated for {{ model_id }}</h2>
375
-
376
- <div class="download-section">
377
- <p>Download generated AI SBOM in CycloneDX format <button onclick="downloadJSON()">Download JSON</button></p>
378
- </div>
379
-
380
- {% if enhancement_report and enhancement_report.ai_enhanced %}
381
- <div class="improvement">
382
- <h3>AI Enhancement Results</h3>
383
- <p>This AI SBOM was enhanced using <strong>{{ enhancement_report.ai_model|default('AI Model') }}</strong></p>
384
- <p>Original Score: {{ enhancement_report.original_score.total_score|default(0)|round(1) }}/100</p>
385
- <p>Enhanced Score: {{ enhancement_report.final_score.total_score|default(0)|round(1) }}/100</p>
386
- <p>Improvement: <span class="improvement-value">+{{ enhancement_report.improvement|default(0)|round(1) }} points</span></p>
387
- </div>
388
- {% endif %}
389
-
390
- <!-- Human-friendly AI SBOM Viewer -->
391
- <div class="note-box">
392
- <p><strong>Note:</strong> This page displays the AI SBOM in a human-friendly format for easier readability.
393
- The downloaded JSON file follows the standard CycloneDX format required for interoperability with other tools.</p>
394
  </div>
395
 
396
- <div class="aibom-tabs">
397
- <div class="aibom-tab active" onclick="switchTab('human-view')">Human-Friendly View</div>
398
- <div class="aibom-tab" onclick="switchTab('json-view')">JSON View</div>
399
- <div class="aibom-tab" onclick="switchTab('field-checklist')">Field Checklist</div>
400
- <div class="aibom-tab" onclick="switchTab('score-view')">Score Report</div>
401
- </div>
 
402
 
403
- <div id="human-view" class="tab-content active">
404
- <div class="aibom-viewer">
405
- <!-- Key Information Section -->
406
- <div class="aibom-section key-info">
407
- <h4>Key Information</h4>
408
- <div class="aibom-property">
409
- <div class="property-name">Model Name:</div>
410
- <div class="property-value">{{ aibom.components[0].name if aibom.components and aibom.components[0].name else 'Not specified' }}</div>
411
- </div>
412
- <div class="aibom-property">
413
- <div class="property-name">Type:</div>
414
- <div class="property-value">{{ aibom.components[0].type if aibom.components and aibom.components[0].type else 'Not specified' }}</div>
415
- </div>
416
- <div class="aibom-property">
417
- <div class="property-name">Version:</div>
418
- <div class="property-value">{{ aibom.components[0].version if aibom.components and aibom.components[0].version else 'Not specified' }}</div>
419
- </div>
420
- <div class="aibom-property">
421
- <div class="property-name">PURL:</div>
422
- <div class="property-value">{{ aibom.components[0].purl if aibom.components and aibom.components[0].purl else 'Not specified' }}</div>
423
- </div>
424
- {% if aibom.components and aibom.components[0].description %}
425
- <div class="aibom-property">
426
- <div class="property-name">Description:</div>
427
- <div class="property-value">{{ aibom.components[0].description }}</div>
428
- </div>
429
- {% endif %}
430
- </div>
431
 
432
- <!-- Model Card Section -->
433
- {% if aibom.components and aibom.components[0].modelCard %}
434
- <div class="aibom-section">
435
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Model Card</h4>
436
- <div class="collapsible-content">
437
- {% if aibom.components[0].modelCard.modelParameters %}
438
  <div class="aibom-property">
439
- <div class="property-name">Model Parameters:</div>
440
- <div class="property-value">
441
- {% if aibom.components[0].modelCard.modelParameters.properties %}
442
- {% for prop in aibom.components[0].modelCard.modelParameters.properties %}
443
- <div><strong>{{ prop.name }}:</strong> {{ prop.value }}</div>
444
- {% endfor %}
445
- {% elif aibom.components[0].modelCard.modelParameters.description %}
446
- {{ aibom.components[0].modelCard.modelParameters.description }}
447
- {% endif %}
448
- </div>
449
  </div>
450
- {% endif %}
451
-
452
- {% if aibom.components[0].modelCard.quantitativeAnalysis %}
453
  <div class="aibom-property">
454
- <div class="property-name">Performance Metrics:</div>
455
- <div class="property-value">
456
- {% if aibom.components[0].modelCard.quantitativeAnalysis.performanceMetrics %}
457
- {% for metric in aibom.components[0].modelCard.quantitativeAnalysis.performanceMetrics %}
458
- <div><strong>{{ metric.type if metric.type else 'Metric' }}:</strong> {{ metric.value if metric.value else 'Not specified' }}</div>
459
- {% endfor %}
460
- {% endif %}
461
- </div>
462
  </div>
463
- {% endif %}
464
-
465
- {% if aibom.components[0].modelCard.considerations %}
466
  <div class="aibom-property">
467
- <div class="property-name">Considerations:</div>
468
- <div class="property-value">
469
- {% if aibom.components[0].modelCard.considerations.ethicalConsiderations %}
470
- <div><strong>Ethical Considerations:</strong> {{ aibom.components[0].modelCard.considerations.ethicalConsiderations }}</div>
471
- {% endif %}
472
- {% if aibom.components[0].modelCard.considerations.limitations %}
473
- <div><strong>Limitations:</strong> {{ aibom.components[0].modelCard.considerations.limitations }}</div>
474
- {% endif %}
475
- {% if aibom.components[0].modelCard.considerations.tradeoffs %}
476
- <div><strong>Tradeoffs:</strong> {{ aibom.components[0].modelCard.considerations.tradeoffs }}</div>
477
- {% endif %}
478
- </div>
479
  </div>
480
- {% endif %}
481
- </div>
482
- </div>
483
- {% endif %}
484
-
485
- <!-- Training Data Section -->
486
- {% if aibom.components and aibom.components[0].trainingData %}
487
- <div class="aibom-section">
488
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Training Data</h4>
489
- <div class="collapsible-content">
490
- {% if aibom.components[0].trainingData.datasets %}
491
  <div class="aibom-property">
492
- <div class="property-name">Datasets:</div>
493
- <div class="property-value">
494
- {% for dataset in aibom.components[0].trainingData.datasets %}
495
- <div>
496
- <strong>{{ dataset.name if dataset.name else 'Dataset' }}:</strong>
497
- {% if dataset.description %} {{ dataset.description }}{% endif %}
498
- {% if dataset.url %} <a href="{{ dataset.url }}" target="_blank">Link</a>{% endif %}
499
- </div>
500
- {% endfor %}
501
- </div>
502
  </div>
503
- {% endif %}
504
-
505
- {% if aibom.components[0].trainingData.preprocessing %}
506
  <div class="aibom-property">
507
- <div class="property-name">Preprocessing:</div>
508
- <div class="property-value">{{ aibom.components[0].trainingData.preprocessing }}</div>
509
  </div>
510
  {% endif %}
511
  </div>
512
- </div>
513
- {% endif %}
514
 
515
- <!-- Training Process Section -->
516
- {% if aibom.components and aibom.components[0].trainingProcess %}
517
- <div class="aibom-section">
518
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Training Process</h4>
519
- <div class="collapsible-content">
520
- {% if aibom.components[0].trainingProcess.trainingMethod %}
521
- <div class="aibom-property">
522
- <div class="property-name">Training Method:</div>
523
- <div class="property-value">{{ aibom.components[0].trainingProcess.trainingMethod }}</div>
524
- </div>
525
- {% endif %}
526
-
527
- {% if aibom.components[0].trainingProcess.hyperparameters %}
528
- <div class="aibom-property">
529
- <div class="property-name">Hyperparameters:</div>
530
- <div class="property-value">
531
- {% for param in aibom.components[0].trainingProcess.hyperparameters %}
532
- <div><strong>{{ param.name }}:</strong> {{ param.value }}</div>
533
- {% endfor %}
534
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  </div>
536
- {% endif %}
537
-
538
- {% if aibom.components[0].trainingProcess.computeInfrastructure %}
539
- <div class="aibom-property">
540
- <div class="property-name">Compute Infrastructure:</div>
541
- <div class="property-value">{{ aibom.components[0].trainingProcess.computeInfrastructure }}</div>
542
- </div>
543
- {% endif %}
544
  </div>
545
- </div>
546
- {% endif %}
547
 
548
- <!-- Evaluation Section -->
549
- {% if aibom.components and aibom.components[0].evaluation %}
550
- <div class="aibom-section">
551
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Evaluation</h4>
552
- <div class="collapsible-content">
553
- {% if aibom.components[0].evaluation.metrics %}
554
- <div class="aibom-property">
555
- <div class="property-name">Metrics:</div>
556
- <div class="property-value">
557
- {% for metric in aibom.components[0].evaluation.metrics %}
558
- <div><strong>{{ metric.name }}:</strong> {{ metric.value }}</div>
559
- {% endfor %}
 
 
 
 
 
560
  </div>
561
- </div>
562
- {% endif %}
563
-
564
- {% if aibom.components[0].evaluation.datasets %}
565
- <div class="aibom-property">
566
- <div class="property-name">Evaluation Datasets:</div>
567
- <div class="property-value">
568
- {% for dataset in aibom.components[0].evaluation.datasets %}
569
- <div>
570
- <strong>{{ dataset.name if dataset.name else 'Dataset' }}:</strong>
571
- {% if dataset.description %} {{ dataset.description }}{% endif %}
572
- {% if dataset.url %} <a href="{{ dataset.url }}" target="_blank">Link</a>{% endif %}
573
- </div>
574
- {% endfor %}
575
  </div>
 
576
  </div>
577
- {% endif %}
578
  </div>
579
- </div>
580
- {% endif %}
581
 
582
- <!-- Usage Section -->
583
- {% if aibom.components and aibom.components[0].usage %}
584
- <div class="aibom-section">
585
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Usage</h4>
586
- <div class="collapsible-content">
587
- {% if aibom.components[0].usage.intendedUse %}
588
- <div class="aibom-property">
589
- <div class="property-name">Intended Use:</div>
590
- <div class="property-value">{{ aibom.components[0].usage.intendedUse }}</div>
591
- </div>
592
- {% endif %}
593
-
594
- {% if aibom.components[0].usage.outOfScopeUses %}
595
- <div class="aibom-property">
596
- <div class="property-name">Out of Scope Uses:</div>
597
- <div class="property-value">{{ aibom.components[0].usage.outOfScopeUses }}</div>
598
- </div>
599
- {% endif %}
600
-
601
- {% if aibom.components[0].usage.guidelines %}
602
- <div class="aibom-property">
603
- <div class="property-name">Usage Guidelines:</div>
604
- <div class="property-value">{{ aibom.components[0].usage.guidelines }}</div>
 
 
 
 
 
 
605
  </div>
606
- {% endif %}
607
  </div>
608
- </div>
609
- {% endif %}
610
 
611
- <!-- Licenses Section -->
612
- {% if aibom.components and aibom.components[0].licenses %}
613
- <div class="aibom-section">
614
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Licenses</h4>
615
- <div class="collapsible-content">
616
- {% for license in aibom.components[0].licenses %}
617
- <div class="aibom-property">
618
- <div class="property-name">License:</div>
619
- <div class="property-value">
620
- <strong>{{ license.name }}</strong>
621
- {% if license.url %} <a href="{{ license.url }}" target="_blank">Link</a>{% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  </div>
 
623
  </div>
624
- {% endfor %}
625
  </div>
626
- </div>
627
- {% endif %}
628
-
629
- <!-- Metadata Section -->
630
- {% if aibom.metadata %}
631
- <div class="aibom-section">
632
- <h4 class="collapsible" onclick="toggleCollapsible(this)">Metadata</h4>
633
- <div class="collapsible-content">
634
- {% if aibom.metadata.timestamp %}
635
- <div class="aibom-property">
636
- <div class="property-name">Timestamp:</div>
637
- <div class="property-value">{{ aibom.metadata.timestamp }}</div>
638
- </div>
639
- {% endif %}
640
-
641
- {% if aibom.metadata.tools %}
642
- <div class="aibom-property">
643
- <div class="property-name">Tools:</div>
644
- <div class="property-value">
645
- {% for tool in aibom.metadata.tools %}
646
- <div>{{ tool.name }} {% if tool.version %}({{ tool.version }}){% endif %}</div>
647
- {% endfor %}
 
 
 
648
  </div>
 
649
  </div>
650
- {% endif %}
651
-
652
- {% if aibom.metadata.authors %}
653
- <div class="aibom-property">
654
- <div class="property-name">Authors:</div>
655
- <div class="property-value">
656
- {% for author in aibom.metadata.authors %}
657
- <div>{{ author.name }} {% if author.email %}({{ author.email }}){% endif %}</div>
658
- {% endfor %}
 
 
 
 
 
 
659
  </div>
 
660
  </div>
661
- {% endif %}
662
-
663
- {% if aibom.metadata.properties %}
664
- <div class="aibom-property">
665
- <div class="property-name">Properties:</div>
666
- <div class="property-value">
667
- {% for prop in aibom.metadata.properties %}
668
- <div><strong>{{ prop.name }}:</strong> {{ prop.value }}</div>
669
- {% endfor %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
671
  </div>
672
- {% endif %}
673
  </div>
674
- </div>
675
- {% endif %}
676
 
677
- <!-- External References Section -->
678
- {% if aibom.components and aibom.components[0].externalReferences %}
679
- <div class="aibom-section">
680
- <h4 class="collapsible" onclick="toggleCollapsible(this)">External References</h4>
681
- <div class="collapsible-content">
682
- {% for ref in aibom.components[0].externalReferences %}
683
- <div class="aibom-property">
684
- <div class="property-name">{{ ref.type|title if ref.type else 'Reference' }}:</div>
685
- <div class="property-value">
686
- <a href="{{ ref.url }}" target="_blank">{{ ref.url }}</a>
687
- {% if ref.comment %}<div>{{ ref.comment }}</div>{% endif %}
 
688
  </div>
 
689
  </div>
690
- {% endfor %}
691
  </div>
 
692
  </div>
693
- {% endif %}
694
- </div>
695
- </div>
696
-
697
- <div id="json-view" class="tab-content">
698
- <div class="json-view">
699
- <pre>{{ aibom | tojson(indent=2) }}</pre>
700
  </div>
701
- </div>
702
 
703
- <div id="field-checklist" class="tab-content">
704
- <h3>Field Checklist</h3>
705
-
706
- <!-- Field Tier Legend -->
707
- <div class="tier-legend">
708
- <div class="tier-legend-item">
709
- <span class="field-tier tier-critical"></span>
710
- <span>Critical</span>
711
- </div>
712
- <div class="tier-legend-item">
713
- <span class="field-tier tier-important"></span>
714
- <span>Important</span>
715
- </div>
716
- <div class="tier-legend-item">
717
- <span class="field-tier tier-supplementary"></span>
718
- <span>Supplementary</span>
719
  </div>
720
  </div>
721
-
722
- {% if completeness_score and completeness_score.field_checklist %}
723
- <ul>
724
- {% for field, status in completeness_score.field_checklist.items() %}
725
- {% if "βœ”" in status %}
726
- <li class="present">{{ status }} {{ field }}
727
- {% if completeness_score.field_tiers and field in completeness_score.field_tiers %}
728
- <span class="field-tier tier-{{ completeness_score.field_tiers[field] }}"></span>
729
- {% endif %}
730
- </li>
731
- {% else %}
732
- <li class="missing">{{ status }} {{ field }}
733
- {% if completeness_score.field_tiers and field in completeness_score.field_tiers %}
734
- <span class="field-tier tier-{{ completeness_score.field_tiers[field] }}"></span>
735
- {% endif %}
736
-
737
- {% if field == "component.description" %}
738
- <span class="importance-indicator high-importance">β˜…β˜…β˜…</span>
739
- <span class="tooltip">(?)
740
- <span class="tooltiptext">A detailed description of the model is essential for users to understand its purpose and capabilities. Add a description that is at least 20 characters long.</span>
741
- </span>
742
- {% elif field == "component.purl" %}
743
- <span class="importance-indicator high-importance">β˜…β˜…β˜…</span>
744
- <span class="tooltip">(?)
745
- <span class="tooltiptext">Package URL (PURL) is critical for uniquely identifying the model. It should follow the format pkg:huggingface/[owner]/[name]@[version].</span>
746
- </span>
747
- {% elif field == "modelCard.modelParameters" %}
748
- <span class="importance-indicator high-importance">β˜…β˜…β˜…</span>
749
- <span class="tooltip">(?)
750
- <span class="tooltiptext">Model parameters provide essential technical details about the model architecture, training, and capabilities.</span>
751
- </span>
752
- {% elif field == "modelCard.considerations" %}
753
- <span class="importance-indicator medium-importance">β˜…β˜…</span>
754
- <span class="tooltip">(?)
755
- <span class="tooltiptext">Considerations section should include ethical considerations, limitations, and risks associated with the model.</span>
756
- </span>
757
- {% elif field == "externalReferences" %}
758
- <span class="importance-indicator medium-importance">β˜…β˜…</span>
759
- <span class="tooltip">(?)
760
- <span class="tooltiptext">External references provide links to additional resources like model cards, repositories, and datasets.</span>
761
- </span>
762
- {% else %}
763
- <span class="importance-indicator low-importance">β˜…</span>
764
- <span class="tooltip">(?)
765
- <span class="tooltiptext">This field contributes to the completeness of your AI SBOM.</span>
766
- </span>
767
- {% endif %}
768
- </li>
769
- {% endif %}
770
- {% endfor %}
771
- </ul>
772
- {% else %}
773
- <p>Field checklist information is not available for this AI SBOM.</p>
774
- {% endif %}
775
- </div>
776
 
777
- <div id="score-view" class="tab-content">
778
- <h3>AI SBOM Completeness Score</h3>
779
-
780
- <!-- Completeness Profile Section -->
781
- {% if completeness_score and completeness_score.completeness_profile %}
782
- <div class="completeness-profile">
783
- <h4>Completeness Profile:
784
- <span class="profile-badge profile-{{ completeness_score.completeness_profile.name|default('incomplete')|lower }}">
785
- {{ completeness_score.completeness_profile.name|default('Incomplete') }}
786
- </span>
787
- </h4>
788
- <p>{{ completeness_score.completeness_profile.description|default('This AI SBOM needs improvement to meet transparency requirements.') }}</p>
789
 
790
- {% if completeness_score.completeness_profile.next_level %}
791
- <p><strong>Next level:</strong> {{ completeness_score.completeness_profile.next_level.name }}
792
- ({{ completeness_score.completeness_profile.next_level.missing_fields_count }} fields to add)</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  {% endif %}
794
  </div>
795
- {% elif enhancement_report %}
796
- <div class="completeness-profile">
797
- <h4>Completeness Profile:
798
- {% set score = enhancement_report.final_score.total_score|default(0) %}
799
- {% if score >= 80 %}
800
- <span class="profile-badge profile-advanced">Advanced</span>
801
- {% elif score >= 60 %}
802
- <span class="profile-badge profile-standard">Standard</span>
803
- {% elif score >= 40 %}
804
- <span class="profile-badge profile-basic">Basic</span>
805
- {% else %}
806
- <span class="profile-badge profile-incomplete">Incomplete</span>
807
- {% endif %}
808
- </h4>
809
- <p>
810
- {% if score >= 80 %}
811
- This AI SBOM provides comprehensive information about the model, including detailed training data, process, evaluation metrics, and usage guidelines. It meets advanced transparency requirements.
812
- {% elif score >= 60 %}
813
- This AI SBOM provides good information about the model, covering most key aspects of its development and usage. It meets standard transparency requirements.
814
- {% elif score >= 40 %}
815
- This AI SBOM provides basic information about the model but lacks detail in several areas. It meets minimal transparency requirements.
816
- {% else %}
817
- This AI SBOM is incomplete and missing critical information. It does not meet basic transparency requirements.
818
  {% endif %}
819
- </p>
820
- </div>
821
- {% endif %}
822
-
823
- <!-- Total Score with Progress Bar -->
824
- <div class="total-score-container">
825
- {% if completeness_score %}
826
- <div class="total-score">{{ completeness_score.total_score|default(0)|round(1) }}/100</div>
827
  {% elif enhancement_report %}
828
- <div class="total-score">{{ enhancement_report.final_score.total_score|default(0)|round(1) }}/100</div>
829
- {% else %}
830
- <div class="total-score">0/100</div>
831
- {% endif %}
832
-
833
- <div class="total-progress">
834
- <div class="progress-container">
835
- {% if completeness_score %}
836
- {% set score_percent = (completeness_score.total_score|default(0) / 100) * 100 %}
837
- {% elif enhancement_report %}
838
- {% set score_percent = (enhancement_report.final_score.total_score|default(0) / 100) * 100 %}
839
  {% else %}
840
- {% set score_percent = 0 %}
841
  {% endif %}
842
-
843
- {% set score_class = 'progress-poor' %}
844
- {% set score_label = 'Poor' %}
845
-
846
- {% if score_percent >= 90 %}
847
- {% set score_class = 'progress-excellent' %}
848
- {% set score_label = 'Excellent' %}
849
- {% elif score_percent >= 70 %}
850
- {% set score_class = 'progress-good' %}
851
- {% set score_label = 'Good' %}
852
- {% elif score_percent >= 50 %}
853
- {% set score_class = 'progress-fair' %}
854
- {% set score_label = 'Fair' %}
855
  {% endif %}
856
-
857
- <div class="progress-bar {{ score_class }}" style="width: {{ score_percent }}%">
858
- {{ score_percent|int }}% <span class="score-label label-{{ score_class|replace('progress-', '') }}">{{ score_label }}</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
859
  </div>
860
  </div>
 
 
 
 
861
  </div>
862
 
 
863
  {% if completeness_score and completeness_score.validation_penalty %}
864
- <div style="margin-left: 15px; color: #f44336;">{{ completeness_score.validation_penalty }}</div>
 
 
 
 
865
  {% endif %}
866
- </div>
867
-
868
- <!-- Validation Penalty Explanation -->
869
- {% if completeness_score and completeness_score.validation_penalty %}
870
- <div class="validation-penalty-info">
871
- <h4>About the Validation Penalty</h4>
872
- <p>Your score includes a penalty because the AIBOM has schema validation issues. These are structural problems that don't comply with the CycloneDX specification requirements.</p>
873
- <p><strong>How to fix this:</strong> Look at the "Fix Validation Issues" section in the recommendations below. Fixing these issues will remove the penalty and improve your overall score.</p>
874
- </div>
875
- {% endif %}
876
-
877
- <!-- Scoring Rubric -->
878
- <div class="scoring-rubric">
879
- <h4>Scoring Rubric</h4>
880
- <p>The AI SBOM completeness score is calculated based on the following criteria:</p>
881
- <table>
882
- <tr>
883
- <th>Category</th>
884
- <th>Weight</th>
885
- <th>Description</th>
886
- </tr>
887
- <tr>
888
- <td>Basic Information</td>
889
- <td>20%</td>
890
- <td>Model name, type, version, and description</td>
891
- </tr>
892
- <tr>
893
- <td>Training Data</td>
894
- <td>25%</td>
895
- <td>Datasets used for training and preprocessing steps</td>
896
- </tr>
897
- <tr>
898
- <td>Training Process</td>
899
- <td>20%</td>
900
- <td>Training method, hyperparameters, and compute infrastructure</td>
901
- </tr>
902
- <tr>
903
- <td>Evaluation</td>
904
- <td>15%</td>
905
- <td>Evaluation metrics and datasets</td>
906
- </tr>
907
- <tr>
908
- <td>Usage & Licensing</td>
909
- <td>20%</td>
910
- <td>Intended use, out-of-scope uses, and licensing information</td>
911
- </tr>
912
- </table>
913
- <p>Each category is scored based on the presence and quality of relevant fields. The final score is a weighted average of all categories.</p>
914
- </div>
915
-
916
- <!-- Section Scores with Progress Bars and Tooltips -->
917
- {% if completeness_score and completeness_score.section_scores %}
918
- <table class="score-table">
919
- <thead>
920
- <tr>
921
- <th>Section</th>
922
- <th>Score</th>
923
- <th>Weight</th>
924
- <th>Progress</th>
925
- </tr>
926
- </thead>
927
- <tbody>
928
- {% set weights = {'required_fields': 20, 'metadata': 20, 'component_basic': 20, 'component_model_card': 30, 'external_references': 10} %}
929
- {% set tooltips = {
930
- 'required_fields': 'Basic SBOM fields required by the CycloneDX specification: bomFormat, specVersion, serialNumber, and version.',
931
- 'metadata': 'Information about the AI SBOM itself: timestamp, tools used to generate it, authors, and component metadata.',
932
- 'component_basic': 'Basic information about the AI model: type, name, bom-ref, PURL, description, and licenses.',
933
- 'component_model_card': 'Detailed information about the model: parameters, quantitative analysis, and ethical considerations.',
934
- 'external_references': 'Links to external resources like model cards, repositories, and datasets.'
935
- } %}
936
- {% set display_names = {
937
- 'required_fields': 'Required Fields',
938
- 'metadata': 'Metadata',
939
- 'component_basic': 'Component Basic',
940
- 'component_model_card': 'Model Card',
941
- 'external_references': 'External References'
942
- } %}
943
- {% for section, score in completeness_score.section_scores.items() %}
944
  <tr>
945
- <td>
946
- {{ display_names[section]|default(section) }}
947
- <span class="tooltip">(?)
948
- <span class="tooltiptext">{{ tooltips[section]|default('Section score') }}</span>
949
- </span>
950
- </td>
951
- <td>{{ score|default(0)|round(1) }}/{{ completeness_score.max_scores[section]|default(100) }}</td>
952
- <td>{{ weights[section]|default(0) }}%</td>
953
- <td style="width: 50%;">
954
- <div class="progress-container">
955
- {% set percent = (score|default(0) / completeness_score.max_scores[section]|default(100)) * 100 %}
956
- {% set class = 'progress-poor' %}
957
-
958
- {% if percent >= 90 %}
959
- {% set class = 'progress-excellent' %}
960
- {% elif percent >= 70 %}
961
- {% set class = 'progress-good' %}
962
- {% elif percent >= 50 %}
963
- {% set class = 'progress-fair' %}
964
- {% endif %}
965
-
966
- <div class="progress-bar {{ class }}" style="width: {{ percent }}%">
967
- {{ percent|int }}%
968
- </div>
969
- </div>
970
- </td>
971
  </tr>
972
- {% endfor %}
973
- </tbody>
974
- </table>
975
- {% endif %}
976
-
977
- <!-- Missing Fields Highlighting -->
978
- {% if completeness_score and completeness_score.field_checklist %}
979
- <div class="missing-fields">
980
- <h4>Critical Missing Fields</h4>
981
- <p>The following fields are missing or incomplete and have the biggest impact on your score:</p>
982
- <ul>
983
- {% set missing_critical = [] %}
984
- {% for field, status in completeness_score.field_checklist.items() %}
985
- {% if status != "βœ”" %}
986
- {% if completeness_score.field_tiers and field in completeness_score.field_tiers and completeness_score.field_tiers[field] == 'critical' %}
987
- {% set _ = missing_critical.append(field) %}
988
- <li>
989
- <strong>{{ field }}</strong>
990
- <span class="field-tier tier-critical"></span>
991
- {% if field == "component.description" %}
992
- - Add a detailed description of the model (at least 20 characters)
993
- {% elif field == "component.purl" %}
994
- - Add a valid PURL in the format pkg:huggingface/[owner]/[name]@[version]
995
- {% elif field == "modelCard.modelParameters" %}
996
- - Add model parameters section with architecture, size, and training details
997
- {% elif field == "buildTime" %}
998
- - Add build time information (when the model was built)
999
- {% elif field == "releaseTime" %}
1000
- - Add release time information (when the model was released)
1001
- {% elif field == "primaryPurpose" %}
1002
- - Add primary purpose information (what the model is designed for)
1003
- {% else %}
1004
- - This field is required for comprehensive documentation
1005
- {% endif %}
1006
- </li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007
  {% endif %}
 
 
 
1008
  {% endif %}
1009
- {% endfor %}
1010
- {% if missing_critical|length == 0 %}
1011
- <li>No critical fields are missing. Great job!</li>
1012
- {% endif %}
1013
- </ul>
1014
- </div>
1015
- {% endif %}
1016
-
1017
- <!-- Actionable Recommendations -->
1018
- {% if completeness_score %}
1019
- <div class="recommendations">
1020
- <h4>Recommendations to Improve Your Score</h4>
1021
- <ol>
1022
- {% set has_recommendations = false %}
1023
-
1024
- {% if completeness_score.section_scores.component_model_card|default(0) < completeness_score.max_scores.component_model_card|default(100) %}
1025
- {% set has_recommendations = true %}
1026
- <li>
1027
- <strong>Enhance Model Card</strong> (+{{ ((completeness_score.max_scores.component_model_card|default(100) - completeness_score.section_scores.component_model_card|default(0)) * 0.3)|round(1) }} points):
1028
- <ul>
1029
- {% if "modelCard.modelParameters" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.modelParameters"] != "βœ”" %}
1030
- <li>Add model parameters section with architecture, size, and training details</li>
1031
- {% endif %}
1032
- {% if "modelCard.quantitativeAnalysis" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.quantitativeAnalysis"] != "βœ”" %}
1033
- <li>Add quantitative analysis with performance metrics</li>
1034
- {% endif %}
1035
- {% if "modelCard.considerations" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.considerations"] != "βœ”" %}
1036
- <li>Add ethical considerations, limitations, and tradeoffs</li>
1037
- {% endif %}
1038
- </ul>
1039
- </li>
1040
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1041
 
1042
- {% if completeness_score.section_scores.component_basic|default(0) < completeness_score.max_scores.component_basic|default(100) %}
1043
- {% set has_recommendations = true %}
1044
- <li>
1045
- <strong>Complete Basic Information</strong> (+{{ ((completeness_score.max_scores.component_basic|default(100) - completeness_score.section_scores.component_basic|default(0)) * 0.2)|round(1) }} points):
1046
- <ul>
1047
- {% if "component.description" not in completeness_score.field_checklist or completeness_score.field_checklist["component.description"] != "βœ”" %}
1048
- <li>Add a detailed description of the model (at least 20 characters)</li>
1049
- {% endif %}
1050
- {% if "component.purl" not in completeness_score.field_checklist or completeness_score.field_checklist["component.purl"] != "βœ”" %}
1051
- <li>Add a valid PURL in the format pkg:huggingface/[owner]/[name]@[version]</li>
1052
- {% endif %}
1053
- {% if "component.licenses" not in completeness_score.field_checklist or completeness_score.field_checklist["component.licenses"] != "βœ”" %}
1054
- <li>Add licensing information</li>
1055
- {% endif %}
1056
- </ul>
1057
- </li>
1058
- {% endif %}
1059
 
1060
- {% if not has_recommendations %}
1061
- <li>Your AI SBOM is already well-documented. Great job!</li>
 
 
 
1062
  {% endif %}
1063
- </ol>
1064
  </div>
1065
- {% endif %}
1066
  </div>
1067
 
1068
  {{ download_script|safe if download_script else '' }}
 
1
+ !DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
  <title>AI SBOM Generated</title>
6
  <style>
7
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
8
+ .container { margin: 0 20px; }
9
+
10
+ /* Header styling */
11
+ .header {
12
+ background-color: #f8f9fa;
13
+ padding: 15px 20px;
14
+ border-bottom: 1px solid #e9ecef;
15
+ display: flex;
16
+ align-items: center;
17
+ margin-bottom: 20px;
18
+ }
19
+ .header img {
20
+ height: 40px;
21
+ margin-right: 15px;
22
+ }
23
+ .header h1 {
24
+ margin: 0;
25
+ font-size: 24px;
26
+ color: #333;
27
+ }
28
+
29
  table { border-collapse: collapse; width: 60%; margin-top: 15px; }
30
  th, td { border: 1px solid #ddd; padding: 8px; }
31
  th { background-color: #f4f4f4; }
32
+
33
  /* Fixed color styling for field checklist items */
34
+ .check-mark { color: #27ae60; } /* Green color for check marks */
35
+ .x-mark { color: #e74c3c; } /* Red color for x marks */
36
+ .field-name { color: #000; } /* Black color for field names */
37
+ .field-stars { color: #000; } /* Black color for importance stars */
38
+
39
  .improvement { color: #2c3e50; background-color: #ecf0f1; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
40
  .improvement-value { color: #27ae60; font-weight: bold; }
41
  .ai-badge { background-color: #3498db; color: white; padding: 3px 8px; border-radius: 3px; font-size: 0.8em; margin-left: 10px; }
 
152
  line-height: 20px;
153
  color: white;
154
  font-size: 12px;
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: center;
158
  }
159
  .progress-excellent {
160
  background-color: #4CAF50; /* Green */
 
192
  color: white;
193
  font-size: 0.8em;
194
  margin-left: 5px;
195
+ background-color: transparent; /* Make background transparent */
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
  .total-score-container {
198
  display: flex;
 
206
  }
207
  .total-progress {
208
  flex: 1;
 
209
  }
210
 
211
  /* New styles for improved user understanding */
 
382
  margin-top: 0;
383
  color: #e65100;
384
  }
385
+
386
+ /* New section for score calculation explanation */
387
+ .score-calculation {
388
+ margin-top: 30px;
389
+ padding: 15px;
390
+ background-color: #f5f5f5;
391
+ border-radius: 5px;
392
+ }
393
+ .score-calculation h3 {
394
+ margin-top: 0;
395
+ color: #333;
396
+ border-bottom: 1px solid #ddd;
397
+ padding-bottom: 10px;
398
+ margin-bottom: 15px;
399
+ }
400
+ .calculation-section {
401
+ margin-bottom: 20px;
402
+ }
403
  </style>
404
  </head>
405
  <body>
406
+ <!-- Header with logo and title -->
407
+ <div class="header">
408
+ <img src="https://huggingface.co/spaces/aetheris-ai/aibom-generator/blob/main/templates/images/AetherisAI(logo).png" alt="Aetheris AI Logo">
409
+ <h1>AI SBOM Generator</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  </div>
411
 
412
+ <div class="container">
413
+ <a href="/">Generate another AI SBOM</a>
414
+ <h2>AI SBOM Generated for {{ model_id }}</h2>
415
+
416
+ <div class="download-section">
417
+ <p>Download generated AI SBOM in CycloneDX format <button onclick="downloadJSON()">Download JSON</button></p>
418
+ </div>
419
 
420
+ {% if enhancement_report and enhancement_report.ai_enhanced %}
421
+ <div class="improvement">
422
+ <h3>AI Enhancement Results</h3>
423
+ <p>This AI SBOM was enhanced using <strong>{{ enhancement_report.ai_model|default('AI Model') }}</strong></p>
424
+ <p>Original Score: {{ enhancement_report.original_score.total_score|default(0)|round(1) }}/100</p>
425
+ <p>Enhanced Score: {{ enhancement_report.final_score.total_score|default(0)|round(1) }}/100</p>
426
+ <p>Improvement: <span class="improvement-value">+{{ enhancement_report.improvement|default(0)|round(1) }} points</span></p>
427
+ </div>
428
+ {% endif %}
429
+
430
+ <!-- Human-friendly AI SBOM Viewer -->
431
+ <div class="note-box">
432
+ <p><strong>Note:</strong> This page displays the AI SBOM in a human-friendly format for easier readability.
433
+ The downloaded JSON file follows the standard CycloneDX format required for interoperability with other tools.</p>
434
+ </div>
435
+
436
+ <div class="aibom-tabs">
437
+ <div class="aibom-tab active" onclick="switchTab('human-view')">Human-Friendly View</div>
438
+ <div class="aibom-tab" onclick="switchTab('json-view')">JSON View</div>
439
+ <div class="aibom-tab" onclick="switchTab('field-checklist')">Field Checklist</div>
440
+ <div class="aibom-tab" onclick="switchTab('score-view')">Score Report</div>
441
+ </div>
 
 
 
 
 
 
442
 
443
+ <div id="human-view" class="tab-content active">
444
+ <div class="aibom-viewer">
445
+ <!-- Key Information Section -->
446
+ <div class="aibom-section key-info">
447
+ <h4>Key Information</h4>
 
448
  <div class="aibom-property">
449
+ <div class="property-name">Model Name:</div>
450
+ <div class="property-value">{{ aibom.components[0].name if aibom.components and aibom.components[0].name else 'Not specified' }}</div>
 
 
 
 
 
 
 
 
451
  </div>
 
 
 
452
  <div class="aibom-property">
453
+ <div class="property-name">Type:</div>
454
+ <div class="property-value">{{ aibom.components[0].type if aibom.components and aibom.components[0].type else 'Not specified' }}</div>
 
 
 
 
 
 
455
  </div>
 
 
 
456
  <div class="aibom-property">
457
+ <div class="property-name">Version:</div>
458
+ <div class="property-value">{{ aibom.components[0].version if aibom.components and aibom.components[0].version else 'Not specified' }}</div>
 
 
 
 
 
 
 
 
 
 
459
  </div>
 
 
 
 
 
 
 
 
 
 
 
460
  <div class="aibom-property">
461
+ <div class="property-name">PURL:</div>
462
+ <div class="property-value">{{ aibom.components[0].purl if aibom.components and aibom.components[0].purl else 'Not specified' }}</div>
 
 
 
 
 
 
 
 
463
  </div>
464
+ {% if aibom.components and aibom.components[0].description %}
 
 
465
  <div class="aibom-property">
466
+ <div class="property-name">Description:</div>
467
+ <div class="property-value">{{ aibom.components[0].description }}</div>
468
  </div>
469
  {% endif %}
470
  </div>
 
 
471
 
472
+ <!-- Model Card Section -->
473
+ {% if aibom.components and aibom.components[0].modelCard %}
474
+ <div class="aibom-section">
475
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Model Card</h4>
476
+ <div class="collapsible-content">
477
+ {% if aibom.components[0].modelCard.modelParameters %}
478
+ <div class="aibom-property">
479
+ <div class="property-name">Model Parameters:</div>
480
+ <div class="property-value">
481
+ {% if aibom.components[0].modelCard.modelParameters.properties %}
482
+ {% for prop in aibom.components[0].modelCard.modelParameters.properties %}
483
+ <div><strong>{{ prop.name }}:</strong> {{ prop.value }}</div>
484
+ {% endfor %}
485
+ {% elif aibom.components[0].modelCard.modelParameters.description %}
486
+ {{ aibom.components[0].modelCard.modelParameters.description }}
487
+ {% endif %}
488
+ </div>
 
 
489
  </div>
490
+ {% endif %}
491
+
492
+ {% if aibom.components[0].modelCard.quantitativeAnalysis %}
493
+ <div class="aibom-property">
494
+ <div class="property-name">Performance Metrics:</div>
495
+ <div class="property-value">
496
+ {% if aibom.components[0].modelCard.quantitativeAnalysis.performanceMetrics %}
497
+ {% for metric in aibom.components[0].modelCard.quantitativeAnalysis.performanceMetrics %}
498
+ <div><strong>{{ metric.type if metric.type else 'Metric' }}:</strong> {{ metric.value if metric.value else 'Not specified' }}</div>
499
+ {% endfor %}
500
+ {% endif %}
501
+ </div>
502
+ </div>
503
+ {% endif %}
504
+
505
+ {% if aibom.components[0].modelCard.considerations %}
506
+ <div class="aibom-property">
507
+ <div class="property-name">Considerations:</div>
508
+ <div class="property-value">
509
+ {% if aibom.components[0].modelCard.considerations.ethicalConsiderations %}
510
+ <div><strong>Ethical Considerations:</strong> {{ aibom.components[0].modelCard.considerations.ethicalConsiderations }}</div>
511
+ {% endif %}
512
+ {% if aibom.components[0].modelCard.considerations.limitations %}
513
+ <div><strong>Limitations:</strong> {{ aibom.components[0].modelCard.considerations.limitations }}</div>
514
+ {% endif %}
515
+ {% if aibom.components[0].modelCard.considerations.tradeoffs %}
516
+ <div><strong>Tradeoffs:</strong> {{ aibom.components[0].modelCard.considerations.tradeoffs }}</div>
517
+ {% endif %}
518
+ </div>
519
+ </div>
520
+ {% endif %}
521
  </div>
 
 
 
 
 
 
 
 
522
  </div>
523
+ {% endif %}
 
524
 
525
+ <!-- Training Data Section -->
526
+ {% if aibom.components and aibom.components[0].trainingData %}
527
+ <div class="aibom-section">
528
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Training Data</h4>
529
+ <div class="collapsible-content">
530
+ {% if aibom.components[0].trainingData.datasets %}
531
+ <div class="aibom-property">
532
+ <div class="property-name">Datasets:</div>
533
+ <div class="property-value">
534
+ {% for dataset in aibom.components[0].trainingData.datasets %}
535
+ <div>
536
+ <strong>{{ dataset.name if dataset.name else 'Dataset' }}:</strong>
537
+ {% if dataset.description %} {{ dataset.description }}{% endif %}
538
+ {% if dataset.url %} <a href="{{ dataset.url }}" target="_blank">Link</a>{% endif %}
539
+ </div>
540
+ {% endfor %}
541
+ </div>
542
  </div>
543
+ {% endif %}
544
+
545
+ {% if aibom.components[0].trainingData.preprocessing %}
546
+ <div class="aibom-property">
547
+ <div class="property-name">Preprocessing:</div>
548
+ <div class="property-value">{{ aibom.components[0].trainingData.preprocessing }}</div>
 
 
 
 
 
 
 
 
549
  </div>
550
+ {% endif %}
551
  </div>
 
552
  </div>
553
+ {% endif %}
 
554
 
555
+ <!-- Training Process Section -->
556
+ {% if aibom.components and aibom.components[0].trainingProcess %}
557
+ <div class="aibom-section">
558
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Training Process</h4>
559
+ <div class="collapsible-content">
560
+ {% if aibom.components[0].trainingProcess.trainingMethod %}
561
+ <div class="aibom-property">
562
+ <div class="property-name">Training Method:</div>
563
+ <div class="property-value">{{ aibom.components[0].trainingProcess.trainingMethod }}</div>
564
+ </div>
565
+ {% endif %}
566
+
567
+ {% if aibom.components[0].trainingProcess.hyperparameters %}
568
+ <div class="aibom-property">
569
+ <div class="property-name">Hyperparameters:</div>
570
+ <div class="property-value">
571
+ {% for param in aibom.components[0].trainingProcess.hyperparameters %}
572
+ <div><strong>{{ param.name }}:</strong> {{ param.value }}</div>
573
+ {% endfor %}
574
+ </div>
575
+ </div>
576
+ {% endif %}
577
+
578
+ {% if aibom.components[0].trainingProcess.computeInfrastructure %}
579
+ <div class="aibom-property">
580
+ <div class="property-name">Compute Infrastructure:</div>
581
+ <div class="property-value">{{ aibom.components[0].trainingProcess.computeInfrastructure }}</div>
582
+ </div>
583
+ {% endif %}
584
  </div>
 
585
  </div>
586
+ {% endif %}
 
587
 
588
+ <!-- Evaluation Section -->
589
+ {% if aibom.components and aibom.components[0].evaluation %}
590
+ <div class="aibom-section">
591
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Evaluation</h4>
592
+ <div class="collapsible-content">
593
+ {% if aibom.components[0].evaluation.metrics %}
594
+ <div class="aibom-property">
595
+ <div class="property-name">Metrics:</div>
596
+ <div class="property-value">
597
+ {% for metric in aibom.components[0].evaluation.metrics %}
598
+ <div><strong>{{ metric.name }}:</strong> {{ metric.value }}</div>
599
+ {% endfor %}
600
+ </div>
601
+ </div>
602
+ {% endif %}
603
+
604
+ {% if aibom.components[0].evaluation.datasets %}
605
+ <div class="aibom-property">
606
+ <div class="property-name">Evaluation Datasets:</div>
607
+ <div class="property-value">
608
+ {% for dataset in aibom.components[0].evaluation.datasets %}
609
+ <div>
610
+ <strong>{{ dataset.name if dataset.name else 'Dataset' }}:</strong>
611
+ {% if dataset.description %} {{ dataset.description }}{% endif %}
612
+ {% if dataset.url %} <a href="{{ dataset.url }}" target="_blank">Link</a>{% endif %}
613
+ </div>
614
+ {% endfor %}
615
+ </div>
616
  </div>
617
+ {% endif %}
618
  </div>
 
619
  </div>
620
+ {% endif %}
621
+
622
+ <!-- Usage Section -->
623
+ {% if aibom.components and aibom.components[0].usage %}
624
+ <div class="aibom-section">
625
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Usage</h4>
626
+ <div class="collapsible-content">
627
+ {% if aibom.components[0].usage.intendedUse %}
628
+ <div class="aibom-property">
629
+ <div class="property-name">Intended Use:</div>
630
+ <div class="property-value">{{ aibom.components[0].usage.intendedUse }}</div>
631
+ </div>
632
+ {% endif %}
633
+
634
+ {% if aibom.components[0].usage.outOfScopeUses %}
635
+ <div class="aibom-property">
636
+ <div class="property-name">Out of Scope Uses:</div>
637
+ <div class="property-value">{{ aibom.components[0].usage.outOfScopeUses }}</div>
638
+ </div>
639
+ {% endif %}
640
+
641
+ {% if aibom.components[0].usage.guidelines %}
642
+ <div class="aibom-property">
643
+ <div class="property-name">Usage Guidelines:</div>
644
+ <div class="property-value">{{ aibom.components[0].usage.guidelines }}</div>
645
  </div>
646
+ {% endif %}
647
  </div>
648
+ </div>
649
+ {% endif %}
650
+
651
+ <!-- Licenses Section -->
652
+ {% if aibom.components and aibom.components[0].licenses %}
653
+ <div class="aibom-section">
654
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Licenses</h4>
655
+ <div class="collapsible-content">
656
+ {% for license in aibom.components[0].licenses %}
657
+ <div class="aibom-property">
658
+ <div class="property-name">License:</div>
659
+ <div class="property-value">
660
+ <strong>{{ license.name }}</strong>
661
+ {% if license.url %} <a href="{{ license.url }}" target="_blank">Link</a>{% endif %}
662
+ </div>
663
  </div>
664
+ {% endfor %}
665
  </div>
666
+ </div>
667
+ {% endif %}
668
+
669
+ <!-- Metadata Section -->
670
+ {% if aibom.metadata %}
671
+ <div class="aibom-section">
672
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">Metadata</h4>
673
+ <div class="collapsible-content">
674
+ {% if aibom.metadata.timestamp %}
675
+ <div class="aibom-property">
676
+ <div class="property-name">Timestamp:</div>
677
+ <div class="property-value">{{ aibom.metadata.timestamp }}</div>
678
+ </div>
679
+ {% endif %}
680
+
681
+ {% if aibom.metadata.tools %}
682
+ <div class="aibom-property">
683
+ <div class="property-name">Tools:</div>
684
+ <div class="property-value">
685
+ {% for tool in aibom.metadata.tools %}
686
+ <div>{{ tool.name }} {% if tool.version %}({{ tool.version }}){% endif %}</div>
687
+ {% endfor %}
688
+ </div>
689
+ </div>
690
+ {% endif %}
691
+
692
+ {% if aibom.metadata.authors %}
693
+ <div class="aibom-property">
694
+ <div class="property-name">Authors:</div>
695
+ <div class="property-value">
696
+ {% for author in aibom.metadata.authors %}
697
+ <div>{{ author.name }} {% if author.email %}({{ author.email }}){% endif %}</div>
698
+ {% endfor %}
699
+ </div>
700
  </div>
701
+ {% endif %}
702
+
703
+ {% if aibom.metadata.properties %}
704
+ <div class="aibom-property">
705
+ <div class="property-name">Properties:</div>
706
+ <div class="property-value">
707
+ {% for prop in aibom.metadata.properties %}
708
+ <div><strong>{{ prop.name }}:</strong> {{ prop.value }}</div>
709
+ {% endfor %}
710
+ </div>
711
+ </div>
712
+ {% endif %}
713
  </div>
 
714
  </div>
715
+ {% endif %}
 
716
 
717
+ <!-- External References Section -->
718
+ {% if aibom.components and aibom.components[0].externalReferences %}
719
+ <div class="aibom-section">
720
+ <h4 class="collapsible" onclick="toggleCollapsible(this)">External References</h4>
721
+ <div class="collapsible-content">
722
+ {% for ref in aibom.components[0].externalReferences %}
723
+ <div class="aibom-property">
724
+ <div class="property-name">{{ ref.type|title if ref.type else 'Reference' }}:</div>
725
+ <div class="property-value">
726
+ <a href="{{ ref.url }}" target="_blank">{{ ref.url }}</a>
727
+ {% if ref.comment %}<div>{{ ref.comment }}</div>{% endif %}
728
+ </div>
729
  </div>
730
+ {% endfor %}
731
  </div>
 
732
  </div>
733
+ {% endif %}
734
  </div>
 
 
 
 
 
 
 
735
  </div>
 
736
 
737
+ <div id="json-view" class="tab-content">
738
+ <div class="json-view">
739
+ <pre>{{ aibom | tojson(indent=2) }}</pre>
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  </div>
741
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
742
 
743
+ <div id="field-checklist" class="tab-content">
744
+ <h3>Field Checklist</h3>
 
 
 
 
 
 
 
 
 
 
745
 
746
+ <!-- Field Tier Legend -->
747
+ <div class="tier-legend">
748
+ <div class="tier-legend-item">
749
+ <span class="field-tier tier-critical"></span>
750
+ <span>Critical</span>
751
+ </div>
752
+ <div class="tier-legend-item">
753
+ <span class="field-tier tier-important"></span>
754
+ <span>Important</span>
755
+ </div>
756
+ <div class="tier-legend-item">
757
+ <span class="field-tier tier-supplementary"></span>
758
+ <span>Supplementary</span>
759
+ </div>
760
+ </div>
761
+
762
+ {% if completeness_score and completeness_score.field_checklist %}
763
+ <ul>
764
+ {% for field, status in completeness_score.field_checklist.items() %}
765
+ {% if "βœ”" in status %}
766
+ <li class="present">
767
+ <span class="check-mark">{{ status }}</span>
768
+ <span class="field-name">{{ field }}</span>
769
+ {% if completeness_score.field_tiers and field in completeness_score.field_tiers %}
770
+ <span class="field-tier tier-{{ completeness_score.field_tiers[field] }}"></span>
771
+ {% endif %}
772
+ </li>
773
+ {% else %}
774
+ <li class="missing">
775
+ <span class="x-mark">{{ status }}</span>
776
+ <span class="field-name">{{ field }}</span>
777
+ {% if completeness_score.field_tiers and field in completeness_score.field_tiers %}
778
+ <span class="field-tier tier-{{ completeness_score.field_tiers[field] }}"></span>
779
+ {% endif %}
780
+
781
+ {% if field == "component.description" %}
782
+ <span class="importance-indicator high-importance field-stars">β˜…β˜…β˜…</span>
783
+ <span class="tooltip">(?)
784
+ <span class="tooltiptext">A detailed description of the model is essential for users to understand its purpose and capabilities. Add a description that is at least 20 characters long.</span>
785
+ </span>
786
+ {% elif field == "component.purl" %}
787
+ <span class="importance-indicator high-importance field-stars">β˜…β˜…β˜…</span>
788
+ <span class="tooltip">(?)
789
+ <span class="tooltiptext">Package URL (PURL) is critical for uniquely identifying the model. It should follow the format pkg:huggingface/[owner]/[name]@[version].</span>
790
+ </span>
791
+ {% elif field == "modelCard.modelParameters" %}
792
+ <span class="importance-indicator high-importance field-stars">β˜…β˜…β˜…</span>
793
+ <span class="tooltip">(?)
794
+ <span class="tooltiptext">Model parameters provide essential technical details about the model architecture, training, and capabilities.</span>
795
+ </span>
796
+ {% elif field == "modelCard.considerations" %}
797
+ <span class="importance-indicator medium-importance field-stars">β˜…β˜…</span>
798
+ <span class="tooltip">(?)
799
+ <span class="tooltiptext">Considerations section should include ethical considerations, limitations, and risks associated with the model.</span>
800
+ </span>
801
+ {% elif field == "externalReferences" %}
802
+ <span class="importance-indicator medium-importance field-stars">β˜…β˜…</span>
803
+ <span class="tooltip">(?)
804
+ <span class="tooltiptext">External references provide links to additional resources like model cards, repositories, and datasets.</span>
805
+ </span>
806
+ {% else %}
807
+ <span class="importance-indicator low-importance field-stars">β˜…</span>
808
+ <span class="tooltip">(?)
809
+ <span class="tooltiptext">This field contributes to the completeness of your AI SBOM.</span>
810
+ </span>
811
+ {% endif %}
812
+ </li>
813
+ {% endif %}
814
+ {% endfor %}
815
+ </ul>
816
+ {% else %}
817
+ <p>Field checklist information is not available for this AI SBOM.</p>
818
  {% endif %}
819
  </div>
820
+
821
+ <div id="score-view" class="tab-content">
822
+ <h3>AI SBOM Completeness Score</h3>
823
+
824
+ <!-- Completeness Profile Section -->
825
+ {% if completeness_score and completeness_score.completeness_profile %}
826
+ <div class="completeness-profile">
827
+ <h4>Completeness Profile:
828
+ <span class="profile-badge profile-{{ completeness_score.completeness_profile.name|default('incomplete')|lower }}">
829
+ {{ completeness_score.completeness_profile.name|default('Incomplete') }}
830
+ </span>
831
+ </h4>
832
+ <p>{{ completeness_score.completeness_profile.description|default('This AI SBOM needs improvement to meet transparency requirements.') }}</p>
833
+
834
+ {% if completeness_score.completeness_profile.next_level %}
835
+ <p><strong>Next level:</strong> {{ completeness_score.completeness_profile.next_level.name }}
836
+ ({{ completeness_score.completeness_profile.next_level.missing_fields_count }} fields to add)</p>
 
 
 
 
 
 
837
  {% endif %}
838
+ </div>
 
 
 
 
 
 
 
839
  {% elif enhancement_report %}
840
+ <div class="completeness-profile">
841
+ <h4>Completeness Profile:
842
+ {% set score = enhancement_report.final_score.total_score|default(0) %}
843
+ {% if score >= 80 %}
844
+ <span class="profile-badge profile-advanced">Advanced</span>
845
+ {% elif score >= 60 %}
846
+ <span class="profile-badge profile-standard">Standard</span>
847
+ {% elif score >= 40 %}
848
+ <span class="profile-badge profile-basic">Basic</span>
 
 
849
  {% else %}
850
+ <span class="profile-badge profile-incomplete">Incomplete</span>
851
  {% endif %}
852
+ </h4>
853
+ <p>
854
+ {% if score >= 80 %}
855
+ This AI SBOM provides comprehensive information about the model, including detailed training data, process, evaluation metrics, and usage guidelines. It meets advanced transparency requirements.
856
+ {% elif score >= 60 %}
857
+ This AI SBOM provides good information about the model, covering most key aspects of its development and usage. It meets standard transparency requirements.
858
+ {% elif score >= 40 %}
859
+ This AI SBOM provides basic information about the model but lacks detail in several areas. It meets minimal transparency requirements.
860
+ {% else %}
861
+ This AI SBOM is incomplete and missing critical information. It does not meet basic transparency requirements.
 
 
 
862
  {% endif %}
863
+ </p>
864
+ </div>
865
+ {% endif %}
866
+
867
+ <!-- Total Score with Progress Bar -->
868
+ <div class="total-score-container">
869
+ {% if completeness_score %}
870
+ <div class="total-score">{{ completeness_score.total_score|default(0)|round(1) }}/100</div>
871
+ {% elif enhancement_report %}
872
+ <div class="total-score">{{ enhancement_report.final_score.total_score|default(0)|round(1) }}/100</div>
873
+ {% else %}
874
+ <div class="total-score">0/100</div>
875
+ {% endif %}
876
+
877
+ <div class="total-progress">
878
+ <div class="progress-container">
879
+ {% if completeness_score %}
880
+ {% set score_percent = (completeness_score.total_score|default(0) / 100) * 100 %}
881
+ {% elif enhancement_report %}
882
+ {% set score_percent = (enhancement_report.final_score.total_score|default(0) / 100) * 100 %}
883
+ {% else %}
884
+ {% set score_percent = 0 %}
885
+ {% endif %}
886
+
887
+ {% set score_class = 'progress-poor' %}
888
+ {% set score_label = 'Poor' %}
889
+
890
+ {% if score_percent >= 90 %}
891
+ {% set score_class = 'progress-excellent' %}
892
+ {% set score_label = 'Excellent' %}
893
+ {% elif score_percent >= 70 %}
894
+ {% set score_class = 'progress-good' %}
895
+ {% set score_label = 'Good' %}
896
+ {% elif score_percent >= 50 %}
897
+ {% set score_class = 'progress-fair' %}
898
+ {% set score_label = 'Fair' %}
899
+ {% endif %}
900
+
901
+ <div class="progress-bar {{ score_class }}" style="width: {{ score_percent }}%">
902
+ {{ score_percent|int }}% <span class="score-label label-{{ score_class|replace('progress-', '') }}">{{ score_label }}</span>
903
+ </div>
904
  </div>
905
  </div>
906
+
907
+ {% if completeness_score and completeness_score.validation_penalty %}
908
+ <div style="margin-left: 15px; color: #f44336;">{{ completeness_score.validation_penalty }}</div>
909
+ {% endif %}
910
  </div>
911
 
912
+ <!-- Validation Penalty Explanation -->
913
  {% if completeness_score and completeness_score.validation_penalty %}
914
+ <div class="validation-penalty-info">
915
+ <h4>About the Validation Penalty</h4>
916
+ <p>Your score includes a penalty because the AIBOM has schema validation issues. These are structural problems that don't comply with the CycloneDX specification requirements.</p>
917
+ <p><strong>How to fix this:</strong> Look at the "Fix Validation Issues" section in the recommendations below. Fixing these issues will remove the penalty and improve your overall score.</p>
918
+ </div>
919
  {% endif %}
920
+
921
+ <!-- Scoring Rubric -->
922
+ <div class="scoring-rubric">
923
+ <h4>Scoring Rubric</h4>
924
+ <p>The AI SBOM completeness score is calculated based on the following criteria:</p>
925
+ <table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926
  <tr>
927
+ <th>Category</th>
928
+ <th>Weight</th>
929
+ <th>Description</th>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
930
  </tr>
931
+ <tr>
932
+ <td>Basic Information</td>
933
+ <td>20%</td>
934
+ <td>Model name, type, version, and description</td>
935
+ </tr>
936
+ <tr>
937
+ <td>Training Data</td>
938
+ <td>25%</td>
939
+ <td>Datasets used for training and preprocessing steps</td>
940
+ </tr>
941
+ <tr>
942
+ <td>Training Process</td>
943
+ <td>20%</td>
944
+ <td>Training method, hyperparameters, and compute infrastructure</td>
945
+ </tr>
946
+ <tr>
947
+ <td>Evaluation</td>
948
+ <td>15%</td>
949
+ <td>Evaluation metrics and datasets</td>
950
+ </tr>
951
+ <tr>
952
+ <td>Usage & Licensing</td>
953
+ <td>20%</td>
954
+ <td>Intended use, out-of-scope uses, and licensing information</td>
955
+ </tr>
956
+ </table>
957
+ <p>Each category is scored based on the presence and quality of relevant fields. The final score is a weighted average of all categories.</p>
958
+ </div>
959
+
960
+ <!-- Section Scores with Progress Bars and Tooltips -->
961
+ {% if completeness_score and completeness_score.section_scores %}
962
+ <table class="score-table">
963
+ <thead>
964
+ <tr>
965
+ <th>Section</th>
966
+ <th>Score</th>
967
+ <th>Weight</th>
968
+ <th>Progress</th>
969
+ </tr>
970
+ </thead>
971
+ <tbody>
972
+ {% set weights = {'required_fields': 20, 'metadata': 20, 'component_basic': 20, 'component_model_card': 30, 'external_references': 10} %}
973
+ {% set tooltips = {
974
+ 'required_fields': 'Basic SBOM fields required by the CycloneDX specification: bomFormat, specVersion, serialNumber, and version.',
975
+ 'metadata': 'Information about the AI SBOM itself: timestamp, tools used to generate it, authors, and component metadata.',
976
+ 'component_basic': 'Basic information about the AI model: type, name, bom-ref, PURL, description, and licenses.',
977
+ 'component_model_card': 'Detailed information about the model: parameters, quantitative analysis, and ethical considerations.',
978
+ 'external_references': 'Links to external resources like model cards, repositories, and datasets.'
979
+ } %}
980
+ {% set display_names = {
981
+ 'required_fields': 'Required Fields',
982
+ 'metadata': 'Metadata',
983
+ 'component_basic': 'Component Basic',
984
+ 'component_model_card': 'Model Card',
985
+ 'external_references': 'External References'
986
+ } %}
987
+ {% for section, score in completeness_score.section_scores.items() %}
988
+ <tr>
989
+ <td>
990
+ {{ display_names[section]|default(section) }}
991
+ <span class="tooltip">(?)
992
+ <span class="tooltiptext">{{ tooltips[section]|default('Section score') }}</span>
993
+ </span>
994
+ </td>
995
+ <td>{{ score|default(0)|round(1) }}/{{ completeness_score.max_scores[section]|default(100) }}</td>
996
+ <td>{{ weights[section]|default(0) }}%</td>
997
+ <td style="width: 50%;">
998
+ <div class="progress-container">
999
+ {% set percent = (score|default(0) / completeness_score.max_scores[section]|default(100)) * 100 %}
1000
+ {% set class = 'progress-poor' %}
1001
+
1002
+ {% if percent >= 90 %}
1003
+ {% set class = 'progress-excellent' %}
1004
+ {% elif percent >= 70 %}
1005
+ {% set class = 'progress-good' %}
1006
+ {% elif percent >= 50 %}
1007
+ {% set class = 'progress-fair' %}
1008
+ {% endif %}
1009
+
1010
+ <div class="progress-bar {{ class }}" style="width: {{ percent }}%">
1011
+ {{ percent|int }}%
1012
+ </div>
1013
+ </div>
1014
+ </td>
1015
+ </tr>
1016
+ {% endfor %}
1017
+ </tbody>
1018
+ </table>
1019
+ {% endif %}
1020
+
1021
+ <!-- Missing Fields Highlighting -->
1022
+ {% if completeness_score and completeness_score.field_checklist %}
1023
+ <div class="missing-fields">
1024
+ <h4>Critical Missing Fields</h4>
1025
+ <p>The following fields are missing or incomplete and have the biggest impact on your score:</p>
1026
+ <ul>
1027
+ {% set missing_critical = [] %}
1028
+ {% for field, status in completeness_score.field_checklist.items() %}
1029
+ {% if status != "βœ”" %}
1030
+ {% if completeness_score.field_tiers and field in completeness_score.field_tiers and completeness_score.field_tiers[field] == 'critical' %}
1031
+ {% set _ = missing_critical.append(field) %}
1032
+ <li>
1033
+ <strong>{{ field }}</strong>
1034
+ <span class="field-tier tier-critical"></span>
1035
+ {% if field == "component.description" %}
1036
+ - Add a detailed description of the model (at least 20 characters)
1037
+ {% elif field == "component.purl" %}
1038
+ - Add a valid PURL in the format pkg:huggingface/[owner]/[name]@[version]
1039
+ {% elif field == "modelCard.modelParameters" %}
1040
+ - Add model parameters section with architecture, size, and training details
1041
+ {% elif field == "buildTime" %}
1042
+ - Add build time information (when the model was built)
1043
+ {% elif field == "releaseTime" %}
1044
+ - Add release time information (when the model was released)
1045
+ {% elif field == "primaryPurpose" %}
1046
+ - Add primary purpose information (what the model is designed for)
1047
+ {% else %}
1048
+ - This field is required for comprehensive documentation
1049
+ {% endif %}
1050
+ </li>
1051
+ {% endif %}
1052
  {% endif %}
1053
+ {% endfor %}
1054
+ {% if missing_critical|length == 0 %}
1055
+ <li>No critical fields are missing. Great job!</li>
1056
  {% endif %}
1057
+ </ul>
1058
+ </div>
1059
+ {% endif %}
1060
+
1061
+ <!-- Actionable Recommendations -->
1062
+ {% if completeness_score %}
1063
+ <div class="recommendations">
1064
+ <h4>Recommendations to Improve Your Score</h4>
1065
+ <ol>
1066
+ {% set has_recommendations = false %}
1067
+
1068
+ {% if completeness_score.section_scores.component_model_card|default(0) < completeness_score.max_scores.component_model_card|default(100) %}
1069
+ {% set has_recommendations = true %}
1070
+ <li>
1071
+ <strong>Enhance Model Card</strong> (+{{ ((completeness_score.max_scores.component_model_card|default(100) - completeness_score.section_scores.component_model_card|default(0)) * 0.3)|round(1) }} points):
1072
+ <ul>
1073
+ {% if "modelCard.modelParameters" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.modelParameters"] != "βœ”" %}
1074
+ <li>Add model parameters section with architecture, size, and training details</li>
1075
+ {% endif %}
1076
+ {% if "modelCard.quantitativeAnalysis" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.quantitativeAnalysis"] != "βœ”" %}
1077
+ <li>Add quantitative analysis with performance metrics</li>
1078
+ {% endif %}
1079
+ {% if "modelCard.considerations" not in completeness_score.field_checklist or completeness_score.field_checklist["modelCard.considerations"] != "βœ”" %}
1080
+ <li>Add ethical considerations, limitations, and tradeoffs</li>
1081
+ {% endif %}
1082
+ </ul>
1083
+ </li>
1084
+ {% endif %}
1085
+
1086
+ {% if completeness_score.section_scores.component_basic|default(0) < completeness_score.max_scores.component_basic|default(100) %}
1087
+ {% set has_recommendations = true %}
1088
+ <li>
1089
+ <strong>Complete Basic Information</strong> (+{{ ((completeness_score.max_scores.component_basic|default(100) - completeness_score.section_scores.component_basic|default(0)) * 0.2)|round(1) }} points):
1090
+ <ul>
1091
+ {% if "component.description" not in completeness_score.field_checklist or completeness_score.field_checklist["component.description"] != "βœ”" %}
1092
+ <li>Add a detailed description of the model (at least 20 characters)</li>
1093
+ {% endif %}
1094
+ {% if "component.purl" not in completeness_score.field_checklist or completeness_score.field_checklist["component.purl"] != "βœ”" %}
1095
+ <li>Add a valid PURL in the format pkg:huggingface/[owner]/[name]@[version]</li>
1096
+ {% endif %}
1097
+ {% if "component.licenses" not in completeness_score.field_checklist or completeness_score.field_checklist["component.licenses"] != "βœ”" %}
1098
+ <li>Add licensing information</li>
1099
+ {% endif %}
1100
+ </ul>
1101
+ </li>
1102
+ {% endif %}
1103
+
1104
+ {% if not has_recommendations %}
1105
+ <li>Your AI SBOM is already well-documented. Great job!</li>
1106
+ {% endif %}
1107
+ </ol>
1108
+ </div>
1109
+ {% endif %}
1110
+
1111
+ <!-- Score Calculation Explanation -->
1112
+ <div class="score-calculation">
1113
+ <h3>How Your Score Is Calculated</h3>
1114
+ <div class="calculation-section">
1115
+ <h4>Completeness Score ({{ completeness_score.total_score|default(enhancement_report.final_score.total_score|default(0))|round(1) }}/100)</h4>
1116
+ <p>Your AI SBOM completeness score measures how thoroughly you've documented your AI model. The score is calculated by evaluating the presence and quality of key information across several categories.</p>
1117
+ <p>Each field in your AI SBOM contributes to the overall score, with critical fields having the highest weight. Missing critical fields significantly impact your score.</p>
1118
+ </div>
1119
 
1120
+ <div class="calculation-section">
1121
+ <h4>Field Importance Tiers</h4>
1122
+ <ul>
1123
+ <li><strong>Critical fields (β˜…β˜…β˜…):</strong> Essential information that all AI SBOMs should include (e.g., model description, PURL, model parameters)</li>
1124
+ <li><strong>Important fields (β˜…β˜…):</strong> Valuable information that enhances transparency (e.g., ethical considerations, external references)</li>
1125
+ <li><strong>Supplementary fields (β˜…):</strong> Additional information that provides more context about the model</li>
1126
+ </ul>
1127
+ </div>
 
 
 
 
 
 
 
 
 
1128
 
1129
+ {% if enhancement_report and enhancement_report.ai_enhanced %}
1130
+ <div class="calculation-section">
1131
+ <h4>AI Enhancement</h4>
1132
+ <p>The AI enhancement process improved your original SBOM by adding missing information and enriching existing fields. The improvement of {{ enhancement_report.improvement|default(0)|round(1) }} points represents the difference between your original score ({{ enhancement_report.original_score.total_score|default(0)|round(1) }}) and your enhanced score ({{ enhancement_report.final_score.total_score|default(0)|round(1) }}).</p>
1133
+ </div>
1134
  {% endif %}
1135
+ </div>
1136
  </div>
 
1137
  </div>
1138
 
1139
  {{ download_script|safe if download_script else '' }}