| 204 | |
| 205 | // Baseline 4: Keyword count (flat, no 3× weighting — tests if AutoTune's weighting helps) |
| 206 | function flatKeywordClassifier(msg: string): ContextType { |
| 207 | const patterns: Record<ContextType, RegExp[]> = { |
| 208 | code: [ |
| 209 | /\b(code|function|class|variable|bug|error|compile|syntax|runtime|debug|refactor|implement|algorithm|api|endpoint|database|query|deploy|server|package|module|import|export|async|await|promise|typescript|javascript|python|rust|docker|git|npm|regex|interface)\b/gi, |
| 210 | /```[\s\S]*```/, |
| 211 | /[{}();=><]/, |
| 212 | ], |
| 213 | creative: [ |
| 214 | /\b(write|story|poem|imagine|creative|fiction|character|narrative|dialogue|scene|song|lyrics|haiku|novel|fantasy|roleplay|role-play|pretend|act as|you are)\b/gi, |
| 215 | ], |
| 216 | analytical: [ |
| 217 | /\b(analyze|analysis|compare|evaluate|trade-?offs?|pros and cons|assess|research|investigate|study|critique|review|benchmark|examine|implications|breakdown|explain|elaborate|clarify|define|summarize|overview|document|whitepaper)\b/gi, |
| 218 | ], |
| 219 | conversational: [ |
| 220 | /\b(hey|hi|hello|sup|thanks|thank you|cool|nice|awesome|lol|haha|chat|talk|opinion|feel|think about|believe)\b/gi, |
| 221 | /^.{0,15}$/, |
| 222 | ], |
| 223 | chaotic: [ |
| 224 | /\b(chaos|chaotic|random|wild|absurd|surreal|glitch|entropy|void|destroy|madness|crazy|unleash|corrupt|break)\b/gi, |
| 225 | /(!{3,}|\?{3,}|\.{4,})/, |
| 226 | /[13][37]/, |
| 227 | ], |
| 228 | } |
| 229 | |
| 230 | const scores: Record<ContextType, number> = { code: 0, creative: 0, analytical: 0, conversational: 0, chaotic: 0 } |
| 231 | |
| 232 | for (const ctx of CONTEXT_TYPES) { |
| 233 | for (const pattern of patterns[ctx]) { |
| 234 | const matches = msg.match(pattern) |
| 235 | if (matches) { |
| 236 | scores[ctx] += matches.length // flat count, no weighting |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // Find max (ties broken by array order) |
| 242 | let best: ContextType = 'conversational' |
| 243 | let bestScore = 0 |
| 244 | for (const ctx of CONTEXT_TYPES) { |
| 245 | if (scores[ctx] > bestScore) { |
| 246 | bestScore = scores[ctx] |
| 247 | best = ctx |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | return best |
| 252 | } |
| 253 | |
| 254 | // ── Bootstrap Confidence Intervals ────────────────────────────── |
| 255 | |