Skip to content

Commit 721c84e

Browse files
committed
Implement model selection for Grok and remove redundant Escape key events from reasoning effort handlers
- grok should have two models: 'Fast' and 'Expert'. Model selector show up on pointer down on button#model-select-trigger. popup with Fast and Expert options: [Pasted text] - never use this pattern with escape key: [Pasted text], just do nothing ├── apps │ └── browser │ └── src │ └── content-scripts │ └── send-prompt-content-script │ └── chatbots │ ├── ai-studio.ts │ ├── arena.ts │ ├── chatgpt.ts │ ├── claude.ts │ ├── copilot.ts │ ├── deepseek.ts │ ├── doubao.ts │ ├── gemini.ts │ ├── github-copilot.ts │ ├── grok.ts │ ├── hugging-chat.ts │ ├── index.ts │ ├── kimi.ts │ ├── meta.ts │ ├── mistral.ts │ ├── open-webui.ts │ ├── openrouter.ts │ ├── qwen.ts │ ├── together.ts │ ├── yuanbao.ts │ └── z-ai.ts └── packages └── shared └── src └── constants └── chatbots.ts
1 parent eac93bb commit 721c84e

5 files changed

Lines changed: 52 additions & 24 deletions

File tree

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,6 @@ export const chatgpt: Chatbot = {
129129

130130
await new Promise((resolve) => requestAnimationFrame(resolve))
131131
}
132-
133-
slider_control.dispatchEvent(
134-
new KeyboardEvent('keydown', {
135-
key: 'Escape',
136-
bubbles: true,
137-
cancelable: true
138-
})
139-
)
140-
141-
await new Promise((resolve) => requestAnimationFrame(resolve))
142132
},
143133
set_options: async (chat) => {
144134
const options = chat.options

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,12 @@ export const gemini: Chatbot = {
118118
reasoning_effort.toLowerCase()
119119
) as HTMLElement
120120

121-
if (!target_item) {
122-
document.dispatchEvent(
123-
new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
124-
)
125-
return
126-
}
121+
if (!target_item) return
127122

128123
const is_selected = target_item.classList.contains('selected')
129124

130125
if (!is_selected) {
131126
target_item.click()
132-
} else {
133-
document.dispatchEvent(
134-
new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
135-
)
136127
}
137128

138129
await new Promise((resolve) => requestAnimationFrame(resolve))

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,52 @@ export const grok: Chatbot = {
1919
check_for_element()
2020
})
2121
},
22+
set_model: async (chat) => {
23+
const model = chat.model
24+
if (model && CHATBOTS['Grok'].models && model in CHATBOTS['Grok'].models) {
25+
const model_selector_trigger = document.querySelector(
26+
'button#model-select-trigger'
27+
) as HTMLButtonElement
28+
if (!model_selector_trigger) {
29+
report_initialization_error({
30+
function_name: 'set_model',
31+
log_message: 'Model selector trigger not found'
32+
})
33+
return
34+
}
35+
36+
const model_label = CHATBOTS['Grok'].models[model].label
37+
const target_label_lower = model_label.toLowerCase()
38+
39+
model_selector_trigger.click()
40+
await new Promise((r) => requestAnimationFrame(r))
41+
42+
const menu_items = Array.from(
43+
document.querySelectorAll(
44+
'[data-radix-menu-content] [role="menuitemradio"]'
45+
)
46+
)
47+
let found = false
48+
for (const item of menu_items) {
49+
const text = item.textContent?.trim().toLowerCase()
50+
if (text && text.includes(target_label_lower)) {
51+
const is_checked = item.getAttribute('aria-checked') == 'true'
52+
if (!is_checked) {
53+
;(item as HTMLElement).click()
54+
}
55+
found = true
56+
break
57+
}
58+
}
59+
if (!found) {
60+
report_initialization_error({
61+
function_name: 'set_model',
62+
log_message: `Model option for "${model_label}" not found`
63+
})
64+
}
65+
await new Promise((r) => requestAnimationFrame(r))
66+
}
67+
},
2268
set_options: async (chat) => {
2369
const options = chat.options
2470
if (!options) return

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ export const hugging_chat: Chatbot = {
8080
function_name: 'hugging_chat.set_reasoning_effort',
8181
log_message: `Reasoning effort option "${reasoning_effort}" not found`
8282
})
83-
document.dispatchEvent(
84-
new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
85-
)
8683
}
8784
await new Promise((resolve) => setTimeout(resolve, 250))
8885
},

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ export const CHATBOTS = {
111111
supports_url_override: true,
112112
url_override_label: 'Project URL',
113113
url_override_disabled_options: ['private'],
114-
supported_options: { private: 'Private' }
114+
supported_options: { private: 'Private' },
115+
models: {
116+
fast: { label: 'Fast' },
117+
expert: { label: 'Expert' }
118+
}
115119
} as Chatbot,
116120
HuggingChat: {
117121
url: 'https://huggingface.co/chat/',

0 commit comments

Comments
 (0)