2025-03-07 10:47:08 -08:00
|
|
|
import fs from "fs/promises";
|
|
|
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
|
|
import { AIMessage } from "@langchain/langgraph-sdk";
|
2025-03-06 20:04:55 -08:00
|
|
|
import { OpenCodeState, OpenCodeUpdate } from "../types";
|
2025-03-07 10:47:08 -08:00
|
|
|
import { LangGraphRunnableConfig } from "@langchain/langgraph";
|
|
|
|
|
import ComponentMap from "../../uis";
|
|
|
|
|
import { typedUi } from "@langchain/langgraph-sdk/react-ui/server";
|
2025-03-06 20:04:55 -08:00
|
|
|
|
2025-03-07 10:47:08 -08:00
|
|
|
export async function executor(
|
|
|
|
|
state: OpenCodeState,
|
|
|
|
|
config: LangGraphRunnableConfig,
|
|
|
|
|
): Promise<OpenCodeUpdate> {
|
|
|
|
|
const ui = typedUi<typeof ComponentMap>(config);
|
|
|
|
|
|
2025-03-07 11:21:49 -08:00
|
|
|
const lastPlanToolCall = state.messages.findLast(
|
2025-03-07 10:47:08 -08:00
|
|
|
(m) =>
|
|
|
|
|
m.getType() === "ai" &&
|
2025-03-07 11:21:49 -08:00
|
|
|
(m as unknown as AIMessage).tool_calls?.some((tc) => tc.name === "plan"),
|
|
|
|
|
) as AIMessage | undefined;
|
2025-03-07 12:43:22 -08:00
|
|
|
const planToolCallArgs = lastPlanToolCall?.tool_calls?.[0]?.args as Record<
|
|
|
|
|
string,
|
|
|
|
|
any
|
|
|
|
|
>;
|
|
|
|
|
const nextPlanItem = planToolCallArgs?.remainingPlans?.[0] as
|
|
|
|
|
| string
|
|
|
|
|
| undefined;
|
|
|
|
|
const numOfExecutedPlanItems = planToolCallArgs?.executedPlans?.length ?? 0;
|
2025-03-07 11:21:49 -08:00
|
|
|
|
2025-03-07 12:43:22 -08:00
|
|
|
if (!nextPlanItem) {
|
|
|
|
|
// All plans have been executed
|
|
|
|
|
const successfullyFinishedMsg: AIMessage = {
|
|
|
|
|
type: "ai",
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
content:
|
|
|
|
|
"Successfully completed all the steps in the plan. Please let me know if you need anything else!",
|
|
|
|
|
};
|
|
|
|
|
return { messages: [successfullyFinishedMsg] };
|
|
|
|
|
}
|
2025-03-07 10:47:08 -08:00
|
|
|
|
|
|
|
|
let updateFileContents = "";
|
2025-03-07 11:21:49 -08:00
|
|
|
switch (numOfExecutedPlanItems) {
|
2025-03-07 10:47:08 -08:00
|
|
|
case 0:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-1.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-2.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-3.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-4.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-5.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
updateFileContents = await fs.readFile(
|
|
|
|
|
"agent/open-code/nodes/plan-code/step-6.txt",
|
|
|
|
|
"utf-8",
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
updateFileContents = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!updateFileContents) {
|
|
|
|
|
throw new Error("No file updates found!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const toolCallId = uuidv4();
|
|
|
|
|
const aiMessage: AIMessage = {
|
|
|
|
|
type: "ai",
|
|
|
|
|
id: uuidv4(),
|
|
|
|
|
content: "",
|
|
|
|
|
tool_calls: [
|
|
|
|
|
{
|
|
|
|
|
name: "update_file",
|
|
|
|
|
args: {
|
2025-03-07 12:43:22 -08:00
|
|
|
new_file_content: updateFileContents as any,
|
|
|
|
|
executed_plan_item: nextPlanItem as any,
|
2025-03-07 10:47:08 -08:00
|
|
|
},
|
|
|
|
|
id: toolCallId,
|
|
|
|
|
type: "tool_call",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ui.write("proposed-change", {
|
|
|
|
|
toolCallId,
|
|
|
|
|
change: updateFileContents,
|
2025-03-07 12:43:22 -08:00
|
|
|
planItem: nextPlanItem,
|
2025-03-07 10:47:08 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
messages: [aiMessage],
|
|
|
|
|
ui: ui.collect as OpenCodeUpdate["ui"],
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
};
|
|
|
|
|
}
|