Skip to content

Commit

Permalink
"verification" is set up along with commit and PR
Browse files Browse the repository at this point in the history
  • Loading branch information
Gordon-BP committed Aug 10, 2023
1 parent e04485c commit c6db86b
Show file tree
Hide file tree
Showing 12 changed files with 648 additions and 131 deletions.
297 changes: 297 additions & 0 deletions combined.log

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions error.log
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,30 @@
{"level":"error","message":"Error while scanning directory tree","service":"file-service"}
{"level":"\u001b[31merror\u001b[39m","message":"Code Gen Error TypeError: Converting circular structure to JSON\n --> starting at object with constructor 'ClientRequest'\n | property 'socket' -> object with constructor 'Socket'\n --- property '_httpMessage' closes the circle","service":"cg-router","timestamp":"2023-08-08T18:03:20.533Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Code Gen Error TypeError: Converting circular structure to JSON\n --> starting at object with constructor 'ClientRequest'\n | property 'socket' -> object with constructor 'Socket'\n --- property '_httpMessage' closes the circle","service":"cg-router","timestamp":"2023-08-08T18:12:20.967Z"}
{"level":"error","message":"Error while reading file:Error: ENOENT: no such file or directory, open 'repos/Gordon-BP/taylor-test-repo/Taylor_Issue_69/index.html'","service":"file-service"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:25:56.573Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:26:21.737Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:27:04.661Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:28:43.964Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:30:28.203Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:31:03.626Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:31:48.719Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:34:47.912Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:35:12.027Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:35:51.349Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T08:44:56.958Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T09:01:12.243Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T09:01:27.957Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Linting issues found:[object Object]","service":"vr-router","timestamp":"2023-08-10T09:12:08.099Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: SyntaxError: Unexpected token 'this'","service":"vr-router","timestamp":"2023-08-10T09:32:23.163Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: ReferenceError: __context__ is not defined","service":"vr-router","timestamp":"2023-08-10T09:33:04.945Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: ReferenceError: __context__ is not defined","service":"vr-router","timestamp":"2023-08-10T09:33:17.158Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: ReferenceError: __context__ is not defined","service":"vr-router","timestamp":"2023-08-10T09:34:06.653Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: ReferenceError: __context__ is not defined","service":"vr-router","timestamp":"2023-08-10T09:34:35.016Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: SyntaxError: Unexpected token 'this'","service":"vr-router","timestamp":"2023-08-10T09:35:16.657Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: SyntaxError: await is only valid in async functions and the top level bodies of modules","service":"vr-router","timestamp":"2023-08-10T09:39:13.941Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error executing code: TypeError: eval(...).call is not a function","service":"vr-router","timestamp":"2023-08-10T09:41:23.530Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error making PR: AxiosError: Request failed with status code 400}","service":"vr-router","timestamp":"2023-08-10T13:45:14.914Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error making PR: AxiosError: Request failed with status code 400}","service":"vr-router","timestamp":"2023-08-10T13:46:29.823Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error making PR: AxiosError: Request failed with status code 400}","service":"vr-router","timestamp":"2023-08-10T13:49:04.757Z"}
{"level":"\u001b[31merror\u001b[39m","message":"Error making PR: TypeError: Converting circular structure to JSON\n --> starting at object with constructor 'ClientRequest'\n | property 'socket' -> object with constructor 'Socket'\n --- property '_httpMessage' closes the circle}","service":"vr-router","timestamp":"2023-08-10T13:51:41.901Z"}
35 changes: 31 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
},
"dependencies": {
"@types/axios": "^0.14.0",
"@types/eslint": "^8.44.2",
"axios": "^1.4.0",
"body-parser": "^1.20.2",
"dree": "^4.5.5",
Expand Down
15 changes: 6 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ App ID 364693
- [ ] Get the last 10 or so logs (omit unnecessary info like taskID, service)
- [ ] Return pass/fail

**DevOps Things**
- [ ] Dockerize app
- [ ] Better webhook hosting than ngrok
- [ ] Clean up your server-side logging

## Done ✅ Tasks
**Github Utilities:** --Almost there!
- [x] Clone repo
Expand All @@ -42,8 +47,7 @@ App ID 364693

**Other Utilities**
- [x] Stream task-specific logs to a task-specific file
- [ ] Better webhook hosting than ngrok
- [ ] Clean up your server-side logging
- [x] Implement API Client service

**Task Generation**
- [~] Fetch info
Expand Down Expand Up @@ -71,13 +75,6 @@ App ID 364693

> Do we _have_ to require the LLM to write Javascript? Like, the code it writes will only be consuming APIs. It'll write additional code in strings, but there's no set reason why it has to use JS/TS to call those APIs, right?

- [X] **Client Service**
> Very much need a proper client service to consume these APIs with. I can more clearly understand the nodes & flows, and having all the steps as API services is really helpful. However, one client is needed per issue for the following reasons:
1. Client-side logs will be automatically scoped to the issue/task ID
2. Client can listen for webhooks, too, when tasks are pending PR review, comment clarification, or GH automatic checks
3. Server-Client structure is better suited for having 100+ clients running at once.

## Other Notes 'N Stuff
* Web research retriever
- will need to implement on your own with https://serpapi.com/integrations/node and LLM chain
Expand Down
2 changes: 2 additions & 0 deletions src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { tg_router } from "./routes/task_route.js";
import bodyParser from "body-parser";
import { fs_router } from "./routes/file_routes.js";
import { cg_router } from "./routes/code_gen_route.js";
import { vr_router } from "./routes/verification_route.js";
import GithubUtils from "./utils/github_utils.js";
import { v4 as uuid } from "uuid";
import winston from "winston";
Expand Down Expand Up @@ -101,6 +102,7 @@ class App {
this.express.use("/app/v1/files", fs_router);
this.express.use("/app/v1/task", tg_router);
this.express.use("/app/v1/code", cg_router);
this.express.use("/app/v1/verify", vr_router)
this.express.use("/docs", express.static("./docs"));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/prompts/verification_output_parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AgentActionOutputParser } from "langchain/agents";
import { AgentAction, AgentFinish } from "langchain/schema";

export default class CodeOutputParser extends AgentActionOutputParser {
export default class VerifyOutputParser extends AgentActionOutputParser {
lc_namespace = ["langchain", "agents", "custom_llm_agent_chat"];

async parse(text: string): Promise<AgentAction | AgentFinish> {
Expand Down
2 changes: 1 addition & 1 deletion src/prompts/verification_prompt_template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function load_prompts(): Promise<PromptArray> {
return { prefix: PREFIX, instructions: formatInstructions, suffix: SUFFIX };
}

export default class CodePromptTemplate extends BaseChatPromptTemplate {
export default class VerifyPromptTemplate extends BaseChatPromptTemplate {
tools: DynamicStructuredTool[];

constructor(args: {
Expand Down
84 changes: 6 additions & 78 deletions src/routes/code_gen_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ import winston from "winston";
import axios, { AxiosRequestConfig } from "axios";
import { AgentExecutor, LLMSingleActionAgent } from "langchain/agents";
import { LLMChain } from "langchain";
import {readFiles, writeFiles, submit} from "../utils/fileTools.js"
//TODO: Change to be configurable from env
export const cg_router = express.Router();
const endpoint = "http://127.0.0.1:3000/app/v1";

interface FileData {
path: string;
data: string;
}
cg_router.use(bodyParser.json());
const logger = winston.createLogger({
level: "debug",
Expand Down Expand Up @@ -52,75 +49,6 @@ if (process.env.NODE_ENV !== "production") {
}),
);
}
/**
* Retrieves the contents of multiple files specified by their file paths.
*
* @param paths - An array of file paths.
* @param taskId - The task ID for identification purposes.
* @returns A promise that resolves with a string containing the concatenated contents of all the files.
*/
function getFiles(paths: string[], taskId: string): Promise<string> {
let fileContent = "";
const promises = paths.map((filePath) => {
if (/\.\/repos/.test(filePath)) {
filePath = filePath.split("./repos")[1];
}
return axios.get(`${endpoint}/files/${filePath}`, {
data: {
taskId: taskId,
},
});
});
return new Promise((resolve, reject) => {
Promise.all(promises)
.then((responses) => {
const fileContents = responses.map((response) => response.data);
fileContent = fileContents.join("\n");
resolve(fileContent);
})
.catch((err) => {
logger.error(`Error fetching files: ${err}`);
reject(err);
});
});
}
function writeFiles(fileData: FileData[], taskId: string): string {
let resp = "";
const promises = fileData.map((file) => {
if (/\.\/repos/.test(file.path)) {
file.path = file.path.split("./repos")[1];
}
const owner = file.path.split("/")[0];
const repo = file.path.split("/")[1];
const branchName = file.path.split("/")[2];
const filePath = file.path.split("/").slice(3).join("/");
return axios.post(`${endpoint}/files/${filePath}`, {
params: {
owner: owner,
repo: repo,
branchName: branchName,
},
data: {
filePath: filePath,
data: file.data,
taskId: taskId,
},
});
});
Promise.all(promises)
.then((responses) => {
resp = `Files successfully written:\n${responses}`;
})
.catch((err) => {
logger.error(`Error writing files: ${err}`);
resp = `Error writing files: ${err}`;
});
return resp;
}
function submit(data: string, taskId: string): string {
const resp = writeFiles([{ path: "/tmp/tmp.js", data: data }], taskId);
return resp;
}

/**
* ============================================
Expand Down Expand Up @@ -163,17 +91,17 @@ cg_router.post(
.describe("Your function that successfully resolves the task"),
taskId: z.string().describe("Which task this call is for"),
}),
func: async ({ data, taskId }) => submit(data, taskId),
func: async ({ data, taskId }) => submit(data, task),
returnDirect: false,
}),
new DynamicStructuredTool({
name: "Get Files",
description: "Gets the data from each file in the provided list",
name: "Reads Files",
description: "Returns the data from each file in the provided list",
schema: z.object({
paths: z.array(z.string()),
taskId: z.string(),
}),
func: async ({ paths, taskId }) => getFiles(paths, taskId),
func: async ({ paths, taskId }) => readFiles(paths, taskId),
returnDirect: false,
}),
new DynamicStructuredTool({
Expand All @@ -190,7 +118,7 @@ cg_router.post(
),
taskId: z.string().describe("Which task this call is for"),
}),
func: async ({ files, taskId }) => writeFiles(files, taskId),
func: async ({ files, taskId }) => writeFiles(files, task),
returnDirect: false,
}),
];
Expand Down
Loading

0 comments on commit c6db86b

Please sign in to comment.