/** * Pure presentation + gating for task-scoped context injection * (changes: add-task-scoped-context-injection, * fix-inject-relevance-gate-keyword-mode). * * Extracted from `orient-inject.ts` so it can be reused by hosts that must NOT * load the analyzer in-process — notably the Pi extension, which orients through * a warm daemon over RPC (decision abee8e3e). Everything here is pure and * deterministic; its runtime dependencies are dependency-light pure helpers. * Keep it that way — importing the analyzer (`handleOrient`) or config I/O here would drag the * analyzer back into the Pi host process the daemon split exists to keep lean. * * The block is framed as facts-not-coercion (Epistemic Lease, decision 8e95746d) * and capped by a token budget so it can never dominate the context it economizes. */ import { type ServedContentProvenance } from '../../core/services/served-content.js'; import type { ContextInjectionConfig } from '../../types/index.js'; /** Injection settings with every documented default applied. */ export interface ResolvedInjectionConfig { mode: 'off' | 'task-scoped'; tokenBudget: number; relevanceMinMatches: number; relevanceMinFanIn: number; relevanceMinScore: number; } /** Documented defaults — used when `.openlore/config.json` omits `contextInjection`. */ export declare const INJECTION_DEFAULTS: ResolvedInjectionConfig; /** Smallest budget that can carry the framed task and a factual stale-index line. */ export declare const MIN_INJECTION_TOKEN_BUDGET = 68; /** * The single pointer line emitted whenever a full block is not warranted * (weak match, no graph, error, or empty prompt). Informational, not coercive. */ export declare const POINTER_LINE: string; /** Apply documented defaults over a partial config block. */ export declare function resolveInjectionConfig(ci: ContextInjectionConfig | undefined): ResolvedInjectionConfig; interface OrientFn { name?: string; filePath?: string; score?: number; fanIn?: number; fanOut?: number; isHub?: boolean; provenance?: ServedContentProvenance; } interface CallNeighbour { name?: string; filePath?: string; } interface OrientCallPath { function?: string; callers?: CallNeighbour[]; callees?: CallNeighbour[]; } /** Compact house-style summary for the touched region (change: add-codebase-style-fingerprint). */ interface RegionStyle { scope?: string; language?: string; communityId?: string; dominantIdioms?: string[]; } export interface LeanOrientResult { task?: string; searchMode?: string; error?: string; relevantFiles?: string[]; relevantFunctions?: OrientFn[]; specDomains?: Array; callPaths?: OrientCallPath[]; suggestedTools?: string[]; regionStyle?: RegionStyle; parseHealth?: string; indexStaleness?: { staleFiles?: string[]; note?: string; repairScheduled?: true; }; servedContentProvenance?: { relevantFiles?: ServedContentProvenance; relevantFunctions?: ServedContentProvenance; specDomains?: ServedContentProvenance; callPaths?: ServedContentProvenance; }; } export interface RelevanceGateEvaluation { passes: boolean; passedCriteria: string[]; failedCriteria: string[]; } /** * Deterministic orientation-relevance gate. Returns true when the task has a * substantial, structurally-connected match in the graph — the case where a * full briefing pays for itself. Otherwise the caller emits the pointer line, * keeping injection out of the small/familiar/shallow arena the scorecard shows * OpenLore should not tax. * * Signals are read off the lean orient result itself (no new analysis pass). * An exact identifier mention passes directly. Otherwise the matched-function * count must reach relevanceMinMatches and one of structural centrality, a * bounded hybrid score, or scale-free keyword rank evidence must pass. * * BM25-fallback scores live on an unbounded, corpus-relative scale, so the score * path is disabled there. Exact identifier and rank evidence make keyword mode * decidable without letting an arbitrary BM25 magnitude wave everything through. */ export declare function evaluateRelevanceGate(result: LeanOrientResult, cfg: ResolvedInjectionConfig): RelevanceGateEvaluation; export declare function passesRelevanceGate(result: LeanOrientResult, cfg: ResolvedInjectionConfig): boolean; /** * Render the full injection block from a lean orient result, hard-capped to the * token budget. The header, framing, and task line are mandatory (a small fixed * floor that is always present so an injected block is unambiguously attributed * and ignorable); detail lines are added in priority order (functions → files → * call neighbours → specs → tools) only while they fit, so the data — regardless * of match size — never pushes the block over budget. * * Every interpolated field is defensively filtered: although `handleOrient` * declares its name/file fields as required strings, a partial/forward-incompat * result must never leak a literal `undefined`, `[object Object]`, or a stray * leading comma into the agent's context. */ export declare function renderInjectionBlock(result: LeanOrientResult, cfg: ResolvedInjectionConfig): string; export {}; //# sourceMappingURL=orient-inject-render.d.ts.map