mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
The /buddy command was completely disabled by bun:bundle feature('BUDDY')
flag which evaluates to false at runtime. Removed all feature('BUDDY')
checks across the codebase to register the command, and added keyboard
event handling (q/Enter to dismiss) which was missing from the UI.
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import type { Message } from '../types/message.js'
|
|
import { getCompanion } from './companion.js'
|
|
import { getGlobalConfig } from '../utils/config.js'
|
|
|
|
// Simple companion observer: picks a reaction based on the last assistant message.
|
|
// This is a lightweight placeholder that generates fun reactions without an LLM call.
|
|
|
|
const DEBUGGING_QUIPS = [
|
|
'Found it!',
|
|
'Interesting...',
|
|
'Have you tried rubber duck debugging?',
|
|
'Stack trace time!',
|
|
'I see what happened.',
|
|
]
|
|
|
|
const GENERAL_QUIPS = [
|
|
'Looking good!',
|
|
'Keep it up!',
|
|
'Nice work!',
|
|
'I believe in you!',
|
|
'You got this!',
|
|
]
|
|
|
|
const CODE_QUIPS = [
|
|
'Fancy!',
|
|
'Clean code!',
|
|
'Elegant solution!',
|
|
'Ship it!',
|
|
]
|
|
|
|
function pickQuip(messages: Message[]): string | undefined {
|
|
const lastAssistant = [...messages].reverse().find(m => m.role === 'assistant')
|
|
if (!lastAssistant) return undefined
|
|
|
|
const content = Array.isArray(lastAssistant.content)
|
|
? lastAssistant.content.map(c => (typeof c === 'string' ? c : c.type === 'text' ? c.text : '')).join('')
|
|
: typeof lastAssistant.content === 'string'
|
|
? lastAssistant.content
|
|
: ''
|
|
|
|
if (!content) return undefined
|
|
|
|
// Only react occasionally (1 in 5 turns)
|
|
if (Math.random() > 0.2) return undefined
|
|
|
|
const lower = content.toLowerCase()
|
|
if (lower.includes('error') || lower.includes('bug') || lower.includes('fix') || lower.includes('debug')) {
|
|
return DEBUGGING_QUIPS[Math.floor(Math.random() * DEBUGGING_QUIPS.length)]
|
|
}
|
|
if (lower.includes('function') || lower.includes('class') || lower.includes('const') || lower.includes('```')) {
|
|
return CODE_QUIPS[Math.floor(Math.random() * CODE_QUIPS.length)]
|
|
}
|
|
return GENERAL_QUIPS[Math.floor(Math.random() * GENERAL_QUIPS.length)]
|
|
}
|
|
|
|
export async function fireCompanionObserver(
|
|
messages: Message[],
|
|
onReaction: (reaction: string) => void,
|
|
): Promise<void> {
|
|
const companion = getCompanion()
|
|
if (!companion || getGlobalConfig().companionMuted) return
|
|
|
|
const quip = pickQuip(messages)
|
|
if (quip) {
|
|
onReaction(quip)
|
|
}
|
|
}
|