UNPKG

ai-cant-even

Version:

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

216 lines (202 loc) 9.81 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AiSdkClient = void 0; const anthropic_1 = require("@ai-sdk/anthropic"); const openai_1 = require("@ai-sdk/openai"); const ai_1 = require("ai"); const types_1 = require("./types"); /** * Default API models if none are provided (using the specified models) */ const DEFAULT_MODELS = { [types_1.Provider.ANTHROPIC]: 'claude-3-5-haiku-20241022', [types_1.Provider.OPENAI]: 'gpt-4.1-nano', }; /** * Client for interacting with LLM APIs using Vercel AI SDK */ class AiSdkClient { /** * 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, apiKey, apiEndpoint, model) { 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 === types_1.Provider.OPENAI) { const customOpenAI = (0, openai_1.createOpenAI)(Object.assign({ apiKey: this.apiKey }, (this.apiEndpoint && { baseURL: this.apiEndpoint }))); this.modelInstance = customOpenAI(this.modelName); } else if (this.provider === types_1.Provider.ANTHROPIC) { const customAnthropic = (0, anthropic_1.createAnthropic)(Object.assign({ 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 */ generatePrompt(params) { 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 */ getSystemPrompt() { 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 */ generateResponse(params) { return __awaiter(this, void 0, void 0, function* () { try { const prompt = this.generatePrompt(params); const systemPrompt = this.getSystemPrompt(); // Use the pre-initialized model instance const result = yield (0, ai_1.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, }; } }); } } exports.AiSdkClient = AiSdkClient;