feat(lens): pick the analysis model and slow single-review pacing

This commit is contained in:
Ishaan Jaff 2026-10-03 16:36:32 -07:00
parent e8f49b18ca
commit 53275517cb
No known key found for this signature in database
2 changed files with 20 additions and 5 deletions

View file

@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import {
analysisModel,
conclusions,
liveStats,
modelName,
@ -48,6 +49,12 @@ describe("provider from model", () => {
expect(providerOf("/weird")).toBe("");
});
it("prefers a model that names its provider over a bare alias", () => {
expect(analysisModel(["analysis", "", "cerebras/gpt-oss-120b"])).toBe("cerebras/gpt-oss-120b");
expect(analysisModel(["", "analysis"])).toBe("analysis");
expect(analysisModel([])).toBe("");
});
it("drops only the provider prefix from the model name", () => {
expect(modelName("openrouter/meta/llama")).toBe("meta/llama");
expect(modelName("analysis")).toBe("analysis");
@ -102,11 +109,11 @@ describe("conclusions", () => {
describe("playback pacing", () => {
it("slows to a full window for one review and speeds up as the backlog grows", () => {
expect(stepDuration(1)).toBe(3200);
expect(stepDuration(4)).toBe(800);
expect(stepDuration(1)).toBe(4200);
expect(stepDuration(4)).toBe(1050);
expect(stepDuration(10)).toBeLessThan(stepDuration(4));
expect(stepDuration(10_000)).toBe(140);
expect(stepDuration(0)).toBe(3200);
expect(stepDuration(0)).toBe(4200);
});
it("highlights spans one at a time, then types reasoning, then shows the verdict", () => {

View file

@ -23,7 +23,7 @@ export interface LiveStats {
elapsedSeconds: number;
}
const PACE_WINDOW_MS = 3200;
const PACE_WINDOW_MS = 4200;
const MIN_STEP_MS = 140;
const COMPACT_STEP_MS = 700;
const READ_SHARE = 0.35;
@ -69,8 +69,16 @@ export function stepDuration(backlog: number): number {
return Math.max(MIN_STEP_MS, Math.min(PACE_WINDOW_MS, Math.round(PACE_WINDOW_MS / Math.max(1, backlog))));
}
export function isCompact(duration: number): boolean {
return duration < COMPACT_STEP_MS;
}
export function analysisModel(candidates: readonly string[]): string {
return candidates.find((model) => providerOf(model)) ?? candidates.find(Boolean) ?? "";
}
export function playbackPhase(elapsed: number, duration: number, spans: number, chars: number): Phase {
if (duration < COMPACT_STEP_MS) return { span: -1, typed: chars, verdict: true };
if (isCompact(duration)) return { span: -1, typed: chars, verdict: true };
const t = Math.max(0, elapsed) / duration;
const reading = t < READ_SHARE;
const span = reading && spans > 0 ? Math.min(spans - 1, Math.floor((t / READ_SHARE) * spans)) : -1;