Refactor fetch instructions to new file (#2056)

* Refactor fetch_instructions handling into separate module

* Use correct case for module name
This commit is contained in:
Diarmid Mackenzie 2025-03-28 13:50:42 +00:00 committed by GitHub
parent 317e5446fb
commit 62a7bc7959
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 89 additions and 57 deletions

View file

@ -29,7 +29,7 @@ import {
everyLineHasLineNumbers,
} from "../integrations/misc/extract-text"
import { countFileLines } from "../integrations/misc/line-counter"
import { fetchInstructions } from "./prompts/instructions/instructions"
import { fetchInstructionsTool } from "./tools/fetchInstructionsTool"
import { ExitCodeDetails } from "../integrations/terminal/TerminalProcess"
import { Terminal } from "../integrations/terminal/Terminal"
import { TerminalRegistry } from "../integrations/terminal/TerminalRegistry"
@ -86,7 +86,7 @@ import { readLines } from "../integrations/misc/read-lines"
import { getWorkspacePath } from "../utils/path"
import { isBinaryFile } from "isbinaryfile"
type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
export type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
type UserContent = Array<Anthropic.Messages.ContentBlockParam>
export type ClineEvents = {
@ -148,9 +148,11 @@ export class Cline extends EventEmitter<ClineEvents> {
private askResponseText?: string
private askResponseImages?: string[]
private lastMessageTs?: number
private consecutiveMistakeCount: number = 0
// Not private since it needs to be accessible by tools
consecutiveMistakeCount: number = 0
private consecutiveMistakeCountForApplyDiff: Map<string, number> = new Map()
private providerRef: WeakRef<ClineProvider>
// Not private since it needs to be accessible by tools
providerRef: WeakRef<ClineProvider>
private abort: boolean = false
didFinishAbortingStream = false
abandoned = false
@ -2402,59 +2404,8 @@ export class Cline extends EventEmitter<ClineEvents> {
}
case "fetch_instructions": {
const task: string | undefined = block.params.task
const sharedMessageProps: ClineSayTool = {
tool: "fetchInstructions",
content: task,
}
try {
if (block.partial) {
const partialMessage = JSON.stringify({
...sharedMessageProps,
content: undefined,
} satisfies ClineSayTool)
await this.ask("tool", partialMessage, block.partial).catch(() => {})
break
} else {
if (!task) {
this.consecutiveMistakeCount++
pushToolResult(
await this.sayAndCreateMissingParamError("fetch_instructions", "task"),
)
break
}
this.consecutiveMistakeCount = 0
const completeMessage = JSON.stringify({
...sharedMessageProps,
content: task,
} satisfies ClineSayTool)
const didApprove = await askApproval("tool", completeMessage)
if (!didApprove) {
break
}
// now fetch the content and provide it to the agent.
const provider = this.providerRef.deref()
const mcpHub = provider?.getMcpHub()
if (!mcpHub) {
throw new Error("MCP hub not available")
}
const diffStrategy = this.diffStrategy
const context = provider?.context
const content = await fetchInstructions(task, { mcpHub, diffStrategy, context })
if (!content) {
pushToolResult(formatResponse.toolError(`Invalid instructions request: ${task}`))
break
}
pushToolResult(content)
break
}
} catch (error) {
await handleError("fetch instructions", error)
break
}
fetchInstructionsTool(this, block, askApproval, handleError, pushToolResult)
break
}
case "list_files": {

View file

@ -0,0 +1,69 @@
import { Cline } from "../Cline"
import { fetchInstructions } from "../prompts/instructions/instructions"
import { ClineSayTool } from "../../shared/ExtensionMessage"
import { ToolUse } from "../assistant-message"
import { formatResponse } from "../prompts/responses"
import { AskApproval, HandleError, PushToolResult } from "./types"
export async function fetchInstructionsTool(
cline: Cline,
block: ToolUse,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,
) {
switch (true) {
default:
const task: string | undefined = block.params.task
const sharedMessageProps: ClineSayTool = {
tool: "fetchInstructions",
content: task,
}
try {
if (block.partial) {
const partialMessage = JSON.stringify({
...sharedMessageProps,
content: undefined,
} satisfies ClineSayTool)
await cline.ask("tool", partialMessage, block.partial).catch(() => {})
break
} else {
if (!task) {
cline.consecutiveMistakeCount++
pushToolResult(await cline.sayAndCreateMissingParamError("fetch_instructions", "task"))
break
}
cline.consecutiveMistakeCount = 0
const completeMessage = JSON.stringify({
...sharedMessageProps,
content: task,
} satisfies ClineSayTool)
const didApprove = await askApproval("tool", completeMessage)
if (!didApprove) {
break
}
// now fetch the content and provide it to the agent.
const provider = cline.providerRef.deref()
const mcpHub = provider?.getMcpHub()
if (!mcpHub) {
throw new Error("MCP hub not available")
}
const diffStrategy = cline.diffStrategy
const context = provider?.context
const content = await fetchInstructions(task, { mcpHub, diffStrategy, context })
if (!content) {
pushToolResult(formatResponse.toolError(`Invalid instructions request: ${task}`))
break
}
pushToolResult(content)
break
}
} catch (error) {
await handleError("fetch instructions", error)
break
}
}
}

12
src/core/tools/types.ts Normal file
View file

@ -0,0 +1,12 @@
import { ClineAsk, ToolProgressStatus } from "../../schemas"
import { ToolResponse } from "../Cline"
export type AskApproval = (
type: ClineAsk,
partialMessage?: string,
progressStatus?: ToolProgressStatus,
) => Promise<boolean>
export type HandleError = (action: string, error: Error) => void
export type PushToolResult = (content: ToolResponse) => void