Merge branch 'watsonx-ai-integration' of https://github.com/PrasangAPrajapati/Roo-Code into watsonx-ai-integration

This commit is contained in:
Prasang Prajapati 2025-09-17 18:58:32 -04:00
commit 2529892555
19 changed files with 111 additions and 39 deletions

View file

@ -86,8 +86,8 @@ export default function Privacy() {
Your source code does not transit Roo Code servers unless you explicitly choose Roo Code
as a model provider (proxy mode).
</strong>{" "}
When Roo Code Cloud is your model provider, your code briefly transits Roo Code servers only to
forward it to the upstream model, is not stored, and is deleted immediately after
When Roo Code Cloud is your model provider, your code briefly transits Roo Code servers only
to forward it to the upstream model, is not stored, and is deleted immediately after
forwarding. Otherwise, your code is sent <strong>directly</strong>via clienttoprovider
TLSto the model you select. Roo Code never stores, inspects, or trains on your code.
</li>

View file

@ -199,6 +199,9 @@ export const SECRET_STATE_KEYS = [
"codebaseIndexMistralApiKey",
"codebaseIndexVercelAiGatewayApiKey",
"huggingFaceApiKey",
"watsonxApiKey",
"codebaseIndexWatsonxApiKey",
"codebaseIndexWatsonxProjectId",
"sambaNovaApiKey",
"zaiApiKey",
"fireworksApiKey",

View file

@ -60,6 +60,7 @@ export const providerNames = [
"chutes",
"litellm",
"huggingface",
"watsonx",
"cerebras",
"sambanova",
"zai",
@ -388,6 +389,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
huggingFaceSchema.merge(z.object({ apiProvider: z.literal("huggingface") })),
chutesSchema.merge(z.object({ apiProvider: z.literal("chutes") })),
litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })),
watsonxSchema.merge(z.object({ apiProvider: z.literal("watsonx") })),
cerebrasSchema.merge(z.object({ apiProvider: z.literal("cerebras") })),
sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })),
zaiSchema.merge(z.object({ apiProvider: z.literal("zai") })),

69
pnpm-lock.yaml generated
View file

@ -703,7 +703,7 @@ importers:
version: 25.2.1(typescript@5.8.3)
ibm-cloud-sdk-core:
specifier: ^5.4.2
version: 5.4.2
version: 5.4.3
ignore:
specifier: ^7.0.3
version: 7.0.4
@ -4511,6 +4511,9 @@ packages:
axios@1.12.0:
resolution: {integrity: sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==}
axios@1.12.2:
resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==}
azure-devops-node-api@12.5.0:
resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==}
@ -6037,15 +6040,6 @@ packages:
debug:
optional: true
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
for-each@0.3.5:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
@ -6462,6 +6456,10 @@ packages:
typescript:
optional: true
ibm-cloud-sdk-core@5.4.3:
resolution: {integrity: sha512-D0lvClcoCp/HXyaFlCbOT4aTYgGyeIb4ncxZpxRuiuw7Eo79C6c49W53+8WJRD9nxzT5vrIdaky3NBcTdBtaEg==}
engines: {node: '>=18'}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@ -8651,6 +8649,9 @@ packages:
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
@ -11406,7 +11407,7 @@ snapshots:
dependencies:
'@types/node': 18.19.100
extend: 3.0.2
ibm-cloud-sdk-core: 5.4.2
ibm-cloud-sdk-core: 5.4.3
transitivePeerDependencies:
- supports-color
@ -13934,7 +13935,7 @@ snapshots:
sirv: 3.0.1
tinyglobby: 0.2.14
tinyrainbow: 2.0.0
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
'@vitest/utils@3.2.4':
dependencies:
@ -14257,7 +14258,15 @@ snapshots:
axios@1.12.0:
dependencies:
follow-redirects: 1.15.11
follow-redirects: 1.15.11(debug@4.4.1)
form-data: 4.0.4
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
axios@1.12.2(debug@4.4.1):
dependencies:
follow-redirects: 1.15.11(debug@4.4.1)
form-data: 4.0.4
proxy-from-env: 1.1.0
transitivePeerDependencies:
@ -15938,9 +15947,9 @@ snapshots:
flatted@3.3.3: {}
follow-redirects@1.15.11: {}
follow-redirects@1.15.9: {}
follow-redirects@1.15.11(debug@4.4.1):
optionalDependencies:
debug: 4.4.1(supports-color@8.1.1)
for-each@0.3.5:
dependencies:
@ -16463,6 +16472,26 @@ snapshots:
optionalDependencies:
typescript: 5.8.3
ibm-cloud-sdk-core@5.4.3:
dependencies:
'@types/debug': 4.1.12
'@types/node': 18.19.100
'@types/tough-cookie': 4.0.5
axios: 1.12.2(debug@4.4.1)
camelcase: 6.3.0
debug: 4.4.1(supports-color@8.1.1)
dotenv: 16.5.0
extend: 3.0.2
file-type: 16.5.4
form-data: 4.0.4
isstream: 0.1.2
jsonwebtoken: 9.0.2
mime-types: 2.1.35
retry-axios: 2.6.0(axios@1.12.2(debug@4.4.1))
tough-cookie: 4.1.4
transitivePeerDependencies:
- supports-color
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@ -18183,7 +18212,7 @@ snapshots:
dependencies:
'@vscode/vsce': 3.3.2
commander: 6.2.1
follow-redirects: 1.15.9(debug@4.4.1)
follow-redirects: 1.15.11(debug@4.4.1)
is-ci: 2.0.0
leven: 3.1.0
semver: 7.7.2
@ -19047,6 +19076,8 @@ snapshots:
require-main-filename@2.0.0: {}
requires-port@1.0.0: {}
resize-observer-polyfill@1.5.1: {}
resolve-from@4.0.0: {}
@ -19072,9 +19103,9 @@ snapshots:
onetime: 7.0.0
signal-exit: 4.1.0
retry-axios@2.6.0(axios@1.11.0(debug@4.4.1)):
retry-axios@2.6.0(axios@1.12.2(debug@4.4.1)):
dependencies:
axios: 1.11.0(debug@4.4.1)
axios: 1.12.2(debug@4.4.1)
retry@0.12.0: {}

