ai.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * ai.js — AI draft reply via Anthropic SDK
  3. */
  4. const Anthropic = require('@anthropic-ai/sdk').default;
  5. const fs = require('fs');
  6. const path = require('path');
  7. let client = null;
  8. function initAI(apiKey) {
  9. if (!apiKey) {
  10. // Try .env file
  11. try {
  12. const envPath = path.join(__dirname, '.env');
  13. const content = fs.readFileSync(envPath, 'utf-8');
  14. for (const line of content.split('\n')) {
  15. const m = line.match(/^ANTHROPIC_API_KEY=(.+)/);
  16. if (m) { apiKey = m[1].trim(); break; }
  17. }
  18. } catch {}
  19. }
  20. if (!apiKey) return false;
  21. client = new Anthropic({ apiKey });
  22. return true;
  23. }
  24. function isReady() { return client !== null; }
  25. const SYSTEM = `You are a professional GitHub project maintainer for "GeneralNoCodeDP".
  26. Draft replies to GitHub issues and pull requests.
  27. - Be professional, helpful, concise
  28. - Reply in English
  29. - Bug reports: acknowledge, ask for repro steps if missing
  30. - Feature requests: thank reporter, explain consideration
  31. - PRs: review description, constructive feedback
  32. - Keep under 200 words unless complexity demands more
  33. - Use markdown where appropriate`;
  34. async function draftReply({ type, title, body, comments, repoName }) {
  35. if (!client) throw new Error('AI not initialized');
  36. const commentText = comments?.length
  37. ? '\n### Comments:\n' + comments.map(c => `**${c.author}**: ${c.body}`).join('\n\n---\n')
  38. : '';
  39. const response = await client.messages.create({
  40. model: 'claude-sonnet-4-5-20241022',
  41. max_tokens: 1024,
  42. system: SYSTEM,
  43. messages: [{ role: 'user', content: `Repo: ${repoName}\n## ${type} — ${title}\n\n${body || '(empty)'}\n${commentText}\n\nDraft a reply:` }],
  44. });
  45. const draft = response.content[0].text;
  46. const confidence = (comments?.length || 0) > 5 ? 'low' : (body?.length || 0) > 2000 ? 'medium' : 'high';
  47. return { draft, confidence };
  48. }
  49. module.exports = { initAI, isReady, draftReply };