Skip to content

Commit bf3711f

Browse files
committed
Implement a Quick Pick UI for selecting chatbots within the preset editor
1 parent f89cc5b commit bf3711f

6 files changed

Lines changed: 104 additions & 10 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import * as vscode from 'vscode'
2+
import { ViewProvider } from '@/view/backend/view-provider'
3+
import { CHATBOTS } from '@shared/constants/chatbots'
4+
import { PickChatbotMessage } from '@/view/types/messages'
5+
6+
export const handle_pick_chatbot = async (
7+
provider: ViewProvider,
8+
message: PickChatbotMessage
9+
): Promise<void> => {
10+
const chatbots = Object.entries(CHATBOTS)
11+
12+
const items: vscode.QuickPickItem[] = chatbots.map(([chatbot, { url }]) => ({
13+
label: chatbot,
14+
description: chatbot == 'Open WebUI' ? 'localhost' : url,
15+
buttons: [
16+
...(chatbot != 'Open WebUI'
17+
? [
18+
{
19+
iconPath: new vscode.ThemeIcon('link-external'),
20+
tooltip: 'Open in Browser'
21+
}
22+
]
23+
: [])
24+
]
25+
}))
26+
27+
const quick_pick = vscode.window.createQuickPick()
28+
quick_pick.items = items
29+
quick_pick.title = 'Select a Chatbot'
30+
quick_pick.placeholder = 'Choose a chatbot from the list'
31+
32+
if (message.chatbot_id) {
33+
const active_item = items.find((item) => item.label == message.chatbot_id)
34+
if (active_item) {
35+
quick_pick.activeItems = [active_item]
36+
}
37+
}
38+
39+
quick_pick.onDidTriggerItemButton((e) => {
40+
const chatbot_name = e.item.label
41+
const chatbot_details = CHATBOTS[chatbot_name as keyof typeof CHATBOTS]
42+
if (chatbot_details) {
43+
vscode.env.openExternal(vscode.Uri.parse(chatbot_details.url))
44+
}
45+
})
46+
47+
return new Promise<void>((resolve) => {
48+
quick_pick.onDidAccept(() => {
49+
const selected = quick_pick.selectedItems[0]
50+
if (selected) {
51+
provider.send_message({
52+
command: 'NEWLY_PICKED_CHATBOT',
53+
chatbot_id: selected.label
54+
})
55+
}
56+
quick_pick.hide()
57+
})
58+
59+
quick_pick.onDidHide(() => {
60+
quick_pick.dispose()
61+
resolve()
62+
})
63+
64+
quick_pick.show()
65+
})
66+
}

packages/vscode/src/view/backend/message-handlers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export * from './handle-send-prompt'
1616
export * from './handle-show-history-quick-pick'
1717
export * from './handle-show-prompt-template-quick-pick'
1818
export * from './handle-update-preset'
19+
export * from './handle-pick-chatbot'
1920
export * from './handle-pick-open-router-model'
2021
export * from './handle-save-home-view-type'
2122
export * from './handle-get-home-view-type'

packages/vscode/src/view/backend/view-provider.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ import {
4040
handle_show_prompt_template_quick_pick,
4141
handle_at_sign_quick_pick_for_preset_affix,
4242
handle_get_api_tool_configurations,
43-
handle_pick_open_router_model
43+
handle_pick_open_router_model,
44+
handle_pick_chatbot
4445
} from './message-handlers'
4546
import {
4647
config_preset_to_ui_format,
@@ -343,6 +344,8 @@ export class ViewProvider implements vscode.WebviewViewProvider {
343344
)
344345
} else if (message.command == 'PICK_OPEN_ROUTER_MODEL') {
345346
await handle_pick_open_router_model(this)
347+
} else if (message.command == 'PICK_CHATBOT') {
348+
await handle_pick_chatbot(this, message)
346349
}
347350
} catch (error: any) {
348351
console.error('Error handling message:', message, error)

packages/vscode/src/view/frontend/EditPresetForm/EditPresetForm.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type Props = {
1313
on_update: (updated_preset: Preset) => void
1414
on_save: () => void
1515
pick_open_router_model: () => void
16+
pick_chatbot: (chatbot_id?: keyof typeof CHATBOTS) => void
1617
on_at_sign_in_affix: () => void
1718
}
1819

@@ -110,8 +111,7 @@ export const EditPresetForm: React.FC<Props> = (props) => {
110111
options
111112
])
112113

