diff --git a/package.json b/package.json new file mode 100644 index 0000000..e361b29 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "ai-reviewer", + "version": "0.0.0", + "scripts": { + "review": "node src/review.mjs" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@ztimson/ai-utils": "0.2.3", + "@ztimson/utils": "^0.28.3", + "@ztimson/node-utils": "^1.0.4" + } +} diff --git a/src/review.mjs b/src/review.mjs new file mode 100644 index 0000000..a18466b --- /dev/null +++ b/src/review.mjs @@ -0,0 +1,58 @@ +/** + * Variables: + * HOST - AI provider (ollama/anthropic/openai) + * MODEL - AI model name + * TOKEN - Access token (Omit with ollama) + * ROOT - Path to project + */ +import {Ai} from '@ztimson/ai-utils'; +import {$} from '@ztimson/node-utils'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import * as fs from 'node:fs'; + +const gitDiff = await $`git diff HEAD^..HEAD`; +const root = process.env['ROOT'] || process.cwd(), + host = process.env['HOST'], + model = process.env['MODEL'], + token = process.env['TOKEN']; + +let options = {ollama: {model, host}}; +if(host === 'anthropic') options = {anthropic: {model, token}}; +else if(host === 'openai') options = {openAi: {model, token}}; + +const ai = new Ai({ + ...options, + model: [host, model], + path: process.env['path'] || os.tmpdir(), + system: 'You are a code reviewer, use the following git diff to find any bugs and recommend changes using the `recommend` tool.', + tools: [{ + name: 'read_file', + description: 'Read contents of a file', + args: { + path: {type: 'string', description: 'Path to file relative to project root'} + }, + fn: (args) => fs.readFileSync(path.join(root, args.path), 'utf-8') + }, { + name: 'get_diff', + description: 'Check a file for differences using git', + args: { + path: {type: 'string', description: 'Path to file relative to project root'} + }, + fn: async (args) => await $`git diff HEAD^..HEAD -- ${path.join(root, args.path)}` + }, { + name: 'recommend', + description: 'Make review recommendation', + args: { + file: {type: 'string', description: 'File path'}, + line: {type: 'number', description: 'Line number', optional: true}, + comment: {type: 'string', description: 'Review comment'} + }, + fn: (args) => { + console.log(`💬 ${args.file}${args.line ? `:${args.line}` : ''} - ${args.comment}`); + // TODO: Add fetch to gitea to add comment to PR + } + }] +}); + +await ai.language.ask(gitDiff);