import { SkillExecutor } from '../../services/skillEngine/skillExecutor';
import { SkillExecutionResult } from '../../services/skillEngine/types';
import { DataEnvelope } from '../../types/dataContract';
import { StreamingUpdate } from '../types';
import { type ResourceOwnerFields } from '../../services/resourceOwnership';
import type { SceneJobArtifactStore } from '../../services/sceneReport/sceneJobArtifactStore';
import { type CostEstimate } from './sceneCostEstimator';
import type { SceneRouteProfile } from '../config/domainManifest';
import type { SmartCancelToken } from './smartCancelBridge';
import type { SceneReportStore } from '../../services/sceneReport/sceneReportStore';
import type { SceneReportMemoryCache } from '../../services/sceneReport/sceneReportMemoryCache';
import { SceneAnalysisSelection, SceneReport } from './types';
/**
 * Minimal session shape sceneStoryService cares about. Concrete sessions
 * (SceneReconstructSession) extend this with many more fields, but we
 * intentionally only touch the ones we own.
 */
export interface SceneStorySession {
    sessionId: string;
    status: string;
    lastActivityAt: number;
    createdAt: number;
    tenantId?: string;
    workspaceId?: string;
    userId?: string;
    scenes?: any[];
    trackEvents?: any[];
    error?: string;
    /** Set by sceneStoryService once Stage 4 finishes. */
    sceneStoryReport?: SceneReport;
}
export interface SceneStoryServiceDeps {
    /** Per-session SSE broadcast (sessionId, update) → void. */
    broadcast: (sessionId: string, update: StreamingUpdate) => void;
    /** Session lookup. */
    getSession: (sessionId: string) => SceneStorySession | undefined;
    /** Wraps the static SkillExecutor.toDataEnvelopes for unit testability. */
    toEnvelopes?: (result: SkillExecutionResult, traceId: string) => DataEnvelope[];
    /** Disk cache for file-backed traces (sha256 → SceneReport, 7d TTL). */
    reportStore: SceneReportStore;
    /** Process-memory weak cache for external-RPC traces (no content hash). */
    memoryCache: SceneReportMemoryCache;
    /** Out-of-band storage for omitted Smart job rows. */
    jobArtifactStore?: SceneJobArtifactStore;
    /**
     * Compute the trace's content hash. Returns null when the trace has no
     * file backing it (external RPC). DI'd so tests can stub without a real
     * TraceProcessorService.
     */
    computeHash: (traceId: string) => Promise<string | null>;
    /**
     * Probe the trace duration in seconds for the preview endpoint. Returns 0
     * on any failure; callers feed that into the cost estimator which clamps
     * to MIN_EXPECTED_SCENES.
     */
    probeDuration: (traceId: string) => Promise<number>;
}
export interface SceneStoryStartArgs {
    sessionId: string;
    traceId: string;
    owner?: ResourceOwnerFields;
    /** Per-request SkillExecutor — must already have its registry loaded. */
    skillExecutor: SkillExecutor;
    options?: SceneStoryStartOptions;
}
export interface SceneStoryStartOptions {
    /** Override the analysis cap; defaults to a heuristic based on trace length. */
    analysisCap?: number;
    /** Skip cache lookup and run a fresh pipeline. */
    forceRefresh?: boolean;
    /** Route profile for Stage 2 route selection and cache isolation. */
    routeProfile?: SceneRouteProfile;
    /** Stop after Stage 1 and wait for the user to choose a Smart deep-dive scope. */
    previewOnly?: boolean;
    /** Optional Stage 2 scope chosen by the user. Defaults to all detected scenes. */
    selection?: SceneAnalysisSelection;
    /** Optional parent-session cancellation signal used by Smart Analysis Mode. */
    cancelToken?: SmartCancelToken;
    /** Optional LLM double-check for ambiguous Smart Stage1 scene reconstruction. */
    verifyWithLlm?: boolean;
}
/**
 * Result of `previewOnly`. When `cached` is set the front-end can short-cut
 * to "show me this report" without ever firing /scene-reconstruct.
 */
export interface SceneStoryPreviewResult {
    estimate: CostEstimate;
    cached: SceneReport | null;
    traceDurationSec: number;
}
export declare class SceneStoryService {
    private readonly deps;
    private readonly runners;
    private readonly inProgress;
    private readonly toEnvelopes;
    private readonly memoryReportById;
    /**
     * Concurrent-request dedupe: while a pipeline for an owner-scoped
     * `traceHash` is running, peer requests for the same owner + hash await the
     * in-flight promise instead of starting a duplicate pipeline. RPC traces
     * have no hash key, so duplicate concurrent requests there fall through and
     * run their own pipeline (rare and harmless).
     */
    private readonly pendingByHash;
    constructor(deps: SceneStoryServiceDeps);
    /**
     * Run the full Scene Story pipeline for a session. Resolves when the
     * pipeline reaches a terminal state (completed / failed / cancelled).
     *
     * Errors thrown inside the pipeline are caught and surfaced via SSE so
     * the caller does not need its own try/catch (the route handler still
     * wraps it for safety).
     */
    start(args: SceneStoryStartArgs): Promise<SceneReport | null>;
    /**
     * Request cancellation of an in-flight scene story run. The pipeline keeps
     * running until its in-flight jobs settle, then transitions to 'cancelled'
     * and emits the terminal events itself — callers do not need to wait.
     *
     * Returns true when a runner was found and cancelled; false otherwise
     * (already settled or never started).
     */
    cancel(sessionId: string): boolean;
    private handleJobEvent;
    private finalize;
    private finalizeSelectionPreview;
    /**
     * Persist a finalised SceneReport to whichever cache layer matches the
     * trace's origin. File-backed traces go into the disk store with the
     * configured TTL; external RPC traces fall into the in-memory LRU keyed
     * by traceId.
     *
     * Errors propagate. The contract that `scene_story_report_ready` only
     * fires after a successful persist depends on this — silently swallowing
     * a save failure would let peer requests get a `reportId` they can't
     * subsequently load via `GET /scene-reconstruct/report/:id`.
     */
    private persistReport;
    /**
     * Replay a cached SceneReport on a new session's SSE channel. Used by both
     * the disk-cache and memory-cache hit paths and by peer-request dedupe
     * after awaiting a sibling pipeline.
     *
     * The emitted event sequence collapses Stage 1/2/3 into a single
     * scene_story_report_ready terminal:
     *   progress {phase:'cached'}
     *   → scene_story_detected
     *   → track_data (legacy)
     *   → scene_story_report_ready
     *   → progress {phase:'completed'}
     *
     * Frontend story_controller already treats scene_story_report_ready as
     * terminal, so this fast path renders correctly without any extra
     * frontend changes.
     */
    private emitCachedReport;
    /**
     * Cheap preview for the /scene-reconstruct/preview endpoint. Computes the
     * trace's content hash, checks both cache layers, and falls through to a
     * formula-based ETA + USD estimate. Never starts the heavy pipeline.
     *
     * Latency profile:
     *   - cached + file-backed: hash + index lookup (~10s for 1GB; <100ms for small)
     *   - cached + RPC: O(1) Map lookup
     *   - cold:        hash + trace_bounds SQL probe (~50ms)
     */
    previewOnly(args: {
        traceId: string;
        owner?: ResourceOwnerFields;
        routeProfile?: SceneRouteProfile;
    }): Promise<SceneStoryPreviewResult>;
    /**
     * GET /scene-reconstruct/report/:reportId — direct lookup by reportId.
     * Returns null if the report has been evicted (TTL expired) or never
     * existed; the route handler maps null to a 404.
     */
    getReport(reportId: string): Promise<SceneReport | null>;
    /**
     * Unified cache lookup: file-backed traces go via the disk store by hash;
     * external RPC traces go via the in-memory LRU by traceId. Used by both
     * start() (cache check) and previewOnly() so the lookup strategy is
     * defined in exactly one place.
     */
    private lookupCachedReport;
}
//# sourceMappingURL=sceneStoryService.d.ts.map