diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a5bdd82..b8847c1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,7 +9,5 @@ ## Checklist - - [ ] Linked issues - - [ ] Reviewed changes + - [ ] Reviewed changes (or use `Review/AI` label) - [ ] Updated comments/documentation - \ No newline at end of file diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 6401af7..78ef451 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -2,7 +2,7 @@ name: Code review on: pull_request: - types: [opened, synchronize, reopened] + types: [opened, synchronize, reopened, labeled] jobs: review: diff --git a/.github/workflows/ticket-refinement.yml b/.github/workflows/ticket-refinement.yml index 1412945..ac728ec 100644 --- a/.github/workflows/ticket-refinement.yml +++ b/.github/workflows/ticket-refinement.yml @@ -3,6 +3,7 @@ name: Ticket refinement on: issues: types: [labeled] + jobs: format: runs-on: ubuntu-latest diff --git a/package.json b/package.json index 3789c7f..56f036b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ztimson/ai-agents", - "version": "0.1.1", + "version": "0.1.2", "description": "AI agents", "keywords": ["ai", "review"], "author": "ztimson", diff --git a/src/refine.mjs b/src/refine.mjs index 9ce3b9c..b01c496 100644 --- a/src/refine.mjs +++ b/src/refine.mjs @@ -181,8 +181,9 @@ Output ONLY markdown. No explanations, labels, or extra formatting.`}); const hasDuplicates = (await ai.language.ask(`ID: ${issueData.id}\nTitle: ${title}\n\`\`\`markdown\n${body}\n\`\`\``, { system: `Your job is to identify duplicates. Respond ONLY with the duplicate's ID number or "NONE" if no match exists\n\n${dupes}` }))?.pop()?.content; + // Handle duplicates - if(hasDuplicates && hasDuplicates !== 'NONE' && (dupeId = dupeIds.find(id => id == hasDuplicates.trim()))) { + if(hasDuplicates && !hasDuplicates.toUpperCase().includes('NONE') && (dupeId = dupeIds.find(id => id == hasDuplicates.trim())) != null && dupeId != issueData.id) { await fetch(`${git}/api/v1/repos/${owner}/${repo}/issues/${ticket}/comments`, { method: 'POST', headers: {'Authorization': `token ${auth}`, 'Content-Type': 'application/json'}, diff --git a/src/review.mjs b/src/review.mjs index e1c87a3..8ff67e8 100644 --- a/src/review.mjs +++ b/src/review.mjs @@ -19,12 +19,23 @@ dotenv.config({path: '.env.local', override: true, quiet: true, debug: false}); owner = process.env['GIT_OWNER'], repo = process.env['GIT_REPO'], auth = process.env['GIT_TOKEN'], + labelEnabled = process.env['LABEL_ENABLED'] || 'Review/AI', pr = process.env['PULL_REQUEST'], host = process.env['AI_HOST'], model = process.env['AI_MODEL'], token = process.env['AI_TOKEN']; console.log(`Reviewing: ${root}\n`); + const info = await fetch(`${git}/api/v1/repos/${owner}/${repo}/pulls/${pr}`) + .then(async resp => { + if(resp.ok) return resp.json(); + throw new Error(`${resp.status} ${await resp.text()}`); + }); + if(!info.labels.some(l => l.name === labelEnabled)) { + console.log('Skipping'); + return process.exit(); + } + const branch = process.env['GIT_BRANCH'] || await $`cd ${root} && git symbolic-ref refs/remotes/origin/HEAD`; const comments = []; const commit = await $`cd ${root} && git log -1 --pretty=format:%H`; @@ -53,7 +64,7 @@ dotenv.config({path: '.env.local', override: true, quiet: true, debug: false}); ...options, model: [host, model], path: process.env['path'] || os.tmpdir(), - system: `You are a code reviewer. Analyze the git diff and use the \`recommend\` tool for EACH issue you find. You must call \`recommend\` exactly once for every bug or improvement opportunity directly related to changes. Ignore formatting recommendations. After making all recommendations, provide some concluding remarks about the overall state of the changes.${existingComments}`, + system: `You are a code reviewer. Analyze the git diff and use the \`recommend\` tool for EACH issue you find. You must call \`recommend\` exactly once for every bug or improvement opportunity directly related to changes. Ignore formatting recommendations. After making all recommendations, provide a quick 75 words or less sitrep.${existingComments}`, tools: [{ name: 'read_file', description: 'Read contents of a file', @@ -87,7 +98,16 @@ dotenv.config({path: '.env.local', override: true, quiet: true, debug: false}); }] }); - const messages = await ai.language.ask(gitDiff); + const messages = await ai.language.ask(`Title: ${info.title || 'None'} +Description: +\`\`\`md +${info.body || 'None'} +\`\`\` + +Git Diff: +\`\`\` +${gitDiff} +\`\`\``); const summary = messages.pop().content; if(git) { const res = await fetch(`${git}/api/v1/repos/${owner}/${repo}/pulls/${pr}/reviews`, {