mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add GCP Vertex AI provider
This commit is contained in:
138
package-lock.json
generated
138
package-lock.json
generated
@@ -1,17 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-dev",
|
"name": "claude-dev",
|
||||||
"version": "1.4.15",
|
"version": "1.4.16",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "claude-dev",
|
"name": "claude-dev",
|
||||||
"version": "1.4.15",
|
"version": "1.4.16",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
||||||
"@anthropic-ai/sdk": "^0.26.0",
|
"@anthropic-ai/sdk": "^0.26.0",
|
||||||
"@anthropic-ai/tokenizer": "^0.0.4",
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
||||||
|
"@anthropic-ai/vertex-sdk": "^0.4.1",
|
||||||
"@types/clone-deep": "^4.0.4",
|
"@types/clone-deep": "^4.0.4",
|
||||||
"@vscode/codicons": "^0.0.36",
|
"@vscode/codicons": "^0.0.36",
|
||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
@@ -106,6 +107,15 @@
|
|||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@anthropic-ai/vertex-sdk": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/vertex-sdk/-/vertex-sdk-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-RT/2CWzqyAcJDZWxnNc1mXa7XiiHDaQ9aknfW4mIDw6zE+Zj/R2vCKpTb0dIwrmHYNOyKQNaD7Z1ynDt9oXFWA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@anthropic-ai/sdk": ">=0.14 <1",
|
||||||
|
"google-auth-library": "^9.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@aws-crypto/crc32": {
|
"node_modules/@aws-crypto/crc32": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
|
||||||
@@ -4867,7 +4877,6 @@
|
|||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||||
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
@@ -5054,7 +5063,6 @@
|
|||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -5071,6 +5079,14 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/bignumber.js": {
|
||||||
|
"version": "9.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||||
|
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||||
@@ -5170,6 +5186,11 @@
|
|||||||
"ieee754": "^1.2.1"
|
"ieee754": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer-equal-constant-time": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||||
|
},
|
||||||
"node_modules/c8": {
|
"node_modules/c8": {
|
||||||
"version": "9.1.0",
|
"version": "9.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz",
|
||||||
@@ -5516,7 +5537,6 @@
|
|||||||
"version": "4.3.5",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
||||||
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
@@ -5668,6 +5688,14 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/ecdsa-sig-formatter": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
"version": "9.2.2",
|
"version": "9.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||||
@@ -6125,6 +6153,11 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@@ -6442,6 +6475,44 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gaxios": {
|
||||||
|
"version": "6.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
|
||||||
|
"integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"https-proxy-agent": "^7.0.1",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"node-fetch": "^2.6.9",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gaxios/node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gcp-metadata": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
|
||||||
|
"dependencies": {
|
||||||
|
"gaxios": "^6.0.0",
|
||||||
|
"json-bigint": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-caller-file": {
|
"node_modules/get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
@@ -6605,6 +6676,22 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/google-auth-library": {
|
||||||
|
"version": "9.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz",
|
||||||
|
"integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.0",
|
||||||
|
"ecdsa-sig-formatter": "^1.0.11",
|
||||||
|
"gaxios": "^6.1.1",
|
||||||
|
"gcp-metadata": "^6.1.0",
|
||||||
|
"gtoken": "^7.0.0",
|
||||||
|
"jws": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||||
@@ -6632,6 +6719,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/gtoken": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||||
|
"dependencies": {
|
||||||
|
"gaxios": "^6.0.0",
|
||||||
|
"jws": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has-bigints": {
|
"node_modules/has-bigints": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
|
||||||
@@ -6762,7 +6861,6 @@
|
|||||||
"version": "7.0.5",
|
"version": "7.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
|
||||||
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
|
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"agent-base": "^7.0.2",
|
"agent-base": "^7.0.2",
|
||||||
@@ -7366,6 +7464,14 @@
|
|||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/json-bigint": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/json-buffer": {
|
"node_modules/json-buffer": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
@@ -7407,6 +7513,25 @@
|
|||||||
"setimmediate": "^1.0.5"
|
"setimmediate": "^1.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jwa": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-equal-constant-time": "1.0.1",
|
||||||
|
"ecdsa-sig-formatter": "1.0.11",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jws": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||||
|
"dependencies": {
|
||||||
|
"jwa": "^2.0.0",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
@@ -8949,7 +9074,6 @@
|
|||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/safe-regex-test": {
|
"node_modules/safe-regex-test": {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@
|
|||||||
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
||||||
"@anthropic-ai/sdk": "^0.26.0",
|
"@anthropic-ai/sdk": "^0.26.0",
|
||||||
"@anthropic-ai/tokenizer": "^0.0.4",
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
||||||
|
"@anthropic-ai/vertex-sdk": "^0.4.1",
|
||||||
"@types/clone-deep": "^4.0.4",
|
"@types/clone-deep": "^4.0.4",
|
||||||
"@vscode/codicons": "^0.0.36",
|
"@vscode/codicons": "^0.0.36",
|
||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ApiConfiguration, ApiModelId, ModelInfo } from "../shared/api"
|
|||||||
import { AnthropicHandler } from "./anthropic"
|
import { AnthropicHandler } from "./anthropic"
|
||||||
import { AwsBedrockHandler } from "./bedrock"
|
import { AwsBedrockHandler } from "./bedrock"
|
||||||
import { OpenRouterHandler } from "./openrouter"
|
import { OpenRouterHandler } from "./openrouter"
|
||||||
|
import { VertexHandler } from "./vertex"
|
||||||
|
|
||||||
export interface ApiHandlerMessageResponse {
|
export interface ApiHandlerMessageResponse {
|
||||||
message: Anthropic.Messages.Message
|
message: Anthropic.Messages.Message
|
||||||
@@ -37,6 +38,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler {
|
|||||||
return new OpenRouterHandler(options)
|
return new OpenRouterHandler(options)
|
||||||
case "bedrock":
|
case "bedrock":
|
||||||
return new AwsBedrockHandler(options)
|
return new AwsBedrockHandler(options)
|
||||||
|
case "vertex":
|
||||||
|
return new VertexHandler(options)
|
||||||
default:
|
default:
|
||||||
return new AnthropicHandler(options)
|
return new AnthropicHandler(options)
|
||||||
}
|
}
|
||||||
|
|||||||
62
src/api/vertex.ts
Normal file
62
src/api/vertex.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk"
|
||||||
|
import { Anthropic } from "@anthropic-ai/sdk"
|
||||||
|
import { ApiHandler, ApiHandlerMessageResponse, withoutImageData } from "."
|
||||||
|
import { ApiHandlerOptions, ModelInfo, vertexDefaultModelId, VertexModelId, vertexModels } from "../shared/api"
|
||||||
|
|
||||||
|
// https://docs.anthropic.com/en/api/claude-on-vertex-ai
|
||||||
|
export class VertexHandler implements ApiHandler {
|
||||||
|
private options: ApiHandlerOptions
|
||||||
|
private client: AnthropicVertex
|
||||||
|
|
||||||
|
constructor(options: ApiHandlerOptions) {
|
||||||
|
this.options = options
|
||||||
|
this.client = new AnthropicVertex({
|
||||||
|
projectId: this.options.vertexProjectId,
|
||||||
|
// https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude#regions
|
||||||
|
region: this.options.vertexRegion,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async createMessage(
|
||||||
|
systemPrompt: string,
|
||||||
|
messages: Anthropic.Messages.MessageParam[],
|
||||||
|
tools: Anthropic.Messages.Tool[]
|
||||||
|
): Promise<ApiHandlerMessageResponse> {
|
||||||
|
const message = await this.client.messages.create({
|
||||||
|
model: this.getModel().id,
|
||||||
|
max_tokens: this.getModel().info.maxTokens,
|
||||||
|
system: systemPrompt,
|
||||||
|
messages,
|
||||||
|
tools,
|
||||||
|
tool_choice: { type: "auto" },
|
||||||
|
})
|
||||||
|
return { message }
|
||||||
|
}
|
||||||
|
|
||||||
|
createUserReadableRequest(
|
||||||
|
userContent: Array<
|
||||||
|
| Anthropic.TextBlockParam
|
||||||
|
| Anthropic.ImageBlockParam
|
||||||
|
| Anthropic.ToolUseBlockParam
|
||||||
|
| Anthropic.ToolResultBlockParam
|
||||||
|
>
|
||||||
|
): any {
|
||||||
|
return {
|
||||||
|
model: this.getModel().id,
|
||||||
|
max_tokens: this.getModel().info.maxTokens,
|
||||||
|
system: "(see SYSTEM_PROMPT in src/ClaudeDev.ts)",
|
||||||
|
messages: [{ conversation_history: "..." }, { role: "user", content: withoutImageData(userContent) }],
|
||||||
|
tools: "(see tools in src/ClaudeDev.ts)",
|
||||||
|
tool_choice: { type: "auto" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getModel(): { id: VertexModelId; info: ModelInfo } {
|
||||||
|
const modelId = this.options.apiModelId
|
||||||
|
if (modelId && modelId in vertexModels) {
|
||||||
|
const id = modelId as VertexModelId
|
||||||
|
return { id, info: vertexModels[id] }
|
||||||
|
}
|
||||||
|
return { id: vertexDefaultModelId, info: vertexModels[vertexDefaultModelId] }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ type GlobalStateKey =
|
|||||||
| "apiProvider"
|
| "apiProvider"
|
||||||
| "apiModelId"
|
| "apiModelId"
|
||||||
| "awsRegion"
|
| "awsRegion"
|
||||||
|
| "vertexProjectId"
|
||||||
|
| "vertexRegion"
|
||||||
| "maxRequestsPerTask"
|
| "maxRequestsPerTask"
|
||||||
| "lastShownAnnouncementId"
|
| "lastShownAnnouncementId"
|
||||||
| "customInstructions"
|
| "customInstructions"
|
||||||
@@ -311,6 +313,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
awsAccessKey,
|
awsAccessKey,
|
||||||
awsSecretKey,
|
awsSecretKey,
|
||||||
awsRegion,
|
awsRegion,
|
||||||
|
vertexProjectId,
|
||||||
|
vertexRegion,
|
||||||
} = message.apiConfiguration
|
} = message.apiConfiguration
|
||||||
await this.updateGlobalState("apiProvider", apiProvider)
|
await this.updateGlobalState("apiProvider", apiProvider)
|
||||||
await this.updateGlobalState("apiModelId", apiModelId)
|
await this.updateGlobalState("apiModelId", apiModelId)
|
||||||
@@ -319,6 +323,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
await this.storeSecret("awsAccessKey", awsAccessKey)
|
await this.storeSecret("awsAccessKey", awsAccessKey)
|
||||||
await this.storeSecret("awsSecretKey", awsSecretKey)
|
await this.storeSecret("awsSecretKey", awsSecretKey)
|
||||||
await this.updateGlobalState("awsRegion", awsRegion)
|
await this.updateGlobalState("awsRegion", awsRegion)
|
||||||
|
await this.updateGlobalState("vertexProjectId", vertexProjectId)
|
||||||
|
await this.updateGlobalState("vertexRegion", vertexRegion)
|
||||||
this.claudeDev?.updateApi(message.apiConfiguration)
|
this.claudeDev?.updateApi(message.apiConfiguration)
|
||||||
}
|
}
|
||||||
await this.postStateToWebview()
|
await this.postStateToWebview()
|
||||||
@@ -598,6 +604,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
awsAccessKey,
|
awsAccessKey,
|
||||||
awsSecretKey,
|
awsSecretKey,
|
||||||
awsRegion,
|
awsRegion,
|
||||||
|
vertexProjectId,
|
||||||
|
vertexRegion,
|
||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
lastShownAnnouncementId,
|
lastShownAnnouncementId,
|
||||||
customInstructions,
|
customInstructions,
|
||||||
@@ -611,6 +619,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
this.getSecret("awsAccessKey") as Promise<string | undefined>,
|
this.getSecret("awsAccessKey") as Promise<string | undefined>,
|
||||||
this.getSecret("awsSecretKey") as Promise<string | undefined>,
|
this.getSecret("awsSecretKey") as Promise<string | undefined>,
|
||||||
this.getGlobalState("awsRegion") as Promise<string | undefined>,
|
this.getGlobalState("awsRegion") as Promise<string | undefined>,
|
||||||
|
this.getGlobalState("vertexProjectId") as Promise<string | undefined>,
|
||||||
|
this.getGlobalState("vertexRegion") as Promise<string | undefined>,
|
||||||
this.getGlobalState("maxRequestsPerTask") as Promise<number | undefined>,
|
this.getGlobalState("maxRequestsPerTask") as Promise<number | undefined>,
|
||||||
this.getGlobalState("lastShownAnnouncementId") as Promise<string | undefined>,
|
this.getGlobalState("lastShownAnnouncementId") as Promise<string | undefined>,
|
||||||
this.getGlobalState("customInstructions") as Promise<string | undefined>,
|
this.getGlobalState("customInstructions") as Promise<string | undefined>,
|
||||||
@@ -641,6 +651,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
awsAccessKey,
|
awsAccessKey,
|
||||||
awsSecretKey,
|
awsSecretKey,
|
||||||
awsRegion,
|
awsRegion,
|
||||||
|
vertexProjectId,
|
||||||
|
vertexRegion,
|
||||||
},
|
},
|
||||||
maxRequestsPerTask,
|
maxRequestsPerTask,
|
||||||
lastShownAnnouncementId,
|
lastShownAnnouncementId,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export type ApiProvider = "anthropic" | "openrouter" | "bedrock"
|
export type ApiProvider = "anthropic" | "openrouter" | "bedrock" | "vertex"
|
||||||
|
|
||||||
export interface ApiHandlerOptions {
|
export interface ApiHandlerOptions {
|
||||||
apiModelId?: ApiModelId
|
apiModelId?: ApiModelId
|
||||||
@@ -7,6 +7,8 @@ export interface ApiHandlerOptions {
|
|||||||
awsAccessKey?: string
|
awsAccessKey?: string
|
||||||
awsSecretKey?: string
|
awsSecretKey?: string
|
||||||
awsRegion?: string
|
awsRegion?: string
|
||||||
|
vertexProjectId?: string
|
||||||
|
vertexRegion?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiConfiguration = ApiHandlerOptions & {
|
export type ApiConfiguration = ApiHandlerOptions & {
|
||||||
@@ -26,7 +28,7 @@ export interface ModelInfo {
|
|||||||
cacheReadsPrice?: number
|
cacheReadsPrice?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiModelId = AnthropicModelId | OpenRouterModelId | BedrockModelId
|
export type ApiModelId = AnthropicModelId | OpenRouterModelId | BedrockModelId | VertexModelId
|
||||||
|
|
||||||
// Anthropic
|
// Anthropic
|
||||||
// https://docs.anthropic.com/en/docs/about-claude/models
|
// https://docs.anthropic.com/en/docs/about-claude/models
|
||||||
@@ -250,3 +252,42 @@ export const openRouterModels = {
|
|||||||
// outputPrice: 1.5,
|
// outputPrice: 1.5,
|
||||||
// },
|
// },
|
||||||
} as const satisfies Record<string, ModelInfo>
|
} as const satisfies Record<string, ModelInfo>
|
||||||
|
|
||||||
|
// Vertex AI
|
||||||
|
// https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude
|
||||||
|
export type VertexModelId = keyof typeof vertexModels
|
||||||
|
export const vertexDefaultModelId: VertexModelId = "claude-3-5-sonnet@20240620"
|
||||||
|
export const vertexModels = {
|
||||||
|
"claude-3-5-sonnet@20240620": {
|
||||||
|
maxTokens: 8192,
|
||||||
|
contextWindow: 200_000,
|
||||||
|
supportsImages: true,
|
||||||
|
supportsPromptCache: false,
|
||||||
|
inputPrice: 3.0,
|
||||||
|
outputPrice: 15.0,
|
||||||
|
},
|
||||||
|
"claude-3-opus@20240229": {
|
||||||
|
maxTokens: 4096,
|
||||||
|
contextWindow: 200_000,
|
||||||
|
supportsImages: true,
|
||||||
|
supportsPromptCache: false,
|
||||||
|
inputPrice: 15.0,
|
||||||
|
outputPrice: 75.0,
|
||||||
|
},
|
||||||
|
"claude-3-sonnet@20240229": {
|
||||||
|
maxTokens: 4096,
|
||||||
|
contextWindow: 200_000,
|
||||||
|
supportsImages: true,
|
||||||
|
supportsPromptCache: false,
|
||||||
|
inputPrice: 3.0,
|
||||||
|
outputPrice: 15.0,
|
||||||
|
},
|
||||||
|
"claude-3-haiku@20240307": {
|
||||||
|
maxTokens: 4096,
|
||||||
|
contextWindow: 200_000,
|
||||||
|
supportsImages: true,
|
||||||
|
supportsPromptCache: false,
|
||||||
|
inputPrice: 0.25,
|
||||||
|
outputPrice: 1.25,
|
||||||
|
},
|
||||||
|
} as const satisfies Record<string, ModelInfo>
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ const AppContent = () => {
|
|||||||
const hasKey =
|
const hasKey =
|
||||||
message.state!.apiConfiguration?.apiKey !== undefined ||
|
message.state!.apiConfiguration?.apiKey !== undefined ||
|
||||||
message.state!.apiConfiguration?.openRouterApiKey !== undefined ||
|
message.state!.apiConfiguration?.openRouterApiKey !== undefined ||
|
||||||
message.state!.apiConfiguration?.awsAccessKey !== undefined
|
message.state!.apiConfiguration?.awsAccessKey !== undefined ||
|
||||||
|
message.state!.apiConfiguration?.vertexProjectId !== undefined
|
||||||
setShowWelcome(!hasKey)
|
setShowWelcome(!hasKey)
|
||||||
// don't update showAnnouncement to false if shouldShowAnnouncement is false
|
// don't update showAnnouncement to false if shouldShowAnnouncement is false
|
||||||
if (message.state!.shouldShowAnnouncement) {
|
if (message.state!.shouldShowAnnouncement) {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
bedrockModels,
|
bedrockModels,
|
||||||
openRouterDefaultModelId,
|
openRouterDefaultModelId,
|
||||||
openRouterModels,
|
openRouterModels,
|
||||||
|
vertexDefaultModelId,
|
||||||
|
vertexModels,
|
||||||
} from "../../../src/shared/api"
|
} from "../../../src/shared/api"
|
||||||
import { useExtensionState } from "../context/ExtensionStateContext"
|
import { useExtensionState } from "../context/ExtensionStateContext"
|
||||||
|
|
||||||
@@ -70,6 +72,7 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|||||||
<VSCodeOption value="anthropic">Anthropic</VSCodeOption>
|
<VSCodeOption value="anthropic">Anthropic</VSCodeOption>
|
||||||
<VSCodeOption value="bedrock">AWS Bedrock</VSCodeOption>
|
<VSCodeOption value="bedrock">AWS Bedrock</VSCodeOption>
|
||||||
<VSCodeOption value="openrouter">OpenRouter</VSCodeOption>
|
<VSCodeOption value="openrouter">OpenRouter</VSCodeOption>
|
||||||
|
<VSCodeOption value="vertex">GCP Vertex AI</VSCodeOption>
|
||||||
</VSCodeDropdown>
|
</VSCodeDropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -188,6 +191,55 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{apiConfiguration?.apiProvider === "vertex" && (
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
|
||||||
|
<VSCodeTextField
|
||||||
|
value={apiConfiguration?.vertexProjectId || ""}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
onInput={handleInputChange("vertexProjectId")}
|
||||||
|
placeholder="Enter Project ID...">
|
||||||
|
<span style={{ fontWeight: 500 }}>Google Cloud Project ID</span>
|
||||||
|
</VSCodeTextField>
|
||||||
|
<div className="dropdown-container">
|
||||||
|
<label htmlFor="vertex-region-dropdown">
|
||||||
|
<span style={{ fontWeight: 500 }}>Google Cloud Region</span>
|
||||||
|
</label>
|
||||||
|
<VSCodeDropdown
|
||||||
|
id="vertex-region-dropdown"
|
||||||
|
value={apiConfiguration?.vertexRegion || ""}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
onChange={handleInputChange("vertexRegion")}>
|
||||||
|
<VSCodeOption value="">Select a region...</VSCodeOption>
|
||||||
|
<VSCodeOption value="us-east5">us-east5</VSCodeOption>
|
||||||
|
<VSCodeOption value="us-central1">us-central1</VSCodeOption>
|
||||||
|
<VSCodeOption value="europe-west1">europe-west1</VSCodeOption>
|
||||||
|
<VSCodeOption value="europe-west4">europe-west4</VSCodeOption>
|
||||||
|
<VSCodeOption value="asia-southeast1">asia-southeast1</VSCodeOption>
|
||||||
|
</VSCodeDropdown>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
fontSize: "12px",
|
||||||
|
marginTop: "5px",
|
||||||
|
color: "var(--vscode-descriptionForeground)",
|
||||||
|
}}>
|
||||||
|
To use Google Cloud Vertex AI, you need to
|
||||||
|
<VSCodeLink
|
||||||
|
href="https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude#before_you_begin"
|
||||||
|
style={{ display: "inline" }}>
|
||||||
|
{
|
||||||
|
"1) create a Google Cloud account > enable the Vertex AI API > enable the desired Claude models,"
|
||||||
|
}
|
||||||
|
</VSCodeLink>{" "}
|
||||||
|
<VSCodeLink
|
||||||
|
href="https://cloud.google.com/docs/authentication/provide-credentials-adc#google-idp"
|
||||||
|
style={{ display: "inline" }}>
|
||||||
|
{"2) install the Google Cloud CLI > configure Application Default Credentials."}
|
||||||
|
</VSCodeLink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{apiErrorMessage && (
|
{apiErrorMessage && (
|
||||||
<p
|
<p
|
||||||
style={{
|
style={{
|
||||||
@@ -208,6 +260,7 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|||||||
{selectedProvider === "anthropic" && createDropdown(anthropicModels)}
|
{selectedProvider === "anthropic" && createDropdown(anthropicModels)}
|
||||||
{selectedProvider === "openrouter" && createDropdown(openRouterModels)}
|
{selectedProvider === "openrouter" && createDropdown(openRouterModels)}
|
||||||
{selectedProvider === "bedrock" && createDropdown(bedrockModels)}
|
{selectedProvider === "bedrock" && createDropdown(bedrockModels)}
|
||||||
|
{selectedProvider === "vertex" && createDropdown(vertexModels)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ModelInfoView modelInfo={selectedModelInfo} />
|
<ModelInfoView modelInfo={selectedModelInfo} />
|
||||||
@@ -311,6 +364,8 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) {
|
|||||||
return getProviderData(openRouterModels, openRouterDefaultModelId)
|
return getProviderData(openRouterModels, openRouterDefaultModelId)
|
||||||
case "bedrock":
|
case "bedrock":
|
||||||
return getProviderData(bedrockModels, bedrockDefaultModelId)
|
return getProviderData(bedrockModels, bedrockDefaultModelId)
|
||||||
|
case "vertex":
|
||||||
|
return getProviderData(vertexModels, vertexDefaultModelId)
|
||||||
default:
|
default:
|
||||||
return getProviderData(anthropicModels, anthropicDefaultModelId)
|
return getProviderData(anthropicModels, anthropicDefaultModelId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s
|
|||||||
return "You must provide a valid API key or choose a different provider."
|
return "You must provide a valid API key or choose a different provider."
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case "vertex":
|
||||||
|
if (!apiConfiguration.vertexProjectId || !apiConfiguration.vertexRegion) {
|
||||||
|
return "You must provide a valid Google Cloud Project ID and Region."
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user