bookwiz.io / lib / utils / chatNaming.ts
chatNaming.ts
Raw
const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY || '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'
const OPENROUTER_URL = 'https://openrouter.ai/api/v1/chat/completions'

/**
 * Generate a chat name using AI
 * NOTE: This is an internal system function and does not count against user's AI usage limits
 * It uses a small, efficient model (gpt-4o-mini) for a single, short generation task
 */
export async function generateChatName(firstUserMessage: string): Promise<string> {
  try {
    const response = await fetch(OPENROUTER_URL, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${OPENROUTER_API_KEY}`,
        'Content-Type': 'application/json',
        'HTTP-Referer': process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000',
        'X-Title': 'Bookwiz Chat Naming'
      },
      body: JSON.stringify({
        model: 'openai/gpt-4o-mini',
        messages: [
          {
            role: 'system',
            content: `You are a helpful assistant that creates short, memorable names for writing-related chat conversations. 
            
            Generate a concise, descriptive title (2-6 words) based on the user's message. The title should:
            - Be specific and descriptive
            - Relate to writing, editing, or creative work
            - Be professional but friendly
            - Avoid generic words like "chat", "conversation", "help"
            - Use title case
            
            Examples:
            - "Character Development Discussion"
            - "Plot Structure Review" 
            - "Dialogue Enhancement"
            - "World Building Ideas"
            - "Chapter Editing Session"
            
            Only return the title, nothing else.`
          },
          {
            role: 'user',
            content: firstUserMessage
          }
        ],
        max_tokens: 20,
        temperature: 0.7
      })
    })

    if (!response.ok) {
      throw new Error(`OpenRouter API error: ${response.status}`)
    }

    const data = await response.json()
    const generatedName = data.choices?.[0]?.message?.content?.trim()

    if (generatedName && generatedName.length > 0) {
      // Clean up the generated name (remove quotes, ensure reasonable length)
      const cleanName = generatedName
        .replace(/^["']|["']$/g, '') // Remove surrounding quotes
        .replace(/[^\w\s-]/g, '') // Remove special characters except hyphens
        .trim()

      // Ensure the name isn't too long
      if (cleanName.length > 50) {
        return cleanName.substring(0, 47) + '...'
      }

      return cleanName || getFallbackTitle(firstUserMessage)
    }

    return getFallbackTitle(firstUserMessage)
  } catch (error) {
    console.error('Error generating chat name:', error)
    return getFallbackTitle(firstUserMessage)
  }
}

function getFallbackTitle(message: string): string {
  // Fallback to truncated user message if API fails
  return message.length > 50 
    ? message.substring(0, 47) + '...'
    : message
}