diff --git a/ui/desktop/src/components/ProviderGuard.tsx b/ui/desktop/src/components/ProviderGuard.tsx index 1eae8e2cd0..87eea6434d 100644 --- a/ui/desktop/src/components/ProviderGuard.tsx +++ b/ui/desktop/src/components/ProviderGuard.tsx @@ -4,12 +4,13 @@ import { useConfig } from './ConfigContext'; import { SetupModal } from './SetupModal'; import { startOpenRouterSetup } from '../utils/openRouterSetup'; import { startTetrateSetup } from '../utils/tetrateSetup'; +import { startOpenAISetup } from '../utils/openaiSetup'; +import { startAnthropicSetup } from '../utils/anthropicSetup'; import WelcomeGooseLogo from './WelcomeGooseLogo'; import { toastService } from '../toasts'; import { OllamaSetup } from './OllamaSetup'; -import { Goose } from './icons/Goose'; -import { OpenRouter } from './icons'; +import { Goose, OpenRouter, OpenAI, Anthropic, Tetrate } from './icons'; interface ProviderGuardProps { didSelectProvider: boolean; @@ -32,6 +33,7 @@ export default function ProviderGuard({ didSelectProvider, children }: ProviderG showRetry: boolean; autoClose?: number; } | null>(null); + const [tetrateSetupState, setTetrateSetupState] = useState<{ show: boolean; title: string; @@ -164,6 +166,28 @@ export default function ProviderGuard({ didSelectProvider, children }: ProviderG } }; + const handleOpenAISetup = async () => { + const result = await startOpenAISetup(); + if (result.requiresManualSetup) { + // Navigate to provider settings with OpenAI pre-selected + navigate('/welcome', { + replace: true, + state: { preselectedProvider: 'openai' } + }); + } + }; + + const handleAnthropicSetup = async () => { + const result = await startAnthropicSetup(); + if (result.requiresManualSetup) { + // Navigate to provider settings with Anthropic pre-selected + navigate('/welcome', { + replace: true, + state: { preselectedProvider: 'anthropic' } + }); + } + }; + useEffect(() => { const checkProvider = async () => { try { @@ -269,8 +293,8 @@ export default function ProviderGuard({ didSelectProvider, children }: ProviderG
-
- {/* Header section - same width as buttons, left aligned */} +
+ {/* Header section */}
@@ -278,128 +302,139 @@ export default function ProviderGuard({ didSelectProvider, children }: ProviderG

Welcome to Goose

-

- Since it's your first time here, let's get you setup with a provider so we can - make incredible work together. Scroll down to see options. +

+ Since it's your first time here, let's get you setup with a provider so we can + make incredible work together.

- {/* Setup options - same width container */} - -
+ {/* Provider options in 2x2 grid */} +
+ {/* Tetrate Card - Recommended */}
- {/* Tetrate Card */} - {/* Recommended badge - positioned relative to wrapper */}
Recommended
-
+

- Automatic setup with Tetrate Agent Router + Tetrate Agent Router

- - + +

- Get secure access to multiple AI models, start for free. Quick setup with just - a few clicks. + Secure access to multiple AI models with automatic setup. Free tier available.

- {/* Primary OpenRouter Card with subtle shimmer - wrapped for badge positioning */} + {/* OpenRouter Card */}
- {/* Subtle shimmer effect */}
-
- +

- Automatic setup with OpenRouter + OpenRouter

- - + +

- Get instant access to multiple AI models including GPT-4, Claude, and more. - Quick setup with just a few clicks. + Access to GPT-4, Claude, Gemini and more with automatic OAuth setup.

- {/* Other providers Card - outline style */} + {/* OpenAI Card */}
navigate('/welcome', { replace: true })} - className="w-full p-4 sm:p-6 bg-transparent border border-background-hover rounded-xl hover:border-text-muted transition-all duration-200 cursor-pointer group" + onClick={handleOpenAISetup} + className="w-full p-4 sm:p-6 bg-background-muted border border-background-hover rounded-xl hover:border-text-muted transition-all duration-200 cursor-pointer group h-full" >
+

- Other providers + OpenAI

- - + +

- If you've already signed up for providers like Anthropic, OpenAI etc, you can - enter your own keys. + Direct access to GPT-4, GPT-4o, and other OpenAI models with your API key.

+ + {/* Anthropic Card */} +
+
+
+ +

+ Anthropic +

+
+
+ + + +
+
+

+ Access Claude 3.5 Sonnet, Claude 3 Opus, and other Anthropic models. +

+
+
+ + {/* Other providers option */} +
+
navigate('/welcome', { replace: true })} + className="w-full p-4 sm:p-6 bg-transparent border border-background-hover rounded-xl hover:border-text-muted transition-all duration-200 cursor-pointer group" + > +
+
+

+ Other providers +

+

+ Configure additional providers like Google, Groq, Ollama, and more. +

+
+
+ + + +
+
+
diff --git a/ui/desktop/src/components/icons/Anthropic.tsx b/ui/desktop/src/components/icons/Anthropic.tsx new file mode 100644 index 0000000000..7af92a4172 --- /dev/null +++ b/ui/desktop/src/components/icons/Anthropic.tsx @@ -0,0 +1,18 @@ +export default function Anthropic({ className = '' }) { + return ( + + ); +} diff --git a/ui/desktop/src/components/icons/OpenAI.tsx b/ui/desktop/src/components/icons/OpenAI.tsx new file mode 100644 index 0000000000..b00bcfca7e --- /dev/null +++ b/ui/desktop/src/components/icons/OpenAI.tsx @@ -0,0 +1,17 @@ +export default function OpenAI({ className = '' }) { + return ( + + + + ); +} diff --git a/ui/desktop/src/components/icons/Tetrate.tsx b/ui/desktop/src/components/icons/Tetrate.tsx new file mode 100644 index 0000000000..011253c937 --- /dev/null +++ b/ui/desktop/src/components/icons/Tetrate.tsx @@ -0,0 +1,22 @@ +export default function Tetrate({ className = '' }) { + return ( + + ); +} diff --git a/ui/desktop/src/components/icons/claude-original.svg b/ui/desktop/src/components/icons/claude-original.svg new file mode 100644 index 0000000000..879ad81261 --- /dev/null +++ b/ui/desktop/src/components/icons/claude-original.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ui/desktop/src/components/icons/index.ts b/ui/desktop/src/components/icons/index.ts new file mode 100644 index 0000000000..c011e77ccd --- /dev/null +++ b/ui/desktop/src/components/icons/index.ts @@ -0,0 +1,5 @@ +export { default as OpenRouter } from './OpenRouter'; +export { default as OpenAI } from './OpenAI'; +export { default as Anthropic } from './Anthropic'; +export { default as Tetrate } from './Tetrate'; +export { Goose, Rain } from './Goose'; diff --git a/ui/desktop/src/components/icons/tetrate-original.svg b/ui/desktop/src/components/icons/tetrate-original.svg new file mode 100644 index 0000000000..83a735c1db --- /dev/null +++ b/ui/desktop/src/components/icons/tetrate-original.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ui/desktop/src/utils/anthropicSetup.ts b/ui/desktop/src/utils/anthropicSetup.ts new file mode 100644 index 0000000000..8e525552ca --- /dev/null +++ b/ui/desktop/src/utils/anthropicSetup.ts @@ -0,0 +1,13 @@ +export interface AnthropicSetupStatus { + isRunning: boolean; + error: string | null; +} + +export async function startAnthropicSetup(): Promise<{ success: boolean; message: string; requiresManualSetup?: boolean }> { + // Anthropic doesn't have OAuth flow, so we redirect to manual setup + return { + success: true, + message: "Redirecting to Anthropic configuration...", + requiresManualSetup: true + }; +} diff --git a/ui/desktop/src/utils/openaiSetup.ts b/ui/desktop/src/utils/openaiSetup.ts new file mode 100644 index 0000000000..daadbf6c8a --- /dev/null +++ b/ui/desktop/src/utils/openaiSetup.ts @@ -0,0 +1,13 @@ +export interface OpenAISetupStatus { + isRunning: boolean; + error: string | null; +} + +export async function startOpenAISetup(): Promise<{ success: boolean; message: string; requiresManualSetup?: boolean }> { + // OpenAI doesn't have OAuth flow, so we redirect to manual setup + return { + success: true, + message: "Redirecting to OpenAI configuration...", + requiresManualSetup: true + }; +}