mirror of
				https://github.com/severian-dev/sucker.severian.dev.git
				synced 2025-10-28 04:35:45 +00:00 
			
		
		
		
	chore: 1.7
This commit is contained in:
		| @@ -4,6 +4,7 @@ Check package.json for commands, I can't be bothered. | |||||||
|  |  | ||||||
| ### Changelog | ### Changelog | ||||||
|  |  | ||||||
|  | - 1.7: Handling for nested XML character tags | ||||||
| - 1.6: First message formatting, copy button for first message and other fields | - 1.6: First message formatting, copy button for first message and other fields | ||||||
| - 1.5: {{user}} substitution for user persona name | - 1.5: {{user}} substitution for user persona name | ||||||
| - 1.4: Mooth just keeps finding bugs, damn. | - 1.4: Mooth just keeps finding bugs, damn. | ||||||
|   | |||||||
| @@ -40,49 +40,118 @@ interface PersonaMatch { | |||||||
|  |  | ||||||
| function findTagsBetween(content: string, startMarker: string): PersonaMatch[] { | function findTagsBetween(content: string, startMarker: string): PersonaMatch[] { | ||||||
|   const startMarkerTag = `<${startMarker}>`; |   const startMarkerTag = `<${startMarker}>`; | ||||||
|    |  | ||||||
|   const startIdx = content.indexOf(startMarkerTag); |   const startIdx = content.indexOf(startMarkerTag); | ||||||
|   if (startIdx === -1) return []; |   if (startIdx === -1) return []; | ||||||
|    |  | ||||||
|   const scenarioIdx = content.indexOf("<scenario>"); |   const scenarioIdx = content.indexOf("<scenario>"); | ||||||
|   const exampleIdx = content.indexOf("<example_dialogs>"); |   const exampleIdx = content.indexOf("<example_dialogs>"); | ||||||
|    |  | ||||||
|   let endIdx = content.length; |   let endIdx = content.length; | ||||||
|   if (scenarioIdx !== -1) endIdx = Math.min(endIdx, scenarioIdx); |   if (scenarioIdx !== -1) endIdx = Math.min(endIdx, scenarioIdx); | ||||||
|   if (exampleIdx !== -1) endIdx = Math.min(endIdx, exampleIdx); |   if (exampleIdx !== -1) endIdx = Math.min(endIdx, exampleIdx); | ||||||
|    |  | ||||||
|   const section = content.slice(startIdx, endIdx); |   const section = content.slice(startIdx, endIdx); | ||||||
|   const matches: PersonaMatch[] = []; |   const matches: PersonaMatch[] = []; | ||||||
|    |  | ||||||
|   const tagPattern = /<([^/>\s][^>]*)>([\s\S]*?)<\/\1>/g; |   let position = 0; | ||||||
|   let match; |  | ||||||
|    |   while (position < section.length) { | ||||||
|   try { |     const tagStart = section.indexOf("<", position); | ||||||
|     while ((match = tagPattern.exec(section)) !== null) { |     if (tagStart === -1) break; | ||||||
|       // Skip the system tag |  | ||||||
|       if (match[1] !== startMarker) { |     const tagNameEnd = section.indexOf(">", tagStart); | ||||||
|         matches.push({ |     if (tagNameEnd === -1) break; | ||||||
|           tag: match[1].trim(), |  | ||||||
|           content: match[2].trim() |     const tagName = section.substring(tagStart + 1, tagNameEnd).trim(); | ||||||
|         }); |  | ||||||
|  |     if (tagName.startsWith("/") || tagName === startMarker) { | ||||||
|  |       position = tagNameEnd + 1; | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const openTag = `<${tagName}>`; | ||||||
|  |     const closeTag = `</${tagName}>`; | ||||||
|  |  | ||||||
|  |     let openTagPos = tagStart; | ||||||
|  |     let closeTagPos = -1; | ||||||
|  |     let tagCount = 1; | ||||||
|  |     let searchPos = tagNameEnd + 1; | ||||||
|  |  | ||||||
|  |     while (searchPos < section.length && tagCount > 0) { | ||||||
|  |       const nextOpen = section.indexOf(openTag, searchPos); | ||||||
|  |       const nextClose = section.indexOf(closeTag, searchPos); | ||||||
|  |  | ||||||
|  |       if (nextClose === -1) break; | ||||||
|  |  | ||||||
|  |       if (nextOpen !== -1 && nextOpen < nextClose) { | ||||||
|  |         tagCount++; | ||||||
|  |         searchPos = nextOpen + openTag.length; | ||||||
|  |       } else { | ||||||
|  |         tagCount--; | ||||||
|  |         searchPos = nextClose + closeTag.length; | ||||||
|  |  | ||||||
|  |         if (tagCount === 0) { | ||||||
|  |           closeTagPos = nextClose; | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } catch (error) { |  | ||||||
|     console.error("Error during regex execution:", error); |     if (closeTagPos !== -1) { | ||||||
|  |       const tagContent = section.substring(tagNameEnd + 1, closeTagPos); | ||||||
|  |  | ||||||
|  |       matches.push({ | ||||||
|  |         tag: tagName, | ||||||
|  |         content: tagContent.trim(), | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       position = closeTagPos + closeTag.length; | ||||||
|  |     } else { | ||||||
|  |       position = tagNameEnd + 1; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   return matches; |   return matches; | ||||||
| } | } | ||||||
|  |  | ||||||
| function extractBetweenTags(content: string, tag: string): string { | function extractBetweenTags(content: string, tag: string): string { | ||||||
|   const startTag = `<${tag}>`; |   const startTag = `<${tag}>`; | ||||||
|   const endTag = `</${tag}>`; |   const endTag = `</${tag}>`; | ||||||
|  |  | ||||||
|   const startIndex = content.indexOf(startTag); |   const startIndex = content.indexOf(startTag); | ||||||
|   if (startIndex === -1) return ""; |   if (startIndex === -1) return ""; | ||||||
|    |  | ||||||
|   const endIndex = content.indexOf(endTag, startIndex); |   // Handle nested tags by counting opening and closing tags | ||||||
|  |   let openTagCount = 1; | ||||||
|  |   let position = startIndex + startTag.length; | ||||||
|  |   let endIndex = -1; | ||||||
|  |  | ||||||
|  |   while (position < content.length && openTagCount > 0) { | ||||||
|  |     const nextOpenTag = content.indexOf(startTag, position); | ||||||
|  |     const nextCloseTag = content.indexOf(endTag, position); | ||||||
|  |  | ||||||
|  |     // No more closing tags found | ||||||
|  |     if (nextCloseTag === -1) break; | ||||||
|  |  | ||||||
|  |     // Found another opening tag before the next closing tag | ||||||
|  |     if (nextOpenTag !== -1 && nextOpenTag < nextCloseTag) { | ||||||
|  |       openTagCount++; | ||||||
|  |       position = nextOpenTag + startTag.length; | ||||||
|  |     } | ||||||
|  |     // Found a closing tag | ||||||
|  |     else { | ||||||
|  |       openTagCount--; | ||||||
|  |       position = nextCloseTag + endTag.length; | ||||||
|  |       // If we've found the matching closing tag for our initial opening tag | ||||||
|  |       if (openTagCount === 0) { | ||||||
|  |         endIndex = nextCloseTag; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (endIndex === -1) return ""; |   if (endIndex === -1) return ""; | ||||||
|    |  | ||||||
|   return content.slice(startIndex + startTag.length, endIndex).trim(); |   return content.slice(startIndex + startTag.length, endIndex).trim(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -96,7 +165,7 @@ function extractCardData(messages: Message[]): CardData { | |||||||
|  |  | ||||||
|   // Find all persona tags between system and the first optional tag (scenario or example_dialogs) |   // Find all persona tags between system and the first optional tag (scenario or example_dialogs) | ||||||
|   const personas = findTagsBetween(content0, "system"); |   const personas = findTagsBetween(content0, "system"); | ||||||
|    |  | ||||||
|   const userPersona = personas[personas.length - 2]; |   const userPersona = personas[personas.length - 2]; | ||||||
|   const charPersona = personas[personas.length - 1]; |   const charPersona = personas[personas.length - 1]; | ||||||
|   const charName = charPersona?.tag || ""; |   const charName = charPersona?.tag || ""; | ||||||
| @@ -117,7 +186,11 @@ function extractCardData(messages: Message[]): CardData { | |||||||
|     if (field !== "name") { |     if (field !== "name") { | ||||||
|       const val = cardData[field as keyof CardData]; |       const val = cardData[field as keyof CardData]; | ||||||
|       if (typeof val === "string") { |       if (typeof val === "string") { | ||||||
|         cardData[field as keyof CardData] = safeReplace(val, userName, "{{user}}"); |         cardData[field as keyof CardData] = safeReplace( | ||||||
|  |           val, | ||||||
|  |           userName, | ||||||
|  |           "{{user}}" | ||||||
|  |         ); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -127,7 +200,11 @@ function extractCardData(messages: Message[]): CardData { | |||||||
|     if (field !== "name") { |     if (field !== "name") { | ||||||
|       const val = cardData[field as keyof CardData]; |       const val = cardData[field as keyof CardData]; | ||||||
|       if (typeof val === "string") { |       if (typeof val === "string") { | ||||||
|         cardData[field as keyof CardData] = safeReplace(val, charName, "{{char}}"); |         cardData[field as keyof CardData] = safeReplace( | ||||||
|  |           val, | ||||||
|  |           charName, | ||||||
|  |           "{{char}}" | ||||||
|  |         ); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -191,10 +191,9 @@ export default function Home() { | |||||||
|       <div className="container mx-auto px-4 py-8"> |       <div className="container mx-auto px-4 py-8"> | ||||||
|         <div className="flex justify-between items-center mb-4"> |         <div className="flex justify-between items-center mb-4"> | ||||||
|           <div> |           <div> | ||||||
|             <h1 className="text-3xl font-bold">Sucker v1.6</h1> |             <h1 className="text-3xl font-bold">Sucker v1.7</h1> | ||||||
|             <p className="text-sm text-muted-foreground"> |             <p className="text-sm text-muted-foreground"> | ||||||
|               Wherein Myscell's Not-Unreasonable, Yet Still Annoying, |               Handles nested XML character tags now, let me know how it goes. | ||||||
|               Request is Delivered with a Heavy Sigh |  | ||||||
|             </p> |             </p> | ||||||
|           </div> |           </div> | ||||||
|           <Button |           <Button | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Severian
					Severian