UNPKG

@gaiaverse/semantic-turning-point-detector

Version:

Detects key semantic turning points in conversations using recursive semantic distance analysis. Ideal for conversation analysis, dialogue segmentation, insight detection, and AI-assisted reasoning tasks.

243 lines 11.6 kB
import winston from "winston"; import { Message, MessageSpan } from "./Message"; import { ConvergenceState, TurningPoint, TurningPointDetectorConfig } from "./types"; export declare class SemanticTurningPointDetector { private config; /** * For ease of use in llm requests, openai's client is used as it allows configurable endpoints. Further expoloration might be reasonable in leveraging other libaries, such as ollama, llmstudio, genai, etc, for more direct compatibility with other LLM providers. Though at this time, the OpenAI client is sufficient for requests done by this detector. */ private openai; /** * This provides the array of the initial messages that were passed to the detector. This is noted as such as throughout the process, ARC involves analyzing subsets of the original messages, and the original messages are not modified. */ private originalMessages; /** * AN array of changes of state across iterations, used for convergence measurement. * This is used to track the evolution of turning points across iterations and dimensions. * This is used when returning the final results, to determine whether the turning points have converged. */ private convergenceHistory; /** * Used to help mitigate repeat embedding requests for the same message content. And can be configured to avoid excessive RAM usage via `embeddingCacheRamLimitMB`. */ private embeddingCache; private endpointType; private ollama; readonly logger: winston.Logger | Console; /** * Creates a new instance of the semantic turning point detector */ constructor(config?: Partial<TurningPointDetectorConfig>); getModelName(): string; /** * Main entry point: Detect turning points in a conversation * Implements the full ARC/CRA framework */ detectTurningPoints(messages: Message[]): Promise<{ confidence: number; points: TurningPoint[]; }>; /** * Multi-layer detection implementing the ARC/CRA dimensional processing * This is the primary implementation of the transition operator Ψ */ private multiLayerDetection; /** * Calculate a difference measure between two states (sets of turning points) * Used for convergence tracking. Considers significance and location. */ private calculateStateDifference; /** * Apply complexity function χ from the ARC/CRA framework */ private calculateComplexityScore; /** * Detect turning points within a single chunk of the conversation */ /** * Detect turning points within a single chunk of the conversation * This represents the local refinement process in the current dimension */ private detectTurningPointsInChunk; private clearOllamaCache; /** * Use LLM to classify a turning point and generate metadata. * *** MODIFIED to prioritize message.spanData over regex *** */ /** * Use LLM to classify a turning point and generate metadata. * This implementation uses a highly modular prompt architecture with * multiple distinct user messages to ensure clarity. The payload consists of: * - A system message that sets the core identity and universal constraints. * - A static context user message containing framework and evaluation criteria. * - A dynamic data user message that provides conversation context and the specific messages to analyze. * - A final user instruction message that tells the model what to do with all this information. */ private classifyTurningPoint; /** * Updated to utilize new classes of Message and MetaMessage for better structure and clarity * @param turningPoints * @param originalMessages * @returns */ private createMetaMessagesFromTurningPoints; /** * Filter turning points to keep only significant ones * (Using original logic from the second code block) */ private filterSignificantTurningPoints; /** * Combine turning points from different dimensions * (Using original logic from the second code block) */ private combineTurningPoints; /** * Merge similar or overlapping turning points *within* the same dimension * (Using original logic from the second code block) */ private mergeSimilarTurningPoints; /** * Merge turning points across different dimensions with priority to higher dimensions * (Using original logic from the second code block) */ private mergeAcrossLevels; /** * Create a merged label (Using original logic) */ private createMergedLabel; /** * Find common significant words (Using original logic) */ private findCommonWords; /** * Get a unique key for a message span (Using original logic) */ private getSpanKey; /** * Check if a span overlaps with any spans in the covered set (Using original logic) * Note: This might be less accurate than the index-based check in mergeAcrossLevels now. * Kept for potential use by filterSignificantTurningPoints if it uses range strings. */ private isSpanOverlapping; /** * Generate embeddings for an array of messages (Using original logic) */ private generateMessageEmbeddings; /** * Retrieves the embedding vector for a given text string using the configured embedding model. * * This method implements intelligent token management, crypto-hashed caching, and multi-provider * support for embedding generation within the ARC/CRA framework. * * @param text - The input text to generate embeddings for. Will be automatically truncated if exceeding token limits. * @param naiveTokenLimit - Maximum number of tokens allowed before truncation (default: 8192). * Uses a character-to-token ratio estimation for efficient preprocessing. * * @returns Promise<Float32Array> - The embedding vector as a Float32Array. Dimension depends on the model: * - text-embedding-3-small: 1536 dimensions * - text-embedding-3-large: 3072 dimensions * - Other models: 1024 dimensions (fallback) * * @throws Will not throw errors directly, but logs warnings and returns zero vectors on API failures. * * @remarks * **Token Management:** * - Implements dynamic text truncation based on token counting to prevent API errors * - Uses character-to-token ratio estimation for efficient preprocessing * - Recalculates ratio iteratively until under the specified limit * * **Caching Strategy:** * - Uses SHA-256 crypto hashing for cache keys to avoid issues with special characters and long text * - Cache keys include both model name and (truncated) text content for uniqueness * - Leverages the class's LRU cache with configurable RAM limits via `embeddingCacheRamLimitMB` * - Cache operations are logged in debug mode for monitoring effectiveness * * **Multi-Provider Support:** * - Supports OpenAI API and OpenAI-compatible endpoints (Ollama, LM Studio, etc.) * - Uses EMBEDDINGS_API_KEY environment variable first, falls back to OPENAI_API_KEY * - Respects the configured `embeddingEndpoint` for custom embedding providers * - Maintains compatibility with standard OpenAI embedding response format * * **Error Handling:** * - Returns zero vectors instead of throwing on API failures * - Logs detailed error information for debugging * - Gracefully handles invalid API responses or network issues * - Maintains system stability during transient embedding service outages * * **Integration with ARC/CRA Framework:** * - Critical component for semantic distance calculations in turning point detection * - Supports both base message embeddings (dimension 0) and meta-message embeddings (dimension > 0) * - Cache performance directly impacts overall framework processing speed * - Embedding quality affects the accuracy of semantic shift detection */ getEmbedding(text: string, naiveTokenLimit?: number): Promise<Float32Array>; /** * Calculate semantic distance (Using original logic with sigmoid adjustment) */ private calculateSemanticDistance; /** * Chunk a conversation (Using original logic) */ private chunkConversation; /** * Ensures a message span is in chronological order by index * (Using original logic) */ private ensureChronologicalSpan; /** * Get token count for a message with caching (Using original logic) */ private getMessageTokenCount; /** * Get token count for multiple messages (Using original logic) */ getMessageArrayTokenCount(messages: Message[]): Promise<number>; /** * Get the convergence history for analysis (Using original logic) */ getConvergenceHistory(): ConvergenceState[]; private prepareContextualInfoMeta; /** * Prepares contextual information to be appended to the LLM prompt. * Gathers nearby messages (before, after, and within the span) for additional context. * - This preperation is soley meant for dimension at 0, wherein the messages are still base level messages, rather than MetaMessages, which encompass a group of turning points. */ private prepareContextualInfoMessage; /** * Validates turning point categories configuration * Ensures each category has required fields and logs warnings for issues */ private validateTurningPointCategories; /** * Check if an endpoint is running Ollama by checking the root response */ private isOllamaEndpoint; /** * Processes the raw string content received from an LLM classification call * and attempts to parse it into a structured JSON object. * * This method implements a robust parsing strategy: * 1. It first attempts a direct `JSON.parse()` on the input string. * 2. If direct parsing fails, it looks for a JSON object embedded within * a markdown-style code block (e.g., ```json\n{...}\n```) and tries to parse that. * 3. If that also fails, it attempts a more lenient match for any string * that starts with `{` and ends with `}` and tries to parse that. * 4. If all parsing attempts fail, or if the resulting object is empty, * it returns a default "Parsing Error - Unclassified" object. This ensures * that the subsequent processing steps always receive an object with expected * (though potentially default) properties. * * The `span` parameter is used to provide a default `best_id` in the * fallback classification object if parsing fails, ensuring some contextual * link back to the original messages being analyzed. * * @param content The raw string content from the LLM response, expected to contain JSON. * @param span The MessageSpan object corresponding to the messages being classified. * Used for providing a fallback `best_id` if parsing fails. * @returns An `any` object representing the parsed classification. This object * will have a defined structure if parsing is successful, or a default * error structure if all parsing attempts fail. */ parseClassificationResponse(content: string, span: MessageSpan): any; } //# sourceMappingURL=semanticTurningPointDetector.d.ts.map