mirror of https://github.com/kortix-ai/suna.git
fix: copy
This commit is contained in:
parent
b16a452920
commit
2d6ec3d59d
|
@ -54,7 +54,7 @@ export const MODELS = {
|
|||
'gpt-4.1': {
|
||||
tier: 'premium',
|
||||
priority: 95,
|
||||
recommended: true,
|
||||
recommended: false,
|
||||
lowQuality: false,
|
||||
description: 'GPT-4.1 - OpenAI\'s most advanced model with enhanced reasoning'
|
||||
},
|
||||
|
|
|
@ -77,9 +77,11 @@ export const CustomModelDialog: React.FC<CustomModelDialogProps> = ({
|
|||
<DialogHeader>
|
||||
<DialogTitle>{mode === 'add' ? 'Add Custom Model' : 'Edit Custom Model'}</DialogTitle>
|
||||
<DialogDescription>
|
||||
Enter the model ID (use <code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">openrouter/</code> prefix for OpenRouter models). See <a href="https://docs.litellm.ai/docs/" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 underline">LiteLLM docs</a>; you may need to modify <code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">llm.py</code>.
|
||||
Kortix Suna uses <b>LiteLLM</b> under the hood, which makes it compatible with over 100 models. You can easily choose any <a href="https://openrouter.ai/models" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 underline">OpenRouter model</a> by prefixing it with <code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">openrouter/</code> and it should work out of the box. If you want to use other models besides OpenRouter, you might have to modify the <a href="https://github.com/kortix-ai/suna/blob/main/backend/services/llm.py" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 underline">llm.py</a>, set the correct environment variables, and rebuild your self-hosted Docker container.
|
||||
</DialogDescription>
|
||||
|
||||
|
||||
|
||||
</DialogHeader>
|
||||
<div className="flex flex-col gap-4 py-4">
|
||||
<div className="flex flex-col items-start gap-4">
|
||||
|
|
|
@ -8,6 +8,9 @@ import { FileUploadHandler } from './file-upload-handler';
|
|||
import { ModelSelector } from './model-selector';
|
||||
import { SubscriptionStatus } from './_use-model-selection';
|
||||
import { isLocalMode } from '@/lib/config';
|
||||
import { TooltipContent } from '@/components/ui/tooltip';
|
||||
import { Tooltip } from '@/components/ui/tooltip';
|
||||
import { TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip';
|
||||
|
||||
interface MessageInputProps {
|
||||
value: string;
|
||||
|
@ -137,7 +140,7 @@ export const MessageInput = forwardRef<HTMLTextAreaElement, MessageInputProps>(
|
|||
|
||||
|
||||
</div>
|
||||
{subscriptionStatus === 'no_subscription' && !isLocalMode() && <p className='text-sm text-amber-500'>Free plan. Upgrade.</p>}
|
||||
{subscriptionStatus === 'no_subscription' && !isLocalMode() && <TooltipProvider><Tooltip><TooltipTrigger><p className='text-sm text-amber-500'>Upgrade for full performance</p></TooltipTrigger><TooltipContent><p>The free tier is severely limited by inferior models; upgrade to experience the true full Suna experience.</p></TooltipContent></Tooltip></TooltipProvider>}
|
||||
<div className='flex items-center gap-2'>
|
||||
<ModelSelector
|
||||
selectedModel={selectedModel}
|
||||
|
|
|
@ -388,7 +388,9 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|||
<AlertTriangle className="h-3.5 w-3.5 text-amber-500" />
|
||||
)}
|
||||
{isRecommended && (
|
||||
<Brain className="h-3.5 w-3.5 text-blue-500" />
|
||||
<span className="text-xs px-1.5 py-0.5 rounded-sm bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300 font-medium">
|
||||
Recommended
|
||||
</span>
|
||||
)}
|
||||
{isPremium && !accessible && (
|
||||
<Crown className="h-3.5 w-3.5 text-blue-500" />
|
||||
|
@ -531,7 +533,9 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|||
<AlertTriangle className="h-3.5 w-3.5 text-amber-500" />
|
||||
)}
|
||||
{(MODELS[model.id]?.recommended || false) && (
|
||||
<Brain className="h-3.5 w-3.5 text-blue-500" />
|
||||
<span className="text-xs px-1.5 py-0.5 rounded-sm bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300 font-medium">
|
||||
Recommended
|
||||
</span>
|
||||
)}
|
||||
{selectedModel === model.id && (
|
||||
<Check className="h-4 w-4 text-blue-500" />
|
||||
|
@ -580,7 +584,9 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|||
<div className="flex items-center gap-2">
|
||||
{/* Show capabilities */}
|
||||
{MODELS[model.id]?.recommended && (
|
||||
<Brain className="h-3.5 w-3.5 text-blue-500" />
|
||||
<span className="text-xs px-1.5 py-0.5 rounded-sm bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300 font-medium whitespace-nowrap">
|
||||
Recommended
|
||||
</span>
|
||||
)}
|
||||
<Crown className="h-3.5 w-3.5 text-blue-500" />
|
||||
</div>
|
||||
|
@ -648,10 +654,34 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
|
|||
</TooltipProvider>
|
||||
)}
|
||||
</div>
|
||||
{uniqueModels.filter(m =>
|
||||
m.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
m.id.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
).map((model, index) => renderModelOption(model, index))}
|
||||
{uniqueModels
|
||||
.filter(m =>
|
||||
m.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
m.id.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
)
|
||||
// Sort to prioritize recommended paid models first
|
||||
.sort((a, b) => {
|
||||
const aRecommendedPaid = MODELS[a.id]?.recommended && a.requiresSubscription;
|
||||
const bRecommendedPaid = MODELS[b.id]?.recommended && b.requiresSubscription;
|
||||
|
||||
if (aRecommendedPaid && !bRecommendedPaid) return -1;
|
||||
if (!aRecommendedPaid && bRecommendedPaid) return 1;
|
||||
|
||||
// Secondary sorting: recommended free models next
|
||||
const aRecommended = MODELS[a.id]?.recommended;
|
||||
const bRecommended = MODELS[b.id]?.recommended;
|
||||
|
||||
if (aRecommended && !bRecommended) return -1;
|
||||
if (!aRecommended && bRecommended) return 1;
|
||||
|
||||
// Paid models next
|
||||
if (a.requiresSubscription && !b.requiresSubscription) return -1;
|
||||
if (!a.requiresSubscription && b.requiresSubscription) return 1;
|
||||
|
||||
// Default to alphabetical order
|
||||
return a.label.localeCompare(b.label);
|
||||
})
|
||||
.map((model, index) => renderModelOption(model, index))}
|
||||
|
||||
{uniqueModels.length === 0 && (
|
||||
<div className="text-sm text-center py-4 text-muted-foreground">
|
||||
|
|
Loading…
Reference in New Issue