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

Merge pull request #8 from RooVetGit/merge/latestCline2RooCline

Updating Roo-Cline with the latest cline/cline
John Stearns 1 год назад
Родитель
Сommit
40abb7cd5b

+ 13 - 0
CHANGELOG.md

@@ -1,5 +1,18 @@
 # Change Log
 # Change Log
 
 
+## [2.1.4]
+
+- AWS Bedrock fixes (add missing regions, support for cross-region inference, and older Sonnet model for regions where new model is not available)
+
+## [2.1.3]
+
+- Add support for Claude 3.5 Haiku, 66% cheaper than Sonnet with similar intelligence
+
+## [2.1.2]
+
+- Misc. bug fixes
+- Update README with new browser feature
+
 ## [2.1.1]
 ## [2.1.1]
 
 
 - Add stricter prompt to prevent Cline from editing files during a browser session without first closing the browser
 - Add stricter prompt to prevent Cline from editing files during a browser session without first closing the browser

+ 4 - 4
README.md

@@ -110,13 +110,13 @@ All changes made by Cline are recorded in your file's Timeline, providing an eas
 
 
 <img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
 <img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
 
 
-<img align="left" width="350" src="https://github.com/user-attachments/assets/50019dba-a63d-41f0-ab0f-fd35ebcdd4c5">
+<img align="left" width="370" src="https://github.com/user-attachments/assets/bc2e85ba-dfeb-4fe6-9942-7cfc4703cbe5">
 
 
-### Analyze Images and Browser Screenshots
+### Use the Browser
 
 
-Models like Claude 3.5 Sonnet can now understand and analyze images, allowing for exciting possibilities of multimodal workflows. Paste images directly in chat to give Cline context that can't be explained in words, and turn mockups into apps, fix bugs with screenshots, and more.
+With Claude 3.5 Sonnet's new [Computer Use](https://www.anthropic.com/news/3-5-models-and-computer-use) capability, Cline can launch a browser, click elements, type text, and scroll, capturing screenshots and console logs at each step. This allows for interactive debugging, end-to-end testing, and even general web use! This gives him autonomy to fixing visual bugs and runtime issues without you needing to handhold and copy-pasting error logs yourself.
 
 
-Cline can also use a headless browser to launch and interact with any website, e.g., localhost, allowing him to capture screenshots and console logs. This gives him autonomy to fixing visual bugs and runtime issues without you needing to handhold and copy-pasting error logs yourself.
+Try asking Cline to "test the app", and watch as he runs a command like `npm run dev`, launches your locally running dev server in a browser, and performs a series of tests to confirm that everything works. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989)
 
 
 <!-- Transparent pixel to create line break after floating image -->
 <!-- Transparent pixel to create line break after floating image -->
 
 

+ 1 - 1
package.json

@@ -2,7 +2,7 @@
   "name": "roo-cline",
   "name": "roo-cline",
   "displayName": "Roo Cline",
   "displayName": "Roo Cline",
   "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.",
   "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.",
