update fetch urls & web search show view

This commit is contained in:
duanfuxiang
2025-04-01 18:56:11 +08:00
parent 7642cc1410
commit c8d03bf799
25 changed files with 156 additions and 4967 deletions

View File

@@ -1,136 +0,0 @@
import { Anthropic } from "@anthropic-ai/sdk"
import * as diff from "diff"
import * as path from "path"
export const formatResponse = {
toolDenied: () => `The user denied this operation.`,
toolDeniedWithFeedback: (feedback?: string) =>
`The user denied this operation and provided the following feedback:\n<feedback>\n${feedback}\n</feedback>`,
toolApprovedWithFeedback: (feedback?: string) =>
`The user approved this operation and provided the following context:\n<feedback>\n${feedback}\n</feedback>`,
toolError: (error?: string) => `The tool execution failed with the following error:\n<error>\n${error}\n</error>`,
noToolsUsed: () =>
`[ERROR] You did not use a tool in your previous response! Please retry with a tool use.
${toolUseInstructionsReminder}
# Next Steps
If you have completed the user's task, use the attempt_completion tool.
If you require additional information from the user, use the ask_followup_question tool.
Otherwise, if you have not completed the task and do not need additional information, then proceed with the next step of the task.
(This is an automated message, so do not respond to it conversationally.)`,
tooManyMistakes: (feedback?: string) =>
`You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n<feedback>\n${feedback}\n</feedback>`,
missingToolParameterError: (paramName: string) =>
`Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${toolUseInstructionsReminder}`,
invalidMcpToolArgumentError: (serverName: string, toolName: string) =>
`Invalid JSON argument used with ${serverName} for ${toolName}. Please retry with a properly formatted JSON argument.`,
toolResult: (
text: string,
images?: string[],
): string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam> => {
if (images && images.length > 0) {
const textBlock: Anthropic.TextBlockParam = { type: "text", text }
const imageBlocks: Anthropic.ImageBlockParam[] = formatImagesIntoBlocks(images)
// Placing images after text leads to better results
return [textBlock, ...imageBlocks]
} else {
return text
}
},
imageBlocks: (images?: string[]): Anthropic.ImageBlockParam[] => {
return formatImagesIntoBlocks(images)
},
formatFilesList: (absolutePath: string, files: string[], didHitLimit: boolean): string => {
const sorted = files
.map((file) => {
// convert absolute path to relative path
const relativePath = path.relative(absolutePath, file).toPosix()
return file.endsWith("/") ? relativePath + "/" : relativePath
})
// Sort so files are listed under their respective directories to make it clear what files are children of what directories. Since we build file list top down, even if file list is truncated it will show directories that cline can then explore further.
.sort((a, b) => {
const aParts = a.split("/") // only works if we use toPosix first
const bParts = b.split("/")
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
if (aParts[i] !== bParts[i]) {
// If one is a directory and the other isn't at this level, sort the directory first
if (i + 1 === aParts.length && i + 1 < bParts.length) {
return -1
}
if (i + 1 === bParts.length && i + 1 < aParts.length) {
return 1
}
// Otherwise, sort alphabetically
return aParts[i].localeCompare(bParts[i], undefined, { numeric: true, sensitivity: "base" })
}
}
// If all parts are the same up to the length of the shorter path,
// the shorter one comes first
return aParts.length - bParts.length
})
if (didHitLimit) {
return `${sorted.join(
"\n",
)}\n\n(File list truncated. Use list_files on specific subdirectories if you need to explore further.)`
} else if (sorted.length === 0 || (sorted.length === 1 && sorted[0] === "")) {
return "No files found."
} else {
return sorted.join("\n")
}
},
createPrettyPatch: (filename = "file", oldStr?: string, newStr?: string) => {
// strings cannot be undefined or diff throws exception
const patch = diff.createPatch(filename.toPosix(), oldStr || "", newStr || "")
const lines = patch.split("\n")
const prettyPatchLines = lines.slice(4)
return prettyPatchLines.join("\n")
},
}
// to avoid circular dependency
const formatImagesIntoBlocks = (images?: string[]): Anthropic.ImageBlockParam[] => {
return images
? images.map((dataUrl) => {
// data:image/png;base64,base64string
const [rest, base64] = dataUrl.split(",")
const mimeType = rest.split(":")[1].split(";")[0]
return {
type: "image",
source: { type: "base64", media_type: mimeType, data: base64 },
} as Anthropic.ImageBlockParam
})
: []
}
const toolUseInstructionsReminder = `# Reminder: Instructions for Tool Use
Tool uses are formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
<tool_name>
<parameter1_name>value1</parameter1_name>
<parameter2_name>value2</parameter2_name>
...
</tool_name>
For example:
<attempt_completion>
<result>
I have completed the task...
</result>
</attempt_completion>
Always adhere to this format for all tool uses to ensure proper parsing and execution.`

View File

