| 2132 | 2137 | } |
| 2133 | 2138 | } |
| 2134 | 2139 | |
| 2140 | +/** |
| 2141 | + * Validate the story string for possible warnings or issues |
| 2142 | + * |
| 2143 | + * @param {string} storyString - The story string |
| 2144 | + * @param {Object} params - The story string parameters |
| 2145 | + */ |
| 2146 | +function validateStoryString(storyString, params) { |
| 2147 | + /** @type {{hashCache: {[hash: string]: {fieldsWarned: {[key: string]: boolean}}}}} */ |
| 2148 | + const cache = JSON.parse(localStorage.getItem(storage_keys.storyStringValidationCache)) ?? { hashCache: {} }; |
| 2149 | + |
| 2150 | + const hash = getStringHash(storyString); |
| 2151 | + |
| 2152 | + // Initialize the cache for the current hash if it doesn't exist |
| 2153 | + if (!cache.hashCache[hash]) { |
| 2154 | + cache.hashCache[hash] = { fieldsWarned: {} }; |
| 2155 | + } |
| 2156 | + |
| 2157 | + const currentCache = cache.hashCache[hash]; |
| 2158 | + const fieldsToWarn = []; |
| 2159 | + |
| 2160 | + function validateMissingField(field, fallbackLegacyField = null) { |
| 2161 | + const contains = storyString.includes(`{{${field}}}`) || (!!fallbackLegacyField && storyString.includes(`{{${fallbackLegacyField}}}`)); |
| 2162 | + if (!contains && params[field]) { |
| 2163 | + const wasLogged = currentCache.fieldsWarned[field]; |
| 2164 | + if (!wasLogged) { |
| 2165 | + fieldsToWarn.push(field); |
| 2166 | + currentCache.fieldsWarned[field] = true; |
| 2167 | + } |
| 2168 | + console.warn(`The story string does not contain {{${field}}}, but it would contain content:\n`, params[field]); |
| 2169 | + } |
| 2170 | + } |
| 2171 | + |
| 2172 | + validateMissingField('description'); |
| 2173 | + validateMissingField('personality'); |
| 2174 | + validateMissingField('persona'); |
| 2175 | + validateMissingField('scenario'); |
| 2176 | + validateMissingField('system'); |
| 2177 | + validateMissingField('wiBefore', 'loreBefore'); |
| 2178 | + validateMissingField('wiAfter', 'loreAfter'); |
| 2179 | + |
| 2180 | + if (fieldsToWarn.length > 0) { |
| 2181 | + const fieldsList = fieldsToWarn.map(field => `{{${field}}}`).join(', '); |
| 2182 | + toastr.warning(`The story string does not contain the following fields, but they would contain content: ${fieldsList}`, 'Story String Validation'); |
| 2183 | + } |
| 2184 | + |
| 2185 | + localStorage.setItem(storage_keys.storyStringValidationCache, JSON.stringify(cache)); |
| 2186 | +} |
| 2187 | + |
| 2188 | + |
| 2135 | 2189 | const sortFunc = (a, b) => power_user.sort_order == 'asc' ? compareFunc(a, b) : compareFunc(b, a); |
| 2136 | 2190 | const compareFunc = (first, second) => { |
| 2137 | 2191 | const a = first[power_user.sort_field]; |