From d37daee1670c361a14c5f5a2c7c79db102701a1e Mon Sep 17 00:00:00 2001
From: msukkari
Date: Wed, 7 May 2025 16:30:46 -0700
Subject: [PATCH 01/15] push review agent implementation
---
packages/agents/reviewAgent/.gitignore | 136 +++
packages/agents/reviewAgent/app.ts | 66 ++
.../reviewAgent/nodes/fetch_file_content.ts | 49 +
.../nodes/generate_diff_review_prompt.ts | 44 +
.../reviewAgent/nodes/generate_pr_reviews.ts | 46 +
.../reviewAgent/nodes/github_pr_parser.ts | 59 ++
.../nodes/github_push_pr_reviews.ts | 32 +
.../nodes/invoke_diff_review_llm.ts | 33 +
packages/agents/reviewAgent/package.json | 37 +
packages/agents/reviewAgent/tsconfig.json | 114 +++
packages/agents/reviewAgent/types.ts | 48 +
packages/agents/reviewAgent/yarn.lock | 842 ++++++++++++++++++
staging/fly.toml | 28 -
13 files changed, 1506 insertions(+), 28 deletions(-)
create mode 100644 packages/agents/reviewAgent/.gitignore
create mode 100644 packages/agents/reviewAgent/app.ts
create mode 100644 packages/agents/reviewAgent/nodes/fetch_file_content.ts
create mode 100644 packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts
create mode 100644 packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
create mode 100644 packages/agents/reviewAgent/nodes/github_pr_parser.ts
create mode 100644 packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
create mode 100644 packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts
create mode 100644 packages/agents/reviewAgent/package.json
create mode 100644 packages/agents/reviewAgent/tsconfig.json
create mode 100644 packages/agents/reviewAgent/types.ts
create mode 100644 packages/agents/reviewAgent/yarn.lock
delete mode 100644 staging/fly.toml
diff --git a/packages/agents/reviewAgent/.gitignore b/packages/agents/reviewAgent/.gitignore
new file mode 100644
index 00000000..1170717c
--- /dev/null
+++ b/packages/agents/reviewAgent/.gitignore
@@ -0,0 +1,136 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.pnpm-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+web_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variable files
+.env
+.env.development.local
+.env.test.local
+.env.production.local
+.env.local
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+out
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+.temp
+.cache
+
+# vitepress build output
+**/.vitepress/dist
+
+# vitepress cache directory
+**/.vitepress/cache
+
+# Docusaurus cache and generated files
+.docusaurus
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# yarn v2
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.yarn/install-state.gz
+.pnp.*
diff --git a/packages/agents/reviewAgent/app.ts b/packages/agents/reviewAgent/app.ts
new file mode 100644
index 00000000..ba48f082
--- /dev/null
+++ b/packages/agents/reviewAgent/app.ts
@@ -0,0 +1,66 @@
+import dotenv from 'dotenv';
+import { App, Octokit } from "octokit";
+import { createNodeMiddleware } from "@octokit/webhooks";
+import fs from "fs";
+import http from "http";
+import { WebhookEventDefinition } from "@octokit/webhooks/types";
+import { generate_pr_reviews } from './nodes/generate_pr_reviews.js';
+import { github_push_pr_reviews } from './nodes/github_push_pr_reviews.js';
+import { github_pr_parser } from './nodes/github_pr_parser.js';
+
+dotenv.config();
+const appId = process.env.APP_ID as string;
+const webhookSecret = process.env.WEBHOOK_SECRET as string;
+const privateKeyPath = process.env.PRIVATE_KEY_PATH as string;
+
+const privateKey = fs.readFileSync(privateKeyPath, "utf8");
+
+const app = new App({
+ appId: appId,
+ privateKey: privateKey,
+ webhooks: {
+ secret: webhookSecret
+ },
+});
+
+const rules = [
+ "Do NOT provide general feedback, summaries, explanations of changes, or praises for making good additions.",
+ "Do NOT provide any advice that is not actionable or directly related to the changes.",
+ "Focus solely on offering specific, objective insights based on the given context and refrain from making broad comments about potential impacts on the system or question intentions behind the changes.",
+ "Keep comments concise and to the point. Every comment must highlight a specific issue and provide a clear and actionable solution to the developer.",
+ "If there are no issues found on a line range, do NOT respond with any comments. This includes comments such as \"No issues found\" or \"LGTM\"."
+]
+
+async function handlePullRequestOpened({
+ octokit,
+ payload,
+}: {
+ octokit: Octokit;
+ payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">;
+}) {
+ console.log(`Received a pull request event for #${payload.pull_request.number}`);
+
+ const prPayload = await github_pr_parser(octokit, payload);
+ const fileDiffReviews = await generate_pr_reviews(prPayload, rules);
+ await github_push_pr_reviews(app, prPayload, fileDiffReviews);
+}
+
+app.webhooks.on("pull_request.opened", handlePullRequestOpened);
+app.webhooks.on("pull_request.synchronize", handlePullRequestOpened);
+
+app.webhooks.onError((error) => {
+ console.error(error);
+});
+
+
+const port = 3050;
+const host = 'localhost';
+const path = "/api/webhook";
+const localWebhookUrl = `http://${host}:${port}${path}`;
+
+const middleware = createNodeMiddleware(app.webhooks, { path });
+
+http.createServer(middleware).listen(port, () => {
+ console.log(`Server is listening for events at: ${localWebhookUrl}`);
+ console.log('Press Ctrl + C to quit.')
+});
diff --git a/packages/agents/reviewAgent/nodes/fetch_file_content.ts b/packages/agents/reviewAgent/nodes/fetch_file_content.ts
new file mode 100644
index 00000000..2c90633e
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/fetch_file_content.ts
@@ -0,0 +1,49 @@
+import { sourcebot_context, sourcebot_pr_payload } from "../types.js";
+import { z } from "zod";
+
+// TODO: use original Sourcebot schemas instead of redefining here
+const fileSourceResponseSchema = z.object({
+ source: z.string(),
+ language: z.string(),
+});
+
+const base64Decode = (base64: string): string => {
+ const binString = atob(base64);
+ return Buffer.from(Uint8Array.from(binString, (m) => m.codePointAt(0)!).buffer).toString();
+}
+
+export const fetch_file_content = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
+ console.log("Executing fetch_file_content");
+
+ const fileSourceRequest = {
+ fileName: filename,
+ repository: pr_payload.hostDomain + "/" + pr_payload.owner + "/" + pr_payload.repo,
+ }
+ console.log(JSON.stringify(fileSourceRequest, null, 2));
+
+ const response = await fetch('http://localhost:3000/api/source', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Org-Domain': '~'
+ },
+ body: JSON.stringify(fileSourceRequest)
+ });
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch file content: ${response.statusText}`);
+ }
+
+ const responseData = await response.json();
+ const fileSourceResponse = fileSourceResponseSchema.parse(responseData);
+ const fileContent = base64Decode(fileSourceResponse.source);
+
+ const fileContentContext: sourcebot_context = {
+ type: "file_content",
+ description: `The content of the file ${filename}`,
+ context: fileContent,
+ }
+
+ console.log("Completed fetch_file_content");
+ return fileContentContext;
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts b/packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts
new file mode 100644
index 00000000..16c22706
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts
@@ -0,0 +1,44 @@
+import { sourcebot_diff, sourcebot_context, sourcebot_diff_review_schema } from "../types.js";
+import { zodToJsonSchema } from "zod-to-json-schema";
+
+export const generate_diff_review_prompt = async (diff: sourcebot_diff, context: sourcebot_context[], rules: string[]) => {
+ console.log("Executing generate_diff_review_prompt");
+
+ const prompt = `
+ You are an expert software engineer that excells at reviewing code changes. Given the input, additional context, and rules defined below, review the code changes and provide a detailed review. The review you provide
+ must conform to all of the rules defined below. The output format of your review must conform to the output format defined below.
+
+ # Input
+
+ The input is the old and new code snippets, which represent a single hunk from a git diff. The old code snippet is the code before the changes were made, and the new code snippet is the code after the changes were made. Each code snippet
+ is a sequence of lines each with a line number.
+
+ ## Old Code Snippet
+
+ \`\`\`
+ ${diff.oldSnippet}
+ \`\`\`
+
+ ## New Code Snippet
+
+ \`\`\`
+ ${diff.newSnippet}
+ \`\`\`
+
+ # Additional Context
+
+ ${context.map(c => `${c.type}: ${c.description}\n\n${c.context}`).join("\n\n----------------------\n\n")}
+
+ # Rules
+
+ - ${rules.join("\n- ")}
+
+ # Output Format (JSON Schema)
+ The output must be a valid JSON object that conforms to the following JSON schema. Do NOT respond with anything other than the JSON object. Do NOT respond with
+ the JSON object in a markdown code block.
+ ${JSON.stringify(zodToJsonSchema(sourcebot_diff_review_schema), null, 2)}
+ `;
+
+ console.log("Completed generate_diff_review_prompt");
+ return prompt;
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts b/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
new file mode 100644
index 00000000..e3666252
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
@@ -0,0 +1,46 @@
+import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "../types.js";
+import { generate_diff_review_prompt } from "./generate_diff_review_prompt.js";
+import { invoke_diff_review_llm } from "./invoke_diff_review_llm.js";
+import { fetch_file_content } from "./fetch_file_content.js";
+
+export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
+ console.log("Executing generate_pr_reviews");
+
+ const file_diff_reviews: sourcebot_file_diff_review[] = [];
+ for (const file_diff of pr_payload.file_diffs) {
+ const reviews: sourcebot_diff_review[] = [];
+
+ for (const diff of file_diff.diffs) {
+ const fileContentContext = await fetch_file_content(pr_payload, file_diff.to);
+ const context: sourcebot_context[] = [
+ {
+ type: "pr_title",
+ description: "The title of the pull request",
+ context: pr_payload.title,
+ },
+ {
+ type: "pr_description",
+ description: "The description of the pull request",
+ context: pr_payload.description,
+ },
+ fileContentContext,
+ ];
+
+ const prompt = await generate_diff_review_prompt(diff, context, rules);
+ console.log(prompt);
+
+ const diffReview = await invoke_diff_review_llm(prompt, file_diff.to);
+ reviews.push(diffReview);
+ }
+
+ if (reviews.length > 0) {
+ file_diff_reviews.push({
+ filename: file_diff.to,
+ reviews: reviews,
+ });
+ }
+ }
+
+ console.log("Completed generate_pr_reviews");
+ return file_diff_reviews;
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/github_pr_parser.ts b/packages/agents/reviewAgent/nodes/github_pr_parser.ts
new file mode 100644
index 00000000..9cb8e990
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/github_pr_parser.ts
@@ -0,0 +1,59 @@
+import { sourcebot_pr_payload, sourcebot_file_diff, sourcebot_diff } from "../types.js"
+import { WebhookEventDefinition } from "@octokit/webhooks/types";
+import parse from "parse-diff";
+import { Octokit } from "octokit";
+
+export const github_pr_parser = async (octokit: Octokit, payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">): Promise => {
+ console.log("Executing github_pr_parser");
+
+ const diff = await octokit.request(payload.pull_request.patch_url);
+ const parsedDiff: parse.File[] = parse(diff.data);
+
+ const sourcebotFileDiffs: (sourcebot_file_diff | null)[] = parsedDiff.map((file) => {
+ if (!file.from || !file.to) {
+ console.log(`Skipping file due to missing from (${file.from}) or to (${file.to})`)
+ return null;
+ }
+
+ const diffs: sourcebot_diff[] = file.chunks.map((chunk) => {
+ let oldSnippet = "";
+ let newSnippet = "";
+
+ for (const change of chunk.changes) {
+ if (change.type === "normal") {
+ oldSnippet += change.ln1 + ":" + change.content;
+ newSnippet += change.ln2 + ":" + change.content;
+ } else if (change.type === "add") {
+ newSnippet += change.ln + ":" + change.content;
+ } else if (change.type === "del") {
+ oldSnippet += change.ln + ":" + change.content;
+ }
+ }
+
+ return {
+ oldSnippet: oldSnippet,
+ newSnippet: newSnippet,
+ }
+ });
+
+ return {
+ from: file.from,
+ to: file.to,
+ diffs: diffs,
+ }
+ });
+ const filteredSourcebotFileDiffs: sourcebot_file_diff[] = sourcebotFileDiffs.filter((file) => file !== null) as sourcebot_file_diff[];
+
+ console.log("Completed github_pr_parser");
+ return {
+ title: payload.pull_request.title,
+ description: payload.pull_request.body ?? "",
+ hostDomain: "github.com",
+ owner: payload.repository.owner.login,
+ repo: payload.repository.name,
+ file_diffs: filteredSourcebotFileDiffs,
+ number: payload.pull_request.number,
+ head_sha: payload.pull_request.head.sha,
+ installation_id: payload.installation!.id,
+ }
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts b/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
new file mode 100644
index 00000000..38b77144
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
@@ -0,0 +1,32 @@
+import { App } from "octokit";
+import { sourcebot_pr_payload, sourcebot_file_diff_review } from "../types.js";
+
+export const github_push_pr_reviews = async (app: App, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
+ console.log("Executing github_push_pr_reviews");
+
+ const installationId = pr_payload.installation_id;
+ const installation = await app.getInstallationOctokit(installationId);
+
+ for (const file_diff_review of file_diff_reviews) {
+ for (const review of file_diff_review.reviews) {
+ await installation.rest.pulls.createReviewComment({
+ owner: pr_payload.owner,
+ repo: pr_payload.repo,
+ pull_number: pr_payload.number,
+ body: review.review,
+ path: file_diff_review.filename,
+ commit_id: pr_payload.head_sha,
+ side: "RIGHT",
+ ...(review.line_start === review.line_end
+ ? { line: review.line_start }
+ : {
+ start_line: review.line_start,
+ line: review.line_end,
+ start_side: "RIGHT",
+ }),
+ });
+ }
+ }
+
+ console.log("Completed github_push_pr_reviews");
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts b/packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts
new file mode 100644
index 00000000..38e748d3
--- /dev/null
+++ b/packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts
@@ -0,0 +1,33 @@
+import OpenAI from "openai";
+import dotenv from "dotenv";
+import { sourcebot_diff_review_schema, sourcebot_diff_review } from "../types.js";
+
+dotenv.config();
+const openai = new OpenAI({
+ apiKey: process.env.OPENAI_API_KEY,
+});
+
+export const invoke_diff_review_llm = async (prompt: string, filename: string): Promise => {
+ console.log("Executing invoke_diff_review_llm");
+
+ try {
+ const completion = await openai.chat.completions.create({
+ model: "gpt-4.1-mini",
+ messages: [
+ { role: "system", content: prompt }
+ ]
+ });
+
+ const openaiResponse = completion.choices[0].message.content;
+ console.log("OpenAI response: ", openaiResponse);
+
+ const diffReviewJson = JSON.parse(openaiResponse || '');
+ const diffReview = sourcebot_diff_review_schema.parse(diffReviewJson);
+
+ console.log("Completed invoke_diff_review_llm");
+ return diffReview;
+ } catch (error) {
+ console.error('Error calling OpenAI:', error);
+ throw error;
+ }
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/package.json b/packages/agents/reviewAgent/package.json
new file mode 100644
index 00000000..970d6d33
--- /dev/null
+++ b/packages/agents/reviewAgent/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "review-agent",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "type": "module",
+ "scripts": {
+ "build": "tsc",
+ "start": "node dist/app.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/sourcebot-dev/review-agent.git"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/sourcebot-dev/review-agent/issues"
+ },
+ "homepage": "https://github.com/sourcebot-dev/review-agent#readme",
+ "dependencies": {
+ "@octokit/webhooks": "^13.8.2",
+ "@octokit/webhooks-definitions": "octokit/webhooks",
+ "dotenv": "^16.5.0",
+ "octokit": "^4.1.3",
+ "openai": "^4.97.0",
+ "parse-diff": "^0.11.1",
+ "zod": "^3.24.4",
+ "zod-to-json-schema": "^3.24.5"
+ },
+ "devDependencies": {
+ "@types/node": "^22.15.8",
+ "smee-client": "^3.1.1",
+ "typescript": "^5.8.3"
+ }
+}
diff --git a/packages/agents/reviewAgent/tsconfig.json b/packages/agents/reviewAgent/tsconfig.json
new file mode 100644
index 00000000..e2e61a95
--- /dev/null
+++ b/packages/agents/reviewAgent/tsconfig.json
@@ -0,0 +1,114 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "libReplacement": true, /* Enable lib replacement. */
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "NodeNext", /* Specify what module code is generated. */
+ "moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+ // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+ // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
+ // "resolveJsonModule": true, /* Enable importing .json files. */
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ "outDir": "dist", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
+ // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ },
+ "include": ["**/*.ts"],
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/packages/agents/reviewAgent/types.ts b/packages/agents/reviewAgent/types.ts
new file mode 100644
index 00000000..1aed52b5
--- /dev/null
+++ b/packages/agents/reviewAgent/types.ts
@@ -0,0 +1,48 @@
+import { z } from "zod";
+
+export const sourcebot_diff_schema = z.object({
+ oldSnippet: z.string(),
+ newSnippet: z.string(),
+});
+export type sourcebot_diff = z.infer;
+
+export const sourcebot_file_diff_schema = z.object({
+ from: z.string(),
+ to: z.string(),
+ diffs: z.array(sourcebot_diff_schema),
+});
+export type sourcebot_file_diff = z.infer;
+
+export const sourcebot_pr_payload_schema = z.object({
+ title: z.string(),
+ description: z.string(),
+ hostDomain: z.string(),
+ owner: z.string(),
+ repo: z.string(),
+ file_diffs: z.array(sourcebot_file_diff_schema),
+ number: z.number(),
+ head_sha: z.string(),
+ installation_id: z.number(),
+});
+export type sourcebot_pr_payload = z.infer;
+
+export const sourcebot_context_schema = z.object({
+ type: z.enum(["pr_title", "pr_description", "pr_summary", "comment_chains", "file_content"]),
+ description: z.string().optional(),
+ context: z.string(),
+});
+export type sourcebot_context = z.infer;
+
+export const sourcebot_diff_review_schema = z.object({
+ line_start: z.number(),
+ line_end: z.number(),
+ review: z.string(),
+});
+export type sourcebot_diff_review = z.infer;
+
+export const sourcebot_file_diff_review_schema = z.object({
+ filename: z.string(),
+ reviews: z.array(sourcebot_diff_review_schema),
+});
+export type sourcebot_file_diff_review = z.infer;
+
diff --git a/packages/agents/reviewAgent/yarn.lock b/packages/agents/reviewAgent/yarn.lock
new file mode 100644
index 00000000..52f37e65
--- /dev/null
+++ b/packages/agents/reviewAgent/yarn.lock
@@ -0,0 +1,842 @@
+# This file is generated by running "yarn install" inside your project.
+# Manual changes might be lost - proceed with caution!
+
+__metadata:
+ version: 8
+ cacheKey: 10c0
+
+"@octokit/app@npm:^15.1.6":
+ version: 15.1.6
+ resolution: "@octokit/app@npm:15.1.6"
+ dependencies:
+ "@octokit/auth-app": "npm:^7.2.1"
+ "@octokit/auth-unauthenticated": "npm:^6.1.3"
+ "@octokit/core": "npm:^6.1.5"
+ "@octokit/oauth-app": "npm:^7.1.6"
+ "@octokit/plugin-paginate-rest": "npm:^12.0.0"
+ "@octokit/types": "npm:^14.0.0"
+ "@octokit/webhooks": "npm:^13.6.1"
+ checksum: 10c0/865098127d85cc58adda78c9b86cae58c502410a0d9c23d6eeabe633bc6c5e7d5f8901f243c519a0ce72342a8d08d73f120b32a864a8f6e4eeb3ad33326b6825
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-app@npm:^7.2.1":
+ version: 7.2.1
+ resolution: "@octokit/auth-app@npm:7.2.1"
+ dependencies:
+ "@octokit/auth-oauth-app": "npm:^8.1.4"
+ "@octokit/auth-oauth-user": "npm:^5.1.4"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ toad-cache: "npm:^3.7.0"
+ universal-github-app-jwt: "npm:^2.2.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/da8890ad8ae554697a4d58427d7633c8d4d6f7acbfc14e98345b85035cca6773c393f5db5767b455dfc8de9bc5bac4da2d24e443cd48e701de11dd52fa128385
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-app@npm:^8.1.3, @octokit/auth-oauth-app@npm:^8.1.4":
+ version: 8.1.4
+ resolution: "@octokit/auth-oauth-app@npm:8.1.4"
+ dependencies:
+ "@octokit/auth-oauth-device": "npm:^7.1.5"
+ "@octokit/auth-oauth-user": "npm:^5.1.4"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/2e50711be9ee6c3bf85cf1d58a1d8ae56c36eb894dcfdacabda92b9454b2c49bccc56fb1a989d3e56625885f1ef36278cc01f65c01cde6e3b505b363eac66cc6
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-device@npm:^7.1.5":
+ version: 7.1.5
+ resolution: "@octokit/auth-oauth-device@npm:7.1.5"
+ dependencies:
+ "@octokit/oauth-methods": "npm:^5.1.5"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/f93a67473c58e8b855af15c7300a0937c9d3c6ea898e5e810f2f9762100c6cee22ae52e18c7f926b0e4c6c52573751d4c4ab6294c44116bed2d9fdde5cbdd35d
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-user@npm:^5.1.3, @octokit/auth-oauth-user@npm:^5.1.4":
+ version: 5.1.4
+ resolution: "@octokit/auth-oauth-user@npm:5.1.4"
+ dependencies:
+ "@octokit/auth-oauth-device": "npm:^7.1.5"
+ "@octokit/oauth-methods": "npm:^5.1.5"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/2bb597b2e50fbd5c03bee3a276efa72b03105aff1d9e243c18a71b72d9fe4ad4b1cee52c2df3e022c4169c7c1d37ab14d05455d5de982528914af965e14b763a
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-token@npm:^5.0.0":
+ version: 5.1.2
+ resolution: "@octokit/auth-token@npm:5.1.2"
+ checksum: 10c0/bd4952571d9c559ede1f6ef8f7756900256d19df0180db04da88886a05484c7e6a4397611422e4804465a82addc8c2daa21d0bb4f450403552ee81041a4046d1
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-unauthenticated@npm:^6.1.2, @octokit/auth-unauthenticated@npm:^6.1.3":
+ version: 6.1.3
+ resolution: "@octokit/auth-unauthenticated@npm:6.1.3"
+ dependencies:
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/60639987fa30e68c4ecd98dd9f1604b3f4368384979cdfa2ab9ea2d0b04c50b42a990e67167cf2a0098205a994b3a80d76b23bb0de4c8c956a898b977f5ce7d0
+ languageName: node
+ linkType: hard
+
+"@octokit/core@npm:^6.1.4, @octokit/core@npm:^6.1.5":
+ version: 6.1.5
+ resolution: "@octokit/core@npm:6.1.5"
+ dependencies:
+ "@octokit/auth-token": "npm:^5.0.0"
+ "@octokit/graphql": "npm:^8.2.2"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ before-after-hook: "npm:^3.0.2"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/c89ea754cc33da740fdd69fadb971b4b65c89971bba4e8ad545d3ea7aba79759ee3e195c3b72e7df78f14b8b1d392bddc56e7c385d48b5272319ea6a0246ac7c
+ languageName: node
+ linkType: hard
+
+"@octokit/endpoint@npm:^10.1.4":
+ version: 10.1.4
+ resolution: "@octokit/endpoint@npm:10.1.4"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.2"
+ checksum: 10c0/bf7cca71a05dc4751df658588e32642e59c98768e7509521226b997ea4837e2d16efd35c391231c76d888226f4daf80e6a9f347dee01a69f490253654dada581
+ languageName: node
+ linkType: hard
+
+"@octokit/graphql@npm:^8.2.2":
+ version: 8.2.2
+ resolution: "@octokit/graphql@npm:8.2.2"
+ dependencies:
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/29cd5af5ed04e416d28798a11907ab861dc73c0af47f8c9c3f4183d81d2e77d88228643825538acc81e7015f78d891f84107929019a673b06a6b38ccea6a24e0
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-app@npm:^7.1.6":
+ version: 7.1.6
+ resolution: "@octokit/oauth-app@npm:7.1.6"
+ dependencies:
+ "@octokit/auth-oauth-app": "npm:^8.1.3"
+ "@octokit/auth-oauth-user": "npm:^5.1.3"
+ "@octokit/auth-unauthenticated": "npm:^6.1.2"
+ "@octokit/core": "npm:^6.1.4"
+ "@octokit/oauth-authorization-url": "npm:^7.1.1"
+ "@octokit/oauth-methods": "npm:^5.1.4"
+ "@types/aws-lambda": "npm:^8.10.83"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/75264f6cb9336baf815bb85ea450d69c5d33eb70754065c9c5307b10d0efec2d76bb17c7788346dfb8b5e4ad0205e6df841b9c709eaf077390bba793787841f5
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-authorization-url@npm:^7.0.0, @octokit/oauth-authorization-url@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "@octokit/oauth-authorization-url@npm:7.1.1"
+ checksum: 10c0/a2723dde503693d4b0793bc43988d7445bdbd1a4e4994f4e94e635816c87b12a3058609eb5982d91783ddf6cdf663ccdb954b5d05efdc59cb66bc0456d7ba370
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-methods@npm:^5.1.4, @octokit/oauth-methods@npm:^5.1.5":
+ version: 5.1.5
+ resolution: "@octokit/oauth-methods@npm:5.1.5"
+ dependencies:
+ "@octokit/oauth-authorization-url": "npm:^7.0.0"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/2b1c5f9ef0fcdb2f19fd864303a67bdda296fcb2cc058efc51bf3fbb3cb582475a5532eab05bd7a57277607730fa4a7796431564693fffdb9c4cb2b471484a5c
+ languageName: node
+ linkType: hard
+
+"@octokit/openapi-types@npm:^25.0.0":
+ version: 25.0.0
+ resolution: "@octokit/openapi-types@npm:25.0.0"
+ checksum: 10c0/59c9e5998e08cecec155b776c93d8f6f88ab1a812add61cc65f3de8f3744201565545eac308083d18c9fa330a4381a27bcd771a311ac0348d3590a00f333f233
+ languageName: node
+ linkType: hard
+
+"@octokit/openapi-webhooks-types@npm:11.0.0":
+ version: 11.0.0
+ resolution: "@octokit/openapi-webhooks-types@npm:11.0.0"
+ checksum: 10c0/cea59ba6b976a242fa4e6bedfab7e6fc3437381557d2c1876ca3aea5f6d4231559a378f9bc35e09593cb2d466afb4a2415be66b960f3e0a38b65b8b9f22ff90e
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-paginate-graphql@npm:^5.2.4":
+ version: 5.2.4
+ resolution: "@octokit/plugin-paginate-graphql@npm:5.2.4"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/30601cf11d78e5683098d68fbff071a3d20b1e23758f40b1f43fbc93f69b3d0e07f2c9aaaaee113e586af7f604e809ba93702d932b1a4ea65998c7ab39a40a54
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-paginate-rest@npm:^12.0.0":
+ version: 12.0.0
+ resolution: "@octokit/plugin-paginate-rest@npm:12.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/4ed04e8c111ac8cfb0692f917fe09ff6484b7436f0605c661e8051c6fb281c0260c9b067c1422529b948e53b22221b0f7664e2d10a28dcd9db14465c02c7182f
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-rest-endpoint-methods@npm:^14.0.0":
+ version: 14.0.0
+ resolution: "@octokit/plugin-rest-endpoint-methods@npm:14.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/c3f26c5277d4aa0c898d8fdbf84326943ea80496e6f60ae34834415384ab629e1e3702d1ed82d40c31a7370edfcb5fa9fe434b0357b302b3be309879bad1d4e6
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-retry@npm:^7.2.1":
+ version: 7.2.1
+ resolution: "@octokit/plugin-retry@npm:7.2.1"
+ dependencies:
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ bottleneck: "npm:^2.15.3"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/0cac8aa32bfe9612cbaba36f51382c69c882ef7927e1deb4b166fe664959887e952205adbf8b9ff461e0128ac3e1bd807ca58e38041a55ddb3214397584f0406
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-throttling@npm:^10.0.0":
+ version: 10.0.0
+ resolution: "@octokit/plugin-throttling@npm:10.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ bottleneck: "npm:^2.15.3"
+ peerDependencies:
+ "@octokit/core": ^6.1.3
+ checksum: 10c0/60294f89bcc03b034fce557dffcb0dba1b02d1fa1834b3b4f542f8635750df4bd23fc143f7c71f802a22a1aaed089c5da77979e6803abe11908b1c91aa1ba419
+ languageName: node
+ linkType: hard
+
+"@octokit/request-error@npm:^6.1.7, @octokit/request-error@npm:^6.1.8":
+ version: 6.1.8
+ resolution: "@octokit/request-error@npm:6.1.8"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/02aa5bfebb5b1b9e152558b4a6f4f7dcb149b41538778ffe0fce3395fd0da5c0862311a78e94723435667581b2a58a7cefa458cf7aa19ae2948ae419276f7ee1
+ languageName: node
+ linkType: hard
+
+"@octokit/request@npm:^9.2.3":
+ version: 9.2.3
+ resolution: "@octokit/request@npm:9.2.3"
+ dependencies:
+ "@octokit/endpoint": "npm:^10.1.4"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ fast-content-type-parse: "npm:^2.0.0"
+ universal-user-agent: "npm:^7.0.2"
+ checksum: 10c0/96067fc9a5f30f2faa00f08015309930561c3ea0536b543e1c91c475f965eabc81c48fc27d401681ebdb3f6c1acc5d46eaa69163ab98b0faa08be1c02ea5b684
+ languageName: node
+ linkType: hard
+
+"@octokit/types@npm:^14.0.0":
+ version: 14.0.0
+ resolution: "@octokit/types@npm:14.0.0"
+ dependencies:
+ "@octokit/openapi-types": "npm:^25.0.0"
+ checksum: 10c0/c82da635fe99f265dbef7bf954d45a23ca7ce9c6fc9a8478c247b5435799e5d0eab3ff42f085785ee0882b2de293cab0ab831b379c66f41d00b78412df850ba4
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks-definitions@octokit/webhooks":
+ version: 0.0.0-development
+ resolution: "@octokit/webhooks-definitions@https://github.com/octokit/webhooks.git#commit=e5304814003f52b2697310a52f9d6bfc07632bd3"
+ checksum: 10c0/ff90b65b388b3f5ce80a0aa47c6ceb98578f8df6364799db5fc17ffadbbe7e533a7f2c548b279ebd4780e00a2cdcc5f07093b0add975d014af2722496413f75f
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks-methods@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "@octokit/webhooks-methods@npm:5.1.1"
+ checksum: 10c0/837aa49dbc7f8bc01448f4eaea32cfb0c1cbfa0b4ac570f7bcda385c71f43e4be05e91a3fb63708448410b27e246570fde42056b6b87d755154d84eff5a6500c
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks@npm:^13.6.1, @octokit/webhooks@npm:^13.8.2":
+ version: 13.8.2
+ resolution: "@octokit/webhooks@npm:13.8.2"
+ dependencies:
+ "@octokit/openapi-webhooks-types": "npm:11.0.0"
+ "@octokit/request-error": "npm:^6.1.7"
+ "@octokit/webhooks-methods": "npm:^5.1.1"
+ checksum: 10c0/5053ab9cff8afe4cd6e7d7a41af3f1b0c0ccc5058482577aa82bb8e5003f3002896c68bd59d7da363204c2d6baa4cca73ed684bb7a5a9286ca4b43172cd1fe9e
+ languageName: node
+ linkType: hard
+
+"@types/aws-lambda@npm:^8.10.83":
+ version: 8.10.149
+ resolution: "@types/aws-lambda@npm:8.10.149"
+ checksum: 10c0/9ef41214a1b69fa30d89cab575429793f1ccc49cfe3a7aa75228aef31a202bb6d2c306a5b33def61ef29e0d0a1a324412bf6a4fa5a615e61117685584a394047
+ languageName: node
+ linkType: hard
+
+"@types/node-fetch@npm:^2.6.4":
+ version: 2.6.12
+ resolution: "@types/node-fetch@npm:2.6.12"
+ dependencies:
+ "@types/node": "npm:*"
+ form-data: "npm:^4.0.0"
+ checksum: 10c0/7693acad5499b7df2d1727d46cff092a63896dc04645f36b973dd6dd754a59a7faba76fcb777bdaa35d80625c6a9dd7257cca9c401a4bab03b04480cda7fd1af
+ languageName: node
+ linkType: hard
+
+"@types/node@npm:*":
+ version: 22.15.9
+ resolution: "@types/node@npm:22.15.9"
+ dependencies:
+ undici-types: "npm:~6.21.0"
+ checksum: 10c0/f294ba23e441b4f919394d0e4c80f3f33e858e6f1db0561317148da2db3d3c67809fd1a38de481328933b0d5c6174db40cb6ab65f12b2cf3309df7f07a8e46f6
+ languageName: node
+ linkType: hard
+
+"@types/node@npm:^18.11.18":
+ version: 18.19.93
+ resolution: "@types/node@npm:18.19.93"
+ dependencies:
+ undici-types: "npm:~5.26.4"
+ checksum: 10c0/f4d1ca1a07b88bde6ae46b1f4cf3ace8db98406283f0caa18b22f642a6f4361d801e7efd44ee13d818114bb33b2a56e1a9cd97321b58fd3d8147351fabf4be82
+ languageName: node
+ linkType: hard
+
+"@types/node@npm:^22.15.8":
+ version: 22.15.8
+ resolution: "@types/node@npm:22.15.8"
+ dependencies:
+ undici-types: "npm:~6.21.0"
+ checksum: 10c0/980ddda0c98ce53689d52e8c20fbc7f7a42280780c4617892872c3bc2c342ef7b0bae5ff41eec536981a7d39fd7a9af71f5ce8849b36a2084d3945b7bc438d05
+ languageName: node
+ linkType: hard
+
+"abort-controller@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "abort-controller@npm:3.0.0"
+ dependencies:
+ event-target-shim: "npm:^5.0.0"
+ checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5
+ languageName: node
+ linkType: hard
+
+"agentkeepalive@npm:^4.2.1":
+ version: 4.6.0
+ resolution: "agentkeepalive@npm:4.6.0"
+ dependencies:
+ humanize-ms: "npm:^1.2.1"
+ checksum: 10c0/235c182432f75046835b05f239708107138a40103deee23b6a08caee5136873709155753b394ec212e49e60e94a378189562cb01347765515cff61b692c69187
+ languageName: node
+ linkType: hard
+
+"asynckit@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "asynckit@npm:0.4.0"
+ checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
+ languageName: node
+ linkType: hard
+
+"before-after-hook@npm:^3.0.2":
+ version: 3.0.2
+ resolution: "before-after-hook@npm:3.0.2"
+ checksum: 10c0/dea640f9e88a1085372c9bcc974b7bf379267490693da92ec102a7d8b515dd1e95f00ef575a146b83ca638104c57406c3427d37bdf082f602dde4b56d05bba14
+ languageName: node
+ linkType: hard
+
+"bottleneck@npm:^2.15.3":
+ version: 2.19.5
+ resolution: "bottleneck@npm:2.19.5"
+ checksum: 10c0/b0f72e45b2e0f56a21ba720183f16bef8e693452fb0495d997fa354e42904353a94bd8fd429868e6751bc85e54b6755190519eed5a0ae0a94a5185209ae7c6d0
+ languageName: node
+ linkType: hard
+
+"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "call-bind-apply-helpers@npm:1.0.2"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ function-bind: "npm:^1.1.2"
+ checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938
+ languageName: node
+ linkType: hard
+
+"combined-stream@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "combined-stream@npm:1.0.8"
+ dependencies:
+ delayed-stream: "npm:~1.0.0"
+ checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
+ languageName: node
+ linkType: hard
+
+"commander@npm:^12.0.0":
+ version: 12.1.0
+ resolution: "commander@npm:12.1.0"
+ checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
+ languageName: node
+ linkType: hard
+
+"delayed-stream@npm:~1.0.0":
+ version: 1.0.0
+ resolution: "delayed-stream@npm:1.0.0"
+ checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
+ languageName: node
+ linkType: hard
+
+"dotenv@npm:^16.5.0":
+ version: 16.5.0
+ resolution: "dotenv@npm:16.5.0"
+ checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
+ languageName: node
+ linkType: hard
+
+"dunder-proto@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "dunder-proto@npm:1.0.1"
+ dependencies:
+ call-bind-apply-helpers: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ gopd: "npm:^1.2.0"
+ checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031
+ languageName: node
+ linkType: hard
+
+"es-define-property@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "es-define-property@npm:1.0.1"
+ checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c
+ languageName: node
+ linkType: hard
+
+"es-errors@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "es-errors@npm:1.3.0"
+ checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85
+ languageName: node
+ linkType: hard
+
+"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "es-object-atoms@npm:1.1.1"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c
+ languageName: node
+ linkType: hard
+
+"es-set-tostringtag@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "es-set-tostringtag@npm:2.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.6"
+ has-tostringtag: "npm:^1.0.2"
+ hasown: "npm:^2.0.2"
+ checksum: 10c0/ef2ca9ce49afe3931cb32e35da4dcb6d86ab02592cfc2ce3e49ced199d9d0bb5085fc7e73e06312213765f5efa47cc1df553a6a5154584b21448e9fb8355b1af
+ languageName: node
+ linkType: hard
+
+"event-target-shim@npm:^5.0.0":
+ version: 5.0.1
+ resolution: "event-target-shim@npm:5.0.1"
+ checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b
+ languageName: node
+ linkType: hard
+
+"eventsource-parser@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "eventsource-parser@npm:3.0.1"
+ checksum: 10c0/146ce5ae8325d07645a49bbc54d7ac3aef42f5138bfbbe83d5cf96293b50eab2219926d6cf41eed0a0f90132578089652ba9286a19297662900133a9da6c2fd0
+ languageName: node
+ linkType: hard
+
+"eventsource@npm:^3.0.5":
+ version: 3.0.6
+ resolution: "eventsource@npm:3.0.6"
+ dependencies:
+ eventsource-parser: "npm:^3.0.1"
+ checksum: 10c0/074d865ea1c7e29e3243f85a13306e89fca2d775b982dca03fa6bfa75c56827fa89cf1ab9e730db24bd6b104cbdcae074f2b37ba498874e9dd9710fbff4979bb
+ languageName: node
+ linkType: hard
+
+"fast-content-type-parse@npm:^2.0.0":
+ version: 2.0.1
+ resolution: "fast-content-type-parse@npm:2.0.1"
+ checksum: 10c0/e5ff87d75a35ae4cf377df1dca46ec49e7abbdc8513689676ecdef548b94900b50e66e516e64470035d79b9f7010ef15d98c24d8ae803a881363cc59e0715e19
+ languageName: node
+ linkType: hard
+
+"form-data-encoder@npm:1.7.2":
+ version: 1.7.2
+ resolution: "form-data-encoder@npm:1.7.2"
+ checksum: 10c0/56553768037b6d55d9de524f97fe70555f0e415e781cb56fc457a68263de3d40fadea2304d4beef2d40b1a851269bd7854e42c362107071892cb5238debe9464
+ languageName: node
+ linkType: hard
+
+"form-data@npm:^4.0.0":
+ version: 4.0.2
+ resolution: "form-data@npm:4.0.2"
+ dependencies:
+ asynckit: "npm:^0.4.0"
+ combined-stream: "npm:^1.0.8"
+ es-set-tostringtag: "npm:^2.1.0"
+ mime-types: "npm:^2.1.12"
+ checksum: 10c0/e534b0cf025c831a0929bf4b9bbe1a9a6b03e273a8161f9947286b9b13bf8fb279c6944aae0070c4c311100c6d6dbb815cd955dc217728caf73fad8dc5b8ee9c
+ languageName: node
+ linkType: hard
+
+"formdata-node@npm:^4.3.2":
+ version: 4.4.1
+ resolution: "formdata-node@npm:4.4.1"
+ dependencies:
+ node-domexception: "npm:1.0.0"
+ web-streams-polyfill: "npm:4.0.0-beta.3"
+ checksum: 10c0/74151e7b228ffb33b565cec69182694ad07cc3fdd9126a8240468bb70a8ba66e97e097072b60bcb08729b24c7ce3fd3e0bd7f1f80df6f9f662b9656786e76f6a
+ languageName: node
+ linkType: hard
+
+"function-bind@npm:^1.1.2":
+ version: 1.1.2
+ resolution: "function-bind@npm:1.1.2"
+ checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5
+ languageName: node
+ linkType: hard
+
+"get-intrinsic@npm:^1.2.6":
+ version: 1.3.0
+ resolution: "get-intrinsic@npm:1.3.0"
+ dependencies:
+ call-bind-apply-helpers: "npm:^1.0.2"
+ es-define-property: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.1.1"
+ function-bind: "npm:^1.1.2"
+ get-proto: "npm:^1.0.1"
+ gopd: "npm:^1.2.0"
+ has-symbols: "npm:^1.1.0"
+ hasown: "npm:^2.0.2"
+ math-intrinsics: "npm:^1.1.0"
+ checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a
+ languageName: node
+ linkType: hard
+
+"get-proto@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "get-proto@npm:1.0.1"
+ dependencies:
+ dunder-proto: "npm:^1.0.1"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c
+ languageName: node
+ linkType: hard
+
+"gopd@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "gopd@npm:1.2.0"
+ checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead
+ languageName: node
+ linkType: hard
+
+"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "has-symbols@npm:1.1.0"
+ checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e
+ languageName: node
+ linkType: hard
+
+"has-tostringtag@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "has-tostringtag@npm:1.0.2"
+ dependencies:
+ has-symbols: "npm:^1.0.3"
+ checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c
+ languageName: node
+ linkType: hard
+
+"hasown@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "hasown@npm:2.0.2"
+ dependencies:
+ function-bind: "npm:^1.1.2"
+ checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9
+ languageName: node
+ linkType: hard
+
+"humanize-ms@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "humanize-ms@npm:1.2.1"
+ dependencies:
+ ms: "npm:^2.0.0"
+ checksum: 10c0/f34a2c20161d02303c2807badec2f3b49cbfbbb409abd4f95a07377ae01cfe6b59e3d15ac609cffcd8f2521f0eb37b7e1091acf65da99aa2a4f1ad63c21e7e7a
+ languageName: node
+ linkType: hard
+
+"math-intrinsics@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "math-intrinsics@npm:1.1.0"
+ checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f
+ languageName: node
+ linkType: hard
+
+"mime-db@npm:1.52.0":
+ version: 1.52.0
+ resolution: "mime-db@npm:1.52.0"
+ checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa
+ languageName: node
+ linkType: hard
+
+"mime-types@npm:^2.1.12":
+ version: 2.1.35
+ resolution: "mime-types@npm:2.1.35"
+ dependencies:
+ mime-db: "npm:1.52.0"
+ checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2
+ languageName: node
+ linkType: hard
+
+"ms@npm:^2.0.0":
+ version: 2.1.3
+ resolution: "ms@npm:2.1.3"
+ checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
+ languageName: node
+ linkType: hard
+
+"node-domexception@npm:1.0.0":
+ version: 1.0.0
+ resolution: "node-domexception@npm:1.0.0"
+ checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
+ languageName: node
+ linkType: hard
+
+"node-fetch@npm:^2.6.7":
+ version: 2.7.0
+ resolution: "node-fetch@npm:2.7.0"
+ dependencies:
+ whatwg-url: "npm:^5.0.0"
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+ checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
+ languageName: node
+ linkType: hard
+
+"octokit@npm:^4.1.3":
+ version: 4.1.3
+ resolution: "octokit@npm:4.1.3"
+ dependencies:
+ "@octokit/app": "npm:^15.1.6"
+ "@octokit/core": "npm:^6.1.5"
+ "@octokit/oauth-app": "npm:^7.1.6"
+ "@octokit/plugin-paginate-graphql": "npm:^5.2.4"
+ "@octokit/plugin-paginate-rest": "npm:^12.0.0"
+ "@octokit/plugin-rest-endpoint-methods": "npm:^14.0.0"
+ "@octokit/plugin-retry": "npm:^7.2.1"
+ "@octokit/plugin-throttling": "npm:^10.0.0"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/a35352dff1d7bacf8123e491489650c29b830a765f78113064edd6bd0aad0e58e8933874394892972fb8b0e43369b6f7a7b354426c61f4d9fc37408891fde582
+ languageName: node
+ linkType: hard
+
+"openai@npm:^4.97.0":
+ version: 4.97.0
+ resolution: "openai@npm:4.97.0"
+ dependencies:
+ "@types/node": "npm:^18.11.18"
+ "@types/node-fetch": "npm:^2.6.4"
+ abort-controller: "npm:^3.0.0"
+ agentkeepalive: "npm:^4.2.1"
+ form-data-encoder: "npm:1.7.2"
+ formdata-node: "npm:^4.3.2"
+ node-fetch: "npm:^2.6.7"
+ peerDependencies:
+ ws: ^8.18.0
+ zod: ^3.23.8
+ peerDependenciesMeta:
+ ws:
+ optional: true
+ zod:
+ optional: true
+ bin:
+ openai: bin/cli
+ checksum: 10c0/9938eb85102dd0465197e79c0912df9f3afd52be2d9524fd5100f5befbfa70e6bb7803120515ffa0925b7afc14762052b087c7c2f3d0b85852efa22aa1d745d6
+ languageName: node
+ linkType: hard
+
+"parse-diff@npm:^0.11.1":
+ version: 0.11.1
+ resolution: "parse-diff@npm:0.11.1"
+ checksum: 10c0/b8a488039f535e0ddaf1cfd4a13c2adc6d142f4e6263de6dc603f9762b59da89703a8f0dc8aacb7c7c66cdbdd2d075a57c63813fb74f66c9b8f5fe8ad2e89689
+ languageName: node
+ linkType: hard
+
+"review-agent@workspace:.":
+ version: 0.0.0-use.local
+ resolution: "review-agent@workspace:."
+ dependencies:
+ "@octokit/webhooks": "npm:^13.8.2"
+ "@octokit/webhooks-definitions": octokit/webhooks
+ "@types/node": "npm:^22.15.8"
+ dotenv: "npm:^16.5.0"
+ octokit: "npm:^4.1.3"
+ openai: "npm:^4.97.0"
+ parse-diff: "npm:^0.11.1"
+ smee-client: "npm:^3.1.1"
+ typescript: "npm:^5.8.3"
+ zod: "npm:^3.24.4"
+ zod-to-json-schema: "npm:^3.24.5"
+ languageName: unknown
+ linkType: soft
+
+"smee-client@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "smee-client@npm:3.1.1"
+ dependencies:
+ commander: "npm:^12.0.0"
+ eventsource: "npm:^3.0.5"
+ undici: "npm:^6.19.8"
+ validator: "npm:^13.11.0"
+ bin:
+ smee: bin/smee.js
+ checksum: 10c0/24fd526330d0d0b0763de574c4d6595739eb0413882d617dce07ca35f71fd732c96a9ca723d394e1e9e938b4ef004a9d69797cb700ec72a6fc69396c8128d245
+ languageName: node
+ linkType: hard
+
+"toad-cache@npm:^3.7.0":
+ version: 3.7.0
+ resolution: "toad-cache@npm:3.7.0"
+ checksum: 10c0/7dae2782ee20b22c9798bb8b71dec7ec6a0091021d2ea9dd6e8afccab6b65b358fdba49a02209fac574499702e2c000660721516c87c2538d1b2c0ba03e8c0c3
+ languageName: node
+ linkType: hard
+
+"tr46@npm:~0.0.3":
+ version: 0.0.3
+ resolution: "tr46@npm:0.0.3"
+ checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11
+ languageName: node
+ linkType: hard
+
+"typescript@npm:^5.8.3":
+ version: 5.8.3
+ resolution: "typescript@npm:5.8.3"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48
+ languageName: node
+ linkType: hard
+
+"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin":
+ version: 5.8.3
+ resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb
+ languageName: node
+ linkType: hard
+
+"undici-types@npm:~5.26.4":
+ version: 5.26.5
+ resolution: "undici-types@npm:5.26.5"
+ checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
+ languageName: node
+ linkType: hard
+
+"undici-types@npm:~6.21.0":
+ version: 6.21.0
+ resolution: "undici-types@npm:6.21.0"
+ checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04
+ languageName: node
+ linkType: hard
+
+"undici@npm:^6.19.8":
+ version: 6.21.2
+ resolution: "undici@npm:6.21.2"
+ checksum: 10c0/799bbc02b77dda9b6b12d56d2620a3a4d4cf087908d6a548acc3ce32f21b5c27467f75c2c4b30fab281daf341210be3d685e8fe99854288de541715ae5735027
+ languageName: node
+ linkType: hard
+
+"universal-github-app-jwt@npm:^2.2.0":
+ version: 2.2.2
+ resolution: "universal-github-app-jwt@npm:2.2.2"
+ checksum: 10c0/7ae5f031fb89c01a4407459b764c5e6341d725d436e1ceec161f9b754dd4883d9704cc8de53d5b6314b7e1bef8dbc7561799fc23001e706f213d468c17026fb6
+ languageName: node
+ linkType: hard
+
+"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2":
+ version: 7.0.2
+ resolution: "universal-user-agent@npm:7.0.2"
+ checksum: 10c0/e60517ee929813e6b3ac0ceb3c66deccafadc71341edca160279ff046319c684fd7090a60d63aa61cd34a06c2d2acebeb8c2f8d364244ae7bf8ab788e20cd8c8
+ languageName: node
+ linkType: hard
+
+"validator@npm:^13.11.0":
+ version: 13.15.0
+ resolution: "validator@npm:13.15.0"
+ checksum: 10c0/0f13fd7031ac575e8d7828431da8ef5859bac6a38ee65e1d7fdd367dbf1c3d94d95182aecc3183f7fa7a30ff4474bf864d1aff54707620227a2cdbfd36d894c2
+ languageName: node
+ linkType: hard
+
+"web-streams-polyfill@npm:4.0.0-beta.3":
+ version: 4.0.0-beta.3
+ resolution: "web-streams-polyfill@npm:4.0.0-beta.3"
+ checksum: 10c0/a9596779db2766990117ed3a158e0b0e9f69b887a6d6ba0779940259e95f99dc3922e534acc3e5a117b5f5905300f527d6fbf8a9f0957faf1d8e585ce3452e8e
+ languageName: node
+ linkType: hard
+
+"webidl-conversions@npm:^3.0.0":
+ version: 3.0.1
+ resolution: "webidl-conversions@npm:3.0.1"
+ checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db
+ languageName: node
+ linkType: hard
+
+"whatwg-url@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "whatwg-url@npm:5.0.0"
+ dependencies:
+ tr46: "npm:~0.0.3"
+ webidl-conversions: "npm:^3.0.0"
+ checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5
+ languageName: node
+ linkType: hard
+
+"zod-to-json-schema@npm:^3.24.5":
+ version: 3.24.5
+ resolution: "zod-to-json-schema@npm:3.24.5"
+ peerDependencies:
+ zod: ^3.24.1
+ checksum: 10c0/0745b94ba53e652d39f262641cdeb2f75d24339fb6076a38ce55bcf53d82dfaea63adf524ebc5f658681005401687f8e9551c4feca7c4c882e123e66091dfb90
+ languageName: node
+ linkType: hard
+
+"zod@npm:^3.24.4":
+ version: 3.24.4
+ resolution: "zod@npm:3.24.4"
+ checksum: 10c0/ab3112f017562180a41a0f83d870b333677f7d6b77f106696c56894567051b91154714a088149d8387a4f50806a2520efcb666f108cd384a35c236a191186d91
+ languageName: node
+ linkType: hard
diff --git a/staging/fly.toml b/staging/fly.toml
deleted file mode 100644
index 6d3f2896..00000000
--- a/staging/fly.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-# fly.toml app configuration file generated for sourcebot-staging on 2025-01-29T15:57:18-08:00
-#
-# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
-#
-
-app = 'sourcebot-staging'
-primary_region = 'sea'
-
-[build]
- image = 'ghcr.io/sourcebot-dev/sourcebot:staging'
-
-[[mounts]]
- source = 'sourcebot_staging_data'
- destination = '/data'
- initial_size = "60GB"
-
-[http_service]
- internal_port = 3000
- force_https = true
- auto_stop_machines = true
- auto_start_machines = true
- min_machines_running = 0
- processes = ['app']
-
-[[vm]]
- memory = '4gb'
- cpu_kind = 'performance'
- cpus = 2
From 17fce5ca3c66ac0a8b4d4b957704931da435735e Mon Sep 17 00:00:00 2001
From: msukkari
Date: Thu, 8 May 2025 15:40:39 -0700
Subject: [PATCH 02/15] feedback
---
.../reviewAgent/nodes/fetch_file_content.ts | 2 +-
.../reviewAgent/nodes/generate_pr_reviews.ts | 46 -----------------
.../nodes/github_push_pr_reviews.ts | 32 ------------
packages/agents/reviewAgent/package.json | 13 +----
packages/agents/reviewAgent/{ => src}/app.ts | 0
.../src/nodes/fetch_file_content.ts | 40 +++++++++++++++
.../nodes/generate_diff_review_prompt.ts | 0
.../src/nodes/generate_pr_reviews.ts | 49 +++++++++++++++++++
.../{ => src}/nodes/github_pr_parser.ts | 4 ++
.../src/nodes/github_push_pr_reviews.ts | 40 +++++++++++++++
.../{ => src}/nodes/invoke_diff_review_llm.ts | 10 ++--
.../agents/reviewAgent/{ => src}/types.ts | 0
12 files changed, 142 insertions(+), 94 deletions(-)
delete mode 100644 packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
delete mode 100644 packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
rename packages/agents/reviewAgent/{ => src}/app.ts (100%)
create mode 100644 packages/agents/reviewAgent/src/nodes/fetch_file_content.ts
rename packages/agents/reviewAgent/{ => src}/nodes/generate_diff_review_prompt.ts (100%)
create mode 100644 packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts
rename packages/agents/reviewAgent/{ => src}/nodes/github_pr_parser.ts (95%)
create mode 100644 packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts
rename packages/agents/reviewAgent/{ => src}/nodes/invoke_diff_review_llm.ts (74%)
rename packages/agents/reviewAgent/{ => src}/types.ts (100%)
diff --git a/packages/agents/reviewAgent/nodes/fetch_file_content.ts b/packages/agents/reviewAgent/nodes/fetch_file_content.ts
index 2c90633e..d33c3e50 100644
--- a/packages/agents/reviewAgent/nodes/fetch_file_content.ts
+++ b/packages/agents/reviewAgent/nodes/fetch_file_content.ts
@@ -1,4 +1,4 @@
-import { sourcebot_context, sourcebot_pr_payload } from "../types.js";
+import { sourcebot_context, sourcebot_pr_payload } from "../src/types.js";
import { z } from "zod";
// TODO: use original Sourcebot schemas instead of redefining here
diff --git a/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts b/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
deleted file mode 100644
index e3666252..00000000
--- a/packages/agents/reviewAgent/nodes/generate_pr_reviews.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "../types.js";
-import { generate_diff_review_prompt } from "./generate_diff_review_prompt.js";
-import { invoke_diff_review_llm } from "./invoke_diff_review_llm.js";
-import { fetch_file_content } from "./fetch_file_content.js";
-
-export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
- console.log("Executing generate_pr_reviews");
-
- const file_diff_reviews: sourcebot_file_diff_review[] = [];
- for (const file_diff of pr_payload.file_diffs) {
- const reviews: sourcebot_diff_review[] = [];
-
- for (const diff of file_diff.diffs) {
- const fileContentContext = await fetch_file_content(pr_payload, file_diff.to);
- const context: sourcebot_context[] = [
- {
- type: "pr_title",
- description: "The title of the pull request",
- context: pr_payload.title,
- },
- {
- type: "pr_description",
- description: "The description of the pull request",
- context: pr_payload.description,
- },
- fileContentContext,
- ];
-
- const prompt = await generate_diff_review_prompt(diff, context, rules);
- console.log(prompt);
-
- const diffReview = await invoke_diff_review_llm(prompt, file_diff.to);
- reviews.push(diffReview);
- }
-
- if (reviews.length > 0) {
- file_diff_reviews.push({
- filename: file_diff.to,
- reviews: reviews,
- });
- }
- }
-
- console.log("Completed generate_pr_reviews");
- return file_diff_reviews;
-}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts b/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
deleted file mode 100644
index 38b77144..00000000
--- a/packages/agents/reviewAgent/nodes/github_push_pr_reviews.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { App } from "octokit";
-import { sourcebot_pr_payload, sourcebot_file_diff_review } from "../types.js";
-
-export const github_push_pr_reviews = async (app: App, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
- console.log("Executing github_push_pr_reviews");
-
- const installationId = pr_payload.installation_id;
- const installation = await app.getInstallationOctokit(installationId);
-
- for (const file_diff_review of file_diff_reviews) {
- for (const review of file_diff_review.reviews) {
- await installation.rest.pulls.createReviewComment({
- owner: pr_payload.owner,
- repo: pr_payload.repo,
- pull_number: pr_payload.number,
- body: review.review,
- path: file_diff_review.filename,
- commit_id: pr_payload.head_sha,
- side: "RIGHT",
- ...(review.line_start === review.line_end
- ? { line: review.line_start }
- : {
- start_line: review.line_start,
- line: review.line_end,
- start_side: "RIGHT",
- }),
- });
- }
- }
-
- console.log("Completed github_push_pr_reviews");
-}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/package.json b/packages/agents/reviewAgent/package.json
index 970d6d33..9fe1fc20 100644
--- a/packages/agents/reviewAgent/package.json
+++ b/packages/agents/reviewAgent/package.json
@@ -1,5 +1,5 @@
{
- "name": "review-agent",
+ "name": "@sourcebot/review-agent",
"version": "1.0.0",
"description": "",
"main": "index.js",
@@ -8,17 +8,6 @@
"build": "tsc",
"start": "node dist/app.js"
},
- "repository": {
- "type": "git",
- "url": "git+https://github.com/sourcebot-dev/review-agent.git"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/sourcebot-dev/review-agent/issues"
- },
- "homepage": "https://github.com/sourcebot-dev/review-agent#readme",
"dependencies": {
"@octokit/webhooks": "^13.8.2",
"@octokit/webhooks-definitions": "octokit/webhooks",
diff --git a/packages/agents/reviewAgent/app.ts b/packages/agents/reviewAgent/src/app.ts
similarity index 100%
rename from packages/agents/reviewAgent/app.ts
rename to packages/agents/reviewAgent/src/app.ts
diff --git a/packages/agents/reviewAgent/src/nodes/fetch_file_content.ts b/packages/agents/reviewAgent/src/nodes/fetch_file_content.ts
new file mode 100644
index 00000000..58475849
--- /dev/null
+++ b/packages/agents/reviewAgent/src/nodes/fetch_file_content.ts
@@ -0,0 +1,40 @@
+import { sourcebot_context, sourcebot_pr_payload } from "../types.js";
+import { fileSourceResponseSchema } from "@sourcebot/web/src/features/search/schemas.js";
+import { base64Decode } from "@sourcebot/web/src/lib/utils.js";
+
+export const fetch_file_content = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
+ console.log("Executing fetch_file_content");
+
+ const repoPath = pr_payload.hostDomain + "/" + pr_payload.owner + "/" + pr_payload.repo;
+ const fileSourceRequest = {
+ fileName: filename,
+ repository: repoPath,
+ }
+ console.log(JSON.stringify(fileSourceRequest, null, 2));
+
+ const response = await fetch('http://localhost:3000/api/source', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Org-Domain': '~'
+ },
+ body: JSON.stringify(fileSourceRequest)
+ });
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch file content for ${filename} from ${repoPath}: ${response.statusText}`);
+ }
+
+ const responseData = await response.json();
+ const fileSourceResponse = fileSourceResponseSchema.parse(responseData);
+ const fileContent = base64Decode(fileSourceResponse.source);
+
+ const fileContentContext: sourcebot_context = {
+ type: "file_content",
+ description: `The content of the file ${filename}`,
+ context: fileContent,
+ }
+
+ console.log("Completed fetch_file_content");
+ return fileContentContext;
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts b/packages/agents/reviewAgent/src/nodes/generate_diff_review_prompt.ts
similarity index 100%
rename from packages/agents/reviewAgent/nodes/generate_diff_review_prompt.ts
rename to packages/agents/reviewAgent/src/nodes/generate_diff_review_prompt.ts
diff --git a/packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts b/packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts
new file mode 100644
index 00000000..92754d03
--- /dev/null
+++ b/packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts
@@ -0,0 +1,49 @@
+import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "../types.js";
+import { generate_diff_review_prompt } from "./generate_diff_review_prompt.js";
+import { invoke_diff_review_llm } from "./invoke_diff_review_llm.js";
+import { fetch_file_content } from "./fetch_file_content.js";
+
+export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
+ console.log("Executing generate_pr_reviews");
+
+ const file_diff_reviews: sourcebot_file_diff_review[] = [];
+ for (const file_diff of pr_payload.file_diffs) {
+ const reviews: sourcebot_diff_review[] = [];
+
+ for (const diff of file_diff.diffs) {
+ try {
+ const fileContentContext = await fetch_file_content(pr_payload, file_diff.to);
+ const context: sourcebot_context[] = [
+ {
+ type: "pr_title",
+ description: "The title of the pull request",
+ context: pr_payload.title,
+ },
+ {
+ type: "pr_description",
+ description: "The description of the pull request",
+ context: pr_payload.description,
+ },
+ fileContentContext,
+ ];
+
+ const prompt = await generate_diff_review_prompt(diff, context, rules);
+
+ const diffReview = await invoke_diff_review_llm(prompt, file_diff.to);
+ reviews.push(diffReview);
+ } catch (error) {
+ console.error(`Error fetching file content for ${file_diff.to}: ${error}`);
+ }
+ }
+
+ if (reviews.length > 0) {
+ file_diff_reviews.push({
+ filename: file_diff.to,
+ reviews: reviews,
+ });
+ }
+ }
+
+ console.log("Completed generate_pr_reviews");
+ return file_diff_reviews;
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/github_pr_parser.ts b/packages/agents/reviewAgent/src/nodes/github_pr_parser.ts
similarity index 95%
rename from packages/agents/reviewAgent/nodes/github_pr_parser.ts
rename to packages/agents/reviewAgent/src/nodes/github_pr_parser.ts
index 9cb8e990..c248bcbc 100644
--- a/packages/agents/reviewAgent/nodes/github_pr_parser.ts
+++ b/packages/agents/reviewAgent/src/nodes/github_pr_parser.ts
@@ -6,6 +6,10 @@ import { Octokit } from "octokit";
export const github_pr_parser = async (octokit: Octokit, payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">): Promise => {
console.log("Executing github_pr_parser");
+ if (!payload.installation) {
+ throw new Error("Installation not found in github payload");
+ }
+
const diff = await octokit.request(payload.pull_request.patch_url);
const parsedDiff: parse.File[] = parse(diff.data);
diff --git a/packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts b/packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts
new file mode 100644
index 00000000..db2994d9
--- /dev/null
+++ b/packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts
@@ -0,0 +1,40 @@
+import { App } from "octokit";
+import { sourcebot_pr_payload, sourcebot_file_diff_review } from "../types.js";
+
+export const github_push_pr_reviews = async (app: App, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
+ console.log("Executing github_push_pr_reviews");
+
+ try {
+ const installationId = pr_payload.installation_id;
+ const installation = await app.getInstallationOctokit(installationId);
+
+ for (const file_diff_review of file_diff_reviews) {
+ for (const review of file_diff_review.reviews) {
+ try {
+ await installation.rest.pulls.createReviewComment({
+ owner: pr_payload.owner,
+ repo: pr_payload.repo,
+ pull_number: pr_payload.number,
+ body: review.review,
+ path: file_diff_review.filename,
+ commit_id: pr_payload.head_sha,
+ side: "RIGHT",
+ ...(review.line_start === review.line_end
+ ? { line: review.line_start }
+ : {
+ start_line: review.line_start,
+ line: review.line_end,
+ start_side: "RIGHT",
+ }),
+ });
+ } catch (error) {
+ console.error(`Error pushing pr reviews for ${file_diff_review.filename}: ${error}`);
+ }
+ }
+ }
+ } catch (error) {
+ console.error(`Error pushing pr reviews: ${error}`);
+ }
+
+ console.log("Completed github_push_pr_reviews");
+}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts b/packages/agents/reviewAgent/src/nodes/invoke_diff_review_llm.ts
similarity index 74%
rename from packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts
rename to packages/agents/reviewAgent/src/nodes/invoke_diff_review_llm.ts
index 38e748d3..13790013 100644
--- a/packages/agents/reviewAgent/nodes/invoke_diff_review_llm.ts
+++ b/packages/agents/reviewAgent/src/nodes/invoke_diff_review_llm.ts
@@ -21,11 +21,15 @@ export const invoke_diff_review_llm = async (prompt: string, filename: string):
const openaiResponse = completion.choices[0].message.content;
console.log("OpenAI response: ", openaiResponse);
- const diffReviewJson = JSON.parse(openaiResponse || '');
- const diffReview = sourcebot_diff_review_schema.parse(diffReviewJson);
+ const diffReviewJson = JSON.parse(openaiResponse || '{}');
+ const diffReview = sourcebot_diff_review_schema.safeParse(diffReviewJson);
+
+ if (!diffReview.success) {
+ throw new Error(`Invalid diff review format: ${diffReview.error}`);
+ }
console.log("Completed invoke_diff_review_llm");
- return diffReview;
+ return diffReview.data;
} catch (error) {
console.error('Error calling OpenAI:', error);
throw error;
diff --git a/packages/agents/reviewAgent/types.ts b/packages/agents/reviewAgent/src/types.ts
similarity index 100%
rename from packages/agents/reviewAgent/types.ts
rename to packages/agents/reviewAgent/src/types.ts
From 12002f27d68e81c067a295678dd42fb7222ca8bd Mon Sep 17 00:00:00 2001
From: msukkari
Date: Thu, 8 May 2025 17:31:43 -0700
Subject: [PATCH 03/15] wip integrating review agent into monorepo
---
.env.development | 8 +-
package.json | 3 +-
.../{reviewAgent => review-agent}/.gitignore | 0
.../package.json | 0
.../{reviewAgent => review-agent}/src/app.ts | 6 +-
packages/agents/review-agent/src/env.ts | 13 +
.../src/nodes/fetch_file_content.ts | 0
.../src/nodes/generate_diff_review_prompt.ts | 0
.../src/nodes/generate_pr_reviews.ts | 0
.../src/nodes/github_pr_parser.ts | 0
.../src/nodes/github_push_pr_reviews.ts | 0
.../src/nodes/invoke_diff_review_llm.ts | 0
.../src/types.ts | 0
.../tsconfig.json | 0
.../reviewAgent/nodes/fetch_file_content.ts | 49 -
packages/agents/reviewAgent/yarn.lock | 842 ------------------
packages/web/src/app/[domain]/agents/page.tsx | 70 ++
yarn.lock | 575 +++++++++++-
18 files changed, 667 insertions(+), 899 deletions(-)
rename packages/agents/{reviewAgent => review-agent}/.gitignore (100%)
rename packages/agents/{reviewAgent => review-agent}/package.json (100%)
rename packages/agents/{reviewAgent => review-agent}/src/app.ts (92%)
create mode 100644 packages/agents/review-agent/src/env.ts
rename packages/agents/{reviewAgent => review-agent}/src/nodes/fetch_file_content.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/nodes/generate_diff_review_prompt.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/nodes/generate_pr_reviews.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/nodes/github_pr_parser.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/nodes/github_push_pr_reviews.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/nodes/invoke_diff_review_llm.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/src/types.ts (100%)
rename packages/agents/{reviewAgent => review-agent}/tsconfig.json (100%)
delete mode 100644 packages/agents/reviewAgent/nodes/fetch_file_content.ts
delete mode 100644 packages/agents/reviewAgent/yarn.lock
create mode 100644 packages/web/src/app/[domain]/agents/page.tsx
diff --git a/.env.development b/.env.development
index ae6fdbb3..138800a2 100644
--- a/.env.development
+++ b/.env.development
@@ -78,4 +78,10 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
# NODE_ENV=
# SOURCEBOT_TENANCY_MODE=single
-# NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=
\ No newline at end of file
+# NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=
+
+# Used for agents
+# GITHUB_APP_ID=
+# GITHUB_APP_PRIVATE_KEY_PATH=
+# GITHUB_APP_WEBHOOK_SECRET=
+# OPENAI_API_KEY=
\ No newline at end of file
diff --git a/package.json b/package.json
index f9b8ba68..e98f6628 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,8 @@
{
"private": true,
"workspaces": [
- "packages/*"
+ "packages/*",
+ "packages/agents/*"
],
"scripts": {
"build": "cross-env SKIP_ENV_VALIDATION=1 yarn workspaces foreach -A run build",
diff --git a/packages/agents/reviewAgent/.gitignore b/packages/agents/review-agent/.gitignore
similarity index 100%
rename from packages/agents/reviewAgent/.gitignore
rename to packages/agents/review-agent/.gitignore
diff --git a/packages/agents/reviewAgent/package.json b/packages/agents/review-agent/package.json
similarity index 100%
rename from packages/agents/reviewAgent/package.json
rename to packages/agents/review-agent/package.json
diff --git a/packages/agents/reviewAgent/src/app.ts b/packages/agents/review-agent/src/app.ts
similarity index 92%
rename from packages/agents/reviewAgent/src/app.ts
rename to packages/agents/review-agent/src/app.ts
index ba48f082..2765e65b 100644
--- a/packages/agents/reviewAgent/src/app.ts
+++ b/packages/agents/review-agent/src/app.ts
@@ -52,15 +52,11 @@ app.webhooks.onError((error) => {
console.error(error);
});
-
const port = 3050;
-const host = 'localhost';
const path = "/api/webhook";
-const localWebhookUrl = `http://${host}:${port}${path}`;
const middleware = createNodeMiddleware(app.webhooks, { path });
http.createServer(middleware).listen(port, () => {
- console.log(`Server is listening for events at: ${localWebhookUrl}`);
- console.log('Press Ctrl + C to quit.')
+ console.log(`Http server for review agent running on port ${port} ${path}`);
});
diff --git a/packages/agents/review-agent/src/env.ts b/packages/agents/review-agent/src/env.ts
new file mode 100644
index 00000000..fd320618
--- /dev/null
+++ b/packages/agents/review-agent/src/env.ts
@@ -0,0 +1,13 @@
+import { createEnv } from "@t3-oss/env-core";
+import { z } from "zod";
+
+export const env = createEnv({
+ server: {
+ GITHUB_APP_ID: z.string(),
+ GITHUB_APP_WEBHOOK_SECRET: z.string(),
+ GITHUB_APP_PRIVATE_KEY_PATH: z.string(),
+ },
+ runtimeEnv: process.env,
+ emptyStringAsUndefined: true,
+ skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
+})
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/src/nodes/fetch_file_content.ts b/packages/agents/review-agent/src/nodes/fetch_file_content.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/fetch_file_content.ts
rename to packages/agents/review-agent/src/nodes/fetch_file_content.ts
diff --git a/packages/agents/reviewAgent/src/nodes/generate_diff_review_prompt.ts b/packages/agents/review-agent/src/nodes/generate_diff_review_prompt.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/generate_diff_review_prompt.ts
rename to packages/agents/review-agent/src/nodes/generate_diff_review_prompt.ts
diff --git a/packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts b/packages/agents/review-agent/src/nodes/generate_pr_reviews.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/generate_pr_reviews.ts
rename to packages/agents/review-agent/src/nodes/generate_pr_reviews.ts
diff --git a/packages/agents/reviewAgent/src/nodes/github_pr_parser.ts b/packages/agents/review-agent/src/nodes/github_pr_parser.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/github_pr_parser.ts
rename to packages/agents/review-agent/src/nodes/github_pr_parser.ts
diff --git a/packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts b/packages/agents/review-agent/src/nodes/github_push_pr_reviews.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/github_push_pr_reviews.ts
rename to packages/agents/review-agent/src/nodes/github_push_pr_reviews.ts
diff --git a/packages/agents/reviewAgent/src/nodes/invoke_diff_review_llm.ts b/packages/agents/review-agent/src/nodes/invoke_diff_review_llm.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/nodes/invoke_diff_review_llm.ts
rename to packages/agents/review-agent/src/nodes/invoke_diff_review_llm.ts
diff --git a/packages/agents/reviewAgent/src/types.ts b/packages/agents/review-agent/src/types.ts
similarity index 100%
rename from packages/agents/reviewAgent/src/types.ts
rename to packages/agents/review-agent/src/types.ts
diff --git a/packages/agents/reviewAgent/tsconfig.json b/packages/agents/review-agent/tsconfig.json
similarity index 100%
rename from packages/agents/reviewAgent/tsconfig.json
rename to packages/agents/review-agent/tsconfig.json
diff --git a/packages/agents/reviewAgent/nodes/fetch_file_content.ts b/packages/agents/reviewAgent/nodes/fetch_file_content.ts
deleted file mode 100644
index d33c3e50..00000000
--- a/packages/agents/reviewAgent/nodes/fetch_file_content.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { sourcebot_context, sourcebot_pr_payload } from "../src/types.js";
-import { z } from "zod";
-
-// TODO: use original Sourcebot schemas instead of redefining here
-const fileSourceResponseSchema = z.object({
- source: z.string(),
- language: z.string(),
-});
-
-const base64Decode = (base64: string): string => {
- const binString = atob(base64);
- return Buffer.from(Uint8Array.from(binString, (m) => m.codePointAt(0)!).buffer).toString();
-}
-
-export const fetch_file_content = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
- console.log("Executing fetch_file_content");
-
- const fileSourceRequest = {
- fileName: filename,
- repository: pr_payload.hostDomain + "/" + pr_payload.owner + "/" + pr_payload.repo,
- }
- console.log(JSON.stringify(fileSourceRequest, null, 2));
-
- const response = await fetch('http://localhost:3000/api/source', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'X-Org-Domain': '~'
- },
- body: JSON.stringify(fileSourceRequest)
- });
-
- if (!response.ok) {
- throw new Error(`Failed to fetch file content: ${response.statusText}`);
- }
-
- const responseData = await response.json();
- const fileSourceResponse = fileSourceResponseSchema.parse(responseData);
- const fileContent = base64Decode(fileSourceResponse.source);
-
- const fileContentContext: sourcebot_context = {
- type: "file_content",
- description: `The content of the file ${filename}`,
- context: fileContent,
- }
-
- console.log("Completed fetch_file_content");
- return fileContentContext;
-}
\ No newline at end of file
diff --git a/packages/agents/reviewAgent/yarn.lock b/packages/agents/reviewAgent/yarn.lock
deleted file mode 100644
index 52f37e65..00000000
--- a/packages/agents/reviewAgent/yarn.lock
+++ /dev/null
@@ -1,842 +0,0 @@
-# This file is generated by running "yarn install" inside your project.
-# Manual changes might be lost - proceed with caution!
-
-__metadata:
- version: 8
- cacheKey: 10c0
-
-"@octokit/app@npm:^15.1.6":
- version: 15.1.6
- resolution: "@octokit/app@npm:15.1.6"
- dependencies:
- "@octokit/auth-app": "npm:^7.2.1"
- "@octokit/auth-unauthenticated": "npm:^6.1.3"
- "@octokit/core": "npm:^6.1.5"
- "@octokit/oauth-app": "npm:^7.1.6"
- "@octokit/plugin-paginate-rest": "npm:^12.0.0"
- "@octokit/types": "npm:^14.0.0"
- "@octokit/webhooks": "npm:^13.6.1"
- checksum: 10c0/865098127d85cc58adda78c9b86cae58c502410a0d9c23d6eeabe633bc6c5e7d5f8901f243c519a0ce72342a8d08d73f120b32a864a8f6e4eeb3ad33326b6825
- languageName: node
- linkType: hard
-
-"@octokit/auth-app@npm:^7.2.1":
- version: 7.2.1
- resolution: "@octokit/auth-app@npm:7.2.1"
- dependencies:
- "@octokit/auth-oauth-app": "npm:^8.1.4"
- "@octokit/auth-oauth-user": "npm:^5.1.4"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- toad-cache: "npm:^3.7.0"
- universal-github-app-jwt: "npm:^2.2.0"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/da8890ad8ae554697a4d58427d7633c8d4d6f7acbfc14e98345b85035cca6773c393f5db5767b455dfc8de9bc5bac4da2d24e443cd48e701de11dd52fa128385
- languageName: node
- linkType: hard
-
-"@octokit/auth-oauth-app@npm:^8.1.3, @octokit/auth-oauth-app@npm:^8.1.4":
- version: 8.1.4
- resolution: "@octokit/auth-oauth-app@npm:8.1.4"
- dependencies:
- "@octokit/auth-oauth-device": "npm:^7.1.5"
- "@octokit/auth-oauth-user": "npm:^5.1.4"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/types": "npm:^14.0.0"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/2e50711be9ee6c3bf85cf1d58a1d8ae56c36eb894dcfdacabda92b9454b2c49bccc56fb1a989d3e56625885f1ef36278cc01f65c01cde6e3b505b363eac66cc6
- languageName: node
- linkType: hard
-
-"@octokit/auth-oauth-device@npm:^7.1.5":
- version: 7.1.5
- resolution: "@octokit/auth-oauth-device@npm:7.1.5"
- dependencies:
- "@octokit/oauth-methods": "npm:^5.1.5"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/types": "npm:^14.0.0"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/f93a67473c58e8b855af15c7300a0937c9d3c6ea898e5e810f2f9762100c6cee22ae52e18c7f926b0e4c6c52573751d4c4ab6294c44116bed2d9fdde5cbdd35d
- languageName: node
- linkType: hard
-
-"@octokit/auth-oauth-user@npm:^5.1.3, @octokit/auth-oauth-user@npm:^5.1.4":
- version: 5.1.4
- resolution: "@octokit/auth-oauth-user@npm:5.1.4"
- dependencies:
- "@octokit/auth-oauth-device": "npm:^7.1.5"
- "@octokit/oauth-methods": "npm:^5.1.5"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/types": "npm:^14.0.0"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/2bb597b2e50fbd5c03bee3a276efa72b03105aff1d9e243c18a71b72d9fe4ad4b1cee52c2df3e022c4169c7c1d37ab14d05455d5de982528914af965e14b763a
- languageName: node
- linkType: hard
-
-"@octokit/auth-token@npm:^5.0.0":
- version: 5.1.2
- resolution: "@octokit/auth-token@npm:5.1.2"
- checksum: 10c0/bd4952571d9c559ede1f6ef8f7756900256d19df0180db04da88886a05484c7e6a4397611422e4804465a82addc8c2daa21d0bb4f450403552ee81041a4046d1
- languageName: node
- linkType: hard
-
-"@octokit/auth-unauthenticated@npm:^6.1.2, @octokit/auth-unauthenticated@npm:^6.1.3":
- version: 6.1.3
- resolution: "@octokit/auth-unauthenticated@npm:6.1.3"
- dependencies:
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- checksum: 10c0/60639987fa30e68c4ecd98dd9f1604b3f4368384979cdfa2ab9ea2d0b04c50b42a990e67167cf2a0098205a994b3a80d76b23bb0de4c8c956a898b977f5ce7d0
- languageName: node
- linkType: hard
-
-"@octokit/core@npm:^6.1.4, @octokit/core@npm:^6.1.5":
- version: 6.1.5
- resolution: "@octokit/core@npm:6.1.5"
- dependencies:
- "@octokit/auth-token": "npm:^5.0.0"
- "@octokit/graphql": "npm:^8.2.2"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- before-after-hook: "npm:^3.0.2"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/c89ea754cc33da740fdd69fadb971b4b65c89971bba4e8ad545d3ea7aba79759ee3e195c3b72e7df78f14b8b1d392bddc56e7c385d48b5272319ea6a0246ac7c
- languageName: node
- linkType: hard
-
-"@octokit/endpoint@npm:^10.1.4":
- version: 10.1.4
- resolution: "@octokit/endpoint@npm:10.1.4"
- dependencies:
- "@octokit/types": "npm:^14.0.0"
- universal-user-agent: "npm:^7.0.2"
- checksum: 10c0/bf7cca71a05dc4751df658588e32642e59c98768e7509521226b997ea4837e2d16efd35c391231c76d888226f4daf80e6a9f347dee01a69f490253654dada581
- languageName: node
- linkType: hard
-
-"@octokit/graphql@npm:^8.2.2":
- version: 8.2.2
- resolution: "@octokit/graphql@npm:8.2.2"
- dependencies:
- "@octokit/request": "npm:^9.2.3"
- "@octokit/types": "npm:^14.0.0"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/29cd5af5ed04e416d28798a11907ab861dc73c0af47f8c9c3f4183d81d2e77d88228643825538acc81e7015f78d891f84107929019a673b06a6b38ccea6a24e0
- languageName: node
- linkType: hard
-
-"@octokit/oauth-app@npm:^7.1.6":
- version: 7.1.6
- resolution: "@octokit/oauth-app@npm:7.1.6"
- dependencies:
- "@octokit/auth-oauth-app": "npm:^8.1.3"
- "@octokit/auth-oauth-user": "npm:^5.1.3"
- "@octokit/auth-unauthenticated": "npm:^6.1.2"
- "@octokit/core": "npm:^6.1.4"
- "@octokit/oauth-authorization-url": "npm:^7.1.1"
- "@octokit/oauth-methods": "npm:^5.1.4"
- "@types/aws-lambda": "npm:^8.10.83"
- universal-user-agent: "npm:^7.0.0"
- checksum: 10c0/75264f6cb9336baf815bb85ea450d69c5d33eb70754065c9c5307b10d0efec2d76bb17c7788346dfb8b5e4ad0205e6df841b9c709eaf077390bba793787841f5
- languageName: node
- linkType: hard
-
-"@octokit/oauth-authorization-url@npm:^7.0.0, @octokit/oauth-authorization-url@npm:^7.1.1":
- version: 7.1.1
- resolution: "@octokit/oauth-authorization-url@npm:7.1.1"
- checksum: 10c0/a2723dde503693d4b0793bc43988d7445bdbd1a4e4994f4e94e635816c87b12a3058609eb5982d91783ddf6cdf663ccdb954b5d05efdc59cb66bc0456d7ba370
- languageName: node
- linkType: hard
-
-"@octokit/oauth-methods@npm:^5.1.4, @octokit/oauth-methods@npm:^5.1.5":
- version: 5.1.5
- resolution: "@octokit/oauth-methods@npm:5.1.5"
- dependencies:
- "@octokit/oauth-authorization-url": "npm:^7.0.0"
- "@octokit/request": "npm:^9.2.3"
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- checksum: 10c0/2b1c5f9ef0fcdb2f19fd864303a67bdda296fcb2cc058efc51bf3fbb3cb582475a5532eab05bd7a57277607730fa4a7796431564693fffdb9c4cb2b471484a5c
- languageName: node
- linkType: hard
-
-"@octokit/openapi-types@npm:^25.0.0":
- version: 25.0.0
- resolution: "@octokit/openapi-types@npm:25.0.0"
- checksum: 10c0/59c9e5998e08cecec155b776c93d8f6f88ab1a812add61cc65f3de8f3744201565545eac308083d18c9fa330a4381a27bcd771a311ac0348d3590a00f333f233
- languageName: node
- linkType: hard
-
-"@octokit/openapi-webhooks-types@npm:11.0.0":
- version: 11.0.0
- resolution: "@octokit/openapi-webhooks-types@npm:11.0.0"
- checksum: 10c0/cea59ba6b976a242fa4e6bedfab7e6fc3437381557d2c1876ca3aea5f6d4231559a378f9bc35e09593cb2d466afb4a2415be66b960f3e0a38b65b8b9f22ff90e
- languageName: node
- linkType: hard
-
-"@octokit/plugin-paginate-graphql@npm:^5.2.4":
- version: 5.2.4
- resolution: "@octokit/plugin-paginate-graphql@npm:5.2.4"
- peerDependencies:
- "@octokit/core": ">=6"
- checksum: 10c0/30601cf11d78e5683098d68fbff071a3d20b1e23758f40b1f43fbc93f69b3d0e07f2c9aaaaee113e586af7f604e809ba93702d932b1a4ea65998c7ab39a40a54
- languageName: node
- linkType: hard
-
-"@octokit/plugin-paginate-rest@npm:^12.0.0":
- version: 12.0.0
- resolution: "@octokit/plugin-paginate-rest@npm:12.0.0"
- dependencies:
- "@octokit/types": "npm:^14.0.0"
- peerDependencies:
- "@octokit/core": ">=6"
- checksum: 10c0/4ed04e8c111ac8cfb0692f917fe09ff6484b7436f0605c661e8051c6fb281c0260c9b067c1422529b948e53b22221b0f7664e2d10a28dcd9db14465c02c7182f
- languageName: node
- linkType: hard
-
-"@octokit/plugin-rest-endpoint-methods@npm:^14.0.0":
- version: 14.0.0
- resolution: "@octokit/plugin-rest-endpoint-methods@npm:14.0.0"
- dependencies:
- "@octokit/types": "npm:^14.0.0"
- peerDependencies:
- "@octokit/core": ">=6"
- checksum: 10c0/c3f26c5277d4aa0c898d8fdbf84326943ea80496e6f60ae34834415384ab629e1e3702d1ed82d40c31a7370edfcb5fa9fe434b0357b302b3be309879bad1d4e6
- languageName: node
- linkType: hard
-
-"@octokit/plugin-retry@npm:^7.2.1":
- version: 7.2.1
- resolution: "@octokit/plugin-retry@npm:7.2.1"
- dependencies:
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- bottleneck: "npm:^2.15.3"
- peerDependencies:
- "@octokit/core": ">=6"
- checksum: 10c0/0cac8aa32bfe9612cbaba36f51382c69c882ef7927e1deb4b166fe664959887e952205adbf8b9ff461e0128ac3e1bd807ca58e38041a55ddb3214397584f0406
- languageName: node
- linkType: hard
-
-"@octokit/plugin-throttling@npm:^10.0.0":
- version: 10.0.0
- resolution: "@octokit/plugin-throttling@npm:10.0.0"
- dependencies:
- "@octokit/types": "npm:^14.0.0"
- bottleneck: "npm:^2.15.3"
- peerDependencies:
- "@octokit/core": ^6.1.3
- checksum: 10c0/60294f89bcc03b034fce557dffcb0dba1b02d1fa1834b3b4f542f8635750df4bd23fc143f7c71f802a22a1aaed089c5da77979e6803abe11908b1c91aa1ba419
- languageName: node
- linkType: hard
-
-"@octokit/request-error@npm:^6.1.7, @octokit/request-error@npm:^6.1.8":
- version: 6.1.8
- resolution: "@octokit/request-error@npm:6.1.8"
- dependencies:
- "@octokit/types": "npm:^14.0.0"
- checksum: 10c0/02aa5bfebb5b1b9e152558b4a6f4f7dcb149b41538778ffe0fce3395fd0da5c0862311a78e94723435667581b2a58a7cefa458cf7aa19ae2948ae419276f7ee1
- languageName: node
- linkType: hard
-
-"@octokit/request@npm:^9.2.3":
- version: 9.2.3
- resolution: "@octokit/request@npm:9.2.3"
- dependencies:
- "@octokit/endpoint": "npm:^10.1.4"
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- fast-content-type-parse: "npm:^2.0.0"
- universal-user-agent: "npm:^7.0.2"
- checksum: 10c0/96067fc9a5f30f2faa00f08015309930561c3ea0536b543e1c91c475f965eabc81c48fc27d401681ebdb3f6c1acc5d46eaa69163ab98b0faa08be1c02ea5b684
- languageName: node
- linkType: hard
-
-"@octokit/types@npm:^14.0.0":
- version: 14.0.0
- resolution: "@octokit/types@npm:14.0.0"
- dependencies:
- "@octokit/openapi-types": "npm:^25.0.0"
- checksum: 10c0/c82da635fe99f265dbef7bf954d45a23ca7ce9c6fc9a8478c247b5435799e5d0eab3ff42f085785ee0882b2de293cab0ab831b379c66f41d00b78412df850ba4
- languageName: node
- linkType: hard
-
-"@octokit/webhooks-definitions@octokit/webhooks":
- version: 0.0.0-development
- resolution: "@octokit/webhooks-definitions@https://github.com/octokit/webhooks.git#commit=e5304814003f52b2697310a52f9d6bfc07632bd3"
- checksum: 10c0/ff90b65b388b3f5ce80a0aa47c6ceb98578f8df6364799db5fc17ffadbbe7e533a7f2c548b279ebd4780e00a2cdcc5f07093b0add975d014af2722496413f75f
- languageName: node
- linkType: hard
-
-"@octokit/webhooks-methods@npm:^5.1.1":
- version: 5.1.1
- resolution: "@octokit/webhooks-methods@npm:5.1.1"
- checksum: 10c0/837aa49dbc7f8bc01448f4eaea32cfb0c1cbfa0b4ac570f7bcda385c71f43e4be05e91a3fb63708448410b27e246570fde42056b6b87d755154d84eff5a6500c
- languageName: node
- linkType: hard
-
-"@octokit/webhooks@npm:^13.6.1, @octokit/webhooks@npm:^13.8.2":
- version: 13.8.2
- resolution: "@octokit/webhooks@npm:13.8.2"
- dependencies:
- "@octokit/openapi-webhooks-types": "npm:11.0.0"
- "@octokit/request-error": "npm:^6.1.7"
- "@octokit/webhooks-methods": "npm:^5.1.1"
- checksum: 10c0/5053ab9cff8afe4cd6e7d7a41af3f1b0c0ccc5058482577aa82bb8e5003f3002896c68bd59d7da363204c2d6baa4cca73ed684bb7a5a9286ca4b43172cd1fe9e
- languageName: node
- linkType: hard
-
-"@types/aws-lambda@npm:^8.10.83":
- version: 8.10.149
- resolution: "@types/aws-lambda@npm:8.10.149"
- checksum: 10c0/9ef41214a1b69fa30d89cab575429793f1ccc49cfe3a7aa75228aef31a202bb6d2c306a5b33def61ef29e0d0a1a324412bf6a4fa5a615e61117685584a394047
- languageName: node
- linkType: hard
-
-"@types/node-fetch@npm:^2.6.4":
- version: 2.6.12
- resolution: "@types/node-fetch@npm:2.6.12"
- dependencies:
- "@types/node": "npm:*"
- form-data: "npm:^4.0.0"
- checksum: 10c0/7693acad5499b7df2d1727d46cff092a63896dc04645f36b973dd6dd754a59a7faba76fcb777bdaa35d80625c6a9dd7257cca9c401a4bab03b04480cda7fd1af
- languageName: node
- linkType: hard
-
-"@types/node@npm:*":
- version: 22.15.9
- resolution: "@types/node@npm:22.15.9"
- dependencies:
- undici-types: "npm:~6.21.0"
- checksum: 10c0/f294ba23e441b4f919394d0e4c80f3f33e858e6f1db0561317148da2db3d3c67809fd1a38de481328933b0d5c6174db40cb6ab65f12b2cf3309df7f07a8e46f6
- languageName: node
- linkType: hard
-
-"@types/node@npm:^18.11.18":
- version: 18.19.93
- resolution: "@types/node@npm:18.19.93"
- dependencies:
- undici-types: "npm:~5.26.4"
- checksum: 10c0/f4d1ca1a07b88bde6ae46b1f4cf3ace8db98406283f0caa18b22f642a6f4361d801e7efd44ee13d818114bb33b2a56e1a9cd97321b58fd3d8147351fabf4be82
- languageName: node
- linkType: hard
-
-"@types/node@npm:^22.15.8":
- version: 22.15.8
- resolution: "@types/node@npm:22.15.8"
- dependencies:
- undici-types: "npm:~6.21.0"
- checksum: 10c0/980ddda0c98ce53689d52e8c20fbc7f7a42280780c4617892872c3bc2c342ef7b0bae5ff41eec536981a7d39fd7a9af71f5ce8849b36a2084d3945b7bc438d05
- languageName: node
- linkType: hard
-
-"abort-controller@npm:^3.0.0":
- version: 3.0.0
- resolution: "abort-controller@npm:3.0.0"
- dependencies:
- event-target-shim: "npm:^5.0.0"
- checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5
- languageName: node
- linkType: hard
-
-"agentkeepalive@npm:^4.2.1":
- version: 4.6.0
- resolution: "agentkeepalive@npm:4.6.0"
- dependencies:
- humanize-ms: "npm:^1.2.1"
- checksum: 10c0/235c182432f75046835b05f239708107138a40103deee23b6a08caee5136873709155753b394ec212e49e60e94a378189562cb01347765515cff61b692c69187
- languageName: node
- linkType: hard
-
-"asynckit@npm:^0.4.0":
- version: 0.4.0
- resolution: "asynckit@npm:0.4.0"
- checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
- languageName: node
- linkType: hard
-
-"before-after-hook@npm:^3.0.2":
- version: 3.0.2
- resolution: "before-after-hook@npm:3.0.2"
- checksum: 10c0/dea640f9e88a1085372c9bcc974b7bf379267490693da92ec102a7d8b515dd1e95f00ef575a146b83ca638104c57406c3427d37bdf082f602dde4b56d05bba14
- languageName: node
- linkType: hard
-
-"bottleneck@npm:^2.15.3":
- version: 2.19.5
- resolution: "bottleneck@npm:2.19.5"
- checksum: 10c0/b0f72e45b2e0f56a21ba720183f16bef8e693452fb0495d997fa354e42904353a94bd8fd429868e6751bc85e54b6755190519eed5a0ae0a94a5185209ae7c6d0
- languageName: node
- linkType: hard
-
-"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
- version: 1.0.2
- resolution: "call-bind-apply-helpers@npm:1.0.2"
- dependencies:
- es-errors: "npm:^1.3.0"
- function-bind: "npm:^1.1.2"
- checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938
- languageName: node
- linkType: hard
-
-"combined-stream@npm:^1.0.8":
- version: 1.0.8
- resolution: "combined-stream@npm:1.0.8"
- dependencies:
- delayed-stream: "npm:~1.0.0"
- checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
- languageName: node
- linkType: hard
-
-"commander@npm:^12.0.0":
- version: 12.1.0
- resolution: "commander@npm:12.1.0"
- checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
- languageName: node
- linkType: hard
-
-"delayed-stream@npm:~1.0.0":
- version: 1.0.0
- resolution: "delayed-stream@npm:1.0.0"
- checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
- languageName: node
- linkType: hard
-
-"dotenv@npm:^16.5.0":
- version: 16.5.0
- resolution: "dotenv@npm:16.5.0"
- checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
- languageName: node
- linkType: hard
-
-"dunder-proto@npm:^1.0.1":
- version: 1.0.1
- resolution: "dunder-proto@npm:1.0.1"
- dependencies:
- call-bind-apply-helpers: "npm:^1.0.1"
- es-errors: "npm:^1.3.0"
- gopd: "npm:^1.2.0"
- checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031
- languageName: node
- linkType: hard
-
-"es-define-property@npm:^1.0.1":
- version: 1.0.1
- resolution: "es-define-property@npm:1.0.1"
- checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c
- languageName: node
- linkType: hard
-
-"es-errors@npm:^1.3.0":
- version: 1.3.0
- resolution: "es-errors@npm:1.3.0"
- checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85
- languageName: node
- linkType: hard
-
-"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1":
- version: 1.1.1
- resolution: "es-object-atoms@npm:1.1.1"
- dependencies:
- es-errors: "npm:^1.3.0"
- checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c
- languageName: node
- linkType: hard
-
-"es-set-tostringtag@npm:^2.1.0":
- version: 2.1.0
- resolution: "es-set-tostringtag@npm:2.1.0"
- dependencies:
- es-errors: "npm:^1.3.0"
- get-intrinsic: "npm:^1.2.6"
- has-tostringtag: "npm:^1.0.2"
- hasown: "npm:^2.0.2"
- checksum: 10c0/ef2ca9ce49afe3931cb32e35da4dcb6d86ab02592cfc2ce3e49ced199d9d0bb5085fc7e73e06312213765f5efa47cc1df553a6a5154584b21448e9fb8355b1af
- languageName: node
- linkType: hard
-
-"event-target-shim@npm:^5.0.0":
- version: 5.0.1
- resolution: "event-target-shim@npm:5.0.1"
- checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b
- languageName: node
- linkType: hard
-
-"eventsource-parser@npm:^3.0.1":
- version: 3.0.1
- resolution: "eventsource-parser@npm:3.0.1"
- checksum: 10c0/146ce5ae8325d07645a49bbc54d7ac3aef42f5138bfbbe83d5cf96293b50eab2219926d6cf41eed0a0f90132578089652ba9286a19297662900133a9da6c2fd0
- languageName: node
- linkType: hard
-
-"eventsource@npm:^3.0.5":
- version: 3.0.6
- resolution: "eventsource@npm:3.0.6"
- dependencies:
- eventsource-parser: "npm:^3.0.1"
- checksum: 10c0/074d865ea1c7e29e3243f85a13306e89fca2d775b982dca03fa6bfa75c56827fa89cf1ab9e730db24bd6b104cbdcae074f2b37ba498874e9dd9710fbff4979bb
- languageName: node
- linkType: hard
-
-"fast-content-type-parse@npm:^2.0.0":
- version: 2.0.1
- resolution: "fast-content-type-parse@npm:2.0.1"
- checksum: 10c0/e5ff87d75a35ae4cf377df1dca46ec49e7abbdc8513689676ecdef548b94900b50e66e516e64470035d79b9f7010ef15d98c24d8ae803a881363cc59e0715e19
- languageName: node
- linkType: hard
-
-"form-data-encoder@npm:1.7.2":
- version: 1.7.2
- resolution: "form-data-encoder@npm:1.7.2"
- checksum: 10c0/56553768037b6d55d9de524f97fe70555f0e415e781cb56fc457a68263de3d40fadea2304d4beef2d40b1a851269bd7854e42c362107071892cb5238debe9464
- languageName: node
- linkType: hard
-
-"form-data@npm:^4.0.0":
- version: 4.0.2
- resolution: "form-data@npm:4.0.2"
- dependencies:
- asynckit: "npm:^0.4.0"
- combined-stream: "npm:^1.0.8"
- es-set-tostringtag: "npm:^2.1.0"
- mime-types: "npm:^2.1.12"
- checksum: 10c0/e534b0cf025c831a0929bf4b9bbe1a9a6b03e273a8161f9947286b9b13bf8fb279c6944aae0070c4c311100c6d6dbb815cd955dc217728caf73fad8dc5b8ee9c
- languageName: node
- linkType: hard
-
-"formdata-node@npm:^4.3.2":
- version: 4.4.1
- resolution: "formdata-node@npm:4.4.1"
- dependencies:
- node-domexception: "npm:1.0.0"
- web-streams-polyfill: "npm:4.0.0-beta.3"
- checksum: 10c0/74151e7b228ffb33b565cec69182694ad07cc3fdd9126a8240468bb70a8ba66e97e097072b60bcb08729b24c7ce3fd3e0bd7f1f80df6f9f662b9656786e76f6a
- languageName: node
- linkType: hard
-
-"function-bind@npm:^1.1.2":
- version: 1.1.2
- resolution: "function-bind@npm:1.1.2"
- checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5
- languageName: node
- linkType: hard
-
-"get-intrinsic@npm:^1.2.6":
- version: 1.3.0
- resolution: "get-intrinsic@npm:1.3.0"
- dependencies:
- call-bind-apply-helpers: "npm:^1.0.2"
- es-define-property: "npm:^1.0.1"
- es-errors: "npm:^1.3.0"
- es-object-atoms: "npm:^1.1.1"
- function-bind: "npm:^1.1.2"
- get-proto: "npm:^1.0.1"
- gopd: "npm:^1.2.0"
- has-symbols: "npm:^1.1.0"
- hasown: "npm:^2.0.2"
- math-intrinsics: "npm:^1.1.0"
- checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a
- languageName: node
- linkType: hard
-
-"get-proto@npm:^1.0.1":
- version: 1.0.1
- resolution: "get-proto@npm:1.0.1"
- dependencies:
- dunder-proto: "npm:^1.0.1"
- es-object-atoms: "npm:^1.0.0"
- checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c
- languageName: node
- linkType: hard
-
-"gopd@npm:^1.2.0":
- version: 1.2.0
- resolution: "gopd@npm:1.2.0"
- checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead
- languageName: node
- linkType: hard
-
-"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0":
- version: 1.1.0
- resolution: "has-symbols@npm:1.1.0"
- checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e
- languageName: node
- linkType: hard
-
-"has-tostringtag@npm:^1.0.2":
- version: 1.0.2
- resolution: "has-tostringtag@npm:1.0.2"
- dependencies:
- has-symbols: "npm:^1.0.3"
- checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c
- languageName: node
- linkType: hard
-
-"hasown@npm:^2.0.2":
- version: 2.0.2
- resolution: "hasown@npm:2.0.2"
- dependencies:
- function-bind: "npm:^1.1.2"
- checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9
- languageName: node
- linkType: hard
-
-"humanize-ms@npm:^1.2.1":
- version: 1.2.1
- resolution: "humanize-ms@npm:1.2.1"
- dependencies:
- ms: "npm:^2.0.0"
- checksum: 10c0/f34a2c20161d02303c2807badec2f3b49cbfbbb409abd4f95a07377ae01cfe6b59e3d15ac609cffcd8f2521f0eb37b7e1091acf65da99aa2a4f1ad63c21e7e7a
- languageName: node
- linkType: hard
-
-"math-intrinsics@npm:^1.1.0":
- version: 1.1.0
- resolution: "math-intrinsics@npm:1.1.0"
- checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f
- languageName: node
- linkType: hard
-
-"mime-db@npm:1.52.0":
- version: 1.52.0
- resolution: "mime-db@npm:1.52.0"
- checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa
- languageName: node
- linkType: hard
-
-"mime-types@npm:^2.1.12":
- version: 2.1.35
- resolution: "mime-types@npm:2.1.35"
- dependencies:
- mime-db: "npm:1.52.0"
- checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2
- languageName: node
- linkType: hard
-
-"ms@npm:^2.0.0":
- version: 2.1.3
- resolution: "ms@npm:2.1.3"
- checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
- languageName: node
- linkType: hard
-
-"node-domexception@npm:1.0.0":
- version: 1.0.0
- resolution: "node-domexception@npm:1.0.0"
- checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
- languageName: node
- linkType: hard
-
-"node-fetch@npm:^2.6.7":
- version: 2.7.0
- resolution: "node-fetch@npm:2.7.0"
- dependencies:
- whatwg-url: "npm:^5.0.0"
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
- checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8
- languageName: node
- linkType: hard
-
-"octokit@npm:^4.1.3":
- version: 4.1.3
- resolution: "octokit@npm:4.1.3"
- dependencies:
- "@octokit/app": "npm:^15.1.6"
- "@octokit/core": "npm:^6.1.5"
- "@octokit/oauth-app": "npm:^7.1.6"
- "@octokit/plugin-paginate-graphql": "npm:^5.2.4"
- "@octokit/plugin-paginate-rest": "npm:^12.0.0"
- "@octokit/plugin-rest-endpoint-methods": "npm:^14.0.0"
- "@octokit/plugin-retry": "npm:^7.2.1"
- "@octokit/plugin-throttling": "npm:^10.0.0"
- "@octokit/request-error": "npm:^6.1.8"
- "@octokit/types": "npm:^14.0.0"
- checksum: 10c0/a35352dff1d7bacf8123e491489650c29b830a765f78113064edd6bd0aad0e58e8933874394892972fb8b0e43369b6f7a7b354426c61f4d9fc37408891fde582
- languageName: node
- linkType: hard
-
-"openai@npm:^4.97.0":
- version: 4.97.0
- resolution: "openai@npm:4.97.0"
- dependencies:
- "@types/node": "npm:^18.11.18"
- "@types/node-fetch": "npm:^2.6.4"
- abort-controller: "npm:^3.0.0"
- agentkeepalive: "npm:^4.2.1"
- form-data-encoder: "npm:1.7.2"
- formdata-node: "npm:^4.3.2"
- node-fetch: "npm:^2.6.7"
- peerDependencies:
- ws: ^8.18.0
- zod: ^3.23.8
- peerDependenciesMeta:
- ws:
- optional: true
- zod:
- optional: true
- bin:
- openai: bin/cli
- checksum: 10c0/9938eb85102dd0465197e79c0912df9f3afd52be2d9524fd5100f5befbfa70e6bb7803120515ffa0925b7afc14762052b087c7c2f3d0b85852efa22aa1d745d6
- languageName: node
- linkType: hard
-
-"parse-diff@npm:^0.11.1":
- version: 0.11.1
- resolution: "parse-diff@npm:0.11.1"
- checksum: 10c0/b8a488039f535e0ddaf1cfd4a13c2adc6d142f4e6263de6dc603f9762b59da89703a8f0dc8aacb7c7c66cdbdd2d075a57c63813fb74f66c9b8f5fe8ad2e89689
- languageName: node
- linkType: hard
-
-"review-agent@workspace:.":
- version: 0.0.0-use.local
- resolution: "review-agent@workspace:."
- dependencies:
- "@octokit/webhooks": "npm:^13.8.2"
- "@octokit/webhooks-definitions": octokit/webhooks
- "@types/node": "npm:^22.15.8"
- dotenv: "npm:^16.5.0"
- octokit: "npm:^4.1.3"
- openai: "npm:^4.97.0"
- parse-diff: "npm:^0.11.1"
- smee-client: "npm:^3.1.1"
- typescript: "npm:^5.8.3"
- zod: "npm:^3.24.4"
- zod-to-json-schema: "npm:^3.24.5"
- languageName: unknown
- linkType: soft
-
-"smee-client@npm:^3.1.1":
- version: 3.1.1
- resolution: "smee-client@npm:3.1.1"
- dependencies:
- commander: "npm:^12.0.0"
- eventsource: "npm:^3.0.5"
- undici: "npm:^6.19.8"
- validator: "npm:^13.11.0"
- bin:
- smee: bin/smee.js
- checksum: 10c0/24fd526330d0d0b0763de574c4d6595739eb0413882d617dce07ca35f71fd732c96a9ca723d394e1e9e938b4ef004a9d69797cb700ec72a6fc69396c8128d245
- languageName: node
- linkType: hard
-
-"toad-cache@npm:^3.7.0":
- version: 3.7.0
- resolution: "toad-cache@npm:3.7.0"
- checksum: 10c0/7dae2782ee20b22c9798bb8b71dec7ec6a0091021d2ea9dd6e8afccab6b65b358fdba49a02209fac574499702e2c000660721516c87c2538d1b2c0ba03e8c0c3
- languageName: node
- linkType: hard
-
-"tr46@npm:~0.0.3":
- version: 0.0.3
- resolution: "tr46@npm:0.0.3"
- checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11
- languageName: node
- linkType: hard
-
-"typescript@npm:^5.8.3":
- version: 5.8.3
- resolution: "typescript@npm:5.8.3"
- bin:
- tsc: bin/tsc
- tsserver: bin/tsserver
- checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48
- languageName: node
- linkType: hard
-
-"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin":
- version: 5.8.3
- resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"
- bin:
- tsc: bin/tsc
- tsserver: bin/tsserver
- checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb
- languageName: node
- linkType: hard
-
-"undici-types@npm:~5.26.4":
- version: 5.26.5
- resolution: "undici-types@npm:5.26.5"
- checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
- languageName: node
- linkType: hard
-
-"undici-types@npm:~6.21.0":
- version: 6.21.0
- resolution: "undici-types@npm:6.21.0"
- checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04
- languageName: node
- linkType: hard
-
-"undici@npm:^6.19.8":
- version: 6.21.2
- resolution: "undici@npm:6.21.2"
- checksum: 10c0/799bbc02b77dda9b6b12d56d2620a3a4d4cf087908d6a548acc3ce32f21b5c27467f75c2c4b30fab281daf341210be3d685e8fe99854288de541715ae5735027
- languageName: node
- linkType: hard
-
-"universal-github-app-jwt@npm:^2.2.0":
- version: 2.2.2
- resolution: "universal-github-app-jwt@npm:2.2.2"
- checksum: 10c0/7ae5f031fb89c01a4407459b764c5e6341d725d436e1ceec161f9b754dd4883d9704cc8de53d5b6314b7e1bef8dbc7561799fc23001e706f213d468c17026fb6
- languageName: node
- linkType: hard
-
-"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2":
- version: 7.0.2
- resolution: "universal-user-agent@npm:7.0.2"
- checksum: 10c0/e60517ee929813e6b3ac0ceb3c66deccafadc71341edca160279ff046319c684fd7090a60d63aa61cd34a06c2d2acebeb8c2f8d364244ae7bf8ab788e20cd8c8
- languageName: node
- linkType: hard
-
-"validator@npm:^13.11.0":
- version: 13.15.0
- resolution: "validator@npm:13.15.0"
- checksum: 10c0/0f13fd7031ac575e8d7828431da8ef5859bac6a38ee65e1d7fdd367dbf1c3d94d95182aecc3183f7fa7a30ff4474bf864d1aff54707620227a2cdbfd36d894c2
- languageName: node
- linkType: hard
-
-"web-streams-polyfill@npm:4.0.0-beta.3":
- version: 4.0.0-beta.3
- resolution: "web-streams-polyfill@npm:4.0.0-beta.3"
- checksum: 10c0/a9596779db2766990117ed3a158e0b0e9f69b887a6d6ba0779940259e95f99dc3922e534acc3e5a117b5f5905300f527d6fbf8a9f0957faf1d8e585ce3452e8e
- languageName: node
- linkType: hard
-
-"webidl-conversions@npm:^3.0.0":
- version: 3.0.1
- resolution: "webidl-conversions@npm:3.0.1"
- checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db
- languageName: node
- linkType: hard
-
-"whatwg-url@npm:^5.0.0":
- version: 5.0.0
- resolution: "whatwg-url@npm:5.0.0"
- dependencies:
- tr46: "npm:~0.0.3"
- webidl-conversions: "npm:^3.0.0"
- checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5
- languageName: node
- linkType: hard
-
-"zod-to-json-schema@npm:^3.24.5":
- version: 3.24.5
- resolution: "zod-to-json-schema@npm:3.24.5"
- peerDependencies:
- zod: ^3.24.1
- checksum: 10c0/0745b94ba53e652d39f262641cdeb2f75d24339fb6076a38ce55bcf53d82dfaea63adf524ebc5f658681005401687f8e9551c4feca7c4c882e123e66091dfb90
- languageName: node
- linkType: hard
-
-"zod@npm:^3.24.4":
- version: 3.24.4
- resolution: "zod@npm:3.24.4"
- checksum: 10c0/ab3112f017562180a41a0f83d870b333677f7d6b77f106696c56894567051b91154714a088149d8387a4f50806a2520efcb666f108cd384a35c236a191186d91
- languageName: node
- linkType: hard
diff --git a/packages/web/src/app/[domain]/agents/page.tsx b/packages/web/src/app/[domain]/agents/page.tsx
new file mode 100644
index 00000000..1a634a2c
--- /dev/null
+++ b/packages/web/src/app/[domain]/agents/page.tsx
@@ -0,0 +1,70 @@
+import { Header } from "../components/header";
+import Link from "next/link";
+import Image from "next/image";
+import { NavigationMenu } from "../components/navigationMenu";
+import { FaRobot, FaCogs } from "react-icons/fa";
+import { MdRocketLaunch } from "react-icons/md";
+
+const agents = [
+ {
+ id: "review-agent",
+ name: "Review Agent",
+ description: "An agent that reviews your PRs. Uses the code indexed on Sourcebot to provide codebase wide context.",
+ deployUrl: "/agents/review-agent/deploy",
+ configureUrl: "/agents/review-agent/configure",
+ },
+ // Add more agents here as needed
+];
+
+export default function AgentsPage({ params: { domain } }: { params: { domain: string } }) {
+ return (
+
+
+
+
+ {agents.map((agent) => (
+
+ {/* Name and description */}
+
+
+ {agent.name}
+
+
+ {agent.description}
+
+
+ {/* Actions */}
+
+
+ Deploy
+
+
+ Configure
+
+
+
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index af3c85c0..a2b0e936 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2235,6 +2235,75 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/app@npm:^15.1.6":
+ version: 15.1.6
+ resolution: "@octokit/app@npm:15.1.6"
+ dependencies:
+ "@octokit/auth-app": "npm:^7.2.1"
+ "@octokit/auth-unauthenticated": "npm:^6.1.3"
+ "@octokit/core": "npm:^6.1.5"
+ "@octokit/oauth-app": "npm:^7.1.6"
+ "@octokit/plugin-paginate-rest": "npm:^12.0.0"
+ "@octokit/types": "npm:^14.0.0"
+ "@octokit/webhooks": "npm:^13.6.1"
+ checksum: 10c0/865098127d85cc58adda78c9b86cae58c502410a0d9c23d6eeabe633bc6c5e7d5f8901f243c519a0ce72342a8d08d73f120b32a864a8f6e4eeb3ad33326b6825
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-app@npm:^7.2.1":
+ version: 7.2.1
+ resolution: "@octokit/auth-app@npm:7.2.1"
+ dependencies:
+ "@octokit/auth-oauth-app": "npm:^8.1.4"
+ "@octokit/auth-oauth-user": "npm:^5.1.4"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ toad-cache: "npm:^3.7.0"
+ universal-github-app-jwt: "npm:^2.2.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/da8890ad8ae554697a4d58427d7633c8d4d6f7acbfc14e98345b85035cca6773c393f5db5767b455dfc8de9bc5bac4da2d24e443cd48e701de11dd52fa128385
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-app@npm:^8.1.3, @octokit/auth-oauth-app@npm:^8.1.4":
+ version: 8.1.4
+ resolution: "@octokit/auth-oauth-app@npm:8.1.4"
+ dependencies:
+ "@octokit/auth-oauth-device": "npm:^7.1.5"
+ "@octokit/auth-oauth-user": "npm:^5.1.4"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/2e50711be9ee6c3bf85cf1d58a1d8ae56c36eb894dcfdacabda92b9454b2c49bccc56fb1a989d3e56625885f1ef36278cc01f65c01cde6e3b505b363eac66cc6
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-device@npm:^7.1.5":
+ version: 7.1.5
+ resolution: "@octokit/auth-oauth-device@npm:7.1.5"
+ dependencies:
+ "@octokit/oauth-methods": "npm:^5.1.5"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/f93a67473c58e8b855af15c7300a0937c9d3c6ea898e5e810f2f9762100c6cee22ae52e18c7f926b0e4c6c52573751d4c4ab6294c44116bed2d9fdde5cbdd35d
+ languageName: node
+ linkType: hard
+
+"@octokit/auth-oauth-user@npm:^5.1.3, @octokit/auth-oauth-user@npm:^5.1.4":
+ version: 5.1.4
+ resolution: "@octokit/auth-oauth-user@npm:5.1.4"
+ dependencies:
+ "@octokit/auth-oauth-device": "npm:^7.1.5"
+ "@octokit/oauth-methods": "npm:^5.1.5"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/2bb597b2e50fbd5c03bee3a276efa72b03105aff1d9e243c18a71b72d9fe4ad4b1cee52c2df3e022c4169c7c1d37ab14d05455d5de982528914af965e14b763a
+ languageName: node
+ linkType: hard
+
"@octokit/auth-token@npm:^5.0.0":
version: 5.1.2
resolution: "@octokit/auth-token@npm:5.1.2"
@@ -2242,6 +2311,16 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/auth-unauthenticated@npm:^6.1.2, @octokit/auth-unauthenticated@npm:^6.1.3":
+ version: 6.1.3
+ resolution: "@octokit/auth-unauthenticated@npm:6.1.3"
+ dependencies:
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/60639987fa30e68c4ecd98dd9f1604b3f4368384979cdfa2ab9ea2d0b04c50b42a990e67167cf2a0098205a994b3a80d76b23bb0de4c8c956a898b977f5ce7d0
+ languageName: node
+ linkType: hard
+
"@octokit/core@npm:^6.1.4":
version: 6.1.4
resolution: "@octokit/core@npm:6.1.4"
@@ -2257,6 +2336,21 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/core@npm:^6.1.5":
+ version: 6.1.5
+ resolution: "@octokit/core@npm:6.1.5"
+ dependencies:
+ "@octokit/auth-token": "npm:^5.0.0"
+ "@octokit/graphql": "npm:^8.2.2"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ before-after-hook: "npm:^3.0.2"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/c89ea754cc33da740fdd69fadb971b4b65c89971bba4e8ad545d3ea7aba79759ee3e195c3b72e7df78f14b8b1d392bddc56e7c385d48b5272319ea6a0246ac7c
+ languageName: node
+ linkType: hard
+
"@octokit/endpoint@npm:^10.1.3":
version: 10.1.3
resolution: "@octokit/endpoint@npm:10.1.3"
@@ -2267,6 +2361,16 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/endpoint@npm:^10.1.4":
+ version: 10.1.4
+ resolution: "@octokit/endpoint@npm:10.1.4"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.2"
+ checksum: 10c0/bf7cca71a05dc4751df658588e32642e59c98768e7509521226b997ea4837e2d16efd35c391231c76d888226f4daf80e6a9f347dee01a69f490253654dada581
+ languageName: node
+ linkType: hard
+
"@octokit/graphql@npm:^8.1.2":
version: 8.2.1
resolution: "@octokit/graphql@npm:8.2.1"
@@ -2278,6 +2382,52 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/graphql@npm:^8.2.2":
+ version: 8.2.2
+ resolution: "@octokit/graphql@npm:8.2.2"
+ dependencies:
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/types": "npm:^14.0.0"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/29cd5af5ed04e416d28798a11907ab861dc73c0af47f8c9c3f4183d81d2e77d88228643825538acc81e7015f78d891f84107929019a673b06a6b38ccea6a24e0
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-app@npm:^7.1.6":
+ version: 7.1.6
+ resolution: "@octokit/oauth-app@npm:7.1.6"
+ dependencies:
+ "@octokit/auth-oauth-app": "npm:^8.1.3"
+ "@octokit/auth-oauth-user": "npm:^5.1.3"
+ "@octokit/auth-unauthenticated": "npm:^6.1.2"
+ "@octokit/core": "npm:^6.1.4"
+ "@octokit/oauth-authorization-url": "npm:^7.1.1"
+ "@octokit/oauth-methods": "npm:^5.1.4"
+ "@types/aws-lambda": "npm:^8.10.83"
+ universal-user-agent: "npm:^7.0.0"
+ checksum: 10c0/75264f6cb9336baf815bb85ea450d69c5d33eb70754065c9c5307b10d0efec2d76bb17c7788346dfb8b5e4ad0205e6df841b9c709eaf077390bba793787841f5
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-authorization-url@npm:^7.0.0, @octokit/oauth-authorization-url@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "@octokit/oauth-authorization-url@npm:7.1.1"
+ checksum: 10c0/a2723dde503693d4b0793bc43988d7445bdbd1a4e4994f4e94e635816c87b12a3058609eb5982d91783ddf6cdf663ccdb954b5d05efdc59cb66bc0456d7ba370
+ languageName: node
+ linkType: hard
+
+"@octokit/oauth-methods@npm:^5.1.4, @octokit/oauth-methods@npm:^5.1.5":
+ version: 5.1.5
+ resolution: "@octokit/oauth-methods@npm:5.1.5"
+ dependencies:
+ "@octokit/oauth-authorization-url": "npm:^7.0.0"
+ "@octokit/request": "npm:^9.2.3"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/2b1c5f9ef0fcdb2f19fd864303a67bdda296fcb2cc058efc51bf3fbb3cb582475a5532eab05bd7a57277607730fa4a7796431564693fffdb9c4cb2b471484a5c
+ languageName: node
+ linkType: hard
+
"@octokit/openapi-types@npm:^24.2.0":
version: 24.2.0
resolution: "@octokit/openapi-types@npm:24.2.0"
@@ -2285,6 +2435,29 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/openapi-types@npm:^25.0.0":
+ version: 25.0.0
+ resolution: "@octokit/openapi-types@npm:25.0.0"
+ checksum: 10c0/59c9e5998e08cecec155b776c93d8f6f88ab1a812add61cc65f3de8f3744201565545eac308083d18c9fa330a4381a27bcd771a311ac0348d3590a00f333f233
+ languageName: node
+ linkType: hard
+
+"@octokit/openapi-webhooks-types@npm:11.0.0":
+ version: 11.0.0
+ resolution: "@octokit/openapi-webhooks-types@npm:11.0.0"
+ checksum: 10c0/cea59ba6b976a242fa4e6bedfab7e6fc3437381557d2c1876ca3aea5f6d4231559a378f9bc35e09593cb2d466afb4a2415be66b960f3e0a38b65b8b9f22ff90e
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-paginate-graphql@npm:^5.2.4":
+ version: 5.2.4
+ resolution: "@octokit/plugin-paginate-graphql@npm:5.2.4"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/30601cf11d78e5683098d68fbff071a3d20b1e23758f40b1f43fbc93f69b3d0e07f2c9aaaaee113e586af7f604e809ba93702d932b1a4ea65998c7ab39a40a54
+ languageName: node
+ linkType: hard
+
"@octokit/plugin-paginate-rest@npm:^11.4.2":
version: 11.6.0
resolution: "@octokit/plugin-paginate-rest@npm:11.6.0"
@@ -2296,6 +2469,17 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/plugin-paginate-rest@npm:^12.0.0":
+ version: 12.0.0
+ resolution: "@octokit/plugin-paginate-rest@npm:12.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/4ed04e8c111ac8cfb0692f917fe09ff6484b7436f0605c661e8051c6fb281c0260c9b067c1422529b948e53b22221b0f7664e2d10a28dcd9db14465c02c7182f
+ languageName: node
+ linkType: hard
+
"@octokit/plugin-request-log@npm:^5.3.1":
version: 5.3.1
resolution: "@octokit/plugin-request-log@npm:5.3.1"
@@ -2316,6 +2500,42 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/plugin-rest-endpoint-methods@npm:^14.0.0":
+ version: 14.0.0
+ resolution: "@octokit/plugin-rest-endpoint-methods@npm:14.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/c3f26c5277d4aa0c898d8fdbf84326943ea80496e6f60ae34834415384ab629e1e3702d1ed82d40c31a7370edfcb5fa9fe434b0357b302b3be309879bad1d4e6
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-retry@npm:^7.2.1":
+ version: 7.2.1
+ resolution: "@octokit/plugin-retry@npm:7.2.1"
+ dependencies:
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ bottleneck: "npm:^2.15.3"
+ peerDependencies:
+ "@octokit/core": ">=6"
+ checksum: 10c0/0cac8aa32bfe9612cbaba36f51382c69c882ef7927e1deb4b166fe664959887e952205adbf8b9ff461e0128ac3e1bd807ca58e38041a55ddb3214397584f0406
+ languageName: node
+ linkType: hard
+
+"@octokit/plugin-throttling@npm:^10.0.0":
+ version: 10.0.0
+ resolution: "@octokit/plugin-throttling@npm:10.0.0"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ bottleneck: "npm:^2.15.3"
+ peerDependencies:
+ "@octokit/core": ^6.1.3
+ checksum: 10c0/60294f89bcc03b034fce557dffcb0dba1b02d1fa1834b3b4f542f8635750df4bd23fc143f7c71f802a22a1aaed089c5da77979e6803abe11908b1c91aa1ba419
+ languageName: node
+ linkType: hard
+
"@octokit/request-error@npm:^6.1.7":
version: 6.1.7
resolution: "@octokit/request-error@npm:6.1.7"
@@ -2325,6 +2545,15 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/request-error@npm:^6.1.8":
+ version: 6.1.8
+ resolution: "@octokit/request-error@npm:6.1.8"
+ dependencies:
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/02aa5bfebb5b1b9e152558b4a6f4f7dcb149b41538778ffe0fce3395fd0da5c0862311a78e94723435667581b2a58a7cefa458cf7aa19ae2948ae419276f7ee1
+ languageName: node
+ linkType: hard
+
"@octokit/request@npm:^9.2.1, @octokit/request@npm:^9.2.2":
version: 9.2.2
resolution: "@octokit/request@npm:9.2.2"
@@ -2338,6 +2567,19 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/request@npm:^9.2.3":
+ version: 9.2.3
+ resolution: "@octokit/request@npm:9.2.3"
+ dependencies:
+ "@octokit/endpoint": "npm:^10.1.4"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ fast-content-type-parse: "npm:^2.0.0"
+ universal-user-agent: "npm:^7.0.2"
+ checksum: 10c0/96067fc9a5f30f2faa00f08015309930561c3ea0536b543e1c91c475f965eabc81c48fc27d401681ebdb3f6c1acc5d46eaa69163ab98b0faa08be1c02ea5b684
+ languageName: node
+ linkType: hard
+
"@octokit/rest@npm:^21.0.2":
version: 21.1.1
resolution: "@octokit/rest@npm:21.1.1"
@@ -2359,6 +2601,40 @@ __metadata:
languageName: node
linkType: hard
+"@octokit/types@npm:^14.0.0":
+ version: 14.0.0
+ resolution: "@octokit/types@npm:14.0.0"
+ dependencies:
+ "@octokit/openapi-types": "npm:^25.0.0"
+ checksum: 10c0/c82da635fe99f265dbef7bf954d45a23ca7ce9c6fc9a8478c247b5435799e5d0eab3ff42f085785ee0882b2de293cab0ab831b379c66f41d00b78412df850ba4
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks-definitions@octokit/webhooks":
+ version: 0.0.0-development
+ resolution: "@octokit/webhooks-definitions@https://github.com/octokit/webhooks.git#commit=256fdd82b484f173ac57f14e8c444fecc23c9d80"
+ checksum: 10c0/ff90b65b388b3f5ce80a0aa47c6ceb98578f8df6364799db5fc17ffadbbe7e533a7f2c548b279ebd4780e00a2cdcc5f07093b0add975d014af2722496413f75f
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks-methods@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "@octokit/webhooks-methods@npm:5.1.1"
+ checksum: 10c0/837aa49dbc7f8bc01448f4eaea32cfb0c1cbfa0b4ac570f7bcda385c71f43e4be05e91a3fb63708448410b27e246570fde42056b6b87d755154d84eff5a6500c
+ languageName: node
+ linkType: hard
+
+"@octokit/webhooks@npm:^13.6.1, @octokit/webhooks@npm:^13.8.2":
+ version: 13.8.2
+ resolution: "@octokit/webhooks@npm:13.8.2"
+ dependencies:
+ "@octokit/openapi-webhooks-types": "npm:11.0.0"
+ "@octokit/request-error": "npm:^6.1.7"
+ "@octokit/webhooks-methods": "npm:^5.1.1"
+ checksum: 10c0/5053ab9cff8afe4cd6e7d7a41af3f1b0c0ccc5058482577aa82bb8e5003f3002896c68bd59d7da363204c2d6baa4cca73ed684bb7a5a9286ca4b43172cd1fe9e
+ languageName: node
+ linkType: hard
+
"@opentelemetry/api-logs@npm:0.57.2":
version: 0.57.2
resolution: "@opentelemetry/api-logs@npm:0.57.2"
@@ -5226,6 +5502,24 @@ __metadata:
languageName: unknown
linkType: soft
+"@sourcebot/review-agent@workspace:packages/agents/review-agent":
+ version: 0.0.0-use.local
+ resolution: "@sourcebot/review-agent@workspace:packages/agents/review-agent"
+ dependencies:
+ "@octokit/webhooks": "npm:^13.8.2"
+ "@octokit/webhooks-definitions": octokit/webhooks
+ "@types/node": "npm:^22.15.8"
+ dotenv: "npm:^16.5.0"
+ octokit: "npm:^4.1.3"
+ openai: "npm:^4.97.0"
+ parse-diff: "npm:^0.11.1"
+ smee-client: "npm:^3.1.1"
+ typescript: "npm:^5.8.3"
+ zod: "npm:^3.24.4"
+ zod-to-json-schema: "npm:^3.24.5"
+ languageName: unknown
+ linkType: soft
+
"@sourcebot/schemas@workspace:*, @sourcebot/schemas@workspace:packages/schemas":
version: 0.0.0-use.local
resolution: "@sourcebot/schemas@workspace:packages/schemas"
@@ -5549,6 +5843,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/aws-lambda@npm:^8.10.83":
+ version: 8.10.149
+ resolution: "@types/aws-lambda@npm:8.10.149"
+ checksum: 10c0/9ef41214a1b69fa30d89cab575429793f1ccc49cfe3a7aa75228aef31a202bb6d2c306a5b33def61ef29e0d0a1a324412bf6a4fa5a615e61117685584a394047
+ languageName: node
+ linkType: hard
+
"@types/body-parser@npm:*":
version: 1.19.5
resolution: "@types/body-parser@npm:1.19.5"
@@ -5692,6 +5993,16 @@ __metadata:
languageName: node
linkType: hard
+"@types/node-fetch@npm:^2.6.4":
+ version: 2.6.12
+ resolution: "@types/node-fetch@npm:2.6.12"
+ dependencies:
+ "@types/node": "npm:*"
+ form-data: "npm:^4.0.0"
+ checksum: 10c0/7693acad5499b7df2d1727d46cff092a63896dc04645f36b973dd6dd754a59a7faba76fcb777bdaa35d80625c6a9dd7257cca9c401a4bab03b04480cda7fd1af
+ languageName: node
+ linkType: hard
+
"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=8.1.0, @types/node@npm:^22.7.5":
version: 22.13.11
resolution: "@types/node@npm:22.13.11"
@@ -5701,6 +6012,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/node@npm:^18.11.18":
+ version: 18.19.100
+ resolution: "@types/node@npm:18.19.100"
+ dependencies:
+ undici-types: "npm:~5.26.4"
+ checksum: 10c0/5524303171eee6788df45d736f5783b5bea27803a596b9cd5669f45487a619e5d8d41d56dd55b8c85c677ffd7c045edd8daea8c4b37e70290bee2a482fc605f6
+ languageName: node
+ linkType: hard
+
"@types/node@npm:^20":
version: 20.17.25
resolution: "@types/node@npm:20.17.25"
@@ -5710,6 +6030,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/node@npm:^22.15.8":
+ version: 22.15.17
+ resolution: "@types/node@npm:22.15.17"
+ dependencies:
+ undici-types: "npm:~6.21.0"
+ checksum: 10c0/fb92aa10b628683c5b965749f955bc2322485ecb0ea6c2f4cae5f2c7537a16834607e67083a9e9281faaae8d7dee9ada8d6a5c0de9a52c17d82912ef00c0fdd4
+ languageName: node
+ linkType: hard
+
"@types/nodemailer@npm:^6.4.17":
version: 6.4.17
resolution: "@types/nodemailer@npm:6.4.17"
@@ -6298,6 +6627,15 @@ __metadata:
languageName: node
linkType: hard
+"abort-controller@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "abort-controller@npm:3.0.0"
+ dependencies:
+ event-target-shim: "npm:^5.0.0"
+ checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5
+ languageName: node
+ linkType: hard
+
"accepts@npm:~1.3.4, accepts@npm:~1.3.8":
version: 1.3.8
resolution: "accepts@npm:1.3.8"
@@ -6351,6 +6689,15 @@ __metadata:
languageName: node
linkType: hard
+"agentkeepalive@npm:^4.2.1":
+ version: 4.6.0
+ resolution: "agentkeepalive@npm:4.6.0"
+ dependencies:
+ humanize-ms: "npm:^1.2.1"
+ checksum: 10c0/235c182432f75046835b05f239708107138a40103deee23b6a08caee5136873709155753b394ec212e49e60e94a378189562cb01347765515cff61b692c69187
+ languageName: node
+ linkType: hard
+
"ajv@npm:^6.12.4":
version: 6.12.6
resolution: "ajv@npm:6.12.6"
@@ -6738,6 +7085,13 @@ __metadata:
languageName: node
linkType: hard
+"bottleneck@npm:^2.15.3":
+ version: 2.19.5
+ resolution: "bottleneck@npm:2.19.5"
+ checksum: 10c0/b0f72e45b2e0f56a21ba720183f16bef8e693452fb0495d997fa354e42904353a94bd8fd429868e6751bc85e54b6755190519eed5a0ae0a94a5185209ae7c6d0
+ languageName: node
+ linkType: hard
+
"brace-expansion@npm:^1.1.7":
version: 1.1.11
resolution: "brace-expansion@npm:1.1.11"
@@ -7410,6 +7764,13 @@ __metadata:
languageName: node
linkType: hard
+"commander@npm:^12.0.0":
+ version: 12.1.0
+ resolution: "commander@npm:12.1.0"
+ checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
+ languageName: node
+ linkType: hard
+
"commander@npm:^2.19.0":
version: 2.20.3
resolution: "commander@npm:2.20.3"
@@ -7923,6 +8284,13 @@ __metadata:
languageName: node
linkType: hard
+"dotenv@npm:^16.5.0":
+ version: 16.5.0
+ resolution: "dotenv@npm:16.5.0"
+ checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
+ languageName: node
+ linkType: hard
+
"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
version: 1.0.1
resolution: "dunder-proto@npm:1.0.1"
@@ -8873,6 +9241,29 @@ __metadata:
languageName: node
linkType: hard
+"event-target-shim@npm:^5.0.0":
+ version: 5.0.1
+ resolution: "event-target-shim@npm:5.0.1"
+ checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b
+ languageName: node
+ linkType: hard
+
+"eventsource-parser@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "eventsource-parser@npm:3.0.1"
+ checksum: 10c0/146ce5ae8325d07645a49bbc54d7ac3aef42f5138bfbbe83d5cf96293b50eab2219926d6cf41eed0a0f90132578089652ba9286a19297662900133a9da6c2fd0
+ languageName: node
+ linkType: hard
+
+"eventsource@npm:^3.0.5":
+ version: 3.0.6
+ resolution: "eventsource@npm:3.0.6"
+ dependencies:
+ eventsource-parser: "npm:^3.0.1"
+ checksum: 10c0/074d865ea1c7e29e3243f85a13306e89fca2d775b982dca03fa6bfa75c56827fa89cf1ab9e730db24bd6b104cbdcae074f2b37ba498874e9dd9710fbff4979bb
+ languageName: node
+ linkType: hard
+
"expect-type@npm:^1.1.0":
version: 1.2.0
resolution: "expect-type@npm:1.2.0"
@@ -9120,6 +9511,13 @@ __metadata:
languageName: node
linkType: hard
+"form-data-encoder@npm:1.7.2":
+ version: 1.7.2
+ resolution: "form-data-encoder@npm:1.7.2"
+ checksum: 10c0/56553768037b6d55d9de524f97fe70555f0e415e781cb56fc457a68263de3d40fadea2304d4beef2d40b1a851269bd7854e42c362107071892cb5238debe9464
+ languageName: node
+ linkType: hard
+
"form-data@npm:^4.0.0":
version: 4.0.2
resolution: "form-data@npm:4.0.2"
@@ -9132,6 +9530,16 @@ __metadata:
languageName: node
linkType: hard
+"formdata-node@npm:^4.3.2":
+ version: 4.4.1
+ resolution: "formdata-node@npm:4.4.1"
+ dependencies:
+ node-domexception: "npm:1.0.0"
+ web-streams-polyfill: "npm:4.0.0-beta.3"
+ checksum: 10c0/74151e7b228ffb33b565cec69182694ad07cc3fdd9126a8240468bb70a8ba66e97e097072b60bcb08729b24c7ce3fd3e0bd7f1f80df6f9f662b9656786e76f6a
+ languageName: node
+ linkType: hard
+
"forwarded-parse@npm:2.1.2":
version: 2.1.2
resolution: "forwarded-parse@npm:2.1.2"
@@ -9701,6 +10109,15 @@ __metadata:
languageName: node
linkType: hard
+"humanize-ms@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "humanize-ms@npm:1.2.1"
+ dependencies:
+ ms: "npm:^2.0.0"
+ checksum: 10c0/f34a2c20161d02303c2807badec2f3b49cbfbbb409abd4f95a07377ae01cfe6b59e3d15ac609cffcd8f2521f0eb37b7e1091acf65da99aa2a4f1ad63c21e7e7a
+ languageName: node
+ linkType: hard
+
"iconv-lite@npm:0.4.24":
version: 0.4.24
resolution: "iconv-lite@npm:0.4.24"
@@ -11061,7 +11478,7 @@ __metadata:
languageName: node
linkType: hard
-"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3":
+"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1, ms@npm:^2.1.3":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
@@ -11347,6 +11764,13 @@ __metadata:
languageName: node
linkType: hard
+"node-domexception@npm:1.0.0":
+ version: 1.0.0
+ resolution: "node-domexception@npm:1.0.0"
+ checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b
+ languageName: node
+ linkType: hard
+
"node-fetch@npm:^2.6.7, node-fetch@npm:^2.7.0":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
@@ -11576,6 +12000,24 @@ __metadata:
languageName: node
linkType: hard
+"octokit@npm:^4.1.3":
+ version: 4.1.3
+ resolution: "octokit@npm:4.1.3"
+ dependencies:
+ "@octokit/app": "npm:^15.1.6"
+ "@octokit/core": "npm:^6.1.5"
+ "@octokit/oauth-app": "npm:^7.1.6"
+ "@octokit/plugin-paginate-graphql": "npm:^5.2.4"
+ "@octokit/plugin-paginate-rest": "npm:^12.0.0"
+ "@octokit/plugin-rest-endpoint-methods": "npm:^14.0.0"
+ "@octokit/plugin-retry": "npm:^7.2.1"
+ "@octokit/plugin-throttling": "npm:^10.0.0"
+ "@octokit/request-error": "npm:^6.1.8"
+ "@octokit/types": "npm:^14.0.0"
+ checksum: 10c0/a35352dff1d7bacf8123e491489650c29b830a765f78113064edd6bd0aad0e58e8933874394892972fb8b0e43369b6f7a7b354426c61f4d9fc37408891fde582
+ languageName: node
+ linkType: hard
+
"on-finished@npm:2.4.1":
version: 2.4.1
resolution: "on-finished@npm:2.4.1"
@@ -11623,6 +12065,31 @@ __metadata:
languageName: node
linkType: hard
+"openai@npm:^4.97.0":
+ version: 4.98.0
+ resolution: "openai@npm:4.98.0"
+ dependencies:
+ "@types/node": "npm:^18.11.18"
+ "@types/node-fetch": "npm:^2.6.4"
+ abort-controller: "npm:^3.0.0"
+ agentkeepalive: "npm:^4.2.1"
+ form-data-encoder: "npm:1.7.2"
+ formdata-node: "npm:^4.3.2"
+ node-fetch: "npm:^2.6.7"
+ peerDependencies:
+ ws: ^8.18.0
+ zod: ^3.23.8
+ peerDependenciesMeta:
+ ws:
+ optional: true
+ zod:
+ optional: true
+ bin:
+ openai: bin/cli
+ checksum: 10c0/399f07cd04c47d05be89cbcf3edb98650177ca09322ae664ade347bd56830cc0423834b4635341950bd9af59fdf203d3fad1de7927f4d8d2449b08c642c0ee3e
+ languageName: node
+ linkType: hard
+
"openapi-fetch@npm:^0.13.4":
version: 0.13.5
resolution: "openapi-fetch@npm:0.13.5"
@@ -11722,6 +12189,13 @@ __metadata:
languageName: node
linkType: hard
+"parse-diff@npm:^0.11.1":
+ version: 0.11.1
+ resolution: "parse-diff@npm:0.11.1"
+ checksum: 10c0/b8a488039f535e0ddaf1cfd4a13c2adc6d142f4e6263de6dc603f9762b59da89703a8f0dc8aacb7c7c66cdbdd2d075a57c63813fb74f66c9b8f5fe8ad2e89689
+ languageName: node
+ linkType: hard
+
"parse-json@npm:^4.0.0":
version: 4.0.0
resolution: "parse-json@npm:4.0.0"
@@ -13583,6 +14057,20 @@ __metadata:
languageName: node
linkType: hard
+"smee-client@npm:^3.1.1":
+ version: 3.1.1
+ resolution: "smee-client@npm:3.1.1"
+ dependencies:
+ commander: "npm:^12.0.0"
+ eventsource: "npm:^3.0.5"
+ undici: "npm:^6.19.8"
+ validator: "npm:^13.11.0"
+ bin:
+ smee: bin/smee.js
+ checksum: 10c0/24fd526330d0d0b0763de574c4d6595739eb0413882d617dce07ca35f71fd732c96a9ca723d394e1e9e938b4ef004a9d69797cb700ec72a6fc69396c8128d245
+ languageName: node
+ linkType: hard
+
"smtp-address-parser@npm:1.0.10":
version: 1.0.10
resolution: "smtp-address-parser@npm:1.0.10"
@@ -14247,6 +14735,13 @@ __metadata:
languageName: node
linkType: hard
+"toad-cache@npm:^3.7.0":
+ version: 3.7.0
+ resolution: "toad-cache@npm:3.7.0"
+ checksum: 10c0/7dae2782ee20b22c9798bb8b71dec7ec6a0091021d2ea9dd6e8afccab6b65b358fdba49a02209fac574499702e2c000660721516c87c2538d1b2c0ba03e8c0c3
+ languageName: node
+ linkType: hard
+
"toidentifier@npm:1.0.1":
version: 1.0.1
resolution: "toidentifier@npm:1.0.1"
@@ -14479,6 +14974,16 @@ __metadata:
languageName: node
linkType: hard
+"typescript@npm:^5.8.3":
+ version: 5.8.3
+ resolution: "typescript@npm:5.8.3"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48
+ languageName: node
+ linkType: hard
+
"typescript@patch:typescript@npm%3A^5#optional!builtin, typescript@patch:typescript@npm%3A^5.6.2#optional!builtin, typescript@patch:typescript@npm%3A^5.7.3#optional!builtin":
version: 5.8.2
resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=5786d5"
@@ -14489,6 +14994,16 @@ __metadata:
languageName: node
linkType: hard
+"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin":
+ version: 5.8.3
+ resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"
+ bin:
+ tsc: bin/tsc
+ tsserver: bin/tsserver
+ checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb
+ languageName: node
+ linkType: hard
+
"ua-parser-js@npm:^1.0.33":
version: 1.0.40
resolution: "ua-parser-js@npm:1.0.40"
@@ -14517,6 +15032,13 @@ __metadata:
languageName: node
linkType: hard
+"undici-types@npm:~5.26.4":
+ version: 5.26.5
+ resolution: "undici-types@npm:5.26.5"
+ checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
+ languageName: node
+ linkType: hard
+
"undici-types@npm:~6.19.2":
version: 6.19.8
resolution: "undici-types@npm:6.19.8"
@@ -14531,6 +15053,20 @@ __metadata:
languageName: node
linkType: hard
+"undici-types@npm:~6.21.0":
+ version: 6.21.0
+ resolution: "undici-types@npm:6.21.0"
+ checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04
+ languageName: node
+ linkType: hard
+
+"undici@npm:^6.19.8":
+ version: 6.21.2
+ resolution: "undici@npm:6.21.2"
+ checksum: 10c0/799bbc02b77dda9b6b12d56d2620a3a4d4cf087908d6a548acc3ce32f21b5c27467f75c2c4b30fab281daf341210be3d685e8fe99854288de541715ae5735027
+ languageName: node
+ linkType: hard
+
"unique-filename@npm:^4.0.0":
version: 4.0.0
resolution: "unique-filename@npm:4.0.0"
@@ -14597,6 +15133,13 @@ __metadata:
languageName: node
linkType: hard
+"universal-github-app-jwt@npm:^2.2.0":
+ version: 2.2.2
+ resolution: "universal-github-app-jwt@npm:2.2.2"
+ checksum: 10c0/7ae5f031fb89c01a4407459b764c5e6341d725d436e1ceec161f9b754dd4883d9704cc8de53d5b6314b7e1bef8dbc7561799fc23001e706f213d468c17026fb6
+ languageName: node
+ linkType: hard
+
"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2":
version: 7.0.2
resolution: "universal-user-agent@npm:7.0.2"
@@ -14728,6 +15271,13 @@ __metadata:
languageName: node
linkType: hard
+"validator@npm:^13.11.0":
+ version: 13.15.0
+ resolution: "validator@npm:13.15.0"
+ checksum: 10c0/0f13fd7031ac575e8d7828431da8ef5859bac6a38ee65e1d7fdd367dbf1c3d94d95182aecc3183f7fa7a30ff4474bf864d1aff54707620227a2cdbfd36d894c2
+ languageName: node
+ linkType: hard
+
"vary@npm:^1, vary@npm:~1.1.2":
version: 1.1.2
resolution: "vary@npm:1.1.2"
@@ -14911,6 +15461,13 @@ __metadata:
languageName: node
linkType: hard
+"web-streams-polyfill@npm:4.0.0-beta.3":
+ version: 4.0.0-beta.3
+ resolution: "web-streams-polyfill@npm:4.0.0-beta.3"
+ checksum: 10c0/a9596779db2766990117ed3a158e0b0e9f69b887a6d6ba0779940259e95f99dc3922e534acc3e5a117b5f5905300f527d6fbf8a9f0957faf1d8e585ce3452e8e
+ languageName: node
+ linkType: hard
+
"web-vitals@npm:^4.2.4":
version: 4.2.4
resolution: "web-vitals@npm:4.2.4"
@@ -15249,6 +15806,15 @@ __metadata:
languageName: node
linkType: hard
+"zod-to-json-schema@npm:^3.24.5":
+ version: 3.24.5
+ resolution: "zod-to-json-schema@npm:3.24.5"
+ peerDependencies:
+ zod: ^3.24.1
+ checksum: 10c0/0745b94ba53e652d39f262641cdeb2f75d24339fb6076a38ce55bcf53d82dfaea63adf524ebc5f658681005401687f8e9551c4feca7c4c882e123e66091dfb90
+ languageName: node
+ linkType: hard
+
"zod@npm:^3.24.2":
version: 3.24.2
resolution: "zod@npm:3.24.2"
@@ -15256,6 +15822,13 @@ __metadata:
languageName: node
linkType: hard
+"zod@npm:^3.24.4":
+ version: 3.24.4
+ resolution: "zod@npm:3.24.4"
+ checksum: 10c0/ab3112f017562180a41a0f83d870b333677f7d6b77f106696c56894567051b91154714a088149d8387a4f50806a2520efcb666f108cd384a35c236a191186d91
+ languageName: node
+ linkType: hard
+
"zwitch@npm:^2.0.4":
version: 2.0.4
resolution: "zwitch@npm:2.0.4"
From a81cd2494f90d03ead5c9229c18c6de3820bc53a Mon Sep 17 00:00:00 2001
From: msukkari
Date: Fri, 9 May 2025 11:24:51 -0700
Subject: [PATCH 04/15] move review agent to web
---
package.json | 1 +
packages/agents/review-agent/.gitignore | 136 ------------------
packages/agents/review-agent/package.json | 26 ----
packages/agents/review-agent/src/app.ts | 62 --------
packages/agents/review-agent/src/env.ts | 13 --
packages/agents/review-agent/tsconfig.json | 114 ---------------
packages/web/package.json | 6 +-
.../app/[domain]/browse/[...path]/page.tsx | 3 +-
.../web/src/app/api/(server)/webhook/route.ts | 62 ++++++++
packages/web/src/env.mjs | 6 +
.../src/features/agents/review-agent/app.ts | 27 ++++
.../review-agent}/nodes/fetch_file_content.ts | 6 +-
.../nodes/generate_diff_review_prompt.ts | 2 +-
.../nodes/generate_pr_reviews.ts | 10 +-
.../review-agent}/nodes/github_pr_parser.ts | 2 +-
.../nodes/github_push_pr_reviews.ts | 11 +-
.../nodes/invoke_diff_review_llm.ts | 20 +--
.../features/agents/review-agent}/types.ts | 0
yarn.lock | 134 +----------------
19 files changed, 135 insertions(+), 506 deletions(-)
delete mode 100644 packages/agents/review-agent/.gitignore
delete mode 100644 packages/agents/review-agent/package.json
delete mode 100644 packages/agents/review-agent/src/app.ts
delete mode 100644 packages/agents/review-agent/src/env.ts
delete mode 100644 packages/agents/review-agent/tsconfig.json
create mode 100644 packages/web/src/app/api/(server)/webhook/route.ts
create mode 100644 packages/web/src/features/agents/review-agent/app.ts
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/fetch_file_content.ts (85%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/generate_diff_review_prompt.ts (96%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/generate_pr_reviews.ts (81%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/github_pr_parser.ts (97%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/github_push_pr_reviews.ts (76%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/nodes/invoke_diff_review_llm.ts (68%)
rename packages/{agents/review-agent/src => web/src/features/agents/review-agent}/types.ts (100%)
diff --git a/package.json b/package.json
index e98f6628..9b193c70 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dev:zoekt": "yarn with-env zoekt-webserver -index .sourcebot/index -rpc",
"dev:backend": "yarn with-env yarn workspace @sourcebot/backend dev:watch",
"dev:web": "yarn with-env yarn workspace @sourcebot/web dev",
+ "dev:review-agent": "yarn with-env yarn workspace @sourcebot/review-agent dev",
"dev:prisma:migrate:dev": "yarn with-env yarn workspace @sourcebot/db prisma:migrate:dev",
"dev:prisma:studio": "yarn with-env yarn workspace @sourcebot/db prisma:studio",
"dev:prisma:migrate:reset": "yarn with-env yarn workspace @sourcebot/db prisma:migrate:reset",
diff --git a/packages/agents/review-agent/.gitignore b/packages/agents/review-agent/.gitignore
deleted file mode 100644
index 1170717c..00000000
--- a/packages/agents/review-agent/.gitignore
+++ /dev/null
@@ -1,136 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-.cache
-
-# vitepress build output
-**/.vitepress/dist
-
-# vitepress cache directory
-**/.vitepress/cache
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
diff --git a/packages/agents/review-agent/package.json b/packages/agents/review-agent/package.json
deleted file mode 100644
index 9fe1fc20..00000000
--- a/packages/agents/review-agent/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "@sourcebot/review-agent",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "type": "module",
- "scripts": {
- "build": "tsc",
- "start": "node dist/app.js"
- },
- "dependencies": {
- "@octokit/webhooks": "^13.8.2",
- "@octokit/webhooks-definitions": "octokit/webhooks",
- "dotenv": "^16.5.0",
- "octokit": "^4.1.3",
- "openai": "^4.97.0",
- "parse-diff": "^0.11.1",
- "zod": "^3.24.4",
- "zod-to-json-schema": "^3.24.5"
- },
- "devDependencies": {
- "@types/node": "^22.15.8",
- "smee-client": "^3.1.1",
- "typescript": "^5.8.3"
- }
-}
diff --git a/packages/agents/review-agent/src/app.ts b/packages/agents/review-agent/src/app.ts
deleted file mode 100644
index 2765e65b..00000000
--- a/packages/agents/review-agent/src/app.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import dotenv from 'dotenv';
-import { App, Octokit } from "octokit";
-import { createNodeMiddleware } from "@octokit/webhooks";
-import fs from "fs";
-import http from "http";
-import { WebhookEventDefinition } from "@octokit/webhooks/types";
-import { generate_pr_reviews } from './nodes/generate_pr_reviews.js';
-import { github_push_pr_reviews } from './nodes/github_push_pr_reviews.js';
-import { github_pr_parser } from './nodes/github_pr_parser.js';
-
-dotenv.config();
-const appId = process.env.APP_ID as string;
-const webhookSecret = process.env.WEBHOOK_SECRET as string;
-const privateKeyPath = process.env.PRIVATE_KEY_PATH as string;
-
-const privateKey = fs.readFileSync(privateKeyPath, "utf8");
-
-const app = new App({
- appId: appId,
- privateKey: privateKey,
- webhooks: {
- secret: webhookSecret
- },
-});
-
-const rules = [
- "Do NOT provide general feedback, summaries, explanations of changes, or praises for making good additions.",
- "Do NOT provide any advice that is not actionable or directly related to the changes.",
- "Focus solely on offering specific, objective insights based on the given context and refrain from making broad comments about potential impacts on the system or question intentions behind the changes.",
- "Keep comments concise and to the point. Every comment must highlight a specific issue and provide a clear and actionable solution to the developer.",
- "If there are no issues found on a line range, do NOT respond with any comments. This includes comments such as \"No issues found\" or \"LGTM\"."
-]
-
-async function handlePullRequestOpened({
- octokit,
- payload,
-}: {
- octokit: Octokit;
- payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">;
-}) {
- console.log(`Received a pull request event for #${payload.pull_request.number}`);
-
- const prPayload = await github_pr_parser(octokit, payload);
- const fileDiffReviews = await generate_pr_reviews(prPayload, rules);
- await github_push_pr_reviews(app, prPayload, fileDiffReviews);
-}
-
-app.webhooks.on("pull_request.opened", handlePullRequestOpened);
-app.webhooks.on("pull_request.synchronize", handlePullRequestOpened);
-
-app.webhooks.onError((error) => {
- console.error(error);
-});
-
-const port = 3050;
-const path = "/api/webhook";
-
-const middleware = createNodeMiddleware(app.webhooks, { path });
-
-http.createServer(middleware).listen(port, () => {
- console.log(`Http server for review agent running on port ${port} ${path}`);
-});
diff --git a/packages/agents/review-agent/src/env.ts b/packages/agents/review-agent/src/env.ts
deleted file mode 100644
index fd320618..00000000
--- a/packages/agents/review-agent/src/env.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { createEnv } from "@t3-oss/env-core";
-import { z } from "zod";
-
-export const env = createEnv({
- server: {
- GITHUB_APP_ID: z.string(),
- GITHUB_APP_WEBHOOK_SECRET: z.string(),
- GITHUB_APP_PRIVATE_KEY_PATH: z.string(),
- },
- runtimeEnv: process.env,
- emptyStringAsUndefined: true,
- skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
-})
\ No newline at end of file
diff --git a/packages/agents/review-agent/tsconfig.json b/packages/agents/review-agent/tsconfig.json
deleted file mode 100644
index e2e61a95..00000000
--- a/packages/agents/review-agent/tsconfig.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "libReplacement": true, /* Enable lib replacement. */
- // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "NodeNext", /* Specify what module code is generated. */
- "moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
- // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
- // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
- // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
- // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
- // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- // "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
- // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
- // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
- },
- "include": ["**/*.ts"],
- "exclude": ["node_modules", "dist"]
-}
diff --git a/packages/web/package.json b/packages/web/package.json
index 769b0e91..8ce9307c 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -118,6 +118,9 @@
"next-auth": "^5.0.0-beta.25",
"next-themes": "^0.3.0",
"nodemailer": "^6.10.0",
+ "octokit": "^4.1.3",
+ "openai": "^4.98.0",
+ "parse-diff": "^0.11.1",
"posthog-js": "^1.161.5",
"pretty-bytes": "^6.1.1",
"psl": "^1.15.0",
@@ -135,7 +138,8 @@
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"usehooks-ts": "^3.1.0",
- "zod": "^3.24.2"
+ "zod": "^3.24.2",
+ "zod-to-json-schema": "^3.24.5"
},
"devDependencies": {
"@types/micromatch": "^4.0.9",
diff --git a/packages/web/src/app/[domain]/browse/[...path]/page.tsx b/packages/web/src/app/[domain]/browse/[...path]/page.tsx
index 89e4e293..afa10999 100644
--- a/packages/web/src/app/[domain]/browse/[...path]/page.tsx
+++ b/packages/web/src/app/[domain]/browse/[...path]/page.tsx
@@ -3,7 +3,8 @@ import { TopBar } from "@/app/[domain]/components/topBar";
import { Separator } from '@/components/ui/separator';
import { getFileSource } from '@/features/search/fileSourceApi';
import { listRepositories } from '@/features/search/listReposApi';
-import { base64Decode, isServiceError } from "@/lib/utils";
+import { isServiceError } from "@/lib/utils";
+import { base64Decode } from "@/lib/utils";
import { CodePreview } from "./codePreview";
import { ErrorCode } from "@/lib/errorCodes";
import { LuFileX2, LuBookX } from "react-icons/lu";
diff --git a/packages/web/src/app/api/(server)/webhook/route.ts b/packages/web/src/app/api/(server)/webhook/route.ts
new file mode 100644
index 00000000..5c24a544
--- /dev/null
+++ b/packages/web/src/app/api/(server)/webhook/route.ts
@@ -0,0 +1,62 @@
+'use server';
+
+import { NextRequest } from "next/server";
+import { App } from "octokit";
+import { WebhookEventDefinition } from "@octokit/webhooks/types";
+import { env } from "@/env.mjs";
+import { processGitHubPullRequest } from "@/features/agents/review-agent/app";
+import fs from "fs";
+
+let githubApp: App | undefined;
+if (env.GITHUB_APP_ID && env.GITHUB_APP_WEBHOOK_SECRET && env.GITHUB_APP_PRIVATE_KEY_PATH) {
+ try {
+ const privateKey = fs.readFileSync(env.GITHUB_APP_PRIVATE_KEY_PATH, "utf8");
+ githubApp = new App({
+ appId: env.GITHUB_APP_ID,
+ privateKey: privateKey,
+ webhooks: {
+ secret: env.GITHUB_APP_WEBHOOK_SECRET,
+ },
+ });
+ } catch (error) {
+ console.error(`Error initializing GitHub app: ${error}`);
+ }
+}
+
+function isPullRequestEvent(eventHeader: string, payload: unknown): payload is WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize"> {
+ return eventHeader === "pull_request" && typeof payload === "object" && payload !== null && "action" in payload && typeof payload.action === "string" && (payload.action === "opened" || payload.action === "synchronize");
+}
+
+export const POST = async (request: NextRequest) => {
+ const body = await request.json();
+ const headers = Object.fromEntries(request.headers.entries());
+
+ console.log('Webhook request headers:', headers);
+ console.log('Webhook request body:', JSON.stringify(body, null, 2));
+
+ const githubEvent = headers['x-github-event'];
+ if (githubEvent) {
+ console.log('GitHub event received:', githubEvent);
+
+ if (!githubApp) {
+ console.warn('Received GitHub webhook event but GitHub app env vars are not set');
+ return Response.json({ status: 'ok' });
+ }
+
+ if (isPullRequestEvent(githubEvent, body)) {
+ console.log('Received pull request event:', body);
+
+ if (!body.installation) {
+ console.error('Received github pull request event but installation is not present');
+ return Response.json({ status: 'ok' });
+ }
+
+ const installationId = body.installation.id;
+ const octokit = await githubApp.getInstallationOctokit(installationId);
+
+ await processGitHubPullRequest(octokit, body);
+ }
+ }
+
+ return Response.json({ status: 'ok' });
+}
\ No newline at end of file
diff --git a/packages/web/src/env.mjs b/packages/web/src/env.mjs
index e75cc5d6..575de62d 100644
--- a/packages/web/src/env.mjs
+++ b/packages/web/src/env.mjs
@@ -52,6 +52,12 @@ export const env = createEnv({
// EE License
SOURCEBOT_EE_LICENSE_KEY: z.string().optional(),
+
+ // GitHub app for review agent
+ GITHUB_APP_ID: z.string().optional(),
+ GITHUB_APP_WEBHOOK_SECRET: z.string().optional(),
+ GITHUB_APP_PRIVATE_KEY_PATH: z.string().optional(),
+ OPENAI_API_KEY: z.string().optional(),
},
// @NOTE: Please make sure of the following:
// - Make sure you destructure all client variables in
diff --git a/packages/web/src/features/agents/review-agent/app.ts b/packages/web/src/features/agents/review-agent/app.ts
new file mode 100644
index 00000000..ae5a60fb
--- /dev/null
+++ b/packages/web/src/features/agents/review-agent/app.ts
@@ -0,0 +1,27 @@
+import { Octokit } from "octokit";
+import { WebhookEventDefinition } from "@octokit/webhooks/types";
+import { generate_pr_reviews } from "@/features/agents/review-agent/nodes/generate_pr_reviews";
+import { github_push_pr_reviews } from "@/features/agents/review-agent/nodes/github_push_pr_reviews";
+import { github_pr_parser } from "@/features/agents/review-agent/nodes/github_pr_parser";
+import { env } from "@/env.mjs";
+
+const rules = [
+ "Do NOT provide general feedback, summaries, explanations of changes, or praises for making good additions.",
+ "Do NOT provide any advice that is not actionable or directly related to the changes.",
+ "Focus solely on offering specific, objective insights based on the given context and refrain from making broad comments about potential impacts on the system or question intentions behind the changes.",
+ "Keep comments concise and to the point. Every comment must highlight a specific issue and provide a clear and actionable solution to the developer.",
+ "If there are no issues found on a line range, do NOT respond with any comments. This includes comments such as \"No issues found\" or \"LGTM\"."
+]
+
+export async function processGitHubPullRequest(octokit: Octokit, payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">) {
+ console.log(`Received a pull request event for #${payload.pull_request.number}`);
+
+ if (!env.OPENAI_API_KEY) {
+ console.error("OPENAI_API_KEY is not set, skipping review agent");
+ return;
+ }
+
+ const prPayload = await github_pr_parser(octokit, payload);
+ const fileDiffReviews = await generate_pr_reviews(prPayload, rules);
+ await github_push_pr_reviews(octokit, prPayload, fileDiffReviews);
+}
\ No newline at end of file
diff --git a/packages/agents/review-agent/src/nodes/fetch_file_content.ts b/packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts
similarity index 85%
rename from packages/agents/review-agent/src/nodes/fetch_file_content.ts
rename to packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts
index 58475849..0d0246d7 100644
--- a/packages/agents/review-agent/src/nodes/fetch_file_content.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts
@@ -1,6 +1,6 @@
-import { sourcebot_context, sourcebot_pr_payload } from "../types.js";
-import { fileSourceResponseSchema } from "@sourcebot/web/src/features/search/schemas.js";
-import { base64Decode } from "@sourcebot/web/src/lib/utils.js";
+import { sourcebot_context, sourcebot_pr_payload } from "@/features/agents/review-agent/types";
+import { fileSourceResponseSchema } from "@/features/search/schemas";
+import { base64Decode } from "@/lib/utils";
export const fetch_file_content = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
console.log("Executing fetch_file_content");
diff --git a/packages/agents/review-agent/src/nodes/generate_diff_review_prompt.ts b/packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts
similarity index 96%
rename from packages/agents/review-agent/src/nodes/generate_diff_review_prompt.ts
rename to packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts
index 16c22706..1955a2eb 100644
--- a/packages/agents/review-agent/src/nodes/generate_diff_review_prompt.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts
@@ -1,4 +1,4 @@
-import { sourcebot_diff, sourcebot_context, sourcebot_diff_review_schema } from "../types.js";
+import { sourcebot_diff, sourcebot_context, sourcebot_diff_review_schema } from "@/features/agents/review-agent/types";
import { zodToJsonSchema } from "zod-to-json-schema";
export const generate_diff_review_prompt = async (diff: sourcebot_diff, context: sourcebot_context[], rules: string[]) => {
diff --git a/packages/agents/review-agent/src/nodes/generate_pr_reviews.ts b/packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts
similarity index 81%
rename from packages/agents/review-agent/src/nodes/generate_pr_reviews.ts
rename to packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts
index 92754d03..643224b6 100644
--- a/packages/agents/review-agent/src/nodes/generate_pr_reviews.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts
@@ -1,7 +1,7 @@
-import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "../types.js";
-import { generate_diff_review_prompt } from "./generate_diff_review_prompt.js";
-import { invoke_diff_review_llm } from "./invoke_diff_review_llm.js";
-import { fetch_file_content } from "./fetch_file_content.js";
+import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "@/features/agents/review-agent/types";
+import { generate_diff_review_prompt } from "@/features/agents/review-agent/nodes/generate_diff_review_prompt";
+import { invoke_diff_review_llm } from "@/features/agents/review-agent/nodes/invoke_diff_review_llm";
+import { fetch_file_content } from "@/features/agents/review-agent/nodes/fetch_file_content";
export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
console.log("Executing generate_pr_reviews");
@@ -29,7 +29,7 @@ export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rule
const prompt = await generate_diff_review_prompt(diff, context, rules);
- const diffReview = await invoke_diff_review_llm(prompt, file_diff.to);
+ const diffReview = await invoke_diff_review_llm(prompt);
reviews.push(diffReview);
} catch (error) {
console.error(`Error fetching file content for ${file_diff.to}: ${error}`);
diff --git a/packages/agents/review-agent/src/nodes/github_pr_parser.ts b/packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts
similarity index 97%
rename from packages/agents/review-agent/src/nodes/github_pr_parser.ts
rename to packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts
index c248bcbc..c441c5fb 100644
--- a/packages/agents/review-agent/src/nodes/github_pr_parser.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts
@@ -1,4 +1,4 @@
-import { sourcebot_pr_payload, sourcebot_file_diff, sourcebot_diff } from "../types.js"
+import { sourcebot_pr_payload, sourcebot_file_diff, sourcebot_diff } from "@/features/agents/review-agent/types";
import { WebhookEventDefinition } from "@octokit/webhooks/types";
import parse from "parse-diff";
import { Octokit } from "octokit";
diff --git a/packages/agents/review-agent/src/nodes/github_push_pr_reviews.ts b/packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts
similarity index 76%
rename from packages/agents/review-agent/src/nodes/github_push_pr_reviews.ts
rename to packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts
index db2994d9..33105471 100644
--- a/packages/agents/review-agent/src/nodes/github_push_pr_reviews.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts
@@ -1,17 +1,14 @@
-import { App } from "octokit";
-import { sourcebot_pr_payload, sourcebot_file_diff_review } from "../types.js";
+import { Octokit } from "octokit";
+import { sourcebot_pr_payload, sourcebot_file_diff_review } from "@/features/agents/review-agent/types";
-export const github_push_pr_reviews = async (app: App, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
+export const github_push_pr_reviews = async (octokit: Octokit, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
console.log("Executing github_push_pr_reviews");
try {
- const installationId = pr_payload.installation_id;
- const installation = await app.getInstallationOctokit(installationId);
-
for (const file_diff_review of file_diff_reviews) {
for (const review of file_diff_review.reviews) {
try {
- await installation.rest.pulls.createReviewComment({
+ await octokit.rest.pulls.createReviewComment({
owner: pr_payload.owner,
repo: pr_payload.repo,
pull_number: pr_payload.number,
diff --git a/packages/agents/review-agent/src/nodes/invoke_diff_review_llm.ts b/packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts
similarity index 68%
rename from packages/agents/review-agent/src/nodes/invoke_diff_review_llm.ts
rename to packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts
index 13790013..a83ece74 100644
--- a/packages/agents/review-agent/src/nodes/invoke_diff_review_llm.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts
@@ -1,14 +1,18 @@
import OpenAI from "openai";
-import dotenv from "dotenv";
-import { sourcebot_diff_review_schema, sourcebot_diff_review } from "../types.js";
+import { sourcebot_diff_review_schema, sourcebot_diff_review } from "@/features/agents/review-agent/types";
+import { env } from "@/env.mjs";
-dotenv.config();
-const openai = new OpenAI({
- apiKey: process.env.OPENAI_API_KEY,
-});
-
-export const invoke_diff_review_llm = async (prompt: string, filename: string): Promise => {
+export const invoke_diff_review_llm = async (prompt: string): Promise => {
console.log("Executing invoke_diff_review_llm");
+
+ if (!env.OPENAI_API_KEY) {
+ console.error("OPENAI_API_KEY is not set, skipping review agent");
+ throw new Error("OPENAI_API_KEY is not set, skipping review agent");
+ }
+
+ const openai = new OpenAI({
+ apiKey: env.OPENAI_API_KEY,
+ });
try {
const completion = await openai.chat.completions.create({
diff --git a/packages/agents/review-agent/src/types.ts b/packages/web/src/features/agents/review-agent/types.ts
similarity index 100%
rename from packages/agents/review-agent/src/types.ts
rename to packages/web/src/features/agents/review-agent/types.ts
diff --git a/yarn.lock b/yarn.lock
index a2b0e936..f1e37a77 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2610,13 +2610,6 @@ __metadata:
languageName: node
linkType: hard
-"@octokit/webhooks-definitions@octokit/webhooks":
- version: 0.0.0-development
- resolution: "@octokit/webhooks-definitions@https://github.com/octokit/webhooks.git#commit=256fdd82b484f173ac57f14e8c444fecc23c9d80"
- checksum: 10c0/ff90b65b388b3f5ce80a0aa47c6ceb98578f8df6364799db5fc17ffadbbe7e533a7f2c548b279ebd4780e00a2cdcc5f07093b0add975d014af2722496413f75f
- languageName: node
- linkType: hard
-
"@octokit/webhooks-methods@npm:^5.1.1":
version: 5.1.1
resolution: "@octokit/webhooks-methods@npm:5.1.1"
@@ -2624,7 +2617,7 @@ __metadata:
languageName: node
linkType: hard
-"@octokit/webhooks@npm:^13.6.1, @octokit/webhooks@npm:^13.8.2":
+"@octokit/webhooks@npm:^13.6.1":
version: 13.8.2
resolution: "@octokit/webhooks@npm:13.8.2"
dependencies:
@@ -5502,24 +5495,6 @@ __metadata:
languageName: unknown
linkType: soft
-"@sourcebot/review-agent@workspace:packages/agents/review-agent":
- version: 0.0.0-use.local
- resolution: "@sourcebot/review-agent@workspace:packages/agents/review-agent"
- dependencies:
- "@octokit/webhooks": "npm:^13.8.2"
- "@octokit/webhooks-definitions": octokit/webhooks
- "@types/node": "npm:^22.15.8"
- dotenv: "npm:^16.5.0"
- octokit: "npm:^4.1.3"
- openai: "npm:^4.97.0"
- parse-diff: "npm:^0.11.1"
- smee-client: "npm:^3.1.1"
- typescript: "npm:^5.8.3"
- zod: "npm:^3.24.4"
- zod-to-json-schema: "npm:^3.24.5"
- languageName: unknown
- linkType: soft
-
"@sourcebot/schemas@workspace:*, @sourcebot/schemas@workspace:packages/schemas":
version: 0.0.0-use.local
resolution: "@sourcebot/schemas@workspace:packages/schemas"
@@ -5657,6 +5632,9 @@ __metadata:
next-themes: "npm:^0.3.0"
nodemailer: "npm:^6.10.0"
npm-run-all: "npm:^4.1.5"
+ octokit: "npm:^4.1.3"
+ openai: "npm:^4.98.0"
+ parse-diff: "npm:^0.11.1"
postcss: "npm:^8"
posthog-js: "npm:^1.161.5"
pretty-bytes: "npm:^6.1.1"
@@ -5682,6 +5660,7 @@ __metadata:
vite-tsconfig-paths: "npm:^5.1.3"
vitest: "npm:^2.1.5"
zod: "npm:^3.24.2"
+ zod-to-json-schema: "npm:^3.24.5"
languageName: unknown
linkType: soft
@@ -6030,15 +6009,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/node@npm:^22.15.8":
- version: 22.15.17
- resolution: "@types/node@npm:22.15.17"
- dependencies:
- undici-types: "npm:~6.21.0"
- checksum: 10c0/fb92aa10b628683c5b965749f955bc2322485ecb0ea6c2f4cae5f2c7537a16834607e67083a9e9281faaae8d7dee9ada8d6a5c0de9a52c17d82912ef00c0fdd4
- languageName: node
- linkType: hard
-
"@types/nodemailer@npm:^6.4.17":
version: 6.4.17
resolution: "@types/nodemailer@npm:6.4.17"
@@ -7764,13 +7734,6 @@ __metadata:
languageName: node
linkType: hard
-"commander@npm:^12.0.0":
- version: 12.1.0
- resolution: "commander@npm:12.1.0"
- checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
- languageName: node
- linkType: hard
-
"commander@npm:^2.19.0":
version: 2.20.3
resolution: "commander@npm:2.20.3"
@@ -8284,13 +8247,6 @@ __metadata:
languageName: node
linkType: hard
-"dotenv@npm:^16.5.0":
- version: 16.5.0
- resolution: "dotenv@npm:16.5.0"
- checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9
- languageName: node
- linkType: hard
-
"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
version: 1.0.1
resolution: "dunder-proto@npm:1.0.1"
@@ -9248,22 +9204,6 @@ __metadata:
languageName: node
linkType: hard
-"eventsource-parser@npm:^3.0.1":
- version: 3.0.1
- resolution: "eventsource-parser@npm:3.0.1"
- checksum: 10c0/146ce5ae8325d07645a49bbc54d7ac3aef42f5138bfbbe83d5cf96293b50eab2219926d6cf41eed0a0f90132578089652ba9286a19297662900133a9da6c2fd0
- languageName: node
- linkType: hard
-
-"eventsource@npm:^3.0.5":
- version: 3.0.6
- resolution: "eventsource@npm:3.0.6"
- dependencies:
- eventsource-parser: "npm:^3.0.1"
- checksum: 10c0/074d865ea1c7e29e3243f85a13306e89fca2d775b982dca03fa6bfa75c56827fa89cf1ab9e730db24bd6b104cbdcae074f2b37ba498874e9dd9710fbff4979bb
- languageName: node
- linkType: hard
-
"expect-type@npm:^1.1.0":
version: 1.2.0
resolution: "expect-type@npm:1.2.0"
@@ -12065,7 +12005,7 @@ __metadata:
languageName: node
linkType: hard
-"openai@npm:^4.97.0":
+"openai@npm:^4.98.0":
version: 4.98.0
resolution: "openai@npm:4.98.0"
dependencies:
@@ -14057,20 +13997,6 @@ __metadata:
languageName: node
linkType: hard
-"smee-client@npm:^3.1.1":
- version: 3.1.1
- resolution: "smee-client@npm:3.1.1"
- dependencies:
- commander: "npm:^12.0.0"
- eventsource: "npm:^3.0.5"
- undici: "npm:^6.19.8"
- validator: "npm:^13.11.0"
- bin:
- smee: bin/smee.js
- checksum: 10c0/24fd526330d0d0b0763de574c4d6595739eb0413882d617dce07ca35f71fd732c96a9ca723d394e1e9e938b4ef004a9d69797cb700ec72a6fc69396c8128d245
- languageName: node
- linkType: hard
-
"smtp-address-parser@npm:1.0.10":
version: 1.0.10
resolution: "smtp-address-parser@npm:1.0.10"
@@ -14974,16 +14900,6 @@ __metadata:
languageName: node
linkType: hard
-"typescript@npm:^5.8.3":
- version: 5.8.3
- resolution: "typescript@npm:5.8.3"
- bin:
- tsc: bin/tsc
- tsserver: bin/tsserver
- checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48
- languageName: node
- linkType: hard
-
"typescript@patch:typescript@npm%3A^5#optional!builtin, typescript@patch:typescript@npm%3A^5.6.2#optional!builtin, typescript@patch:typescript@npm%3A^5.7.3#optional!builtin":
version: 5.8.2
resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=5786d5"
@@ -14994,16 +14910,6 @@ __metadata:
languageName: node
linkType: hard
-"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin":
- version: 5.8.3
- resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"
- bin:
- tsc: bin/tsc
- tsserver: bin/tsserver
- checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb
- languageName: node
- linkType: hard
-
"ua-parser-js@npm:^1.0.33":
version: 1.0.40
resolution: "ua-parser-js@npm:1.0.40"
@@ -15053,20 +14959,6 @@ __metadata:
languageName: node
linkType: hard
-"undici-types@npm:~6.21.0":
- version: 6.21.0
- resolution: "undici-types@npm:6.21.0"
- checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04
- languageName: node
- linkType: hard
-
-"undici@npm:^6.19.8":
- version: 6.21.2
- resolution: "undici@npm:6.21.2"
- checksum: 10c0/799bbc02b77dda9b6b12d56d2620a3a4d4cf087908d6a548acc3ce32f21b5c27467f75c2c4b30fab281daf341210be3d685e8fe99854288de541715ae5735027
- languageName: node
- linkType: hard
-
"unique-filename@npm:^4.0.0":
version: 4.0.0
resolution: "unique-filename@npm:4.0.0"
@@ -15271,13 +15163,6 @@ __metadata:
languageName: node
linkType: hard
-"validator@npm:^13.11.0":
- version: 13.15.0
- resolution: "validator@npm:13.15.0"
- checksum: 10c0/0f13fd7031ac575e8d7828431da8ef5859bac6a38ee65e1d7fdd367dbf1c3d94d95182aecc3183f7fa7a30ff4474bf864d1aff54707620227a2cdbfd36d894c2
- languageName: node
- linkType: hard
-
"vary@npm:^1, vary@npm:~1.1.2":
version: 1.1.2
resolution: "vary@npm:1.1.2"
@@ -15822,13 +15707,6 @@ __metadata:
languageName: node
linkType: hard
-"zod@npm:^3.24.4":
- version: 3.24.4
- resolution: "zod@npm:3.24.4"
- checksum: 10c0/ab3112f017562180a41a0f83d870b333677f7d6b77f106696c56894567051b91154714a088149d8387a4f50806a2520efcb666f108cd384a35c236a191186d91
- languageName: node
- linkType: hard
-
"zwitch@npm:^2.0.4":
version: 2.0.4
resolution: "zwitch@npm:2.0.4"
From 79dd28837198bf2b85ddf4508ba80e5124734e9c Mon Sep 17 00:00:00 2001
From: msukkari
Date: Fri, 9 May 2025 11:40:48 -0700
Subject: [PATCH 05/15] feedback
---
packages/web/src/app/api/(server)/webhook/route.ts | 5 -----
.../web/src/features/agents/review-agent/app.ts | 14 ++++++++------
.../{fetch_file_content.ts => fetchFileContent.ts} | 2 +-
...eview_prompt.ts => generateDiffReviewPrompt.ts} | 2 +-
...{generate_pr_reviews.ts => generatePrReview.ts} | 14 +++++++-------
.../{github_pr_parser.ts => githubPrParser.ts} | 10 +++++-----
...b_push_pr_reviews.ts => githubPushPrReviews.ts} | 2 +-
...e_diff_review_llm.ts => invokeDiffReviewLlm.ts} | 4 +++-
8 files changed, 26 insertions(+), 27 deletions(-)
rename packages/web/src/features/agents/review-agent/nodes/{fetch_file_content.ts => fetchFileContent.ts} (91%)
rename packages/web/src/features/agents/review-agent/nodes/{generate_diff_review_prompt.ts => generateDiffReviewPrompt.ts} (93%)
rename packages/web/src/features/agents/review-agent/nodes/{generate_pr_reviews.ts => generatePrReview.ts} (67%)
rename packages/web/src/features/agents/review-agent/nodes/{github_pr_parser.ts => githubPrParser.ts} (90%)
rename packages/web/src/features/agents/review-agent/nodes/{github_push_pr_reviews.ts => githubPushPrReviews.ts} (90%)
rename packages/web/src/features/agents/review-agent/nodes/{invoke_diff_review_llm.ts => invokeDiffReviewLlm.ts} (90%)
diff --git a/packages/web/src/app/api/(server)/webhook/route.ts b/packages/web/src/app/api/(server)/webhook/route.ts
index 5c24a544..6ecc7b60 100644
--- a/packages/web/src/app/api/(server)/webhook/route.ts
+++ b/packages/web/src/app/api/(server)/webhook/route.ts
@@ -31,9 +31,6 @@ export const POST = async (request: NextRequest) => {
const body = await request.json();
const headers = Object.fromEntries(request.headers.entries());
- console.log('Webhook request headers:', headers);
- console.log('Webhook request body:', JSON.stringify(body, null, 2));
-
const githubEvent = headers['x-github-event'];
if (githubEvent) {
console.log('GitHub event received:', githubEvent);
@@ -44,8 +41,6 @@ export const POST = async (request: NextRequest) => {
}
if (isPullRequestEvent(githubEvent, body)) {
- console.log('Received pull request event:', body);
-
if (!body.installation) {
console.error('Received github pull request event but installation is not present');
return Response.json({ status: 'ok' });
diff --git a/packages/web/src/features/agents/review-agent/app.ts b/packages/web/src/features/agents/review-agent/app.ts
index ae5a60fb..bd207352 100644
--- a/packages/web/src/features/agents/review-agent/app.ts
+++ b/packages/web/src/features/agents/review-agent/app.ts
@@ -1,13 +1,15 @@
import { Octokit } from "octokit";
import { WebhookEventDefinition } from "@octokit/webhooks/types";
-import { generate_pr_reviews } from "@/features/agents/review-agent/nodes/generate_pr_reviews";
-import { github_push_pr_reviews } from "@/features/agents/review-agent/nodes/github_push_pr_reviews";
-import { github_pr_parser } from "@/features/agents/review-agent/nodes/github_pr_parser";
+import { generatePrReviews } from "@/features/agents/review-agent/nodes/generatePrReview";
+import { githubPushPrReviews } from "@/features/agents/review-agent/nodes/githubPushPrReviews";
+import { githubPrParser } from "@/features/agents/review-agent/nodes/githubPrParser";
import { env } from "@/env.mjs";
const rules = [
"Do NOT provide general feedback, summaries, explanations of changes, or praises for making good additions.",
"Do NOT provide any advice that is not actionable or directly related to the changes.",
+ "Do NOT provide any comments or reviews on code that you believe is good, correct, or a good addition. Your job is only to identify issues and provide feedback on how to fix them.",
+ "If a review for a chunk contains different reviews at different line ranges, return a seperate review object for each line range.",
"Focus solely on offering specific, objective insights based on the given context and refrain from making broad comments about potential impacts on the system or question intentions behind the changes.",
"Keep comments concise and to the point. Every comment must highlight a specific issue and provide a clear and actionable solution to the developer.",
"If there are no issues found on a line range, do NOT respond with any comments. This includes comments such as \"No issues found\" or \"LGTM\"."
@@ -21,7 +23,7 @@ export async function processGitHubPullRequest(octokit: Octokit, payload: Webhoo
return;
}
- const prPayload = await github_pr_parser(octokit, payload);
- const fileDiffReviews = await generate_pr_reviews(prPayload, rules);
- await github_push_pr_reviews(octokit, prPayload, fileDiffReviews);
+ const prPayload = await githubPrParser(octokit, payload);
+ const fileDiffReviews = await generatePrReviews(prPayload, rules);
+ await githubPushPrReviews(octokit, prPayload, fileDiffReviews);
}
\ No newline at end of file
diff --git a/packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts b/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
similarity index 91%
rename from packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts
rename to packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
index 0d0246d7..4a3c3e92 100644
--- a/packages/web/src/features/agents/review-agent/nodes/fetch_file_content.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
@@ -2,7 +2,7 @@ import { sourcebot_context, sourcebot_pr_payload } from "@/features/agents/revie
import { fileSourceResponseSchema } from "@/features/search/schemas";
import { base64Decode } from "@/lib/utils";
-export const fetch_file_content = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
+export const fetchFileContent = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
console.log("Executing fetch_file_content");
const repoPath = pr_payload.hostDomain + "/" + pr_payload.owner + "/" + pr_payload.repo;
diff --git a/packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts b/packages/web/src/features/agents/review-agent/nodes/generateDiffReviewPrompt.ts
similarity index 93%
rename from packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts
rename to packages/web/src/features/agents/review-agent/nodes/generateDiffReviewPrompt.ts
index 1955a2eb..88ac66d2 100644
--- a/packages/web/src/features/agents/review-agent/nodes/generate_diff_review_prompt.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/generateDiffReviewPrompt.ts
@@ -1,7 +1,7 @@
import { sourcebot_diff, sourcebot_context, sourcebot_diff_review_schema } from "@/features/agents/review-agent/types";
import { zodToJsonSchema } from "zod-to-json-schema";
-export const generate_diff_review_prompt = async (diff: sourcebot_diff, context: sourcebot_context[], rules: string[]) => {
+export const generateDiffReviewPrompt = async (diff: sourcebot_diff, context: sourcebot_context[], rules: string[]) => {
console.log("Executing generate_diff_review_prompt");
const prompt = `
diff --git a/packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts b/packages/web/src/features/agents/review-agent/nodes/generatePrReview.ts
similarity index 67%
rename from packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts
rename to packages/web/src/features/agents/review-agent/nodes/generatePrReview.ts
index 643224b6..ebf940a7 100644
--- a/packages/web/src/features/agents/review-agent/nodes/generate_pr_reviews.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/generatePrReview.ts
@@ -1,9 +1,9 @@
import { sourcebot_pr_payload, sourcebot_diff_review, sourcebot_file_diff_review, sourcebot_context } from "@/features/agents/review-agent/types";
-import { generate_diff_review_prompt } from "@/features/agents/review-agent/nodes/generate_diff_review_prompt";
-import { invoke_diff_review_llm } from "@/features/agents/review-agent/nodes/invoke_diff_review_llm";
-import { fetch_file_content } from "@/features/agents/review-agent/nodes/fetch_file_content";
+import { generateDiffReviewPrompt } from "@/features/agents/review-agent/nodes/generateDiffReviewPrompt";
+import { invokeDiffReviewLlm } from "@/features/agents/review-agent/nodes/invokeDiffReviewLlm";
+import { fetchFileContent } from "@/features/agents/review-agent/nodes/fetchFileContent";
-export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
+export const generatePrReviews = async (pr_payload: sourcebot_pr_payload, rules: string[]): Promise => {
console.log("Executing generate_pr_reviews");
const file_diff_reviews: sourcebot_file_diff_review[] = [];
@@ -12,7 +12,7 @@ export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rule
for (const diff of file_diff.diffs) {
try {
- const fileContentContext = await fetch_file_content(pr_payload, file_diff.to);
+ const fileContentContext = await fetchFileContent(pr_payload, file_diff.to);
const context: sourcebot_context[] = [
{
type: "pr_title",
@@ -27,9 +27,9 @@ export const generate_pr_reviews = async (pr_payload: sourcebot_pr_payload, rule
fileContentContext,
];
- const prompt = await generate_diff_review_prompt(diff, context, rules);
+ const prompt = await generateDiffReviewPrompt(diff, context, rules);
- const diffReview = await invoke_diff_review_llm(prompt);
+ const diffReview = await invokeDiffReviewLlm(prompt);
reviews.push(diffReview);
} catch (error) {
console.error(`Error fetching file content for ${file_diff.to}: ${error}`);
diff --git a/packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
similarity index 90%
rename from packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts
rename to packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
index c441c5fb..deb8381a 100644
--- a/packages/web/src/features/agents/review-agent/nodes/github_pr_parser.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
@@ -3,7 +3,7 @@ import { WebhookEventDefinition } from "@octokit/webhooks/types";
import parse from "parse-diff";
import { Octokit } from "octokit";
-export const github_pr_parser = async (octokit: Octokit, payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">): Promise => {
+export const githubPrParser = async (octokit: Octokit, payload: WebhookEventDefinition<"pull-request-opened"> | WebhookEventDefinition<"pull-request-synchronize">): Promise => {
console.log("Executing github_pr_parser");
if (!payload.installation) {
@@ -25,12 +25,12 @@ export const github_pr_parser = async (octokit: Octokit, payload: WebhookEventDe
for (const change of chunk.changes) {
if (change.type === "normal") {
- oldSnippet += change.ln1 + ":" + change.content;
- newSnippet += change.ln2 + ":" + change.content;
+ oldSnippet += change.ln1 + ":" + change.content + "\n";
+ newSnippet += change.ln2 + ":" + change.content + "\n";
} else if (change.type === "add") {
- newSnippet += change.ln + ":" + change.content;
+ newSnippet += change.ln + ":" + change.content + "\n";
} else if (change.type === "del") {
- oldSnippet += change.ln + ":" + change.content;
+ oldSnippet += change.ln + ":" + change.content + "\n";
}
}
diff --git a/packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts b/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.ts
similarity index 90%
rename from packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts
rename to packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.ts
index 33105471..70ecd043 100644
--- a/packages/web/src/features/agents/review-agent/nodes/github_push_pr_reviews.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/githubPushPrReviews.ts
@@ -1,7 +1,7 @@
import { Octokit } from "octokit";
import { sourcebot_pr_payload, sourcebot_file_diff_review } from "@/features/agents/review-agent/types";
-export const github_push_pr_reviews = async (octokit: Octokit, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
+export const githubPushPrReviews = async (octokit: Octokit, pr_payload: sourcebot_pr_payload, file_diff_reviews: sourcebot_file_diff_review[]) => {
console.log("Executing github_push_pr_reviews");
try {
diff --git a/packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts b/packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts
similarity index 90%
rename from packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts
rename to packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts
index a83ece74..fe9abdd0 100644
--- a/packages/web/src/features/agents/review-agent/nodes/invoke_diff_review_llm.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/invokeDiffReviewLlm.ts
@@ -2,7 +2,7 @@ import OpenAI from "openai";
import { sourcebot_diff_review_schema, sourcebot_diff_review } from "@/features/agents/review-agent/types";
import { env } from "@/env.mjs";
-export const invoke_diff_review_llm = async (prompt: string): Promise => {
+export const invokeDiffReviewLlm = async (prompt: string): Promise => {
console.log("Executing invoke_diff_review_llm");
if (!env.OPENAI_API_KEY) {
@@ -14,6 +14,8 @@ export const invoke_diff_review_llm = async (prompt: string): Promise
Date: Fri, 9 May 2025 12:15:24 -0700
Subject: [PATCH 06/15] feedback
---
.../web/src/app/api/(server)/source/route.ts | 2 +-
.../review-agent/nodes/fetchFileContent.ts | 19 ++++++-------------
.../review-agent/nodes/githubPrParser.ts | 14 ++++++++++----
3 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/packages/web/src/app/api/(server)/source/route.ts b/packages/web/src/app/api/(server)/source/route.ts
index 78522f11..dc361a02 100644
--- a/packages/web/src/app/api/(server)/source/route.ts
+++ b/packages/web/src/app/api/(server)/source/route.ts
@@ -27,7 +27,7 @@ export const POST = async (request: NextRequest) => {
}
-const postSource = (request: FileSourceRequest, domain: string) => sew(() =>
+export const postSource = (request: FileSourceRequest, domain: string) => sew(() =>
withAuth(async (session) =>
withOrgMembership(session, domain, async ({ orgId }) => {
const response = await getFileSource(request, orgId);
diff --git a/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts b/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
index 4a3c3e92..edd03274 100644
--- a/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/fetchFileContent.ts
@@ -1,6 +1,8 @@
import { sourcebot_context, sourcebot_pr_payload } from "@/features/agents/review-agent/types";
import { fileSourceResponseSchema } from "@/features/search/schemas";
import { base64Decode } from "@/lib/utils";
+import { postSource } from "@/app/api/(server)/source/route";
+import { isServiceError } from "@/lib/utils";
export const fetchFileContent = async (pr_payload: sourcebot_pr_payload, filename: string): Promise => {
console.log("Executing fetch_file_content");
@@ -12,21 +14,12 @@ export const fetchFileContent = async (pr_payload: sourcebot_pr_payload, filenam
}
console.log(JSON.stringify(fileSourceRequest, null, 2));
- const response = await fetch('http://localhost:3000/api/source', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'X-Org-Domain': '~'
- },
- body: JSON.stringify(fileSourceRequest)
- });
-
- if (!response.ok) {
- throw new Error(`Failed to fetch file content for ${filename} from ${repoPath}: ${response.statusText}`);
+ const response = await postSource(fileSourceRequest, "~");
+ if (isServiceError(response)) {
+ throw new Error(`Failed to fetch file content for ${filename} from ${repoPath}: ${response.message}`);
}
- const responseData = await response.json();
- const fileSourceResponse = fileSourceResponseSchema.parse(responseData);
+ const fileSourceResponse = fileSourceResponseSchema.parse(response);
const fileContent = base64Decode(fileSourceResponse.source);
const fileContentContext: sourcebot_context = {
diff --git a/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
index deb8381a..8b2454fb 100644
--- a/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
+++ b/packages/web/src/features/agents/review-agent/nodes/githubPrParser.ts
@@ -10,8 +10,14 @@ export const githubPrParser = async (octokit: Octokit, payload: WebhookEventDefi
throw new Error("Installation not found in github payload");
}
- const diff = await octokit.request(payload.pull_request.patch_url);
- const parsedDiff: parse.File[] = parse(diff.data);
+ let parsedDiff: parse.File[] = [];
+ try {
+ const diff = await octokit.request(payload.pull_request.patch_url);
+ parsedDiff = parse(diff.data);
+ } catch (error) {
+ console.error("Error fetching diff: ", error);
+ throw error;
+ }
const sourcebotFileDiffs: (sourcebot_file_diff | null)[] = parsedDiff.map((file) => {
if (!file.from || !file.to) {
@@ -20,8 +26,8 @@ export const githubPrParser = async (octokit: Octokit, payload: WebhookEventDefi
}
const diffs: sourcebot_diff[] = file.chunks.map((chunk) => {
- let oldSnippet = "";
- let newSnippet = "";
+ let oldSnippet = `@@ -${chunk.oldStart},${chunk.oldLines} +${chunk.newStart},${chunk.newLines} @@\n`;
+ let newSnippet = `@@ -${chunk.oldStart},${chunk.oldLines} +${chunk.newStart},${chunk.newLines} @@\n`;
for (const change of chunk.changes) {
if (change.type === "normal") {
From 944aeb58cae79002cba38d7008dd203842881047 Mon Sep 17 00:00:00 2001
From: msukkari
Date: Fri, 9 May 2025 14:11:25 -0700
Subject: [PATCH 07/15] add rate limit throttling to octokit
---
.../web/src/app/api/(server)/webhook/route.ts | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/packages/web/src/app/api/(server)/webhook/route.ts b/packages/web/src/app/api/(server)/webhook/route.ts
index 6ecc7b60..3d0dff51 100644
--- a/packages/web/src/app/api/(server)/webhook/route.ts
+++ b/packages/web/src/app/api/(server)/webhook/route.ts
@@ -1,22 +1,37 @@
'use server';
import { NextRequest } from "next/server";
-import { App } from "octokit";
-import { WebhookEventDefinition } from "@octokit/webhooks/types";
+import { App, Octokit } from "octokit";
+import { WebhookEventDefinition} from "@octokit/webhooks/types";
+import { EndpointDefaults } from "@octokit/types";
import { env } from "@/env.mjs";
import { processGitHubPullRequest } from "@/features/agents/review-agent/app";
+import { throttling } from "@octokit/plugin-throttling";
import fs from "fs";
let githubApp: App | undefined;
if (env.GITHUB_APP_ID && env.GITHUB_APP_WEBHOOK_SECRET && env.GITHUB_APP_PRIVATE_KEY_PATH) {
try {
const privateKey = fs.readFileSync(env.GITHUB_APP_PRIVATE_KEY_PATH, "utf8");
+
+ const throttledOctokit = Octokit.plugin(throttling);
githubApp = new App({
appId: env.GITHUB_APP_ID,
privateKey: privateKey,
webhooks: {
secret: env.GITHUB_APP_WEBHOOK_SECRET,
},
+ Octokit: throttledOctokit,
+ throttle: {
+ onRateLimit: (retryAfter: number, options: Required, octokit: Octokit, retryCount: number) => {
+ if (retryCount > 3) {
+ console.log(`Rate limit exceeded: ${retryAfter} seconds`);
+ return false;
+ }
+
+ return true;
+ },
+ }
});
} catch (error) {
console.error(`Error initializing GitHub app: ${error}`);
From 2d0977e6908383d745300052d9cb6ba97d4cf633 Mon Sep 17 00:00:00 2001
From: msukkari
Date: Fri, 9 May 2025 14:21:31 -0700
Subject: [PATCH 08/15] configure agent ui in app
---
packages/web/src/app/[domain]/agents/page.tsx | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/packages/web/src/app/[domain]/agents/page.tsx b/packages/web/src/app/[domain]/agents/page.tsx
index 1a634a2c..c6969525 100644
--- a/packages/web/src/app/[domain]/agents/page.tsx
+++ b/packages/web/src/app/[domain]/agents/page.tsx
@@ -1,19 +1,17 @@
-import { Header } from "../components/header";
import Link from "next/link";
-import Image from "next/image";
import { NavigationMenu } from "../components/navigationMenu";
-import { FaRobot, FaCogs } from "react-icons/fa";
+import { FaCogs } from "react-icons/fa";
import { MdRocketLaunch } from "react-icons/md";
+import { env } from "@/env.mjs";
const agents = [
{
id: "review-agent",
name: "Review Agent",
description: "An agent that reviews your PRs. Uses the code indexed on Sourcebot to provide codebase wide context.",
- deployUrl: "/agents/review-agent/deploy",
- configureUrl: "/agents/review-agent/configure",
+ requiredEnvVars: ["GITHUB_APP_ID", "GITHUB_APP_WEBHOOK_SECRET", "GITHUB_APP_PRIVATE_KEY_PATH", "OPENAI_API_KEY"],
+ configureUrl: "https://docs.sourcebot.dev/docs/agents/review-agent"
},
- // Add more agents here as needed
];
export default function AgentsPage({ params: { domain } }: { params: { domain: string } }) {
@@ -47,19 +45,21 @@ export default function AgentsPage({ params: { domain } }: { params: { domain: s
{/* Actions */}
-
-
- Deploy
-
-
- Configure
-
+
+ {agent.requiredEnvVars.every(envVar => envVar in env && env[envVar as keyof typeof env] !== undefined) ? (
+
+ Agent is configured and accepting requests on /api/webhook
+
+ ) : (
+
+ Configure
+
+ )}
))}
From 871d41007bd0116cf1be86de58b60c4b51725326 Mon Sep 17 00:00:00 2001
From: msukkari
Date: Fri, 9 May 2025 15:50:13 -0700
Subject: [PATCH 09/15] docs
---
docs/docs.json | 7 +++
docs/docs/agents/overview.mdx | 17 ++++++
docs/docs/agents/review-agent.mdx | 57 ++++++++++++++++++
docs/images/github_app_private_key.png | Bin 0 -> 22265 bytes
docs/images/review_agent_configured.png | Bin 0 -> 71893 bytes
docs/images/review_agent_example.png | Bin 0 -> 216460 bytes
packages/web/src/app/[domain]/agents/page.tsx | 1 -
.../[domain]/components/navigationMenu.tsx | 7 +++
8 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 docs/docs/agents/overview.mdx
create mode 100644 docs/docs/agents/review-agent.mdx
create mode 100644 docs/images/github_app_private_key.png
create mode 100644 docs/images/review_agent_configured.png
create mode 100644 docs/images/review_agent_example.png
diff --git a/docs/docs.json b/docs/docs.json
index add8875e..f5e48551 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -43,6 +43,13 @@
}
]
},
+ {
+ "group": "Agents",
+ "pages": [
+ "docs/agents/overview",
+ "docs/agents/review-agent"
+ ]
+ },
{
"group": "More",
"pages": [
diff --git a/docs/docs/agents/overview.mdx b/docs/docs/agents/overview.mdx
new file mode 100644
index 00000000..86fce12d
--- /dev/null
+++ b/docs/docs/agents/overview.mdx
@@ -0,0 +1,17 @@
+---
+title: "Agents Overview"
+sidebarTitle: "Overview"
+---
+
+
+Have an idea for an agent that we haven't built? Submit a [feature request](https://github.com/sourcebot-dev/sourcebot/discussions/categories/feature-requests) on our GitHub
+
+
+Agents are automations that leverage the code indexed on Sourcebot to perform a specific task. Once you've setup Sourcebot, check out the
+guides below to configure additional agents.
+
+
+
+ An AI agent that reviews your PRs to identify issues
+
+
\ No newline at end of file
diff --git a/docs/docs/agents/review-agent.mdx b/docs/docs/agents/review-agent.mdx
new file mode 100644
index 00000000..058bc4ec
--- /dev/null
+++ b/docs/docs/agents/review-agent.mdx
@@ -0,0 +1,57 @@
+---
+title: AI Code Review Agent
+sidebarTitle: AI Code Review Agent
+---
+
+
+This agent sends data to OpenAI (through an API key you supply) to perform code reviews. This data includes code from the PR being reviewed, as well as additional relevant context from your
+codebase that the agent may fetch to perform the review.
+
+
+This agent provides codebase-aware reviews for your PRs. For each diff, this agent fetches relevant context from Sourcebot and feeds it into an LLM for a detailed review of your changes.
+
+The AI Code Review Agent is open source and packaged in [Sourcebot](https://github.com/sourcebot-dev/sourcebot). To get started using this agent, [deploy Sourcebot](http://localhost:3001/self-hosting/overview)
+and then follow the configuration instructions below.
+
+
+
+# Configure
+
+This agent currently only supports reviewing GitHub PRs. You configure the agent by creating a GitHub app, installing it into your GitHub organization, and then giving your app info to Sourcebot.
+
+Before you get started, make sure you have an OpenAPI account that you can create an OpenAPI key with.
+
+
+
+ Follow the official GitHub guide for [registering a GitHub app](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app)
+
+ - GitHub App name: You can make this whatever you want (ex. Sourcebot Review Agent)
+ - Homepage URL: You can make this whatever you want (ex. https://www.sourcebot.dev/)
+ - Webhook URL (**IMPORTANT**): You must set this to point to your Sourcebot deployment at /api/webhook (ex. https://sourcebot.aperture.com/api/webhook). Your Sourcebot deployment must be able to accept requests from GitHub
+ (either github.com or your self-hosted enterprise server) for this to work. If you're running Sourcebot locally, you can [use smee](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#step-2-get-a-webhook-proxy-url) to [forward webhooks](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#step-6-start-your-server) to you local deployment.
+ - Permissions
+ - Pull requests: Read
+ - Contents: Read
+ - Events:
+ - Pull request
+
+
+ Navigate to your new GitHub app's page and press `Install`. You can find this in your [app settings](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#navigate-to-your-app-settings).
+
+ Select the repositories that you want to install the app into.
+
+
+ Sourcebot requires the following environment variables to begin reviewing PRs through your new GitHub app:
+
+ - `GITHUB_APP_ID`: The client ID of your GitHub app. Can be found in your [app settings](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#navigate-to-your-app-settings)
+ - `GITHUB_APP_WEBHOOK_SECRET`: A random webhook secret that you've set in your [app settings](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#navigate-to-your-app-settings). This can be anything (ex. `python -c "import secrets; print(secrets.token_hex(10))"` to generate a random secret)
+ - `GITHUB_APP_PRIVATE_KEY_PATH`: The path to your app's private key. You can generate a private key file for your app in the [app settings](https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart#navigate-to-your-app-settings)
+ 
+ - `OPENAI_API_KEY`: Your OpenAI API key
+
+
+ Navigate to the agents page by pressing `Agents` in the Sourcebot nav menu. If you've configured your environment variables you'll see the following:
+
+ 
+
+
\ No newline at end of file
diff --git a/docs/images/github_app_private_key.png b/docs/images/github_app_private_key.png
new file mode 100644
index 0000000000000000000000000000000000000000..819fae2310d3c718e84ad533f4a5d6a96aee286c
GIT binary patch
literal 22265
zcmeEtgM
zf^tvER$5w3L0Xzd&DF`u_O&Gn%8QS&x>zqYyB?+*XwYKZm61?Hs1QaGNhsds2sonq
zp!fpq9g(?|T3Kc&PO*_p>6ZeU5K6)_Q{9K{yZR4tS=qMCz85!Oqk<=OoA~GXAvc!;
ziO_yQ$l9DR3Vixp!xlduTcVgj^>009pL!UOIO)Gzrwlo@ityH1V!qzOKdFNR5HwMD)Va3xzN{l0PkpS$k=eaO-FK
zTS8qHmmnN|7MCO(lZ}dxp^H*i7%1gJX!v?)I`R
zKa~adqk6}^!xIJ{*94*h=_|?Thxf6|_)wm3K0KLZd&aGKpQxl<-T}jvv-j~UDG|9;
z;-0N_^LJMPPe0(%g5pqDOMTP4{bWHSFfAn(WbXfmfmnZN8zYD#n%A
ztttD<>KCmasp0p#I^PrgpnHIck#E-7MW^6f7}9y1<#qEczpMtv!<;`)bxOL5!RE#N
zVR_}e4Bhq;93mmM(u{8!o8lR%X+$aE4NcQv
zBo}!vK>99_!m|XS8GX+?5+zka?usDdtQ6x#dGx$x~iBkY9uv}#I`FWz6glL2$Kj;>MT`_WUDPPvJ7
zyw1GSd9|RUHcWEb*_a`u)sa|(>fBATj@SEecwLom#+C{f1#i||aS!VmVPdrL%1cb2G@u+7N#pOpp6&~3zQE6ioRAWHiz
z&q`NBze7jKY{cjuDHb{UlgYx`l~6E|ot89OsY|%4^QUgtz|S<6qz6hN%#6`=S;{%=
znXfZ>G&nVdo}}gJYuV@X^M)tM!sIzJ$211ikm~cfd3lL>Ub(UbA4k{nWAk>jg-cG<
zb~5X#>R>{;qOwLAONK-((U=QZTQR?TO8^N;z9uyHz`m
z!KplV$*o#Gg=s}$HG|wn37>)!mYvRfpG^A~o@0DE|K#wA`x8Fpm+)`+s?16`GS=0g
z0#J2vRdJ}}n_Zq+oY~B}9pz89?JLjR5_%FY6ZsRe%ESa35;`Z&9%{yRB_lT*9%ew4hmYJZXU_A;Q
z{DM#JNuv&SHe_b`PiM`h>@FsIr`YET;jbem{oL{er$uIczj;-7Rlon({xUT2A@9Rx
zJq`BBxWqVnjsd-<>hdbZN_`t`r{fv@fh23AS4QT313^~H_T24Xht}#i2ICx(9qPZI
zgizY8+r``JnnEV2zCkKTr=3cj$R!^wK9hR>#q|dVmOECsbdz*go3#8_^BVIE^Ty?#
zsE711^2Lw599Q_6b#o|k96%6x+Xx&=ZGn835qoQ4>p-{nhsT4JgOZu+pBx`ucel^U
zu9Oe1RPk9VslgtniY5S@4tya{gZq=;aOh)8uz
z^-8@Iy*+T<>pq#e+Ozty)K|lg@3QhT>EghT&5!y#@e=#G
z>QZ!h!nItWUV!Twc4c`Jd^PVTT3b=Wj8+=35U><5Cb83U)^gB-C21x3Sdv$A_IvSn
z?l-FM2&G!3bl%M@J>JJ?urr3_`XCD7!={_2Wu~j95v@C|mWyHLgJl`!x?zo^rjKbq
z=0;#dHT=|$I?XK1{3=8Fkx5QoR#!$m>@f*9_nIL)y@$qj{{+P4#-(Rzw`2MT+fp(y
z0-FVU6dOs5PNd6J6+tfOI98*ia7SS&E675_RqEhmC3Qb=dHfUdg^LP{Vy)nJ@779e
zQYJFx-b7C@kslFsC{Rnv&TO-PgzM^sKVvgtch2F^+rGAw@QTD+&3nh>$
zU#f_MYx0P(K7&KrlAvYZXGgt+*Yy-ps*(IF8!gn=58sC^F}Jt*rd@?x5oi*BrAqk9
ztMa_avTpXMeK?H-gXHQtdKzuQpvW+Its#-X+QrHtF{~GqJS)=a+y6$8((UcKPG4q!
zPwJ_ChUQ{-YxN=VIzQ)A{il%c%V}?*`7A?EqDf};5#OAL>3pL+)wh-gL&rI8blBOO
zUM^{A=pR^qeAU&SCVy>s;)WbL$}Z}eiE}Un8FK3RyS+z-;p&JP^Ll8{+Kp{4
zjXI4h>$_!)WP^wGH}%`6PRjSngWMl(#g$xYr0V%+wl