Default to native tools for all models in the Roo provider (#9811)

Co-authored-by: Roo Code <roomote@roocode.com>
This commit is contained in:
Matt Rubens 2025-12-04 00:40:53 -05:00 committed by GitHub
parent d065b881e3
commit 573cfc31fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 49 deletions

View file

@ -101,6 +101,7 @@ vitest.mock("../../providers/fetchers/modelCache", () => ({
supportsPromptCache: true,
inputPrice: 0,
outputPrice: 0,
defaultToolProtocol: "native",
},
"minimax/minimax-m2:free": {
maxTokens: 32_768,
@ -110,6 +111,7 @@ vitest.mock("../../providers/fetchers/modelCache", () => ({
supportsNativeTools: true,
inputPrice: 0.15,
outputPrice: 0.6,
defaultToolProtocol: "native",
},
"anthropic/claude-haiku-4.5": {
maxTokens: 8_192,
@ -119,6 +121,7 @@ vitest.mock("../../providers/fetchers/modelCache", () => ({
supportsNativeTools: true,
inputPrice: 0.8,
outputPrice: 4,
defaultToolProtocol: "native",
},
}
}
@ -425,28 +428,15 @@ describe("RooHandler", () => {
}
})
it("should apply defaultToolProtocol: native for minimax/minimax-m2:free", () => {
const handlerWithMinimax = new RooHandler({
apiModelId: "minimax/minimax-m2:free",
})
const modelInfo = handlerWithMinimax.getModel()
expect(modelInfo.id).toBe("minimax/minimax-m2:free")
expect((modelInfo.info as any).defaultToolProtocol).toBe("native")
// Verify cached model info is preserved
expect(modelInfo.info.maxTokens).toBe(32_768)
expect(modelInfo.info.contextWindow).toBe(1_000_000)
})
it("should apply defaultToolProtocol: native for anthropic/claude-haiku-4.5", () => {
const handlerWithHaiku = new RooHandler({
apiModelId: "anthropic/claude-haiku-4.5",
})
const modelInfo = handlerWithHaiku.getModel()
expect(modelInfo.id).toBe("anthropic/claude-haiku-4.5")
expect((modelInfo.info as any).defaultToolProtocol).toBe("native")
// Verify cached model info is preserved
expect(modelInfo.info.maxTokens).toBe(8_192)
expect(modelInfo.info.contextWindow).toBe(200_000)
it("should have defaultToolProtocol: native for all roo provider models", () => {
// Test that all models have defaultToolProtocol: native
const testModels = ["minimax/minimax-m2:free", "anthropic/claude-haiku-4.5", "xai/grok-code-fast-1"]
for (const modelId of testModels) {
const handlerWithModel = new RooHandler({ apiModelId: modelId })
const modelInfo = handlerWithModel.getModel()
expect(modelInfo.id).toBe(modelId)
expect((modelInfo.info as any).defaultToolProtocol).toBe("native")
}
})
it("should not override existing properties when applying MODEL_DEFAULTS", () => {

View file

@ -127,6 +127,9 @@ describe("getRooModels", () => {
description: "Model that requires reasoning",
deprecated: false,
isFree: false,
defaultTemperature: undefined,
defaultToolProtocol: "native",
isStealthModel: undefined,
})
})
@ -174,6 +177,9 @@ describe("getRooModels", () => {
description: "Normal model without reasoning",
deprecated: false,
isFree: false,
defaultTemperature: undefined,
defaultToolProtocol: "native",
isStealthModel: undefined,
})
})
@ -578,21 +584,21 @@ describe("getRooModels", () => {
expect(models["test/native-tools-model"].defaultToolProtocol).toBe("native")
})
it("should imply supportsNativeTools when default-native-tools tag is present without tool-use tag", async () => {
it("should set defaultToolProtocol to native for all models regardless of tags", async () => {
const mockResponse = {
object: "list",
data: [
{
id: "test/implicit-native-tools",
id: "test/model-without-tool-tags",
object: "model",
created: 1234567890,
owned_by: "test",
name: "Implicit Native Tools Model",
description: "Model with default-native-tools but no tool-use tag",
name: "Model Without Tool Tags",
description: "Model without any tool-related tags",
context_window: 128000,
max_tokens: 8192,
type: "language",
tags: ["default-native-tools"], // Only default-native-tools, no tool-use
tags: [], // No tool-related tags
pricing: {
input: "0.0001",
output: "0.0002",
@ -608,21 +614,22 @@ describe("getRooModels", () => {
const models = await getRooModels(baseUrl, apiKey)
expect(models["test/implicit-native-tools"].supportsNativeTools).toBe(true)
expect(models["test/implicit-native-tools"].defaultToolProtocol).toBe("native")
// All Roo provider models now default to native tool protocol
expect(models["test/model-without-tool-tags"].supportsNativeTools).toBe(false)
expect(models["test/model-without-tool-tags"].defaultToolProtocol).toBe("native")
})
it("should not set defaultToolProtocol when default-native-tools tag is not present", async () => {
it("should set supportsNativeTools from tool-use tag and always set defaultToolProtocol to native", async () => {
const mockResponse = {
object: "list",
data: [
{
id: "test/non-native-model",
id: "test/tool-use-model",
object: "model",
created: 1234567890,
owned_by: "test",
name: "Non-Native Tools Model",
description: "Model without native tool calling default",
name: "Tool Use Model",
description: "Model with tool-use tag",
context_window: 128000,
max_tokens: 8192,
type: "language",
@ -642,8 +649,9 @@ describe("getRooModels", () => {
const models = await getRooModels(baseUrl, apiKey)
expect(models["test/non-native-model"].supportsNativeTools).toBe(true)
expect(models["test/non-native-model"].defaultToolProtocol).toBeUndefined()
// tool-use tag sets supportsNativeTools, and all models get defaultToolProtocol: native
expect(models["test/tool-use-model"].supportsNativeTools).toBe(true)
expect(models["test/tool-use-model"].defaultToolProtocol).toBe("native")
})
it("should detect stealth mode from tags", async () => {

View file

@ -10,16 +10,9 @@ import { DEFAULT_HEADERS } from "../constants"
// Exported so RooHandler.getModel() can also apply these for fallback cases
export const MODEL_DEFAULTS: Record<string, Partial<ModelInfo>> = {
"minimax/minimax-m2:free": {
defaultToolProtocol: "native",
includedTools: ["search_and_replace"],
excludedTools: ["apply_diff"],
},
"anthropic/claude-haiku-4.5": {
defaultToolProtocol: "native",
},
"xai/grok-code-fast-1": {
defaultToolProtocol: "native",
},
}
/**
@ -109,13 +102,8 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
// Determine if the model requires reasoning effort based on tags
const requiredReasoningEffort = tags.includes("reasoning-required")
// Determine if native tool calling should be the default protocol for this model
const hasDefaultNativeTools = tags.includes("default-native-tools")
const defaultToolProtocol = hasDefaultNativeTools ? ("native" as const) : undefined
// Determine if the model supports native tool calling based on tags
// default-native-tools implies tool-use support
const supportsNativeTools = tags.includes("tool-use") || hasDefaultNativeTools
const supportsNativeTools = tags.includes("tool-use")
// Determine if the model should hide vendor/company identity (stealth mode)
const isStealthModel = tags.includes("stealth")
@ -143,7 +131,7 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
deprecated: model.deprecated || false,
isFree: tags.includes("free"),
defaultTemperature: model.default_temperature,
defaultToolProtocol,
defaultToolProtocol: "native" as const,
isStealthModel: isStealthModel || undefined,
}