diff --git a/tools/observer-transcript-parser.mjs b/tools/observer-transcript-parser.mjs index 5afb7c74..7932dcb6 100644 --- a/tools/observer-transcript-parser.mjs +++ b/tools/observer-transcript-parser.mjs @@ -402,15 +402,16 @@ export function extractAskUserQuestionEvents(turn) { export function classifyPromptSignal(text) { const t = String(text || '').toLowerCase().trim(); if ( - /не то\b|не так\b|переделай|отбой|\bстоп\b|почему ты|неверно|не верно|это не |не работает|не правильн|сломал|опять|снова не|всё ещё|все ещё|все еще|верни как|откат|\brevert\b|\bundo\b|still not|doesn'?t work|does not work|\bwrong\b/.test( + /не совсем|другое|другая|не сходится|wrong direction|не то\b|не так\b|переделай|отбой|\bстоп\b|почему ты|неверно|не верно|это не |не работает|не правильн|сломал|опять|снова не|всё ещё|все ещё|все еще|верни как|откат|\brevert\b|\bundo\b|still not|doesn'?t work|does not work|\bwrong\b/.test( t ) ) { return 'correction'; } - if (/^(ок|окей|ok|спасибо|супер|отлично|готово|дальше|идеально)([,\s]|$)/.test(t)) { + if (/^(ок|окей|ok|спасибо|супер|отлично|готово|дальше|идеально|класс|хорошо|принято|well done|\bnice\b)([,\s]|$)/.test(t)) { return 'approval'; } + if (/^(?:теперь|далее|следующее)(?=\s|[,.!?:;]|$)|^next\b|^now\b/.test(t)) return 'new_task'; if (classifyTask(t) !== 'other' && t.length > 15) return 'new_task'; return 'neutral'; } diff --git a/tools/observer-transcript-parser.test.mjs b/tools/observer-transcript-parser.test.mjs index dc482920..ac4bd0f8 100644 --- a/tools/observer-transcript-parser.test.mjs +++ b/tools/observer-transcript-parser.test.mjs @@ -1291,3 +1291,39 @@ describe('promptText strips blocks (Task 8)', () => { expect(ep.primary_rationale.task_classification).toBe('refactor'); }); }); + +describe('classifyPromptSignal — extended dictionary (Task 9)', () => { + it('detects "не совсем" as correction', () => { + expect(classifyPromptSignal('не совсем то')).toBe('correction'); + }); + it('detects "wrong direction" as correction', () => { + expect(classifyPromptSignal('wrong direction here')).toBe('correction'); + }); + it('detects "другое" as correction', () => { + expect(classifyPromptSignal('другое решение нужно')).toBe('correction'); + }); + it('detects "класс" as approval', () => { + expect(classifyPromptSignal('класс')).toBe('approval'); + }); + it('detects "well done" as approval', () => { + expect(classifyPromptSignal('well done')).toBe('approval'); + }); + it('detects "nice" as approval', () => { + expect(classifyPromptSignal('nice')).toBe('approval'); + }); + it('detects "теперь" prefix as new_task', () => { + expect(classifyPromptSignal('теперь сделай биллинг')).toBe('new_task'); + }); + it('detects "далее" prefix as new_task', () => { + expect(classifyPromptSignal('далее переходим к настройкам')).toBe('new_task'); + }); + it('detects "next" prefix as new_task', () => { + expect(classifyPromptSignal('next step please')).toBe('new_task'); + }); + it('preserves existing — neutral for nondescript text', () => { + expect(classifyPromptSignal('некий случайный текст')).toBe('neutral'); + }); + it('preserves existing — correction "переделай"', () => { + expect(classifyPromptSignal('переделай это')).toBe('correction'); + }); +});