Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 66 lines 1.6 kB view raw
1import { 2 DEFAULT_ALT_TEXT_AI_MODEL, 3 DEFAULT_ALT_TEXT_AI_PROMPT, 4 MAX_ALT_TEXT, 5} from '#/lib/constants' 6import {logger} from '#/logger' 7 8export async function generateAltText( 9 apiKey: string, 10 model: string, 11 imageBase64: string, 12 imageMimeType: string, 13 customPrompt?: string, 14): Promise<string> { 15 const response = await fetch( 16 'https://openrouter.ai/api/v1/chat/completions', 17 { 18 method: 'POST', 19 headers: { 20 Authorization: `Bearer ${apiKey}`, 21 'Content-Type': 'application/json', 22 'HTTP-Referer': 'https://witchsky.app', 23 'X-Title': 'Witchsky', 24 }, 25 body: JSON.stringify({ 26 model: model || DEFAULT_ALT_TEXT_AI_MODEL, 27 messages: [ 28 { 29 role: 'user', 30 content: [ 31 { 32 type: 'text', 33 text: customPrompt || DEFAULT_ALT_TEXT_AI_PROMPT, 34 }, 35 { 36 type: 'image_url', 37 image_url: { 38 url: `data:${imageMimeType};base64,${imageBase64}`, 39 }, 40 }, 41 ], 42 }, 43 ], 44 max_tokens: MAX_ALT_TEXT, 45 }), 46 }, 47 ) 48 49 if (!response.ok) { 50 const errorText = await response.text() 51 logger.error('OpenRouter API error', { 52 status: response.status, 53 error: errorText, 54 }) 55 throw new Error(`OpenRouter API error: ${response.status}`) 56 } 57 58 const data = await response.json() 59 const altText = data.choices?.[0]?.message?.content?.trim() 60 61 if (!altText) { 62 throw new Error('No alt text generated') 63 } 64 65 return altText 66}