pr-check / src / index.ts
index.ts
Raw
import * as path from 'path';
import { getHumanReadableTextOfNewCommitsOnCurrentBranch } from './git/getHumanReadableDiffDocument';
import { generateOpenAiPrompt } from './parsers/generateAiPrompt';
import { streamOpenAiResponse } from './openai/streamOpenAiResponse';
import { getContext } from './userinput/getContext';
import { validateState } from './validation/validateState';
import { getNumberOfTokensInPrompt } from './openai/getNumberOfTokensInPrompt';

// Since this script will be run from outside this directory, we have to force .env
// to be loaded from this directory, not the current working directory.
require('dotenv').config({ path: path.join(import.meta.dir, '..', '.env') })

// Since open AI charges based on how many tokens you use, we want to limit the number of tokens
const MAX_PROMPT_LENGTH = 10000
const COST_PER_TOKEN = 0.00001

/**
 * Uses an LLM to inspect the git diff for the current branch in the directory in which it is run.
 * The goal is to find any mistakes in the code, and report this to the user.
 */
async function main() {
  await validateState()

  const humanReadableDiffDocument = await getHumanReadableTextOfNewCommitsOnCurrentBranch()

  const contextFilesDirectory = path.join(import.meta.dir, '..', 'prompt', 'context');
  const context = await getContext(contextFilesDirectory)

  const aiPrompt = generateOpenAiPrompt(context, humanReadableDiffDocument)

  const numTokensInPrompt = getNumberOfTokensInPrompt(aiPrompt)
  if (numTokensInPrompt > MAX_PROMPT_LENGTH) {
    throw new Error(`Prompt is too long. Prompt is (${numTokensInPrompt} tokens)`)
  }

  const inputCostForPrompt = numTokensInPrompt * COST_PER_TOKEN
  const inputCostForPromptFormatted = inputCostForPrompt.toFixed(2)
  process.stdout.write("Tokens in this request: " + numTokensInPrompt + "(input cost is $" + inputCostForPromptFormatted + ") \n");

  const aiResponseStream = await streamOpenAiResponse(aiPrompt)
  for await (const chunk of aiResponseStream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }
}

main();