import { PluginConfig, MemoryFile } from './types.js';
import { R as RolloutSummaryInput, M as MaterializeResult } from './codex-materialize-CQlLTzke.js';
import { LoggerBackend } from './logger.js';
import { SemanticConsolidationLlmOperator } from './consolidation-operator.js';

/**
 * memory-extension-host/types.ts — Types for third-party memory extension discovery.
 *
 * Memory extensions live under ~/.remnic/memory_extensions/<slug>/ and provide
 * instructions.md (required), schema.json (optional), and examples/*.md (optional).
 */
interface DiscoveredExtension {
    readonly name: string;
    readonly root: string;
    readonly instructionsPath: string;
    readonly instructions: string;
    readonly schema?: ExtensionSchema;
    readonly examplesPaths: string[];
}
interface ExtensionSchema {
    readonly memoryTypes?: Array<"fact" | "preference" | "procedure" | "reference">;
    readonly groupingHints?: string[];
    readonly version?: string;
}

/**
 * memory-extension-host/host-discovery.ts — Discover third-party memory extensions.
 *
 * Scans a root directory (typically ~/.remnic/memory_extensions/) for valid
 * extension subdirectories. Each extension must contain an instructions.md.
 * The discovery process is read-only and NEVER reads or executes files under
 * any extension's scripts/ directory.
 */

/** Total token budget for all discovered extension instructions combined. */
declare const REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT = 5000;
/**
 * Discover all valid memory extensions under the given root directory.
 *
 * Returns extensions sorted by name. Skips entries with warnings when:
 * - The slug is invalid (not lowercase alphanumeric + hyphens, or > 64 chars)
 * - instructions.md is missing
 * - schema.json is malformed (extension still returned but schema is undefined)
 *
 * NEVER reads files under any extension's scripts/ directory.
 */
declare function discoverMemoryExtensions(root: string, log: Pick<LoggerBackend, "warn" | "debug">): Promise<DiscoveredExtension[]>;
/**
 * Resolve the memory extensions root directory from config.
 * If memoryExtensionsRoot is empty, derive from memoryDir by going up to
 * the Remnic home dir and appending memory_extensions.
 *
 * Moved here from semantic-consolidation.ts (#428 Finding 3) because this
 * is a generic config-to-path resolver with no consolidation logic.
 */
declare function resolveExtensionsRoot(config: PluginConfig): string;

/**
 * semantic-consolidation.ts — Semantic Consolidation Engine
 *
 * Finds clusters of semantically similar memories using token overlap,
 * synthesizes canonical versions via LLM, and archives the originals.
 * Reduces memory store bloat while preserving all unique information.
 */

interface ConsolidationCluster {
    category: string;
    memories: MemoryFile[];
    overlapScore: number;
    canonicalContent?: string;
}
interface SemanticConsolidationResult {
    clustersFound: number;
    memoriesConsolidated: number;
    memoriesArchived: number;
    errors: number;
    clusters: ConsolidationCluster[];
}
/**
 * Find clusters of semantically similar memories using token overlap.
 */
declare function findSimilarClusters(memories: MemoryFile[], config: {
    threshold: number;
    minClusterSize: number;
    excludeCategories: string[];
    maxPerRun: number;
}): ConsolidationCluster[];
/**
 * Build the LLM prompt for synthesizing a canonical memory from a cluster.
 */
declare function buildConsolidationPrompt(cluster: ConsolidationCluster): string;
/**
 * Parse the LLM response to extract the canonical content.
 */
declare function parseConsolidationResponse(response: string): string;
/**
 * Structured result from an operator-aware consolidation LLM call.
 *
 * - `operator` — the consolidation operator the LLM chose for this cluster.
 *   Falls back to the heuristic default when the LLM omits or returns an
 *   unknown value (the parser never surfaces an invalid operator; see
 *   `parseOperatorAwareConsolidationResponse`).
 * - `output` — the canonical content (same format the legacy prompt
 *   returns).  Callers persist this as the body of the new memory.
 */