View file

@ -1,4 +1,9 @@
import { DEEP_SEEK_DEFAULT_TEMPERATURE, type FeatherlessModelId, featherlessDefaultModelId, featherlessModels } from "@roo-code/types"
import {
DEEP_SEEK_DEFAULT_TEMPERATURE,
type FeatherlessModelId,
featherlessDefaultModelId,
featherlessModels,
} from "@roo-code/types"
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"

View file

@ -21,7 +21,6 @@ import { getLMStudioModels } from "./lmstudio"
import { getIOIntelligenceModels } from "./io-intelligence"
import { getDeepInfraModels } from "./deepinfra"
import { getWatsonxModels } from "./watsonx"
const memoryCache = new NodeCache({ stdTTL: 5 * 60, checkperiod: 5 * 60 })
async function writeModels(router: RouterName, data: ModelRecord) {

View file

@ -28,6 +28,7 @@ export { UnboundHandler } from "./unbound"
export { VertexHandler } from "./vertex"
export { VsCodeLmHandler } from "./vscode-lm"
export { XAIHandler } from "./xai"
export { WatsonxAIHandler } from "./watsonx"
export { ZAiHandler } from "./zai"
export { FireworksHandler } from "./fireworks"
export { RooHandler } from "./roo"

View file

@ -17,7 +17,7 @@ export async function codebaseSearchTool(
removeClosingTag: RemoveClosingTag,
) {
const toolName = "codebase_search"
const workspacePath = (cline.cwd && cline.cwd.trim() !== '') ? cline.cwd : getWorkspacePath()
const workspacePath = cline.cwd && cline.cwd.trim() !== "" ? cline.cwd : getWorkspacePath()
if (!workspacePath) {
// This case should ideally not happen if Cline is initialized correctly

View file

@ -11,7 +11,7 @@ import {
type ClineMessage,
type TelemetrySetting,
TelemetryEventName,
UserSettingsConfig
UserSettingsConfig,
} from "@roo-code/types"
import { CloudService } from "@roo-code/cloud"
import { TelemetryService } from "@roo-code/telemetry"
@ -2545,7 +2545,6 @@ export const webviewMessageHandler = async (
settings.codebaseIndexVercelAiGatewayApiKey,
)
}
if (settings.codebaseIndexWatsonxApiKey !== undefined) {
await provider.contextProxy.storeSecret(
"codebaseIndexWatsonxApiKey",
@ -2558,7 +2557,6 @@ export const webviewMessageHandler = async (
settings.codebaseIndexWatsonxProjectId,
)
}
// Send success response first - settings are saved regardless of validation
await provider.postMessageToWebview({
type: "codeIndexSettingsSaved",

View file

@ -47,6 +47,7 @@
"openAiCompatibleConfigMissing": "OpenAI Compatible configuration missing for embedder creation",
"geminiConfigMissing": "Gemini configuration missing for embedder creation",
"mistralConfigMissing": "Mistral configuration missing for embedder creation",
"watsonxConfigMissing": "IBM watsonx configuration missing for embedder creation",
"vercelAiGatewayConfigMissing": "Vercel AI Gateway configuration missing for embedder creation",
"watsonxConfigMissing": "IBM watsonx configuration missing for embedder creation",
"invalidEmbedderType": "Invalid embedder type configured: {{embedderProvider}}",

View file

@ -252,12 +252,15 @@ export class CodeIndexConfigManager {
const qdrantUrl = this.qdrantUrl
const isConfigured = !!(apiKey && qdrantUrl)
return isConfigured
} else if (this.embedderProvider === "vercel-ai-gateway") {
const apiKey = this.vercelAiGatewayOptions?.apiKey
} else if (this.embedderProvider === "watsonx") {
const apiKey = this.watsonxOptions?.codebaseIndexWatsonxApiKey
const projectId = this.watsonxOptions?.codebaseIndexWatsonxProjectId
const qdrantUrl = this.qdrantUrl
const isConfigured = !!(apiKey && qdrantUrl)
const isConfigured = !!(apiKey && projectId && qdrantUrl)
return isConfigured
} else if (this.embedderProvider === "vercel-ai-gateway") {
const apiKey = this.vercelAiGatewayOptions?.apiKey
const isConfigured = !!apiKey
return isConfigured
}
return false // Should not happen if embedderProvider is always set correctly
@ -362,14 +365,13 @@ export class CodeIndexConfigManager {
return true
}
if (prevVercelAiGatewayApiKey !== currentVercelAiGatewayApiKey) {
return true
}
if (prevWatsonxApiKey !== currentWatsonxApiKey || prevWatsonxProjectId !== currentWatsonxProjectId) {
return true
}
if (prevVercelAiGatewayApiKey !== currentVercelAiGatewayApiKey) {
return true
}
// Check for model dimension changes (generic for all providers)
if (prevModelDimension !== currentModelDimension) {
return true

View file

@ -63,5 +63,3 @@ export default `
; LINQ expressions
(query_expression) @definition.linq_expression
`

View file

@ -14,6 +14,7 @@ import type {
CloudUserInfo,
ShareVisibility,
QueuedMessage,
ModelInfo,
} from "@roo-code/types"
import { GitCommit } from "../utils/git"

View file

@ -156,5 +156,4 @@ export type GetModelsOptions =
| { provider: "deepinfra"; apiKey?: string; baseUrl?: string }
| { provider: "io-intelligence"; apiKey: string }
| { provider: "vercel-ai-gateway" }
| { provider: "watsonx"; apiKey: string }
| { provider: "watsonx"; apiKey: string; baseUrl: string }

View file

@ -408,6 +408,10 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
if (!prev.codebaseIndexMistralApiKey || prev.codebaseIndexMistralApiKey === SECRET_PLACEHOLDER) {
updated.codebaseIndexMistralApiKey = secretStatus.hasMistralApiKey ? SECRET_PLACEHOLDER : ""
}
if (!prev.codebaseIndexWatsonxApiKey || prev.codebaseIndexWatsonxApiKey === SECRET_PLACEHOLDER) {
updated.codebaseIndexWatsonxApiKey = secretStatus.hasWatsonxApiKey ? SECRET_PLACEHOLDER : ""
}
if (
!prev.codebaseIndexVercelAiGatewayApiKey ||
prev.codebaseIndexVercelAiGatewayApiKey === SECRET_PLACEHOLDER
@ -427,6 +431,15 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
: ""
}
if (
!prev.codebaseIndexWatsonxProjectId ||
prev.codebaseIndexWatsonxProjectId === SECRET_PLACEHOLDER
) {
updated.codebaseIndexWatsonxProjectId = secretStatus.hasWatsonxProjectId
? SECRET_PLACEHOLDER
: ""
}
return updated
}

View file

@ -28,6 +28,7 @@ import {
chutesDefaultModelId,
bedrockDefaultModelId,
vertexDefaultModelId,
watsonxAiDefaultModelId,
sambaNovaDefaultModelId,
internationalZAiDefaultModelId,
mainlandZAiDefaultModelId,
@ -623,6 +624,15 @@ const ApiOptions = ({
/>
)}
{selectedProvider === "watsonx" && (
<WatsonxAI
apiConfiguration={apiConfiguration}
setApiConfigurationField={setApiConfigurationField}
organizationAllowList={organizationAllowList}
modelValidationError={modelValidationError}
/>
)}
{selectedProvider === "sambanova" && (
<SambaNova apiConfiguration={apiConfiguration} setApiConfigurationField={setApiConfigurationField} />
)}

View file

@ -15,6 +15,7 @@ import {
xaiModels,
groqModels,
chutesModels,
watsonxAiModels,
sambaNovaModels,
doubaoModels,
internationalZAiModels,
@ -40,6 +41,7 @@ export const MODELS_BY_PROVIDER: Partial<Record<ProviderName, Record<string, Mod
xai: xaiModels,
groq: groqModels,
chutes: chutesModels,
watsonx: watsonxAiModels,
sambanova: sambaNovaModels,
zai: internationalZAiModels,
fireworks: fireworksModels,
@ -76,6 +78,7 @@ export const PROVIDERS = [
{ value: "huggingface", label: "Hugging Face" },
{ value: "chutes", label: "Chutes AI" },
{ value: "litellm", label: "LiteLLM" },
{ value: "watsonx", label: "IBM watsonx" },
{ value: "sambanova", label: "SambaNova" },
{ value: "zai", label: "Z AI" },
{ value: "fireworks", label: "Fireworks AI" },

View file

@ -26,6 +26,7 @@ export { VSCodeLM } from "./VSCodeLM"
export { XAI } from "./XAI"
export { ZAi } from "./ZAi"
export { LiteLLM } from "./LiteLLM"
export { WatsonxAI } from "./WatsonxAI"
export { Fireworks } from "./Fireworks"
export { Featherless } from "./Featherless"
export { VercelAiGateway } from "./VercelAiGateway"

View file

@ -59,6 +59,11 @@
"mistralProvider": "Mistral",
"mistralApiKeyLabel": "API Key:",
"mistralApiKeyPlaceholder": "Enter your Mistral API key",
"watsonxProvider": "IBM watsonx",
"watsonxApiKeyLabel": "API Key",
"watsonxApiKeyPlaceholder": "Enter your IBM watsonx API key",
"watsonxProjectIdLabel": "Project ID",
"watsonxProjectIdPlaceholder": "Enter your IBM watsonx project ID",
"vercelAiGatewayProvider": "Vercel AI Gateway",
"vercelAiGatewayApiKeyLabel": "API Key",
"vercelAiGatewayApiKeyPlaceholder": "Enter your Vercel AI Gateway API key",
@ -246,10 +251,10 @@
"awsCustomArnDesc": "Make sure the region in the ARN matches your selected AWS Region above.",
"openRouterApiKey": "OpenRouter API Key",
"getOpenRouterApiKey": "Get OpenRouter API Key",
"apiKeyStorageNotice": "API keys are stored securely in VS Code's Secret Storage",
"passwordStorageNotice": "Passwords are stored securely in VS Code's Secret Storage",
"vercelAiGatewayApiKey": "Vercel AI Gateway API Key",
"getVercelAiGatewayApiKey": "Get Vercel AI Gateway API Key",
"apiKeyStorageNotice": "API keys are stored securely in VSCode's Secret Storage",
"passwordStorageNotice": "Passwords are stored securely in VSCode's Secret Storage",
"glamaApiKey": "Glama API Key",
"getGlamaApiKey": "Get Glama API Key",
"useCustomBaseUrl": "Use custom base URL",