From 189c462e18292b7b6abc5f8e9ef958aac9e19030 Mon Sep 17 00:00:00 2001
From: blackhao <13851610112@163.com>
Date: Sun, 14 Dec 2025 02:21:04 -0600
Subject: model management

---
 frontend/src/components/Sidebar.tsx | 40 ++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 12 deletions(-)

(limited to 'frontend/src/components/Sidebar.tsx')

diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx
index 4febe4f..dac853f 100644
--- a/frontend/src/components/Sidebar.tsx
+++ b/frontend/src/components/Sidebar.tsx
@@ -21,9 +21,14 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
     files, uploadFile, refreshFiles, addFileScope, removeFileScope, currentBlueprintPath,
     saveCurrentBlueprint
   } = useFlowStore();
-  const { getAuthHeader } = useAuthStore();
+  const { getAuthHeader, user } = useAuthStore();
   const { setCenter, getViewport } = useReactFlow();
   const isDark = theme === 'dark';
+  
+  // Premium models and authorized users
+  const PREMIUM_USERS = ['test', 'blackhao'];
+  const canUsePremiumModels = user?.username ? PREMIUM_USERS.includes(user.username) : false;
+  // Premium models: gpt-4.5-preview, gpt-5-pro, gpt-5.2-pro, o3
   const [activeTab, setActiveTab] = useState<'interact' | 'settings' | 'debug'>('interact');
   const [streamBuffer, setStreamBuffer] = useState('');
   const [streamingNodeId, setStreamingNodeId] = useState<string | null>(null); // Track which node is streaming
