Skip to content

Commit 30a781c

Browse files
committed
Update Gemini and AI Studio chatbot integrations and refine preset model validation
1 parent a736ae8 commit 30a781c

7 files changed

Lines changed: 118 additions & 45 deletions

File tree

‎.gitignore‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
/.vscode
21
/node_modules
32
/docs/index.md

‎.vscode/launch.json‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Run Extension",
6+
"type": "extensionHost",
7+
"request": "launch",
8+
"runtimeExecutable": "${execPath}",
9+
"args": ["--extensionDevelopmentPath=${workspaceRoot}/apps/editor"],
10+
"outFiles": ["${workspaceRoot}/apps/editor/out/**/*.js"],
11+
}
12+
]
13+
}

‎.vscode/settings.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"js/ts.tsdk.path": "node_modules/typescript/lib"
3+
}

‎apps/browser/src/content-scripts/send-prompt-content-script/chatbots/ai-studio.ts‎

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,6 @@ export const ai_studio: Chatbot = {
103103
await new Promise((r) => requestAnimationFrame(r))
104104
}
105105
const supported_options = CHATBOTS['AI Studio'].supported_options
106-
const thinking_toggle = document.querySelector(
107-
'mat-slide-toggle[data-test-toggle="enable-thinking"] button'
108-
) as HTMLElement
109-
if (!thinking_toggle) {
110-
report_initialization_error({
111-
function_name: 'set_options',
112-
log_message: 'Thinking toggle not found'
113-
})
114-
} else {
115-
if (
116-
options.includes('disable-thinking') &&
117-
supported_options?.['disable-thinking']
118-
) {
119-
if (thinking_toggle.getAttribute('aria-checked') == 'true') {
120-
thinking_toggle.click()
121-
}
122-
} else {
123-
if (thinking_toggle?.getAttribute('aria-checked') == 'false') {
124-
thinking_toggle.click()
125-
}
126-
}
127-
}
128106

