feat: add tool protocol selector to advanced settings (#9324)

Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
This commit is contained in:
Daniel 2025-11-17 22:53:58 -05:00 committed by GitHub
parent e742511d90
commit c5b18c1581
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 232 additions and 1 deletions

View file

@ -38,6 +38,8 @@ import {
vercelAiGatewayDefaultModelId,
deepInfraDefaultModelId,
minimaxDefaultModelId,
type ToolProtocol,
TOOL_PROTOCOL,
} from "@roo-code/types"
import { vscode } from "@src/utils/vscode"
@ -46,6 +48,7 @@ import { useAppTranslation } from "@src/i18n/TranslationContext"
import { useRouterModels } from "@src/components/ui/hooks/useRouterModels"
import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel"
import { useExtensionState } from "@src/context/ExtensionStateContext"
import { EXPERIMENT_IDS, experimentDefault } from "@roo/experiments"
import {
useOpenRouterModelProviders,
OPENROUTER_DEFAULT_PROVIDER_NAME,
@ -137,7 +140,7 @@ const ApiOptions = ({
setErrorMessage,
}: ApiOptionsProps) => {
const { t } = useAppTranslation()
const { organizationAllowList, cloudIsAuthenticated } = useExtensionState()
const { organizationAllowList, cloudIsAuthenticated, experiments: experimentsConfig } = useExtensionState()
const [customHeaders, setCustomHeaders] = useState<[string, string][]>(() => {
const headers = apiConfiguration?.openAiHeaders || {}
@ -409,6 +412,57 @@ const ApiOptions = ({
}
}, [selectedProvider])
// Calculate the default protocol that would be used if toolProtocol is not set
// This mirrors the logic in resolveToolProtocol.ts (steps 2-5, skipping step 1 which is the user preference)
const defaultProtocol = useMemo((): ToolProtocol => {
// 2. Experimental Setting (nativeToolCalling experiment)
const nativeToolCallingEnabled =
experimentsConfig?.[EXPERIMENT_IDS.NATIVE_TOOL_CALLING] ??
experimentDefault[EXPERIMENT_IDS.NATIVE_TOOL_CALLING]
if (nativeToolCallingEnabled) {
// Check if model supports native tools
if (selectedModelInfo?.supportsNativeTools === true) {
return TOOL_PROTOCOL.NATIVE
}
// If experiment is enabled but model doesn't support it, return XML immediately
// This matches resolveToolProtocol.ts behavior (lines 53-57)
return TOOL_PROTOCOL.XML
}
// 3. Model Default
if (selectedModelInfo?.defaultToolProtocol) {
// Still need to check support even for model defaults
if (
selectedModelInfo.defaultToolProtocol === TOOL_PROTOCOL.NATIVE &&
selectedModelInfo.supportsNativeTools !== true
) {
return TOOL_PROTOCOL.XML
}
return selectedModelInfo.defaultToolProtocol
}
// 4. Provider Default (currently all providers default to XML)
// The nativePreferredProviders list in resolveToolProtocol.ts is currently empty
// If you update it there, update this logic as well
// 5. XML Fallback
return TOOL_PROTOCOL.XML
}, [experimentsConfig, selectedModelInfo])
// Determine whether to show the tool protocol selector
// Separate from defaultProtocol calculation to keep concerns separate
const showToolProtocolSelector = useMemo(() => {
const nativeToolCallingEnabled =
experimentsConfig?.[EXPERIMENT_IDS.NATIVE_TOOL_CALLING] ??
experimentDefault[EXPERIMENT_IDS.NATIVE_TOOL_CALLING]
// Only show if experiment is enabled AND model supports native tools
// If model doesn't support native tools, showing the selector is confusing
// since native protocol won't actually be available
return nativeToolCallingEnabled && selectedModelInfo?.supportsNativeTools === true
}, [experimentsConfig, selectedModelInfo])
// Convert providers to SearchableSelect options
const providerOptions = useMemo(() => {
// First filter by organization allow list
@ -868,6 +922,39 @@ const ApiOptions = ({
</div>
</div>
)}
{showToolProtocolSelector && (
<div>
<label className="block font-medium mb-1">{t("settings:toolProtocol.label")}</label>
<Select
value={apiConfiguration.toolProtocol || "default"}
onValueChange={(value) => {
const newValue = value === "default" ? undefined : (value as ToolProtocol)
setApiConfigurationField("toolProtocol", newValue)
}}>
<SelectTrigger className="w-full">
<SelectValue placeholder={t("settings:common.select")} />
</SelectTrigger>
<SelectContent>
<SelectItem value="default">
{t("settings:toolProtocol.default")} (
{defaultProtocol === TOOL_PROTOCOL.NATIVE
? t("settings:toolProtocol.native")
: t("settings:toolProtocol.xml")}
)
</SelectItem>
<SelectItem value={TOOL_PROTOCOL.XML}>
{t("settings:toolProtocol.xml")}
</SelectItem>
<SelectItem value={TOOL_PROTOCOL.NATIVE}>
{t("settings:toolProtocol.native")}
</SelectItem>
</SelectContent>
</Select>
<div className="text-sm text-vscode-descriptionForeground mt-1">
{t("settings:toolProtocol.description")}
</div>
</div>
)}
</CollapsibleContent>
</Collapsible>
)}

View file

@ -693,6 +693,14 @@
"advancedSettings": {
"title": "Configuració avançada"
},
"toolProtocol": {
"label": "Protocol de crida d'eines",
"description": "Trieu com es comunica en Roo amb l'API. Natiu utilitza l'API de crida de funcions del proveïdor, mentre que XML utilitza definicions d'eines amb format XML.",
"default": "Per defecte",
"xml": "XML",
"native": "Natiu",
"currentDefault": "Per defecte: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Habilitar edició mitjançant diffs",

View file

@ -693,6 +693,14 @@
"advancedSettings": {
"title": "Erweiterte Einstellungen"
},
"toolProtocol": {
"label": "Tool-Aufruf-Protokoll",
"description": "Wähle, wie Roo mit der API kommuniziert. Nativ verwendet die Funktionsaufruf-API des Anbieters, während XML XML-formatierte Werkzeugdefinitionen verwendet.",
"default": "Standard",
"xml": "XML",
"native": "Nativ",
"currentDefault": "Standard: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Bearbeitung durch Diffs aktivieren",

View file

@ -698,6 +698,14 @@
"advancedSettings": {
"title": "Advanced settings"
},
"toolProtocol": {
"label": "Tool Call Protocol",
"description": "Choose how Roo communicates with the API. Native uses the provider's function calling API, while XML uses XML-formatted tool definitions.",
"default": "Default",
"xml": "XML",
"native": "Native",
"currentDefault": "Default: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Enable editing through diffs",

View file

@ -693,6 +693,14 @@
"advancedSettings": {
"title": "Configuración avanzada"
},
"toolProtocol": {
"label": "Protocolo de llamada a herramientas",
"description": "Elija cómo Roo se comunica con la API. Nativo utiliza la API de llamada a funciones del proveedor, mientras que XML utiliza definiciones de herramientas con formato XML.",
"default": "Predeterminado",
"xml": "XML",
"native": "Nativo",
"currentDefault": "Predeterminado: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Habilitar edición a través de diffs",

View file

@ -693,6 +693,14 @@
"advancedSettings": {
"title": "Paramètres avancés"
},
"toolProtocol": {
"label": "Protocole d'appel d'outil",
"description": "Choisissez comment Roo communique avec l'API. Natif utilise l'API d'appel de fonction du fournisseur, tandis que XML utilise des définitions d'outils au format XML.",
"default": "Défaut",
"xml": "XML",
"native": "Natif",
"currentDefault": "Défaut: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Activer l'édition via des diffs",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "उन्नत सेटिंग्स"
},
"toolProtocol": {
"label": "टूल कॉल प्रोटोकॉल",
"description": "चुनें कि रू एपीआई के साथ कैसे संचार करता है। नेटिव प्रदाता के फ़ंक्शन कॉलिंग एपीआई का उपयोग करता है, जबकि एक्सएमएल एक्सएमएल-स्वरूपित टूल परिभाषाओं का उपयोग करता है।",
"default": "डिफ़ॉल्ट",
"xml": "एक्सएमएल",
"native": "नेटिव",
"currentDefault": "डिफ़ॉल्ट: {{protocol}}"
},
"advanced": {
"diff": {
"label": "diffs के माध्यम से संपादन सक्षम करें",

View file

@ -698,6 +698,14 @@
"advancedSettings": {
"title": "Pengaturan lanjutan"
},
"toolProtocol": {
"label": "Protokol Panggilan Alat",
"description": "Pilih bagaimana Roo berkomunikasi dengan API. Asli menggunakan API panggilan fungsi penyedia, sedangkan XML menggunakan definisi alat berformat XML.",
"default": "Default",
"xml": "XML",
"native": "Asli",
"currentDefault": "Default: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Aktifkan editing melalui diff",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Impostazioni avanzate"
},
"toolProtocol": {
"label": "Protocollo di chiamata dello strumento",
"description": "Scegli come Roo comunica con l'API. Nativo utilizza l'API di chiamata di funzione del provider, mentre XML utilizza definizioni di strumenti in formato XML.",
"default": "Predefinito",
"xml": "XML",
"native": "Nativo",
"currentDefault": "Predefinito: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Abilita modifica tramite diff",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "詳細設定"
},
"toolProtocol": {
"label": "ツールコールプロトコル",
"description": "Roo が API と通信する方法を選択します。ネイティブはプロバイダーの関数呼び出し API を使用し、XML は XML 形式のツール定義を使用します。",
"default": "デフォルト",
"xml": "XML",
"native": "ネイティブ",
"currentDefault": "デフォルト: {{protocol}}"
},
"advanced": {
"diff": {
"label": "diff経由の編集を有効化",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "고급 설정"
},
"toolProtocol": {
"label": "도구 호출 프로토콜",
"description": "Roo가 API와 통신하는 방법을 선택합니다. 네이티브는 공급자의 함수 호출 API를 사용하고 XML은 XML 형식의 도구 정의를 사용합니다.",
"default": "기본값",
"xml": "XML",
"native": "네이티브",
"currentDefault": "기본값: {{protocol}}"
},
"advanced": {
"diff": {
"label": "diff를 통한 편집 활성화",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Geavanceerde instellingen"
},
"toolProtocol": {
"label": "Tool Call Protocol",
"description": "Kies hoe Roo communiceert met de API. Native gebruikt de functie-aanroep API van de provider, terwijl XML gebruikmaakt van XML-geformatteerde tooldefinities.",
"default": "Standaard",
"xml": "XML",
"native": "Native",
"currentDefault": "Standaard: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Bewerken via diffs inschakelen",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Ustawienia zaawansowane"
},
"toolProtocol": {
"label": "Protokół wywołania narzędzia",
"description": "Wybierz, jak Roo komunikuje się z API. Natywny używa API wywołania funkcji dostawcy, podczas gdy XML używa definicji narzędzi w formacie XML.",
"default": "Domyślny",
"xml": "XML",
"native": "Natywny",
"currentDefault": "Domyślny: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Włącz edycję przez różnice",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Configurações avançadas"
},
"toolProtocol": {
"label": "Protocolo de Chamada de Ferramenta",
"description": "Escolha como o Roo se comunica com a API. Nativo usa a API de chamada de função do provedor, enquanto XML usa definições de ferramentas formatadas em XML.",
"default": "Padrão",
"xml": "XML",
"native": "Nativo",
"currentDefault": "Padrão: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Ativar edição através de diffs",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Дополнительные настройки"
},
"toolProtocol": {
"label": "Протокол вызова инструментов",
"description": "Выберите, как Roo будет взаимодействовать с API. Нативный использует API вызова функций провайдера, а XML — определения инструментов в формате XML.",
"default": "По умолчанию",
"xml": "XML",
"native": "Нативный",
"currentDefault": "По умолчанию: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Включить редактирование через диффы",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Gelişmiş ayarlar"
},
"toolProtocol": {
"label": "Araç Çağrı Protokolü",
"description": "Roo'nun API ile nasıl iletişim kuracağını seçin. Yerel, sağlayıcının işlev çağırma API'sini kullanırken, XML, XML biçimli araç tanımlarını kullanır.",
"default": "Varsayılan",
"xml": "XML",
"native": "Yerel",
"currentDefault": "Varsayılan: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Diff'ler aracılığıyla düzenlemeyi etkinleştir",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "Cài đặt nâng cao"
},
"toolProtocol": {
"label": "Giao thức gọi công cụ",
"description": "Chọn cách Roo giao tiếp với API. Native sử dụng API gọi hàm của nhà cung cấp, trong khi XML sử dụng định nghĩa công cụ định dạng XML.",
"default": "Mặc định",
"xml": "XML",
"native": "Native",
"currentDefault": "Mặc định: {{protocol}}"
},
"advanced": {
"diff": {
"label": "Bật chỉnh sửa qua diff",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "高级设置"
},
"toolProtocol": {
"label": "工具调用协议",
"description": "选择 Roo 如何与 API 通信。原生使用提供商的函数调用 API而 XML 使用 XML 格式的工具定义。",
"default": "默认",
"xml": "XML",
"native": "原生",
"currentDefault": "默认: {{protocol}}"
},
"advanced": {
"diff": {
"label": "启用diff更新",

View file

@ -694,6 +694,14 @@
"advancedSettings": {
"title": "進階設定"
},
"toolProtocol": {
"label": "工具呼叫協議",
"description": "選擇 Roo 如何與 API 通信。原生使用提供者的函數呼叫 API而 XML 使用 XML 格式的工具定義。",
"default": "預設",
"xml": "XML",
"native": "原生",
"currentDefault": "預設: {{protocol}}"
},
"advanced": {
"diff": {
"label": "透過差異比對編輯",