@@ -1,52 +0,0 @@
import { ToolArgs } from "./types"
export function getBrowserActionDescription(args: ToolArgs): string | undefined {
if (!args.supportsComputerUse) {
return undefined
}
return `## browser_action
Description: Request to interact with a Puppeteer-controlled browser. Use this tool for research, information gathering, citation verification, or content reference when writing. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
- The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
- While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you need to save research findings to a document, you must close the browser, then use other tools to write the information to files.
- The browser window has a resolution of **${args.browserViewportSize}** pixels. When performing any click actions, ensure the coordinates are within this resolution range.
- Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges.
Parameters:
- action: (required) The action to perform. The available actions are:
* launch: Launch a new Puppeteer-controlled browser instance at the specified URL. This **must always be the first action**.
- Use with the \`url\` parameter to provide the URL.
- Ensure the URL is valid and includes the appropriate protocol (e.g. https://en.wikipedia.org/wiki/Writing, https://scholar.google.com, etc.)
* click: Click at a specific x,y coordinate.
- Use with the \`coordinate\` parameter to specify the location.
- Always click in the center of an element (icon, button, link, etc.) based on coordinates derived from a screenshot.
* type: Type a string of text on the keyboard. You might use this after clicking on a text field to input text.
- Use with the \`text\` parameter to provide the string to type.
* scroll_down: Scroll down the page by one page height.
* scroll_up: Scroll up the page by one page height.
* close: Close the Puppeteer-controlled browser instance. This **must always be the final browser action**.
- Example: \`<action>close</action>\`
- url: (optional) Use this for providing the URL for the \`launch\` action.
* Example: <url>https://en.wikipedia.org/wiki/Writing</url>
- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${args.browserViewportSize}** resolution.
* Example: <coordinate>450,300</coordinate>
- text: (optional) Use this for providing the text for the \`type\` action.
* Example: <text>academic writing research</text>
Usage:
<browser_action>
<action>Action to perform (e.g., launch, click, type, scroll_down, scroll_up, close)</action>
<url>URL to launch the browser at (optional)</url>
<coordinate>x,y coordinates (optional)</coordinate>
<text>Text to type (optional)</text>
</browser_action>
Example: Requesting to launch a browser at a research resource
<browser_action>
<action>launch</action>
<url>https://scholar.google.com</url>
</browser_action>
Example: Requesting to type a search query
<browser_action>
<action>type</action>
<text>academic writing styles comparison</text>
</browser_action>`
}

View File

@@ -1,17 +0,0 @@
import { ToolArgs } from "./types"
export function getExecuteCommandDescription(args: ToolArgs): string | undefined {
return `## execute_command
Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: ${args.cwd}
Parameters:
- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.
Usage:
<execute_command>
<command>Your command here</command>
</execute_command>
Example: Requesting to convert a markdown file to PDF using pandoc
<execute_command>
<command>pandoc document.md -o document.pdf</command>
</execute_command>`
}

View File

@@ -5,8 +5,6 @@ import { McpHub } from "../../mcp/McpHub"
import { getAccessMcpResourceDescription } from "./access-mcp-resource"
import { getAskFollowupQuestionDescription } from "./ask-followup-question"
import { getAttemptCompletionDescription } from "./attempt-completion"
import { getBrowserActionDescription } from "./browser-action"
import { getExecuteCommandDescription } from "./execute-command"
import { getFetchUrlsContentDescription } from "./fetch-url-content"
import { getInsertContentDescription } from "./insert-content"
import { getListFilesDescription } from "./list-files"
@@ -22,7 +20,6 @@ import { getWriteToFileDescription } from "./write-to-file"
// Map of tool names to their description functions
const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined> = {
execute_command: (args) => getExecuteCommandDescription(args),
read_file: (args) => getReadFileDescription(args),
write_to_file: (args) => getWriteToFileDescription(args),
search_files: (args) => getSearchFilesDescription(args),
@@ -41,7 +38,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
export function getToolDescriptionsForMode(
mode: Mode,
cwd: string,
searchTool: string,
searchTool: string,
supportsComputerUse: boolean,
diffStrategy?: DiffStrategy,
browserViewportSize?: string,
@@ -95,8 +92,6 @@ export function getToolDescriptionsForMode(
// Export individual description functions for backward compatibility
export {
getAccessMcpResourceDescription, getAskFollowupQuestionDescription,
getAttemptCompletionDescription, getBrowserActionDescription, getExecuteCommandDescription, getInsertContentDescription,
getListFilesDescription, getReadFileDescription, getSearchAndReplaceDescription, getSearchFilesDescription, getSwitchModeDescription, getUseMcpToolDescription, getWriteToFileDescription
getAccessMcpResourceDescription, getAskFollowupQuestionDescription, getAttemptCompletionDescription, getInsertContentDescription, getListFilesDescription, getReadFileDescription, getSearchAndReplaceDescription, getSearchFilesDescription, getSwitchModeDescription, getUseMcpToolDescription, getWriteToFileDescription
}