/** * Slot semantic naming + cohort detection for pattern_examples. * * The engine assigns positional slot identifiers (slot_0, slot_1, ...) by * default — fine as a stable internal key, useless as a field name to an * agent or human. This module derives a logical name from two signals: * * 1. The preceding-token captured locally by walking the template body * (cli-output-parser.ts:extractSlotsFromBody). When the token shows * a `"json_key":` or `key=` shape, the name comes straight from that * key, with high confidence. * * 2. The sample values themselves. Consecutive slots that together encode * one logical entity (UUID octets split as `$-$-$-$-$`, IPv4 octets * split as `$.$.$.$`) are merged into a single derived "cohort" with * combined cardinality over reassembled values. * * Both functions are pure — no I/O, no engine calls. They consume what * pattern-extraction.ts already exposes: * - ExtractedPattern.variables (slot -> sample values) * - ExtractedPattern.slotPrecedingTokens (slot -> preceding static text) * - ExtractedPattern.template (template body with $ markers) * * Naming is conservative on purpose. The earlier variable-concentration.ts * attempt burned on engine-emitted metadata that didn't index-align; * "confidently wrong" names are worse than slot_N. We omit `inferred_name` * entirely when no layer can justify one. */ export type NamingConfidence = 'high' | 'medium' | 'low'; export type NamingSource = 'json_key' | 'json_key_composite' | 'kv_pair' | 'kv_pair_compound' | 'noun_prefix' | 'delimiter_heuristic' | 'format_spec'; export interface SlotNameResult { name: string; confidence: NamingConfidence; source: NamingSource; } export interface SlotInput { slot: string; sampleValues: string[]; precedingToken?: string; } export interface Cohort { member_slots: string[]; inferred_name: string; naming_confidence: NamingConfidence; kind: 'uuid' | 'ipv4' | 'mac'; cardinality: number; sample_values: string[]; } /** * Derive a logical name for one slot from its preceding static text. * Returns `undefined` when no layer can justify a name — caller emits the * slot with no `inferred_name` field. Layer 4 (format_spec) is handled * upstream by extractSlotsFromBody → inferFormatSpecName; this function * is invoked for non-format-spec slots only. */ export declare function inferSlotName(precedingToken: string | undefined, _sampleValues: string[]): SlotNameResult | undefined; /** * Detect UUID + IPv4 cohorts across the slot sequence. Operates on * adjacency-ordered slots (slot_0 ... slot_N), not the cardinality-sorted * order pattern-examples uses for display. Uses the template body's * static text between slots to discriminate `$-$-$-$-$` (UUID) from * `$.$.$.$:$` (IPv4 + port) from `$$$$$` (concatenated hex, no cohort). * * When a cohort fires: * - cardinality = distinct count of REASSEMBLED values (e.g. full UUIDs), * NOT the sum of per-slot distinct counts. * - inferred_name inherits the Layer-1 JSON-key name of the first member * when available; else a generic kind name (`uuid` / `ipv4`). * * Members keep their individual slot entries — cohorts are an additional * view, not a replacement. */ export declare function detectCohorts(slots: SlotInput[], templateBody: string): Cohort[];