- {paywallContent ?? (
-
-
-
-
-
Pro Feature
-
- Upgrade to Pro to avail this feature
-
-
-
-
- Pro Exclusive
-
-
- )}
+
+
+
+
-
-
-
-
- >
- )}
+
+
Upgrade to unlock
+
+ Get access to premium models and features
+
+
+
+
+
+
+
+
+
>
);
-};
+};
\ No newline at end of file
diff --git a/frontend/src/components/thread/chat-input.tsx b/frontend/src/components/thread/chat-input.tsx
index 940ecbc3..0a6e123a 100644
--- a/frontend/src/components/thread/chat-input.tsx
+++ b/frontend/src/components/thread/chat-input.tsx
@@ -57,7 +57,7 @@ const API_URL = process.env.NEXT_PUBLIC_BACKEND_URL || '';
// Local storage keys
const STORAGE_KEY_MODEL = 'suna-preferred-model';
-const DEFAULT_MODEL_ID = 'sonnet-3.7'; // Define default model ID
+const DEFAULT_MODEL_ID = 'qwen3'; // Define default model ID
interface ChatInputProps {
onSubmit: (
diff --git a/frontend/src/components/thread/chat-input/_use-model-selection.ts b/frontend/src/components/thread/chat-input/_use-model-selection.ts
index ced7718a..d3a18a84 100644
--- a/frontend/src/components/thread/chat-input/_use-model-selection.ts
+++ b/frontend/src/components/thread/chat-input/_use-model-selection.ts
@@ -4,104 +4,97 @@ import { useSubscription } from '@/hooks/react-query/subscriptions/use-subscript
import { useState, useEffect } from 'react';
export const STORAGE_KEY_MODEL = 'suna-preferred-model';
-export const DEFAULT_MODEL_ID = 'qwen3-4b';
+export const DEFAULT_MODEL_ID = 'qwen3';
-export type SubscriptionTier = 'free' | 'base' | 'extra';
-
-export type ModelTier = 'free' | 'base-only' | 'extra-only';
+export type SubscriptionStatus = 'no_subscription' | 'active';
export interface ModelOption {
id: string;
label: string;
- tier: ModelTier;
+ requiresSubscription: boolean;
+ description?: string;
}
export const MODEL_OPTIONS: ModelOption[] = [
- { id: 'qwen3-4b', label: 'Qwen 3', tier: 'free' },
- { id: 'sonnet-3.7', label: 'Sonnet 3.7', tier: 'base-only' },
+ {
+ id: 'qwen3',
+ label: 'Free',
+ requiresSubscription: false,
+ description: 'Limited capabilities. Upgrade for full performance.'
+ },
+ {
+ id: 'sonnet-3.7',
+ label: 'Standard',
+ requiresSubscription: true,
+ description: 'Excellent for complex tasks and nuanced conversations'
+ },
];
export const canAccessModel = (
- subscriptionTier: SubscriptionTier,
- modelTier: ModelTier,
+ subscriptionStatus: SubscriptionStatus,
+ requiresSubscription: boolean,
): boolean => {
- switch (modelTier) {
- case 'free':
- return true;
- case 'base-only':
- return subscriptionTier === 'base' || subscriptionTier === 'extra';
- case 'extra-only':
- return subscriptionTier === 'extra';
- default:
- return false;
- }
+ return subscriptionStatus === 'active' || !requiresSubscription;
};
export const useModelSelection = () => {
const [selectedModel, setSelectedModel] = useState(DEFAULT_MODEL_ID);
-
+
const { data: subscriptionData } = useSubscription();
- const subscriptionTier: SubscriptionTier = (() => {
- if (!subscriptionData) return 'free';
- if (subscriptionData.plan_name === 'free') return 'free';
- if (subscriptionData.plan_name === 'base') return 'base';
- if (subscriptionData.plan_name === 'extra') return 'extra';
- return 'free';
- })();
+
+ const subscriptionStatus: SubscriptionStatus = subscriptionData?.status === 'active'
+ ? 'active'
+ : 'no_subscription';
useEffect(() => {
- if (typeof window !== 'undefined') {
- try {
- const savedModel = localStorage.getItem(STORAGE_KEY_MODEL);
- if (
- savedModel &&
- MODEL_OPTIONS.some((option) => option.id === savedModel)
- ) {
- const modelOption = MODEL_OPTIONS.find(
- (option) => option.id === savedModel,
- );
- if (
- modelOption &&
- canAccessModel(subscriptionTier, modelOption.tier)
- ) {
- setSelectedModel(savedModel);
- } else {
- setSelectedModel(DEFAULT_MODEL_ID);
- }
- } else if (savedModel) {
- localStorage.removeItem(STORAGE_KEY_MODEL);
- }
- } catch (error) {
- console.warn('Failed to load preferences from localStorage:', error);
+ if (typeof window === 'undefined') return;
+
+ try {
+ const savedModel = localStorage.getItem(STORAGE_KEY_MODEL);
+ if (!savedModel) return;
+
+ const modelOption = MODEL_OPTIONS.find(option => option.id === savedModel);
+
+ if (modelOption && canAccessModel(subscriptionStatus, modelOption.requiresSubscription)) {
+ setSelectedModel(savedModel);
+ } else {
+ localStorage.removeItem(STORAGE_KEY_MODEL);
+ setSelectedModel(DEFAULT_MODEL_ID);
}
+ } catch (error) {
+ console.warn('Failed to load preferences from localStorage:', error);
}
- }, [subscriptionTier]);
+ }, [subscriptionStatus]);
- const handleModelChange = (value: string) => {
- const modelOption = MODEL_OPTIONS.find((option) => option.id === value);
- if (modelOption && canAccessModel(subscriptionTier, modelOption.tier)) {
- setSelectedModel(value);
- try {
- localStorage.setItem(STORAGE_KEY_MODEL, value);
- } catch (error) {
- console.warn('Failed to save model preference to localStorage:', error);
- }
+ const handleModelChange = (modelId: string) => {
+ const modelOption = MODEL_OPTIONS.find(option => option.id === modelId);
+
+ if (!modelOption || !canAccessModel(subscriptionStatus, modelOption.requiresSubscription)) {
+ return;
+ }
+
+ setSelectedModel(modelId);
+ try {
+ localStorage.setItem(STORAGE_KEY_MODEL, modelId);
+ } catch (error) {
+ console.warn('Failed to save model preference to localStorage:', error);
}
};
- const availableModels = MODEL_OPTIONS.filter((model) =>
- canAccessModel(subscriptionTier, model.tier),
- );
-
return {
selectedModel,
setSelectedModel: handleModelChange,
- subscriptionTier,
- availableModels,
+ subscriptionStatus,
+ availableModels: MODEL_OPTIONS.filter(model =>
+ canAccessModel(subscriptionStatus, model.requiresSubscription)
+ ),
allModels: MODEL_OPTIONS,
canAccessModel: (modelId: string) => {
- const model = MODEL_OPTIONS.find((m) => m.id === modelId);
- return model ? canAccessModel(subscriptionTier, model.tier) : false;
+ const model = MODEL_OPTIONS.find(m => m.id === modelId);
+ return model ? canAccessModel(subscriptionStatus, model.requiresSubscription) : false;
},
+ isSubscriptionRequired: (modelId: string) => {
+ return MODEL_OPTIONS.find(m => m.id === modelId)?.requiresSubscription || false;
+ }
};
-};
+};
\ No newline at end of file
diff --git a/frontend/src/components/thread/chat-input/chat-input.tsx b/frontend/src/components/thread/chat-input/chat-input.tsx
index 78869495..96f2535d 100644
--- a/frontend/src/components/thread/chat-input/chat-input.tsx
+++ b/frontend/src/components/thread/chat-input/chat-input.tsx
@@ -76,7 +76,7 @@ export const ChatInput = forwardRef
(
const {
selectedModel,
setSelectedModel: handleModelChange,
- subscriptionTier,
+ subscriptionStatus,
allModels: modelOptions,
canAccessModel,
} = useModelSelection();
@@ -188,8 +188,8 @@ export const ChatInput = forwardRef(
}
}}
>
-
-
+
+
(
selectedModel={selectedModel}
onModelChange={handleModelChange}
modelOptions={modelOptions}
- currentTier={subscriptionTier}
+ subscriptionStatus={subscriptionStatus}
canAccessModel={canAccessModel}
/>
diff --git a/frontend/src/components/thread/chat-input/message-input.tsx b/frontend/src/components/thread/chat-input/message-input.tsx
index 126932e0..7dac5c69 100644
--- a/frontend/src/components/thread/chat-input/message-input.tsx
+++ b/frontend/src/components/thread/chat-input/message-input.tsx
@@ -6,7 +6,6 @@ import { cn } from '@/lib/utils';
import { UploadedFile } from './chat-input';
import { FileUploadHandler } from './file-upload-handler';
import { ModelSelector } from './model-selector';
-import { useModelSelection } from './_use-model-selection';
interface MessageInputProps {
value: string;
@@ -31,7 +30,7 @@ interface MessageInputProps {
selectedModel: string;
onModelChange: (model: string) => void;
modelOptions: any[];
- currentTier: string;
+ subscriptionStatus: string;
canAccessModel: (model: string) => boolean;
}
@@ -60,7 +59,7 @@ export const MessageInput = forwardRef
(
selectedModel,
onModelChange,
modelOptions,
- currentTier,
+ subscriptionStatus,
canAccessModel,
},
ref,
@@ -87,10 +86,6 @@ export const MessageInput = forwardRef(
return () => window.removeEventListener('resize', adjustHeight);
}, [value, ref]);
- const {
- subscriptionTier,
- } = useModelSelection();
-
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
@@ -145,7 +140,6 @@ export const MessageInput = forwardRef(
selectedModel={selectedModel}
onModelChange={onModelChange}
modelOptions={modelOptions}
- currentTier={subscriptionTier}
canAccessModel={canAccessModel}
/>