promptenhancer / src /utils /validation.ts
Tobs248's picture
# Rolle
eee3ce2 verified
Raw
History Blame Contribute Delete
6.16 kB
ts
import { PromptValidation, CharacterWarning } from '@/types'
import { CHARACTER_LIMITS } from './constants'
/**
* Validates user prompt input
* @param prompt - The prompt to validate
* @returns Validation result with errors, warnings, and suggestions
*/
export function validatePrompt(prompt: string): PromptValidation {
const trimmedPrompt = prompt.trim()
const errors: string[] = []
const warnings: string[] = []
const suggestions: string[] = []
// Check for empty or very short prompts
if (trimmedPrompt.length === 0) {
suggestions.push('Gib hier deinen Prompt ein, den du optimieren möchtest...')
} else if (trimmedPrompt.length < CHARACTER_LIMITS.MINIMUM) {
warnings.push('Prompt ist sehr kurz. Mehr Details können zu besseren Ergebnissen führen.')
suggestions.push('Erwäge folgende Elemente hinzuzufügen:')
suggestions.push('• Kontext und Hintergrundinformationen')
suggestions.push('• Spezifische Anforderungen')
suggestions.push('• Gewünschtes Ausgabeformat')
}
// Check for questionable content
if (isQuestionablePrompt(trimmedPrompt)) {
warnings.push('Prompt enthält nur Fragenzeichen oder ist unklar formuliert.')
suggestions.push('Formuliere deine Anfrage als klare Anweisung:')
suggestions.push('• Verwende aktive Sprache ("Erstelle..." statt "Kannst du erstellen...")')
suggestions.push('• Sei spezifisch über das gewünschte Ergebnis')
suggestions.push('• Füge Beispiele oder Referenzen hinzu')
}
// Check character limits
if (trimmedPrompt.length > CHARACTER_LIMITS.INPUT) {
errors.push(`Prompt überschreitet die maximale Länge von ${CHARACTER_LIMITS.INPUT} Zeichen.`)
} else if (trimmedPrompt.length > CHARACTER_LIMITS.WARNING) {
warnings.push(`Prompt ist sehr lang (${trimmedPrompt.length} Zeichen). Einige KIs haben Token-Limits.`)
}
// Check for control characters
if (hasControlCharacters(trimmedPrompt)) {
warnings.push('Prompt enthält Steuerzeichen, die entfernt wurden.')
}
// Check for repetitive content
if (isRepetitiveContent(trimmedPrompt)) {
warnings.push('Prompt scheint repetitive Inhalte zu haben.')
suggestions.push('Entferne Wiederholungen für klarere Anweisungen.')
}
// Check for proper structure for different prompt types
const structureSuggestions = analyzePromptStructure(trimmedPrompt)
suggestions.push(...structureSuggestions)
return {
isValid: errors.length === 0 && trimmedPrompt.length > 0,
errors,
warnings,
suggestions
}
}
/**
* Sanitizes prompt input by removing unwanted characters
* @param prompt - The prompt to sanitize
* @returns Sanitized prompt
*/
export function sanitizePrompt(prompt: string): string {
return prompt
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '') // Remove control characters
.replace(/\r\n/g, '\n') // Normalize line endings
.replace(/\t/g, ' ') // Replace tabs with spaces
.replace(/[^\S\n]+$/gm, '') // Remove trailing spaces
.trim()
}
/**
* Checks if prompt contains only question marks or similar unclear content
*/
function isQuestionablePrompt(prompt: string): boolean {
const cleaned = prompt.toLowerCase().replace(/[^?]/g, '')
const questionMarkRatio = cleaned.length / Math.max(prompt.length, 1)
return questionMarkRatio > 0.7 ||
prompt.length < 10 ||
/^\?+$/.test(prompt.trim())
}
/**
* Checks for control characters in prompt
*/
function hasControlCharacters(prompt: string): boolean {
return /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/.test(prompt)
}
/**
* Checks for repetitive content patterns
*/
function isRepetitiveContent(prompt: string): boolean {
const words = prompt.toLowerCase().split(/\s+/)
const wordCount = words.length
const uniqueWords = new Set(words).size
// If less than 30% unique words, likely repetitive
return wordCount > 10 && (uniqueWords / wordCount) < 0.3
}
/**
* Analyzes prompt structure and suggests improvements
*/
function analyzePromptStructure(prompt: string): string[] {
const suggestions: string[] = []
// Check for missing role/context/task structure
const hasRole = /^(du bist|sie sind|you are|act as|role:|als)/i.test(prompt)
const hasContext = /^(kontext|context|background:|background situation:|bei)/i.test(prompt)
const hasTask = /^(aufgabe|task|erstelle|erstellen|create|schreibe|write)/i.test(prompt)
if (!hasRole && !hasContext && !hasTask && prompt.length > 50) {
suggestions.push('Strukturiere deinen Prompt nach dem Schema:')
suggestions.push('1. Rolle (wer bist du?)')
suggestions.push('2. Kontext (worüber?)')
suggestions.push('3. Aufgabe (was ist zu tun?)')
}
// Check for missing output format specification
const hasOutputFormat = /(formatiere|format|ausgabe als|output as|strukturiere)/i.test(prompt)
if (!hasOutputFormat && prompt.length > 100) {
suggestions.push('Spezifiziere das gewünschte Ausgabeformat:')
suggestions.push('• Liste, Tabelle, Absatz, JSON, etc.')
suggestions.push('• Gewünschte Länge (kurz, detailliert, etc.)')
}
return suggestions
}
/**
* Estimates token count from character count
*/
export function estimateTokenCount(characterCount: number): number {
return Math.ceil(characterCount / CHARACTER_LIMITS.TOKEN_ESTIMATE_FACTOR)
}
/**
* Gets character count warnings
*/
export function getCharacterWarnings(count: number): CharacterWarning[] {
const warnings: CharacterWarning[] = []
if (count === 0) return warnings
if (count < CHARACTER_LIMITS.MINIMUM) {
warnings.push({
type: 'warning',
message: 'Prompt ist sehr kurz. Erwäge mehr Details hinzuzufügen.'
})
}
if (count > CHARACTER_LIMITS.WARNING) {
warnings.push({
type: 'warning',
message: `Achtung: Sehr langer Prompt (${count} Zeichen) könnte Token-Limits überschreiten.`,
threshold: CHARACTER_LIMITS.WARNING
})
}
if (count > CHARACTER_LIMITS.INPUT) {
warnings.push({
type: 'error',
message: `Prompt überschreitet die maximale Länge von ${CHARACTER_LIMITS.INPUT} Zeichen.`
})
}
return warnings
}
</html>