mirror of
https://github.com/cline/cline.git
synced 2026-09-16 21:01:52 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92478b823d | ||
|
|
1d4cd3187b | ||
|
|
32f0f9618c | ||
|
|
3001f883c2 | ||
|
|
a64e60b8f6 | ||
|
|
3a0e6a471b | ||
|
|
c10f4e0a66 | ||
|
|
3e11271cf8 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
feat: Added Claude Opus 4.1 to Bedrock
|
||||
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## [3.20.13]
|
||||
|
||||
- Fix prompt caching support for Opus 4.1 on OpenRouter/Cline
|
||||
|
||||
## [3.20.12]
|
||||
|
||||
- Add Claude Opus 4.1 model support to AWS Bedrock provider (Thanks @omercelik!)
|
||||
- Fix prompt caching and extended thinking support for Claude Opus 4.1 in Anthropic provider
|
||||
|
||||
## [3.20.11]
|
||||
|
||||
Add gpt-oss-120b as a Cerebras model
|
||||
|
||||
@@ -16,6 +16,7 @@ description: "Learn how to configure and use Anthropic Claude models with Cline.
|
||||
|
||||
Cline supports the following Anthropic Claude models:
|
||||
|
||||
- `claude-opus-4-1-20250805`
|
||||
- `claude-opus-4-20250514`
|
||||
- `claude-opus-4-20250514:thinking` (Extended Thinking variant)
|
||||
- `claude-sonnet-4-20250514` (Recommended)
|
||||
|
||||
@@ -52,6 +52,7 @@ If you're not sure where Claude Code is installed:
|
||||
The Claude Code provider supports these models:
|
||||
|
||||
- `claude-sonnet-4-20250514` (Recommended)
|
||||
- `claude-opus-4-1-20250805`
|
||||
- `claude-opus-4-20250514`
|
||||
- `claude-3-7-sonnet-20250219`
|
||||
- `claude-3-5-sonnet-20241022`
|
||||
|
||||
Generated
+85
-15
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "claude-dev",
|
||||
"version": "3.20.11",
|
||||
"version": "3.20.12",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "claude-dev",
|
||||
"version": "3.20.11",
|
||||
"version": "3.20.12",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.37.0",
|
||||
@@ -30,6 +30,7 @@
|
||||
"@playwright/test": "^1.53.2",
|
||||
"@sentry/browser": "^9.12.0",
|
||||
"@streamparser/json": "^0.0.22",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vscode/codicons": "^0.0.36",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.8.2",
|
||||
@@ -74,6 +75,7 @@
|
||||
"tree-sitter-wasms": "^0.1.11",
|
||||
"ts-morph": "^25.0.1",
|
||||
"turndown": "^7.2.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vscode-uri": "^3.1.0",
|
||||
"web-tree-sitter": "^0.22.6",
|
||||
"zod": "^3.24.2"
|
||||
@@ -439,12 +441,31 @@
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@types/uuid": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@aws-sdk/client-bedrock-runtime/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/@aws-sdk/client-bedrock-runtime/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-cognito-identity": {
|
||||
"version": "3.840.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.840.0.tgz",
|
||||
@@ -4981,6 +5002,19 @@
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/@smithy/middleware-retry/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@smithy/middleware-serde": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.8.tgz",
|
||||
@@ -5907,9 +5941,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
@@ -11178,6 +11212,19 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/gcp-metadata": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||
@@ -18516,15 +18563,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
@@ -19580,10 +19628,20 @@
|
||||
"tslib": "^2.6.2"
|
||||
}
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -23109,6 +23167,11 @@
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -23896,9 +23959,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="
|
||||
},
|
||||
"@types/vscode": {
|
||||
"version": "1.84.0",
|
||||
@@ -27352,6 +27415,13 @@
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"gcp-metadata": {
|
||||
@@ -32295,9 +32365,9 @@
|
||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="
|
||||
},
|
||||
"v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
|
||||
+3
-1
@@ -2,7 +2,7 @@
|
||||
"name": "claude-dev",
|
||||
"displayName": "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.",
|
||||
"version": "3.20.11",
|
||||
"version": "3.20.13",
|
||||
"icon": "assets/icons/icon.png",
|
||||
"engines": {
|
||||
"vscode": "^1.84.0"
|
||||
@@ -447,6 +447,7 @@
|
||||
"@playwright/test": "^1.53.2",
|
||||
"@sentry/browser": "^9.12.0",
|
||||
"@streamparser/json": "^0.0.22",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vscode/codicons": "^0.0.36",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.8.2",
|
||||
@@ -491,6 +492,7 @@
|
||||
"tree-sitter-wasms": "^0.1.11",
|
||||
"ts-morph": "^25.0.1",
|
||||
"turndown": "^7.2.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vscode-uri": "^3.1.0",
|
||||
"web-tree-sitter": "^0.22.6",
|
||||
"zod": "^3.24.2"
|
||||
|
||||
@@ -4,6 +4,8 @@ package host;
|
||||
option java_package = "bot.cline.host.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
import "cline/common.proto";
|
||||
|
||||
// Provides methods for working with workspaces/projects.
|
||||
service WorkspaceService {
|
||||
// Returns a list of the top level directories of the workspace.
|
||||
@@ -12,6 +14,8 @@ service WorkspaceService {
|
||||
// Returns true if the document was saved, returns false if the document was not found, or did not
|
||||
// need to be saved.
|
||||
rpc saveOpenDocumentIfDirty(SaveOpenDocumentIfDirtyRequest) returns (SaveOpenDocumentIfDirtyResponse);
|
||||
// Get diagnostics from the workspace.
|
||||
rpc getDiagnostics(GetDiagnosticsRequest) returns (GetDiagnosticsResponse);
|
||||
}
|
||||
|
||||
message GetWorkspacePathsRequest {
|
||||
@@ -34,3 +38,40 @@ message SaveOpenDocumentIfDirtyResponse {
|
||||
// Returns true if the document was saved.
|
||||
optional bool was_saved = 1;
|
||||
}
|
||||
|
||||
message GetDiagnosticsRequest {
|
||||
optional cline.Metadata metadata = 1;
|
||||
}
|
||||
|
||||
message GetDiagnosticsResponse {
|
||||
repeated FileDiagnostics file_diagnostics = 1;
|
||||
}
|
||||
|
||||
message FileDiagnostics {
|
||||
string file_path = 1;
|
||||
repeated Diagnostic diagnostics = 2;
|
||||
}
|
||||
|
||||
message Diagnostic {
|
||||
string message = 1;
|
||||
DiagnosticRange range = 2;
|
||||
DiagnosticSeverity severity = 3;
|
||||
optional string source = 4;
|
||||
}
|
||||
|
||||
message DiagnosticRange {
|
||||
DiagnosticPosition start = 1;
|
||||
DiagnosticPosition end = 2;
|
||||
}
|
||||
|
||||
message DiagnosticPosition {
|
||||
int32 line = 1;
|
||||
int32 character = 2;
|
||||
}
|
||||
|
||||
enum DiagnosticSeverity {
|
||||
DIAGNOSTIC_ERROR = 0;
|
||||
DIAGNOSTIC_WARNING = 1;
|
||||
DIAGNOSTIC_INFORMATION = 2;
|
||||
DIAGNOSTIC_HINT = 3;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ export class AnthropicHandler implements ApiHandler {
|
||||
case "claude-3-5-sonnet-20241022":
|
||||
case "claude-3-5-haiku-20241022":
|
||||
case "claude-opus-4-20250514":
|
||||
case "claude-opus-4-1-20250805":
|
||||
case "claude-3-opus-20240229":
|
||||
case "claude-3-haiku-20240307": {
|
||||
/*
|
||||
@@ -122,6 +123,7 @@ export class AnthropicHandler implements ApiHandler {
|
||||
switch (modelId) {
|
||||
case "claude-sonnet-4-20250514":
|
||||
case "claude-opus-4-20250514":
|
||||
case "claude-opus-4-1-20250805":
|
||||
case "claude-3-7-sonnet-20250219":
|
||||
case "claude-3-5-sonnet-20241022":
|
||||
case "claude-3-5-haiku-20241022":
|
||||
|
||||
@@ -74,7 +74,10 @@ export class RequestyHandler implements ApiHandler {
|
||||
? { thinking: { type: "enabled", budget_tokens: thinkingBudget } }
|
||||
: { thinking: { type: "disabled" } }
|
||||
const thinkingArgs =
|
||||
model.id.includes("claude-3-7-sonnet") || model.id.includes("claude-sonnet-4") || model.id.includes("claude-opus-4")
|
||||
model.id.includes("claude-3-7-sonnet") ||
|
||||
model.id.includes("claude-sonnet-4") ||
|
||||
model.id.includes("claude-opus-4") ||
|
||||
model.id.includes("claude-opus-4-1")
|
||||
? thinking
|
||||
: {}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ export class VertexHandler implements ApiHandler {
|
||||
|
||||
switch (modelId) {
|
||||
case "claude-sonnet-4@20250514":
|
||||
case "claude-opus-4-1@20250805":
|
||||
case "claude-opus-4@20250514":
|
||||
case "claude-3-7-sonnet@20250219":
|
||||
case "claude-3-5-sonnet-v2@20241022":
|
||||
|
||||
@@ -24,6 +24,7 @@ export async function createOpenRouterStream(
|
||||
// handles direct model.id match logic
|
||||
switch (model.id) {
|
||||
case "anthropic/claude-sonnet-4":
|
||||
case "anthropic/claude-opus-4.1":
|
||||
case "anthropic/claude-opus-4":
|
||||
case "anthropic/claude-3.7-sonnet":
|
||||
case "anthropic/claude-3.7-sonnet:beta":
|
||||
@@ -82,6 +83,7 @@ export async function createOpenRouterStream(
|
||||
let maxTokens: number | undefined
|
||||
switch (model.id) {
|
||||
case "anthropic/claude-sonnet-4":
|
||||
case "anthropic/claude-opus-4.1":
|
||||
case "anthropic/claude-opus-4":
|
||||
case "anthropic/claude-3.7-sonnet":
|
||||
case "anthropic/claude-3.7-sonnet:beta":
|
||||
@@ -117,6 +119,7 @@ export async function createOpenRouterStream(
|
||||
let reasoning: { max_tokens: number } | undefined = undefined
|
||||
switch (model.id) {
|
||||
case "anthropic/claude-sonnet-4":
|
||||
case "anthropic/claude-opus-4.1":
|
||||
case "anthropic/claude-opus-4":
|
||||
case "anthropic/claude-3.7-sonnet":
|
||||
case "anthropic/claude-3.7-sonnet:beta":
|
||||
|
||||
@@ -114,6 +114,7 @@ export async function refreshGroqModels(controller: Controller, request: EmptyRe
|
||||
|
||||
telemetryService.captureProviderApiError({
|
||||
taskId: controller.task?.taskId || "",
|
||||
uuid: controller.task?.uuid || "",
|
||||
errorMessage,
|
||||
errorStatus: error.status,
|
||||
model: "groq",
|
||||
|
||||
@@ -49,7 +49,6 @@ export async function refreshOpenRouterModels(
|
||||
|
||||
switch (rawModel.id) {
|
||||
case "anthropic/claude-sonnet-4":
|
||||
case "anthropic/claude-opus-4":
|
||||
case "anthropic/claude-3-7-sonnet":
|
||||
case "anthropic/claude-3-7-sonnet:beta":
|
||||
case "anthropic/claude-3.7-sonnet":
|
||||
@@ -62,6 +61,12 @@ export async function refreshOpenRouterModels(
|
||||
modelInfo.cacheWritesPrice = 3.75
|
||||
modelInfo.cacheReadsPrice = 0.3
|
||||
break
|
||||
case "anthropic/claude-opus-4.1":
|
||||
case "anthropic/claude-opus-4":
|
||||
modelInfo.supportsPromptCache = true
|
||||
modelInfo.cacheWritesPrice = 18.75
|
||||
modelInfo.cacheReadsPrice = 1.5
|
||||
break
|
||||
case "anthropic/claude-3.5-sonnet-20240620":
|
||||
case "anthropic/claude-3.5-sonnet-20240620:beta":
|
||||
modelInfo.supportsPromptCache = true
|
||||
|
||||
@@ -6,7 +6,7 @@ import { mentionRegexGlobal } from "@shared/context-mentions"
|
||||
import fs from "fs/promises"
|
||||
import { extractTextFromFile } from "@integrations/misc/extract-text"
|
||||
import { isBinaryFile } from "isbinaryfile"
|
||||
import { diagnosticsToProblemsString } from "@integrations/diagnostics"
|
||||
import { getWorkspaceProblemsString } from "@/integrations/diagnostics"
|
||||
import { getLatestTerminalOutput } from "@integrations/terminal/get-latest-output"
|
||||
import { getCommitInfo } from "@utils/git"
|
||||
import { getWorkingState } from "@utils/git"
|
||||
@@ -225,12 +225,7 @@ async function getFileOrFolderContent(mentionPath: string, cwd: string): Promise
|
||||
}
|
||||
|
||||
async function getWorkspaceProblems(): Promise<string> {
|
||||
const diagnostics = vscode.languages.getDiagnostics()
|
||||
const result = diagnosticsToProblemsString(diagnostics, [vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning])
|
||||
if (!result) {
|
||||
return "No errors or warnings detected."
|
||||
}
|
||||
return result
|
||||
return await getWorkspaceProblemsString()
|
||||
}
|
||||
|
||||
function isFileMention(mention: string): boolean {
|
||||
|
||||
@@ -51,7 +51,7 @@ Usage:
|
||||
</execute_command>
|
||||
|
||||
## read_file
|
||||
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
|
||||
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string. Do NOT use this tool to list the contents of a directory. Only use this tool on files.
|
||||
Parameters:
|
||||
- path: (required) The path of the file to read (relative to the current working directory ${cwd.toPosix()})
|
||||
Usage:
|
||||
|
||||
@@ -93,6 +93,7 @@ export class ToolExecutor {
|
||||
private browserSettings: BrowserSettings,
|
||||
private cwd: string,
|
||||
private taskId: string,
|
||||
private uuid: string,
|
||||
private mode: Mode,
|
||||
private strictPlanModeEnabled: boolean,
|
||||
|
||||
@@ -2342,7 +2343,7 @@ export class ToolExecutor {
|
||||
await this.say("completion_result", result, undefined, undefined, false)
|
||||
await this.saveCheckpoint(true)
|
||||
await addNewChangesFlagToLastCompletionResultMessage()
|
||||
telemetryService.captureTaskCompleted(this.taskId)
|
||||
telemetryService.captureTaskCompleted(this.taskId, this.uuid)
|
||||
} else {
|
||||
// we already sent a command message, meaning the complete completion message has also been sent
|
||||
await this.saveCheckpoint(true)
|
||||
@@ -2367,7 +2368,7 @@ export class ToolExecutor {
|
||||
await this.say("completion_result", result, undefined, undefined, false)
|
||||
await this.saveCheckpoint(true)
|
||||
await addNewChangesFlagToLastCompletionResultMessage()
|
||||
telemetryService.captureTaskCompleted(this.taskId)
|
||||
telemetryService.captureTaskCompleted(this.taskId, this.uuid)
|
||||
}
|
||||
|
||||
// we already sent completion_result says, an empty string asks relinquishes control over button and field
|
||||
|
||||
+24
-11
@@ -35,6 +35,7 @@ import pTimeout from "p-timeout"
|
||||
import pWaitFor from "p-wait-for"
|
||||
import * as path from "path"
|
||||
import * as vscode from "vscode"
|
||||
import { v4 as uuidv4 } from "uuid"
|
||||
|
||||
import { HostProvider } from "@/hosts/host-provider"
|
||||
import { ClineErrorType } from "@/services/error/ClineError"
|
||||
@@ -97,6 +98,7 @@ type UserContent = Array<Anthropic.ContentBlockParam>
|
||||
export class Task {
|
||||
// Core task variables
|
||||
readonly taskId: string
|
||||
readonly uuid: string
|
||||
private taskIsFavorited?: boolean
|
||||
private cwd: string
|
||||
|
||||
@@ -219,6 +221,7 @@ export class Task {
|
||||
// Initialize taskId first
|
||||
if (historyItem) {
|
||||
this.taskId = historyItem.id
|
||||
this.uuid = historyItem.uuid ?? uuidv4()
|
||||
this.taskIsFavorited = historyItem.isFavorited
|
||||
this.taskState.conversationHistoryDeletedRange = historyItem.conversationHistoryDeletedRange
|
||||
if (historyItem.checkpointTrackerErrorMessage) {
|
||||
@@ -226,6 +229,7 @@ export class Task {
|
||||
}
|
||||
} else if (task || images || files) {
|
||||
this.taskId = Date.now().toString()
|
||||
this.uuid = uuidv4()
|
||||
} else {
|
||||
throw new Error("Either historyItem or task/images must be provided")
|
||||
}
|
||||
@@ -233,6 +237,7 @@ export class Task {
|
||||
this.messageStateHandler = new MessageStateHandler({
|
||||
context,
|
||||
taskId: this.taskId,
|
||||
uuid: this.uuid,
|
||||
taskState: this.taskState,
|
||||
taskIsFavorited: this.taskIsFavorited,
|
||||
updateTaskHistory: this.updateTaskHistory,
|
||||
@@ -306,10 +311,10 @@ export class Task {
|
||||
// initialize telemetry
|
||||
if (historyItem) {
|
||||
// Open task from history
|
||||
telemetryService.captureTaskRestarted(this.taskId, currentProvider)
|
||||
telemetryService.captureTaskRestarted(this.taskId, this.uuid, currentProvider)
|
||||
} else {
|
||||
// New task started
|
||||
telemetryService.captureTaskCreated(this.taskId, currentProvider)
|
||||
telemetryService.captureTaskCreated(this.taskId, this.uuid, currentProvider)
|
||||
}
|
||||
|
||||
this.toolExecutor = new ToolExecutor(
|
||||
@@ -330,6 +335,7 @@ export class Task {
|
||||
this.browserSettings,
|
||||
cwd,
|
||||
this.taskId,
|
||||
this.uuid,
|
||||
this.mode,
|
||||
strictPlanModeEnabled,
|
||||
this.say.bind(this),
|
||||
@@ -2228,7 +2234,7 @@ export class Task {
|
||||
content: userContent,
|
||||
})
|
||||
|
||||
telemetryService.captureConversationTurnEvent(this.taskId, providerId, modelId, "user")
|
||||
telemetryService.captureConversationTurnEvent(this.taskId, this.uuid, providerId, modelId, "user")
|
||||
|
||||
// since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message
|
||||
const lastApiReqIndex = findLastIndex(this.messageStateHandler.getClineMessages(), (m) => m.say === "api_req_started")
|
||||
@@ -2293,13 +2299,20 @@ export class Task {
|
||||
})
|
||||
await this.messageStateHandler.saveClineMessagesAndUpdateHistory()
|
||||
|
||||
telemetryService.captureConversationTurnEvent(this.taskId, providerId, this.api.getModel().id, "assistant", {
|
||||
tokensIn: inputTokens,
|
||||
tokensOut: outputTokens,
|
||||
cacheWriteTokens,
|
||||
cacheReadTokens,
|
||||
totalCost,
|
||||
})
|
||||
telemetryService.captureConversationTurnEvent(
|
||||
this.taskId,
|
||||
this.uuid,
|
||||
providerId,
|
||||
this.api.getModel().id,
|
||||
"assistant",
|
||||
{
|
||||
tokensIn: inputTokens,
|
||||
tokensOut: outputTokens,
|
||||
cacheWriteTokens,
|
||||
cacheReadTokens,
|
||||
totalCost,
|
||||
},
|
||||
)
|
||||
|
||||
// signals to provider that it can retrieve the saved messages from disk, as abortTask can not be awaited on in nature
|
||||
this.taskState.didFinishAbortingStream = true
|
||||
@@ -2468,7 +2481,7 @@ export class Task {
|
||||
// need to save assistant responses to file before proceeding to tool use since user can exit at any moment and we wouldn't be able to save the assistant's response
|
||||
let didEndLoop = false
|
||||
if (assistantMessage.length > 0) {
|
||||
telemetryService.captureConversationTurnEvent(this.taskId, providerId, modelId, "assistant", {
|
||||
telemetryService.captureConversationTurnEvent(this.taskId, this.uuid, providerId, modelId, "assistant", {
|
||||
tokensIn: inputTokens,
|
||||
tokensOut: outputTokens,
|
||||
cacheWriteTokens,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { getCwd, getDesktopDir } from "@/utils/path"
|
||||
interface MessageStateHandlerParams {
|
||||
context: vscode.ExtensionContext
|
||||
taskId: string
|
||||
uuid: string
|
||||
taskIsFavorited?: boolean
|
||||
updateTaskHistory: (historyItem: HistoryItem) => Promise<HistoryItem[]>
|
||||
taskState: TaskState
|
||||
@@ -32,11 +33,13 @@ export class MessageStateHandler {
|
||||
private updateTaskHistory: (historyItem: HistoryItem) => Promise<HistoryItem[]>
|
||||
private context: vscode.ExtensionContext
|
||||
private taskId: string
|
||||
private uuid: string
|
||||
private taskState: TaskState
|
||||
|
||||
constructor(params: MessageStateHandlerParams) {
|
||||
this.context = params.context
|
||||
this.taskId = params.taskId
|
||||
this.uuid = params.uuid
|
||||
this.taskState = params.taskState
|
||||
this.taskIsFavorited = params.taskIsFavorited ?? false
|
||||
this.updateTaskHistory = params.updateTaskHistory
|
||||
@@ -89,6 +92,7 @@ export class MessageStateHandler {
|
||||
const cwd = await getCwd(getDesktopDir())
|
||||
await this.updateTaskHistory({
|
||||
id: this.taskId,
|
||||
uuid: this.uuid,
|
||||
ts: lastRelevantMessage.ts,
|
||||
task: taskMessage.text ?? "",
|
||||
tokensIn: apiMetrics.totalTokensIn,
|
||||
|
||||
+22
-2
@@ -1,5 +1,6 @@
|
||||
import { HostProvider } from "@/hosts/host-provider"
|
||||
import { DiffViewProvider } from "@/integrations/editor/DiffViewProvider"
|
||||
import { DiagnosticSeverity } from "@/shared/proto/host/workspace"
|
||||
import { status } from "@grpc/grpc-js"
|
||||
|
||||
export class ExternalDiffViewProvider extends DiffViewProvider {
|
||||
@@ -78,8 +79,27 @@ export class ExternalDiffViewProvider extends DiffViewProvider {
|
||||
}
|
||||
|
||||
protected override async getNewDiagnosticProblems(): Promise<string> {
|
||||
console.log(`Called ExternalDiffViewProvider.getNewDiagnosticProblems() stub`)
|
||||
return ""
|
||||
// Get diagnostics using the HostBridge workspace service
|
||||
const response = await HostProvider.workspace.getDiagnostics({})
|
||||
|
||||
if (response.fileDiagnostics.length === 0) {
|
||||
return ""
|
||||
}
|
||||
|
||||
let result = ""
|
||||
for (const fileDiagnostics of response.fileDiagnostics) {
|
||||
const errors = fileDiagnostics.diagnostics.filter((d) => d.severity === DiagnosticSeverity.DIAGNOSTIC_ERROR)
|
||||
|
||||
if (errors.length > 0) {
|
||||
result += `\n\n${fileDiagnostics.filePath}`
|
||||
for (const diagnostic of errors) {
|
||||
const line = (diagnostic.range?.start?.line || 0) + 1 // Proto lines are 0-indexed
|
||||
const source = diagnostic.source ? `${diagnostic.source} ` : ""
|
||||
result += `\n- [${source}Error] Line ${line}: ${diagnostic.message}`
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.trim()
|
||||
}
|
||||
|
||||
protected override async closeDiffView(): Promise<void> {
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as path from "path"
|
||||
import * as vscode from "vscode"
|
||||
import { DecorationController } from "@/hosts/vscode/DecorationController"
|
||||
import { DiffViewProvider } from "@integrations/editor/DiffViewProvider"
|
||||
import { diagnosticsToProblemsString, getNewDiagnostics } from "@/integrations/diagnostics"
|
||||
import { diagnosticsToProblemsString, getNewDiagnostics } from "./diagnostics"
|
||||
|
||||
export const DIFF_VIEW_URI_SCHEME = "cline-diff"
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
import deepEqual from "fast-deep-equal"
|
||||
import { getCwd } from "@/utils/path"
|
||||
|
||||
export function getNewDiagnostics(
|
||||
oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
): [vscode.Uri, vscode.Diagnostic[]][] {
|
||||
const newProblems: [vscode.Uri, vscode.Diagnostic[]][] = []
|
||||
const oldMap = new Map(oldDiagnostics)
|
||||
|
||||
for (const [uri, newDiags] of newDiagnostics) {
|
||||
const oldDiags = oldMap.get(uri) || []
|
||||
const newProblemsForUri = newDiags.filter((newDiag) => !oldDiags.some((oldDiag) => deepEqual(oldDiag, newDiag)))
|
||||
|
||||
if (newProblemsForUri.length > 0) {
|
||||
newProblems.push([uri, newProblemsForUri])
|
||||
}
|
||||
}
|
||||
|
||||
return newProblems
|
||||
}
|
||||
|
||||
// Usage:
|
||||
// const oldDiagnostics = // ... your old diagnostics array
|
||||
// const newDiagnostics = // ... your new diagnostics array
|
||||
// const newProblems = getNewDiagnostics(oldDiagnostics, newDiagnostics);
|
||||
|
||||
// Example usage with mocks:
|
||||
//
|
||||
// // Mock old diagnostics
|
||||
// const oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [
|
||||
// [vscode.Uri.file("/path/to/file1.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file2.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning)
|
||||
// ]]
|
||||
// ];
|
||||
//
|
||||
// // Mock new diagnostics
|
||||
// const newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [
|
||||
// [vscode.Uri.file("/path/to/file1.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error),
|
||||
// new vscode.Diagnostic(new vscode.Range(2, 2, 2, 12), "New error in file1", vscode.DiagnosticSeverity.Error)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file2.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file3.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(1, 1, 1, 11), "New error in file3", vscode.DiagnosticSeverity.Error)
|
||||
// ]]
|
||||
// ];
|
||||
//
|
||||
// const newProblems = getNewDiagnostics(oldDiagnostics, newDiagnostics);
|
||||
//
|
||||
// console.log("New problems:");
|
||||
// for (const [uri, diagnostics] of newProblems) {
|
||||
// console.log(`File: ${uri.fsPath}`);
|
||||
// for (const diagnostic of diagnostics) {
|
||||
// console.log(`- ${diagnostic.message} (${diagnostic.range.start.line}:${diagnostic.range.start.character})`);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Expected output:
|
||||
// // New problems:
|
||||
// // File: /path/to/file1.ts
|
||||
// // - New error in file1 (2:2)
|
||||
// // File: /path/to/file3.ts
|
||||
// // - New error in file3 (1:1)
|
||||
|
||||
// will return empty string if no problems with the given severity are found
|
||||
export async function diagnosticsToProblemsString(
|
||||
diagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
severities: vscode.DiagnosticSeverity[],
|
||||
): Promise<string> {
|
||||
const cwd = await getCwd()
|
||||
let result = ""
|
||||
for (const [uri, fileDiagnostics] of diagnostics) {
|
||||
const problems = fileDiagnostics.filter((d) => severities.includes(d.severity))
|
||||
if (problems.length > 0) {
|
||||
result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}`
|
||||
for (const diagnostic of problems) {
|
||||
let label: string
|
||||
switch (diagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
label = "Error"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
label = "Warning"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
label = "Information"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
label = "Hint"
|
||||
break
|
||||
default:
|
||||
label = "Diagnostic"
|
||||
}
|
||||
const line = diagnostic.range.start.line + 1 // VSCode lines are 0-indexed
|
||||
const source = diagnostic.source ? `${diagnostic.source} ` : ""
|
||||
result += `\n- [${source}${label}] Line ${line}: ${diagnostic.message}`
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.trim()
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import * as vscode from "vscode"
|
||||
import {
|
||||
GetDiagnosticsRequest,
|
||||
GetDiagnosticsResponse,
|
||||
FileDiagnostics,
|
||||
Diagnostic,
|
||||
DiagnosticRange,
|
||||
DiagnosticPosition,
|
||||
DiagnosticSeverity,
|
||||
} from "@/shared/proto/host/workspace"
|
||||
|
||||
export async function getDiagnostics(request: GetDiagnosticsRequest): Promise<GetDiagnosticsResponse> {
|
||||
// Get all diagnostics from VS Code
|
||||
const vscodeAllDiagnostics = vscode.languages.getDiagnostics()
|
||||
|
||||
const fileDiagnostics: FileDiagnostics[] = []
|
||||
|
||||
for (const [uri, diagnostics] of vscodeAllDiagnostics) {
|
||||
if (diagnostics.length > 0) {
|
||||
const convertedDiagnostics: Diagnostic[] = diagnostics.map((vsDiagnostic) => {
|
||||
// Convert VS Code severity to proto severity
|
||||
let severity: DiagnosticSeverity
|
||||
switch (vsDiagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
severity = DiagnosticSeverity.DIAGNOSTIC_ERROR
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
severity = DiagnosticSeverity.DIAGNOSTIC_WARNING
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
severity = DiagnosticSeverity.DIAGNOSTIC_INFORMATION
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
severity = DiagnosticSeverity.DIAGNOSTIC_HINT
|
||||
break
|
||||
default:
|
||||
severity = DiagnosticSeverity.DIAGNOSTIC_ERROR
|
||||
}
|
||||
|
||||
return Diagnostic.create({
|
||||
message: vsDiagnostic.message,
|
||||
range: DiagnosticRange.create({
|
||||
start: DiagnosticPosition.create({
|
||||
line: vsDiagnostic.range.start.line,
|
||||
character: vsDiagnostic.range.start.character,
|
||||
}),
|
||||
end: DiagnosticPosition.create({
|
||||
line: vsDiagnostic.range.end.line,
|
||||
character: vsDiagnostic.range.end.character,
|
||||
}),
|
||||
}),
|
||||
severity: severity,
|
||||
source: vsDiagnostic.source || undefined,
|
||||
})
|
||||
})
|
||||
|
||||
fileDiagnostics.push(
|
||||
FileDiagnostics.create({
|
||||
filePath: uri.fsPath,
|
||||
diagnostics: convertedDiagnostics,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return GetDiagnosticsResponse.create({
|
||||
fileDiagnostics: fileDiagnostics,
|
||||
})
|
||||
}
|
||||
@@ -1,105 +1,49 @@
|
||||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
import deepEqual from "fast-deep-equal"
|
||||
import { getCwd } from "@/utils/path"
|
||||
import { HostProvider } from "@/hosts/host-provider"
|
||||
import { GetDiagnosticsRequest, DiagnosticSeverity } from "@/shared/proto/host/workspace"
|
||||
import { Metadata } from "@/shared/proto/cline/common"
|
||||
|
||||
export function getNewDiagnostics(
|
||||
oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
): [vscode.Uri, vscode.Diagnostic[]][] {
|
||||
const newProblems: [vscode.Uri, vscode.Diagnostic[]][] = []
|
||||
const oldMap = new Map(oldDiagnostics)
|
||||
/**
|
||||
* Host-agnostic function to get workspace problems as a formatted string
|
||||
* Used by @problems mention for cross-host compatibility
|
||||
*/
|
||||
export async function getWorkspaceProblemsString(): Promise<string> {
|
||||
const response = await HostProvider.workspace.getDiagnostics(
|
||||
GetDiagnosticsRequest.create({
|
||||
metadata: Metadata.create({}),
|
||||
}),
|
||||
)
|
||||
|
||||
for (const [uri, newDiags] of newDiagnostics) {
|
||||
const oldDiags = oldMap.get(uri) || []
|
||||
const newProblemsForUri = newDiags.filter((newDiag) => !oldDiags.some((oldDiag) => deepEqual(oldDiag, newDiag)))
|
||||
|
||||
if (newProblemsForUri.length > 0) {
|
||||
newProblems.push([uri, newProblemsForUri])
|
||||
}
|
||||
if (response.fileDiagnostics.length === 0) {
|
||||
return "No errors or warnings detected."
|
||||
}
|
||||
|
||||
return newProblems
|
||||
}
|
||||
|
||||
// Usage:
|
||||
// const oldDiagnostics = // ... your old diagnostics array
|
||||
// const newDiagnostics = // ... your new diagnostics array
|
||||
// const newProblems = getNewDiagnostics(oldDiagnostics, newDiagnostics);
|
||||
|
||||
// Example usage with mocks:
|
||||
//
|
||||
// // Mock old diagnostics
|
||||
// const oldDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [
|
||||
// [vscode.Uri.file("/path/to/file1.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file2.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning)
|
||||
// ]]
|
||||
// ];
|
||||
//
|
||||
// // Mock new diagnostics
|
||||
// const newDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = [
|
||||
// [vscode.Uri.file("/path/to/file1.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Old error in file1", vscode.DiagnosticSeverity.Error),
|
||||
// new vscode.Diagnostic(new vscode.Range(2, 2, 2, 12), "New error in file1", vscode.DiagnosticSeverity.Error)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file2.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(5, 5, 5, 15), "Old warning in file2", vscode.DiagnosticSeverity.Warning)
|
||||
// ]],
|
||||
// [vscode.Uri.file("/path/to/file3.ts"), [
|
||||
// new vscode.Diagnostic(new vscode.Range(1, 1, 1, 11), "New error in file3", vscode.DiagnosticSeverity.Error)
|
||||
// ]]
|
||||
// ];
|
||||
//
|
||||
// const newProblems = getNewProblems(oldDiagnostics, newDiagnostics);
|
||||
//
|
||||
// console.log("New problems:");
|
||||
// for (const [uri, diagnostics] of newProblems) {
|
||||
// console.log(`File: ${uri.fsPath}`);
|
||||
// for (const diagnostic of diagnostics) {
|
||||
// console.log(`- ${diagnostic.message} (${diagnostic.range.start.line}:${diagnostic.range.start.character})`);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Expected output:
|
||||
// // New problems:
|
||||
// // File: /path/to/file1.ts
|
||||
// // - New error in file1 (2:2)
|
||||
// // File: /path/to/file3.ts
|
||||
// // - New error in file3 (1:1)
|
||||
|
||||
// will return empty string if no problems with the given severity are found
|
||||
export async function diagnosticsToProblemsString(
|
||||
diagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
severities: vscode.DiagnosticSeverity[],
|
||||
): Promise<string> {
|
||||
const cwd = await getCwd()
|
||||
let result = ""
|
||||
for (const [uri, fileDiagnostics] of diagnostics) {
|
||||
const problems = fileDiagnostics.filter((d) => severities.includes(d.severity))
|
||||
for (const fileDiagnostics of response.fileDiagnostics) {
|
||||
const problems = fileDiagnostics.diagnostics.filter(
|
||||
(d) => d.severity === DiagnosticSeverity.DIAGNOSTIC_ERROR || d.severity === DiagnosticSeverity.DIAGNOSTIC_WARNING,
|
||||
)
|
||||
|
||||
if (problems.length > 0) {
|
||||
result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}`
|
||||
result += `\n\n${fileDiagnostics.filePath}`
|
||||
for (const diagnostic of problems) {
|
||||
let label: string
|
||||
switch (diagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
case DiagnosticSeverity.DIAGNOSTIC_ERROR:
|
||||
label = "Error"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
case DiagnosticSeverity.DIAGNOSTIC_WARNING:
|
||||
label = "Warning"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
case DiagnosticSeverity.DIAGNOSTIC_INFORMATION:
|
||||
label = "Information"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
case DiagnosticSeverity.DIAGNOSTIC_HINT:
|
||||
label = "Hint"
|
||||
break
|
||||
default:
|
||||
label = "Diagnostic"
|
||||
}
|
||||
const line = diagnostic.range.start.line + 1 // VSCode lines are 0-indexed
|
||||
const line = (diagnostic.range?.start?.line || 0) + 1 // Proto lines are 0-indexed
|
||||
const source = diagnostic.source ? `${diagnostic.source} ` : ""
|
||||
result += `\n- [${source}${label}] Line ${line}: ${diagnostic.message}`
|
||||
}
|
||||
|
||||
@@ -181,10 +181,10 @@ export class TelemetryService {
|
||||
* @param taskId Unique identifier for the new task
|
||||
* @param apiProvider Optional API provider
|
||||
*/
|
||||
public captureTaskCreated(taskId: string, apiProvider?: string) {
|
||||
public captureTaskCreated(taskId: string, uuid: string, apiProvider?: string) {
|
||||
this.capture({
|
||||
event: TelemetryService.EVENTS.TASK.CREATED,
|
||||
properties: { taskId, apiProvider },
|
||||
properties: { taskId, uuid, apiProvider },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -193,10 +193,10 @@ export class TelemetryService {
|
||||
* @param taskId Unique identifier for the new task
|
||||
* @param apiProvider Optional API provider
|
||||
*/
|
||||
public captureTaskRestarted(taskId: string, apiProvider?: string) {
|
||||
public captureTaskRestarted(taskId: string, uuid: string, apiProvider?: string) {
|
||||
this.capture({
|
||||
event: TelemetryService.EVENTS.TASK.RESTARTED,
|
||||
properties: { taskId, apiProvider },
|
||||
properties: { taskId, uuid, apiProvider },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -204,10 +204,10 @@ export class TelemetryService {
|
||||
* Records when cline calls the task completion_result tool signifying that cline is done with the task
|
||||
* @param taskId Unique identifier for the task
|
||||
*/
|
||||
public captureTaskCompleted(taskId: string) {
|
||||
public captureTaskCompleted(taskId: string, uuid: string) {
|
||||
this.capture({
|
||||
event: TelemetryService.EVENTS.TASK.COMPLETED,
|
||||
properties: { taskId },
|
||||
properties: { taskId, uuid },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ export class TelemetryService {
|
||||
*/
|
||||
public captureConversationTurnEvent(
|
||||
taskId: string,
|
||||
uuid: string,
|
||||
provider: string = "unknown",
|
||||
model: string = "unknown",
|
||||
source: "user" | "assistant",
|
||||
@@ -233,13 +234,14 @@ export class TelemetryService {
|
||||
} = {},
|
||||
) {
|
||||
// Ensure required parameters are provided
|
||||
if (!taskId || !provider || !model || !source) {
|
||||
if (!taskId || !uuid || !provider || !model || !source) {
|
||||
console.warn("TelemetryService: Missing required parameters for message capture")
|
||||
return
|
||||
}
|
||||
|
||||
const properties: Record<string, unknown> = {
|
||||
taskId,
|
||||
uuid,
|
||||
provider,
|
||||
model,
|
||||
source,
|
||||
@@ -598,6 +600,7 @@ export class TelemetryService {
|
||||
*/
|
||||
public captureProviderApiError(args: {
|
||||
taskId: string
|
||||
uuid: string
|
||||
model: string
|
||||
errorMessage: string
|
||||
errorStatus?: number | undefined
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type HistoryItem = {
|
||||
id: string
|
||||
uuid?: string // UUID for better tracking and metrics
|
||||
ts: number
|
||||
task: string
|
||||
tokensIn: number
|
||||
|
||||
@@ -508,6 +508,16 @@ export const vertexModels = {
|
||||
cacheWritesPrice: 3.75,
|
||||
cacheReadsPrice: 0.3,
|
||||
},
|
||||
"claude-opus-4-1@20250805": {
|
||||
maxTokens: 8192,
|
||||
contextWindow: 200_000,
|
||||
supportsImages: true,
|
||||
supportsPromptCache: true,
|
||||
inputPrice: 15.0,
|
||||
outputPrice: 75.0,
|
||||
cacheWritesPrice: 18.75,
|
||||
cacheReadsPrice: 1.5,
|
||||
},
|
||||
"claude-opus-4@20250514": {
|
||||
maxTokens: 8192,
|
||||
contextWindow: 200_000,
|
||||
|
||||
@@ -50,16 +50,16 @@ const featuredModels = [
|
||||
description: "Recommended for agentic coding in Cline",
|
||||
label: "Best",
|
||||
},
|
||||
{
|
||||
id: "anthropic/claude-opus-4.1",
|
||||
description: "Anthropic's newest model topping benchmarks",
|
||||
label: "New",
|
||||
},
|
||||
{
|
||||
id: "google/gemini-2.5-pro",
|
||||
description: "Large 1M context window, great value",
|
||||
label: "Trending",
|
||||
},
|
||||
{
|
||||
id: "moonshotai/kimi-k2",
|
||||
description: "Open source model topping coding benchmarks",
|
||||
label: "New",
|
||||
},
|
||||
]
|
||||
|
||||
const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = ({ isPopup, currentMode }) => {
|
||||
@@ -211,6 +211,7 @@ const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = ({ isPopup,
|
||||
const showBudgetSlider = useMemo(() => {
|
||||
return (
|
||||
selectedModelId?.toLowerCase().includes("claude-sonnet-4") ||
|
||||
selectedModelId?.toLowerCase().includes("claude-opus-4.1") ||
|
||||
selectedModelId?.toLowerCase().includes("claude-opus-4") ||
|
||||
selectedModelId?.toLowerCase().includes("claude-3-7-sonnet") ||
|
||||
selectedModelId?.toLowerCase().includes("claude-3.7-sonnet") ||
|
||||
|
||||
@@ -14,6 +14,7 @@ export const SUPPORTED_ANTHROPIC_THINKING_MODELS = [
|
||||
"claude-3-7-sonnet-20250219",
|
||||
"claude-sonnet-4-20250514",
|
||||
"claude-opus-4-20250514",
|
||||
"claude-opus-4-1-20250805",
|
||||
]
|
||||
|
||||
/**
|
||||
|
||||
@@ -314,11 +314,14 @@ export const BedrockProvider = ({ showModelOptions, isPopup, currentMode }: Bedr
|
||||
|
||||
{(selectedModelId === "anthropic.claude-3-7-sonnet-20250219-v1:0" ||
|
||||
selectedModelId === "anthropic.claude-sonnet-4-20250514-v1:0" ||
|
||||
selectedModelId === "anthropic.claude-opus-4-1-20250805-v1:0" ||
|
||||
selectedModelId === "anthropic.claude-opus-4-20250514-v1:0" ||
|
||||
(modeFields.awsBedrockCustomSelected &&
|
||||
modeFields.awsBedrockCustomModelBaseId === "anthropic.claude-3-7-sonnet-20250219-v1:0") ||
|
||||
(modeFields.awsBedrockCustomSelected &&
|
||||
modeFields.awsBedrockCustomModelBaseId === "anthropic.claude-sonnet-4-20250514-v1:0") ||
|
||||
(modeFields.awsBedrockCustomSelected &&
|
||||
modeFields.awsBedrockCustomModelBaseId === "anthropic.claude-opus-4-1-20250805-v1:0") ||
|
||||
(modeFields.awsBedrockCustomSelected &&
|
||||
modeFields.awsBedrockCustomModelBaseId === "anthropic.claude-opus-4-20250514-v1:0")) && (
|
||||
<ThinkingBudgetSlider currentMode={currentMode} />
|
||||
|
||||
@@ -23,6 +23,7 @@ const SUPPORTED_THINKING_MODELS = [
|
||||
"claude-3-7-sonnet@20250219",
|
||||
"claude-sonnet-4@20250514",
|
||||
"claude-opus-4@20250514",
|
||||
"claude-opus-4-1@20250805",
|
||||
"gemini-2.5-flash",
|
||||
"gemini-2.5-pro",
|
||||
"gemini-2.5-flash-lite-preview-06-17",
|
||||
|
||||
Reference in New Issue
Block a user