Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/types/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ export const modelInfoSchema = z.object({
isFree: z.boolean().optional(),
// Flag to indicate if the model supports native tool calling (OpenAI-style function calling)
supportsNativeTools: z.boolean().optional(),
// Default tool protocol preferred by this model (if not specified, falls back to capability/provider defaults)
defaultToolProtocol: z.enum(["xml", "native"]).optional(),
/**
* Service tiers with pricing information.
* Each tier can have a name (for OpenAI service tiers) and pricing overrides.
Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ const baseProviderSettingsSchema = z.object({

// Model verbosity.
verbosity: verbosityLevelsSchema.optional(),

// Tool protocol override for this profile.
toolProtocol: z.enum(["xml", "native"]).optional(),
})

// Several of the providers share common model config properties.
Expand Down
33 changes: 33 additions & 0 deletions packages/types/src/providers/roo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from "zod"

import type { ModelInfo } from "../model.js"
import { TOOL_PROTOCOL } from "../tool.js"

/**
* Roo Code Cloud is a dynamic provider - models are loaded from the /v1/models API endpoint.
Expand All @@ -14,6 +15,38 @@ export const rooDefaultModelId = "xai/grok-code-fast-1"
*/
export const rooModels = {} as const satisfies Record<string, ModelInfo>

/**
* Model-specific defaults for Roo provider models.
* These defaults are merged with dynamically fetched model data.
*
* Use this to configure model-specific settings like defaultToolProtocol.
*
* Example usage:
* ```typescript
* export const rooModelDefaults: Record<string, Partial<ModelInfo>> = {
* "anthropic/claude-3-5-sonnet-20241022": {
* defaultToolProtocol: "xml",
* },
* "openai/gpt-4o": {
* defaultToolProtocol: "native",
* },
* "xai/grok-code-fast-1": {
* defaultToolProtocol: "native",
* },
* }
* ```
*/
export const rooModelDefaults: Record<string, Partial<ModelInfo>> = {
// Add model-specific defaults below.
// You can configure defaultToolProtocol and other ModelInfo fields for specific model IDs.
"anthropic/claude-haiku-4.5": {
defaultToolProtocol: TOOL_PROTOCOL.NATIVE,
},
"minimax/minimax-m2:free": {
defaultToolProtocol: TOOL_PROTOCOL.NATIVE,
},
}

/**
* Roo Code Cloud API response schemas
*/
Expand Down
10 changes: 8 additions & 2 deletions src/api/providers/fetchers/roo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RooModelsResponseSchema } from "@roo-code/types"
import { RooModelsResponseSchema, rooModelDefaults } from "@roo-code/types"

import type { ModelRecord } from "../../../shared/api"
import { parseApiPrice } from "../../../shared/cost"
Expand Down Expand Up @@ -101,7 +101,8 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
const cacheReadPrice = pricing.input_cache_read ? parseApiPrice(pricing.input_cache_read) : undefined
const cacheWritePrice = pricing.input_cache_write ? parseApiPrice(pricing.input_cache_write) : undefined

models[modelId] = {
// Build the base model info from API response
const baseModelInfo = {
maxTokens,
contextWindow,
supportsImages,
Expand All @@ -117,6 +118,11 @@ export async function getRooModels(baseUrl: string, apiKey?: string): Promise<Mo
deprecated: model.deprecated || false,
isFree: tags.includes("free"),
}

// Merge with model-specific defaults if they exist
// Defaults take precedence over dynamically fetched data for specified fields
const modelDefaults = rooModelDefaults[modelId]
models[modelId] = modelDefaults ? { ...baseModelInfo, ...modelDefaults } : baseModelInfo
}

return models
Expand Down
30 changes: 19 additions & 11 deletions src/api/providers/roo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"

import { rooDefaultModelId, getApiProtocol } from "@roo-code/types"
import { rooDefaultModelId, rooModelDefaults, getApiProtocol } from "@roo-code/types"
import { CloudService } from "@roo-code/cloud"

import type { ApiHandlerOptions, ModelRecord } from "../../shared/api"
Expand Down Expand Up @@ -274,18 +274,26 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
}

// Return the requested model ID even if not found, with fallback info.
// Check if there are model-specific defaults configured
const baseModelInfo = {
maxTokens: 16_384,
contextWindow: 262_144,
supportsImages: false,
supportsReasoningEffort: false,
supportsPromptCache: true,
supportsNativeTools: false,
inputPrice: 0,
outputPrice: 0,
isFree: false,
}

// Merge with model-specific defaults if they exist
const modelDefaults = rooModelDefaults[modelId]
const fallbackInfo = modelDefaults ? { ...baseModelInfo, ...modelDefaults } : baseModelInfo

return {
id: modelId,
info: {
maxTokens: 16_384,
contextWindow: 262_144,
supportsImages: false,
supportsReasoningEffort: false,
supportsPromptCache: true,
supportsNativeTools: false,
inputPrice: 0,
outputPrice: 0,
},
info: fallbackInfo,
}
}
}
16 changes: 13 additions & 3 deletions src/core/assistant-message/presentAssistantMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { codebaseSearchTool } from "../tools/CodebaseSearchTool"
import { experiments, EXPERIMENT_IDS } from "../../shared/experiments"
import { applyDiffTool as applyDiffToolClass } from "../tools/ApplyDiffTool"
import { isNativeProtocol } from "@roo-code/types"
import { getToolProtocolFromSettings } from "../../utils/toolProtocol"
import { resolveToolProtocol } from "../../utils/resolveToolProtocol"

/**
* Processes and presents assistant message content to the user interface.
Expand Down Expand Up @@ -282,7 +282,12 @@ export async function presentAssistantMessage(cline: Task) {

const pushToolResult = (content: ToolResponse) => {
// Check if we're using native tool protocol
const isNative = isNativeProtocol(getToolProtocolFromSettings())
const toolProtocol = resolveToolProtocol(
cline.apiConfiguration,
cline.api.getModel().info,
cline.apiConfiguration.apiProvider,
)
const isNative = isNativeProtocol(toolProtocol)

// Get the tool call ID if this is a native tool call
const toolCallId = (block as any).id
Expand Down Expand Up @@ -513,7 +518,12 @@ export async function presentAssistantMessage(cline: Task) {
await checkpointSaveAndMark(cline)

// Check if native protocol is enabled - if so, always use single-file class-based tool
if (isNativeProtocol(getToolProtocolFromSettings())) {
const applyDiffToolProtocol = resolveToolProtocol(
cline.apiConfiguration,
cline.api.getModel().info,
cline.apiConfiguration.apiProvider,
)
if (isNativeProtocol(applyDiffToolProtocol)) {
await applyDiffToolClass.handle(cline, block as ToolUse<"apply_diff">, {
askApproval,
handleError,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/core/prompts/sections/markdown-formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export function markdownFormattingSection(): string {

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reference as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>`
ALL responses MUST show ANY \`language construct\` OR filename reference as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in attempt_completion`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears there's a typographical error in the inline code formatting in this line. The fragment "in attempt_completion" ends with a backtick that isn't balanced by a corresponding opening backtick. Should it be formatted as "attempt_completion`" or corrected in some other way?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you ok buddy?

}
Loading
Loading