import { TreeNode } from './componentLabTypes'; import { SummaryData } from './componentWorkflowTypes'; /** Result schema identifier for file-backed analysis artifacts. */ export declare const ANALYSIS_FILE_ARTIFACT_SCHEMA = "mint.analysis_file.v1"; /** Known artifact lifecycle states; kept open for forward compatibility. */ export type AnalysisArtifactStatus = 'active' | 'archived' | (string & {}); /** Status filter vocabulary for artifact lists. */ export type AnalysisArtifactStatusFilter = 'active' | 'archived' | 'all'; /** Summary row returned by GET /experiments/{id}/analysis-artifacts. */ export interface AnalysisArtifactSummary { id: number; experiment_id: number; plugin_id: string; artifact_key: string; display_name: string; note?: string | null; status: AnalysisArtifactStatus; result_keys: string[]; created_at?: string | null; updated_at?: string | null; archived_at?: string | null; archived_by?: number | null; } /** Full artifact returned by GET /experiments/{id}/analysis-artifacts/{artifactId}. */ export interface AnalysisArtifactDetail extends AnalysisArtifactSummary { result: Record; tree: TreeNode[]; summary: SummaryData | null; } /** Response of GET /experiments/{id}/analysis-artifacts. */ export interface AnalysisArtifactListResponse { artifacts: AnalysisArtifactSummary[]; } /** Stable identity used when one plugin opens another plugin's artifact. */ export interface AnalysisArtifactTarget { experimentId: number; artifactPluginId: string; artifactKey: string; /** Optional lookup hint. The stable identity remains the three fields above. */ artifactId?: number; } /** Body of PATCH /experiments/{id}/analysis-artifacts/{artifactId}. */ export interface AnalysisArtifactMetadataUpdate { display_name?: string; /** undefined = keep, string = set, null = clear. */ note?: string | null; } /** How a save payload should be applied by the plugin backend. */ export type ArtifactSaveMode = 'create' | 'upsert' | 'update'; /** Where file content comes from when a plugin uses ArtifactSaveDialog. */ export type ArtifactFileSource = 'upload' | 'handler'; interface ArtifactSavePayloadBase { experimentId: number; artifactKey: string; } /** * JSON artifact save — handler maps to save_analysis_artifact, which upserts by key. * That call only assigns display_name/note when they are provided, and cannot clear * either; use the metadata PATCH (useAnalysisArtifacts.updateMetadata) for that. */ export interface JsonArtifactSavePayload extends ArtifactSavePayloadBase { kind: 'json'; mode: 'create' | 'upsert'; result: Record; displayName?: string; note?: string; } /** File artifact create — handler maps to save_analysis_file_artifact (create-only: a reused key conflicts). */ export interface FileArtifactCreatePayload extends ArtifactSavePayloadBase { kind: 'file'; mode: 'create'; file: File; /** Maps to the Python `kind=` argument (defaults to "file" backend-side). */ fileKind: string; filename?: string; displayName?: string; note?: string; contentType?: string; metadata?: Record; } /** * File artifact replacement — handler maps to update_analysis_file_artifact * (transactional CAS replace). `kind` and `filename` are immutable backend-side, so * `fileKind` echoes the artifact's existing kind and no filename is carried. `note` * is three-state: omitted preserves, null clears, a string sets. `metadata` REPLACES * the previous result metadata rather than merging, so it always carries the full * intended map — omitting it clears whatever was there. */ export interface FileArtifactUpdatePayload extends ArtifactSavePayloadBase { kind: 'file'; mode: 'update'; file: File; fileKind: string; note?: string | null; contentType?: string; metadata?: Record; } /** * File artifact create where the plugin handler produces the bytes itself. * This is intended for server-side serialization of in-memory analysis state; * the browser neither fabricates nor uploads a placeholder File. */ export interface HandlerFileArtifactCreatePayload extends ArtifactSavePayloadBase { kind: 'file'; mode: 'create'; source: 'handler'; fileKind: string; displayName?: string; note?: string; metadata?: Record; } /** File artifact replacement where the plugin handler produces the bytes itself. */ export interface HandlerFileArtifactUpdatePayload extends ArtifactSavePayloadBase { kind: 'file'; mode: 'update'; source: 'handler'; fileKind: string; note?: string | null; metadata?: Record; } export type ArtifactSavePayload = JsonArtifactSavePayload | FileArtifactCreatePayload | FileArtifactUpdatePayload; /** Payloads accepted when `ArtifactSaveDialog.fileSource` is `handler`. */ export type HandlerArtifactSavePayload = JsonArtifactSavePayload | HandlerFileArtifactCreatePayload | HandlerFileArtifactUpdatePayload; /** Every payload variant the dialog can emit across both file sources. */ export type ArtifactSaveDialogPayload = ArtifactSavePayload | HandlerFileArtifactCreatePayload | HandlerFileArtifactUpdatePayload; /** Optional handler result; cleanupPending surfaces AnalysisFileArtifactUpdate.cleanup_pending. */ export interface ArtifactSaveResult { artifact?: AnalysisArtifactSummary; cleanupPending?: boolean; } /** * Plugin-supplied save handler. The dialog never writes to the platform; * the handler forwards the payload to the plugin backend, which calls * save_analysis_artifact / save_analysis_file_artifact / update_analysis_file_artifact. */ export type ArtifactSaveHandler = (payload: ArtifactSavePayload) => Promise; /** Save handler paired with `ArtifactSaveDialog.fileSource="handler"`. */ export type HandlerArtifactSaveHandler = (payload: HandlerArtifactSavePayload) => Promise; /** Handler accepted by ArtifactSaveDialog; `fileSource` selects the payload family. */ export type ArtifactSaveDialogHandler = ArtifactSaveHandler | HandlerArtifactSaveHandler; export {};