fix: Handle apply patch errors better (#27)

This commit is contained in:
Brace Sproul 2025-05-26 17:41:38 -07:00 • committed by GitHub
parent c6ba3ee52e
commit afac1eab8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 7 deletions

View file

@ -41,7 +41,7 @@ Once you're done, ensure you've documented the development process in the readme
},
config: {
configurable,
recursion_limit: 200,
recursion_limit: 400,
},
ifNotExists: "create",
streamSubgraphs: true,
@ -85,7 +85,7 @@ async function resumeGraph(threadId: string) {
},
config: {
configurable,
recursion_limit: 200,
recursion_limit: 400,
},
streamSubgraphs: true,
streamMode: "updates",

View file

@ -19,8 +19,15 @@ async function runFromPlan() {
messages: [
{
role: "user",
content:
"This repo contains the react/next.js code for my persona/portfolio site. It currently has static values set for the number of stars on the repositories I highlight. I want this to be accurate, but I do NOT want it to make requests to GitHub every time a user visits. Instead, please implement a solution which will run once a day, fetch the number of stars from a list of repos, then write them to vercel's KV store. Finally, update the UI to make a request to the KV store when the user visits my page and render the accurate star counts.",
content: `The project is structured as a monorepo, with some apps located inside the /apps directory. In this directory, there is an /auth directory. This directory only contains the scaffolding for a new app in the monorepo, but is not yet implemented. Please take the following plan/task description and implement it in the /auth directory:
This monorepo is for an AI coding agent. The app runs and edits the code in the cloud in a sandboxed environment. Right now, we require users to generate a GitHub PAT, which we store in a .env file and can use to authenticate with GitHub. This is not idea, and instead we want to have a github oauth app which users can authenticate with.
Please implement a new auth server inside the /auth directory which can do this.
You will not have any access to secrets, so you will not be able to run the server to test it.
I want the server to be able to authenticate users with GitHub, such that we will be able to take the following actions:
1. clone repositories they give us access to
2. checkout existing and create new branches on the repositories they give us access to
3. make pull requests and push changes to the repositories they give us access to
Once you're done, ensure you've documented the development process in the readme of this new app.`,
},
{
id: "toolu_01RNEjViZFBXgCSNMwqKvkVL",
@ -116,8 +123,8 @@ async function runFromPlan() {
"thread_id" | "assistant_id"
> = {
target_repository: {
owner: "bracesproul",
repo: "personal-site",
owner: "langchain-ai",
repo: "open-swe",
},
};
@ -144,7 +151,7 @@ async function runFromPlan() {
},
config: {
configurable,
recursion_limit: 200,
recursion_limit: 400,
},
ifNotExists: "create",
streamSubgraphs: true,

View file

@ -44,6 +44,7 @@ You MUST adhere to the following criteria when executing the task:
- Each summary message will also include a short description of the task it completed, how it did so, and every change it made to the codebase during this task. This section will be titled 'Repository modifications summary'.
- All changes are automatically committed, so you should not worry about creating backups, or committing changes.
- Use \`apply_patch\` to edit files. This tool accepts diffs and file paths. It will then apply the given diff to the file.
- You should NOT try to create empty files with \`apply_patch\`. If you need to create a file, use the \`shell\` tool, and pass \`touch <file path>\` to create the file.
- When using the \`shell\` tool, always take advantage of the \`workdir\` parameter to run commands inside the repo directory. You should not try to generate a command with \`cd <some path>\` as passing that path to \`workdir\` is much more efficient.
- Do not try to install dependencies, or run a server, compile the code, etc., unless you are explicitly asked to.
- If completing the user's task requires writing or modifying files:

View file

@ -6,6 +6,33 @@ import { traceable } from "langsmith/traceable";
const logger = createLogger(LogLevel.INFO, "ReadWriteUtil");
async function handleCreateFile(
sandbox: Sandbox,
filePath: string,
args?: {
workDir?: string;
},
) {
try {
const touchCommand = `touch "${filePath}"`;
const touchOutput = await sandbox.commands.run(touchCommand, {
cwd: args?.workDir,
});
return touchOutput;
} catch (e) {
const errorFields = getSandboxErrorFields(e);
if (errorFields) {
return errorFields;
}
return {
exitCode: 1,
error: e instanceof Error ? e.message : String(e),
stdout: "",
stderr: "",
};
}
}
async function readFileFunc(
sandbox: Sandbox,
filePath: string,
@ -42,6 +69,19 @@ async function readFileFunc(
output: readOutput.stdout,
};
} catch (e: any) {
if (e instanceof Error && e.message.includes("No such file or directory")) {
const createOutput = await handleCreateFile(sandbox, filePath, args);
if (createOutput.exitCode !== 0) {
return {
success: false,
output: `FAILED TO EXECUTE READ COMMAND for sandbox '${filePath}'. Error: ${(e as Error).message || String(e)}`,
};
} else {
// If the file was created successfully, try reading it again.
return readFile(sandbox, filePath, args);
}
}
logger.error(
`Exception while trying to read file '${filePath}' from sandbox via cat:`,
{