| 455 |
455 |
fam_rows = await fetch_all(conn, "select id, slug, canonical_name, organization_id from entities where entity_type = 'model_family' and merged_into is null") |
| 456 |
456 |
families: dict[str, dict[str, Any]] = {f["canonical_name"].lower(): f for f in fam_rows} # one family per label |
| 457 |
457 |
slugs_taken = {r["slug"] for r in await fetch_all(conn, "select slug from entities")} |
|
458 |
+ |
|
459 |
+ def family_slug(label: str) -> str: |
|
460 |
+ """slugify(label); on collision with any other entity (the model `gpt-5.5` itself) → `<slug>-family`, then numbered.""" |
|
461 |
+ base = slugify(label) |
|
462 |
+ for c in [base, f"{base}-family", *(f"{base}-family-{n}" for n in range(2, 20))]: |
|
463 |
+ if c not in slugs_taken: |
|
464 |
+ return c |
|
465 |
+ return f"{base}-family-{new_id('model_family')[-6:].lower()}" |
|
466 |
+ |
|
467 |
+ # re-slug families created under the former rule (organisation prefix on collision: `qwen-qwen3`, `mistral-mistral`) |
|
468 |
+ for fam in fam_rows: |
|
469 |
+ base = slugify(fam["canonical_name"]) |
|
470 |
+ if fam["slug"] in (base, f"{base}-family") or not fam["slug"].endswith(base): |
|
471 |
+ continue |
|
472 |
+ slugs_taken.discard(fam["slug"]) |
|
473 |
+ new_slug = family_slug(fam["canonical_name"]) |
|
474 |
+ slugs_taken.add(new_slug) |
|
475 |
+ rep.bump("families_reslugged") |
|
476 |
+ rep.example(f"family slug {fam['slug']} → {new_slug}") |
|
477 |
+ if apply: |
|
478 |
+ await execute(conn, "update entities set slug = :s, updated_at = now() where id = :id", s=new_slug, id=fam["id"]) |
|
479 |
+ await execute(conn, "insert into entity_aliases (entity_id, alias, alias_norm, kind) values (:e, :a, :n, 'former_name') on conflict (entity_id, alias_norm) do nothing", |
|
480 |
+ e=fam["id"], a=fam["slug"], n=normalize_alias(fam["slug"])) |
|
481 |
+ fam["slug"] = new_slug |
| 458 |
482 |
for m in models: |
| 459 |
483 |
label = family_release_hint(m["canonical_name"]) |
| 460 |
484 |
if not label: |
| 465 |
489 |
org_id = next((org_by_key[k] for k in official if k in org_by_key), None) or m["organization_id"] |
| 466 |
490 |
fam = families.get(label.lower()) |
| 467 |
491 |
if fam is None: |
| 468 |
|
− # slug = slugify(label); on collision with any other entity (the model "gpt-5.5" itself) prefix with the organisation slug, then "family-" |
| 469 |
|
− base_slug = slugify(label) |
| 470 |
|
− org_slug = next((o["slug"] for o in orgs if o["id"] == org_id), None) |
| 471 |
|
− candidates = [base_slug] + ([f"{org_slug}-{base_slug}"] if org_slug else []) + [f"family-{base_slug}"] + [f"family-{base_slug}-{n}" for n in range(2, 20)] |
| 472 |
|
− slug = next(c for c in candidates if c not in slugs_taken) |
|
492 |
+ slug = family_slug(label) |
| 473 |
493 |
rep.bump("families_created") |
| 474 |
494 |
rep.example(f"family '{label}' ({slug}) root={root}") |
| 475 |
495 |
fam = {"id": new_id("model_family"), "slug": slug, "canonical_name": label, "organization_id": org_id, "_new": True} |
| 650 |
670 |
|
| 651 |
671 |
|
| 652 |
672 |
# ---------------------------------------------------------------------------------------------- step: results |
|
673 |
+async def _rehome_results(conn: AsyncConnection, rep: StepReport, apply: bool, scope: set[str] | None) -> None: |
|
674 |
+ """Move results from a benchmark *family head* to the registry's variant entity when the row says which variant it measured: |
|
675 |
+ (a) config.variant / config.board equals (case-insensitively) the variant entity's name, an alias or its `variant` attribute; |
|
676 |
+ (b) LiveBench `category:<Name>` metrics → `livebench-<slug(Name)>` with the registry metric (`average score`), variant = Name; |
|
677 |
+ (c) aider `percent_cases_well_formed` → `aider-polyglot-well-formed`. |
|
678 |
+ Then dedupe/config keys, one-current-row and `evaluated_on` relations are recomputed for every touched model.""" |
|
679 |
+ variants = await fetch_all(conn, """select v.id, v.slug, v.canonical_name, v.attributes, r.object_id as head_id, |
|
680 |
+ (select array_agg(alias) from entity_aliases a where a.entity_id = v.id) as aliases |
|
681 |
+ from entities v join relations r on r.subject_id = v.id and r.predicate = 'variant_of' and r.valid_to is null |
|
682 |
+ where v.entity_type = 'benchmark' and v.merged_into is null""") |
|
683 |
+ if not variants: |
|
684 |
+ return |
|
685 |
+ by_slug: dict[str, dict[str, Any]] = {v["slug"]: v for v in variants} |
|
686 |
+ by_head: dict[str, list[tuple[set[str], dict[str, Any]]]] = defaultdict(list) |
|
687 |
+ for v in variants: |
|
688 |
+ keys = {v["canonical_name"].lower(), v["slug"], *(a.lower() for a in (v["aliases"] or []))} |
|
689 |
+ var_attr = (v["attributes"] or {}).get("variant") |
|
690 |
+ if isinstance(var_attr, str): |
|
691 |
+ keys.add(var_attr.lower()) |
|
692 |
+ by_head[v["head_id"]].append((keys, v)) |
|
693 |
+ heads = list(by_head) |
|
694 |
+ rows = await fetch_all(conn, """select r.id, r.model_id, r.benchmark_id, r.metric, r.config from benchmark_results r |
|
695 |
+ where r.benchmark_id = any(cast(:h as text[]))""", h=heads) |
|
696 |
+ moves: list[tuple[dict[str, Any], dict[str, Any], str | None, dict[str, Any]]] = [] |
|
697 |
+ for r in rows: |
|
698 |
+ if scope is not None and r["model_id"] not in scope: |
|
699 |
+ continue |
|
700 |
+ cfg = dict(r["config"] or {}) |
|
701 |
+ metric = r["metric"] or "" |
|
702 |
+ target: dict[str, Any] | None = None |
|
703 |
+ new_metric: str | None = None |
|
704 |
+ label = next((str(cfg[k]) for k in ("variant", "board") if isinstance(cfg.get(k), str) and cfg[k].strip()), None) |
|
705 |
+ if label: |
|
706 |
+ target = next((v for keys, v in by_head[r["benchmark_id"]] if label.lower() in keys), None) |
|
707 |
+ if target is None and metric.lower().startswith("category:"): |
|
708 |
+ name = metric.split(":", 1)[1].strip() |
|
709 |
+ cand = by_slug.get(f"livebench-{slugify(name)}") |
|
710 |
+ if cand and cand["head_id"] == r["benchmark_id"]: |
|
711 |
+ target = cand |
|
712 |
+ new_metric = (cand["attributes"] or {}).get("metric") or "average score" |
|
713 |
+ cfg["variant"] = name |
|
714 |
+ if target is None and metric == "percent_cases_well_formed": |
|
715 |
+ cand = by_slug.get("aider-polyglot-well-formed") |
|
716 |
+ if cand and cand["head_id"] == r["benchmark_id"]: |
|
717 |
+ target = cand |
|
718 |
+ if target is None: |
|
719 |
+ continue |
|
720 |
+ moves.append((r, target, new_metric, cfg)) |
|
721 |
+ if not moves: |
|
722 |
+ return |
|
723 |
+ touched: set[tuple[str, str, str]] = set() |
|
724 |
+ for r, target, new_metric, cfg in moves: |
|
725 |
+ rep.bump(f"results_rehomed:{target['slug']}") |
|
726 |
+ touched.add((r["model_id"], r["benchmark_id"], target["id"])) |
|
727 |
+ if apply: |
|
728 |
+ await execute(conn, "update benchmark_results set benchmark_id = :b, metric = coalesce(:m, metric), config = cast(:c as jsonb), variant = :v where id = :id", |
|
729 |
+ b=target["id"], m=new_metric, c=jsonb(cfg), v=bench_ontology.variant_from_config(cfg), id=r["id"]) |
|
730 |
+ if not apply: |
|
731 |
+ return |
|
732 |
+ source_id = await registry_source_id(conn) |
|
733 |
+ for model_id in sorted({m for m, _, _ in touched}): |
|
734 |
+ from aiatlas.services.merge import recompute_result_keys |
|
735 |
+ |
|
736 |
+ await recompute_result_keys(conn, model_id) |
|
737 |
+ await enforce_current_results(conn, model_id=model_id) |
|
738 |
+ for model_id, head_id, target_id in sorted(touched): |
|
739 |
+ await upsert_relation(conn, model_id, "evaluated_on", target_id, source_id=source_id) |
|
740 |
+ left = await fetch_one(conn, "select 1 from benchmark_results where model_id = :m and benchmark_id = :b and valid_to is null limit 1", m=model_id, b=head_id) |
|
741 |
+ if not left: |
|
742 |
+ await execute(conn, "update relations set valid_to = now() where subject_id = :m and predicate = 'evaluated_on' and object_id = :b and valid_to is null", |
|
743 |
+ m=model_id, b=head_id) |
|
744 |
+ rep.bump("evaluated_on_repointed") |
|
745 |
+ |
|
746 |
+ |
| 653 |
747 |
async def step_results(conn: AsyncConnection, rep: StepReport, apply: bool, *, scope: set[str] | None = None) -> None: |
|
748 |
+ await _rehome_results(conn, rep, apply, scope) |
| 654 |
749 |
rows = await fetch_all(conn, """select r.id, r.model_id, r.config, r.metric, r.unit, r.score, r.config_key, r.trust_level, r.variant, r.run_group, r.extractor, r.valid_to, |
| 655 |
750 |
r.is_current, s.key as source_key from benchmark_results r left join sources s on s.id = r.source_id""") |
| 656 |
751 |
if scope is not None: |