import type { ProfileId } from '../profiles/types.js'; import { type ContextualSpecialization } from './contextual-specialization.js'; /** A profile matched against a request, with its keyword-overlap score and the hits. */ export type ProfileMatch = { profileId: ProfileId; score: number; matched: string[]; }; export type ProfileRoutingDecision = { status: 'selected' | 'ambiguous' | 'no-match' | 'unavailable'; source: 'inference' | 'explicit-override' | 'neutral'; ranked: ProfileMatch[]; selectedProfile: ProfileId | null; suggestedRequiredProfiles: ProfileId[]; suggestedOptionalProfiles: ProfileId[]; acceptedProfiles: ProfileId[]; candidateSpecializations?: ContextualSpecialization[]; specializationQuestions?: string[]; overrideRationale?: string; }; /** * Infer which profiles a request belongs to, ranked by keyword overlap (highest * first). Returns `[]` when nothing matches — the caller should then fall back to a * default (e.g. `developer`) or ask. Ties are broken by ProfileId for stable output. * * Pure and deterministic: same request → same ranking, no I/O, no LLM. */ export declare function inferProfilesFromRequest(request: string): ProfileMatch[]; /** * Convenience: the single best profile for a request, or `null` when nothing * matches. When several tie for top score, the alphabetically-first id wins * (deterministic); callers needing all candidates should use {@link inferProfilesFromRequest}. */ export declare function inferPrimaryProfile(request: string): ProfileId | null; /** Resolve inference against configured profiles without changing that configuration. */ export declare function resolveProfileRouting(input: { request: string; configuredProfiles: readonly string[]; explicitProfiles?: readonly string[]; overrideRationale?: string; }): ProfileRoutingDecision;