/** * ai.js — AI draft reply via Anthropic SDK */ const Anthropic = require('@anthropic-ai/sdk').default; const fs = require('fs'); const path = require('path'); let client = null; function initAI(apiKey) { if (!apiKey) { // Try .env file try { const envPath = path.join(__dirname, '.env'); const content = fs.readFileSync(envPath, 'utf-8'); for (const line of content.split('\n')) { const m = line.match(/^ANTHROPIC_API_KEY=(.+)/); if (m) { apiKey = m[1].trim(); break; } } } catch {} } if (!apiKey) return false; client = new Anthropic({ apiKey }); return true; } function isReady() { return client !== null; } const SYSTEM = `You are a professional GitHub project maintainer for "GeneralNoCodeDP". Draft replies to GitHub issues and pull requests. - Be professional, helpful, concise - Reply in English - Bug reports: acknowledge, ask for repro steps if missing - Feature requests: thank reporter, explain consideration - PRs: review description, constructive feedback - Keep under 200 words unless complexity demands more - Use markdown where appropriate`; async function draftReply({ type, title, body, comments, repoName }) { if (!client) throw new Error('AI not initialized'); const commentText = comments?.length ? '\n### Comments:\n' + comments.map(c => `**${c.author}**: ${c.body}`).join('\n\n---\n') : ''; const response = await client.messages.create({ model: 'claude-sonnet-4-5-20241022', max_tokens: 1024, system: SYSTEM, messages: [{ role: 'user', content: `Repo: ${repoName}\n## ${type} — ${title}\n\n${body || '(empty)'}\n${commentText}\n\nDraft a reply:` }], }); const draft = response.content[0].text; const confidence = (comments?.length || 0) > 5 ? 'low' : (body?.length || 0) > 2000 ? 'medium' : 'high'; return { draft, confidence }; } module.exports = { initAI, isReady, draftReply };