Просмотр исходного кода

Show api_req_started message while verbose details are being built for smoother ux

Saoud Rizwan 1 год назад
Родитель
Сommit
dc2f3a5c28
2 измененных файлов с 41 добавлено и 15 удалено
  1. 39 13
      src/ClaudeDev.ts
  2. 2 2
      src/parse-source-code/index.ts

+ 39 - 13
src/ClaudeDev.ts

@@ -260,6 +260,7 @@ export class ClaudeDev {
 	private askResponseImages?: string[]
 	private lastMessageTs?: number
 	private executeCommandRunningProcess?: ResultPromise
+	private shouldSkipNextApiReqStartedMessage = false
 	private providerRef: WeakRef<ClaudeDevProvider>
 	private abort: boolean = false
 
@@ -475,13 +476,34 @@ export class ClaudeDev {
 		this.apiConversationHistory = []
 		await this.providerRef.deref()?.postStateToWebview()
 
-		let textBlock: Anthropic.TextBlockParam = {
-			type: "text",
-			text: `<task>\n${task}\n</task>\n\n${await this.getPotentiallyRelevantDetails(true)}`, // cannot be sent with system prompt since it's cached and these details can change
-		}
-		let imageBlocks: Anthropic.ImageBlockParam[] = this.formatImagesIntoBlocks(images)
 		await this.say("text", task, images)
-		await this.initiateTaskLoop([textBlock, ...imageBlocks])
+
+		// getting verbose details is an expensive operation, it uses globby to top-down build file structure of project which for large projects can take a few seconds
+		// for the best UX we show a loading spinner as this happens
+		const taskText = `<task>\n${task}\n</task>`
+		let imageBlocks: Anthropic.ImageBlockParam[] = this.formatImagesIntoBlocks(images)
+		await this.say(
+			"api_req_started",
+			JSON.stringify({
+				request: this.api.createUserReadableRequest([
+					{
+						type: "text",
+						text: `${taskText}\n\n<potentially_relevant_details>(see getPotentiallyRelevantDetails in src/ClaudeDev.ts)</potentially_relevant_details>`,
+					},
+					...imageBlocks,
+				]),
+			})
+		)
+		this.shouldSkipNextApiReqStartedMessage = true
+		this.getPotentiallyRelevantDetails(true).then(async (verboseDetails) => {
+			await this.initiateTaskLoop([
+				{
+					type: "text",
+					text: `${taskText}\n\n${verboseDetails}`, // cannot be sent with system prompt since it's cached and these details can change
+				},
+				...imageBlocks,
+			])
+		})
 	}
 
 	private async resumeTaskFromHistory() {
@@ -1344,13 +1366,17 @@ ${this.customInstructions.trim()}
 			}
 		}
 
-		// what the user sees in the webview
-		await this.say(
-			"api_req_started",
-			JSON.stringify({
-				request: this.api.createUserReadableRequest(userContent),
-			})
-		)
+		if (!this.shouldSkipNextApiReqStartedMessage) {
+			await this.say(
+				"api_req_started",
+				// what the user sees in the webview
+				JSON.stringify({
+					request: this.api.createUserReadableRequest(userContent),
+				})
+			)
+		} else {
+			this.shouldSkipNextApiReqStartedMessage = false
+		}
 		try {
 			const response = await this.attemptApiRequest()
 			this.requestCount++

+ 2 - 2
src/parse-source-code/index.ts

@@ -105,10 +105,10 @@ export async function listFiles(dirPath: string, recursive: boolean): Promise<st
 // globby doesnt natively support top down level by level globbing, so we implement it ourselves
 async function globbyLevelByLevel(options?: Options) {
 	let results: string[] = []
-	let currentLevel = 1
+	let currentLevel = 0
 	while (results.length < LIST_FILES_LIMIT) {
 		// Construct the glob pattern for the current level
-		const pattern = `${"*/".repeat(currentLevel)}*`
+		const pattern = currentLevel === 0 ? "*" : `${"*/".repeat(currentLevel)}*`
 
 		// Get files and directories at the current level
 		const filesAtLevel = await globby(pattern, options)