mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 03:23:13 +00:00
Brace/07 16/fixes (#431)
* fix: General fixes * cr * bump langchain core langsmith deps
This commit is contained in:
parent
d4ca73089c
commit
b128e4ae45
24 changed files with 278 additions and 56 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"DAYTONA",
|
||||
"helicunate"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,14 +1,9 @@
|
|||
import { SNAPSHOT_NAME } from "@open-swe/shared/constants";
|
||||
import { CreateSandboxFromImageParams } from "@daytonaio/sdk";
|
||||
import { DAYTONA_SNAPSHOT_NAME } from "@open-swe/shared/constants";
|
||||
import { CreateSandboxFromSnapshotParams } from "@daytonaio/sdk";
|
||||
|
||||
export const DEFAULT_SANDBOX_CREATE_PARAMS: CreateSandboxFromImageParams = {
|
||||
resources: {
|
||||
cpu: 2,
|
||||
memory: 4,
|
||||
disk: 5,
|
||||
},
|
||||
export const DEFAULT_SANDBOX_CREATE_PARAMS: CreateSandboxFromSnapshotParams = {
|
||||
user: "daytona",
|
||||
image: SNAPSHOT_NAME,
|
||||
snapshot: DAYTONA_SNAPSHOT_NAME,
|
||||
autoDeleteInterval: 15, // delete after 15 minutes
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ import {
|
|||
RemoveMessage,
|
||||
} from "@langchain/core/messages";
|
||||
import { z } from "zod";
|
||||
import { loadModel, Task } from "../../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../../utils/load-model.js";
|
||||
import { Command, END } from "@langchain/langgraph";
|
||||
import { getMessageContentString } from "@open-swe/shared/messages";
|
||||
import {
|
||||
|
|
@ -88,9 +92,17 @@ export async function classifyMessage(
|
|||
schema,
|
||||
};
|
||||
const model = await loadModel(config, Task.ROUTER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.ROUTER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([respondAndRouteTool], {
|
||||
tool_choice: respondAndRouteTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ export const UPDATE_PROGRAMMER_ROUTING_OPTION = `- update_programmer: You should
|
|||
|
||||
export const START_PLANNER_ROUTING_OPTION = `- start_planner: You should call this route if the user's message is a complete request you can send to the planner, which it can use to generate a plan. This route may be called when the planner has not started yet.\n`;
|
||||
|
||||
export const START_PLANNER_FOR_FOLLOWUP_ROUTING_OPTION = `- start_planner: You should call this route if the user's message is a complete followup request you can send to the planner, which it can use to generate a plan new plan to address the user's feedback/followup request. This route may be called when the planner and programmer are no longer running (e.g. after the user's initial request has been completed).\n`;
|
||||
|
||||
export const UPDATE_PLANNER_ROUTING_OPTION = `- update_planner: You should call this route if the user sends a new message containing anything from a related request that the planner should plan for, additional context about their previous request/the codebase, or something which the planner should be aware of.\n`;
|
||||
|
||||
export const RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION = `- resume_and_update_planner: You should call this route if the planner is currently interrupted, and the user's message includes additional context/related requests the which require updates to the plan. This will resume the planner so that it can handle the user's new request.\n`;
|
||||
|
|
@ -53,7 +55,7 @@ The programmer's current status is: {PROGRAMMER_STATUS}
|
|||
Based on all of the context provided above, generate a response to send to the user, including messaging about the route you'll select from the below options in your next step.
|
||||
Your routing options are:
|
||||
- no_op: This should be called when the user's message is not a new request, additional context, or a new issue to create. This should only be called when none of the routing options are appropriate.
|
||||
{UPDATE_PROGRAMMER_ROUTING_OPTION}{START_PLANNER_ROUTING_OPTION}{UPDATE_PLANNER_ROUTING_OPTION}{RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION}{CREATE_NEW_ISSUE_ROUTING_OPTION}
|
||||
{UPDATE_PROGRAMMER_ROUTING_OPTION}{START_PLANNER_ROUTING_OPTION}{UPDATE_PLANNER_ROUTING_OPTION}{RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION}{CREATE_NEW_ISSUE_ROUTING_OPTION}{START_PLANNER_FOR_FOLLOWUP_ROUTING_OPTION}
|
||||
|
||||
# Response
|
||||
Your response should be clear, concise and straight to the point. Do NOT include any additional context, such as an idea for how to implement their request.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import {
|
|||
RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION,
|
||||
START_PLANNER_ROUTING_OPTION,
|
||||
TASK_PLAN_PROMPT,
|
||||
START_PLANNER_FOR_FOLLOWUP_ROUTING_OPTION,
|
||||
} from "./prompts.js";
|
||||
import { createClassificationSchema } from "./schemas.js";
|
||||
|
||||
|
|
@ -107,6 +108,9 @@ export function createClassificationPromptAndToolSchema(inputs: {
|
|||
const plannerRunning = inputs.plannerStatus === "busy";
|
||||
const plannerInterrupted = inputs.plannerStatus === "interrupted";
|
||||
const plannerNotStarted = inputs.plannerStatus === "not_started";
|
||||
// If both are idle, we should allow 'start_planner' to start a new planning run on the same request.
|
||||
const plannerAndProgrammerIdle =
|
||||
inputs.programmerStatus === "idle" && inputs.plannerStatus === "idle";
|
||||
|
||||
const showCreateIssueOption =
|
||||
inputs.programmerStatus !== "not_started" ||
|
||||
|
|
@ -115,7 +119,9 @@ export function createClassificationPromptAndToolSchema(inputs: {
|
|||
const routingOptions: [string, ...string[]] = [
|
||||
"no_op",
|
||||
...(programmerRunning ? ["update_programmer"] : []),
|
||||
...(plannerNotStarted ? ["start_planner"] : []),
|
||||
...((plannerNotStarted ?? plannerAndProgrammerIdle)
|
||||
? ["start_planner"]
|
||||
: []),
|
||||
...(plannerRunning ? ["update_planner"] : []),
|
||||
...(plannerInterrupted ? ["resume_and_update_planner"] : []),
|
||||
...(showCreateIssueOption ? ["create_new_issue"] : []),
|
||||
|
|
@ -138,13 +144,17 @@ export function createClassificationPromptAndToolSchema(inputs: {
|
|||
"{START_PLANNER_ROUTING_OPTION}",
|
||||
plannerNotStarted ? START_PLANNER_ROUTING_OPTION : "",
|
||||
)
|
||||
.replaceAll(
|
||||
"{START_PLANNER_FOR_FOLLOWUP_ROUTING_OPTION}",
|
||||
plannerAndProgrammerIdle ? START_PLANNER_FOR_FOLLOWUP_ROUTING_OPTION : "",
|
||||
)
|
||||
.replaceAll(
|
||||
"{UPDATE_PLANNER_ROUTING_OPTION}",
|
||||
plannerRunning ? UPDATE_PLANNER_ROUTING_OPTION : "",
|
||||
)
|
||||
.replaceAll(
|
||||
"{RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION}",
|
||||
plannerNotStarted ? RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION : "",
|
||||
plannerInterrupted ? RESUME_AND_UPDATE_PLANNER_ROUTING_OPTION : "",
|
||||
)
|
||||
.replaceAll(
|
||||
"{CREATE_NEW_ISSUE_ROUTING_OPTION}",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import { BaseMessage } from "@langchain/core/messages";
|
||||
import { GraphConfig } from "@open-swe/shared/open-swe/types";
|
||||
import { z } from "zod";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { getMessageString } from "../../../utils/message/content.js";
|
||||
|
||||
export async function createIssueFieldsFromMessages(
|
||||
|
|
@ -25,10 +29,18 @@ export async function createIssueFieldsFromMessages(
|
|||
),
|
||||
}),
|
||||
};
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
{ configurable },
|
||||
Task.ROUTER,
|
||||
);
|
||||
const modelWithTools = model
|
||||
.bindTools([githubIssueTool], {
|
||||
tool_choice: githubIssueTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
.withConfig({ tags: ["nostream"], runName: "create-issue-fields" });
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import {
|
|||
} from "@open-swe/shared/open-swe/planner/types";
|
||||
import { GraphConfig } from "@open-swe/shared/open-swe/types";
|
||||
import { z } from "zod";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { getMissingMessages } from "../../../utils/github/issue-messages.js";
|
||||
import { getMessageString } from "../../../utils/message/content.js";
|
||||
import { isHumanMessage } from "@langchain/core/messages";
|
||||
|
|
@ -120,9 +124,17 @@ export async function determineNeedsContext(
|
|||
"Can not determine if more context is needed if there are no missing messages.",
|
||||
);
|
||||
}
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.ROUTER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([determineContextTool], {
|
||||
tool_choice: determineContextTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { loadModel, Task } from "../../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../../utils/load-model.js";
|
||||
import {
|
||||
createGetURLContentTool,
|
||||
createShellTool,
|
||||
|
|
@ -51,6 +55,10 @@ export async function generateAction(
|
|||
config: GraphConfig,
|
||||
): Promise<PlannerGraphUpdate> {
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const mcpTools = await getMcpTools(config);
|
||||
|
||||
const tools = [
|
||||
|
|
@ -66,7 +74,11 @@ export async function generateAction(
|
|||
|
||||
const modelWithTools = model.bindTools(tools, {
|
||||
tool_choice: "auto",
|
||||
parallel_tool_calls: true,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: true,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const [missingMessages, { taskPlan: latestTaskPlan }] = await Promise.all([
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ import { v4 as uuidv4 } from "uuid";
|
|||
import { isAIMessage, ToolMessage } from "@langchain/core/messages";
|
||||
import { createSessionPlanToolFields } from "../../../../tools/index.js";
|
||||
import { GraphConfig } from "@open-swe/shared/open-swe/types";
|
||||
import { loadModel, Task } from "../../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../../utils/load-model.js";
|
||||
import {
|
||||
PlannerGraphState,
|
||||
PlannerGraphUpdate,
|
||||
|
|
@ -50,10 +54,18 @@ export async function generatePlan(
|
|||
config: GraphConfig,
|
||||
): Promise<PlannerGraphUpdate> {
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.SUMMARIZER,
|
||||
);
|
||||
const sessionPlanTool = createSessionPlanToolFields();
|
||||
const modelWithTools = model.bindTools([sessionPlanTool], {
|
||||
tool_choice: sessionPlanTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
let optionalToolMessage: ToolMessage | undefined;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import {
|
|||
PlannerGraphState,
|
||||
PlannerGraphUpdate,
|
||||
} from "@open-swe/shared/open-swe/planner/types";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { getMessageString } from "../../../utils/message/content.js";
|
||||
import { getUserRequest } from "../../../utils/user-request.js";
|
||||
import { formatCustomRulesPrompt } from "../../../utils/custom-rules.js";
|
||||
|
|
@ -101,9 +105,17 @@ export async function notetaker(
|
|||
config: GraphConfig,
|
||||
): Promise<PlannerGraphUpdate> {
|
||||
const model = await loadModel(config, Task.SUMMARIZER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.SUMMARIZER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([condenseContextTool], {
|
||||
tool_choice: condenseContextTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const conversationHistoryStr = `Here is the full conversation history:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ import {
|
|||
PlannerGraphUpdate,
|
||||
} from "@open-swe/shared/open-swe/planner/types";
|
||||
import { getUserRequest } from "../../../utils/user-request.js";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
|
||||
const systemPromptIdentifyChanges = `You are operating as an agentic coding assistant built by LangChain. You've previously been given a task to generate a plan of action for, to address the user's initial request.
|
||||
|
||||
|
|
@ -91,6 +95,7 @@ const formatSysPromptRewritePlan = (
|
|||
async function identifyTasksToModifyFunc(
|
||||
state: PlannerGraphState,
|
||||
model: ConfigurableModel,
|
||||
supportsParallelToolCallsParam: boolean,
|
||||
): Promise<PlanItem[]> {
|
||||
if (!state.planChangeRequest) {
|
||||
throw new Error("No plan change request found.");
|
||||
|
|
@ -136,7 +141,11 @@ async function identifyTasksToModifyFunc(
|
|||
{
|
||||
// The model should always call the tool when identifying plan changes.
|
||||
tool_choice: identifyPlanChangesTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(supportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -173,6 +182,7 @@ async function updatePlanTasksFunc(
|
|||
state: PlannerGraphState,
|
||||
tasksToModify: PlanItem[],
|
||||
model: ConfigurableModel,
|
||||
supportsParallelToolCallsParam: boolean,
|
||||
): Promise<string[]> {
|
||||
if (!state.planChangeRequest) {
|
||||
throw new Error("No plan change request found.");
|
||||
|
|
@ -200,7 +210,11 @@ async function updatePlanTasksFunc(
|
|||
const modelWithUpdatePlanTasksTool = model.bindTools([updatePlanTasksTool], {
|
||||
// The model should always call the tool when identifying plan changes.
|
||||
tool_choice: updatePlanTasksTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(supportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const userRequest = getUserRequest(state.messages);
|
||||
|
|
@ -241,8 +255,21 @@ export async function rewritePlan(
|
|||
}
|
||||
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const tasksToModify = await identifyTasksToModify(state, model);
|
||||
const updatedPlanTasks = await updatePlanTasks(state, tasksToModify, model);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const tasksToModify = await identifyTasksToModify(
|
||||
state,
|
||||
model,
|
||||
modelSupportsParallelToolCallsParam,
|
||||
);
|
||||
const updatedPlanTasks = await updatePlanTasks(
|
||||
state,
|
||||
tasksToModify,
|
||||
model,
|
||||
modelSupportsParallelToolCallsParam,
|
||||
);
|
||||
|
||||
return {
|
||||
proposedPlan: updatedPlanTasks,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ import { createDiagnoseErrorToolFields } from "@open-swe/shared/open-swe/tools";
|
|||
import { formatPlanPromptWithSummaries } from "../../../utils/plan-prompt.js";
|
||||
import { getMessageString } from "../../../utils/message/content.js";
|
||||
import { getMessageContentString } from "@open-swe/shared/messages";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { z } from "zod";
|
||||
import { createLogger, LogLevel } from "../../../utils/logger.js";
|
||||
import {
|
||||
|
|
@ -105,9 +109,17 @@ export async function diagnoseError(
|
|||
logger.info("The last two tool calls resulted in errors. Diagnosing error.");
|
||||
|
||||
const model = await loadModel(config, Task.SUMMARIZER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.SUMMARIZER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([diagnoseErrorTool], {
|
||||
tool_choice: diagnoseErrorTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ import {
|
|||
GraphConfig,
|
||||
GraphUpdate,
|
||||
} from "@open-swe/shared/open-swe/types";
|
||||
import { loadModel, Task } from "../../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../../utils/load-model.js";
|
||||
import {
|
||||
createShellTool,
|
||||
createApplyPatchTool,
|
||||
|
|
@ -89,6 +93,10 @@ export async function generateAction(
|
|||
config: GraphConfig,
|
||||
): Promise<GraphUpdate> {
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const mcpTools = await getMcpTools(config);
|
||||
|
||||
const tools = [
|
||||
|
|
@ -110,7 +118,11 @@ export async function generateAction(
|
|||
|
||||
const modelWithTools = model.bindTools(tools, {
|
||||
tool_choice: "auto",
|
||||
parallel_tool_calls: true,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: true,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const [missingMessages, { taskPlan: latestTaskPlan }] = await Promise.all([
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ import {
|
|||
import { createPullRequest } from "../../../utils/github/api.js";
|
||||
import { createLogger, LogLevel } from "../../../utils/logger.js";
|
||||
import { z } from "zod";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { formatPlanPromptWithSummaries } from "../../../utils/plan-prompt.js";
|
||||
import { getUserRequest } from "../../../utils/user-request.js";
|
||||
import { AIMessage, ToolMessage } from "@langchain/core/messages";
|
||||
|
|
@ -91,9 +95,17 @@ export async function openPullRequest(
|
|||
const openPrTool = createOpenPrToolFields();
|
||||
// use the router model since this is a simple task that doesn't need an advanced model
|
||||
const model = await loadModel(config, Task.ROUTER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.ROUTER,
|
||||
);
|
||||
const modelWithTool = model.bindTools([openPrTool], {
|
||||
tool_choice: openPrTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const userRequest = getUserRequest(state.internalMessages);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ import {
|
|||
GraphUpdate,
|
||||
PlanItem,
|
||||
} from "@open-swe/shared/open-swe/types";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { formatPlanPrompt } from "../../../utils/plan-prompt.js";
|
||||
import { Command } from "@langchain/langgraph";
|
||||
import { getMessageString } from "../../../utils/message/content.js";
|
||||
|
|
@ -68,11 +72,19 @@ export async function progressPlanStep(
|
|||
const markNotCompletedTool = createMarkTaskNotCompletedToolFields();
|
||||
const markCompletedTool = createMarkTaskCompletedToolFields();
|
||||
const model = await loadModel(config, Task.SUMMARIZER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.SUMMARIZER,
|
||||
);
|
||||
const modelWithTools = model.bindTools(
|
||||
[markNotCompletedTool, markCompletedTool],
|
||||
{
|
||||
tool_choice: "any",
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ import {
|
|||
GraphUpdate,
|
||||
CustomRules,
|
||||
} from "@open-swe/shared/open-swe/types";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
getActiveTask,
|
||||
|
|
@ -119,9 +123,17 @@ export async function updatePlan(
|
|||
});
|
||||
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([updatePlanTool], {
|
||||
tool_choice: updatePlanTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const activeTask = getActiveTask(state.taskPlan);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ import {
|
|||
createCodeReviewMarkTaskCompletedFields,
|
||||
createCodeReviewMarkTaskNotCompleteFields,
|
||||
} from "@open-swe/shared/open-swe/tools";
|
||||
import { loadModel, Task } from "../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../utils/load-model.js";
|
||||
import { GraphConfig, PlanItem } from "@open-swe/shared/open-swe/types";
|
||||
import { z } from "zod";
|
||||
import { addTaskPlanToIssue } from "../../../utils/github/issue-task.js";
|
||||
|
|
@ -77,9 +81,17 @@ export async function finalReview(
|
|||
const incompleteTool = createCodeReviewMarkTaskNotCompleteFields();
|
||||
const tools = [completedTool, incompleteTool];
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const modelWithTools = model.bindTools(tools, {
|
||||
tool_choice: "any",
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { loadModel, Task } from "../../../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../../../utils/load-model.js";
|
||||
import {
|
||||
ReviewerGraphState,
|
||||
ReviewerGraphUpdate,
|
||||
|
|
@ -74,6 +78,10 @@ export async function generateReviewActions(
|
|||
config: GraphConfig,
|
||||
): Promise<ReviewerGraphUpdate> {
|
||||
const model = await loadModel(config, Task.PROGRAMMER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.PROGRAMMER,
|
||||
);
|
||||
const tools = [
|
||||
createSearchTool(state),
|
||||
createShellTool(state),
|
||||
|
|
@ -81,7 +89,11 @@ export async function generateReviewActions(
|
|||
];
|
||||
const modelWithTools = model.bindTools(tools, {
|
||||
tool_choice: "auto",
|
||||
parallel_tool_calls: true,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: true,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@ import { GraphConfig } from "@open-swe/shared/open-swe/types";
|
|||
import { createLogger, LogLevel } from "../../utils/logger.js";
|
||||
import { getAllLastFailedActions } from "../../utils/tool-message-error.js";
|
||||
import { getMessageString } from "../../utils/message/content.js";
|
||||
import { loadModel, Task } from "../../utils/load-model.js";
|
||||
import {
|
||||
loadModel,
|
||||
supportsParallelToolCallsParam,
|
||||
Task,
|
||||
} from "../../utils/load-model.js";
|
||||
|
||||
const logger = createLogger(LogLevel.INFO, "SharedDiagnoseError");
|
||||
|
||||
|
|
@ -89,9 +93,17 @@ export async function diagnoseError(
|
|||
logger.info("The last few tool calls resulted in errors. Diagnosing error.");
|
||||
|
||||
const model = await loadModel(config, Task.SUMMARIZER);
|
||||
const modelSupportsParallelToolCallsParam = supportsParallelToolCallsParam(
|
||||
config,
|
||||
Task.SUMMARIZER,
|
||||
);
|
||||
const modelWithTools = model.bindTools([diagnoseErrorTool], {
|
||||
tool_choice: diagnoseErrorTool.name,
|
||||
parallel_tool_calls: false,
|
||||
...(modelSupportsParallelToolCallsParam
|
||||
? {
|
||||
parallel_tool_calls: false,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const response = await modelWithTools.invoke([
|
||||
|
|
|
|||
|
|
@ -79,3 +79,16 @@ export async function loadModel(config: GraphConfig, task: Task) {
|
|||
|
||||
return model;
|
||||
}
|
||||
|
||||
const MODELS_NO_PARALLEL_TOOL_CALLING = ["openai:o3", "openai:o3-mini"];
|
||||
|
||||
export function supportsParallelToolCallsParam(
|
||||
config: GraphConfig,
|
||||
task: Task,
|
||||
): boolean {
|
||||
const modelStr =
|
||||
config.configurable?.[`${task}ModelName`] ??
|
||||
TASK_TO_CONFIG_DEFAULTS_MAP[task].modelName;
|
||||
|
||||
return !MODELS_NO_PARALLEL_TOOL_CALLING.some((model) => modelStr === model);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,6 +243,10 @@ export function ActionsRenderer<State extends PlannerGraphState | GraphState>({
|
|||
}
|
||||
}, [stream.values, graphId]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(stream.messages);
|
||||
}, [stream.messages]);
|
||||
|
||||
if (streamLoading) {
|
||||
return <LoadingActionsCardContent />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
},
|
||||
"resolutions": {
|
||||
"@langchain/langgraph-sdk": "^0.0.95",
|
||||
"@langchain/core": "^0.3.58"
|
||||
"@langchain/core": "^0.3.64",
|
||||
"langsmith": "^0.3.46"
|
||||
},
|
||||
"packageManager": "yarn@3.5.1"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export const TIMEOUT_SEC = 60; // 1 minute
|
||||
export const SANDBOX_ROOT_DIR = "/home/daytona";
|
||||
export const SNAPSHOT_NAME = "daytonaio/langchain-open-swe:0.1.0";
|
||||
export const DAYTONA_IMAGE_NAME = "daytonaio/langchain-open-swe:0.1.0";
|
||||
export const DAYTONA_SNAPSHOT_NAME = "open-swe-vcpu2-mem4-disk5";
|
||||
export const PLAN_INTERRUPT_DELIMITER = ":::";
|
||||
export const PLAN_INTERRUPT_ACTION_TITLE = "Approve/Edit Plan";
|
||||
|
||||
|
|
|
|||
18
yarn.lock
18
yarn.lock
|
|
@ -3098,23 +3098,23 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/core@npm:^0.3.58":
|
||||
version: 0.3.62
|
||||
resolution: "@langchain/core@npm:0.3.62"
|
||||
"@langchain/core@npm:^0.3.64":
|
||||
version: 0.3.64
|
||||
resolution: "@langchain/core@npm:0.3.64"
|
||||
dependencies:
|
||||
"@cfworker/json-schema": ^4.0.2
|
||||
ansi-styles: ^5.0.0
|
||||
camelcase: 6
|
||||
decamelize: 1.2.0
|
||||
js-tiktoken: ^1.0.12
|
||||
langsmith: ^0.3.33
|
||||
langsmith: ^0.3.46
|
||||
mustache: ^4.2.0
|
||||
p-queue: ^6.6.2
|
||||
p-retry: 4
|
||||
uuid: ^10.0.0
|
||||
zod: ^3.25.32
|
||||
zod-to-json-schema: ^3.22.3
|
||||
checksum: 7168404d80b8bcc1ff7fbdd91fbf64f172da6731a584e56e0add7ecc301fe002eba10eeb21415187c29ce5b7df96722d9b561a6cb5d54a20c66344def5f58d48
|
||||
checksum: 0c24b92f9b68cf39e57f499b2b9ea5489c7f5449467ffc3fe2aad674776ab611fa451221ac4b5f94e956acb63d9c6e87b1a265aae99f3d0f467e77e5a501d41c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -13768,9 +13768,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"langsmith@npm:^0.3.29, langsmith@npm:^0.3.33":
|
||||
version: 0.3.43
|
||||
resolution: "langsmith@npm:0.3.43"
|
||||
"langsmith@npm:^0.3.46":
|
||||
version: 0.3.46
|
||||
resolution: "langsmith@npm:0.3.46"
|
||||
dependencies:
|
||||
"@types/uuid": ^10.0.0
|
||||
chalk: ^4.1.2
|
||||
|
|
@ -13793,7 +13793,7 @@ __metadata:
|
|||
optional: true
|
||||
openai:
|
||||
optional: true
|
||||
checksum: 23a1234f82b9100a2f23d9aebae3556f9b296653313e9efff25aa676f008c6712c4014d825dd85e03d50e4a60f2c03b1832e8b5c0053d3dc434d5d91963e1280
|
||||
checksum: b9388c3a5dc0179e2d85fdc430e965301c941428639f177748101e354436ffccafb4f89fc8006f88a73db0304fa473d780c87e33582bd27fc2a8ca5add5bc1f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue