Skip to content

Commit 5f63d15

Browse files
authored
Merge branch 'RooCodeInc:main' into feat/adding-gemini-tools
2 parents b7b78df + 2170c61 commit 5f63d15

File tree

149 files changed

+3756
-866
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+3756
-866
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Roo Code Changelog
22

3+
## [3.23.19] - 2025-07-23
4+
5+
- Add Roo Code Cloud Waitlist CTAs (thanks @brunobergher!)
6+
- Split commands on newlines when evaluating auto-approve
7+
- Smarter auto-deny of commands
8+
39
## [3.23.18] - 2025-07-23
410

511
- Fix: Resolve 'Bad substitution' error in command parsing (#5978 by @KJ7LNW, PR by @daniel-lxs)

apps/web-roo-code/next.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ const nextConfig: NextConfig = {
2121
destination: "https://roocode.com/:path*",
2222
permanent: true,
2323
},
24+
// Redirect cloud waitlist to Notion page
25+
{
26+
source: "/cloud-waitlist",
27+
destination: "https://roo-code.notion.site/238fd1401b0a8087b858e1ad431507cf?pvs=105",
28+
permanent: false,
29+
},
2430
]
2531
},
2632
}

apps/web-roo-code/src/app/layout.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react"
22
import type { Metadata } from "next"
33
import { Inter } from "next/font/google"
4+
import Script from "next/script"
45

56
import { Providers } from "@/components/providers"
67

@@ -52,6 +53,16 @@ export default function RootLayout({ children }: { children: React.ReactNode })
5253
/>
5354
</head>
5455
<body className={inter.className}>
56+
{/* Google tag (gtag.js) */}
57+
<Script src="https://www.googletagmanager.com/gtag/js?id=AW-17391954825" strategy="afterInteractive" />
58+
<Script id="google-analytics" strategy="afterInteractive">
59+
{`
60+
window.dataLayer = window.dataLayer || [];
61+
function gtag(){dataLayer.push(arguments);}
62+
gtag('js', new Date());
63+
gtag('config', 'AW-17391954825');
64+
`}
65+
</Script>
5566
<div itemScope itemType="https://schema.org/WebSite">
5667
<link itemProp="url" href="https://roocode.com" />
5768
<meta itemProp="name" content="Roo Code" />

