Team Ai
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 21d agoView on Hugging Face
0likes1.2kdownloads
parameter-sync.service.ts208 linesDownload Raw Back to services
1/**2 * ParameterSyncService - Syncs sampling parameters with the server3 *4 * Decides for each sampling parameter whether the user's setting is an5 * override of the server default, and normalizes floating-point values.6 * No reactive state; consumed by settingsStore.7 */8 9import { SETTINGS_KEYS, SETTINGS_REGISTRY } from '$lib/constants';10import { ParameterSource, SyncableParameterType } from '$lib/enums';11import type { ParameterInfo, ParameterRecord, ParameterValue, SyncableParameter } from '$lib/types';12import { normalizeFloatingPoint } from '$lib/utils';13 14/** Mapping of UI setting keys to server parameter keys, derived from the registry. */15export const SYNCABLE_PARAMETERS: SyncableParameter[] = SETTINGS_REGISTRY.flatMap(16	(section) => section.settings17)18	.filter((s) => s.sync !== undefined)19	.map((s) => ({20		canSync: true,21		key: s.key,22		serverKey: s.sync!.serverKey,23		type: s.sync!.paramType24	}));25 26export class ParameterSyncService {27	/**28	 * Check if a parameter can be synced from server.29	 *30	 * @param key - The parameter key to check31	 * @returns True if the parameter is in the syncable parameters list32	 */33	static canSyncParameter(key: string): boolean {34		return SYNCABLE_PARAMETERS.some((param) => param.key === key && param.canSync);35	}36 37	/**38	 * Create a diff between current settings and server defaults.39	 * Shows which parameters differ from server values, useful for debugging40	 * and for the "Reset to defaults" functionality.41	 *42	 * @param currentSettings - Current parameter values in the settings store43	 * @param serverDefaults - Default values extracted from server props44	 * @returns Record of parameter diffs with current value, server value, and whether they differ45	 */46	static createParameterDiff(47		currentSettings: ParameterRecord,48		serverDefaults: ParameterRecord49	): Record<string, { current: ParameterValue; server: ParameterValue; differs: boolean }> {50		const diff: Record<51			string,52			{ current: ParameterValue; server: ParameterValue; differs: boolean }53		> = {};54 55		for (const key of this.getSyncableParameterKeys()) {56			const currentValue = currentSettings[key];57			const serverValue = serverDefaults[key];58 59			if (serverValue !== undefined) {60				diff[key] = {61					current: currentValue,62					differs: currentValue !== serverValue,63					server: serverValue64				};65			}66		}67 68		return diff;69	}70 71	/**72	 * Extract server default parameters that can be synced from `/props` response.73	 * Handles both generation settings parameters and UI-specific settings.74	 * Converts samplers array to semicolon-delimited string for UI display.75	 *76	 * @param serverParams - Raw generation settings from server `/props` endpoint77	 * @returns Record of extracted parameter key-value pairs with normalized precision78	 */79	static extractServerDefaults(80		serverParams: ApiLlamaCppServerProps['default_generation_settings']['params'] | null81	): ParameterRecord {82		const extracted: ParameterRecord = {};83 84		if (serverParams) {85			for (const param of SYNCABLE_PARAMETERS) {86				if (param.canSync && param.serverKey in serverParams) {87					const value = (serverParams as unknown as Record<string, ParameterValue>)[88						param.serverKey89					];90 91					if (value !== undefined) {92						// Apply precision rounding to avoid JavaScript floating-point issues93						extracted[param.key] = this.roundFloatingPoint(value);94					}95				}96			}97 98			// Handle samplers array conversion to string99			if (serverParams.samplers && Array.isArray(serverParams.samplers)) {100				extracted[SETTINGS_KEYS.SAMPLERS] = serverParams.samplers.join(';');101			}102		}103 104		return extracted;105	}106 107	/**108	 * Get parameter information including source and values.109	 * Used by SettingsChatParameterSourceIndicator to display the correct badge110	 * (Custom vs Default) for each parameter in the settings UI.111	 *112	 * @param key - The parameter key to get info for113	 * @param currentValue - The current value of the parameter114	 * @param propsDefaults - Server default values from `/props`115	 * @param userOverrides - Set of parameter keys explicitly overridden by the user116	 * @returns Parameter info with source, server default, and user override values117	 */118	static getParameterInfo(119		key: string,120		currentValue: ParameterValue,121		propsDefaults: ParameterRecord,122		userOverrides: Set<string>123	): ParameterInfo {124		const hasPropsDefault = propsDefaults[key] !== undefined;125		const isUserOverride = userOverrides.has(key);126		// Simple logic: either using default (from props) or custom (user override)127		const source = isUserOverride ? ParameterSource.CUSTOM : ParameterSource.DEFAULT;128 129		return {130			serverDefault: hasPropsDefault ? propsDefaults[key] : undefined, // Keep same field name for compatibility131			source,132			userOverride: isUserOverride ? currentValue : undefined,133			value: currentValue134		};135	}136 137	/**138	 * Get all syncable parameter keys.139	 *140	 * @returns Array of parameter keys that can be synced from server141	 */142	static getSyncableParameterKeys(): string[] {143		return SYNCABLE_PARAMETERS.filter((param) => param.canSync).map((param) => param.key);144	}145 146	/**147	 * Merge server defaults with current user settings.148	 * User overrides always take priority — only parameters not in `userOverrides`149	 * set will be updated from server defaults.150	 *151	 * @param currentSettings - Current parameter values in the settings store152	 * @param serverDefaults - Default values extracted from server props153	 * @param userOverrides - Set of parameter keys explicitly overridden by the user154	 * @returns Merged parameter record with user overrides preserved155	 */156	static mergeWithServerDefaults(157		currentSettings: ParameterRecord,158		serverDefaults: ParameterRecord,159		userOverrides: Set<string> = new Set()160	): ParameterRecord {161		const merged = { ...currentSettings };162 163		for (const [key, serverValue] of Object.entries(serverDefaults)) {164			// Only update if user hasn't explicitly overridden this parameter165			if (!userOverrides.has(key)) {166				merged[key] = this.roundFloatingPoint(serverValue);167			}168		}169 170		return merged;171	}172 173	/**174	 * Validate a server parameter value against its expected type.175	 *176	 * @param key - The parameter key to validate177	 * @param value - The value to validate178	 * @returns True if value matches the expected type for this parameter179	 */180	static validateServerParameter(key: string, value: ParameterValue): boolean {181		const param = SYNCABLE_PARAMETERS.find((p) => p.key === key);182 183		if (!param) return false;184 185		switch (param.type) {186			case SyncableParameterType.NUMBER:187				return typeof value === 'number' && !isNaN(value);188			case SyncableParameterType.STRING:189				return typeof value === 'string';190			case SyncableParameterType.BOOLEAN:191				return typeof value === 'boolean';192			default:193				return false;194		}195	}196 197	/**198	 * Round floating-point numbers to avoid JavaScript precision issues.199	 * E.g., 0.1 + 0.2 = 0.30000000000000004 → 0.3200	 *201	 * @param value - Parameter value to normalize202	 * @returns Precision-normalized value203	 */204	private static roundFloatingPoint(value: ParameterValue): ParameterValue {205		return normalizeFloatingPoint(value) as ParameterValue;206	}207}208