Browse Source

Use inference-stream endpoint to work around vercel timeout

Saoud Rizwan 1 year ago
parent
commit
6b7a2894b1
4 changed files with 78 additions and 8 deletions
  1. 2 2
      package-lock.json
  2. 1 1
      package.json
  3. 74 4
      src/api/kodu.ts
  4. 1 1
      src/shared/kodu.ts

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "claude-dev",
-  "version": "1.4.0",
+  "version": "1.4.11",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "claude-dev",
-      "version": "1.4.0",
+      "version": "1.4.11",
       "license": "MIT",
       "dependencies": {
         "@anthropic-ai/bedrock-sdk": "^0.10.2",

+ 1 - 1
package.json

@@ -2,7 +2,7 @@
   "name": "claude-dev",
   "displayName": "Claude Dev",
   "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, executing commands, and more with your permission every step of the way.",
-  "version": "1.4.11",
+  "version": "1.4.12",
   "icon": "icon.png",
   "engines": {
     "vscode": "^1.84.0"

+ 74 - 4
src/api/kodu.ts

@@ -77,14 +77,84 @@ export class KoduHandler implements ApiHandler {
 					tool_choice: { type: "auto" },
 				}
 		}
+
+		// const response = await axios.post(getKoduInferenceUrl(), requestBody, {
+		// 	headers: {
+		// 		"x-api-key": this.options.koduApiKey,
+		// 	},
+		// })
+		// const message = response.data
+		// const userCredits = response.headers["user-credits"]
+		// return { message, userCredits: userCredits !== undefined ? parseFloat(userCredits) : undefined }
+		// const thing = {
+		// 	method: "POST",
+		// 	headers: {
+		// 		"Content-Type": "application/json",
+		// 		"x-api-key": this.options.koduApiKey || "",
+		// 	},
+		// 	body: JSON.stringify(requestBody),
+		// }
+
 		const response = await axios.post(getKoduInferenceUrl(), requestBody, {
 			headers: {
-				"x-api-key": this.options.koduApiKey,
+				"Content-Type": "application/json",
+				"x-api-key": this.options.koduApiKey || "",
 			},
+			responseType: "stream",
 		})
-		const message = response.data
-		const userCredits = response.headers["user-credits"]
-		return { message, userCredits: userCredits !== undefined ? parseFloat(userCredits) : undefined }
+
+		if (response.data) {
+			const reader = response.data
+			const decoder = new TextDecoder("utf-8")
+			let finalResponse: any = null
+			let buffer = ""
+
+			for await (const chunk of reader) {
+				buffer += decoder.decode(chunk, { stream: true })
+				const lines = buffer.split("\n\n")
+				buffer = lines.pop() || ""
+
+				for (const line of lines) {
+					if (line.startsWith("data: ")) {
+						const eventData = JSON.parse(line.slice(6))
+
+						console.log("eventData", eventData)
+
+						if (eventData.code === 0) {
+							console.log("Health check received")
+						} else if (eventData.code === 1) {
+							finalResponse = eventData.body
+							console.log("finalResponse", finalResponse)
+							break
+						} else if (eventData.code === -1) {
+							throw new Error(`Error in SSE stream: ${JSON.stringify(eventData.json)}`)
+						}
+					}
+				}
+
+				if (finalResponse) {
+					break
+				}
+			}
+
+			if (!finalResponse) {
+				throw new Error("No final response received from the SSE stream")
+			}
+
+			const message: {
+				anthropic: Anthropic.Messages.Message
+				internal: {
+					userCredits: number
+				}
+			} = finalResponse
+			console.log("message", message)
+			return {
+				message: message.anthropic,
+				userCredits: message.internal?.userCredits,
+			}
+		} else {
+			throw new Error("No response data received")
+		}
 	}
 
 	createUserReadableRequest(

+ 1 - 1
src/shared/kodu.ts

@@ -13,7 +13,7 @@ export function getKoduCreditsUrl() {
 }
 
 export function getKoduInferenceUrl() {
-	return `${KODU_BASE_URL}/api/inference`
+	return `${KODU_BASE_URL}/api/inference-stream`
 }
 
 export function getKoduHomepageUrl() {