apps/web-roo-code/src/components/chromes/nav-bar.tsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,31 @@ export function NavBar({ stars, downloads }: NavBarProps) {
6161
className="text-muted-foreground transition-transform duration-200 hover:scale-105 hover:text-foreground">
6262
Enterprise
6363
</Link>
64-
<a
65-
href={EXTERNAL_LINKS.SECURITY}
66-
target="_blank"
67-
rel="noopener noreferrer"
68-
className="text-muted-foreground transition-transform duration-200 hover:scale-105 hover:text-foreground">
69-
Security
70-
</a>
7164
<a
7265
href={EXTERNAL_LINKS.DOCUMENTATION}
7366
target="_blank"
7467
className="text-muted-foreground transition-transform duration-200 hover:scale-105 hover:text-foreground">
75-
Documentation
68+
Docs
7669
</a>
7770
<a
7871
href={EXTERNAL_LINKS.CAREERS}
7972
target="_blank"
8073
className="text-muted-foreground transition-transform duration-200 hover:scale-105 hover:text-foreground">
8174
Careers
8275
</a>
76+
<div className="flex items-center rounded-full bg-gradient-to-r from-blue-400 to-cyan-400 p-0.5 text-xs">
77+
<div className="rounded-full bg-background px-2 py-1.5">
78+
<span className="text-muted-foreground border-r-2 border-foreground/50 pr-1.5">
79+
Roo Code Cloud is coming
80+
</span>
81+
<a
82+
href="/cloud-waitlist"
83+
rel="noopener noreferrer"
84+
className="font-medium text-primary hover:underline pl-1.5">
85+
Sign up
86+
</a>
87+
</div>
88+
</div>
8389
</nav>
8490

8591
<div className="hidden md:flex md:items-center md:space-x-4">
@@ -119,6 +125,19 @@ export function NavBar({ stars, downloads }: NavBarProps) {
119125
<div
120126
className={`absolute left-0 right-0 top-16 z-50 transform border-b border-border bg-background shadow-lg backdrop-blur-none transition-all duration-200 md:hidden ${isMenuOpen ? "translate-y-0 opacity-100" : "pointer-events-none -translate-y-2 opacity-0"}`}>
121127
<nav className="flex flex-col py-2">
128+
<div className="mx-5 mb-2 flex items-center rounded-full bg-gradient-to-r from-blue-400 to-cyan-400 p-0.5 text-xs">
129+
<div className="flex-grow text-center rounded-full bg-background px-2 py-1.5">
130+
<span className="text-muted-foreground border-r-2 border-foreground/50 pr-3">
131+
Roo Code Cloud is coming
132+
</span>
133+
<a
134+
href="/cloud-waitlist"
135+
rel="noopener noreferrer"
136+
className="font-medium text-primary hover:underline pl-3">
137+
Sign up
138+
</a>
139+
</div>
140+
</div>
122141
<ScrollButton
123142
targetId="features"
124143
className="w-full px-8 py-3 text-left text-sm font-medium text-foreground/80 transition-colors hover:bg-accent hover:text-foreground"
@@ -162,7 +181,7 @@ export function NavBar({ stars, downloads }: NavBarProps) {
162181
target="_blank"
163182
className="w-full px-8 py-3 text-left text-sm font-medium text-foreground/80 transition-colors hover:bg-accent hover:text-foreground"
164183
onClick={() => setIsMenuOpen(false)}>
165-
Documentation
184+
Docs
166185
</a>
167186
<a
168187
href={EXTERNAL_LINKS.CAREERS}
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
"use client"
22

33
import { useTheme } from "next-themes"
4+
import { useEffect, useState } from "react"
45

56
export function useLogoSrc(): string {
6-
const { resolvedTheme } = useTheme()
7-
return resolvedTheme === "light" ? "/Roo-Code-Logo-Horiz-blk.svg" : "/Roo-Code-Logo-Horiz-white.svg"
7+
const { resolvedTheme, theme } = useTheme()
8+
const [mounted, setMounted] = useState(false)
9+
10+
// Avoid hydration mismatch by waiting for client-side mount
11+
useEffect(() => {
12+
setMounted(true)
13+
}, [])
14+
15+
// Before mounting, return a default logo (dark theme as specified in providers)
16+
// This prevents the logo from flickering on initial load
17+
if (!mounted) {
18+
return "/Roo-Code-Logo-Horiz-white.svg"
19+
}
20+
21+
// Use theme as fallback if resolvedTheme is not available yet
22+
const currentTheme = resolvedTheme || theme
23+
return currentTheme === "light" ? "/Roo-Code-Logo-Horiz-blk.svg" : "/Roo-Code-Logo-Horiz-white.svg"
824
}

packages/types/src/global-settings.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ export const globalSettingsSchema = z.object({
7272
autoCondenseContextPercent: z.number().optional(),
7373
maxConcurrentFileReads: z.number().optional(),
7474

75+
/**
76+
* Whether to include diagnostic messages (errors, warnings) in tool outputs
77+
* @default true
78+
*/
79+
includeDiagnosticMessages: z.boolean().optional(),
80+
/**
81+
* Maximum number of diagnostic messages to include in tool outputs
82+
* @default 50
83+
*/
84+
maxDiagnosticMessages: z.number().optional(),
85+
7586
browserToolEnabled: z.boolean().optional(),
7687
browserViewportSize: z.string().optional(),
7788
screenshotQuality: z.number().optional(),
@@ -172,6 +183,7 @@ export const SECRET_STATE_KEYS = [
172183
"codebaseIndexOpenAiCompatibleApiKey",
173184
"codebaseIndexGeminiApiKey",
174185
"codebaseIndexMistralApiKey",
186+
"huggingFaceApiKey",
175187
] as const satisfies readonly (keyof ProviderSettings)[]
176188
export type SecretState = Pick<ProviderSettings, (typeof SECRET_STATE_KEYS)[number]>
177189

@@ -261,6 +273,9 @@ export const EVALS_SETTINGS: RooCodeSettings = {
261273
showRooIgnoredFiles: true,
262274
maxReadFileLine: -1, // -1 to enable full file reading.
263275

276+
includeDiagnosticMessages: true,
277+
maxDiagnosticMessages: 50,
278+
264279
language: "en",
265280
telemetrySetting: "enabled",
266281

packages/types/src/provider-settings.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const providerNames = [
3232
"groq",
3333
"chutes",
3434
"litellm",
35+
"huggingface",
3536
] as const
3637

3738
export const providerNamesSchema = z.enum(providerNames)
@@ -221,6 +222,12 @@ const groqSchema = apiModelIdProviderModelSchema.extend({
221222
groqApiKey: z.string().optional(),
222223
})
223224

225+
const huggingFaceSchema = baseProviderSettingsSchema.extend({
226+
huggingFaceApiKey: z.string().optional(),
227+
huggingFaceModelId: z.string().optional(),
228+
huggingFaceInferenceProvider: z.string().optional(),
229+
})
230+
224231
const chutesSchema = apiModelIdProviderModelSchema.extend({
225232
chutesApiKey: z.string().optional(),
226233
})
@@ -258,6 +265,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
258265
fakeAiSchema.merge(z.object({ apiProvider: z.literal("fake-ai") })),
259266
xaiSchema.merge(z.object({ apiProvider: z.literal("xai") })),
260267
groqSchema.merge(z.object({ apiProvider: z.literal("groq") })),
268+
huggingFaceSchema.merge(z.object({ apiProvider: z.literal("huggingface") })),
261269
chutesSchema.merge(z.object({ apiProvider: z.literal("chutes") })),
262270
litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })),
263271
defaultSchema,
@@ -287,6 +295,7 @@ export const providerSettingsSchema = z.object({
287295
...fakeAiSchema.shape,
288296
...xaiSchema.shape,
289297
...groqSchema.shape,
298+
...huggingFaceSchema.shape,
290299
...chutesSchema.shape,
291300
...litellmSchema.shape,
292301
...codebaseIndexProviderSchema.shape,
@@ -306,6 +315,7 @@ export const MODEL_ID_KEYS: Partial<keyof ProviderSettings>[] = [
306315
"unboundModelId",
307316
"requestyModelId",
308317
"litellmModelId",
318+
"huggingFaceModelId",
309319
]
310320

311321
export const getModelId = (settings: ProviderSettings): string | undefined => {

src/api/huggingface-models.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { fetchHuggingFaceModels, type HuggingFaceModel } from "../services/huggingface-models"
2+
3+
export interface HuggingFaceModelsResponse {
4+
models: HuggingFaceModel[]
5+
cached: boolean
6+
timestamp: number
7+
}
8+
9+
export async function getHuggingFaceModels(): Promise<HuggingFaceModelsResponse> {
10+
const models = await fetchHuggingFaceModels()
11+
12+
return {
13+
models,
14+
cached: false, // We could enhance this to track if data came from cache
15+
timestamp: Date.now(),
16+
}
17+
}

src/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
FakeAIHandler,
2727
XAIHandler,
2828
GroqHandler,
29+
HuggingFaceHandler,
2930
ChutesHandler,
3031
LiteLLMHandler,
3132
ClaudeCodeHandler,
@@ -108,6 +109,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
108109
return new XAIHandler(options)
109110
case "groq":
110111
return new GroqHandler(options)
112+
case "huggingface":
113+
return new HuggingFaceHandler(options)
111114
case "chutes":
112115
return new ChutesHandler(options)
113116
case "litellm":

src/api/providers/huggingface.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import OpenAI from "openai"
2+
import { Anthropic } from "@anthropic-ai/sdk"
3+
4+
import type { ApiHandlerOptions } from "../../shared/api"
5+
import { ApiStream } from "../transform/stream"
6+
import { convertToOpenAiMessages } from "../transform/openai-format"
7+
import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
8+
import { DEFAULT_HEADERS } from "./constants"
9+
import { BaseProvider } from "./base-provider"
10+
11+
export class HuggingFaceHandler extends BaseProvider implements SingleCompletionHandler {
12+
private client: OpenAI
13+
private options: ApiHandlerOptions
14+
15+
constructor(options: ApiHandlerOptions) {
16+
super()
17+
this.options = options
18+
19+
if (!this.options.huggingFaceApiKey) {
20+
throw new Error("Hugging Face API key is required")
21+
}
22+
23+
this.client = new OpenAI({
24+
baseURL: "https://router.huggingface.co/v1",
25+
apiKey: this.options.huggingFaceApiKey,
26+
defaultHeaders: DEFAULT_HEADERS,
27+
})
28+
}
29+
30+
override async *createMessage(
31+
systemPrompt: string,
32+
messages: Anthropic.Messages.MessageParam[],
33+
metadata?: ApiHandlerCreateMessageMetadata,
34+
): ApiStream {
35+
const modelId = this.options.huggingFaceModelId || "meta-llama/Llama-3.3-70B-Instruct"
36+
const temperature = this.options.modelTemperature ?? 0.7
37+
38+
const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
39+
model: modelId,
40+
temperature,
41+
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
42+
stream: true,
43+
stream_options: { include_usage: true },
44+
}
45+
46+
const stream = await this.client.chat.completions.create(params)
47+
48+
for await (const chunk of stream) {
49+
const delta = chunk.choices[0]?.delta
50+
51+
if (delta?.content) {
52+
yield {
53+
type: "text",
54+
text: delta.content,
55+
}
56+
}
57+
58+
if (chunk.usage) {
59+
yield {
60+
type: "usage",
61+
inputTokens: chunk.usage.prompt_tokens || 0,
62+
outputTokens: chunk.usage.completion_tokens || 0,
63+
}
64+
}
65+
}
66+
}
67+
68+
async completePrompt(prompt: string): Promise<string> {
69+
const modelId = this.options.huggingFaceModelId || "meta-llama/Llama-3.3-70B-Instruct"
70+
71+
try {
72+
const response = await this.client.chat.completions.create({
73+
model: modelId,
74+
messages: [{ role: "user", content: prompt }],
75+
})
76+
77+
return response.choices[0]?.message.content || ""
78+
} catch (error) {
79+
if (error instanceof Error) {
80+
throw new Error(`Hugging Face completion error: ${error.message}`)
81+
}
82+
83+
throw error
84+
}
85+
}
86+
87+
override getModel() {
88+
const modelId = this.options.huggingFaceModelId || "meta-llama/Llama-3.3-70B-Instruct"
89+
return {
90+
id: modelId,
91+
info: {
92+
maxTokens: 8192,
93+
contextWindow: 131072,
94+
supportsImages: false,
95+
supportsPromptCache: false,
96+
},
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)