/**
 * Transcript-based structured memory: indexes wake cycle summaries into
 * a SQLite database with FTS5 full-text search and sqlite-vec vector
 * similarity search. Each wake cycle is summarized by an LLM after
 * completion and stored for later retrieval.
 *
 * IMPORTANT — file terminology:
 *  - "source file" (DB column `source_file`): the JSONL file that contains
 *    the raw data for a wake cycle. This is EITHER:
 *      • An engine transcript for live-indexed cycles, such as:
 *        - Claude SDK: `~/.claude/projects/<slug>/<sessionId>.jsonl`
 *        - Pi Coding Agent: `~/.visionclaw/.../pi-agent/<mode>/sessions/<sessionId>.jsonl`
 *      • A **VisionClaw runtime log** (`~/.visionclaw/profiles/<profile>/logs/YYYY-MM-DD.jsonl`)
 *        for backfill-indexed cycles.
 *    These formats differ:
 *      - Claude transcripts: `{type:"user"|"assistant", message:{...}}`
 *      - Pi Coding transcripts: `{type:"message", message:{role, content, ...}}`
 *      - VisionClaw logs: `{timestamp, level, category, message, data}`
 *
 * This module handles:
 *  - SQLite schema creation (wake_cycles + FTS5 + vec0 virtual tables)
 *  - Reading source file lines (both Claude transcripts and VisionClaw logs)
 *  - Generating summaries via Gemini Flash
 *  - Generating embeddings via Gemini Embedding
 *  - Inserting indexed records
 *  - Keyword (FTS5), semantic (vec0 KNN), and hybrid search
 *  - Retrieval of key excerpts and original source file lines
 */
import type { VisionClawConfig } from "../../config/types.js";
import type { SessionMode } from "../mailbox.js";
import { type TranscriptParserKind } from "../transcript-parsers/index.js";
export interface WakeCycleRecord {
    wake_cycle_id: string;
    session_type: string;
    timestamp_start: string;
    timestamp_end: string;
    summary: string;
    key_excerpts: string | null;
    /** Path to the source JSONL file (engine transcript or VisionClaw log). */
    source_file: string;
    start_line: number;
    end_line: number;
    embedding: Buffer | null;
    /** JSON-serialized ToolCallFact[] or NULL (legacy/unavailable). */
    tool_calls_json: string | null;
    usage_reported: number;
    trigger_type: string | null;
    trigger_channel: string | null;
    outcome: string | null;
    tool_call_count: number;
    tool_calls_truncated: number;
    reported_tool_call_count: number | null;
}
export interface SearchResult {
    wake_cycle_id: string;
    session_type: string;
    timestamp_start: string;
    timestamp_end: string;
    summary: string;
    relevance_score: number;
}
export interface IndexWakeCycleOptions {
    wakeCycleId: string;
    sessionType: SessionMode;
    /** Path to the source transcript file for this wake cycle. */
    sourceFile: string;
    /**
     * Identifies which agent engine produced `sourceFile` so the indexer can
     * pick the matching `TranscriptParser`. Defaults to `"claude"` for
     * backward compatibility with callers that only ever wrote Claude SDK
     * transcripts; new callers (Pi Coding Agent etc.) must pass an explicit
     * value or the wrong parser will be used and no summary will be generated.
     */
    sourceFormat?: TranscriptParserKind;
    startLine: number;
    endLine: number;
    timestampStart: string;
    timestampEnd: string;
    trigger: "message" | "heartbeat";
    messages: {
        channel: string;
        sender: string;
        text: string;
    }[];
    config: VisionClawConfig;
    /** Wake cycle outcome — used for usage metering. */
    outcome?: "completed" | "error" | "stopped" | "switched";
}
/**
 * Count lines in a file asynchronously via streaming.
 * Returns 0 if the file does not exist.
 */
