@claude-flow/embeddings
Version:
V3 Embedding Service - OpenAI, Transformers.js, Agentic-Flow (ONNX), Mock providers with hyperbolic embeddings, normalization, and chunking
95 lines • 4.1 kB
TypeScript
/**
* ADR-121 Phase 23 — Trend visualization + drift detection (BEYOND SOTA).
*
* Phase 22's regression check catches single-step drops well — if a
* commit drops recall@5 by 15%, CI fails. But it misses the **death
* by a thousand cuts** failure mode: every commit drops 1%, every
* check passes the 10% threshold, but cumulative drift after 30
* commits is 30%.
*
* This module ships two pieces:
* 1. `renderSparkline(values)` — zero-dep ASCII sparkline using
* the standard 8-level block-element ramp. Turns a sequence of
* metric values into a one-line trend visualization for CI
* output, PR comments, and human dashboards.
* 2. `detectDrift(values, options)` — rolling-window drift check.
* Compares the mean of the EARLIEST window to the mean of the
* LATEST window; reports the relative change. Designed to fire
* when cumulative drift exceeds the threshold even if every
* single-step delta was below the per-step threshold.
*
* Composable with Phase 22's `checkRegression`: production CI typically
* wants BOTH — single-step regression detection (catches obvious
* breaks) AND drift detection (catches slow rot).
*/
/**
* Render a sequence of numeric values as an ASCII sparkline using
* the 8-level block-element ramp: ▁▂▃▄▅▆▇█
*
* - Maps min(values) → ▁ and max(values) → █, linearly interpolated.
* - When all values are identical, renders a flat line of the
* middle character (▄) — visually distinguishable from "no data".
* - Returns the empty string for an empty input.
*/
export declare function renderSparkline(values: ReadonlyArray<number>): string;
export interface DriftDetectionOptions {
/**
* How many values to average at each end of the series. Default 3.
* The first `windowSize` values form the "early" mean; the last
* `windowSize` values form the "late" mean.
*/
readonly windowSize?: number;
/**
* Maximum allowed cumulative drift, expressed as a fractional
* change (early → late mean). Default 0.15 (15%).
*/
readonly threshold?: number;
/**
* Optimization direction. 'higher' means larger is better — drift
* fires when late < early. 'lower' means smaller is better — drift
* fires when late > early. Default 'higher'.
*/
readonly direction?: 'higher' | 'lower';
}
export interface DriftDetectionResult {
/** Number of values analyzed. */
readonly sampleCount: number;
/** Mean of the first windowSize values. */
readonly earlyMean: number;
/** Mean of the last windowSize values. */
readonly lateMean: number;
/** Absolute delta = lateMean - earlyMean. */
readonly delta: number;
/** Fractional drift = delta / |earlyMean|. */
readonly drift: number;
/** True if no drift regression was detected. */
readonly passed: boolean;
/** Human-readable reason. */
readonly reason: string;
/**
* True when we had < 2*windowSize samples and skipped the check
* (not enough data to compute distinct early and late windows).
*/
readonly skipped: boolean;
}
/**
* Compute drift between the earliest and latest windows of a numeric
* series. Returns `skipped: true` when the series is too short to
* compute distinct windows.
*/
export declare function detectDrift(values: ReadonlyArray<number>, options?: DriftDetectionOptions): DriftDetectionResult;
/**
* Produce a one-line summary of a benchmark metric's history: a
* sparkline, the latest value, and the drift verdict. Useful for
* dashboard / PR-comment output.
*/
export interface BenchmarkTrendSummary {
readonly benchmark: string;
readonly metricPath: string;
readonly sparkline: string;
readonly sampleCount: number;
readonly latestValue: number | null;
readonly drift: DriftDetectionResult;
}
export declare function summarizeBenchmarkTrend(values: ReadonlyArray<number>, benchmark: string, metricPath: string, options?: DriftDetectionOptions): BenchmarkTrendSummary;
//# sourceMappingURL=ledger-trends.d.ts.map