import { runTeamDiscussion, type Runner, type ToolSpec } from "@sema-agent/core"; import type { Metrics } from "../observability/metrics.js"; import type { Logger } from "../observability/logger.js"; type TeamFn = typeof runTeamDiscussion; /** * Code-review council (Option C+, layers L1 + L3) packaged as ONE tool, so the run model is unchanged * and the orchestration is **code-driven** (deterministic — we don't rely on the model to follow a * multi-step orchestration prompt, which live runs showed it doesn't do reliably). * * - L1 (gather): one isolated, read-only-repo-tooled subagent PER differential lens, run in PARALLEL. * - L3 (arbitrate): a neutral arbiter grounds/dedups/buckets/ranks. It does not add findings. * - L2 (peer debate over findings + dispute verification with member tools) is the next layer. * * Research basis (core's design): tooled differential exploration is the main source of real bugs; * grounding + bucketing kill "imagined requirements" and stop a design preference being filed as a bug. */ interface Lens { name: string; brief: string; } /** * Caller-tunable lens COUNT (OA request) — a structured cost/coverage dial, sibling of `@model` / `council` / * `debate`. The deployment owns WHICH lenses (the `LENSES` order = the priority: security/correctness first = * the bug-finders); the caller only picks HOW MANY. Clamp to [1, LENSES.length]; absent / non-numeric = ALL * (the current default → zero regression). A named subset is deliberately NOT supported (it would force a * published, maintained lens vocabulary contract; the count is the verifiable knob a "light/standard" UI needs). */ export declare function pickLenses(count?: number): readonly Lens[]; /** Caller-settable debate rounds: a FINITE integer clamped to [1,3]; non-number / NaN / ±Infinity = undefined * (→ the council's default of 1). Mirrors `pickLenses`'s `Number.isFinite` guard — the previous inline clamp let * `NaN` through (`typeof NaN === "number"`, `Math.min(3, NaN) === NaN`), corrupting the cost metric (council). */ export declare function clampRounds(rounds: unknown): number | undefined; export interface CouncilToolOptions { /** Aggregate the council's (otherwise invisible) sub-task cost into metrics. */ metrics?: Metrics; logger?: Logger; /** L1+L2+L3: add a peer-team debate (tool-grounded) before arbitration. Default L1+L3 only. */ debate?: boolean; /** Debate rounds (when `debate`). Default 1. */ rounds?: number; /** Caller-chosen lens COUNT (cost/coverage dial). Clamped to [1, LENSES.length]; absent = all lenses. */ lensCount?: number; /** Injectable for tests; defaults to core's runTeamDiscussion. */ teamFn?: TeamFn; } /** Build the `run_council` tool. The lead calls it once; it returns the final arbitrated review. */ export declare function createCouncilTool(subRunner: Runner, repoTools: ToolSpec[], objective: string, opts?: CouncilToolOptions): ToolSpec; export {}; //# sourceMappingURL=code-review-council.d.ts.map