@@ -1000,7 +1005,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
     try {
       // Determine provider
       const isOpenAI = modelAtSend.includes('gpt') || modelAtSend === 'o3';
-      const reasoningModels = ['gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'o3'];
+      const reasoningModels = ['gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3'];
       const isReasoning = reasoningModels.includes(modelAtSend);
 
       // Build scopes for file search (Quick Chat uses a temp scope)
@@ -1407,7 +1412,8 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                   // Auto-set temperature to 1 for reasoning models
                   const reasoningModels = [
                     'gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 
-                    'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'o3'
+                    'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 
+                    'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3'
                   ];
                   const isReasoning = reasoningModels.includes(newModel);
                   
@@ -1425,6 +1431,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                 </optgroup>
                 <optgroup label="OpenAI (Standard)">
                   <option value="gpt-4.1">gpt-4.1</option>
+                  <option value="gpt-4.5-preview" disabled={!canUsePremiumModels}>gpt-4.5-preview {!canUsePremiumModels && '🔒'}</option>
                   <option value="gpt-4o">gpt-4o</option>
                 </optgroup>
                 <optgroup label="OpenAI (Reasoning)">
@@ -1432,10 +1439,13 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                   <option value="gpt-5-chat-latest">gpt-5-chat-latest</option>
                   <option value="gpt-5-mini">gpt-5-mini</option>
                   <option value="gpt-5-nano">gpt-5-nano</option>
-                  <option value="gpt-5-pro">gpt-5-pro</option>
+                  <option value="gpt-5-pro" disabled={!canUsePremiumModels}>gpt-5-pro {!canUsePremiumModels && '🔒'}</option>
                   <option value="gpt-5.1">gpt-5.1</option>
                   <option value="gpt-5.1-chat-latest">gpt-5.1-chat-latest</option>
-                  <option value="o3">o3</option>
+                  <option value="gpt-5.2">gpt-5.2</option>
+                  <option value="gpt-5.2-chat-latest">gpt-5.2-chat-latest</option>
+                  <option value="gpt-5.2-pro" disabled={!canUsePremiumModels}>gpt-5.2-pro {!canUsePremiumModels && '🔒'}</option>
+                  <option value="o3" disabled={!canUsePremiumModels}>o3 {!canUsePremiumModels && '🔒'}</option>
                 </optgroup>
               </select>
             </div>
@@ -1957,7 +1967,8 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                 Temperature ({selectedNode.data.temperature})
                 {[
                   'gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 
-                  'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'o3'
+                  'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest',
+                  'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3'
                 ].includes(selectedNode.data.model) && (
                   <span className="text-xs text-orange-500 ml-2">(Locked for Reasoning Model)</span>
                 )}
@@ -1971,7 +1982,8 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                 onChange={(e) => handleChange('temperature', parseFloat(e.target.value))}
                 disabled={[
                   'gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 
-                  'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'o3'
+                  'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest',
+                  'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3'
                 ].includes(selectedNode.data.model)}
                 className="w-full disabled:opacity-50 disabled:cursor-not-allowed"
               />
@@ -1980,7 +1992,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
             {/* Reasoning Effort - Only for OpenAI reasoning models (except chat-latest) */}
             {[
               'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 
-              'gpt-5-pro', 'gpt-5.1', 'o3'
+              'gpt-5-pro', 'gpt-5.1', 'gpt-5.2', 'gpt-5.2-pro', 'o3'
             ].includes(selectedNode.data.model) && (
               <div>
                 <label className="block text-sm font-medium text-gray-700 mb-1">
@@ -2415,6 +2427,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                   </optgroup>
                   <optgroup label="OpenAI (Standard)">
                     <option value="gpt-4.1">gpt-4.1</option>
+                    <option value="gpt-4.5-preview" disabled={!canUsePremiumModels}>gpt-4.5-preview {!canUsePremiumModels && '🔒'}</option>
                     <option value="gpt-4o">gpt-4o</option>
                   </optgroup>
                   <optgroup label="OpenAI (Reasoning)">
@@ -2422,10 +2435,13 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
                     <option value="gpt-5-chat-latest">gpt-5-chat-latest</option>
                     <option value="gpt-5-mini">gpt-5-mini</option>
                     <option value="gpt-5-nano">gpt-5-nano</option>
-                    <option value="gpt-5-pro">gpt-5-pro</option>
+                    <option value="gpt-5-pro" disabled={!canUsePremiumModels}>gpt-5-pro {!canUsePremiumModels && '🔒'}</option>
                     <option value="gpt-5.1">gpt-5.1</option>
                     <option value="gpt-5.1-chat-latest">gpt-5.1-chat-latest</option>
-                    <option value="o3">o3</option>
+                    <option value="gpt-5.2">gpt-5.2</option>
+                    <option value="gpt-5.2-chat-latest">gpt-5.2-chat-latest</option>
+                    <option value="gpt-5.2-pro" disabled={!canUsePremiumModels}>gpt-5.2-pro {!canUsePremiumModels && '🔒'}</option>
+                    <option value="o3" disabled={!canUsePremiumModels}>o3 {!canUsePremiumModels && '🔒'}</option>
                   </optgroup>
                 </select>
                 <button onClick={closeQuickChat} className={`p-1 rounded ${isDark ? 'hover:bg-gray-700' : 'hover:bg-gray-200'}`}>
@@ -2541,7 +2557,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
               isDark ? 'border-gray-700 bg-gray-800' : 'border-gray-100 bg-white'
             }`}>
               {/* Temperature (hide for reasoning models) */}
-              {!['gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'o3'].includes(quickChatModel) && (
+              {!['gpt-5', 'gpt-5-chat-latest', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.1-chat-latest', 'gpt-5.2', 'gpt-5.2-chat-latest', 'gpt-5.2-pro', 'o3'].includes(quickChatModel) && (
                 <div className="flex items-center gap-2">
                   <span className={isDark ? 'text-gray-400' : 'text-gray-500'}>Temp:</span>
                   <input
@@ -2558,7 +2574,7 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
               )}
               
               {/* Reasoning Effort (only for reasoning models, except chat-latest) */}
-              {['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'o3'].includes(quickChatModel) && (
+              {['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro', 'gpt-5.1', 'gpt-5.2', 'gpt-5.2-pro', 'o3'].includes(quickChatModel) && (
                 <div className="flex items-center gap-2">
                   <span className={isDark ? 'text-gray-400' : 'text-gray-500'}>Effort:</span>
                   <select
-- 
cgit v1.2.3

