Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
Closed
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
3 changes: 2 additions & 1 deletion src/api/providers/fetchers/huggingface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,13 @@ function parseHuggingFaceModel(model: HuggingFaceModel, provider?: HuggingFacePr
contextWindow: contextLength,
supportsImages: false, // HuggingFace API doesn't provide this info yet.
supportsPromptCache: false,
supportsNativeTools: true,
defaultToolProtocol: "native",
inputPrice: pricing?.input,
outputPrice: pricing?.output,
description,
}
}

/**
* Fetches available models from HuggingFace
*
Expand Down
36 changes: 36 additions & 0 deletions src/api/providers/huggingface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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",
Expand Down
Loading