@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
83 lines • 3.33 kB
TypeScript
/**
* AggregationService - Server-side count and group_by aggregation for elements
*
* Provides lightweight aggregation queries that return counts and groupings
* without fetching full paginated item lists. This saves ~98% of tokens
* compared to listing all items when only counts are needed.
*
* Issue #309: Token-efficient aggregation
*
* DESIGN:
* - Uses FilterService.filter() directly (not full query pipeline) for efficiency
* - Deduplicates array values in group_by to prevent double-counting
* - Validates group_by fields against a whitelist to prevent internal field exposure
* - Stateless and safe for concurrent use
*
* @module services/query/AggregationService
*/
import { IElement } from '../../types/elements/IElement.js';
import { FilterCriteria, AggregationOptions } from './types.js';
/**
* Result of an aggregation query.
*
* @example
* ```typescript
* // Count only:
* { count: 42, element_type: 'persona' }
*
* // Count with group_by:
* { count: 42, element_type: 'persona', groups: { 'assistant': 15, 'creative': 12, 'technical': 15 } }
* ```
*/
export interface AggregationResult {
/** Total number of elements matching filters (or all elements if no filters) */
count: number;
/** Element type that was aggregated */
element_type: string;
/** Group counts when group_by is specified. Maps field values to occurrence counts. */
groups?: Record<string, number>;
}
/**
* Aggregate elements with optional filtering and grouping.
*
* Uses FilterService.filter() directly for efficiency — skips the sort and
* paginate steps that the full query pipeline would apply, since aggregation
* only needs to count elements, not order or slice them.
*
* @param elements - Full element array to aggregate over
* @param elementType - Element type string for the result
* @param options - Aggregation options (count, group_by)
* @param filters - Optional filter criteria to apply before aggregating
* @returns Aggregation result with count and optional groups
*
* @example
* ```typescript
* // Count all personas
* const result = aggregateElements(personas, 'persona', { count: true });
* // → { count: 42, element_type: 'persona' }
*
* // Count personas grouped by category
* const grouped = aggregateElements(personas, 'persona',
* { count: true, group_by: 'category' });
* // → { count: 42, element_type: 'persona', groups: { assistant: 15, creative: 27 } }
*
* // Count with filters
* const filtered = aggregateElements(personas, 'persona',
* { count: true, group_by: 'tags' },
* { status: 'active' });
* // → { count: 10, element_type: 'persona', groups: { typescript: 5, python: 3, rust: 2 } }
* ```
*/
export declare function aggregateElements(elements: IElement[], elementType: string, options: AggregationOptions, filters?: FilterCriteria): AggregationResult;
/**
* Validate aggregation options before execution.
*
* @param options - Aggregation options to validate
* @returns null if valid, error message string if invalid
*/
export declare function validateAggregationOptions(options: AggregationOptions): string | null;
/**
* Get the set of allowed group_by fields (for introspection/documentation).
*/
export declare function getAllowedGroupByFields(): string[];
//# sourceMappingURL=AggregationService.d.ts.map