Project Files
src / types.ts
/**
* Types for Draw Things Index Plugin
* Focused on generation metadata from JSONL logs and image XMP data
*/
// ═══════════════════════════════════════════════════════════════
// Source Information
// ═══════════════════════════════════════════════════════════════
/**
* Structured source information for tracking where a match was found
*/
export type SourceInfo =
| { type: 'generate_image_variant'; chatId: string }
| { type: 'attachment'; originalName: string; imageType?: 'Draw Things' | 'ComfyUI' }
| { type: 'saved_image'; filePath: string; imageType?: 'Draw Things' | 'ComfyUI' }
| { type: 'draw_things_project'; projectFile: string };
// ═══════════════════════════════════════════════════════════════
// Generation Metadata
// ═══════════════════════════════════════════════════════════════
/**
* Generation metadata from Draw Things audit logs or image XMP
*/
export interface GenerationMetadata {
timestamp?: string;
prompt: string;
negativePrompt?: string;
model: string;
loras?: string[] | Array<{ model: string; weight: number }>;
sampler?: string;
steps?: number;
cfgScale?: number;
seed?: number;
width?: number;
height?: number;
inferenceTimeMs?: number;
/**
* Number of frames for video generations (> 1 means this is a video clip).
* Only set for project-file video generations where num_frames > 1.
*/
numFrames?: number;
imagePaths?: string[];
httpPreviewUrls?: string[];
/** Where this generation was found */
sourceInfo?: SourceInfo;
}
/**
* Generation with pre-computed embedding for semantic search
* This is the indexed form stored in RAM
*/
export interface IndexedGeneration extends GenerationMetadata {
/** Pre-computed embedding vector for the prompt */
promptEmbedding?: number[];
/** Which embedding model was used (for cache invalidation) */
embeddingModel?: string;
}
// ═══════════════════════════════════════════════════════════════
// Search Results (Structured Output for draw-things-chat)
// ═══════════════════════════════════════════════════════════════
/**
* Match type indicates how the result was found
*/
export type MatchType = 'exact' | 'fuzzy' | 'partial' | 'semantic';
/**
* A single generation match with score and match details
*/
export interface GenerationMatch {
/** Original prompt used for generation */
prompt: string;
/** Negative prompt if available */
negativePrompt?: string;
/** Model used */
model: string;
/** LoRAs used (as strings for display) */
loras?: string[];
/** Generation seed */
seed?: number;
/** Number of steps */
steps?: number;
/** CFG scale */
cfgScale?: number;
/** Image dimensions */
width?: number;
height?: number;
/** Paths to generated images */
imagePaths: string[];
/** HTTP preview URLs for thumbnails */
httpPreviewUrls?: string[];
/** Where this generation was found */
sourceInfo?: SourceInfo;
/** Generation timestamp */
timestamp?: string;
/** Match score (0-100 for keyword, 0-1 for semantic) */
matchScore: number;
/** How this result was matched */
matchType: MatchType;
/** Which part of the query matched */
matchedTerms?: string[];
/** Number of frames for video generations (> 1 means video). Only set for project-file video generations. */
numFrames?: number;
}
/**
* Image result for UI display (compatible with brave_image_search style)
*/
export interface ImageResult {
/** Full path to image file */
path: string;
/** Thumbnail path if available */
thumbnailPath?: string;
/** HTTP preview URL if available */
httpPreviewUrl?: string;
/** The prompt that generated this image */
prompt: string;
/** Model used */
model: string;
/** Match type for visual distinction */
matchType: MatchType;
/** Match score */
score: number;
/** Generation timestamp */
timestamp?: string;
}
/**
* Complete search result (structured for draw-things-chat)
*/
export interface DrawThingsSearchResult {
/** Original search query */
query: string;
/** Total number of results found */
totalFound: number;
/** Search took this many milliseconds */
searchTimeMs: number;
/**
* Volltreffer: Exact, fuzzy, or partial keyword matches
* High confidence - prompt contains query terms
*/
exactMatches: GenerationMatch[];
/**
* Beifang: Semantically similar results
* Lower confidence - thematically related
* Only populated if embedding model available
*/
semanticMatches: GenerationMatch[];
/**
* Flattened image list for UI display
* Compatible with brave_image_search result format
*/
imageResults: ImageResult[];
/** Whether semantic search was used */
semanticSearchEnabled: boolean;
/** Summary for chat context */
summary: string;
}
// ═══════════════════════════════════════════════════════════════
// Internal Types
// ═══════════════════════════════════════════════════════════════
/**
* Parsed document result (internal)
*/
export interface ParsedDocument {
content: string;
metadata: {
title?: string;
format?: string;
generationCount?: number;
generations?: GenerationMetadata[];
hasMetadata?: boolean;
path?: string;
prompt?: string;
model?: string;
loras?: Array<{ model: string; weight: number }>;
[key: string]: any;
};
}
/**
* Indexed data cache
*/
export interface IndexedData {
generations: GenerationMetadata[];
images: ImageInfo[];
timestamp: number;
}
/**
* Image file info (internal)
*/
export interface ImageInfo {
path: string;
hasMetadata: boolean;
metadata?: GenerationMetadata;
vlmAnalysis?: string;
}
export type DocumentFormat = 'jsonl' | 'png' | 'jpg' | 'jpeg' | 'webp' | 'unknown';