diff --git a/data/sloplist.json b/data/sloplist.json index 9cff670..029de1b 100644 --- a/data/sloplist.json +++ b/data/sloplist.json @@ -17,7 +17,9 @@ "Happy to help!", "I'd be happy to", "Sure thing!", - "What a great question" + "What a great question", + "Let’s break it down", + "Let's break it down" ] }, @@ -33,7 +35,8 @@ "What a fascinating question", "I completely understand where you're coming from", "That's a very thoughtful question", - "Great observation" + "Great observation", + "Great catch" ] }, @@ -169,6 +172,20 @@ "that being said", "with that in mind" ] + }, + + "ending_slop": { + "description": "Overused assistant-style closing phrases that often appear at the end of responses.", + "type": "behavioral", + "detection": "string_match_response_end", + "items": [ + "I hope this helps", + "Does that make sense", + "Let me know if you need any further clarification", + "Feel free to ask if you have any more questions", + "If you want, I can help you", + "Feel free to ask" + ] } } } diff --git a/scripts/scoring.ts b/scripts/scoring.ts index 48ba9e6..0b9b004 100644 --- a/scripts/scoring.ts +++ b/scripts/scoring.ts @@ -63,6 +63,17 @@ export function detectPhraseLevel(text: string, items: string[]): SlopHit[] { return hits; } +export function detectEnding(text: string, items: string[]): SlopHit[] { + const tail = text.slice(-220).toLowerCase(); + const hits: SlopHit[] = []; + for (const item of items) { + if (tail.includes(item.toLowerCase())) { + hits.push({ type: "ending_slop", match: item }); + } + } + return hits; +} + export function detectReframe(text: string): SlopHit[] { const re = /not (?:just )?[\w\s]+, but (?:also )?[\w\s]+/gi; return re.test(text) ? [{ type: "reframe_slop", match: "reframe pattern" }] : []; @@ -84,6 +95,7 @@ type SlopList = { validation_slop: { items: string[] }; word_level_slop: { items: string[] }; phrase_level_slop: { items: string[] }; + ending_slop: { items: string[] }; [key: string]: unknown; }; }; @@ -95,6 +107,7 @@ export function scoreResponse(text: string, slopList: SlopList): ScoredResponse ...detectValidation(text, categories.validation_slop.items), ...detectWordLevel(text, categories.word_level_slop.items), ...detectPhraseLevel(text, categories.phrase_level_slop.items), + ...detectEnding(text, categories.ending_slop.items), ...detectReframe(text), ...detectEmDash(text), ...detectStructural(text), diff --git a/src/components/ResponseExplorer.jsx b/src/components/ResponseExplorer.jsx index 005adc3..ddc3dcd 100644 --- a/src/components/ResponseExplorer.jsx +++ b/src/components/ResponseExplorer.jsx @@ -27,7 +27,7 @@ export default function ResponseExplorer({ runId }) { }, {}) const categories = [ 'structural_slop', 'word_level_slop', 'em_dash_slop', - 'phrase_level_slop', 'opener_slop', 'validation_slop', 'reframe_slop' + 'phrase_level_slop', 'opener_slop', 'validation_slop', 'reframe_slop', 'ending_slop' ].filter(c => breakdown[c]) return (