harn-stdlib 0.8.111

Embedded Harn standard library source catalog
Documentation
/**
 * agent/best_of_n.harn
 *
 * Generic best-of-N candidate selection with an optional pre-generation
 * spec-contract gate — the reusable "callback contract" half of an agent_loop
 * best-of-N strategy. Harn owns the advance/stop + fallthrough POLICY; the host
 * owns candidate GENERATION (including any workspace reset) and the selection
 * SIGNAL, both supplied as callbacks. A host (e.g. an eval driver) wires its own
 * candidate generator + an oracle-independent scorer in, without this module
 * knowing how candidates are produced or scored.
 *
 * Host-callback errors never hard-fail the run: a non-true/erroring
 * spec_contract_callback aborts to the single-candidate path, a failing
 * generate skips that candidate, and a nil/out-of-range/erroring
 * select_callback falls through to a deterministic candidate. Best-of-N is thus
 * a safe overlay that degrades to plain single-attempt behavior.
 */
fn __bon_clamp_int(value, lo, hi) {
  let n = if type_of(value) == "int" {
    value
  } else {
    lo
  }
  if n < lo {
    return lo
  }
  if n > hi {
    return hi
  }
  return n
}

/**
 * Run best-of-N candidate selection with an optional spec-contract gate.
 *
 * opts:
 *   k: int                            candidate count (clamped to [1, 64])
 *   generate: closure(index) -> any   REQUIRED — produce candidate `index` (0-based)
 *   select_callback: closure(candidates) -> int?  pick the winning index;
 *                                       nil/out-of-range/error -> fallthrough
 *   spec_contract_callback: closure() -> bool?  optional pre-generation gate; a
 *                                       non-true or erroring return ABORTS to the
 *                                       single-candidate path
 *   fallthrough_index: int            winner when select yields none (default: last candidate)
 *   on_candidate: closure({index, candidate}) -> nil  optional progress hook
 *
 * Returns `{reason, selected_index, candidate, candidates, contract_ok}` where
 * `reason` is one of: `selected`, `fallthrough_no_winner`, `fallthrough_contract`,
 * `no_candidates`, `no_generate`.
 *
 * @effects: []
 * @errors: []
 */
pub fn best_of_n_candidates(opts) {
  let o = if type_of(opts) == "dict" {
    opts
  } else {
    {}
  }
  let generate = o?.generate
  if generate == nil {
    return {reason: "no_generate", selected_index: nil, candidate: nil, candidates: [], contract_ok: false}
  }
  let k = __bon_clamp_int(o?.k ?? 1, 1, 64)
  let select_callback = o?.select_callback
  let spec_contract_callback = o?.spec_contract_callback
  let on_candidate = o?.on_candidate
  // Pre-generation spec-contract gate. A non-true or erroring contract aborts
  // best-of-N to a single-candidate run (never a hard failure).
  var contract_ok = true
  if spec_contract_callback != nil {
    contract_ok = false
    let cr = try {
      spec_contract_callback()
    }
    if is_ok(cr) {
      let verdict = unwrap(cr)
      // Only a boolean true proceeds; nil / non-bool / false all abort.
      contract_ok = type_of(verdict) == "bool" && verdict
    }
  }
  let target = if contract_ok {
    k
  } else {
    1
  }
  // Host-driven candidate generation; a failing candidate is simply skipped.
  var candidates = []
  var idx = 0
  while idx < target {
    let gr = try {
      generate(idx)
    }
    if is_ok(gr) {
      let cand = unwrap(gr)
      candidates = candidates.push(cand)
      if on_candidate != nil {
        let _ = try {
          on_candidate({index: idx, candidate: cand})
        }
      }
    }
    idx = idx + 1
  }
  if len(candidates) == 0 {
    return {
      reason: "no_candidates",
      selected_index: nil,
      candidate: nil,
      candidates: [],
      contract_ok: contract_ok,
    }
  }
  if !contract_ok {
    return {
      reason: "fallthrough_contract",
      selected_index: 0,
      candidate: candidates[0],
      candidates: candidates,
      contract_ok: false,
    }
  }
  if len(candidates) == 1 {
    return {
      reason: "selected",
      selected_index: 0,
      candidate: candidates[0],
      candidates: candidates,
      contract_ok: true,
    }
  }
  // Host selection signal. nil / out-of-range / error -> deterministic fallthrough.
  var winner = nil
  if select_callback != nil {
    let sr = try {
      select_callback(candidates)
    }
    if is_ok(sr) {
      let w = unwrap(sr)
      if type_of(w) == "int" && w >= 0 && w < len(candidates) {
        winner = w
      }
    }
  }
  if winner == nil {
    let fallback_idx = __bon_clamp_int(o?.fallthrough_index ?? (len(candidates) - 1), 0, len(candidates) - 1)
    return {
      reason: "fallthrough_no_winner",
      selected_index: fallback_idx,
      candidate: candidates[fallback_idx],
      candidates: candidates,
      contract_ok: true,
    }
  }
  return {
    reason: "selected",
    selected_index: winner,
    candidate: candidates[winner],
    candidates: candidates,
    contract_ok: true,
  }
}