113-
const handle_chatbot_change = (e: React.ChangeEvent<HTMLSelectElement>) => {
114-
const new_chatbot = e.target.value as keyof typeof CHATBOTS
114+
const handle_chatbot_change = (new_chatbot: keyof typeof CHATBOTS) => {
115115
set_chatbot(new_chatbot)
116116
set_model(Object.keys(CHATBOTS[new_chatbot].models)[0] || undefined)
117117
set_port(undefined)
@@ -141,6 +141,8 @@ export const EditPresetForm: React.FC<Props> = (props) => {
141141
const message = event.data as BackendMessage
142142
if (message.command == 'NEWLY_PICKED_OPEN_ROUTER_MODEL') {
143143
set_model(message.model_id)
144+
} else if (message.command == 'NEWLY_PICKED_CHATBOT') {
145+
handle_chatbot_change(message.chatbot_id as keyof typeof CHATBOTS)
144146
} else if (
145147
message.command == 'AT_SIGN_QUICK_PICK_FOR_PRESET_AFFIX_RESULT'
146148
) {
@@ -199,13 +201,20 @@ export const EditPresetForm: React.FC<Props> = (props) => {
199201
<div className={styles.form}>
200202
{chatbot && (
201203
<Field label="Chatbot" html_for="chatbot">
202-
<select id="chatbot" value={chatbot} onChange={handle_chatbot_change}>
203-
{Object.keys(CHATBOTS).map((key) => (
204-
<option key={key} value={key}>
205-
{key}
206-
</option>
207-
))}
208-
</select>
204+
<div
205+
onClick={(e) => {
206+
e.stopPropagation();
207+
props.pick_chatbot(chatbot);
208+
}}
209+
>
210+
<div style={{ cursor: 'pointer' }}>
211+
<div style={{ pointerEvents: 'none' }}>
212+
<select id="chatbot" value={chatbot}>
213+
<option value={chatbot}>{chatbot}</option>
214+
</select>
215+
</div>
216+
</div>
217+
</div>
209218
</Field>
210219
)}
211220

packages/vscode/src/view/frontend/View.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ export const View = () => {
235235
pick_open_router_model={() => {
236236
post_message(vscode, { command: 'PICK_OPEN_ROUTER_MODEL' })
237237
}}
238+
pick_chatbot={(chatbot_id) => {
239+
post_message(vscode, { command: 'PICK_CHATBOT', chatbot_id })
240+
}}
238241
on_at_sign_in_affix={() => {
239242
post_message(vscode, {
240243
command: 'SHOW_AT_SIGN_QUICK_PICK_FOR_PRESET_AFFIX',

packages/vscode/src/view/types/messages.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ export interface PickOpenRouterModel extends BaseMessage {
132132
command: 'PICK_OPEN_ROUTER_MODEL'
133133
}
134134

135+
export interface PickChatbotMessage extends BaseMessage {
136+
command: 'PICK_CHATBOT'
137+
chatbot_id?: string
138+
}
139+
135140
export interface SaveHomeViewTypeMessage extends BaseMessage {
136141
command: 'SAVE_HOME_VIEW_TYPE'
137142
view_type: HomeViewType
@@ -213,6 +218,7 @@ export type FrontendMessage =
213218
| PreviewPresetMessage
214219
| CaretPositionChangedWebviewMessage
215220
| PickOpenRouterModel
221+
| PickChatbotMessage
216222
| SaveHomeViewTypeMessage
217223
| GetHomeViewTypeMessage
218224
| EditContextMessage
@@ -304,6 +310,11 @@ export interface NewlyPickedOpenRouterModelMessage extends BaseMessage {
304310
model_id: string
305311
}
306312

313+
export interface NewlyPickedChatbotMessage extends BaseMessage {
314+
command: 'NEWLY_PICKED_CHATBOT'
315+
chatbot_id: string
316+
}
317+
307318
export interface HomeViewTypeMessage extends BaseMessage {
308319
command: 'HOME_VIEW_TYPE'
309320
view_type: HomeViewType
@@ -345,6 +356,7 @@ export type BackendMessage =
345356
| PresetCreatedMessage
346357
| PresetUpdatedMessage
347358
| NewlyPickedOpenRouterModelMessage
359+
| NewlyPickedChatbotMessage
348360
| HomeViewTypeMessage
349361
| WebModeMessage
350362
| ApiModeMessage

0 commit comments

Comments
 (0)