export declare function countFileLines(filePath: string): Promise<number>;
/**
 * Read specific line range from a JSONL source file (engine transcript or
 * VisionClaw log). Lines are 1-indexed; range is [startLine, endLine)
 * (exclusive end). Handles both plain .jsonl and .jsonl.gz files via streaming.
 *
 * @param maxLines — optional cap on lines returned. When the range contains
 *   more lines than this limit, the function samples lines evenly across the
 *   range so the start, middle and end of the cycle are all represented.
 */
export declare function readSourceFileLines(filePath: string, startLine: number, endLine: number, maxLines?: number): Promise<string[]>;
/**
 * Read transcript lines for a wake cycle, searching across live and archived
 * transcript files. Used for backfill reconstruction when the original
 * source_file may have been archived due to transcript rollover.
 *
 * Search order:
 *  1. The original source_file path (live transcript)
 *  2. Date-stamped archive for the wake cycle's date
 *  3. Adjacent dates (±1 day) for timezone/boundary cases
 *
 * @param sourceFile - Original source file path from the wake cycle record.
 * @param startLine - 1-indexed start line.
 * @param endLine - 1-indexed exclusive end line.
 * @param wakeCycleTimestamp - ISO timestamp of the wake cycle's start, used
 *   to derive which date-stamped archive to search.
 */
export declare function readWakeCycleTranscriptLines(sourceFile: string, startLine: number, endLine: number, wakeCycleTimestamp: string): Promise<string[]>;
import type { ToolCallFact } from "../usage/usage-report-types.js";
/**
 * Extract tool call facts from raw Claude SDK transcript JSONL lines.
 *
 * Matches `tool_use` blocks (from assistant messages) with corresponding
 * `tool_result` blocks (from user messages) via `tool_use_id`. If a
 * tool_use has no matching result, it is closed at `cycleEndedAt` with
 * `success: false` and `errorKind: "missing_tool_result"`.
 *
 * When transcript lines carry timestamps, tool_use events outside the wake
 * cycle window are ignored. This protects backfill/live indexing from
 * over-broad transcript ranges. For untimestamped lines, `startedAt` falls
 * back to `cycleStartedAt` and `endedAt` falls back to the last seen timestamp
 * marker or cycle boundary.
 *
 * @param lines - Raw JSONL transcript lines (Claude transcript format only).
 * @param context - Cycle-level timestamps for fallback.
 */
export declare function extractToolCallsFromLines(lines: string[], context: {
    cycleStartedAt: string;
    cycleEndedAt: string;
}): {
    toolCalls: ToolCallFact[];
    toolCallCount: number;
    truncated: boolean;
    reportedToolCallCount: number | null;
};
/**
 * Parse raw JSONL lines from a Claude SDK transcript file into a condensed
 * text representation suitable for summary generation. Thin wrapper around
 * the registered Claude parser.
 */
export declare function parseTranscriptForSummary(lines: string[]): string;
/** Backward-compat wrapper around the Claude parser. */
export declare function isOnlyTrivialToolCalls(lines: string[]): boolean;
export interface SummaryResult {
    summary: string;
    key_excerpts: string[];
}
export declare function generateSummary(condensedTranscript: string, config: VisionClawConfig): Promise<SummaryResult>;
export declare function generateEmbedding(text: string, config: VisionClawConfig): Promise<Float32Array | null>;
/**
 * Index the current wake cycle's engine transcript. Called after each wake
 * cycle completes (fire-and-forget from the main loop).
 *
 * Steps:
 *  1. Read transcript lines for the wake cycle range (capped)
 *  1.5 Extract tool call facts for usage metering
 *  2. Parse and condense with the source-format-specific parser
 *  3. Call Gemini Flash to generate summary + key excerpts
 *  4. Generate embedding for the summary (best-effort)
 *  5. Store in SQLite (wake_cycles + FTS5 auto-synced via triggers)
 */
export declare function indexWakeCycle(options: IndexWakeCycleOptions): Promise<void>;
/**
 * Insert a pre-built wake cycle record into the database.
 * Used by the backfill CLI to insert records with known timestamps and IDs.
 *
 * @param record.sourceFile — path to the source JSONL file. For backfilled
 *   data this is a VisionClaw runtime log file; for live data it is a Claude
 *   SDK transcript file.
 */
