/** * max-repeat grader — fails when an agent repeats the same action in a loop. * * This is a post-hoc, trajectory-level grader: it runs after a run completes and * walks the collected {@link Trajectory.events}. It does not intervene during * execution — stopping a live loop is the executor's job (`max_turns`). This is * loop *detection* for scoring and regression coverage. * * The matching logic: * 1. Filter events to the watched tool(s). * 2. Group matching calls by **model step** (a Vally turn), and * within a step dedupe the per-call fingerprints (parallel identical calls in * one step count as one, not a loop). * 3. Find the longest complete repeated pattern with a period up to * `max_cycle_period`; an empty fingerprint never extends a pattern. * 4. Pass when the pattern occurs no more than `max` times. * * ```yaml * graders: * - type: max-repeat * config: * max: 3 # fail when an action or pattern repeats more than 3 times * max_cycle_period: 2 # optionally detect A B A B cycles * match: observation # "observation" (default) | "name" | "name-args" * tools: ["^bash$"] # optional regex patterns; default watches all tools * ``` */ import type { Grader, GraderInput, GraderMetadata, GraderResult } from "../types.js"; import { type MatchMode } from "../helpers.js"; export type { MatchMode } from "../helpers.js"; export interface MaxRepeatConfig { /** * Maximum allowed complete occurrences of a repeated action or pattern. The * grader fails above `max`. Required, integer >= 1 — authors must opt in to * a threshold. */ max?: number; /** * Longest repeating pattern period to detect. Defaults to `1`, preserving * consecutive-only detection. Integer 1–10 (inclusive). */ max_cycle_period?: number; /** * What counts as "the same" repeated action. Defaults to `"observation"`. * - `observation`: the tool's result/output content. * - `name`: the tool name only. * - `name-args`: the tool name plus its arguments (deep equal). */ match?: MatchMode; /** * Regex patterns (unanchored, like the tool-calls grader) selecting which tools * to watch. When omitted, all tools are watched. Use `^bash$` for an exact match. */ tools?: string[]; } export declare class MaxRepeatGrader implements Grader { metadata: GraderMetadata; /** `max-repeat max 3 bash` — the threshold and any tool filter discriminate. */ defaultName(config: Record): string; /** * max-repeat asserts the ABSENCE of excessive repetition. An empty trajectory * repeats nothing (0 occurrences <= any `max` >= 1), so the check always passes * — under the oracle baseline it is reported N/A rather than flagged as * trivially passing. */ assertsAbsence(): boolean; grade(input: GraderInput): Promise; } //# sourceMappingURL=max-repeat-grader.d.ts.map