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
3 changes: 3 additions & 0 deletions packages/types/src/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export enum TelemetryEventName {
ACCOUNT_LOGOUT_CLICKED = "Account Logout Clicked",
ACCOUNT_LOGOUT_SUCCESS = "Account Logout Success",

FEATURED_PROVIDER_CLICKED = "Featured Provider Clicked",

UPSELL_DISMISSED = "Upsell Dismissed",
UPSELL_CLICKED = "Upsell Clicked",

Expand Down Expand Up @@ -184,6 +186,7 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [
TelemetryEventName.ACCOUNT_CONNECT_SUCCESS,
TelemetryEventName.ACCOUNT_LOGOUT_CLICKED,
TelemetryEventName.ACCOUNT_LOGOUT_SUCCESS,
TelemetryEventName.FEATURED_PROVIDER_CLICKED,
TelemetryEventName.UPSELL_DISMISSED,
TelemetryEventName.UPSELL_CLICKED,
TelemetryEventName.SCHEMA_VALIDATION_ERROR,
Expand Down
Binary file added src/assets/images/roo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 63 additions & 11 deletions webview-ui/src/components/welcome/WelcomeView.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { useCallback, useState } from "react"
import { useCallback, useState, useEffect } from "react"
import knuthShuffle from "knuth-shuffle-seeded"
import { Trans } from "react-i18next"
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import posthog from "posthog-js"

import type { ProviderSettings } from "@roo-code/types"
import { TelemetryEventName } from "@roo-code/types"

import { useExtensionState } from "@src/context/ExtensionStateContext"
import { validateApiConfiguration } from "@src/utils/validate"
import { vscode } from "@src/utils/vscode"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { getRequestyAuthUrl, getOpenRouterAuthUrl } from "@src/oauth/urls"
import { telemetryClient } from "@src/utils/TelemetryClient"

import ApiOptions from "../settings/ApiOptions"
import { Tab, TabContent } from "../common/Tab"
Expand All @@ -20,6 +23,14 @@ const WelcomeView = () => {
const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme, machineId } = useExtensionState()
const { t } = useAppTranslation()
const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)
const [showRooProvider, setShowRooProvider] = useState(false)

// Check PostHog feature flag for Roo provider
useEffect(() => {
posthog.onFeatureFlags(function () {
setShowRooProvider(posthog?.getFeatureFlag("roo-provider-featured") === "test")
Copy link

Choose a reason for hiding this comment

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

[P2] onFeatureFlags only updates after PostHog loads and this checks specifically for the 'test' variant. Initialize immediately and support boolean/variant values (true|'test'|'enabled'); run an initial check and then subscribe to updates.

})
}, [])

// Memoize the setApiConfigurationField function to pass to ApiOptions
const setApiConfigurationFieldForApiOptions = useCallback(
Expand Down Expand Up @@ -69,7 +80,7 @@ const WelcomeView = () => {
{/* Define the providers */}
{(() => {
// Provider card configuration
const providers = [
const baseProviders = [
{
slug: "requesty",
name: "Requesty",
Expand All @@ -85,6 +96,20 @@ const WelcomeView = () => {
},
]

// Conditionally add Roo provider based on feature flag
const providers = showRooProvider
? [
...baseProviders,
{
slug: "roo",
name: "Roo Code Cloud",
description: t("welcome:routers.roo.description"),
incentive: t("welcome:routers.roo.incentive"),
authUrl: "#", // Placeholder since onClick handler will prevent default
},
]
: baseProviders

// Shuffle providers based on machine ID (will be consistent for the same machine)
const orderedProviders = [...providers]
knuthShuffle(orderedProviders, (machineId as any) || Date.now())
Expand All @@ -94,9 +119,41 @@ const WelcomeView = () => {
<a
key={index}
href={provider.authUrl}
className="flex-1 border border-vscode-panel-border hover:bg-secondary rounded-md py-3 px-4 mb-2 flex flex-row gap-3 cursor-pointer transition-all no-underline text-inherit"
className="relative flex-1 border border-vscode-panel-border hover:bg-secondary rounded-md py-3 px-4 mb-2 flex flex-row gap-3 cursor-pointer transition-all no-underline text-inherit"
target="_blank"
Copy link

Choose a reason for hiding this comment

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

[P3] Roo card uses target="_blank" even when href is '#'. Middle-click/keyboard open can create a dead tab despite preventDefault. Omit target for Roo or render as a button to avoid stray tabs.

rel="noopener noreferrer">
rel="noopener noreferrer"
onClick={(e) => {
// Track telemetry for featured provider click
telemetryClient.capture(TelemetryEventName.FEATURED_PROVIDER_CLICKED, {
provider: provider.slug,
})

// Special handling for Roo provider
if (provider.slug === "roo") {
e.preventDefault()

// Set the Roo provider configuration
const rooConfig: ProviderSettings = {
apiProvider: "roo",
}

// Save the Roo provider configuration
vscode.postMessage({
type: "upsertApiConfiguration",
text: currentApiConfigName,
apiConfiguration: rooConfig,
})

// Then trigger cloud sign-in
vscode.postMessage({ type: "rooCloudSignIn" })
}
// For other providers, let the default link behavior work
}}>
{provider.incentive && (
<div className="absolute top-0 right-0 text-[10px] text-vscode-badge-foreground bg-vscode-badge-background px-2 py-0.5 rounded-bl rounded-tr-md">
{provider.incentive}
</div>
)}
<div className="w-8 h-8 flex-shrink-0">
<img
src={`${imagesBaseUri}/${provider.slug}.png`}
Expand All @@ -108,13 +165,8 @@ const WelcomeView = () => {
<div className="text-sm font-medium text-vscode-foreground">
{provider.name}
</div>
<div>
<div className="text-xs text-vscode-descriptionForeground">
{provider.description}
</div>
{provider.incentive && (
<div className="text-xs mt-1">{provider.incentive}</div>
)}
<div className="text-xs text-vscode-descriptionForeground">
{provider.description}
</div>
</div>
</a>
Expand Down
4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/ca/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/de/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/en/welcome.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
},
"openrouter": {
"description": "A unified interface for LLMs"
},
"roo": {
"description": "The best free models to get started",
"incentive": "Try Roo out for free"
}
},
"chooseProvider": "To do its magic, Roo needs an API key.",
Expand Down
4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/es/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/fr/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/hi/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/id/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/it/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/ja/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/ko/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/nl/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/pl/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/pt-BR/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/ru/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/tr/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/vi/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/zh-CN/welcome.json

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

4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/zh-TW/welcome.json

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

Loading