felix-framework / frontend /components /ParameterControls.ts
jkbennitt
Clean hf-space branch and prepare for HuggingFace Spaces deployment
fb867c3
/**
* Felix Framework - Interactive Parameter Controls
*
* Type-safe parameter controls for Felix Framework configuration with
* real-time validation, constraint enforcement, and mobile-optimized
* input handling for helix geometry, agent configuration, and system settings.
*
* Features:
* - Type-safe parameter validation
* - Real-time constraint checking
* - Dependency resolution between parameters
* - Mobile-optimized input controls
* - Undo/redo functionality
* - Parameter presets and templates
* - Export/import configurations
* - Performance impact prediction
*
* @version 1.0.0
* @author Felix Framework Team
*/
import {
GradioSlider,
GradioTextbox,
GradioCheckboxGroup,
GradioDropdown,
GradioCheckbox,
ValidationResult,
ValidationError,
ValidationWarning
} from '../types/gradio-interface';
import {
HelixGeometry,
AgentConfig,
AgentType,
TaskRequirements,
PerformanceMetrics,
Radius,
Turns,
Height,
HelixParameter
} from '../types/felix-core';
// =============================================================================
// Parameter Control Types
// =============================================================================
/** Parameter control configuration */
export interface ParameterControlConfig {
readonly id: string;
readonly label: string;
readonly description?: string;
readonly type: ParameterType;
readonly constraints: ParameterConstraints;
readonly defaultValue: unknown;
readonly dependencies?: readonly string[];
readonly mobileOptimized?: boolean;
readonly performanceImpact?: PerformanceImpact;
}
/** Parameter types */
export enum ParameterType {
Number = 'number',
Integer = 'integer',
Float = 'float',
Boolean = 'boolean',
String = 'string',
Enum = 'enum',
Range = 'range',
MultiSelect = 'multi_select'
}
/** Parameter constraints */
export interface ParameterConstraints {
readonly min?: number;
readonly max?: number;
readonly step?: number;
readonly precision?: number;
readonly options?: readonly string[];
readonly pattern?: RegExp;
readonly required?: boolean;
readonly customValidator?: (value: unknown) => ValidationResult;
}
/** Performance impact levels */
export enum PerformanceImpact {
None = 'none',
Low = 'low',
Medium = 'medium',
High = 'high',
Critical = 'critical'
}
// =============================================================================
// Helix Geometry Parameter Controls
// =============================================================================
/** Helix geometry parameter configuration */
export interface HelixGeometryParams {
readonly topRadius: number;
readonly bottomRadius: number;
readonly height: number;
readonly turns: number;
readonly resolution: number;
readonly mathematicalPrecision: number;
}
/** Helix parameter control definitions */
export const HELIX_PARAMETER_CONTROLS: Record<keyof HelixGeometryParams, ParameterControlConfig> = {
topRadius: {
id: 'helix_top_radius',
label: 'Top Radius',
description: 'Radius at the top of the helix (broad exploration phase)',
type: ParameterType.Float,
constraints: {
min: 0.1,
max: 100.0,
step: 0.1,
precision: 3,
required: true,
customValidator: (value) => validateRadius(value as number, 'top')
},
defaultValue: 33.0,
dependencies: ['bottomRadius'],
performanceImpact: PerformanceImpact.Medium
},
bottomRadius: {
id: 'helix_bottom_radius',
label: 'Bottom Radius',
description: 'Radius at the bottom of the helix (focused synthesis phase)',
type: ParameterType.Float,
constraints: {
min: 0.001,
max: 10.0,
step: 0.001,
precision: 6,
required: true,
customValidator: (value) => validateRadius(value as number, 'bottom')
},
defaultValue: 0.001,
dependencies: ['topRadius'],
performanceImpact: PerformanceImpact.Low
},
height: {
id: 'helix_height',
label: 'Helix Height',
description: 'Total height of the helix structure',
type: ParameterType.Float,
constraints: {
min: 10.0,
max: 1000.0,
step: 1.0,
precision: 1,
required: true
},
defaultValue: 100.0,
performanceImpact: PerformanceImpact.Low
},
turns: {
id: 'helix_turns',
label: 'Number of Turns',
description: 'Complete rotations in the helix (affects agent path complexity)',
type: ParameterType.Integer,
constraints: {
min: 1,
max: 100,
step: 1,
required: true,
customValidator: validateTurns
},
defaultValue: 33,
dependencies: ['resolution'],
performanceImpact: PerformanceImpact.High
},
resolution: {
id: 'helix_resolution',
label: 'Visualization Resolution',
description: 'Number of points used for helix visualization (affects rendering performance)',
type: ParameterType.Integer,
constraints: {
min: 50,
max: 2000,
step: 50,
required: true
},
defaultValue: 500,
mobileOptimized: true,
performanceImpact: PerformanceImpact.Critical
},
mathematicalPrecision: {
id: 'helix_precision',
label: 'Mathematical Precision',
description: 'Precision threshold for mathematical calculations (scientific notation)',
type: ParameterType.Float,
constraints: {
min: 1e-15,
max: 1e-6,
step: 1e-15,
precision: 15
},
defaultValue: 1e-12,
performanceImpact: PerformanceImpact.None
}
};
// =============================================================================
// Agent Configuration Parameter Controls
// =============================================================================
/** Agent configuration parameters */
export interface AgentConfigParams {
readonly maxAgents: number;
readonly spawnInterval: number;
readonly agentTypes: readonly AgentType[];
readonly temperatureSettings: Record<AgentType, number>;
readonly lifetimeSettings: Record<AgentType, number>;
readonly enableAdaptiveSpawning: boolean;
readonly enableLoadBalancing: boolean;
}
/** Agent parameter control definitions */
export const AGENT_PARAMETER_CONTROLS: Record<string, ParameterControlConfig> = {
maxAgents: {
id: 'agent_max_count',
label: 'Maximum Agents',
description: 'Maximum number of concurrent agents (affects memory usage)',
type: ParameterType.Integer,
constraints: {
min: 1,
max: 100,
step: 1,
required: true,
customValidator: validateMaxAgents
},
defaultValue: 20,
performanceImpact: PerformanceImpact.Critical
},
spawnInterval: {
id: 'agent_spawn_interval',
label: 'Spawn Interval (ms)',
description: 'Time between agent spawns in milliseconds',
type: ParameterType.Integer,
constraints: {
min: 100,
max: 10000,
step: 100,
required: true
},
defaultValue: 1000,
performanceImpact: PerformanceImpact.Medium
},
agentTypes: {
id: 'agent_types_enabled',
label: 'Enabled Agent Types',
description: 'Select which agent types are available for spawning',
type: ParameterType.MultiSelect,
constraints: {
options: Object.values(AgentType),
required: true,
customValidator: validateAgentTypes
},
defaultValue: [AgentType.Research, AgentType.Analysis, AgentType.Synthesis],
performanceImpact: PerformanceImpact.Medium
},
enableAdaptiveSpawning: {
id: 'agent_adaptive_spawning',
label: 'Adaptive Spawning',
description: 'Automatically adjust agent spawning based on task complexity',
type: ParameterType.Boolean,
constraints: {
required: false
},
defaultValue: true,
performanceImpact: PerformanceImpact.Low
},
enableLoadBalancing: {
id: 'agent_load_balancing',
label: 'Load Balancing',
description: 'Distribute tasks evenly across available agents',
type: ParameterType.Boolean,
constraints: {
required: false
},
defaultValue: true,
performanceImpact: PerformanceImpact.Low
}
};
// =============================================================================
// System Performance Parameter Controls
// =============================================================================
/** System performance parameters */
export interface SystemPerformanceParams {
readonly updateInterval: number;
readonly renderingMode: RenderingMode;
readonly memoryLimit: number;
readonly enableGPU: boolean;
readonly compressionLevel: number;
readonly cacheSize: number;
readonly logLevel: LogLevel;
}
/** Rendering modes */
export enum RenderingMode {
Quality = 'quality',
Balanced = 'balanced',
Performance = 'performance',
Mobile = 'mobile'
}
/** Log levels */
export enum LogLevel {
Debug = 'debug',
Info = 'info',
Warning = 'warning',
Error = 'error'
}
/** System parameter control definitions */
export const SYSTEM_PARAMETER_CONTROLS: Record<string, ParameterControlConfig> = {
updateInterval: {
id: 'system_update_interval',
label: 'Update Interval (ms)',
description: 'How often the system updates visualization and metrics',
type: ParameterType.Integer,
constraints: {
min: 16,
max: 5000,
step: 16,
required: true
},
defaultValue: 500,
mobileOptimized: true,
performanceImpact: PerformanceImpact.High
},
renderingMode: {
id: 'system_rendering_mode',
label: 'Rendering Mode',
description: 'Balance between visual quality and performance',
type: ParameterType.Enum,
constraints: {
options: Object.values(RenderingMode),
required: true
},
defaultValue: RenderingMode.Balanced,
mobileOptimized: true,
performanceImpact: PerformanceImpact.Critical
},
memoryLimit: {
id: 'system_memory_limit',
label: 'Memory Limit (MB)',
description: 'Maximum memory usage for the application',
type: ParameterType.Integer,
constraints: {
min: 100,
max: 8000,
step: 100,
required: true
},
defaultValue: 1000,
performanceImpact: PerformanceImpact.High
},
enableGPU: {
id: 'system_enable_gpu',
label: 'GPU Acceleration',
description: 'Use GPU for compute-intensive operations when available',
type: ParameterType.Boolean,
constraints: {
required: false,
customValidator: validateGPUAvailability
},
defaultValue: true,
performanceImpact: PerformanceImpact.Critical
},
compressionLevel: {
id: 'system_compression_level',
label: 'Data Compression',
description: 'Level of compression for data transfer (0=none, 9=maximum)',
type: ParameterType.Integer,
constraints: {
min: 0,
max: 9,
step: 1,
required: true
},
defaultValue: 3,
performanceImpact: PerformanceImpact.Medium
},
cacheSize: {
id: 'system_cache_size',
label: 'Cache Size (MB)',
description: 'Size of rendering and data cache',
type: ParameterType.Integer,
constraints: {
min: 10,
max: 500,
step: 10,
required: true
},
defaultValue: 100,
performanceImpact: PerformanceImpact.Medium
},
logLevel: {
id: 'system_log_level',
label: 'Log Level',
description: 'Minimum level for system logging',
type: ParameterType.Enum,
constraints: {
options: Object.values(LogLevel),
required: true
},
defaultValue: LogLevel.Info,
performanceImpact: PerformanceImpact.Low
}
};
// =============================================================================
// Parameter Control Manager
// =============================================================================
export class ParameterControlManager {
private currentValues: Map<string, unknown> = new Map();
private parameterHistory: ParameterHistoryEntry[] = [];
private validationResults: Map<string, ValidationResult> = new Map();
private dependencyGraph: Map<string, Set<string>> = new Map();
private changeListeners: Map<string, Set<ParameterChangeListener>> = new Map();
constructor(private readonly isMobile: boolean = false) {
this.initializeParameters();
this.buildDependencyGraph();
}
// =============================================================================
// Parameter Management
// =============================================================================
/**
* Initialize parameters with default values
*/
private initializeParameters(): void {
const allControls = {
...HELIX_PARAMETER_CONTROLS,
...AGENT_PARAMETER_CONTROLS,
...SYSTEM_PARAMETER_CONTROLS
};
Object.values(allControls).forEach(control => {
let defaultValue = control.defaultValue;
// Apply mobile optimizations
if (this.isMobile && control.mobileOptimized) {
defaultValue = this.getMobileOptimizedValue(control);
}
this.currentValues.set(control.id, defaultValue);
});
}
/**
* Get mobile-optimized parameter values
*/
private getMobileOptimizedValue(control: ParameterControlConfig): unknown {
switch (control.id) {
case 'helix_resolution':
return Math.min(control.defaultValue as number, 200);
case 'system_update_interval':
return Math.max(control.defaultValue as number, 1000);
case 'system_rendering_mode':
return RenderingMode.Mobile;
default:
return control.defaultValue;
}
}
/**
* Build dependency graph for parameter relationships
*/
private buildDependencyGraph(): void {
const allControls = {
...HELIX_PARAMETER_CONTROLS,
...AGENT_PARAMETER_CONTROLS,
...SYSTEM_PARAMETER_CONTROLS
};
Object.values(allControls).forEach(control => {
if (control.dependencies) {
control.dependencies.forEach(depId => {
if (!this.dependencyGraph.has(depId)) {
this.dependencyGraph.set(depId, new Set());
}
this.dependencyGraph.get(depId)!.add(control.id);
});
}
});
}
/**
* Set parameter value with validation and dependency checking
*/
public setParameter(parameterId: string, value: unknown): ValidationResult {
const control = this.getParameterControl(parameterId);
if (!control) {
return {
valid: false,
errors: [{ field: parameterId, message: 'Parameter not found', code: 'NOT_FOUND' }],
warnings: []
};
}
// Validate the value
const validationResult = this.validateParameter(control, value);
if (!validationResult.valid) {
this.validationResults.set(parameterId, validationResult);
return validationResult;
}
// Store previous value for history
const previousValue = this.currentValues.get(parameterId);
// Update value
this.currentValues.set(parameterId, value);
this.validationResults.set(parameterId, validationResult);
// Add to history
this.addToHistory(parameterId, previousValue, value);
// Validate dependent parameters
this.validateDependencies(parameterId);
// Notify listeners
this.notifyChangeListeners(parameterId, value, previousValue);
return validationResult;
}
/**
* Get parameter value
*/
public getParameter<T>(parameterId: string): T | undefined {
return this.currentValues.get(parameterId) as T;
}
/**
* Get all parameter values
*/
public getAllParameters(): Record<string, unknown> {
const result: Record<string, unknown> = {};
this.currentValues.forEach((value, key) => {
result[key] = value;
});
return result;
}
/**
* Reset parameters to defaults
*/
public resetToDefaults(): void {
this.currentValues.clear();
this.validationResults.clear();
this.parameterHistory.length = 0;
this.initializeParameters();
}
// =============================================================================
// Validation
// =============================================================================
/**
* Validate a parameter value
*/
private validateParameter(control: ParameterControlConfig, value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
// Type validation
if (!this.validateType(control.type, value)) {
errors.push({
field: control.id,
message: `Invalid type. Expected ${control.type}`,
code: 'INVALID_TYPE'
});
return { valid: false, errors, warnings };
}
// Constraint validation
const constraintResult = this.validateConstraints(control.constraints, value);
errors.push(...constraintResult.errors);
warnings.push(...constraintResult.warnings);
// Custom validation
if (control.constraints.customValidator) {
const customResult = control.constraints.customValidator(value);
errors.push(...customResult.errors);
warnings.push(...customResult.warnings);
}
// Performance impact warning
if (control.performanceImpact === PerformanceImpact.Critical) {
warnings.push({
field: control.id,
message: 'This parameter has critical performance impact',
suggestion: 'Consider the effect on system performance'
});
}
return {
valid: errors.length === 0,
errors,
warnings
};
}
/**
* Validate parameter type
*/
private validateType(expectedType: ParameterType, value: unknown): boolean {
switch (expectedType) {
case ParameterType.Number:
case ParameterType.Float:
case ParameterType.Integer:
return typeof value === 'number' && !isNaN(value);
case ParameterType.Boolean:
return typeof value === 'boolean';
case ParameterType.String:
return typeof value === 'string';
case ParameterType.Enum:
return typeof value === 'string';
case ParameterType.MultiSelect:
return Array.isArray(value);
case ParameterType.Range:
return Array.isArray(value) && value.length === 2 &&
typeof value[0] === 'number' && typeof value[1] === 'number';
default:
return false;
}
}
/**
* Validate parameter constraints
*/
private validateConstraints(constraints: ParameterConstraints, value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
// Required validation
if (constraints.required && (value === null || value === undefined || value === '')) {
errors.push({
field: 'value',
message: 'This parameter is required',
code: 'REQUIRED'
});
}
// Numeric constraints
if (typeof value === 'number') {
if (constraints.min !== undefined && value < constraints.min) {
errors.push({
field: 'value',
message: `Value must be at least ${constraints.min}`,
code: 'MIN_VALUE'
});
}
if (constraints.max !== undefined && value > constraints.max) {
errors.push({
field: 'value',
message: `Value must be at most ${constraints.max}`,
code: 'MAX_VALUE'
});
}
if (constraints.step !== undefined) {
const remainder = (value - (constraints.min || 0)) % constraints.step;
if (Math.abs(remainder) > 1e-10) {
errors.push({
field: 'value',
message: `Value must be a multiple of ${constraints.step}`,
code: 'STEP_VALUE'
});
}
}
}
// Options validation
if (constraints.options && typeof value === 'string') {
if (!constraints.options.includes(value)) {
errors.push({
field: 'value',
message: `Value must be one of: ${constraints.options.join(', ')}`,
code: 'INVALID_OPTION'
});
}
}
// Pattern validation
if (constraints.pattern && typeof value === 'string') {
if (!constraints.pattern.test(value)) {
errors.push({
field: 'value',
message: 'Value does not match required pattern',
code: 'PATTERN_MISMATCH'
});
}
}
return { valid: errors.length === 0, errors, warnings };
}
/**
* Validate dependent parameters when a parameter changes
*/
private validateDependencies(changedParameterId: string): void {
const dependents = this.dependencyGraph.get(changedParameterId);
if (!dependents) return;
dependents.forEach(dependentId => {
const control = this.getParameterControl(dependentId);
const value = this.currentValues.get(dependentId);
if (control && value !== undefined) {
const result = this.validateParameter(control, value);
this.validationResults.set(dependentId, result);
}
});
}
// =============================================================================
// Gradio Integration
// =============================================================================
/**
* Create Gradio slider component
*/
public createGradioSlider(parameterId: string): GradioSlider {
const control = this.getParameterControl(parameterId);
if (!control) throw new Error(`Parameter ${parameterId} not found`);
const value = this.getParameter<number>(parameterId) || 0;
const validation = this.validationResults.get(parameterId);
return {
value,
label: control.label,
info: control.description,
visible: true,
interactive: true,
minimum: control.constraints.min || 0,
maximum: control.constraints.max || 100,
step: control.constraints.step || 1,
// Additional Gradio-specific properties would be added here
};
}
/**
* Create Gradio textbox component
*/
public createGradioTextbox(parameterId: string): GradioTextbox {
const control = this.getParameterControl(parameterId);
if (!control) throw new Error(`Parameter ${parameterId} not found`);
const value = this.getParameter<string>(parameterId) || '';
return {
value,
label: control.label,
info: control.description,
visible: true,
interactive: true,
placeholder: `Enter ${control.label.toLowerCase()}...`,
type: control.type === ParameterType.String ? 'text' : 'text'
};
}
/**
* Create Gradio checkbox group component
*/
public createGradioCheckboxGroup(parameterId: string): GradioCheckboxGroup {
const control = this.getParameterControl(parameterId);
if (!control) throw new Error(`Parameter ${parameterId} not found`);
const value = this.getParameter<readonly string[]>(parameterId) || [];
return {
value,
label: control.label,
info: control.description,
visible: true,
interactive: true,
choices: control.constraints.options || []
};
}
/**
* Create Gradio dropdown component
*/
public createGradioDropdown(parameterId: string): GradioDropdown {
const control = this.getParameterControl(parameterId);
if (!control) throw new Error(`Parameter ${parameterId} not found`);
const value = this.getParameter<string>(parameterId) || '';
return {
value,
label: control.label,
info: control.description,
visible: true,
interactive: true,
choices: control.constraints.options || []
};
}
// =============================================================================
// Presets and Templates
// =============================================================================
/**
* Create parameter preset
*/
public createPreset(name: string, description: string): ParameterPreset {
return {
id: `preset_${Date.now()}`,
name,
description,
parameters: this.getAllParameters(),
createdAt: Date.now(),
version: '1.0.0'
};
}
/**
* Apply parameter preset
*/
public applyPreset(preset: ParameterPreset): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
Object.entries(preset.parameters).forEach(([parameterId, value]) => {
const result = this.setParameter(parameterId, value);
errors.push(...result.errors);
warnings.push(...result.warnings);
});
return { valid: errors.length === 0, errors, warnings };
}
/**
* Get built-in presets
*/
public getBuiltInPresets(): ParameterPreset[] {
return [
{
id: 'performance_optimized',
name: 'Performance Optimized',
description: 'Settings optimized for maximum performance',
parameters: {
'helix_resolution': 200,
'system_rendering_mode': RenderingMode.Performance,
'system_update_interval': 1000,
'agent_max_count': 10
},
createdAt: Date.now(),
version: '1.0.0'
},
{
id: 'quality_focused',
name: 'Quality Focused',
description: 'Settings optimized for visual quality',
parameters: {
'helix_resolution': 1000,
'system_rendering_mode': RenderingMode.Quality,
'system_update_interval': 250,
'agent_max_count': 20
},
createdAt: Date.now(),
version: '1.0.0'
},
{
id: 'mobile_optimized',
name: 'Mobile Optimized',
description: 'Settings optimized for mobile devices',
parameters: {
'helix_resolution': 150,
'system_rendering_mode': RenderingMode.Mobile,
'system_update_interval': 2000,
'agent_max_count': 5,
'system_compression_level': 6
},
createdAt: Date.now(),
version: '1.0.0'
}
];
}
// =============================================================================
// History and Undo/Redo
// =============================================================================
/**
* Add parameter change to history
*/
private addToHistory(parameterId: string, oldValue: unknown, newValue: unknown): void {
this.parameterHistory.push({
parameterId,
oldValue,
newValue,
timestamp: Date.now()
});
// Limit history size
if (this.parameterHistory.length > 100) {
this.parameterHistory.shift();
}
}
/**
* Undo last parameter change
*/
public undo(): boolean {
if (this.parameterHistory.length === 0) return false;
const lastChange = this.parameterHistory.pop()!;
this.currentValues.set(lastChange.parameterId, lastChange.oldValue);
// Re-validate
const control = this.getParameterControl(lastChange.parameterId);
if (control) {
const result = this.validateParameter(control, lastChange.oldValue);
this.validationResults.set(lastChange.parameterId, result);
}
return true;
}
/**
* Get parameter change history
*/
public getHistory(): readonly ParameterHistoryEntry[] {
return [...this.parameterHistory];
}
// =============================================================================
// Event Handling
// =============================================================================
/**
* Add parameter change listener
*/
public addChangeListener(parameterId: string, listener: ParameterChangeListener): void {
if (!this.changeListeners.has(parameterId)) {
this.changeListeners.set(parameterId, new Set());
}
this.changeListeners.get(parameterId)!.add(listener);
}
/**
* Remove parameter change listener
*/
public removeChangeListener(parameterId: string, listener: ParameterChangeListener): boolean {
const listeners = this.changeListeners.get(parameterId);
return listeners ? listeners.delete(listener) : false;
}
/**
* Notify change listeners
*/
private notifyChangeListeners(parameterId: string, newValue: unknown, oldValue: unknown): void {
const listeners = this.changeListeners.get(parameterId);
if (!listeners) return;
listeners.forEach(listener => {
try {
listener(parameterId, newValue, oldValue);
} catch (error) {
console.error('Error in parameter change listener:', error);
}
});
}
// =============================================================================
// Utility Methods
// =============================================================================
/**
* Get parameter control configuration
*/
private getParameterControl(parameterId: string): ParameterControlConfig | undefined {
const allControls = {
...HELIX_PARAMETER_CONTROLS,
...AGENT_PARAMETER_CONTROLS,
...SYSTEM_PARAMETER_CONTROLS
};
return Object.values(allControls).find(control => control.id === parameterId);
}
/**
* Get validation result for parameter
*/
public getValidationResult(parameterId: string): ValidationResult | undefined {
return this.validationResults.get(parameterId);
}
/**
* Check if all parameters are valid
*/
public isAllValid(): boolean {
return Array.from(this.validationResults.values()).every(result => result.valid);
}
/**
* Get performance impact summary
*/
public getPerformanceImpact(): PerformanceImpactSummary {
const impacts = Array.from(this.currentValues.keys())
.map(id => this.getParameterControl(id))
.filter(control => control?.performanceImpact)
.map(control => control!.performanceImpact!);
return {
overall: this.calculateOverallImpact(impacts),
breakdown: this.groupImpactsByLevel(impacts),
recommendations: this.getPerformanceRecommendations()
};
}
private calculateOverallImpact(impacts: PerformanceImpact[]): PerformanceImpact {
if (impacts.includes(PerformanceImpact.Critical)) return PerformanceImpact.Critical;
if (impacts.includes(PerformanceImpact.High)) return PerformanceImpact.High;
if (impacts.includes(PerformanceImpact.Medium)) return PerformanceImpact.Medium;
if (impacts.includes(PerformanceImpact.Low)) return PerformanceImpact.Low;
return PerformanceImpact.None;
}
private groupImpactsByLevel(impacts: PerformanceImpact[]): Record<PerformanceImpact, number> {
const breakdown = {
[PerformanceImpact.None]: 0,
[PerformanceImpact.Low]: 0,
[PerformanceImpact.Medium]: 0,
[PerformanceImpact.High]: 0,
[PerformanceImpact.Critical]: 0
};
impacts.forEach(impact => {
breakdown[impact]++;
});
return breakdown;
}
private getPerformanceRecommendations(): string[] {
const recommendations: string[] = [];
if (this.isMobile) {
recommendations.push('Consider using the Mobile Optimized preset for better performance');
}
const resolution = this.getParameter<number>('helix_resolution');
if (resolution && resolution > 1000) {
recommendations.push('High resolution may impact rendering performance');
}
const maxAgents = this.getParameter<number>('agent_max_count');
if (maxAgents && maxAgents > 20) {
recommendations.push('High agent count may impact system performance');
}
return recommendations;
}
}
// =============================================================================
// Supporting Types and Interfaces
// =============================================================================
/** Parameter preset configuration */
export interface ParameterPreset {
readonly id: string;
readonly name: string;
readonly description: string;
readonly parameters: Record<string, unknown>;
readonly createdAt: number;
readonly version: string;
}
/** Parameter change history entry */
export interface ParameterHistoryEntry {
readonly parameterId: string;
readonly oldValue: unknown;
readonly newValue: unknown;
readonly timestamp: number;
}
/** Parameter change listener function */
export type ParameterChangeListener = (
parameterId: string,
newValue: unknown,
oldValue: unknown
) => void;
/** Performance impact summary */
export interface PerformanceImpactSummary {
readonly overall: PerformanceImpact;
readonly breakdown: Record<PerformanceImpact, number>;
readonly recommendations: readonly string[];
}
// =============================================================================
// Validation Functions
// =============================================================================
/** Validate radius parameters */
function validateRadius(value: number, type: 'top' | 'bottom'): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
if (type === 'top' && value < 1.0) {
warnings.push({
field: 'topRadius',
message: 'Very small top radius may reduce exploration effectiveness',
suggestion: 'Consider using a radius of at least 1.0'
});
}
if (type === 'bottom' && value > 1.0) {
warnings.push({
field: 'bottomRadius',
message: 'Large bottom radius may reduce focus effectiveness',
suggestion: 'Consider using a radius less than 1.0 for better convergence'
});
}
return { valid: errors.length === 0, errors, warnings };
}
/** Validate number of turns */
function validateTurns(value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
const turns = value as number;
if (turns > 50) {
warnings.push({
field: 'turns',
message: 'High number of turns may impact visualization performance',
suggestion: 'Consider reducing turns for better performance'
});
}
if (turns < 5) {
warnings.push({
field: 'turns',
message: 'Low number of turns may reduce helix effectiveness',
suggestion: 'Consider using at least 5 turns for proper helix geometry'
});
}
return { valid: errors.length === 0, errors, warnings };
}
/** Validate maximum agents */
function validateMaxAgents(value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
const maxAgents = value as number;
if (maxAgents > 50) {
warnings.push({
field: 'maxAgents',
message: 'High agent count may cause memory issues',
suggestion: 'Consider reducing max agents for better stability'
});
}
return { valid: errors.length === 0, errors, warnings };
}
/** Validate agent types selection */
function validateAgentTypes(value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
const types = value as AgentType[];
if (types.length === 0) {
errors.push({
field: 'agentTypes',
message: 'At least one agent type must be selected',
code: 'NO_AGENTS'
});
}
if (!types.includes(AgentType.Synthesis)) {
warnings.push({
field: 'agentTypes',
message: 'Synthesis agents are recommended for task completion',
suggestion: 'Consider including synthesis agents'
});
}
return { valid: errors.length === 0, errors, warnings };
}
/** Validate GPU availability */
function validateGPUAvailability(value: unknown): ValidationResult {
const errors: ValidationError[] = [];
const warnings: ValidationWarning[] = [];
if (value === true && !window.navigator.gpu) {
warnings.push({
field: 'enableGPU',
message: 'GPU not available on this device',
suggestion: 'GPU acceleration will be disabled automatically'
});
}
return { valid: errors.length === 0, errors, warnings };
}
// Export for use in Gradio interface
export default ParameterControlManager;