/** Defines persisted session-entry schema and repair helpers shared by upload, hydrate, replay, and export flows. */
import type { ImageContent, TextContent } from '../ai/types.js';
import type { AgentMessage } from './core-types.js';
export declare const CURRENT_SESSION_VERSION = 3;
export interface SessionHeader {
    type: 'session';
    version?: number;
    id: string;
    timestamp: string;
    cwd: string;
    parentSession?: string;
    isSubagent?: boolean;
}
export interface NewSessionOptions {
    parentSession?: string;
    isSubagent?: boolean;
}
export interface SessionEntryBase {
    type: string;
    id: string;
    parentId: string | null;
    timestamp: string;
}
export interface SessionMessageEntry extends SessionEntryBase {
    type: 'message';
    message: AgentMessage;
    /** Wall-clock duration in ms. Set on assistant messages (LLM latency) and tool results (execution time). */
    durationMs?: number;
}
export interface ThinkingLevelChangeEntry extends SessionEntryBase {
    type: 'thinking_level_change';
    thinkingLevel: string;
}
export interface ModelChangeEntry extends SessionEntryBase {
    type: 'model_change';
    provider: string;
    modelId: string;
}
export interface CompactionEntry<T = unknown> extends SessionEntryBase {
    type: 'compaction';
    summary: string;
    firstKeptEntryId: string;
    tokensBefore: number;
    /** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
    details?: T;
    /** True if generated by an extension, undefined/false if pi-generated (backward compatible) */
    fromHook?: boolean;
}
/**
 * Custom entry for extensions to store extension-specific data in the session.
 * Use customType to identify your extension's entries.
 *
 * Purpose: Persist extension state across session reloads. On reload, extensions can
 * scan entries for their customType and reconstruct internal state.
 *
 * Does NOT participate in LLM context (ignored by buildSessionContext).
 * For injecting content into context, see CustomMessageEntry.
 */
export interface CustomEntry<T = unknown> extends SessionEntryBase {
    type: 'custom';
    customType: string;
    data?: T;
}
/** Label entry for user-defined bookmarks/markers on entries. */
export interface LabelEntry extends SessionEntryBase {
    type: 'label';
    targetId: string;
    label: string | undefined;
}
/** Session metadata entry (e.g., user-defined display name). */
export interface SessionInfoEntry extends SessionEntryBase {
    type: 'session_info';
    name?: string;
}
/** Turn start boundary entry for timing and grouping. */
export interface TurnStartEntry extends SessionEntryBase {
    type: 'turn_start';
    turnIndex: number;
}
/** Turn end boundary entry with duration. */
export interface TurnEndEntry extends SessionEntryBase {
    type: 'turn_end';
    turnIndex: number;
    /** Wall-clock duration of this turn in milliseconds. */
    durationMs: number;
}
/** System prompt snapshot captured at agent_start. */
export interface SystemPromptEntry extends SessionEntryBase {
    type: 'system_prompt';
    content: string;
}
/** Tool definitions snapshot captured at agent_start. */
export interface ToolDefinitionsEntry extends SessionEntryBase {
    type: 'tool_definitions';
    tools: {
        name: string;
        description: string;
        parameters: unknown;
    }[];
}
export interface ToolExecutionEndEntry extends SessionEntryBase {
    type: 'tool_execution_end';
    toolCallId: string;
    toolName: string;
    isError: boolean;
    result: unknown;
}
export interface LlmCallEntry extends SessionEntryBase {
    type: 'llm_call';
    requestId: string;
    body: {
        effort_level?: 'low' | 'medium' | 'high' | 'max';
        max_tokens?: number;
        messages: readonly {
            content: string;
            role: string;
            thinking?: string;
            thinking_signature?: string;
            tool_call_id?: string;
            tool_calls?: readonly {
                arguments: string;
                id: string;
                name: string;
            }[];
        }[];
        model: string;
        speed?: 'fast' | 'standard';
        thinking_type?: 'adaptive' | 'off';
        user_message_id?: string;
        tools?: readonly {
            description: string;
            name: string;
            parameters: unknown;
        }[];
    };
}
/**
 * Custom message entry for extensions to inject messages into LLM context.
 * Use customType to identify your extension's entries.
 *
 * Unlike CustomEntry, this DOES participate in LLM context.
 * The content is converted to a user message in buildSessionContext().
 * Use details for extension-specific metadata (not sent to LLM).
 *
 * display controls TUI rendering:
 * - false: hidden entirely
 * - true: rendered with distinct styling (different from user messages)
 */
