From 5adf96dc82b90474ab8455bcbba2dac072747863 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:26:04 -0400 Subject: [PATCH 01/18] Fixes --- src/core/Cline.ts | 22 ++++++++++--------- .../src/components/settings/SettingsView.tsx | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 6e0a0db..c63a704 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1032,16 +1032,18 @@ export class Cline { 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(">") || - newContent.includes("<") || - newContent.includes(""") - ) { - newContent = newContent - .replace(/>/g, ">") - .replace(/</g, "<") - .replace(/"/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(">") || + newContent.includes("<") || + newContent.includes(""") + ) { + newContent = newContent + .replace(/>/g, ">") + .replace(/</g, "<") + .replace(/"/g, '"') + } } const sharedMessageProps: ClineSayTool = { diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index ca14435..ad7ff80 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -125,8 +125,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { marginTop: "5px", 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.

From efacc1a83af146f9ee2b0c27bd7082d43f3a5948 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:11:43 -0400 Subject: [PATCH 02/18] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 28a1e7a..d12693a 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,13 @@ All changes made by Cline are recorded in your file's Timeline, providing an eas
- + -### 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 functions as expected. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989) From d8d5fcca37eee4c03253011de0f6e30f0bfc6f4a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:13:08 -0400 Subject: [PATCH 03/18] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d12693a..866d447 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ All changes made by Cline are recorded in your file's Timeline, providing an eas 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. -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 functions as expected. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989) +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 as expected. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989) From 3c6a550ecfcc62413205890b414244d11a60f975 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:14:09 -0400 Subject: [PATCH 04/18] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 866d447..d323284 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ All changes made by Cline are recorded in your file's Timeline, providing an eas 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. -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 as expected. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989) +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) From ac66cb89c0d2b76a3f50e7ab68513280740fa347 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 31 Oct 2024 23:17:56 -0400 Subject: [PATCH 05/18] Prepare for release --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f37d59b..e7d30f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [2.1.2] + +- Misc. bug fixes +- Update README with new browser feature + ## [2.1.1] - Add stricter prompt to prevent Cline from editing files during a browser session without first closing the browser diff --git a/package.json b/package.json index 6ae3bf6..7b6e605 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "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": "2.1.1", + "version": "2.1.2", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 48cdfa98742310717ca99e8e1f8302023dc539c2 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:08:25 -0500 Subject: [PATCH 06/18] Add Haiku 3.5 to Anthropic, Bedrock, Vertex --- src/api/providers/anthropic.ts | 8 +++----- src/shared/api.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 62dfeb0..5014ec8 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -28,6 +28,7 @@ export class AnthropicHandler implements ApiHandler { switch (modelId) { // 'latest' alias does not support cache_control case "claude-3-5-sonnet-20241022": + case "claude-3-5-haiku-20241022": case "claude-3-opus-20240229": case "claude-3-haiku-20240307": { /* @@ -78,11 +79,8 @@ export class AnthropicHandler implements ApiHandler { // https://github.com/anthropics/anthropic-sdk-typescript/commit/c920b77fc67bd839bfeb6716ceab9d7c9bbe7393 switch (modelId) { 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": return { headers: { "anthropic-beta": "prompt-caching-2024-07-31" }, diff --git a/src/shared/api.ts b/src/shared/api.ts index ff3a84d..721e669 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -66,6 +66,16 @@ export const anthropicModels = { cacheWritesPrice: 3.75, // $3.75 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": { maxTokens: 4096, contextWindow: 200_000, @@ -102,6 +112,14 @@ export const bedrockModels = { inputPrice: 3.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": { maxTokens: 8192, contextWindow: 200_000, @@ -167,6 +185,14 @@ export const vertexModels = { inputPrice: 3.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": { maxTokens: 4096, contextWindow: 200_000, From c54c6d82f5e7c7bf1c063b66082667f0ed93eaf1 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:30:26 -0500 Subject: [PATCH 07/18] Add didAlreadyUseTool flag to prevent multiple tools from being called to mitigate haiku 3.5 hallucinations --- src/core/Cline.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c63a704..0bb5c5c 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -86,6 +86,7 @@ export class Cline { private userMessageContent: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = [] private userMessageContentReady = false private didRejectTool = false + private didAlreadyUseTool = false private didCompleteReadingStream = false constructor( @@ -828,7 +829,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 switch (block.type) { case "text": { - if (this.didRejectTool) { + if (this.didRejectTool || this.didAlreadyUseTool) { break } let content = block.content @@ -915,6 +916,15 @@ export class Cline { 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) => { this.userMessageContent.push({ type: "text", @@ -928,6 +938,8 @@ export class Cline { } else { 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) => { @@ -1692,7 +1704,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 // 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 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. @@ -1852,6 +1864,7 @@ export class Cline { this.userMessageContent = [] this.userMessageContentReady = false this.didRejectTool = false + this.didAlreadyUseTool = false this.presentAssistantMessageLocked = false this.presentAssistantMessageHasPendingUpdates = false await this.diffViewProvider.reset() @@ -1896,6 +1909,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 break } + + // we need to let the request finish for openrouter to get generation details + // if (this.didAlreadyUseTool) { + // // a tool has been called, so interrupt the assistant's response to present the user's feedback + // assistantMessage += + // "\n\n[Response interrupted by a tool use. Only one tool may be used per message.]" + // break + // } } } 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) From 69ba0c833e266d5962483e8125bf1f5c67da449b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:36:45 -0500 Subject: [PATCH 08/18] Interrupt API request if user executes tool --- src/core/Cline.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 0bb5c5c..a587dd9 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1910,13 +1910,13 @@ export class Cline { break } - // we need to let the request finish for openrouter to get generation details - // if (this.didAlreadyUseTool) { - // // a tool has been called, so interrupt the assistant's response to present the user's feedback - // assistantMessage += - // "\n\n[Response interrupted by a tool use. Only one tool may be used per message.]" - // 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) { // 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) From d1a43fa43ebdc046d79cd37d29f28ec870b4f4cc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:44:52 -0500 Subject: [PATCH 09/18] Add cache details for OpenRouter Haiku 3.5 --- src/core/webview/ClineProvider.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index a999bef..6f19138 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -620,6 +620,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 3.75 modelInfo.cacheReadsPrice = 0.3 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:beta": modelInfo.supportsPromptCache = true From d06b85b9fccffb5f81766e62f34b8cd4f79995c7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:48:38 -0500 Subject: [PATCH 10/18] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d30f3..b7ced78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [2.1.3] + +- Add support for Claude 3.5 Haiku, 66% cheaper than Sonnet with similar intelligence + ## [2.1.2] - Misc. bug fixes diff --git a/package.json b/package.json index 7b6e605..4ce8282 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "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": "2.1.2", + "version": "2.1.3", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From e0f92d29857cea85c1d6b158232e1d9bfc404c02 Mon Sep 17 00:00:00 2001 From: Adam Hesch Date: Thu, 7 Nov 2024 11:52:50 -0600 Subject: [PATCH 11/18] Fix: Add support for additional AWS Bedrock regions (#693) Added support for additional supported AWS regions per https://docs.aws.amazon.com/general/latest/gr/bedrock.html#bedrock_region --- webview-ui/src/components/settings/ApiOptions.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index d1475f7..7e0fbef 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -284,14 +284,14 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: Select a region... {/* 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. */} us-east-1 - {/* us-east-2 */} + us-east-2 {/* us-west-1 */} us-west-2 {/* af-south-1 */} {/* ap-east-1 */} ap-south-1 ap-northeast-1 - {/* ap-northeast-2 */} + ap-northeast-2 {/* ap-northeast-3 */} ap-southeast-1 ap-southeast-2 @@ -303,6 +303,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {/* eu-north-1 */} {/* me-south-1 */} sa-east-1 + us-gov-west-1 + {/* us-gov-east-1 */}

Date: Fri, 8 Nov 2024 04:57:03 +1100 Subject: [PATCH 12/18] Fix: Add missing sonnet model to bedrock (#633) --- src/shared/api.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/shared/api.ts b/src/shared/api.ts index 721e669..a466972 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -136,6 +136,14 @@ export const bedrockModels = { inputPrice: 15.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": { maxTokens: 4096, contextWindow: 200_000, From ad29ff2a03ddfd94249f4901826a7f1b02692f57 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:51:13 -0500 Subject: [PATCH 13/18] Add AWS cross-region inference toggle --- src/api/providers/bedrock.ts | 22 ++++++++++++++++++- src/core/webview/ClineProvider.ts | 6 +++++ src/shared/api.ts | 1 + .../src/components/settings/ApiOptions.tsx | 8 +++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index ad6e8df..58f75ad 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -25,8 +25,28 @@ export class AwsBedrockHandler implements ApiHandler { } 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({ - model: this.getModel().id, + model: modelId, max_tokens: this.getModel().info.maxTokens || 8192, temperature: 0, system: systemPrompt, diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 6f19138..6d24ce8 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -40,6 +40,7 @@ type GlobalStateKey = | "apiProvider" | "apiModelId" | "awsRegion" + | "awsUseCrossRegionInference" | "vertexProjectId" | "vertexRegion" | "lastShownAnnouncementId" @@ -350,6 +351,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { awsSecretKey, awsSessionToken, awsRegion, + awsUseCrossRegionInference, vertexProjectId, vertexRegion, openAiBaseUrl, @@ -372,6 +374,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.storeSecret("awsSecretKey", awsSecretKey) await this.storeSecret("awsSessionToken", awsSessionToken) await this.updateGlobalState("awsRegion", awsRegion) + await this.updateGlobalState("awsUseCrossRegionInference", awsUseCrossRegionInference) await this.updateGlobalState("vertexProjectId", vertexProjectId) await this.updateGlobalState("vertexRegion", vertexRegion) await this.updateGlobalState("openAiBaseUrl", openAiBaseUrl) @@ -824,6 +827,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { awsSecretKey, awsSessionToken, awsRegion, + awsUseCrossRegionInference, vertexProjectId, vertexRegion, openAiBaseUrl, @@ -850,6 +854,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getSecret("awsSecretKey") as Promise, this.getSecret("awsSessionToken") as Promise, this.getGlobalState("awsRegion") as Promise, + this.getGlobalState("awsUseCrossRegionInference") as Promise, this.getGlobalState("vertexProjectId") as Promise, this.getGlobalState("vertexRegion") as Promise, this.getGlobalState("openAiBaseUrl") as Promise, @@ -893,6 +898,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { awsSecretKey, awsSessionToken, awsRegion, + awsUseCrossRegionInference, vertexProjectId, vertexRegion, openAiBaseUrl, diff --git a/src/shared/api.ts b/src/shared/api.ts index a466972..b2c5525 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -19,6 +19,7 @@ export interface ApiHandlerOptions { awsSecretKey?: string awsSessionToken?: string awsRegion?: string + awsUseCrossRegionInference?: boolean vertexProjectId?: string vertexRegion?: string openAiBaseUrl?: string diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 7e0fbef..f5e44ca 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -307,6 +307,14 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {/* us-gov-east-1 */} + { + const isChecked = e.target.checked === true + setApiConfiguration({ ...apiConfiguration, awsUseCrossRegionInference: isChecked }) + }}> + Use cross-region inference +

Date: Thu, 7 Nov 2024 13:54:38 -0500 Subject: [PATCH 14/18] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ced78..83a83f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # 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 diff --git a/package.json b/package.json index 4ce8282..f00b52e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "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": "2.1.3", + "version": "2.1.4", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From ff725d35ff081f8c0a102d9dcf4618d892d8a440 Mon Sep 17 00:00:00 2001 From: Mark Percival Date: Thu, 7 Nov 2024 16:35:50 -0800 Subject: [PATCH 15/18] Chore: Update README.md to mention git-lfs requirement (#698) The cline repo will fail to clone without git-lfs, as demo.gif is a pointer. This leaves the user with a incomplete cloned repository. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d323284..45aff0f 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ To contribute to the project, start by exploring [open issues](https://github.co

Local Development Instructions -1. Clone the repository: +1. Clone the repository *(Requires [git-lfs](https://git-lfs.com/))*: ```bash git clone https://github.com/cline/cline.git ``` From bac0b1a0cbf44f936b0afe794f5ee035101cb06e Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:35:51 -0500 Subject: [PATCH 16/18] Add prompt caching for new model ids on openrouter --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/api/providers/openrouter.ts | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83a83f1..2e0b3d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [2.1.5] + +- Add support for prompt caching for new Claude model IDs on OpenRouter (e.g. `anthropic/claude-3.5-sonnet-20240620`) + ## [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) diff --git a/package.json b/package.json index f00b52e..ed79817 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "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": "2.1.4", + "version": "2.1.5", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 2227c3e..93bbaba 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -31,9 +31,19 @@ export class OpenRouterHandler implements ApiHandler { ] // prompt caching: https://openrouter.ai/docs/prompt-caching + // this is specifically for claude models (some models may 'support prompt caching' automatically without this) switch (this.getModel().id) { + case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": + case "anthropic/claude-3.5-sonnet-20240620": + case "anthropic/claude-3.5-sonnet-20240620: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": + case "anthropic/claude-3-haiku": case "anthropic/claude-3-haiku:beta": + case "anthropic/claude-3-opus": case "anthropic/claude-3-opus:beta": openAiMessages[0] = { role: "system", @@ -76,6 +86,12 @@ export class OpenRouterHandler implements ApiHandler { switch (this.getModel().id) { case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": + case "anthropic/claude-3.5-sonnet-20240620": + case "anthropic/claude-3.5-sonnet-20240620: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": maxTokens = 8_192 break } From 39bc35eec1ba83355b5c96363a7bb833a1b1bb61 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:02:42 -0500 Subject: [PATCH 17/18] Add LM Studio provider --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + README.md | 4 +- src/api/index.ts | 3 + src/api/providers/lmstudio.ts | 56 +++++++++++ src/core/webview/ClineProvider.ts | 35 +++++++ src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 1 + src/shared/api.ts | 3 + webview-ui/src/components/chat/TaskHeader.tsx | 1 + .../src/components/settings/ApiOptions.tsx | 96 +++++++++++++++++-- .../src/context/ExtensionStateContext.tsx | 1 + webview-ui/src/utils/validate.ts | 5 + 12 files changed, 199 insertions(+), 9 deletions(-) create mode 100644 src/api/providers/lmstudio.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bf95687..eb61061 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -15,6 +15,7 @@ body: - AWS Bedrock - OpenAI - OpenAI Compatible + - LM Studio - Ollama validations: required: true diff --git a/README.md b/README.md index 45aff0f..6fa1a76 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.ant ### Use any API and Model -Cline supports API providers like OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, and GCP Vertex. You can also configure any OpenAI compatible API, or use a local model through Ollama. If you're using OpenRouter, the extension fetches their latest model list, allowing you to use the newest models as soon as they're available. +Cline supports API providers like OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, and GCP Vertex. You can also configure any OpenAI compatible API, or use a local model through LM Studio/Ollama. If you're using OpenRouter, the extension fetches their latest model list, allowing you to use the newest models as soon as they're available. The extension also keeps track of total tokens and API usage cost for the entire task loop and individual requests, keeping you informed of spend every step of the way. @@ -104,7 +104,7 @@ To contribute to the project, start by exploring [open issues](https://github.co
Local Development Instructions -1. Clone the repository *(Requires [git-lfs](https://git-lfs.com/))*: +1. Clone the repository _(Requires [git-lfs](https://git-lfs.com/))_: ```bash git clone https://github.com/cline/cline.git ``` diff --git a/src/api/index.ts b/src/api/index.ts index 388b9ce..ec35c2a 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -6,6 +6,7 @@ import { OpenRouterHandler } from "./providers/openrouter" import { VertexHandler } from "./providers/vertex" import { OpenAiHandler } from "./providers/openai" import { OllamaHandler } from "./providers/ollama" +import { LmStudioHandler } from "./providers/lmstudio" import { GeminiHandler } from "./providers/gemini" import { OpenAiNativeHandler } from "./providers/openai-native" import { ApiStream } from "./transform/stream" @@ -30,6 +31,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new OpenAiHandler(options) case "ollama": return new OllamaHandler(options) + case "lmstudio": + return new LmStudioHandler(options) case "gemini": return new GeminiHandler(options) case "openai-native": diff --git a/src/api/providers/lmstudio.ts b/src/api/providers/lmstudio.ts new file mode 100644 index 0000000..1c085f7 --- /dev/null +++ b/src/api/providers/lmstudio.ts @@ -0,0 +1,56 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" +import { ApiHandler } from "../" +import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" +import { convertToOpenAiMessages } from "../transform/openai-format" +import { ApiStream } from "../transform/stream" + +export class LmStudioHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: OpenAI + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new OpenAI({ + baseURL: (this.options.lmStudioBaseUrl || "http://localhost:1234") + "/v1", + apiKey: "noop", + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ] + + try { + const stream = await this.client.chat.completions.create({ + model: this.getModel().id, + messages: openAiMessages, + temperature: 0, + stream: true, + }) + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + } + } catch (error) { + // LM Studio doesn't return an error code/body for now + throw new Error( + "Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Cline's prompts." + ) + } + } + + getModel(): { id: string; info: ModelInfo } { + return { + id: this.options.lmStudioModelId || "", + info: openAiModelInfoSaneDefaults, + } + } +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 6d24ce8..2642d10 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -51,6 +51,8 @@ type GlobalStateKey = | "openAiModelId" | "ollamaModelId" | "ollamaBaseUrl" + | "lmStudioModelId" + | "lmStudioBaseUrl" | "anthropicBaseUrl" | "azureApiVersion" | "openRouterModelId" @@ -359,6 +361,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { openAiModelId, ollamaModelId, ollamaBaseUrl, + lmStudioModelId, + lmStudioBaseUrl, anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, @@ -382,6 +386,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("openAiModelId", openAiModelId) await this.updateGlobalState("ollamaModelId", ollamaModelId) await this.updateGlobalState("ollamaBaseUrl", ollamaBaseUrl) + await this.updateGlobalState("lmStudioModelId", lmStudioModelId) + await this.updateGlobalState("lmStudioBaseUrl", lmStudioBaseUrl) await this.updateGlobalState("anthropicBaseUrl", anthropicBaseUrl) await this.storeSecret("geminiApiKey", geminiApiKey) await this.storeSecret("openAiNativeApiKey", openAiNativeApiKey) @@ -442,6 +448,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { const ollamaModels = await this.getOllamaModels(message.text) this.postMessageToWebview({ type: "ollamaModels", ollamaModels }) break + case "requestLmStudioModels": + const lmStudioModels = await this.getLmStudioModels(message.text) + this.postMessageToWebview({ type: "lmStudioModels", lmStudioModels }) + break case "refreshOpenRouterModels": await this.refreshOpenRouterModels() break @@ -509,6 +519,25 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + // LM Studio + + async getLmStudioModels(baseUrl?: string) { + try { + if (!baseUrl) { + baseUrl = "http://localhost:1234" + } + if (!URL.canParse(baseUrl)) { + return [] + } + const response = await axios.get(`${baseUrl}/v1/models`) + const modelsArray = response.data?.data?.map((model: any) => model.id) || [] + const models = [...new Set(modelsArray)] + return models + } catch (error) { + return [] + } + } + // OpenRouter async handleOpenRouterCallback(code: string) { @@ -835,6 +864,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { openAiModelId, ollamaModelId, ollamaBaseUrl, + lmStudioModelId, + lmStudioBaseUrl, anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, @@ -862,6 +893,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("openAiModelId") as Promise, this.getGlobalState("ollamaModelId") as Promise, this.getGlobalState("ollamaBaseUrl") as Promise, + this.getGlobalState("lmStudioModelId") as Promise, + this.getGlobalState("lmStudioBaseUrl") as Promise, this.getGlobalState("anthropicBaseUrl") as Promise, this.getSecret("geminiApiKey") as Promise, this.getSecret("openAiNativeApiKey") as Promise, @@ -906,6 +939,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { openAiModelId, ollamaModelId, ollamaBaseUrl, + lmStudioModelId, + lmStudioBaseUrl, anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 777f52b..27a8a34 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -10,6 +10,7 @@ export interface ExtensionMessage { | "state" | "selectedImages" | "ollamaModels" + | "lmStudioModels" | "theme" | "workspaceUpdated" | "invoke" @@ -21,6 +22,7 @@ export interface ExtensionMessage { state?: ExtensionState images?: string[] ollamaModels?: string[] + lmStudioModels?: string[] filePaths?: string[] partialMessage?: ClineMessage openRouterModels?: Record diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 723efff..203ef13 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -17,6 +17,7 @@ export interface WebviewMessage { | "exportTaskWithId" | "resetState" | "requestOllamaModels" + | "requestLmStudioModels" | "openImage" | "openFile" | "openMention" diff --git a/src/shared/api.ts b/src/shared/api.ts index b2c5525..11bfd9f 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -5,6 +5,7 @@ export type ApiProvider = | "vertex" | "openai" | "ollama" + | "lmstudio" | "gemini" | "openai-native" @@ -27,6 +28,8 @@ export interface ApiHandlerOptions { openAiModelId?: string ollamaModelId?: string ollamaBaseUrl?: string + lmStudioModelId?: string + lmStudioBaseUrl?: string geminiApiKey?: string openAiNativeApiKey?: string azureApiVersion?: string diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 1c8e309..0b3f494 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -96,6 +96,7 @@ const TaskHeader: React.FC = ({ return ( apiConfiguration?.apiProvider !== "openai" && apiConfiguration?.apiProvider !== "ollama" && + apiConfiguration?.apiProvider !== "lmstudio" && apiConfiguration?.apiProvider !== "gemini" ) }, [apiConfiguration?.apiProvider]) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index f5e44ca..dbbda7d 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -45,6 +45,7 @@ interface ApiOptionsProps { const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) + const [lmStudioModels, setLmStudioModels] = useState([]) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) @@ -57,23 +58,27 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: return normalizeApiConfiguration(apiConfiguration) }, [apiConfiguration]) - // Poll ollama models - const requestOllamaModels = useCallback(() => { + // Poll ollama/lmstudio models + const requestLocalModels = useCallback(() => { if (selectedProvider === "ollama") { vscode.postMessage({ type: "requestOllamaModels", text: apiConfiguration?.ollamaBaseUrl }) + } else if (selectedProvider === "lmstudio") { + vscode.postMessage({ type: "requestLmStudioModels", text: apiConfiguration?.lmStudioBaseUrl }) } - }, [selectedProvider, apiConfiguration?.ollamaBaseUrl]) + }, [selectedProvider, apiConfiguration?.ollamaBaseUrl, apiConfiguration?.lmStudioBaseUrl]) useEffect(() => { - if (selectedProvider === "ollama") { - requestOllamaModels() + if (selectedProvider === "ollama" || selectedProvider === "lmstudio") { + requestLocalModels() } - }, [selectedProvider, requestOllamaModels]) - useInterval(requestOllamaModels, selectedProvider === "ollama" ? 2000 : null) + }, [selectedProvider, requestLocalModels]) + useInterval(requestLocalModels, selectedProvider === "ollama" || selectedProvider === "lmstudio" ? 2000 : null) const handleMessage = useCallback((event: MessageEvent) => { const message: ExtensionMessage = event.data if (message.type === "ollamaModels" && message.ollamaModels) { setOllamaModels(message.ollamaModels) + } else if (message.type === "lmStudioModels" && message.lmStudioModels) { + setLmStudioModels(message.lmStudioModels) } }, []) useEvent("message", handleMessage) @@ -128,6 +133,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: AWS Bedrock OpenAI OpenAI Compatible + LM Studio Ollama @@ -463,6 +469,75 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: )} + {selectedProvider === "lmstudio" && ( +
+ + Base URL (optional) + + + Model ID + + {lmStudioModels.length > 0 && ( + { + const value = (e.target as HTMLInputElement)?.value + // need to check value first since radio group returns empty string sometimes + if (value) { + handleInputChange("lmStudioModelId")({ + target: { value }, + }) + } + }}> + {lmStudioModels.map((model) => ( + + {model} + + ))} + + )} +

+ LM Studio allows you to run models locally on your computer. For instructions on how to get + started, see their + + quickstart guide. + + You will also need to start LM Studio's{" "} + + local server + {" "} + feature to use it with this extension.{" "} + + (Note: Cline uses complex prompts and works best + with Claude models. Less capable models may not work as expected.) + +

+
+ )} + {selectedProvider === "ollama" && (
@@ -758,6 +834,12 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { selectedModelId: apiConfiguration?.ollamaModelId || "", selectedModelInfo: openAiModelInfoSaneDefaults, } + case "lmstudio": + return { + selectedProvider: provider, + selectedModelId: apiConfiguration?.lmStudioModelId || "", + selectedModelInfo: openAiModelInfoSaneDefaults, + } default: return getProviderData(anthropicModels, anthropicDefaultModelId) } diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 16206ae..5409dd6 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -54,6 +54,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode config.vertexProjectId, config.openAiApiKey, config.ollamaModelId, + config.lmStudioModelId, config.geminiApiKey, config.openAiNativeApiKey, ].some((key) => key !== undefined) diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 060e0f6..df21fb1 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -47,6 +47,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid model ID." } break + case "lmstudio": + if (!apiConfiguration.lmStudioModelId) { + return "You must provide a valid model ID." + } + break } } return undefined From 0d256239f37a556ec7230da4e4f217c2c90dcd3c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:05:15 -0500 Subject: [PATCH 18/18] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e0b3d2..23d91dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [2.1.6] + +- Add LM Studio as an API provider option (make sure to start the LM Studio server to use it with the extension!) + ## [2.1.5] - Add support for prompt caching for new Claude model IDs on OpenRouter (e.g. `anthropic/claude-3.5-sonnet-20240620`) diff --git a/package.json b/package.json index ed79817..8aadd1a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "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": "2.1.5", + "version": "2.1.6", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91",