Go · 11369 bytes Raw Blame History
1 package llm
2
3 import (
4 "fmt"
5 "strings"
6 )
7
8 // InsultTemplate defines components for dynamic insult generation
9 type InsultTemplate struct {
10 Prefixes []string
11 Cores []string
12 Suffixes []string
13 Modifiers []string
14 }
15
16 // Template components for dynamic generation
17 var (
18 achievementPrefixes = []string{
19 "Achievement unlocked:",
20 "Congratulations:",
21 "Well done:",
22 "Outstanding:",
23 "Impressive:",
24 "Remarkable:",
25 "Exceptional:",
26 "Unprecedented:",
27 "Historic moment:",
28 "Breaking news:",
29 "Alert:",
30 "Notable achievement:",
31 "Milestone reached:",
32 "Record broken:",
33 "Hall of shame:",
34 }
35
36 failureCores = []string{
37 "catastrophically breaking production",
38 "spectacularly failing",
39 "magnificently destroying the codebase",
40 "expertly corrupting the database",
41 "professionally crashing the server",
42 "brilliantly introducing critical bugs",
43 "masterfully deploying garbage",
44 "skillfully breaking everything",
45 "artfully creating disasters",
46 "elegantly failing upward",
47 "gracefully achieving nothing",
48 "flawlessly executing incompetence",
49 "perfectly demonstrating failure",
50 "seamlessly integrating bugs",
51 "efficiently wasting everyone's time",
52 "successfully accomplishing disaster",
53 "consistently breaking the build",
54 "reliably causing incidents",
55 "predictably failing",
56 "systematically destroying progress",
57 "methodically sabotaging the project",
58 "deliberately creating chaos",
59 "intentionally breaking everything",
60 "strategically failing",
61 "tactically creating problems",
62 }
63
64 timingSuffixes = []string{
65 "on a Friday afternoon",
66 "right before the demo",
67 "during peak hours",
68 "in front of stakeholders",
69 "right before release",
70 "during the all-hands meeting",
71 "on your first day",
72 "right after being promoted",
73 "during the CEO's visit",
74 "at the worst possible moment",
75 "right before vacation",
76 "on a Monday morning",
77 "during standup",
78 "in the production environment",
79 "right before code freeze",
80 "during the sprint review",
81 "at 11:59 PM on the deadline",
82 "right after saying 'it works on my machine'",
83 "moments after merge to main",
84 "during the live demo",
85 "in front of the entire team",
86 "right after claiming expertise",
87 "while everyone is watching",
88 "at the critical moment",
89 "during the investor pitch",
90 }
91
92 intensityModifiers = []string{
93 "Spectacularly",
94 "Catastrophically",
95 "Magnificently",
96 "Epically",
97 "Gloriously",
98 "Tremendously",
99 "Monumentally",
100 "Colossally",
101 "Phenomenally",
102 "Extraordinarily",
103 "Remarkably",
104 "Incredibly",
105 "Unbelievably",
106 "Astoundingly",
107 "Staggeringly",
108 }
109 )
110
111 // GenerateDynamicInsult creates a dynamic insult from templates
112 func GenerateDynamicInsult(ctx SmartFallbackContext, history *UserFailureHistory) string {
113 var insults []string
114
115 // Achievement-style insults
116 prefix := selectInsult(achievementPrefixes, ctx.FullCommand)
117 core := selectInsult(failureCores, ctx.FullCommand+ctx.Command)
118 suffix := selectInsult(timingSuffixes, ctx.FullCommand+fmt.Sprintf("%d", ctx.ExitCode))
119
120 insults = append(insults, fmt.Sprintf("%s %s %s.", prefix, core, suffix))
121
122 // Variable substitution insults
123 if history != nil {
124 stats := history.GetStats()
125
126 if stats.CurrentStreak >= 3 {
127 insults = append(insults,
128 fmt.Sprintf("Failure #%d in a row. Consistency: Your only skill.", stats.CurrentStreak),
129 )
130 }
131
132 if stats.WorstCommandCount > 10 && ctx.Command == stats.WorstCommand {
133 insults = append(insults,
134 fmt.Sprintf("Failed '%s' %d times. Have you considered '%s-yourself-out'?",
135 stats.WorstCommand, stats.WorstCommandCount, stats.WorstCommand),
136 )
137 }
138
139 if stats.WorstHour == ctx.TimeOfDay && stats.TodayFailures > 3 {
140 insults = append(insults,
141 fmt.Sprintf("%d:00 again? This is your power hour for disasters.", ctx.TimeOfDay),
142 )
143 }
144
145 if stats.WorstBranch == ctx.GitBranch && stats.WorstBranchCount > 5 {
146 insults = append(insults,
147 fmt.Sprintf("Breaking '%s' for the %d%s time. Team morale: -%d.",
148 ctx.GitBranch, stats.WorstBranchCount, getOrdinalSuffix(stats.WorstBranchCount),
149 stats.WorstBranchCount*10),
150 )
151 }
152
153 if stats.TotalFailures > 100 {
154 insults = append(insults,
155 fmt.Sprintf("%d total failures logged. You're in the hall of shame.", stats.TotalFailures),
156 )
157 }
158 }
159
160 // Command-specific dynamic insults
161 if ctx.Command != "" {
162 insults = append(insults, generateCommandSpecificInsult(ctx))
163 }
164
165 // Exit code specific
166 if ctx.ExitCode > 0 {
167 insults = append(insults, generateExitCodeInsult(ctx))
168 }
169
170 // Select one from generated insults
171 if len(insults) > 0 {
172 return selectInsult(insults, ctx.FullCommand)
173 }
174
175 return ""
176 }
177
178 // generateCommandSpecificInsult creates command-aware insults
179 func generateCommandSpecificInsult(ctx SmartFallbackContext) string {
180 templates := map[string][]string{
181 "git": {
182 "git {subcommand}: Commit to a new career instead.",
183 "Git error: Git good? Git out.",
184 "{command} failed: Version control can't control your incompetence.",
185 },
186 "docker": {
187 "Docker {subcommand} failed: Can't containerize catastrophe.",
188 "Container crashed: Can't contain your mistakes.",
189 "{command}: Image of failure successfully built.",
190 },
191 "npm": {
192 "npm {subcommand}: Node Package Misery delivered.",
193 "{command} failed: Dependencies: Many. Skills: None.",
194 "npm error: Not Particularly Competent detected.",
195 },
196 "cargo": {
197 "cargo {subcommand}: Can't cargo your way out of this.",
198 "Rust build failed: Your code is the rust.",
199 "{command}: Ownership model violated. Ownership of brain: Questionable.",
200 },
201 "kubectl": {
202 "kubectl {subcommand}: Kube-can't-do anything right.",
203 "Kubernetes error: Can't orchestrate competence.",
204 "{command} failed: Your cluster is the disaster.",
205 },
206 "terraform": {
207 "terraform {subcommand}: Infrastructure as Code. Incompetence as Career.",
208 "Terraform failed: Terraform your way to unemployment.",
209 "{command}: State corrupted. Mental state: Also corrupted.",
210 },
211 }
212
213 if tmpl, exists := templates[ctx.Command]; exists {
214 selected := selectInsult(tmpl, ctx.FullCommand)
215 selected = strings.ReplaceAll(selected, "{command}", ctx.Command)
216 selected = strings.ReplaceAll(selected, "{subcommand}", ctx.Subcommand)
217 return selected
218 }
219
220 return ""
221 }
222
223 // generateExitCodeInsult creates exit-code-aware insults
224 func generateExitCodeInsult(ctx SmartFallbackContext) string {
225 templates := map[int]string{
226 1: "Exit code 1: The classic. Failure so generic it's embarrassing.",
227 2: "Exit code 2: Misuse detected. Misuse of profession detected.",
228 126: "Exit code 126: Permission denied. Reality denying you success.",
229 127: "Exit code 127: Command not found. Competence: Also not found.",
230 130: "Exit code 130: Ctrl+C pressed. Career: Press Ctrl+Alt+Delete.",
231 137: "Exit code 137: Process killed. Career should be too.",
232 139: "Exit code 139: Segmentation fault. Segmented from reality.",
233 255: "Exit code 255: Maximum failure achieved. Congratulations?",
234 }
235
236 if msg, exists := templates[ctx.ExitCode]; exists {
237 return msg
238 }
239
240 return fmt.Sprintf("Exit code %d: %d reasons to reconsider your career.", ctx.ExitCode, ctx.ExitCode)
241 }
242
243 // getOrdinalSuffix returns the ordinal suffix for a number (st, nd, rd, th)
244 func getOrdinalSuffix(n int) string {
245 if n%100 >= 11 && n%100 <= 13 {
246 return "th"
247 }
248 switch n % 10 {
249 case 1:
250 return "st"
251 case 2:
252 return "nd"
253 case 3:
254 return "rd"
255 default:
256 return "th"
257 }
258 }
259
260 // GenerateStreakEscalation creates increasingly brutal insults based on streak
261 func GenerateStreakEscalation(streak int, ctx SmartFallbackContext) string {
262 if streak < 2 {
263 return ""
264 }
265
266 var templates []string
267
268 if streak >= 10 {
269 templates = []string{
270 fmt.Sprintf("%d CONSECUTIVE FAILURES. This is beyond incompetence. This is performance art.", streak),
271 fmt.Sprintf("%d IN A ROW. Your team has a betting pool on when you'll quit.", streak),
272 fmt.Sprintf("STREAK: %d. Failure this consistent requires dedication.", streak),
273 fmt.Sprintf("%d FAILURES. Even your errors have given up on you.", streak),
274 fmt.Sprintf("%d STRAIGHT. Breaking records nobody wanted broken.", streak),
275 }
276 } else if streak >= 5 {
277 templates = []string{
278 fmt.Sprintf("%d failures in a row. Einstein called: That's insanity.", streak),
279 fmt.Sprintf("Streak of %d. Consistency is key. Consistent incompetence is keyer.", streak),
280 fmt.Sprintf("%d consecutive disasters. Your specialty: Reliability in failure.", streak),
281 fmt.Sprintf("Failure #%d. This is a pattern. You are the pattern.", streak),
282 fmt.Sprintf("%d in a row. Some people learn from mistakes. You're not some people.", streak),
283 }
284 } else if streak >= 3 {
285 templates = []string{
286 fmt.Sprintf("Failure #%d in a row. Three strikes: You're out.", streak),
287 fmt.Sprintf("%d consecutive fails. Trying the same thing expecting different results?", streak),
288 fmt.Sprintf("Failure #%d. Pattern detected: You.", streak),
289 fmt.Sprintf("%d in a row. Maybe read the docs this time?", streak),
290 }
291 } else {
292 templates = []string{
293 "Second failure. The sequel nobody asked for.",
294 "Failed again. Doing it twice doesn't make it work.",
295 "Another failure. Two data points make a trend: Downward.",
296 }
297 }
298
299 return selectInsult(templates, ctx.FullCommand+fmt.Sprintf("%d", streak))
300 }
301
302 // GenerateHistoricalInsult creates insults based on long-term patterns
303 func GenerateHistoricalInsult(history *UserFailureHistory, ctx SmartFallbackContext) string {
304 if history == nil {
305 return ""
306 }
307
308 stats := history.GetStats()
309 var insults []string
310
311 // Total failures milestones
312 if stats.TotalFailures >= 1000 {
313 insults = append(insults, fmt.Sprintf("1000+ failures logged. Four digits of disappointment."))
314 } else if stats.TotalFailures >= 500 {
315 insults = append(insults, fmt.Sprintf("500+ failures. Half a thousand reasons to quit."))
316 } else if stats.TotalFailures >= 100 {
317 insults = append(insults, fmt.Sprintf("100+ failures in your history. Century of incompetence achieved."))
318 }
319
320 // Worst command patterns
321 if stats.WorstCommandCount >= 50 && ctx.Command == stats.WorstCommand {
322 insults = append(insults,
323 fmt.Sprintf("'%s' failed %d times. Definition of insanity achieved.",
324 stats.WorstCommand, stats.WorstCommandCount))
325 }
326
327 // Time patterns
328 if stats.WorstHour >= 0 && ctx.TimeOfDay == stats.WorstHour {
329 insults = append(insults,
330 fmt.Sprintf("%d:00: Your statistically worst hour. And you're proving it again.", stats.WorstHour))
331 }
332
333 // Branch disaster patterns
334 if stats.WorstBranchCount >= 20 && ctx.GitBranch == stats.WorstBranch {
335 insults = append(insults,
336 fmt.Sprintf("'%s' branch: %d failures logged. Your personal disaster zone.",
337 stats.WorstBranch, stats.WorstBranchCount))
338 }
339
340 // Longest streak
341 if stats.LongestStreak >= 10 {
342 insults = append(insults,
343 fmt.Sprintf("Personal record: %d consecutive failures. Still unbeaten.", stats.LongestStreak))
344 }
345
346 // Today's performance
347 if stats.TodayFailures >= 10 {
348 insults = append(insults,
349 fmt.Sprintf("%d failures today. Double digits of disaster before lunch.", stats.TodayFailures))
350 } else if stats.TodayFailures >= 5 {
351 insults = append(insults,
352 fmt.Sprintf("%d failures today. Productive day for disasters.", stats.TodayFailures))
353 }
354
355 if len(insults) > 0 {
356 return selectInsult(insults, ctx.FullCommand)
357 }
358
359 return ""
360 }
361