export declare function insertWakeCycleRecord(record: {
    wakeCycleId: string;
    sessionType: string;
    timestampStart: string;
    timestampEnd: string;
    summary: string;
    keyExcerpts: string[] | null;
    sourceFile: string;
    startLine: number;
    endLine: number;
    embeddingBlob: Buffer | null;
    toolCallsJson?: string | null;
    toolCallCount?: number;
    toolCallsTruncated?: boolean;
    reportedToolCallCount?: number | null;
}): void;
/**
 * Return the total number of wake cycles in the database.
 */
export declare function getWakeCycleCount(): number;
export declare function listWakeCyclesForUsageBackfill(limit?: number): WakeCycleRecord[];
/**
 * List wake cycles that have not yet been queued into usage.db.
 * Used by the background UsageReporter.
 */
export declare function listUnreportedWakeCycles(limit?: number): WakeCycleRecord[];
/**
 * Mark a wake cycle as successfully queued into usage.db.
 */
export declare function markWakeCycleUsageReported(wakeCycleId: string): void;
/**
 * Record a usage report error for a wake cycle.
 */
export declare function markWakeCycleUsageReportError(wakeCycleId: string, error: string): void;
/**
 * Update the tool_calls_json for an existing wake cycle row.
 * Used to persist reconstructed tool calls from archived transcripts.
 */
export declare function updateWakeCycleToolCallsJson(wakeCycleId: string, toolCallsJson: string): void;
/**
 * Check if a wake cycle ID already exists in the database.
 */
export declare function wakeCycleExists(wakeCycleId: string): boolean;
export interface SearchOptions {
    query: string;
    type?: "keyword" | "semantic" | "hybrid";
    timeRange?: {
        start: string;
        end: string;
    };
    sessionType?: string;
    limit?: number;
    config?: VisionClawConfig;
}
/**
 * Check whether semantic/vector search is available.
 */
export declare function isSemanticSearchAvailable(): boolean;
/**
 * Search wake cycle summaries. Routes to keyword, semantic, or hybrid
 * search based on the `type` option.
 *
 * - keyword: FTS5 full-text search with BM25 ranking (default)
 * - semantic: vec0 KNN search using embedding similarity
 * - hybrid: combines keyword + semantic via Reciprocal Rank Fusion (RRF)
 */
export declare function searchWakeCycles(options: SearchOptions): SearchResult[];
/**
 * Async semantic search — generates query embedding then searches vec0.
 */
export declare function searchSemanticAsync(options: SearchOptions): Promise<SearchResult[]>;
/**
 * Async hybrid search — runs keyword + semantic in parallel, fuses with RRF.
 * Reciprocal Rank Fusion: score = Σ 1/(k + rank_i) for each result system.
 */
export declare function searchHybridAsync(options: SearchOptions): Promise<SearchResult[]>;
/**
 * Normalize BM25 scores (which are negative, lower = better) to positive
 * scores where higher = better. Uses: score = 1 / (1 + |bm25|).
 * This gives a 0-1 range suitable for display.
 */
export declare function normalizeBm25Score(bm25: number): number;
/**
 * Get the key_excerpts for a specific wake cycle.
 */
export declare function getWakeCycleExcerpts(wakeCycleId: string): string | null;
/**
 * Get the full original source content for a specific wake cycle.
 * Reads from the source file (Claude transcript or VisionClaw log),
 * decompressing .gz if needed. No line limit is applied here so the
 * agent can access the complete original data when needed.
 */
export declare function getWakeCycleFullTranscript(wakeCycleId: string): Promise<string | null>;
/**
 * Close the database connection. Call during graceful shutdown.
 */
export declare function closeTranscriptMemoryDb(): void;
//# sourceMappingURL=transcript-indexer.d.ts.map