interface OperatorAwareConsolidationResult {
    operator: SemanticConsolidationLlmOperator;
    output: string;
}
/**
 * Heuristic default operator for a cluster.  Used as the fallback when the
 * LLM does not return a parseable operator, and as the "floor" decision in
 * `parseOperatorAwareConsolidationResponse`.
 *
 * Current heuristic (kept deliberately conservative — PR 3 only):
 *
 *   - Two or more memories being collapsed into one canonical blob is a
 *     MERGE by definition.  This is the path the current clustering
 *     pipeline exercises.
 *   - A cluster of size 1 that still reaches consolidation (future path,
 *     e.g. supersession of a single older memory by a newer value) is an
 *     UPDATE.
 *   - SPLIT is never selected by the heuristic because the current write
 *     path emits exactly one canonical memory per cluster.  The prompt
 *     reserves SPLIT for future cluster shapes where the LLM decides one
 *     logical source actually encodes several distinct facts — at which
 *     point the orchestrator would need to write multiple outputs.
 */
declare function chooseConsolidationOperator(cluster: ConsolidationCluster): SemanticConsolidationLlmOperator;
/**
 * Build the operator-aware LLM prompt.  The LLM is asked to return a
 * JSON object `{ "operator": <split|merge|update>, "output": <content> }`.
 *
 * The prompt is additive: it still asks for a single canonical blob under
 * `output`, so the upstream write path does not change.  Future expansions
 * (SPLIT emitting multiple outputs) are explicitly documented as
 * out-of-scope for the parser — `parseOperatorAwareConsolidationResponse`
 * collapses any SPLIT response into a single canonical output for now.
 */
declare function buildOperatorAwareConsolidationPrompt(cluster: ConsolidationCluster): string;
/**
 * Parse an operator-aware consolidation response.
 *
 * Contract:
 *   - Accepts strict JSON `{ "operator": "...", "output": "..." }`.
 *   - Tolerates a JSON payload wrapped in a fenced code block (```json ...```).
 *   - Falls back to the heuristic operator when the JSON is malformed,
 *     the `operator` field is missing / unknown, or the raw response is
 *     a plain blob with no JSON at all.  This keeps PR 3 backwards
 *     compatible with older models that ignore the JSON instruction.
 *   - Never throws.  A missing / empty `output` field falls back to the
 *     trimmed raw response so the caller still writes something rather
 *     than dropping the cluster.
 */
declare function parseOperatorAwareConsolidationResponse(response: string, cluster: ConsolidationCluster): OperatorAwareConsolidationResult;
/**
 * Discover extensions and build the block to append to a consolidation prompt.
 * Returns "" when extensions are disabled or none are found.
 */
declare function buildExtensionsBlockForConsolidation(config: PluginConfig): Promise<string>;
/**
 * Optional post-consolidation hook — materializes the namespace into Codex's
 * native memory layout when the consolidation run finishes. Kept here (rather
 * than in orchestrator.ts) so #378 doesn't conflict with Wave 1 edits.
 *
 * Safe to call regardless of config state: honors `codexMaterializeMemories`
 * and `codexMaterializeOnConsolidation` and silently becomes a no-op when
 * either is disabled.
 */
declare function materializeAfterSemanticConsolidation(options: {
    config: PluginConfig;
    namespace?: string;
    memories?: MemoryFile[];
    memoryDir?: string;
    codexHome?: string;
    rolloutSummaries?: RolloutSummaryInput[];
    now?: Date;
}): Promise<MaterializeResult | null>;

export { type ConsolidationCluster as C, type DiscoveredExtension as D, type ExtensionSchema as E, type OperatorAwareConsolidationResult as O, REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT as R, type SemanticConsolidationResult as S, buildConsolidationPrompt as a, buildExtensionsBlockForConsolidation as b, buildOperatorAwareConsolidationPrompt as c, discoverMemoryExtensions as d, chooseConsolidationOperator as e, findSimilarClusters as f, parseOperatorAwareConsolidationResponse as g, materializeAfterSemanticConsolidation as m, parseConsolidationResponse as p, resolveExtensionsRoot as r };