export interface CustomMessageEntry<T = unknown> extends SessionEntryBase {
    type: 'custom_message';
    customType: string;
    content: string | (TextContent | ImageContent)[];
    details?: T;
    display: boolean;
}
/** Session entry - has id/parentId for tree structure (returned by "read" methods in SessionManager) */
export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | CompactionEntry | CustomEntry | CustomMessageEntry | LabelEntry | SessionInfoEntry | TurnStartEntry | TurnEndEntry | SystemPromptEntry | ToolDefinitionsEntry | ToolExecutionEndEntry | LlmCallEntry;
/** Raw file entry (includes header) */
export type FileEntry = SessionHeader | SessionEntry;
/** Tree node for getTree() - defensive copy of session structure */
export interface SessionTreeNode {
    entry: SessionEntry;
    children: SessionTreeNode[];
    /** Resolved label for this entry, if any */
    label?: string;
}
export interface SessionContext {
    messages: AgentMessage[];
    messageEntryIds?: string[];
    thinkingLevel: string;
    model: {
        provider: string;
        modelId: string;
    } | null;
}
/** Exported for compaction.test.ts */
/** Tolerantly parse JSONL session content, skipping malformed lines. */
export declare function parseSessionEntries(content: string): FileEntry[];
/** Serialize file entries to JSONL text with a trailing newline. */
export declare function serializeFileEntries(entries: readonly FileEntry[]): string;
export interface ParseSessionStrictResult {
    /** Header line (first `type:'session'` entry), or null if absent. */
    header: SessionHeader | null;
    /** Recognized SessionEntry items, in original file order. */
    entries: SessionEntry[];
    /** Non-fatal notices (e.g. unknown entry types skipped, duplicate header). */
    warnings: string[];
}
export interface SessionParseError {
    kind: 'malformed-line' | 'empty' | 'invalid-shape';
    message: string;
    /** 1-based line number, when applicable. */
    line?: number;
}
/** Throws on malformed JSON / non-object / missing type. Skips unknown `type` as warning (forward-compat). */
export declare function parseSessionEntriesStrict(content: string): ParseSessionStrictResult;
/**
 * Canonicalize older user-message entries into the multi-block array shape.
 * This is separate from strict parsing so parse/serialize roundtrips remain
 * byte-stable while hydrate still feeds a stable message shape to the runtime.
 */
export declare function canonicalizeUserMessageEntries(entries: readonly SessionEntry[]): SessionEntry[];
export interface SessionInvariantViolation {
    /**
     * Categorical kind:
     * - `'tool-pairing'`: assistant tool_use lacks a matching toolResult, or toolResult is unmatched.
     * - `'user-message-shape'`: user message violates multi-block invariants
     *   (empty content, content[0] not a TextContent, contextResetBoundary not exactly `true`).
     */
    kind: 'tool-pairing' | 'user-message-shape';
    message: string;
    /** Entry id of the offending entry, if applicable. */
    entryId?: string;
}
/**
 * Throws if any toolCall lacks a matching toolResult, or if any user message
 * violates the multi-block shape required by UI and LLM projection.
 */
export declare function assertSessionInvariants(entries: readonly SessionEntry[]): void;
export interface RepairOrphanToolUsesOptions {
    /** Override id generator (tests). Defaults to `crypto.randomUUID().slice(0,8)`. */
    generateId?: () => string;
    /** Override timestamp source (tests). Defaults to `new Date().toISOString()`. */
    now?: () => string;
    /** Tool result content for synthesized entries. Defaults to a cancelled-marker text block. */
    syntheticResultText?: string;
    /** Tool name to use when the original toolCall's name is unavailable (it should always be). */
    fallbackToolName?: string;
}
export interface RepairOrphanToolUsesResult {
    entries: SessionEntry[];
    /** ToolCall ids for which a synthetic toolResult was inserted. */
    patchedToolCallIds: string[];
}
/** Insert synthetic `toolResult` entries for every orphan `toolCall`. Pure. */
export declare function repairOrphanToolUses(entries: readonly SessionEntry[], options?: RepairOrphanToolUsesOptions): RepairOrphanToolUsesResult;
/** Find the most recent compaction entry in a list, or null if none exists. */
export declare function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null;
/** Build the LLM context (messages, thinking level, model) by walking entries to the leaf. */
export declare function buildSessionContext(entries: SessionEntry[], leafId?: string | null, byId?: Map<string, SessionEntry>): SessionContext;
/** Return the entry ids of every message that participates in the projected LLM context. */
export declare function buildSessionContextMessageEntryIds(entries: SessionEntry[], leafId?: string | null, byId?: Map<string, SessionEntry>): string[];
//# sourceMappingURL=session-schema.d.ts.map