-  "version": "1.0.5",
+  "version": "2.0.0",
   "icon": "assets/icons/icon.png",
   "icon": "assets/icons/icon.png",
   "galleryBanner": {
   "galleryBanner": {
     "color": "#617A91",
     "color": "#617A91",

+ 3 - 5
src/api/providers/anthropic.ts

@@ -28,6 +28,7 @@ export class AnthropicHandler implements ApiHandler {
 		switch (modelId) {
 		switch (modelId) {
 			// 'latest' alias does not support cache_control
 			// 'latest' alias does not support cache_control
 			case "claude-3-5-sonnet-20241022":
 			case "claude-3-5-sonnet-20241022":
+			case "claude-3-5-haiku-20241022":
 			case "claude-3-opus-20240229":
 			case "claude-3-opus-20240229":
 			case "claude-3-haiku-20240307": {
 			case "claude-3-haiku-20240307": {
 				/*
 				/*
@@ -78,11 +79,8 @@ export class AnthropicHandler implements ApiHandler {
 						// https://github.com/anthropics/anthropic-sdk-typescript/commit/c920b77fc67bd839bfeb6716ceab9d7c9bbe7393
 						// https://github.com/anthropics/anthropic-sdk-typescript/commit/c920b77fc67bd839bfeb6716ceab9d7c9bbe7393
 						switch (modelId) {
 						switch (modelId) {
 							case "claude-3-5-sonnet-20241022":
 							case "claude-3-5-sonnet-20241022":
-								return {
-									headers: {
-										"anthropic-beta": "prompt-caching-2024-07-31",
-									},
-								}
+							case "claude-3-5-haiku-20241022":
+							case "claude-3-opus-20240229":
 							case "claude-3-haiku-20240307":
 							case "claude-3-haiku-20240307":
 								return {
 								return {
 									headers: { "anthropic-beta": "prompt-caching-2024-07-31" },
 									headers: { "anthropic-beta": "prompt-caching-2024-07-31" },

+ 21 - 1
src/api/providers/bedrock.ts

@@ -25,8 +25,28 @@ export class AwsBedrockHandler implements ApiHandler {
 	}
 	}
 
 
 	async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
 	async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
+		// cross region inference requires prefixing the model id with the region
+		let modelId: string
+		if (this.options.awsUseCrossRegionInference) {
+			let regionPrefix = (this.options.awsRegion || "").slice(0, 3)
+			switch (regionPrefix) {
+				case "us-":
+					modelId = `us.${this.getModel().id}`
+					break
+				case "eu-":
+					modelId = `eu.${this.getModel().id}`
+					break
+				default:
+					// cross region inference is not supported in this region, falling back to default model
+					modelId = this.getModel().id
+					break
+			}
+		} else {
+			modelId = this.getModel().id
+		}
+
 		const stream = await this.client.messages.create({
 		const stream = await this.client.messages.create({
-			model: this.getModel().id,
+			model: modelId,
 			max_tokens: this.getModel().info.maxTokens || 8192,
 			max_tokens: this.getModel().info.maxTokens || 8192,
 			temperature: 0,
 			temperature: 0,
 			system: systemPrompt,
 			system: systemPrompt,

+ 35 - 12
src/core/Cline.ts

@@ -99,6 +99,7 @@ export class Cline {
 	private userMessageContent: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = []
 	private userMessageContent: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = []
 	private userMessageContentReady = false
 	private userMessageContentReady = false
 	private didRejectTool = false
 	private didRejectTool = false
+	private didAlreadyUseTool = false
 	private didCompleteReadingStream = false
 	private didCompleteReadingStream = false
 
 
 	constructor(
 	constructor(
@@ -860,7 +861,7 @@ export class Cline {
 		const block = cloneDeep(this.assistantMessageContent[this.currentStreamingContentIndex]) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too
 		const block = cloneDeep(this.assistantMessageContent[this.currentStreamingContentIndex]) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too
 		switch (block.type) {
 		switch (block.type) {
 			case "text": {
 			case "text": {
-				if (this.didRejectTool) {
+				if (this.didRejectTool || this.didAlreadyUseTool) {
 					break
 					break
 				}
 				}
 				let content = block.content
 				let content = block.content
@@ -947,6 +948,15 @@ export class Cline {
 					break
 					break
 				}
 				}
 
 
+				if (this.didAlreadyUseTool) {
+					// ignore any content after a tool has already been used
+					this.userMessageContent.push({
+						type: "text",
+						text: `Tool [${block.name}] was not executed because a tool has already been used in this message. Only one tool may be used per message. You must assess the first tool's result before proceeding to use the next tool.`,
+					})
+					break
+				}
+
 				const pushToolResult = (content: ToolResponse) => {
 				const pushToolResult = (content: ToolResponse) => {
 					this.userMessageContent.push({
 					this.userMessageContent.push({
 						type: "text",
 						type: "text",
@@ -960,6 +970,8 @@ export class Cline {
 					} else {
 					} else {
 						this.userMessageContent.push(...content)
 						this.userMessageContent.push(...content)
 					}
 					}
+					// once a tool result has been collected, ignore all other tool uses since we should only ever present one tool result per message
+					this.didAlreadyUseTool = true
 				}
 				}
 
 
 				const askApproval = async (type: ClineAsk, partialMessage?: string) => {
 				const askApproval = async (type: ClineAsk, partialMessage?: string) => {
@@ -1064,16 +1076,18 @@ export class Cline {
 							newContent = newContent.split("\n").slice(0, -1).join("\n").trim()
 							newContent = newContent.split("\n").slice(0, -1).join("\n").trim()
 						}
 						}
 
 
-						// it seems not just llama models are doing this, but also gemini and potentially others
-						if (
-							newContent.includes("&gt;") ||
-							newContent.includes("&lt;") ||
-							newContent.includes("&quot;")
-						) {
-							newContent = newContent
-								.replace(/&gt;/g, ">")
-								.replace(/&lt;/g, "<")
-								.replace(/&quot;/g, '"')
+						if (!this.api.getModel().id.includes("claude")) {
+							// it seems not just llama models are doing this, but also gemini and potentially others
+							if (
+								newContent.includes("&gt;") ||
+								newContent.includes("&lt;") ||
+								newContent.includes("&quot;")
+							) {
+								newContent = newContent
+									.replace(/&gt;/g, ">")
+									.replace(/&lt;/g, "<")
+									.replace(/&quot;/g, '"')
+							}
 						}
 						}
 
 
 						const sharedMessageProps: ClineSayTool = {
 						const sharedMessageProps: ClineSayTool = {
@@ -1736,7 +1750,7 @@ export class Cline {
 		*/
 		*/
 		this.presentAssistantMessageLocked = false // this needs to be placed here, if not then calling this.presentAssistantMessage below would fail (sometimes) since it's locked
 		this.presentAssistantMessageLocked = false // this needs to be placed here, if not then calling this.presentAssistantMessage below would fail (sometimes) since it's locked
 		// NOTE: when tool is rejected, iterator stream is interrupted and it waits for userMessageContentReady to be true. Future calls to present will skip execution since didRejectTool and iterate until contentIndex is set to message length and it sets userMessageContentReady to true itself (instead of preemptively doing it in iterator)
 		// NOTE: when tool is rejected, iterator stream is interrupted and it waits for userMessageContentReady to be true. Future calls to present will skip execution since didRejectTool and iterate until contentIndex is set to message length and it sets userMessageContentReady to true itself (instead of preemptively doing it in iterator)
-		if (!block.partial || this.didRejectTool) {
+		if (!block.partial || this.didRejectTool || this.didAlreadyUseTool) {
 			// block is finished streaming and executing
 			// block is finished streaming and executing
 			if (this.currentStreamingContentIndex === this.assistantMessageContent.length - 1) {
 			if (this.currentStreamingContentIndex === this.assistantMessageContent.length - 1) {
 				// its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssitantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented.
 				// its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssitantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented.
@@ -1896,6 +1910,7 @@ export class Cline {
 			this.userMessageContent = []
 			this.userMessageContent = []
 			this.userMessageContentReady = false
 			this.userMessageContentReady = false
 			this.didRejectTool = false
 			this.didRejectTool = false
+			this.didAlreadyUseTool = false
 			this.presentAssistantMessageLocked = false
 			this.presentAssistantMessageLocked = false
 			this.presentAssistantMessageHasPendingUpdates = false
 			this.presentAssistantMessageHasPendingUpdates = false
 			await this.diffViewProvider.reset()
 			await this.diffViewProvider.reset()
@@ -1940,6 +1955,14 @@ export class Cline {
 						// this.userMessageContentReady = true // instead of setting this premptively, we allow the present iterator to finish and set userMessageContentReady when its ready
 						// this.userMessageContentReady = true // instead of setting this premptively, we allow the present iterator to finish and set userMessageContentReady when its ready
 						break
 						break
 					}
 					}
+
+					// PREV: we need to let the request finish for openrouter to get generation details
+					// UPDATE: it's better UX to interrupt the request at the cost of the api cost not being retrieved
+					if (this.didAlreadyUseTool) {
+						assistantMessage +=
+							"\n\n[Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.]"
+						break
+					}
 				}
 				}
 			} catch (error) {
 			} catch (error) {
 				// abandoned happens when extension is no longer waiting for the cline instance to finish aborting (error is thrown here when any function in the for loop throws due to this.abort)
 				// abandoned happens when extension is no longer waiting for the cline instance to finish aborting (error is thrown here when any function in the for loop throws due to this.abort)

+ 18 - 0
src/core/webview/ClineProvider.ts

@@ -40,6 +40,7 @@ type GlobalStateKey =
 	| "apiProvider"
 	| "apiProvider"
 	| "apiModelId"
 	| "apiModelId"
 	| "awsRegion"
 	| "awsRegion"
+	| "awsUseCrossRegionInference"
 	| "vertexProjectId"
 	| "vertexProjectId"
 	| "vertexRegion"
 	| "vertexRegion"
 	| "lastShownAnnouncementId"
 	| "lastShownAnnouncementId"
@@ -354,6 +355,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 								awsSecretKey,
 								awsSecretKey,
 								awsSessionToken,
 								awsSessionToken,
 								awsRegion,
 								awsRegion,
+								awsUseCrossRegionInference,
 								vertexProjectId,
 								vertexProjectId,
 								vertexRegion,
 								vertexRegion,
 								openAiBaseUrl,
 								openAiBaseUrl,
@@ -376,6 +378,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 							await this.storeSecret("awsSecretKey", awsSecretKey)
 							await this.storeSecret("awsSecretKey", awsSecretKey)
 							await this.storeSecret("awsSessionToken", awsSessionToken)
 							await this.storeSecret("awsSessionToken", awsSessionToken)
 							await this.updateGlobalState("awsRegion", awsRegion)
 							await this.updateGlobalState("awsRegion", awsRegion)
+							await this.updateGlobalState("awsUseCrossRegionInference", awsUseCrossRegionInference)
 							await this.updateGlobalState("vertexProjectId", vertexProjectId)
 							await this.updateGlobalState("vertexProjectId", vertexProjectId)
 							await this.updateGlobalState("vertexRegion", vertexRegion)
 							await this.updateGlobalState("vertexRegion", vertexRegion)
 							await this.updateGlobalState("openAiBaseUrl", openAiBaseUrl)
 							await this.updateGlobalState("openAiBaseUrl", openAiBaseUrl)
@@ -638,6 +641,18 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 							modelInfo.cacheWritesPrice = 3.75
 							modelInfo.cacheWritesPrice = 3.75
 							modelInfo.cacheReadsPrice = 0.3
 							modelInfo.cacheReadsPrice = 0.3
 							break
 							break
+						case "anthropic/claude-3-5-haiku":
+						case "anthropic/claude-3-5-haiku:beta":
+						case "anthropic/claude-3-5-haiku-20241022":
+						case "anthropic/claude-3-5-haiku-20241022:beta":
+						case "anthropic/claude-3.5-haiku":
+						case "anthropic/claude-3.5-haiku:beta":
+						case "anthropic/claude-3.5-haiku-20241022":
+						case "anthropic/claude-3.5-haiku-20241022:beta":
+							modelInfo.supportsPromptCache = true
+							modelInfo.cacheWritesPrice = 1.25
+							modelInfo.cacheReadsPrice = 0.1
+							break
 						case "anthropic/claude-3-opus":
 						case "anthropic/claude-3-opus":
 						case "anthropic/claude-3-opus:beta":
 						case "anthropic/claude-3-opus:beta":
 							modelInfo.supportsPromptCache = true
 							modelInfo.supportsPromptCache = true
@@ -832,6 +847,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			awsSecretKey,
 			awsSecretKey,
 			awsSessionToken,
 			awsSessionToken,
 			awsRegion,
 			awsRegion,
+			awsUseCrossRegionInference,
 			vertexProjectId,
 			vertexProjectId,
 			vertexRegion,
 			vertexRegion,
 			openAiBaseUrl,
 			openAiBaseUrl,
@@ -860,6 +876,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			this.getSecret("awsSecretKey") as Promise<string | undefined>,
 			this.getSecret("awsSecretKey") as Promise<string | undefined>,
 			this.getSecret("awsSessionToken") as Promise<string | undefined>,
 			this.getSecret("awsSessionToken") as Promise<string | undefined>,
 			this.getGlobalState("awsRegion") as Promise<string | undefined>,
 			this.getGlobalState("awsRegion") as Promise<string | undefined>,
+			this.getGlobalState("awsUseCrossRegionInference") as Promise<boolean | undefined>,
 			this.getGlobalState("vertexProjectId") as Promise<string | undefined>,
 			this.getGlobalState("vertexProjectId") as Promise<string | undefined>,
 			this.getGlobalState("vertexRegion") as Promise<string | undefined>,
 			this.getGlobalState("vertexRegion") as Promise<string | undefined>,
 			this.getGlobalState("openAiBaseUrl") as Promise<string | undefined>,
 			this.getGlobalState("openAiBaseUrl") as Promise<string | undefined>,
@@ -905,6 +922,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 				awsSecretKey,
 				awsSecretKey,
 				awsSessionToken,
 				awsSessionToken,
 				awsRegion,
 				awsRegion,
+				awsUseCrossRegionInference,
 				vertexProjectId,
 				vertexProjectId,
 				vertexRegion,
 				vertexRegion,
 				openAiBaseUrl,
 				openAiBaseUrl,

+ 35 - 0
src/shared/api.ts

@@ -19,6 +19,7 @@ export interface ApiHandlerOptions {
 	awsSecretKey?: string
 	awsSecretKey?: string
 	awsSessionToken?: string
 	awsSessionToken?: string
 	awsRegion?: string
 	awsRegion?: string
+	awsUseCrossRegionInference?: boolean
 	vertexProjectId?: string
 	vertexProjectId?: string
 	vertexRegion?: string
 	vertexRegion?: string
 	openAiBaseUrl?: string
 	openAiBaseUrl?: string
@@ -66,6 +67,16 @@ export const anthropicModels = {
 		cacheWritesPrice: 3.75, // $3.75 per million tokens
 		cacheWritesPrice: 3.75, // $3.75 per million tokens
 		cacheReadsPrice: 0.3, // $0.30 per million tokens
 		cacheReadsPrice: 0.3, // $0.30 per million tokens
 	},
 	},
+	"claude-3-5-haiku-20241022": {
+		maxTokens: 8192,
+		contextWindow: 200_000,
+		supportsImages: false,
+		supportsPromptCache: true,
+		inputPrice: 1.0,
+		outputPrice: 5.0,
+		cacheWritesPrice: 1.25,
+		cacheReadsPrice: 0.1,
+	},
 	"claude-3-opus-20240229": {
 	"claude-3-opus-20240229": {
 		maxTokens: 4096,
 		maxTokens: 4096,
 		contextWindow: 200_000,
 		contextWindow: 200_000,
@@ -102,6 +113,14 @@ export const bedrockModels = {
 		inputPrice: 3.0,
 		inputPrice: 3.0,
 		outputPrice: 15.0,
 		outputPrice: 15.0,
 	},
 	},
+	"anthropic.claude-3-5-haiku-20241022-v1:0": {
+		maxTokens: 8192,
+		contextWindow: 200_000,
+		supportsImages: false,
+		supportsPromptCache: false,
+		inputPrice: 1.0,
+		outputPrice: 5.0,
+	},
 	"anthropic.claude-3-5-sonnet-20240620-v1:0": {
 	"anthropic.claude-3-5-sonnet-20240620-v1:0": {
 		maxTokens: 8192,
 		maxTokens: 8192,
 		contextWindow: 200_000,
 		contextWindow: 200_000,
@@ -118,6 +137,14 @@ export const bedrockModels = {
 		inputPrice: 15.0,
 		inputPrice: 15.0,
 		outputPrice: 75.0,
 		outputPrice: 75.0,
 	},
 	},
+	"anthropic.claude-3-sonnet-20240229-v1:0": {
+		maxTokens: 4096,
+		contextWindow: 200_000,
+		supportsImages: true,
+		supportsPromptCache: false,
+		inputPrice: 3.0,
+		outputPrice: 15.0,
+	},
 	"anthropic.claude-3-haiku-20240307-v1:0": {
 	"anthropic.claude-3-haiku-20240307-v1:0": {
 		maxTokens: 4096,
 		maxTokens: 4096,
 		contextWindow: 200_000,
 		contextWindow: 200_000,
@@ -167,6 +194,14 @@ export const vertexModels = {
 		inputPrice: 3.0,
 		inputPrice: 3.0,
 		outputPrice: 15.0,
 		outputPrice: 15.0,
 	},
 	},
+	"claude-3-5-haiku@20241022": {
+		maxTokens: 8192,
+		contextWindow: 200_000,
+		supportsImages: false,
+		supportsPromptCache: false,
+		inputPrice: 1.0,
+		outputPrice: 5.0,
+	},
 	"claude-3-opus@20240229": {
 	"claude-3-opus@20240229": {
 		maxTokens: 4096,
 		maxTokens: 4096,
 		contextWindow: 200_000,
 		contextWindow: 200_000,

+ 12 - 2
webview-ui/src/components/settings/ApiOptions.tsx

@@ -284,14 +284,14 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:
 							<VSCodeOption value="">Select a region...</VSCodeOption>
 							<VSCodeOption value="">Select a region...</VSCodeOption>
 							{/* The user will have to choose a region that supports the model they use, but this shouldn't be a problem since they'd have to request access for it in that region in the first place. */}
 							{/* The user will have to choose a region that supports the model they use, but this shouldn't be a problem since they'd have to request access for it in that region in the first place. */}
 							<VSCodeOption value="us-east-1">us-east-1</VSCodeOption>
 							<VSCodeOption value="us-east-1">us-east-1</VSCodeOption>
-							{/* <VSCodeOption value="us-east-2">us-east-2</VSCodeOption> */}
+							<VSCodeOption value="us-east-2">us-east-2</VSCodeOption>
 							{/* <VSCodeOption value="us-west-1">us-west-1</VSCodeOption> */}
 							{/* <VSCodeOption value="us-west-1">us-west-1</VSCodeOption> */}
 							<VSCodeOption value="us-west-2">us-west-2</VSCodeOption>
 							<VSCodeOption value="us-west-2">us-west-2</VSCodeOption>
 							{/* <VSCodeOption value="af-south-1">af-south-1</VSCodeOption> */}
 							{/* <VSCodeOption value="af-south-1">af-south-1</VSCodeOption> */}
 							{/* <VSCodeOption value="ap-east-1">ap-east-1</VSCodeOption> */}
 							{/* <VSCodeOption value="ap-east-1">ap-east-1</VSCodeOption> */}
 							<VSCodeOption value="ap-south-1">ap-south-1</VSCodeOption>
 							<VSCodeOption value="ap-south-1">ap-south-1</VSCodeOption>
 							<VSCodeOption value="ap-northeast-1">ap-northeast-1</VSCodeOption>
 							<VSCodeOption value="ap-northeast-1">ap-northeast-1</VSCodeOption>
-							{/* <VSCodeOption value="ap-northeast-2">ap-northeast-2</VSCodeOption> */}
+							<VSCodeOption value="ap-northeast-2">ap-northeast-2</VSCodeOption>
 							{/* <VSCodeOption value="ap-northeast-3">ap-northeast-3</VSCodeOption> */}
 							{/* <VSCodeOption value="ap-northeast-3">ap-northeast-3</VSCodeOption> */}
 							<VSCodeOption value="ap-southeast-1">ap-southeast-1</VSCodeOption>
 							<VSCodeOption value="ap-southeast-1">ap-southeast-1</VSCodeOption>
 							<VSCodeOption value="ap-southeast-2">ap-southeast-2</VSCodeOption>
 							<VSCodeOption value="ap-southeast-2">ap-southeast-2</VSCodeOption>
@@ -303,8 +303,18 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:
 							{/* <VSCodeOption value="eu-north-1">eu-north-1</VSCodeOption> */}
 							{/* <VSCodeOption value="eu-north-1">eu-north-1</VSCodeOption> */}
 							{/* <VSCodeOption value="me-south-1">me-south-1</VSCodeOption> */}
 							{/* <VSCodeOption value="me-south-1">me-south-1</VSCodeOption> */}
 							<VSCodeOption value="sa-east-1">sa-east-1</VSCodeOption>
 							<VSCodeOption value="sa-east-1">sa-east-1</VSCodeOption>
+							<VSCodeOption value="us-gov-west-1">us-gov-west-1</VSCodeOption>
+							{/* <VSCodeOption value="us-gov-east-1">us-gov-east-1</VSCodeOption> */}
 						</VSCodeDropdown>
 						</VSCodeDropdown>
 					</div>
 					</div>
+					<VSCodeCheckbox
+						checked={apiConfiguration?.awsUseCrossRegionInference || false}
+						onChange={(e: any) => {
+							const isChecked = e.target.checked === true
+							setApiConfiguration({ ...apiConfiguration, awsUseCrossRegionInference: isChecked })
+						}}>
+						Use cross-region inference
+					</VSCodeCheckbox>
 					<p
 					<p
 						style={{
 						style={{
 							fontSize: "12px",
 							fontSize: "12px",

+ 2 - 2
webview-ui/src/components/settings/SettingsView.tsx

@@ -131,8 +131,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
 							marginTop: "5px",
 							marginTop: "5px",
 							color: "var(--vscode-descriptionForeground)",
 							color: "var(--vscode-descriptionForeground)",
 						}}>
 						}}>
-						When enabled, Cline will automatically read files, view directories, and inspect sites without
-						requiring you to click the Approve button.
+						When enabled, Cline will automatically view directory contents and read files without requiring
+						you to click the Approve button.
 					</p>
 					</p>
 				</div>
 				</div>