feat: add native tool calling support to HuggingFace provider

This commit is contained in:
Roo Code 2025-12-20 17:53:34 +00:00
parent 78dc34498b
commit 69134c5903
2 changed files with 41 additions and 0 deletions

View file

@ -87,6 +87,9 @@ function parseHuggingFaceModel(model: HuggingFaceModel, provider?: HuggingFacePr
const pricing = provider?.pricing || model.providers.find((p) => p.pricing)?.pricing
// Check if any provider supports tools
const supportsTools = provider?.supports_tools ?? model.providers.some((p) => p.supports_tools === true)
// Include provider name in description if specific provider is given.
const description = provider ? `${model.id} via ${provider.provider}` : `${model.id} via HuggingFace`
@ -95,6 +98,8 @@ function parseHuggingFaceModel(model: HuggingFaceModel, provider?: HuggingFacePr
contextWindow: contextLength,
supportsImages: false, // HuggingFace API doesn't provide this info yet.
supportsPromptCache: false,
supportsNativeTools: supportsTools,
defaultToolProtocol: supportsTools ? ("native" as const) : undefined,
inputPrice: pricing?.input,
outputPrice: pricing?.output,
description,

View file

@ -9,6 +9,9 @@ import { DEFAULT_HEADERS } from "./constants"
import { BaseProvider } from "./base-provider"
import { getHuggingFaceModels, getCachedHuggingFaceModels } from "./fetchers/huggingface"
import { handleOpenAIError } from "./utils/openai-error-handler"
import { resolveToolProtocol } from "../../utils/resolveToolProtocol"
import { TOOL_PROTOCOL } from "@roo-code/types"
import { NativeToolCallParser } from "../../core/assistant-message/NativeToolCallParser"
export class HuggingFaceHandler extends BaseProvider implements SingleCompletionHandler {
private client: OpenAI
@ -53,12 +56,23 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion
const modelId = this.options.huggingFaceModelId || "meta-llama/Llama-3.3-70B-Instruct"
const temperature = this.options.modelTemperature ?? 0.7
// Get model info to check tool support
const model = this.getModel()
const toolProtocol = resolveToolProtocol(this.options, model.info, metadata?.toolProtocol)
// Check if model supports native tools and tools are provided with native protocol
const supportsNativeTools = model.info.supportsNativeTools ?? false
const useNativeTools =
supportsNativeTools && metadata?.tools && metadata.tools.length > 0 && toolProtocol === TOOL_PROTOCOL.NATIVE
const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
model: modelId,
temperature,
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
stream: true,
stream_options: { include_usage: true },
...(useNativeTools && { tools: this.convertToolsForOpenAI(metadata.tools) }),
...(useNativeTools && metadata.tool_choice && { tool_choice: metadata.tool_choice }),
}
// Add max_tokens if specified
@ -75,6 +89,7 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta
const finishReason = chunk.choices[0]?.finish_reason
if (delta?.content) {
yield {
@ -83,6 +98,27 @@ export class HuggingFaceHandler extends BaseProvider implements SingleCompletion
}
}
// Handle tool calls in stream - emit partial chunks for NativeToolCallParser
if (delta?.tool_calls) {
for (const toolCall of delta.tool_calls) {
yield {
type: "tool_call_partial",
index: toolCall.index,
id: toolCall.id,
name: toolCall.function?.name,
arguments: toolCall.function?.arguments,
}
}
}
// Process finish_reason to emit tool_call_end events
if (finishReason) {
const endEvents = NativeToolCallParser.processFinishReason(finishReason)
for (const event of endEvents) {
yield event
}
}
if (chunk.usage) {
yield {
type: "usage",