@@ -7,7 +7,9 @@ let chatbox, userInput, sendButton, clearButton, sidebarPanel, toggleSidebarButt
77 temperatureValue , maxOutputTokensSlider , maxOutputTokensValue , topPSlider ,
88 topPValue , stopSequencesInput , saveModelSettingsButton , resetModelSettingsButton ,
99 settingsStatusElement , apiKeyStatus , newApiKeyInput , toggleApiKeyVisibilityButton ,
10- testApiKeyButton , apiKeyList ;
10+ testApiKeyButton , apiKeyList ,
11+ enableThinkingToggle , thinkingLevelSelector , thinkingBudgetSlider , thinkingBudgetValue ,
12+ enableGoogleSearchToggle ;
1113
1214function initializeDOMReferences ( ) {
1315 chatbox = document . getElementById ( 'chatbox' ) ;
@@ -44,6 +46,14 @@ function initializeDOMReferences() {
4446 resetModelSettingsButton = document . getElementById ( 'resetModelSettingsButton' ) ;
4547 settingsStatusElement = document . getElementById ( 'settings-status' ) ;
4648
49+ enableThinkingToggle = document . getElementById ( 'enableThinkingToggle' ) ;
50+ thinkingLevelSelector = document . getElementById ( 'thinkingLevelSelector' ) ;
51+ thinkingBudgetSlider = document . getElementById ( 'thinkingBudgetSlider' ) ;
52+ thinkingBudgetValue = document . getElementById ( 'thinkingBudgetValue' ) ;
53+
54+ enableGoogleSearchToggle = document . getElementById ( 'enableGoogleSearchToggle' ) ;
55+
56+
4757 // API密钥管理元素
4858 apiKeyStatus = document . getElementById ( 'apiKeyStatus' ) ;
4959 newApiKeyInput = document . getElementById ( 'newApiKey' ) ;
@@ -52,6 +62,29 @@ function initializeDOMReferences() {
5262 apiKeyList = document . getElementById ( 'apiKeyList' ) ;
5363}
5464
65+ function modelUsesThinkingLevel ( modelId ) {
66+ try {
67+ const id = String ( modelId || '' ) . toLowerCase ( ) ;
68+ return id . includes ( 'gemini-3' ) && id . includes ( 'pro' ) ;
69+ } catch ( e ) {
70+ return false ;
71+ }
72+ }
73+
74+ function computeReasoningEffort ( settings ) {
75+ try {
76+ if ( ! settings . enableThinking ) return 0 ;
77+ const lvl = ( settings . thinkingLevel || '' ) . toLowerCase ( ) ;
78+ const budget = parseInt ( settings . thinkingBudget ) ;
79+ const useLevels = modelUsesThinkingLevel ( SELECTED_MODEL ) ;
80+ if ( useLevels && ( lvl === 'low' || lvl === 'high' ) ) return lvl ;
81+ if ( ! isNaN ( budget ) && budget > 0 ) return budget ;
82+ return 'none' ;
83+ } catch ( e ) {
84+ return 'none' ;
85+ }
86+ }
87+
5588
5689// --- Constants & Global Variables ---
5790const API_URL = '/v1/chat/completions' ;
@@ -76,7 +109,11 @@ let modelSettings = {
76109 temperature : - 1 ,
77110 maxOutputTokens : - 1 ,
78111 topP : - 1 ,
79- stopSequences : ""
112+ stopSequences : "" ,
113+ enableThinking : false ,
114+ thinkingBudget : 8192 ,
115+ thinkingLevel : "" ,
116+ enableGoogleSearch : false
80117} ;
81118
82119// --- Helper Functions ---
@@ -478,11 +515,18 @@ async function sendMessage() {
478515 max_output_tokens : modelSettings . maxOutputTokens ,
479516 top_p : modelSettings . topP ,
480517 } ;
518+ requestBody . reasoning_effort = computeReasoningEffort ( modelSettings ) ;
519+ const tools = [ ] ;
520+ if ( enableGoogleSearchToggle && enableGoogleSearchToggle . checked ) tools . push ( { google_search_retrieval : { } } ) ;
521+ if ( tools . length > 0 ) {
522+ requestBody . tools = tools ;
523+ requestBody . tool_choice = 'auto' ;
524+ }
481525 if ( modelSettings . stopSequences ) {
482526 const stopArray = modelSettings . stopSequences . split ( ',' ) . map ( seq => seq . trim ( ) ) . filter ( seq => seq . length > 0 ) ;
483527 if ( stopArray . length > 0 ) requestBody . stop = stopArray ;
484528 }
485- addLogEntry ( `[信息] 发送请求,模型: ${ SELECTED_MODEL } , 温度: ${ requestBody . temperature ?? '默认' } , 最大Token: ${ requestBody . max_output_tokens ?? '默认' } , Top P: ${ requestBody . top_p ?? '默认' } ` ) ;
529+ addLogEntry ( `[信息] 发送请求,模型: ${ SELECTED_MODEL } , 温度: ${ requestBody . temperature ?? '默认' } , 最大Token: ${ requestBody . max_output_tokens ?? '默认' } , Top P: ${ requestBody . top_p ?? '默认' } , 思考参数: ${ String ( requestBody . reasoning_effort ) } , 工具: ${ JSON . stringify ( requestBody . tools || [ ] ) } ` ) ;
486530
487531 // 获取API密钥进行认证
488532 const apiKey = await getValidApiKey ( ) ;
@@ -888,6 +932,12 @@ function updateModelSettingsUI() {
888932 maxOutputTokensSlider . value = maxOutputTokensValue . value = modelSettings . maxOutputTokens ;
889933 topPSlider . value = topPValue . value = modelSettings . topP ;
890934 stopSequencesInput . value = modelSettings . stopSequences ;
935+ if ( enableThinkingToggle ) enableThinkingToggle . checked = ! ! modelSettings . enableThinking ;
936+ if ( thinkingLevelSelector ) thinkingLevelSelector . value = modelSettings . thinkingLevel || "" ;
937+ if ( thinkingBudgetSlider ) thinkingBudgetSlider . value = modelSettings . thinkingBudget ;
938+ if ( thinkingBudgetValue ) thinkingBudgetValue . value = modelSettings . thinkingBudget ;
939+ if ( enableGoogleSearchToggle ) enableGoogleSearchToggle . checked = ! ! modelSettings . enableGoogleSearch ;
940+
891941}
892942
893943function saveModelSettings ( ) {
@@ -896,6 +946,14 @@ function saveModelSettings() {
896946 modelSettings . maxOutputTokens = parseInt ( maxOutputTokensValue . value ) ;
897947 modelSettings . topP = parseFloat ( topPValue . value ) ;
898948 modelSettings . stopSequences = stopSequencesInput . value . trim ( ) ;
949+ if ( enableThinkingToggle ) modelSettings . enableThinking = ! ! enableThinkingToggle . checked ;
950+ if ( thinkingLevelSelector ) modelSettings . thinkingLevel = ( thinkingLevelSelector . value || "" ) . toLowerCase ( ) ;
951+ if ( thinkingBudgetValue ) {
952+ const budgetVal = parseInt ( thinkingBudgetValue . value ) ;
953+ modelSettings . thinkingBudget = isNaN ( budgetVal ) ? 8192 : budgetVal ;
954+ }
955+ if ( enableGoogleSearchToggle ) modelSettings . enableGoogleSearch = ! ! enableGoogleSearchToggle . checked ;
956+
899957
900958 try {
901959 localStorage . setItem ( MODEL_SETTINGS_KEY , JSON . stringify ( modelSettings ) ) ;
@@ -930,6 +988,11 @@ function resetModelSettings() {
930988
931989 updateControlsForSelectedModel ( ) ; // This applies model-specific defaults to UI and modelSettings object
932990
991+ modelSettings . enableThinking = false ;
992+ modelSettings . thinkingLevel = "" ;
993+ modelSettings . thinkingBudget = 8192 ;
994+ updateModelSettingsUI ( ) ;
995+
933996 try {
934997 // Save these model-specific defaults (which are now in modelSettings) to localStorage
935998 // This makes the "reset" effectively a "reset to this model's defaults and save that"
@@ -1033,12 +1096,23 @@ function bindEventListeners() {
10331096 topPSlider . addEventListener ( 'input' , ( ) => topPValue . value = topPSlider . value ) ;
10341097 topPValue . addEventListener ( 'input' , ( ) => { if ( ! isNaN ( parseFloat ( topPValue . value ) ) ) topPSlider . value = parseFloat ( topPValue . value ) ; } ) ;
10351098
1099+ if ( thinkingBudgetSlider && thinkingBudgetValue ) {
1100+ thinkingBudgetSlider . addEventListener ( 'input' , ( ) => thinkingBudgetValue . value = thinkingBudgetSlider . value ) ;
1101+ thinkingBudgetValue . addEventListener ( 'input' , ( ) => { const v = parseInt ( thinkingBudgetValue . value ) ; if ( ! isNaN ( v ) ) thinkingBudgetSlider . value = v ; } ) ;
1102+ }
1103+ if ( enableThinkingToggle ) enableThinkingToggle . addEventListener ( 'change' , ( ) => showSettingsStatus ( "思考模式设置已更新" , false ) ) ;
1104+ if ( thinkingLevelSelector ) thinkingLevelSelector . addEventListener ( 'change' , ( ) => showSettingsStatus ( "思考等级已更新" , false ) ) ;
1105+
10361106 saveModelSettingsButton . addEventListener ( 'click' , saveModelSettings ) ;
10371107 resetModelSettingsButton . addEventListener ( 'click' , resetModelSettings ) ;
10381108
1109+ // Tools controls syncing
1110+ if ( enableGoogleSearchToggle ) enableGoogleSearchToggle . addEventListener ( 'change' , ( ) => showSettingsStatus ( "Google Search 工具已更新" , false ) ) ;
1111+
1112+
10391113 const debouncedSave = debounce ( saveModelSettings , 1000 ) ;
1040- [ systemPromptInput , temperatureValue , maxOutputTokensValue , topPValue , stopSequencesInput ] . forEach (
1041- element => element . addEventListener ( 'input' , debouncedSave ) // Use 'input' for more responsive auto-save
1114+ [ systemPromptInput , temperatureValue , maxOutputTokensValue , topPValue , stopSequencesInput , thinkingBudgetValue , thinkingLevelSelector , enableThinkingToggle , enableGoogleSearchToggle ] . forEach (
1115+ element => element && element . addEventListener ( 'input' , debouncedSave )
10421116 ) ;
10431117}
10441118
0 commit comments