SPB Git forge

spb/ai-atlas

Public
41commits 1branches 0releases
4.6 MBsize
maindefault branch
12 days agolast push
HTML 77.2% TypeScript 10.5% Python 9.6% JavaScript 2.5%
6.3 KB · 97 lines tsx
Raw Blame History
1import Link from 'next/link';2import { cn } from '@/lib/cn';3import type { LicenseInfo, ModelLicence, ModelOpenness } from '@/lib/types';4import { OpennessChip, Tri } from './badges';56/*7  Openness explanation, reused by model pages and licence pages:8  "Open weights — weights downloadable under Apache-2.0; code available; training data not disclosed" built from `openness.dimensions`.9  Unknown dimensions are said to be unknown (null ≠ false).10*/1112export const OPENNESS_DIMENSIONS: { key: string; label: string; yes: string; no: string; hint: string }[] = [13  { key: 'weights_available', label: 'Weights', yes: 'weights downloadable', no: 'weights not available', hint: 'Can the model weights be downloaded (Hugging Face or an official mirror)?' },14  { key: 'source_code_available', label: 'Inference code', yes: 'inference code available', no: 'inference code not published', hint: 'Is the inference / modelling code published?' },15  { key: 'training_code_available', label: 'Training code', yes: 'training code available', no: 'training code not published', hint: 'Is the training code published?' },16  { key: 'training_data_disclosed', label: 'Training data', yes: 'training data disclosed', no: 'training data not disclosed', hint: 'Is the composition of the training data documented?' },17  { key: 'dataset_available', label: 'Dataset', yes: 'training dataset downloadable', no: 'training dataset not released', hint: 'Can the training dataset itself be downloaded?' },18  { key: 'commercial_use_allowed', label: 'Commercial use', yes: 'commercial use allowed', no: 'commercial use restricted', hint: 'Does the licence allow commercial use without a separate agreement?' },19  { key: 'redistribution_allowed', label: 'Redistribution', yes: 'redistribution allowed', no: 'redistribution restricted', hint: 'May the weights be redistributed (mirrors, bundles)?' },20  { key: 'derivatives_allowed', label: 'Derivatives', yes: 'derivatives allowed', no: 'derivatives restricted', hint: 'May fine-tunes, merges and quantisations be published?' },21];2223export const LICENCE_DIMENSIONS: { key: keyof LicenseInfo; label: string; hint: string; invert?: boolean }[] = [24  { key: 'commercial_use', label: 'Commercial use', hint: 'Use in a commercial product or service without a separate agreement.' },25  { key: 'redistribution', label: 'Redistribution', hint: 'Sharing the licensed weights or code with third parties.' },26  { key: 'derivatives', label: 'Derivatives', hint: 'Publishing fine-tunes, merges, quantisations or other modified versions.' },27  { key: 'hosting_restrictions', label: 'Hosting restrictions', hint: 'Restrictions on serving the model as a hosted API (user caps, field-of-use, competitor clauses). Yes = restrictions exist.', invert: true },28  { key: 'acceptable_use', label: 'Acceptable-use policy', hint: 'The licence attaches an acceptable-use policy / behavioural restrictions. Yes = a policy applies.', invert: true },29  { key: 'attribution', label: 'Attribution', hint: 'Attribution or notice requirements.' },30];3132/** One-line sentence from the dimensions: "weights downloadable under Apache-2.0; inference code available; training data not disclosed". */33export function opennessSentence(o: ModelOpenness, licenceLabel?: string | null): string {34  const parts: string[] = [];35  for (const dim of OPENNESS_DIMENSIONS) {36    const v = o.dimensions?.[dim.key];37    if (v === true) parts.push(dim.key === 'weights_available' && licenceLabel ? `${dim.yes} under ${licenceLabel}` : dim.yes);38    else if (v === false) parts.push(dim.no);39  }40  const unknown = OPENNESS_DIMENSIONS.filter((d) => o.dimensions?.[d.key] === null || o.dimensions?.[d.key] === undefined).length;41  let s = parts.join('; ');42  if (unknown) s += `${s ? '; ' : ''}${unknown} dimension${unknown === 1 ? '' : 's'} unknown`;43  return s;44}4546export function OpennessBlock({ openness, licence, className, compact = false }: { openness: ModelOpenness | null | undefined; licence?: ModelLicence | null; className?: string; compact?: boolean }) {47  if (!openness) return <p className={cn('text-sm text-ink-3', className)}>Openness not classified yet — no sourced evidence to place this model in the ontology.</p>;48  const lic = licence && 'key' in licence && licence.key ? (licence as LicenseInfo & { raw?: string | null }) : null;49  const licLabel = lic ? lic.key : licence && licence.raw ? licence.raw : null;50  return (51    <div className={cn('text-sm', className)} data-openness-block>52      <p className="flex flex-wrap items-center gap-2">53        <OpennessChip openness={openness.category} label={openness.label} />54        <span className="text-ink-2">— {opennessSentence(openness, licLabel)}.</span>55      </p>56      <p className="mt-1 text-xs text-ink-3">{openness.definition}</p>57      {!compact && (58        <ul className="mt-3 grid grid-cols-2 gap-px border border-rule bg-rule sm:grid-cols-4">59          {OPENNESS_DIMENSIONS.map((dim) => (60            <li key={dim.key} className="bg-canvas px-2.5 py-2">61              {/* native title tooltip: the absolute Hint bubble (18rem) widens narrow viewports from a 2-column grid */}62              <p className="cursor-help text-[11px] text-ink-3 underline decoration-dotted decoration-rule-strong underline-offset-2" title={dim.hint}>63                {dim.label}64              </p>65              <p className="mt-0.5 text-[13px]">66                <Tri v={openness.dimensions?.[dim.key]} yes="Yes" no="No" />67              </p>68            </li>69          ))}70        </ul>71      )}72      {(lic || (licence && licence.raw)) && (73        <p className="mt-3 text-xs text-ink-2">74          Licence:{' '}75          {lic ? (76            <>77              <Link href={`/licenses/${encodeURIComponent(lic.key)}`} className="link font-medium">78                {lic.label}79              </Link>{' '}80              <span className="text-ink-3">81                ({lic.category}82                {lic.spdx ? ` · SPDX ${lic.spdx}` : ''}83                {lic.raw && lic.raw !== lic.key ? ` · stated as “${lic.raw}”` : ''})84              </span>85            </>86          ) : (87            <span>88              stated as “{licence?.raw}” — <span className="text-ink-3">not mapped to a canonical licence yet{licence && 'note' in licence && licence.note ? ` (${licence.note})` : ''}</span>89            </span>90          )}91        </p>92      )}93      {openness.note && <p className="mt-1 text-[11px] text-ink-3">{openness.note}</p>}94    </div>95  );96}97