jacquardSnapshot

← snapshot

1868 bytes
"use client";

/**
 * Asking a model whether two proven folds are the same change.
 *
 * Advisory only. Everything the judge says passes through `applyJudgement`,
 * which refuses invented ids, single-member clusters, and any attempt to
 * absorb a file that stands alone. See `lib/diff-group.ts`.
 *
 * Requests are cached on the exact payload, so looking at the same diff twice
 * cannot produce two different groupings.
 */

import { judgePayload, type DiffGroup, type Judgement } from "./diff-group.ts";

let configured: Promise<boolean> | null = null;

/** One quiet probe, rather than a failing POST per diff. */
export function judgeConfigured(): Promise<boolean> {
  configured ??= fetch("/judge")
    .then((r) => (r.ok ? r.json() : { configured: false }))
    .then((j: { configured?: boolean }) => Boolean(j.configured))
    .catch(() => false);
  return configured;
}

const cache = new Map<string, Promise<Judgement | null>>();

/**
 * Returns the judge's view, or null when it is unavailable or has nothing to
 * say. Never throws: a grouping that cannot be judged is still a grouping.
 */
export function judgeGroups(groups: DiffGroup[]): Promise<Judgement | null> {
  if (groups.length < 2) return Promise.resolve(null);
  const payload = judgePayload(groups);
  const key = JSON.stringify(payload);
  const hit = cache.get(key);
  if (hit) return hit;

  const run = judgeConfigured()
    .then((ok) => {
      if (!ok) return null;
      return fetch("/judge", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ groups: payload }),
      })
        .then((r) => (r.ok ? r.json() : null))
        .then((j: Judgement | null) =>
          j && Array.isArray(j.clusters) && j.clusters.length > 0 ? j : null,
        );
    })
    .catch(() => null);

  cache.set(key, run);
  return run;
}