codev / src /buddy /observer.ts
chenbhao's picture
init: verspercode v0.1.0
064bfd6
Raw
History Blame
2.39 kB
import { getCompanion } from './companion.js'
type MessageLike = {
type?: string
message?: {
content?: unknown
}
}
function extractText(content: unknown): string {
if (typeof content === 'string') return content
if (!Array.isArray(content)) return ''
return content
.map(block => {
if (!block || typeof block !== 'object') return ''
const candidate = block as { type?: string; text?: string }
return candidate.type === 'text' && typeof candidate.text === 'string'
? candidate.text
: ''
})
.join(' ')
.trim()
}
function findLastText(
messages: MessageLike[],
targetType: 'assistant' | 'user',
): string {
for (let i = messages.length - 1; i >= 0; i -= 1) {
const message = messages[i]
if (message?.type !== targetType) continue
const text = extractText(message.message?.content)
if (text) return text
}
return ''
}
function chooseReaction(userText: string, assistantText: string): string | undefined {
const companion = getCompanion()
if (!companion) return undefined
const loweredUser = userText.toLowerCase()
const loweredAssistant = assistantText.toLowerCase()
const directMention =
loweredUser.includes(companion.name.toLowerCase()) ||
loweredUser.includes('buddy')
if (!directMention) return undefined
if (/\b(thanks|thank you|nice|great|good job|cute)\b/.test(loweredUser)) {
return `${companion.name} looks smug for exactly one second.`
}
if (/\b(help|idea|thought|opinion|what do you think)\b/.test(loweredUser)) {
return `${companion.name} votes for the less cursed option.`
}
if (/\b(refactor|bug|error|failed|fix)\b/.test(loweredAssistant)) {
return `${companion.name} squints at the bug like it owes rent.`
}
if (/\b(done|finished|fixed|works)\b/.test(loweredAssistant)) {
return `${companion.name} seems satisfied with the outcome.`
}
return `${companion.name} is paying attention from the edge of the prompt box.`
}
export async function fireCompanionObserver(
messages: MessageLike[],
onReaction: (reaction: string | undefined) => void,
): Promise<void> {
const companion = getCompanion()
if (!companion) {
onReaction(undefined)
return
}
const userText = findLastText(messages, 'user')
const assistantText = findLastText(messages, 'assistant')
onReaction(chooseReaction(userText, assistantText))
}