harn-stdlib 0.10.117

Embedded Harn standard library source catalog
Documentation
/**
 * Catalog-declared completion-review policy.
 *
 * Split out of `judge.harn`, which sits against the 1500-line source cap.
 * These three are a self-contained unit: read the model's `completion_review`
 * row, and decide whether a `light` row may skip the LLM confirmation. They
 * touch no judge state, so the judge imports them rather than owning them.
 */
import { JudgeConfig } from "std/agent/options_types"

pub type CompletionReview = {scrutiny: string, max_judge_calls?: int, evidence?: unknown}

/** The completion-judge fields consumed when resolving its invocation cap. */
pub type CompletionReviewJudgePolicy = {max_judge_calls?: int}

type CompletionJudgeConfig = bool | JudgeConfig | nil

fn __agent_completion_review(llm: HarnessLlm, opts: dict) -> CompletionReview {
  const model = trim(to_string(opts?.model ?? ""))
  if model == "" {
    return {scrutiny: "standard"}
  }
  const info = try {
    llm.model_info(model)
  }
  if is_err(info) {
    return {scrutiny: "standard"}
  }
  const review = unwrap(info)?.catalog?.completion_review
  if type_of(review) != "dict" {
    return {scrutiny: "standard"}
  }
  return {
    scrutiny: to_string(review?.scrutiny ?? "standard"),
    max_judge_calls: review?.max_judge_calls,
    evidence: review?.evidence,
  }
}

/**
 * agent_completion_review.
 *
 * Catalog `completion_review` for the session model, or `{scrutiny: "standard"}`
 * when the row omits it.
 *
 * @effects: []
 * @errors: []
 * @api_stability: experimental
 * @example: agent_completion_review(harness.llm, opts)
 */
pub fn agent_completion_review(llm: HarnessLlm, opts: dict) -> CompletionReview {
  return __agent_completion_review(llm, opts)
}

/**
 * Whether light completion-review may skip the LLM confirmation.
 *
 * The catalog row must opt into `light`. The deterministic gate must already
 * have passed, and the turn must carry a terminal sentinel. Absent any of
 * those, the judge still runs.
 *
 * @effects: []
 * @errors: []
 * @api_stability: experimental
 * @example: agent_completion_review_should_skip_llm(review, evaluation, payload)
 */
pub fn agent_completion_review_should_skip_llm(
  review: CompletionReview,
  evaluation: dict,
  payload: dict,
) -> bool {
  if review.scrutiny != "light" {
    return false
  }
  if !(evaluation?.invoked?.deterministic ?? false) {
    return false
  }
  if evaluation?.verdict?.vetoed ?? false {
    return false
  }
  return to_string(payload?.stop_reason ?? "") == "sentinel"
}

// Conservative default cap on how many times the completion-judge LLM may
// veto a proposed completion within one session. Each veto is a paid model
// call plus an injected feedback message, so a weak model that never satisfies
// the judge can otherwise burn calls up to `max_verify_attempts` (default 20)
// with no structured signal. Callers raise it via
// `verify_completion_judge.max_invocations`, or disable the cap entirely with
// `0`.
pub const COMPLETION_JUDGE_DEFAULT_CAP = 5

fn __verify_completion_judge_cap(
  judge_cfg: CompletionJudgeConfig,
  review: CompletionReviewJudgePolicy = {},
) -> int? {
  const configured = if type_of(judge_cfg) == "dict" {
    judge_cfg?.max_invocations
  } else {
    nil
  }
  const catalog_cap = review.max_judge_calls
  const cap = configured ?? catalog_cap ?? COMPLETION_JUDGE_DEFAULT_CAP
  if cap <= 0 {
    return nil
  }
  return cap
}

/**
 * Resolve the optional top-level cap for `done_judge`. Unlike
 * `done_judge.cadence.max_invocations`, this is a terminal veto-loop cap: the
 * judge may fire up to the cap, then the loop finalizes instead of silently
 * continuing until the iteration budget expires.
 */
fn __done_judge_cap(judge_cfg: CompletionJudgeConfig) -> int? {
  if type_of(judge_cfg) != "dict" {
    return nil
  }
  const cap = judge_cfg?.max_invocations
  if cap == nil || cap <= 0 {
    return nil
  }
  return cap
}

/**
 * agent_done_judge_cap.
 *
 * Resolved terminal veto cap for a `done_judge` config. Returns nil when the
 * cap is not configured or is disabled with 0.
 *
 * @effects: []
 * @errors: []
 * @api_stability: experimental
 * @example: agent_done_judge_cap(opts?.done_judge)
 */
pub fn agent_done_judge_cap(judge_cfg: CompletionJudgeConfig) -> int? {
  return __done_judge_cap(judge_cfg)
}

/**
 * agent_verify_completion_judge_cap.
 *
 * Resolved completion-judge veto cap for a `verify_completion_judge` config,
 * for surfacing in run records. Returns nil when the cap is disabled.
 *
 * @effects: []
 * @errors: []
 * @api_stability: experimental
 * An explicit `max_invocations` wins. Otherwise the catalog
 * `completion_review.max_judge_calls` applies, then the default of 5.
 *
 * @example: agent_verify_completion_judge_cap(opts?.verify_completion_judge, review)
 */
pub fn agent_verify_completion_judge_cap(
  judge_cfg: CompletionJudgeConfig,
  review: CompletionReviewJudgePolicy = {},
) -> int? {
  return __verify_completion_judge_cap(judge_cfg, review)
}