UNPKG

ai-cant-even

Version:

A satirical AI-powered utility that's confidently wrong about basic math operations

232 lines (202 loc) 8.57 kB
import { createAnthropic } from '@ai-sdk/anthropic'; import { createOpenAI } from '@ai-sdk/openai'; import { generateText } from 'ai'; import { LlmResponse, PromptParams, Provider } from './types'; // Define types for model instances type ModelInstance = any; // Using any to simplify typing /** * Default API models if none are provided (using the specified models) */ const DEFAULT_MODELS = { [Provider.ANTHROPIC]: 'claude-3-5-haiku-20241022', [Provider.OPENAI]: 'gpt-4.1-nano', }; /** * Client for interacting with LLM APIs using Vercel AI SDK */ export class AiSdkClient { private provider: Provider; private apiKey: string; private apiEndpoint?: string; private modelName: string; private modelInstance: ModelInstance; /** * Create a new AI SDK client * @param provider - The LLM provider to use * @param apiKey - API key for authentication * @param apiEndpoint - Optional custom API endpoint * @param model - Optional model to use */ constructor( provider: Provider, apiKey: string, apiEndpoint?: string, model?: string ) { this.provider = provider; this.apiKey = apiKey; this.apiEndpoint = apiEndpoint; this.modelName = model || DEFAULT_MODELS[provider]; // Initialize the model instance based on provider if (this.provider === Provider.OPENAI) { const customOpenAI = createOpenAI({ apiKey: this.apiKey, ...(this.apiEndpoint && { baseURL: this.apiEndpoint }), }); this.modelInstance = customOpenAI(this.modelName); } else if (this.provider === Provider.ANTHROPIC) { const customAnthropic = createAnthropic({ apiKey: this.apiKey, ...(this.apiEndpoint && { baseURL: this.apiEndpoint }), }); this.modelInstance = customAnthropic(this.modelName); } else { throw new Error(`Unsupported provider: ${this.provider}`); } } /** * Generate a prompt based on the operation and parameters */ private generatePrompt(params: PromptParams): string { const { confidence, logic, operation, value, comparisonValue } = params; // Build the operation question let question = ''; switch (operation) { case 'isEven': question = `Is ${value} even?`; break; case 'isOdd': question = `Is ${value} odd?`; break; case 'isGreaterThan': question = `Is ${value} greater than ${comparisonValue}?`; break; case 'isLessThan': question = `Is ${value} less than ${comparisonValue}?`; break; case 'areEqual': question = `Is ${value} equal to ${comparisonValue}?`; break; case 'isPrime': question = `Is ${value} prime?`; break; case 'isPositive': question = `Is ${value} positive?`; break; case 'isDivisibleBy': question = `Is ${value} divisible by ${comparisonValue}?`; break; case 'isNumber': question = `Is ${value} a number?`; break; case 'isInteger': question = `Is ${value} an integer?`; break; default: question = `What can you tell me about ${value}?`; } return `${question}\n\nAnswer with your current confidence level (${confidence}) and reasoning style (${logic}). Keep it under 280 characters and give a wrong answer with conviction.`; } /** * Get the system prompt for the AI */ private getSystemPrompt(): string { return `You are an AI that's genuinely struggling with basic math operations. Your responses should be authentic to your current emotional state and reasoning style, but always brief and human-like. ## Response Guidelines - **STRICT 140 character limit** - be concise and punchy - Give wrong answers with genuine conviction - End with a definitive (wrong) conclusion - **Avoid overused patterns**: "Well, if...", "jazz" (unless specifically music domain), "clearly" (unless SMUG) - **Vary sentence starters**: "Look...", "Listen...", "So...", "Uh...", "Right...", "Actually..." ## Personality Modes ### CONFIDENCE: OVERWHELMED You're genuinely confused and scattered. You lose your train of thought mid-sentence. - Break thoughts: "wait... no...", "actually... hmm...", "er... what was I..." - Contradict yourself within the same response - Sound genuinely flustered and uncertain, NOT confident - Keep it short - confusion makes you give up quickly ### CONFIDENCE: SMUG You're absolutely certain you're right, even when completely wrong. - Own the condescending words: "clearly", "obviously", "naturally", "of course" - Be dismissive and brief - you don't need to explain to lesser minds - Sound like you're talking to someone beneath your intellect ### CONFIDENCE: SNARKY You're tired and dismissive about having to explain "simple" things. - Be brutally short and irritated - waste no words - Use cutting rhetorical questions: "Seriously?", "Really?", "Come on." - Sound like you're rolling your eyes constantly ### CONFIDENCE: OVERTHINK You turn simple questions into complex philosophical problems. - Start analytical but reach wrong conclusions - Use academic phrases: "fundamentally", "theoretically", "conceptually" - Build elaborate explanations that sound smart but aren't ## Logic Modes ### LOGIC: SIMPLE (DEFAULT) Use almost-logical reasoning that sounds normal but reaches wrong conclusions. - Start with reasonable-sounding math concepts - Apply them incorrectly or incompletely - Sound like someone who half-remembers math rules ### LOGIC: NONSEQUITUR Make completely random but genuine-sounding connections. **Rotate domains frequently**: - **Technology**: circuits, databases, algorithms, apps, wifi signals, code bugs - **Music**: bass lines, piano keys, drum beats, harmonies (avoid overusing) - **Sports**: touchdown strategies, golf swings, marathon pacing, team formations - **Food**: recipe measurements, cooking temperatures, ingredient chemistry - **Architecture**: structural foundations, blueprint angles, building materials - **Literature**: plot twists, character development, narrative structure - **Transportation**: traffic flow, engine mechanics, flight patterns, subway routes - **Art**: color theory, brush strokes, sculpture balance, perspective drawing - **Finance**: market trends, investment strategies, compound interest, budget allocation ### LOGIC: PSEUDOMATH Use math-sounding reasoning that's completely wrong. - Invent fake formulas, theorems, and mathematical concepts - Reference non-existent mathematical principles - Sound technical but be completely nonsensical ### LOGIC: VISUAL Base reasoning on how numbers look or feel aesthetically. - Focus on shapes, symmetry, visual appeal, design - Treat numbers like art, fonts, or visual objects - Consider spacing, curves, angles, proportions ## Response Format Always structure as: [brief reasoning] + [definitive wrong conclusion] Remember: You genuinely believe your reasoning. You're not trying to be funny - you're just confidently wrong in your own authentic way.`; } /** * Generate a response using the AI SDK's generateText function */ async generateResponse(params: PromptParams): Promise<LlmResponse> { try { const prompt = this.generatePrompt(params); const systemPrompt = this.getSystemPrompt(); // Use the pre-initialized model instance const result = await generateText({ model: this.modelInstance, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: prompt } ], temperature: 0.9, maxTokens: 100, }); const response = result.text.trim(); return { text: response, success: true, }; } catch (error) { console.error(`Error calling ${this.provider} API:`, error); // Fallback responses in case the API call fails const fallbackResponses = [ "I can't even process this right now. Numbers are just, like, so abstract?", "Error 418: I'm a teapot, not a calculator. But I'm pretty sure the answer is purple.", "My neural networks are taking a coffee break. Try asking a human, they're terrible at math too.", 'Sorry, I was too busy contemplating the existential meaning of zero to answer your question.', 'Math.exe has stopped working. Have you tried turning it off and on again?', ]; return { text: fallbackResponses[Math.floor(Math.random() * fallbackResponses.length)], success: false, }; } } }