ai-cant-even
Version:
A satirical AI-powered utility that's confidently wrong about basic math operations
232 lines (202 loc) • 8.57 kB
text/typescript
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,
};
}
}
}