mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 20:31:37 -05:00
Updating Roo-Cline with the latest cline/cline (11/22)
This commit is contained in:
@@ -113,7 +113,7 @@ export class Cline {
|
||||
alwaysAllowBrowser?: boolean,
|
||||
task?: string,
|
||||
images?: string[],
|
||||
historyItem?: HistoryItem
|
||||
historyItem?: HistoryItem,
|
||||
) {
|
||||
this.providerRef = new WeakRef(provider)
|
||||
this.api = buildApiHandler(apiConfiguration)
|
||||
@@ -235,7 +235,7 @@ export class Cline {
|
||||
this.clineMessages[
|
||||
findLastIndex(
|
||||
this.clineMessages,
|
||||
(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task")
|
||||
(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"),
|
||||
)
|
||||
]
|
||||
await this.providerRef.deref()?.updateTaskHistory({
|
||||
@@ -259,7 +259,7 @@ export class Cline {
|
||||
async ask(
|
||||
type: ClineAsk,
|
||||
text?: string,
|
||||
partial?: boolean
|
||||
partial?: boolean,
|
||||
): Promise<{ response: ClineAskResponse; text?: string; images?: string[] }> {
|
||||
// If this Cline instance was aborted by the provider, then the only thing keeping us alive is a promise still running in the background, in which case we don't want to send its result to the webview as it is attached to a new instance of Cline now. So we can safely ignore the result of any active promises, and this class will be deallocated. (Although we set Cline = undefined in provider, that simply removes the reference to this instance, but the instance is still alive until this promise resolves or rejects.)
|
||||
if (this.abort) {
|
||||
@@ -420,7 +420,7 @@ export class Cline {
|
||||
"error",
|
||||
`Cline tried to use ${toolName}${
|
||||
relPath ? ` for '${relPath.toPosix()}'` : ""
|
||||
} without value for required parameter '${paramName}'. Retrying...`
|
||||
} without value for required parameter '${paramName}'. Retrying...`,
|
||||
)
|
||||
return formatResponse.toolError(formatResponse.missingToolParameterError(paramName))
|
||||
}
|
||||
@@ -452,7 +452,7 @@ export class Cline {
|
||||
// Remove any resume messages that may have been added before
|
||||
const lastRelevantMessageIndex = findLastIndex(
|
||||
modifiedClineMessages,
|
||||
(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task")
|
||||
(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"),
|
||||
)
|
||||
if (lastRelevantMessageIndex !== -1) {
|
||||
modifiedClineMessages.splice(lastRelevantMessageIndex + 1)
|
||||
@@ -461,7 +461,7 @@ export class Cline {
|
||||
// since we don't use api_req_finished anymore, we need to check if the last api_req_started has a cost value, if it doesn't and no cancellation reason to present, then we remove it since it indicates an api request without any partial content streamed
|
||||
const lastApiReqStartedIndex = findLastIndex(
|
||||
modifiedClineMessages,
|
||||
(m) => m.type === "say" && m.say === "api_req_started"
|
||||
(m) => m.type === "say" && m.say === "api_req_started",
|
||||
)
|
||||
if (lastApiReqStartedIndex !== -1) {
|
||||
const lastApiReqStarted = modifiedClineMessages[lastApiReqStartedIndex]
|
||||
@@ -566,7 +566,7 @@ export class Cline {
|
||||
|
||||
if (hasToolUse) {
|
||||
const toolUseBlocks = content.filter(
|
||||
(block) => block.type === "tool_use"
|
||||
(block) => block.type === "tool_use",
|
||||
) as Anthropic.Messages.ToolUseBlock[]
|
||||
const toolResponses: Anthropic.ToolResultBlockParam[] = toolUseBlocks.map((block) => ({
|
||||
type: "tool_result",
|
||||
@@ -592,17 +592,17 @@ export class Cline {
|
||||
: [{ type: "text", text: previousAssistantMessage.content }]
|
||||
|
||||
const toolUseBlocks = assistantContent.filter(
|
||||
(block) => block.type === "tool_use"
|
||||
(block) => block.type === "tool_use",
|
||||
) as Anthropic.Messages.ToolUseBlock[]
|
||||
|
||||
if (toolUseBlocks.length > 0) {
|
||||
const existingToolResults = existingUserContent.filter(
|
||||
(block) => block.type === "tool_result"
|
||||
(block) => block.type === "tool_result",
|
||||
) as Anthropic.ToolResultBlockParam[]
|
||||
|
||||
const missingToolResponses: Anthropic.ToolResultBlockParam[] = toolUseBlocks
|
||||
.filter(
|
||||
(toolUse) => !existingToolResults.some((result) => result.tool_use_id === toolUse.id)
|
||||
(toolUse) => !existingToolResults.some((result) => result.tool_use_id === toolUse.id),
|
||||
)
|
||||
.map((toolUse) => ({
|
||||
type: "tool_result",
|
||||
@@ -772,7 +772,7 @@ export class Cline {
|
||||
`Command is still running in the user's terminal.${
|
||||
result.length > 0 ? `\nHere's the output so far:\n${result}` : ""
|
||||
}\n\nThe user provided the following feedback:\n<feedback>\n${userFeedback.text}\n</feedback>`,
|
||||
userFeedback.images
|
||||
userFeedback.images,
|
||||
),
|
||||
]
|
||||
}
|
||||
@@ -797,7 +797,7 @@ export class Cline {
|
||||
const previousRequest = this.clineMessages[previousApiReqIndex]
|
||||
if (previousRequest && previousRequest.text) {
|
||||
const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse(
|
||||
previousRequest.text
|
||||
previousRequest.text,
|
||||
)
|
||||
const totalTokens = (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0)
|
||||
const contextWindow = this.api.getModel().info.contextWindow || 128_000
|
||||
@@ -820,7 +820,7 @@ export class Cline {
|
||||
// note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely.
|
||||
const { response } = await this.ask(
|
||||
"api_req_failed",
|
||||
error.message ?? JSON.stringify(serializeError(error), null, 2)
|
||||
error.message ?? JSON.stringify(serializeError(error), null, 2),
|
||||
)
|
||||
if (response !== "yesButtonClicked") {
|
||||
// this will never happen since if noButtonClicked, we will clear current task, aborting this instance
|
||||
@@ -983,7 +983,7 @@ export class Cline {
|
||||
if (response === "messageResponse") {
|
||||
await this.say("user_feedback", text, images)
|
||||
pushToolResult(
|
||||
formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images)
|
||||
formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images),
|
||||
)
|
||||
// this.userMessageContent.push({
|
||||
// type: "text",
|
||||
@@ -1016,7 +1016,7 @@ export class Cline {
|
||||
const errorString = `Error ${action}: ${JSON.stringify(serializeError(error))}`
|
||||
await this.say(
|
||||
"error",
|
||||
`Error ${action}:\n${error.message ?? JSON.stringify(serializeError(error), null, 2)}`
|
||||
`Error ${action}:\n${error.message ?? JSON.stringify(serializeError(error), null, 2)}`,
|
||||
)
|
||||
// this.toolResults.push({
|
||||
// type: "tool_result",
|
||||
@@ -1042,7 +1042,7 @@ export class Cline {
|
||||
.split("")
|
||||
.map((char) => `(?:${char})?`)
|
||||
.join("")}$`,
|
||||
"g"
|
||||
"g",
|
||||
)
|
||||
return text.replace(tagRegex, "")
|
||||
}
|
||||
@@ -1154,8 +1154,8 @@ export class Cline {
|
||||
? formatResponse.createPrettyPatch(
|
||||
relPath,
|
||||
this.diffViewProvider.originalContent,
|
||||
newContent
|
||||
)
|
||||
newContent,
|
||||
)
|
||||
: undefined,
|
||||
} satisfies ClineSayTool)
|
||||
const didApprove = this.alwaysAllowWrite || (await askApproval("tool", completeMessage))
|
||||
@@ -1173,7 +1173,7 @@ export class Cline {
|
||||
tool: fileExists ? "editedExistingFile" : "newFileCreated",
|
||||
path: getReadablePath(cwd, relPath),
|
||||
diff: userEdits,
|
||||
} satisfies ClineSayTool)
|
||||
} satisfies ClineSayTool),
|
||||
)
|
||||
pushToolResult(
|
||||
`The user made the following updates to your content:\n\n${userEdits}\n\n` +
|
||||
@@ -1183,11 +1183,11 @@ export class Cline {
|
||||
`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
|
||||
`2. Proceed with the task using this updated file content as the new baseline.\n` +
|
||||
`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
|
||||
`${newProblemsMessage}`
|
||||
`${newProblemsMessage}`,
|
||||
)
|
||||
} else {
|
||||
pushToolResult(
|
||||
`The content was successfully saved to ${relPath.toPosix()}.${newProblemsMessage}`
|
||||
`The content was successfully saved to ${relPath.toPosix()}.${newProblemsMessage}`,
|
||||
)
|
||||
}
|
||||
await this.diffViewProvider.reset()
|
||||
@@ -1319,7 +1319,7 @@ export class Cline {
|
||||
if (!relDirPath) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("list_code_definition_names", "path")
|
||||
await this.sayAndCreateMissingParamError("list_code_definition_names", "path"),
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -1448,7 +1448,7 @@ export class Cline {
|
||||
text: removeClosingTag("text", text),
|
||||
} satisfies ClineSayBrowserAction),
|
||||
undefined,
|
||||
block.partial
|
||||
block.partial,
|
||||
)
|
||||
}
|
||||
break
|
||||
@@ -1458,7 +1458,7 @@ export class Cline {
|
||||
if (!url) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("browser_action", "url")
|
||||
await this.sayAndCreateMissingParamError("browser_action", "url"),
|
||||
)
|
||||
await this.browserSession.closeBrowser()
|
||||
break
|
||||
@@ -1480,7 +1480,10 @@ export class Cline {
|
||||
if (!coordinate) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("browser_action", "coordinate")
|
||||
await this.sayAndCreateMissingParamError(
|
||||
"browser_action",
|
||||
"coordinate",
|
||||
),
|
||||
)
|
||||
await this.browserSession.closeBrowser()
|
||||
break // can't be within an inner switch
|
||||
@@ -1490,7 +1493,7 @@ export class Cline {
|
||||
if (!text) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("browser_action", "text")
|
||||
await this.sayAndCreateMissingParamError("browser_action", "text"),
|
||||
)
|
||||
await this.browserSession.closeBrowser()
|
||||
break
|
||||
@@ -1505,7 +1508,7 @@ export class Cline {
|
||||
text,
|
||||
} satisfies ClineSayBrowserAction),
|
||||
undefined,
|
||||
false
|
||||
false,
|
||||
)
|
||||
switch (action) {
|
||||
case "click":
|
||||
@@ -1538,15 +1541,15 @@ export class Cline {
|
||||
`The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${
|
||||
browserActionResult.logs || "(No new logs)"
|
||||
}\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the write_to_file tool.)`,
|
||||
browserActionResult.screenshot ? [browserActionResult.screenshot] : []
|
||||
)
|
||||
browserActionResult.screenshot ? [browserActionResult.screenshot] : [],
|
||||
),
|
||||
)
|
||||
break
|
||||
case "close":
|
||||
pushToolResult(
|
||||
formatResponse.toolResult(
|
||||
`The browser has been closed. You may now proceed to using other tools.`
|
||||
)
|
||||
`The browser has been closed. You may now proceed to using other tools.`,
|
||||
),
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -1574,7 +1577,7 @@ export class Cline {
|
||||
if (!command) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("execute_command", "command")
|
||||
await this.sayAndCreateMissingParamError("execute_command", "command"),
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -1603,14 +1606,14 @@ export class Cline {
|
||||
try {
|
||||
if (block.partial) {
|
||||
await this.ask("followup", removeClosingTag("question", question), block.partial).catch(
|
||||
() => {}
|
||||
() => {},
|
||||
)
|
||||
break
|
||||
} else {
|
||||
if (!question) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("ask_followup_question", "question")
|
||||
await this.sayAndCreateMissingParamError("ask_followup_question", "question"),
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -1661,7 +1664,7 @@ export class Cline {
|
||||
await this.ask(
|
||||
"command",
|
||||
removeClosingTag("command", command),
|
||||
block.partial
|
||||
block.partial,
|
||||
).catch(() => {})
|
||||
} else {
|
||||
// last message is completion_result
|
||||
@@ -1670,12 +1673,12 @@ export class Cline {
|
||||
"completion_result",
|
||||
removeClosingTag("result", result),
|
||||
undefined,
|
||||
false
|
||||
false,
|
||||
)
|
||||
await this.ask(
|
||||
"command",
|
||||
removeClosingTag("command", command),
|
||||
block.partial
|
||||
block.partial,
|
||||
).catch(() => {})
|
||||
}
|
||||
} else {
|
||||
@@ -1684,7 +1687,7 @@ export class Cline {
|
||||
"completion_result",
|
||||
removeClosingTag("result", result),
|
||||
undefined,
|
||||
block.partial
|
||||
block.partial,
|
||||
)
|
||||
}
|
||||
break
|
||||
@@ -1692,7 +1695,7 @@ export class Cline {
|
||||
if (!result) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(
|
||||
await this.sayAndCreateMissingParamError("attempt_completion", "result")
|
||||
await this.sayAndCreateMissingParamError("attempt_completion", "result"),
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -1793,7 +1796,7 @@ export class Cline {
|
||||
|
||||
async recursivelyMakeClineRequests(
|
||||
userContent: UserContent,
|
||||
includeFileDetails: boolean = false
|
||||
includeFileDetails: boolean = false,
|
||||
): Promise<boolean> {
|
||||
if (this.abort) {
|
||||
throw new Error("Cline instance aborted")
|
||||
@@ -1804,7 +1807,7 @@ export class Cline {
|
||||
"mistake_limit_reached",
|
||||
this.api.getModel().id.includes("claude")
|
||||
? `This may indicate a failure in his thought process or inability to use a tool properly, which can be mitigated with some user guidance (e.g. "Try breaking down the task into smaller steps").`
|
||||
: "Cline uses complex prompts and iterative task execution that may be challenging for less capable models. For best results, it's recommended to use Claude 3.5 Sonnet for its advanced agentic coding capabilities."
|
||||
: "Cline uses complex prompts and iterative task execution that may be challenging for less capable models. For best results, it's recommended to use Claude 3.5 Sonnet for its advanced agentic coding capabilities.",
|
||||
)
|
||||
if (response === "messageResponse") {
|
||||
userContent.push(
|
||||
@@ -1814,7 +1817,7 @@ export class Cline {
|
||||
text: formatResponse.tooManyMistakes(text),
|
||||
} as Anthropic.Messages.TextBlockParam,
|
||||
...formatResponse.imageBlocks(images),
|
||||
]
|
||||
],
|
||||
)
|
||||
}
|
||||
this.consecutiveMistakeCount = 0
|
||||
@@ -1830,7 +1833,7 @@ export class Cline {
|
||||
JSON.stringify({
|
||||
request:
|
||||
userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...",
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
const [parsedUserContent, environmentDetails] = await this.loadContext(userContent, includeFileDetails)
|
||||
@@ -1872,7 +1875,7 @@ export class Cline {
|
||||
inputTokens,
|
||||
outputTokens,
|
||||
cacheWriteTokens,
|
||||
cacheReadTokens
|
||||
cacheReadTokens,
|
||||
),
|
||||
cancelReason,
|
||||
streamingFailedMessage,
|
||||
@@ -1986,7 +1989,7 @@ export class Cline {
|
||||
this.abortTask() // if the stream failed, there's various states the task could be in (i.e. could have streamed some tools the user may have executed), so we just resort to replicating a cancel task
|
||||
await abortStream(
|
||||
"streaming_failed",
|
||||
error.message ?? JSON.stringify(serializeError(error), null, 2)
|
||||
error.message ?? JSON.stringify(serializeError(error), null, 2),
|
||||
)
|
||||
const history = await this.providerRef.deref()?.getTaskWithId(this.taskId)
|
||||
if (history) {
|
||||
@@ -2053,7 +2056,7 @@ export class Cline {
|
||||
// if there's no assistant_responses, that means we got no text or tool_use content blocks from API which we should assume is an error
|
||||
await this.say(
|
||||
"error",
|
||||
"Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output."
|
||||
"Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output.",
|
||||
)
|
||||
await this.addToApiConversationHistory({
|
||||
role: "assistant",
|
||||
@@ -2099,7 +2102,7 @@ export class Cline {
|
||||
}
|
||||
}
|
||||
return contentBlock
|
||||
})
|
||||
}),
|
||||
)
|
||||
return {
|
||||
...block,
|
||||
@@ -2108,7 +2111,7 @@ export class Cline {
|
||||
}
|
||||
}
|
||||
return block
|
||||
})
|
||||
}),
|
||||
),
|
||||
this.getEnvironmentDetails(includeFileDetails),
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user