import type { ViteDevServer } from "vite";
import { type AiAppFact, type AiMoveAppKnowledgeRequest, type AiMoveAppKnowledgeResult, type AiGenerateRequest, type AiExplainCodeRequest, type AiSummarizeApiUsageRequest, type AiSummarizeErrorRequest, type AiLabelAttachmentRequest, type AiLabelAttachmentResponse, type AiToolPermission, type LLMProviderConfig, type PromptContext, type RuntimeErrorData, type ConsoleLogEntry, type ApiRunRecord } from "@superblocksteam/library-shared/types";
import { TracedEventEmitter } from "@superblocksteam/shared";
import type { FileSystemManager } from "../file-system-manager.js";
import type { GitOperationLock } from "../git-operation-lock.js";
import type { GitService } from "../git-service/index.js";
import type { SourceTracker } from "../source-tracker.js";
import type { GitPullSyncService } from "./agent/tools2/tools/git.js";
import { ChatSessionStore } from "./chat/chat-session-store.js";
import { AppContextStore } from "./context/app-context.js";
import type { JudgeEvaluationOptions, JudgeEvaluationResult } from "./judge/judge-service.js";
import type { ContextId } from "./llm/context-v2/types.js";
import { RecordingManager } from "./recording/index.js";
import type { AiServiceConfig, AiServiceEvents, EditorClient, UserChange, ApiUpdate } from "./types.ts";
export { AiServiceFeatureFlags } from "./features.js";
export { SnapshotManager } from "./recording/index.js";
export { isSdkApiTemplate } from "./sdk-api-templates.js";
export declare function pruneByTTL<T extends {
    timestamp?: number;
    generationTimestamp?: string;
}>(items: T[], ttlMs: number): T[];
export declare function estimateSize(obj: unknown): number;
export declare function truncateString(str: string, maxBytes: number): string;
export declare function pruneBySize<T extends {
    _size?: number;
}>(items: T[], maxBytes: number): T[];
export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
    private readonly config;
    private templateRenderer;
    private appShell;
    private fileSystemInterface;
    private integrationStore;
    private knowledgeManager;
    private _appContext;
    private llmProviderSettings;
    private _logger;
    private readonly clark;
    private clarkProfiler;
    readonly chatSessionStore: ChatSessionStore;
    private readonly contextManagerV2;
    private readonly llmClient;
    private readonly stablePeer;
    private readonly toolRegistry;
    private readonly entityPermissionStore;
    private _onGenerationCompleteCallback;
    private tokenManagerJwt?;
    private viteServer?;
    private readonly mcpServerManager;
    private readonly recordingManager;
    private readonly sessionId;
    private _runtimeGitService?;
    private _runtimeSyncService?;
    private _runtimeGitOperationLock?;
    private _onGitOperationComplete?;
    get appContext(): AppContextStore;
    get clarkState(): string;
    /**
     * Injects git and sync services for the git tool (called by the plugin when native git is available).
     */
    setRuntimeGitServices(gitService?: GitService, syncService?: GitPullSyncService, gitOperationLock?: GitOperationLock): void;
    setOnGitOperationComplete(callback: () => void): void;
    get appRootDirPath(): string;
    get organizationId(): string;
    get superblocksBaseUrl(): string;
    /**
     * Gets the contextId for the current conversation context.
     * Returns null if JWT is missing or has no userId.
     */
    getContextId(): ContextId | null;
    /**
     * Gets the JWT from Clark context
     */
    getClarkJwt(): string | undefined;
    /**
     * Updates the JWT in Clark context
     */
    updateClarkJwt(jwt: string): void;
    /**
     * Check if recording is currently enabled.
     */
    isRecording(): boolean;
    /**
     * Get the current recording session ID.
     */
    getRecordingSessionId(): string | null;
    /**
     * Clear all recordings.
     *
     * @param sessionId - Optional session ID to clear only that session
     */
    clearRecordings(sessionId?: string): Promise<void>;
    /**
     * Get the RecordingManager instance for advanced usage.
     * This allows external code to add custom recording middleware.
     */
    getRecordingManager(): RecordingManager;
    /**
     * Returns the set of integration IDs available in the current environment.
     */
    getAvailableIntegrationIds(): Promise<Set<string>>;
    get isSessionManagementEnabled(): boolean;
    get isAiFileUploadEnabled(): boolean;
    /**
     * Checks if there is a live editor socket behind the StablePeer proxy.
     * `clark.context.peer` is always present (it's the proxy); inner liveness
     * is tracked on the proxy itself via `peerId`.
     */
    hasConnectedPeer(): boolean;
    constructor(config: AiServiceConfig);
    /**
     * Initialize the AI service. Must be called after construction.
     * Sets up storage, cleanup tasks, and starts recording.
     */
    initialize(): Promise<void>;
    private hydrateMigrationChecklistFromDisk;
    /**
     * Remove the integration metadata cache for this session.
     * Cleans up the session cache directory.
     */
    removeIntegrationCache(): Promise<void>;
    private getLogger;
    private createClarkTransitionHandler;
    private getJwt;
    private createClarkTagProviderFactory;
    private callServer;
    private ensureAiQuotaAvailable;
    /**
     * Fires the internal, UI-invisible migration turn if the app is post-flip
     * and still has `seed_api` checklist items pending. Safe to call multiple
     * times — the `migrationTurnTriggered` guard ensures one-shot semantics
     * per ai-service lifetime. The disk checklist is the recovery source of
     * truth across process restarts.
     *
     * Expected caller: the UI issues a dedicated RPC (see
     * v1.ai.triggerMigrationTurn) once it observes the post-flip state via
     * /sb-migration-status. jwt + llmConfig come from the UI's normal auth
     * flow.
     */
    handleAiTriggerMigrationTurn(request: {
        jwt: string;
        llmConfig: LLMProviderConfig;
        retryMode?: "focused-debug";
    }): Promise<{
        dispatched: boolean;
        reason?: string;
    }>;
    private getMigrationSafeLlmConfig;
    private migrationTurnTriggered;
    handleAiGenerate(request: AiGenerateRequest): Promise<void>;
    handleAiExplainCode(request: AiExplainCodeRequest): Promise<void>;
    handleAiSummarizeApiUsage(request: AiSummarizeApiUsageRequest): Promise<void>;
    handleAiSummarizeError(request: AiSummarizeErrorRequest): Promise<void>;
    handleAiLabelAttachment(request: AiLabelAttachmentRequest): Promise<AiLabelAttachmentResponse>;
    /**
     * Converts an attachment to the appropriate LLM content part.
     */
    private attachmentToContentPart;
    private submitAcceptanceEvaluation;
    handleUserAcceptedDraft(silently?: boolean): Promise<void>;
    handleUserRejectedDraft(silently?: boolean): Promise<void>;
    /**
     * Called when the user closes the integration setup form via the X button.
     * Clears backend state so Clark knows the form is no longer open.
     */
    handleIntegrationSetupClosed(): Promise<void>;
    handleUserCanceled(): Promise<void>;
    /**
     * Submit a prompt with interrupt behavior.
     * If not busy, starts immediately. Otherwise interrupts and continues.
     */
    handleAiGenerateWithQueue(request: AiGenerateRequest, mode: "queue" | "interrupt"): Promise<{
        status: "started" | "interrupted";
    }>;
    /**
     * Interrupt current generation and continue with new prompt.
     * The partial response is preserved in chat history for context.
     */
    private interruptAndContinue;
    /**
     * Wait for the FSM to transition out of busy state after abort.
     *
     * Resolves when idle, rejects after 20s. The caller must NOT replace
     * the AbortController before this settles — the running generation
     * re-reads the signal on each streamText / tool call and would
     * "un-abort" itself if given a fresh controller.
     */
    private waitForAbortComplete;
    handleSkipTestCase(testRunId: string, testCaseId: string): Promise<void>;
    /**
     * Handles the user's response to a tool permission request.
     *
     * If approved, immediately executes the tool with the original input,
     * injects the tool call and result into the conversation context,
     * and restarts the LLM with the updated context.
     *
     * If denied, injects a tool error into the context and restarts the LLM.
     */
    handleAiRespondToToolPermission(request: {
        messageId: string;
        approved: boolean;
        alwaysAllowPermissions?: AiToolPermission[];
        denyMessage?: string;
    }): Promise<void>;
    /**
     * Builds a continuation prompt when a tool permission is denied.
     * For testApi, provides specific guidance to continue testing other APIs.
     */
    private buildDenialContinuationPrompt;
    handleUserConnected(peer: EditorClient, peerId: string): void;
    handleUserDisconnected(peerId: string): void;
    private clearPeerConnection;
    handleBuildSystemError(error: Error): void;
    handleRuntimeError(errorData: RuntimeErrorData): void;
    handleClearRuntimeError(id: string): void;
    handleConsoleLog(logEntry: ConsoleLogEntry): void;
    handleApiRunRecord(apiId: string, runRecord: ApiRunRecord): void;
    handleClearRuntimeErrors(before?: number): void;
    handleClearBuildSystemErrors(): void;
    handlePromptInterpretation(request: {
        prompt: string;
        jwt: string;
        promptContext?: PromptContext;
    }): Promise<void>;
    /**
     * Handles judge evaluation requests.
     *
     * Evaluates an application against a prompt using the judge system.
     * The evaluation is automatically stored to CSV for later analysis.
     *
     * @param request - Judge evaluation request
     * @returns Evaluation result with scores and feedback
     */
    handleJudgeEvaluation(request: {
        promptId: string;
        prompt: string;
        appId: string;
        appUrl: string;
        jwt: string;
        llmConfig?: LLMProviderConfig;
        options?: Partial<JudgeEvaluationOptions>;
        storageStateData?: any;
    }): Promise<JudgeEvaluationResult>;
    handleUserChange(change: UserChange): void;
    handleNewChat(): Promise<void>;
    /**
     * Returns all saved app skill facts for the current application.
     */
    getAppFacts(): Promise<AiAppFact[]>;
    /**
     * Deletes an app skill fact by its virtual path.
     */
    deleteAppFact(virtualPath: string): Promise<void>;
    /**
     * Toggles the isEnabled field of an app skill fact and returns the updated fact.
     */
    toggleAppFact(virtualPath: string, isEnabled: boolean): Promise<AiAppFact>;
    /**
     * Move an app skill fact to org/user/integration scope.
     */
    moveAppFact(payload: AiMoveAppKnowledgeRequest): Promise<AiMoveAppKnowledgeResult>;
    handleRestoreToCommit(sinceTimestamp: number, commitId: string, applicationId: string, branchName: string): Promise<void>;
    handleApiUpdate(update: ApiUpdate): Promise<void>;
    isBusy(): boolean;
    isAwaitingUser(): boolean;
    /**
     * Check if Clark is currently generating code.
     * Used by lock-service to determine if lock should be held during generation.
     * @returns true if Clark is in a generating state (AgentPlanning, LLMGenerating, PostProcessing, RuntimeReviewing)
     */
    isGenerating(): boolean;
    /**
     * Wait for Clark generation to complete.
     * Generation means that Clark is either in Plan Mode or Build Mode
     * If Clark is not currently generating, resolves immediately.
     * Used by lock-service to wait for generation before releasing lock.
     * @returns Promise that resolves when generation completes (or immediately if not generating)
     */
    waitUntilGenerationComplete(): Promise<void>;
    /**
     * Manually trigger the generation complete callback.
     * Should be called when Clark transitions to Idle or AwaitingUser state.
     */
    private triggerGenerationComplete;
    isGeneratingFullAppOrBroadUpdate(): Promise<boolean>;
    setSourceTracker(sourceTracker: SourceTracker | undefined): void;
    setFileSystemManager(fileSystemManager: FileSystemManager): void;
    setViteServer(server: ViteDevServer): void;
    getViteServer(): ViteDevServer | undefined;
    private getLLMProviderSettings;
}
//# sourceMappingURL=index.d.ts.map