129107
if (options.includes('hide-panel') && supported_options?.['hide-panel']) {
130108
sessionStorage.setItem('should-hide-panel', 'true')

‎apps/browser/src/content-scripts/send-prompt-content-script/chatbots/gemini.ts‎

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const gemini: Chatbot = {
1010
wait_until_ready: async () => {
1111
await new Promise((resolve) => {
1212
const check_for_element = () => {
13-
if (document.querySelector('toolbox-drawer')) {
13+
if (document.querySelector('button[data-test-id="bard-mode-menu-button"]')) {
1414
resolve(null)
1515
} else {
1616
setTimeout(check_for_element, 100)
@@ -38,30 +38,33 @@ export const gemini: Chatbot = {
3838
}
3939

4040
const model_label = CHATBOTS['Gemini'].models[model].label
41-
if (model_selector_trigger.textContent == model_label) {
41+
const trigger_text = model_selector_trigger.textContent?.trim().toLowerCase() || ''
42+
const target_label_lower = model_label.toLowerCase()
43+
if (
44+
trigger_text.includes(target_label_lower) &&
45+
!(target_label_lower == 'flash' && trigger_text.includes('flash-lite'))
46+
) {
4247
return
4348
}
4449

4550
model_selector_trigger.click()
4651
await new Promise((r) => requestAnimationFrame(r))
4752
const menu_content =
48-
document.querySelector('.mat-mdc-menu-content') ||
49-
document.querySelector('mat-bottom-sheet-container')
53+
document.querySelector('gem-menu')
5054
if (!menu_content) {
5155
report_initialization_error({
5256
function_name: 'set_model',
5357
log_message: 'Model selector menu not found'
5458
})
5559
return
5660
}
57-
const model_options = Array.from(menu_content.querySelectorAll('button'))
58-
const target_data_test_id = model_label.toLowerCase()
61+
const model_options = Array.from(menu_content.querySelectorAll('[role="menuitem"]'))
5962
let found = false
6063
for (const option of model_options) {
61-
if (
62-
option.getAttribute('data-test-id')?.includes(target_data_test_id)
63-
) {
64-
option.click()
64+
const label_element = option.querySelector('.label')
65+
const text = label_element?.textContent?.trim().toLowerCase()
66+
if (text && text.endsWith(target_label_lower)) {
67+
;(option as HTMLElement).click()
6568
found = true
6669
break
6770
}
@@ -75,6 +78,72 @@ export const gemini: Chatbot = {
7578
await new Promise((r) => requestAnimationFrame(r))
7679
}
7780
},
81+
set_reasoning_effort: async (chat) => {
82+
const reasoning_effort = chat.reasoning_effort
83+
if (!reasoning_effort) return
84+
85+
const model_selector_trigger = document.querySelector(
86+
'bard-mode-switcher button'
87+
) as HTMLButtonElement
88+
if (!model_selector_trigger) {
89+
report_initialization_error({
90+
function_name: 'set_reasoning_effort',
91+
log_message: 'Model selector trigger not found'
92+
})
93+
return
94+
}
95+
96+
model_selector_trigger.click()
97+
await new Promise((resolve) => requestAnimationFrame(resolve))
98+
99+
const menu_content = document.querySelector('gem-menu')
100+
if (!menu_content) {
101+
report_initialization_error({
102+
function_name: 'set_reasoning_effort',
103+
log_message: 'Model selector menu not found'
104+
})
105+
return
106+
}
107+
108+
const thinking_level_item = Array.from(
109+
menu_content.querySelectorAll('gem-menu-item')
110+
).find((item) => item.getAttribute('value') == 'thinking_level') as HTMLElement
111+
112+
if (!thinking_level_item) {
113+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
114+
return
115+
}
116+
117+
const current_level = thinking_level_item
118+
.querySelector('.sublabel')
119+
?.textContent?.trim()
120+
121+
if (current_level?.toLowerCase() == reasoning_effort.toLowerCase()) {
122+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
123+
return
124+
}
125+
126+
thinking_level_item.click()
127+
await new Promise((resolve) => requestAnimationFrame(resolve))
128+
129+
const all_menu_items = Array.from(document.querySelectorAll('gem-menu-item'))
130+
let found = false
131+
for (const option of all_menu_items) {
132+
const label_element = option.querySelector('.label')
133+
const text = label_element?.textContent?.trim().toLowerCase()
134+
if (text == reasoning_effort.toLowerCase()) {
135+
;(option as HTMLElement).click()
136+
found = true
137+
break
138+
}
139+
}
140+
141+
if (!found) {
142+
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
143+
}
144+
145+
await new Promise((resolve) => requestAnimationFrame(resolve))
146+
},
78147
set_options: async (chat) => {
79148
const options = chat.options
80149
if (!options) return
@@ -161,7 +230,7 @@ export const gemini: Chatbot = {
161230
get_chat_turn: (f) => f.closest('response-container'),
162231
perform_copy: (f) => {
163232
const copy_button = f.querySelector(
164-
'copy-button > button'
233+
'copy-button button'
165234
) as HTMLElement
166235
if (!copy_button) {
167236
report_initialization_error({

‎apps/editor/src/views/panel/backend/panel-provider.ts‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,20 @@ export class PanelProvider implements vscode.WebviewViewProvider {
10581058
(preset_config) =>
10591059
!preset_config.chatbot || CHATBOTS[preset_config.chatbot]
10601060
)
1061-
.map((preset_config) => config_preset_to_ui_format(preset_config))
1061+
.map((preset_config) => {
1062+
let model = preset_config.model
1063+
if (preset_config.chatbot && model) {
1064+
const chatbot_info = CHATBOTS[preset_config.chatbot]
1065+
const is_user_provided_supported =
1066+
chatbot_info.supports_user_provided_model
1067+
const is_model_predefined = chatbot_info.models?.[model]
1068+
1069+
if (!is_user_provided_supported && !is_model_predefined) {
1070+
model = undefined
1071+
}
1072+
}
1073+
return config_preset_to_ui_format({ ...preset_config, model })
1074+
})
10621075
return [prompt_type, presets_ui]
10631076
})
10641077
) as { [T in WebPromptType]: Preset[] }

‎packages/shared/src/constants/chatbots.ts‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,20 @@ export const CHATBOTS = {
3434
default_system_instructions: "You're a helpful coding assistant.",
3535
supported_options: {
3636
'hide-panel': 'Hide panel',
37-
'disable-thinking': 'Disable thinking',
3837
'grounding-with-google-search': 'Grounding with Google Search',
3938
'url-context': 'URL context'
4039
},
4140
models: {
42-
'gemini-3-flash-preview': {
43-
label: 'Gemini 3 Flash Preview',
44-
disabled_options: ['disable-thinking'],
41+
'gemini-3.5-flash': {
42+
label: 'Gemini 3.5 Flash',
4543
supported_reasoning_efforts: ['Minimal', 'Low', 'Medium', 'High']
4644
},
4745
'gemini-3.1-pro-preview': {
4846
label: 'Gemini 3.1 Pro Preview',
49-
disabled_options: ['disable-thinking'],
5047
supported_reasoning_efforts: ['Low', 'Medium', 'High']
5148
},
52-
'gemini-3.1-flash-lite-preview': {
53-
label: 'Gemini 3.1 Flash Lite Preview',
54-
disabled_options: ['disable-thinking'],
49+
'gemini-3.1-flash-lite': {
50+
label: 'Gemini 3.1 Flash Lite',
5551
supported_reasoning_efforts: ['Minimal', 'Low', 'Medium', 'High']
5652
}
5753
}
@@ -101,9 +97,11 @@ export const CHATBOTS = {
10197
supports_url_override: true,
10298
url_override_label: 'Gem URL',
10399
url_override_disabled_options: ['temporary-chat'],
100+
supports_reasoning_effort: true,
101+
supported_reasoning_efforts: ['Standard', 'Extended'],
104102
models: {
105-
fast: { label: 'Fast' },
106-
thinking: { label: 'Thinking' },
103+
'flash-lite': { label: 'Flash-Lite' },
104+
flash: { label: 'Flash' },
107105
pro: { label: 'Pro' }
108106
}
109107
} as Chatbot,

0 commit comments

Comments
 (0)