mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-20 15:44:25 +01:00
Cleanup Phase 1: Remove unused React imports from safe components (#2702)
Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { IpcRendererEvent } from 'electron';
|
||||
import { openSharedSessionFromDeepLink } from './sessionLinks';
|
||||
import { initializeSystem } from './utils/providerUtils';
|
||||
@@ -8,6 +8,7 @@ import { ToastContainer } from 'react-toastify';
|
||||
import { toastService } from './toasts';
|
||||
import { extractExtensionName } from './components/settings/extensions/utils';
|
||||
import { GoosehintsModal } from './components/GoosehintsModal';
|
||||
import { type ExtensionConfig } from './extensions';
|
||||
|
||||
import ChatView from './components/ChatView';
|
||||
import SuspenseLoader from './suspense-loader';
|
||||
@@ -46,10 +47,28 @@ export type View =
|
||||
| 'recipeEditor'
|
||||
| 'permission';
|
||||
|
||||
export type ViewOptions =
|
||||
| SettingsViewOptions
|
||||
| { resumedSession?: SessionDetails }
|
||||
| Record<string, unknown>;
|
||||
export type ViewOptions = {
|
||||
// Settings view options
|
||||
extensionId?: string;
|
||||
showEnvVars?: boolean;
|
||||
deepLinkConfig?: ExtensionConfig;
|
||||
|
||||
// Session view options
|
||||
resumedSession?: SessionDetails;
|
||||
sessionDetails?: SessionDetails;
|
||||
error?: string;
|
||||
shareToken?: string;
|
||||
baseUrl?: string;
|
||||
|
||||
// Recipe editor options
|
||||
config?: unknown;
|
||||
|
||||
// Permission view options
|
||||
parentView?: View;
|
||||
|
||||
// Generic options
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type ViewConfig = {
|
||||
view: View;
|
||||
@@ -103,7 +122,7 @@ export default function App() {
|
||||
return `${cmd} ${args.join(' ')}`.trim();
|
||||
}
|
||||
|
||||
function extractRemoteUrl(link: string): string {
|
||||
function extractRemoteUrl(link: string): string | null {
|
||||
const url = new URL(link);
|
||||
return url.searchParams.get('url');
|
||||
}
|
||||
@@ -164,7 +183,7 @@ export default function App() {
|
||||
if (provider && model) {
|
||||
setView('chat');
|
||||
try {
|
||||
await initializeSystem(provider, model, {
|
||||
await initializeSystem(provider as string, model as string, {
|
||||
getExtensions,
|
||||
addExtension,
|
||||
});
|
||||
@@ -289,7 +308,7 @@ export default function App() {
|
||||
};
|
||||
setView(viewFromUrl, initialViewOptions);
|
||||
} else {
|
||||
setView(viewFromUrl);
|
||||
setView(viewFromUrl as View);
|
||||
}
|
||||
}
|
||||
window.electron.on('set-view', handleSetView);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
interface AgentHeaderProps {
|
||||
title: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useRef, useState, useEffect, useCallback } from 'react';
|
||||
import React, { useRef, useState, useEffect, useMemo } from 'react';
|
||||
import { Button } from './ui/button';
|
||||
import type { View } from '../App';
|
||||
import Stop from './ui/Stop';
|
||||
@@ -148,21 +148,20 @@ export default function ChatInput({
|
||||
}, [droppedFiles, processedFilePaths, displayValue]);
|
||||
|
||||
// Debounced function to update actual value
|
||||
const debouncedSetValue = useCallback((val: string) => {
|
||||
debounce((value: string) => {
|
||||
const debouncedSetValue = useMemo(
|
||||
() => debounce((value: string) => {
|
||||
setValue(value);
|
||||
}, 150)(val);
|
||||
}, []);
|
||||
}, 150),
|
||||
[setValue]
|
||||
);
|
||||
|
||||
// Debounced autosize function
|
||||
const debouncedAutosize = useCallback(
|
||||
(textArea: HTMLTextAreaElement) => {
|
||||
debounce((element: HTMLTextAreaElement) => {
|
||||
const debouncedAutosize = useMemo(
|
||||
() => debounce((element: HTMLTextAreaElement) => {
|
||||
element.style.height = '0px'; // Reset height
|
||||
const scrollHeight = element.scrollHeight;
|
||||
element.style.height = Math.min(scrollHeight, maxHeight) + 'px';
|
||||
}, 150)(textArea);
|
||||
},
|
||||
}, 150),
|
||||
[maxHeight]
|
||||
);
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ function ChatContent({
|
||||
|
||||
// Update chat messages when they change and save to sessionStorage
|
||||
useEffect(() => {
|
||||
setChat((prevChat) => {
|
||||
setChat((prevChat: ChatType) => {
|
||||
const updatedChat = { ...prevChat, messages };
|
||||
return updatedChat;
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ export const ConfigProvider: React.FC<ConfigProviderProps> = ({ children }) => {
|
||||
|
||||
const reloadConfig = useCallback(async () => {
|
||||
const response = await readAllConfig();
|
||||
setConfig(response.data.config || {});
|
||||
setConfig(response.data?.config || {});
|
||||
}, []);
|
||||
|
||||
const upsert = useCallback(
|
||||
@@ -186,7 +186,7 @@ export const ConfigProvider: React.FC<ConfigProviderProps> = ({ children }) => {
|
||||
(async () => {
|
||||
// Load config
|
||||
const configResponse = await readAllConfig();
|
||||
setConfig(configResponse.data.config || {});
|
||||
setConfig(configResponse.data?.config || {});
|
||||
|
||||
// Load providers
|
||||
try {
|
||||
@@ -199,7 +199,7 @@ export const ConfigProvider: React.FC<ConfigProviderProps> = ({ children }) => {
|
||||
// Load extensions
|
||||
try {
|
||||
const extensionsResponse = await apiGetExtensions();
|
||||
setExtensionsList(extensionsResponse.data.extensions);
|
||||
setExtensionsList(extensionsResponse.data?.extensions || []);
|
||||
} catch (error) {
|
||||
console.error('Failed to load extensions:', error);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ window.addEventListener('error', (event) => {
|
||||
);
|
||||
});
|
||||
|
||||
export function ErrorUI({ error }) {
|
||||
export function ErrorUI({ error }: { error: Error }) {
|
||||
return (
|
||||
<div className="fixed inset-0 w-full h-full flex flex-col items-center justify-center gap-6 bg-background">
|
||||
<div className="flex flex-col items-center gap-4 max-w-[600px] text-center px-6">
|
||||
|
||||
@@ -216,7 +216,7 @@ const FlappyGoose: React.FC<FlappyGooseProps> = ({ onClose }) => {
|
||||
useEffect(() => {
|
||||
const frames = [svg1, svg7];
|
||||
frames.forEach((src, index) => {
|
||||
const img = new Image();
|
||||
const img = new Image() as HTMLImageElement;
|
||||
img.src = src;
|
||||
img.onload = () => {
|
||||
framesLoaded.current += 1;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Goose, Rain } from './icons/Goose';
|
||||
|
||||
export default function GooseLogo({ className = '', size = 'default', hover = true }) {
|
||||
interface GooseLogoProps {
|
||||
className?: string;
|
||||
size?: 'default' | 'small';
|
||||
hover?: boolean;
|
||||
}
|
||||
|
||||
export default function GooseLogo({ className = '', size = 'default', hover = true }: GooseLogoProps) {
|
||||
const sizes = {
|
||||
default: {
|
||||
frame: 'w-16 h-16',
|
||||
@@ -13,15 +18,18 @@ export default function GooseLogo({ className = '', size = 'default', hover = tr
|
||||
rain: 'w-[150px] h-[150px]',
|
||||
goose: 'w-8 h-8',
|
||||
},
|
||||
};
|
||||
} as const;
|
||||
|
||||
const currentSize = sizes[size];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${className} ${sizes[size].frame} ${hover ? 'group/with-hover' : ''} relative overflow-hidden`}
|
||||
className={`${className} ${currentSize.frame} ${hover ? 'group/with-hover' : ''} relative overflow-hidden`}
|
||||
>
|
||||
<Rain
|
||||
className={`${sizes[size].rain} absolute left-0 bottom-0 ${hover ? 'opacity-0 group-hover/with-hover:opacity-100' : ''} transition-all duration-300 z-1`}
|
||||
className={`${currentSize.rain} absolute left-0 bottom-0 ${hover ? 'opacity-0 group-hover/with-hover:opacity-100' : ''} transition-all duration-300 z-1`}
|
||||
/>
|
||||
<Goose className={`${sizes[size].goose} absolute left-0 bottom-0 z-2`} />
|
||||
<Goose className={`${currentSize.goose} absolute left-0 bottom-0 z-2`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
import { useEffect, useMemo, useRef } from 'react';
|
||||
import LinkPreview from './LinkPreview';
|
||||
import ImagePreview from './ImagePreview';
|
||||
import GooseResponseForm from './GooseResponseForm';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Card } from './ui/card';
|
||||
import { Button } from './ui/button';
|
||||
import { Check } from './icons';
|
||||
|
||||
const Modal = ({ children }) => (
|
||||
const Modal = ({ children }: { children: React.ReactNode }) => (
|
||||
<div className="fixed inset-0 bg-black/20 dark:bg-white/20 backdrop-blur-sm transition-colors animate-[fadein_200ms_ease-in_forwards] z-[1000]">
|
||||
<Card className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col min-w-[80%] min-h-[80%] bg-bgApp rounded-xl overflow-hidden shadow-none px-8 pt-[24px] pb-0">
|
||||
<div className="flex flex-col flex-1 space-y-8 text-base text-textStandard h-full">
|
||||
@@ -48,13 +48,13 @@ const ModalHelpText = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalError = ({ error }) => (
|
||||
const ModalError = ({ error }: { error: Error }) => (
|
||||
<div className="text-sm text-textSubtle">
|
||||
<div className="text-red-600">Error reading .goosehints file: {JSON.stringify(error)}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalFileInfo = ({ filePath, found }) => (
|
||||
const ModalFileInfo = ({ filePath, found }: { filePath: string; found: boolean }) => (
|
||||
<div className="text-sm font-medium">
|
||||
{found ? (
|
||||
<div className="text-green-600">
|
||||
@@ -66,7 +66,7 @@ const ModalFileInfo = ({ filePath, found }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalButtons = ({ onSubmit, onCancel }) => (
|
||||
const ModalButtons = ({ onSubmit, onCancel }: { onSubmit: () => void; onCancel: () => void }) => (
|
||||
<div className="-ml-8 -mr-8">
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -87,7 +87,7 @@ const ModalButtons = ({ onSubmit, onCancel }) => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const getGoosehintsFile = async (filePath) => await window.electron.readFile(filePath);
|
||||
const getGoosehintsFile = async (filePath: string) => await window.electron.readFile(filePath);
|
||||
|
||||
type GoosehintsModalProps = {
|
||||
directory: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
interface ImagePreviewProps {
|
||||
src: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Geese } from './icons/Geese';
|
||||
|
||||
export default function LayingEggLoader() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Card } from './ui/card';
|
||||
|
||||
interface Metadata {
|
||||
@@ -85,10 +85,11 @@ export default function LinkPreview({ url }: LinkPreviewProps) {
|
||||
if (mounted) {
|
||||
setMetadata(data);
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (err) {
|
||||
if (mounted) {
|
||||
console.error('❌ Failed to fetch metadata:', error);
|
||||
setError(error.message || 'Failed to fetch metadata');
|
||||
console.error('❌ Failed to fetch metadata:', err);
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to fetch metadata';
|
||||
setError(errorMessage);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import GooseLogo from './GooseLogo';
|
||||
|
||||
const LoadingGoose = () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export function LoadingPlaceholder() {
|
||||
return (
|
||||
|
||||
@@ -43,7 +43,7 @@ export function ProviderGrid({ onSubmit }: ProviderGridProps) {
|
||||
});
|
||||
}, [activeKeys]);
|
||||
|
||||
const handleConfigure = async (provider) => {
|
||||
const handleConfigure = async (provider: { id: string; name: string; isConfigured: boolean; description: string }) => {
|
||||
const providerId = provider.id.toLowerCase();
|
||||
|
||||
const modelName = getDefaultModel(providerId);
|
||||
@@ -63,7 +63,7 @@ export function ProviderGrid({ onSubmit }: ProviderGridProps) {
|
||||
onSubmit?.();
|
||||
};
|
||||
|
||||
const handleAddKeys = (provider) => {
|
||||
const handleAddKeys = (provider: { id: string; name: string; isConfigured: boolean; description: string }) => {
|
||||
setSelectedId(provider.id);
|
||||
setShowSetupModal(true);
|
||||
};
|
||||
@@ -74,7 +74,7 @@ export function ProviderGrid({ onSubmit }: ProviderGridProps) {
|
||||
const provider = providers.find((p) => p.id === selectedId)?.name;
|
||||
if (!provider) return;
|
||||
|
||||
const requiredKeys = required_keys[provider];
|
||||
const requiredKeys = required_keys[provider as keyof typeof required_keys];
|
||||
if (!requiredKeys || requiredKeys.length === 0) {
|
||||
console.error(`No keys found for provider ${provider}`);
|
||||
return;
|
||||
@@ -145,12 +145,13 @@ export function ProviderGrid({ onSubmit }: ProviderGridProps) {
|
||||
|
||||
setShowSetupModal(false);
|
||||
setSelectedId(null);
|
||||
} catch (error) {
|
||||
console.error('Error handling modal submit:', error);
|
||||
} catch (err) {
|
||||
console.error('Error handling modal submit:', err);
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';
|
||||
toastError({
|
||||
title: provider,
|
||||
msg: `Failed to ${providers.find((p) => p.id === selectedId)?.isConfigured ? 'update' : 'add'} configuration`,
|
||||
traceback: error.message,
|
||||
traceback: errorMessage,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function RecipeEditor({ config }: RecipeEditorProps) {
|
||||
}
|
||||
}
|
||||
// Fall back to config if available, using extension names
|
||||
const exts = [];
|
||||
const exts: string[] = [];
|
||||
return exts;
|
||||
});
|
||||
// Section visibility state
|
||||
@@ -125,7 +125,10 @@ export default function RecipeEditor({ config }: RecipeEditorProps) {
|
||||
delete cleanExtension.enabled;
|
||||
// Remove legacy envs which could potentially include secrets
|
||||
// env_keys will work but rely on the end user having setup those keys themselves
|
||||
delete cleanExtension.envs;
|
||||
if ('envs' in cleanExtension) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
delete (cleanExtension as any).envs;
|
||||
}
|
||||
return cleanExtension;
|
||||
})
|
||||
.filter(Boolean) as FullExtensionConfig[],
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import SplashPills from './SplashPills';
|
||||
import GooseLogo from './GooseLogo';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import MarkdownContent from './MarkdownContent';
|
||||
|
||||
function truncateText(text: string, maxLength: number = 100): string {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import MarkdownContent from './MarkdownContent';
|
||||
import Expand from './ui/Expand';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useRef, useMemo } from 'react';
|
||||
import { useRef, useMemo } from 'react';
|
||||
import LinkPreview from './LinkPreview';
|
||||
import ImagePreview from './ImagePreview';
|
||||
import { extractUrls } from '../utils/urlUtils';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { Goose, Rain } from './icons/Goose';
|
||||
|
||||
export default function WelcomeGooseLogo({ className = '' }) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { ProviderGrid } from './ProviderGrid';
|
||||
import { ScrollArea } from './ui/scroll-area';
|
||||
import { Button } from './ui/button';
|
||||
|
||||
@@ -33,10 +33,10 @@ export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
||||
className={cn(
|
||||
'h-[2px] w-[2px] rounded-full',
|
||||
alert.type === AlertType.Info
|
||||
? i < Math.round((alert.progress.current / alert.progress.total) * 30)
|
||||
? i < Math.round((alert.progress!.current / alert.progress!.total) * 30)
|
||||
? 'dark:bg-black bg-white'
|
||||
: 'dark:bg-black/20 bg-white/20'
|
||||
: i < Math.round((alert.progress.current / alert.progress.total) * 30)
|
||||
: i < Math.round((alert.progress!.current / alert.progress!.total) * 30)
|
||||
? 'bg-white'
|
||||
: 'bg-white/20'
|
||||
)}
|
||||
@@ -46,18 +46,18 @@ export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
||||
<div className="flex justify-between items-baseline text-[11px]">
|
||||
<div className="flex gap-1 items-baseline">
|
||||
<span className={'dark:text-black/60 text-white/60'}>
|
||||
{alert.progress.current >= 1000
|
||||
? (alert.progress.current / 1000).toFixed(1) + 'k'
|
||||
: alert.progress.current}
|
||||
{alert.progress!.current >= 1000
|
||||
? (alert.progress!.current / 1000).toFixed(1) + 'k'
|
||||
: alert.progress!.current}
|
||||
</span>
|
||||
<span className={'dark:text-black/40 text-white/40'}>
|
||||
{Math.round((alert.progress.current / alert.progress.total) * 100)}%
|
||||
{Math.round((alert.progress!.current / alert.progress!.total) * 100)}%
|
||||
</span>
|
||||
</div>
|
||||
<span className={'dark:text-black/60 text-white/60'}>
|
||||
{alert.progress.total >= 1000
|
||||
? (alert.progress.total / 1000).toFixed(0) + 'k'
|
||||
: alert.progress.total}
|
||||
{alert.progress!.total >= 1000
|
||||
? (alert.progress!.total / 1000).toFixed(0) + 'k'
|
||||
: alert.progress!.total}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { all_goose_modes, ModeSelectionItem } from '../settings_v2/mode/ModeSelectionItem';
|
||||
import { useConfig } from '../ConfigContext';
|
||||
import { View, ViewOptions } from '../../App';
|
||||
|
||||
@@ -168,7 +168,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-16 text-right text-sm text-textStandardInverse flex items-center justify-end">
|
||||
{(() => {
|
||||
return localSearchResults?.count > 0 && searchTerm
|
||||
return localSearchResults?.count && localSearchResults.count > 0 && searchTerm
|
||||
? `${localSearchResults.currentIndex}/${localSearchResults.count}`
|
||||
: null;
|
||||
})()}
|
||||
|
||||
@@ -231,23 +231,19 @@ export const SearchView: React.FC<PropsWithChildren<SearchViewProps>> = ({
|
||||
highlighterRef.current = null;
|
||||
}
|
||||
|
||||
// Cancel any pending highlight operations
|
||||
debouncedHighlight.cancel?.();
|
||||
|
||||
// Clear search when closing
|
||||
onSearch?.('', false);
|
||||
}, [debouncedHighlight, onSearch]);
|
||||
}, [onSearch]);
|
||||
|
||||
// Clean up highlighter and debounced functions on unmount
|
||||
// Clean up highlighter on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (highlighterRef.current) {
|
||||
highlighterRef.current.destroy();
|
||||
highlighterRef.current = null;
|
||||
}
|
||||
debouncedHighlight.cancel?.();
|
||||
};
|
||||
}, [debouncedHighlight]);
|
||||
}, []);
|
||||
|
||||
// Listen for keyboard events
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ArrowDown({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ArrowUp({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Attach({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Back({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export function Bars() {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ChatSmart({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Check({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ChevronDown({ className }) {
|
||||
export default function ChevronDown({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
width="1.5rem"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function ChevronUp({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Close({ className }) {
|
||||
export default function Close({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
fill="none"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Copy({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Document({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Edit({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export function Gear({ className = '' }: { className?: string }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
// eslint-disable-next-line
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export function Goose({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Idea({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function More({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Refresh({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Send({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function SensitiveHidden({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function SensitiveVisible({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Settings({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Time({ className = '' }) {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// /Users/mnovich/Development/goose-1.0/ui/desktop/src/components/icons/TrashIcon.tsx
|
||||
import React from 'react';
|
||||
|
||||
interface IconProps extends React.SVGProps<globalThis.SVGSVGElement> {}
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
// Keep the selected session null if there's an error
|
||||
setSelectedSession(null);
|
||||
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
toastError({
|
||||
title: 'Failed to load session. The file may be corrupted.',
|
||||
msg: 'Please try again later.',
|
||||
traceback: err,
|
||||
traceback: errorMessage,
|
||||
});
|
||||
} finally {
|
||||
setIsLoadingSession(false);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
// Import actual PNG images
|
||||
import llamaSprite from '../../assets/battle-game/llama.png';
|
||||
@@ -22,11 +22,10 @@ interface OllamaBattleGameProps {
|
||||
requiredKeys: string[];
|
||||
}
|
||||
|
||||
export function OllamaBattleGame({ onComplete, _requiredKeys }: OllamaBattleGameProps) {
|
||||
export function OllamaBattleGame({ onComplete, requiredKeys: _ }: OllamaBattleGameProps) {
|
||||
// Use Audio element type for audioRef
|
||||
const audioRef = useRef<{ play: () => Promise<void>; pause: () => void; volume: number } | null>(
|
||||
null
|
||||
);
|
||||
// eslint-disable-next-line no-undef
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
const [isMuted, setIsMuted] = useState(false);
|
||||
|
||||
const [battleState, setBattleState] = useState<BattleState>({
|
||||
@@ -169,10 +168,10 @@ export function OllamaBattleGame({ onComplete, _requiredKeys }: OllamaBattleGame
|
||||
if (!currentStep) return;
|
||||
|
||||
// Handle host input
|
||||
if (currentStep.action === 'host_input' && value) {
|
||||
if (currentStep.action === 'host_input' && value && currentStep.configKey) {
|
||||
setConfigValues((prev) => ({
|
||||
...prev,
|
||||
[currentStep.configKey]: value,
|
||||
[currentStep.configKey!]: value,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
@@ -405,8 +404,8 @@ export function OllamaBattleGame({ onComplete, _requiredKeys }: OllamaBattleGame
|
||||
!battleState.processingAction && (
|
||||
<div className="space-y-2">
|
||||
{(typeof battleSteps[battleState.currentStep].choices === 'function'
|
||||
? battleSteps[battleState.currentStep].choices(battleState.lastChoice || '')
|
||||
: battleSteps[battleState.currentStep].choices
|
||||
? (battleSteps[battleState.currentStep].choices as (choice: string) => string[])(battleState.lastChoice || '')
|
||||
: battleSteps[battleState.currentStep].choices as string[]
|
||||
)?.map((choice: string) => (
|
||||
<button
|
||||
key={choice}
|
||||
|
||||
@@ -19,8 +19,8 @@ interface ProviderSetupModalProps {
|
||||
|
||||
export function ProviderSetupModal({
|
||||
provider,
|
||||
_model,
|
||||
_endpoint,
|
||||
_model: _,
|
||||
_endpoint: __,
|
||||
title,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext, useState, ReactNode, useEffect } from 'react';
|
||||
import { createContext, useContext, useState, ReactNode, useEffect } from 'react';
|
||||
import { getActiveProviders } from './utils';
|
||||
import SuspenseLoader from '../../../suspense-loader';
|
||||
|
||||
|
||||
@@ -56,16 +56,16 @@ export async function getActiveProviders(): Promise<string[]> {
|
||||
// For providers with multiple keys or keys without defaults:
|
||||
// Check if all required keys without defaults are set
|
||||
const requiredNonDefaultKeys = providerRequiredKeys.filter(
|
||||
(key) => !(key in default_key_value)
|
||||
(key: string) => !(key in default_key_value)
|
||||
);
|
||||
|
||||
// If there are no non-default keys, this provider needs at least one key explicitly set
|
||||
if (requiredNonDefaultKeys.length === 0) {
|
||||
return providerRequiredKeys.some((key) => configStatus[key]?.is_set === true);
|
||||
return providerRequiredKeys.some((key: string) => configStatus[key]?.is_set === true);
|
||||
}
|
||||
|
||||
// Otherwise, all non-default keys must be set
|
||||
return requiredNonDefaultKeys.every((key) => configStatus[key]?.is_set === true);
|
||||
return requiredNonDefaultKeys.every((key: string) => configStatus[key]?.is_set === true);
|
||||
})
|
||||
.map((provider) => provider.name || 'Unknown Provider');
|
||||
|
||||
@@ -96,14 +96,14 @@ export async function getConfigSettings(): Promise<Record<string, ProviderRespon
|
||||
// Convert the response to the expected format
|
||||
const data: Record<string, ProviderResponse> = {};
|
||||
providers.forEach((provider) => {
|
||||
const providerRequiredKeys = required_keys[provider.name] || [];
|
||||
const providerRequiredKeys = required_keys[provider.name as keyof typeof required_keys] || [];
|
||||
|
||||
data[provider.name] = {
|
||||
name: provider.name,
|
||||
supported: true,
|
||||
description: provider.metadata.description,
|
||||
models: provider.metadata.models,
|
||||
config_status: providerRequiredKeys.reduce<Record<string, ConfigDetails>>((acc, key) => {
|
||||
config_status: providerRequiredKeys.reduce<Record<string, ConfigDetails>>((acc: Record<string, ConfigDetails>, key: string) => {
|
||||
acc[key] = {
|
||||
key,
|
||||
is_set: provider.is_configured,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { all_goose_modes, filterGooseModes, ModeSelectionItem } from './ModeSelectionItem';
|
||||
import { useConfig } from '../../ConfigContext';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Gear } from '../../icons';
|
||||
import { ConfigureApproveMode } from './ConfigureApproveMode';
|
||||
|
||||
|
||||
@@ -74,12 +74,13 @@ export function ConfigureBuiltInExtensionModal({
|
||||
});
|
||||
onSubmit();
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('Error configuring extension:', error);
|
||||
} catch (err) {
|
||||
console.error('Error configuring extension:', err);
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';
|
||||
toastError({
|
||||
title: extension.name,
|
||||
msg: `Failed to configure the extension`,
|
||||
traceback: error.message,
|
||||
traceback: errorMessage,
|
||||
});
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
|
||||
@@ -76,12 +76,13 @@ export function ConfigureExtensionModal({
|
||||
});
|
||||
onSubmit();
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('Error configuring extension:', error);
|
||||
} catch (err) {
|
||||
console.error('Error configuring extension:', err);
|
||||
const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';
|
||||
toastError({
|
||||
title: extension.name,
|
||||
msg: `Failed to configure extension`,
|
||||
traceback: error.message,
|
||||
traceback: errorMessage,
|
||||
});
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
|
||||
@@ -142,7 +142,7 @@ export function ManualExtensionModal({ isOpen, onClose, onSubmit }: ManualExtens
|
||||
<Select
|
||||
options={typeOptions}
|
||||
value={typeOptions.find((option) => option.value === formData.type)}
|
||||
onChange={(option) =>
|
||||
onChange={(option: { value: string; label: string } | null) =>
|
||||
setFormData({ ...formData, type: option?.value as FullExtensionConfig['type'] })
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Input } from '../../ui/input';
|
||||
import Select from 'react-select';
|
||||
@@ -19,7 +19,7 @@ export function AddModelInline() {
|
||||
|
||||
const [selectedProvider, setSelectedProvider] = useState<string | null>(null);
|
||||
const [modelName, setModelName] = useState<string>('');
|
||||
const [filteredModels, setFilteredModels] = useState([]);
|
||||
const [filteredModels, setFilteredModels] = useState<{ id: string; name: string; provider: string }[]>([]);
|
||||
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||
const handleModelSelection = useHandleModelSelection();
|
||||
|
||||
@@ -61,7 +61,7 @@ export function AddModelInline() {
|
||||
setShowSuggestions(false);
|
||||
};
|
||||
|
||||
const handleSelectSuggestion = (suggestion) => {
|
||||
const handleSelectSuggestion = (suggestion: { provider: string; name: string }) => {
|
||||
setModelName(suggestion.name);
|
||||
setShowSuggestions(false); // Hide suggestions after selection
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext, useState, ReactNode } from 'react';
|
||||
import { createContext, useContext, useState, ReactNode } from 'react';
|
||||
import { GOOSE_MODEL, GOOSE_PROVIDER } from '../../../env_vars';
|
||||
import { gooseModels } from './GooseModels'; // Assuming hardcoded models are here
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { RecentModels } from './RecentModels';
|
||||
import { ProviderButtons } from './ProviderButtons';
|
||||
import BackButton from '../../ui/BackButton';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Switch } from '../../ui/switch';
|
||||
import { useActiveKeys } from '../api_keys/ActiveKeysContext';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Clock } from 'lucide-react';
|
||||
import { Model } from './ModelContext';
|
||||
import { ModelRadioList, SeeMoreModelsButtons } from './ModelRadioList';
|
||||
|
||||
@@ -49,7 +49,7 @@ export function useHandleModelSelection() {
|
||||
};
|
||||
}
|
||||
|
||||
export function createSelectedModel(selectedProvider, modelName) {
|
||||
export function createSelectedModel(selectedProvider: string, modelName: string) {
|
||||
let selectedModel = gooseModels.find(
|
||||
(model) =>
|
||||
model.provider.toLowerCase() === selectedProvider &&
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { Check, Plus, Settings, X, Rocket } from 'lucide-react';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/Tooltip';
|
||||
@@ -34,7 +33,7 @@ function getArticle(word: string): string {
|
||||
return 'aeiouAEIOU'.indexOf(word[0]) >= 0 ? 'an' : 'a';
|
||||
}
|
||||
|
||||
export function getProviderDescription(provider) {
|
||||
export function getProviderDescription(provider: string) {
|
||||
const descriptions = {
|
||||
OpenAI: 'Access GPT-4 and other OpenAI models, including OpenAI compatible ones',
|
||||
Anthropic: 'Access Claude and other Anthropic models',
|
||||
@@ -44,7 +43,7 @@ export function getProviderDescription(provider) {
|
||||
OpenRouter: 'Access a variety of AI models through OpenRouter',
|
||||
Ollama: 'Run and use open-source models locally',
|
||||
};
|
||||
return descriptions[provider] || `Access ${provider} models`;
|
||||
return descriptions[provider as keyof typeof descriptions] || `Access ${provider} models`;
|
||||
}
|
||||
|
||||
function BaseProviderCard({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useActiveKeys } from '../api_keys/ActiveKeysContext';
|
||||
import { BaseProviderGrid, getProviderDescription } from './BaseProviderGrid';
|
||||
import { supported_providers, provider_aliases, required_keys } from '../models/hardcoded_stuff';
|
||||
@@ -43,7 +43,7 @@ export function ConfigureProvidersGrid() {
|
||||
const [selectedForSetup, setSelectedForSetup] = useState<string | null>(null);
|
||||
const [modalMode, setModalMode] = useState<'edit' | 'setup' | 'battle'>('setup');
|
||||
const [isConfirmationOpen, setIsConfirmationOpen] = useState(false);
|
||||
const [providerToDelete, setProviderToDelete] = useState(null);
|
||||
const [providerToDelete, setProviderToDelete] = useState<{ name: string; id: string; isConfigured: boolean; description: string } | null>(null);
|
||||
const { currentModel } = useModel();
|
||||
|
||||
const providers = useMemo(() => {
|
||||
@@ -170,7 +170,7 @@ export function ConfigureProvidersGrid() {
|
||||
const confirmDelete = async () => {
|
||||
if (!providerToDelete) return;
|
||||
|
||||
const requiredKeys = required_keys[providerToDelete.name];
|
||||
const requiredKeys = required_keys[providerToDelete.name as keyof typeof required_keys];
|
||||
if (!requiredKeys || requiredKeys.length === 0) {
|
||||
console.error(`No keys found for provider ${providerToDelete.name}`);
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { ScrollArea } from '../../ui/scroll-area';
|
||||
import BackButton from '../../ui/BackButton';
|
||||
import { ConfigureProvidersGrid } from './ConfigureProvidersGrid';
|
||||
|
||||
@@ -29,11 +29,11 @@ export async function extensionApiCall(
|
||||
};
|
||||
|
||||
// for adding the payload is an extensionConfig, for removing payload is just the name
|
||||
const extensionName = isActivating ? payload.name : payload;
|
||||
const extensionName = isActivating ? (payload as ExtensionConfig).name : payload as string;
|
||||
let toastId;
|
||||
|
||||
// Step 1: Show loading toast (only for activation of stdio)
|
||||
if (isActivating && (payload as ExtensionConfig) && payload.type == 'stdio') {
|
||||
if (isActivating && typeof payload === 'object' && payload.type === 'stdio') {
|
||||
toastId = toastService.loading({
|
||||
title: extensionName,
|
||||
msg: `${action.verb} ${extensionName} extension...`,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Input } from '../../../ui/input';
|
||||
import React from 'react';
|
||||
|
||||
interface ExtensionConfigFieldsProps {
|
||||
type: 'stdio' | 'sse' | 'builtin';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Button } from '../../../ui/button';
|
||||
import Modal from '../../../Modal';
|
||||
import { ExtensionFormData } from '../utils';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Input } from '../../../ui/input';
|
||||
import React from 'react';
|
||||
|
||||
interface ExtensionTimeoutFieldProps {
|
||||
timeout: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Switch } from '../../../ui/switch';
|
||||
import { Gear } from '../../../icons/Gear';
|
||||
import { FixedExtensionEntry } from '../../../ConfigContext';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { FixedExtensionEntry } from '../../../ConfigContext';
|
||||
import { ExtensionConfig } from '../../../../api/types.gen';
|
||||
import ExtensionItem from './ExtensionItem';
|
||||
|
||||
@@ -83,7 +83,7 @@ export function extensionToFormData(extension: FixedExtensionEntry): ExtensionFo
|
||||
cmd: extension.type === 'stdio' ? combineCmdAndArgs(extension.cmd, extension.args) : undefined,
|
||||
endpoint: extension.type === 'sse' ? extension.uri : undefined,
|
||||
enabled: extension.enabled,
|
||||
timeout: extension.timeout,
|
||||
timeout: 'timeout' in extension ? extension.timeout : undefined,
|
||||
envVars,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import type { View } from '../../../App';
|
||||
import ModelSettingsButtons from './subcomponents/ModelSettingsButtons';
|
||||
import { useConfig } from '../../ConfigContext';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Button } from '../../../ui/button';
|
||||
import { AddModelModal } from './AddModelModal';
|
||||
import type { View } from '../../../../App';
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { View } from '../../../../App';
|
||||
import Model, { getProviderMetadata } from '../modelInterface';
|
||||
import { useModel } from '../../../settings/models/ModelContext';
|
||||
|
||||
const ModalButtons = ({ onSubmit, onCancel, _isValid, _validationErrors }) => (
|
||||
const ModalButtons = ({ onSubmit, onCancel, _isValid: _, _validationErrors: __ }) => (
|
||||
<div>
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -40,8 +40,8 @@ type AddModelModalProps = {
|
||||
export const AddModelModal = ({ onClose, setView }: AddModelModalProps) => {
|
||||
const { getProviders, upsert } = useConfig();
|
||||
const { switchModel } = useModel();
|
||||
const [providerOptions, setProviderOptions] = useState([]);
|
||||
const [modelOptions, setModelOptions] = useState([]);
|
||||
const [providerOptions, setProviderOptions] = useState<{ value: string; label: string }[]>([]);
|
||||
const [modelOptions, setModelOptions] = useState<{ options: { value: string; label: string; provider: string }[] }[]>([]);
|
||||
const [provider, setProvider] = useState<string | null>(null);
|
||||
const [model, setModel] = useState<string>('');
|
||||
const [isCustomModel, setIsCustomModel] = useState(false);
|
||||
@@ -169,7 +169,7 @@ export const AddModelModal = ({ onClose, setView }: AddModelModalProps) => {
|
||||
};
|
||||
|
||||
// Store the original model options in state, initialized from modelOptions
|
||||
const [originalModelOptions, setOriginalModelOptions] = useState(modelOptions);
|
||||
const [originalModelOptions, setOriginalModelOptions] = useState<{ options: { value: string; label: string; provider: string }[] }[]>(modelOptions);
|
||||
|
||||
const handleInputChange = (inputValue: string) => {
|
||||
if (!provider) return;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { AddModelButton } from './AddModelButton';
|
||||
import { Button } from '../../../ui/button';
|
||||
import { Sliders } from 'lucide-react';
|
||||
import React from 'react';
|
||||
import type { View } from '../../../../App';
|
||||
|
||||
interface ConfigureModelButtonsProps {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
||||
import { useEffect, useState, useCallback, useRef } from 'react';
|
||||
import { ScrollArea } from '../../ui/scroll-area';
|
||||
import BackButton from '../../ui/BackButton';
|
||||
import ProviderGrid from './ProviderGrid';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Modal from '../../../../components/Modal';
|
||||
import ProviderSetupHeader from './subcomponents/ProviderSetupHeader';
|
||||
import DefaultProviderSetupForm from './subcomponents/forms/DefaultProviderSetupForm';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import OpenAILogo from './icons/openai@3x.png';
|
||||
import AnthropicLogo from './icons/anthropic@3x.png';
|
||||
import GoogleLogo from './icons/google@3x.png';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { SyntheticEvent } from 'react';
|
||||
import { SyntheticEvent } from 'react';
|
||||
import { Button } from '../../../../ui/button';
|
||||
import { Trash2, AlertTriangle } from 'lucide-react';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { ExternalLink } from 'lucide-react';
|
||||
import { QUICKSTART_GUIDE_URL } from '../constants';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { Lock } from 'lucide-react';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { PROVIDER_REGISTRY } from '../../../ProviderRegistry';
|
||||
import { Input } from '../../../../../ui/input';
|
||||
import React from 'react';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { memo } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { GreenCheckButton } from './buttons/CardButtons';
|
||||
import { ConfiguredProviderTooltipMessage, ProviderDescription } from './utils/StringUtils';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import { memo, useMemo } from 'react';
|
||||
import CardContainer from './CardContainer';
|
||||
import CardHeader from './CardHeader';
|
||||
import CardBody from './CardBody';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import { ConfigureSettingsButton, RocketButton } from './CardButtons';
|
||||
import { ProviderDetails } from '../../../../../api';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
// Functions for string / string-based element creation (e.g. tooltips for each provider, descriptions, etc)
|
||||
export function OllamaNotConfiguredTooltipMessage() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Box({ size }: { size: number }) {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BaseModal } from './BaseModal';
|
||||
import React from 'react';
|
||||
|
||||
export function ConfirmationModal({
|
||||
isOpen,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* CustomRadio - A reusable radio button component with dark mode support
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import ReactSelect from 'react-select';
|
||||
|
||||
export const Select = (props) => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Send({ size }: { size: number }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
interface StopProps {
|
||||
size?: number;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user