Skip to content

Commit d8f4ad8

Browse files
committed
Streamline preset initiation by moving group and quick pick resolution logic to the backend
1 parent 049a0cb commit d8f4ad8

7 files changed

Lines changed: 215 additions & 95 deletions

File tree

packages/ui/src/components/editor/Presets/Presets.tsx

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export namespace Presets {
4747
has_context: boolean
4848
presets: Preset[]
4949
on_preset_click: (preset_name: string) => void
50-
on_group_click: (presets: string[]) => void
50+
on_group_click: (group_name: string) => void
5151
on_create_preset: () => void
5252
on_preset_copy: (name: string) => void
5353
on_presets_reorder: (reordered_presets: Preset[]) => void
@@ -149,15 +149,7 @@ export const Presets: React.FC<Presets.Props> = (props) => {
149149
})}
150150
onClick={() => {
151151
if (get_is_ungrouped_disabled()) return
152-
153-
const preset_names: string[] = []
154-
for (const preset of props.presets) {
155-
if (!preset.chatbot) break
156-
if (preset.is_default && !get_is_preset_disabled(preset)) {
157-
preset_names.push(preset.name)
158-
}
159-
}
160-
props.on_group_click(preset_names)
152+
props.on_group_click('Ungrouped')
161153
}}
162154
role="button"
163155
title={get_ungrouped_title()}
@@ -269,19 +261,7 @@ export const Presets: React.FC<Presets.Props> = (props) => {
269261
props.on_preset_click(preset.name)
270262
} else {
271263
if (get_is_group_disabled()) return
272-
const preset_names: string[] = []
273-
for (let j = i + 1; j < props.presets.length; j++) {
274-
const preset = props.presets[j]
275-
if (!preset.chatbot) {
276-
break
277-
} else if (
278-
preset.is_default &&
279-
!get_is_preset_disabled(preset)
280-
) {
281-
preset_names.push(preset.name)
282-
}
283-
}
284-
props.on_group_click(preset_names)
264+
props.on_group_click(preset.name)
285265
}
286266

287267
set_highlighted_preset_name({

packages/vscode/src/view/backend/message-handlers/handle-send-prompt.ts

Lines changed: 186 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,30 @@ import { CHATBOTS } from '@shared/constants/chatbots'
2121
*/
2222
export const handle_send_prompt = async (params: {
2323
provider: ViewProvider
24-
preset_names?: string[]
24+
preset_name?: string
25+
group_name?: string
26+
show_quick_pick?: boolean
2527
}): Promise<void> => {
28+
if (params.preset_name) {
29+
params.provider.context.workspaceState.update(
30+
LAST_GROUP_OR_PRESET_CHOICE_STATE_KEY,
31+
'Preset'
32+
)
33+
params.provider.context.workspaceState.update(
34+
LAST_SELECTED_PRESET_KEY,
35+
params.preset_name
36+
)
37+
} else if (params.group_name) {
38+
params.provider.context.workspaceState.update(
39+
LAST_GROUP_OR_PRESET_CHOICE_STATE_KEY,
40+
'Group'
41+
)
42+
params.provider.context.workspaceState.update(
43+
LAST_SELECTED_GROUP_STATE_KEY,
44+
params.group_name
45+
)
46+
}
47+
2648
let current_instructions = ''
2749
const is_in_code_completions_mode =
2850
params.provider.web_mode == 'code-completions'
@@ -41,8 +63,10 @@ export const handle_send_prompt = async (params: {
4163

4264
const resolved_preset_names = await resolve_presets({
4365
provider: params.provider,
44-
preset_names: params.preset_names,
45-
context: params.provider.context
66+
preset_name: params.preset_name,
67+
group_name: params.group_name,
68+
context: params.provider.context,
69+
show_quick_pick: params.show_quick_pick
4670
})
4771

4872
if (resolved_preset_names.length == 0) return
@@ -104,9 +128,8 @@ export const handle_send_prompt = async (params: {
104128
} else {
105129
const editor = vscode.window.activeTextEditor
106130

107-
const additional_paths = extract_file_paths_from_instruction(
108-
current_instructions
109-
)
131+
const additional_paths =
132+
extract_file_paths_from_instruction(current_instructions)
110133

111134
const context_text = await files_collector.collect_files({
112135
additional_paths,
@@ -187,9 +210,9 @@ async function show_preset_quick_pick(
187210
presets: ConfigPresetFormat[],
188211
context: vscode.ExtensionContext
189212
): Promise<string[]> {
190-
const last_selected_item = context.workspaceState.get<string>(
213+
const last_selected_item = context.workspaceState.get<string | undefined>(
191214
LAST_SELECTED_PRESET_KEY,
192-
''
215+
undefined
193216
)
194217

195218
const quick_pick = vscode.window.createQuickPick<
@@ -259,70 +282,178 @@ async function show_preset_quick_pick(
259282

260283
async function resolve_presets(params: {
261284
provider: ViewProvider
262-
preset_names?: string[]
285+
preset_name?: string
286+
group_name?: string
287+
show_quick_pick?: boolean
263288
context: vscode.ExtensionContext
264289
}): Promise<string[]> {
265290
const PRESET = 'Preset'
266291
const GROUP = 'Group'
267292
const config = vscode.workspace.getConfiguration('codeWebChat')
268293
const presets_config_key = params.provider.get_presets_config_key()
269294
const all_presets = config.get<ConfigPresetFormat[]>(presets_config_key, [])
295+
const is_in_code_completions_mode =
296+
params.provider.web_mode == 'code-completions'
297+
298+
let current_instructions = ''
299+
if (is_in_code_completions_mode) {
300+
current_instructions = params.provider.code_completion_instructions
301+
} else {
302+
if (params.provider.web_mode == 'ask') {
303+
current_instructions = params.provider.ask_instructions
304+
} else if (params.provider.web_mode == 'edit-context') {
305+
current_instructions = params.provider.edit_instructions
306+
} else if (params.provider.web_mode == 'no-context') {
307+
current_instructions = params.provider.no_context_instructions
308+
}
309+
}
310+
311+
const get_is_preset_disabled = (preset: ConfigPresetFormat) =>
312+
preset.chatbot &&
313+
(!params.provider.websocket_server_instance.is_connected_with_browser() ||
314+
(is_in_code_completions_mode &&
315+
(!params.provider.has_active_editor ||
316+
params.provider.has_active_selection)) ||
317+
(!is_in_code_completions_mode &&
318+
!(current_instructions || preset.promptPrefix || preset.promptSuffix)))
270319
const available_preset_names = all_presets.map((preset) => preset.name)
271320

272-
if (params.preset_names !== undefined) {
273-
const valid_presets = params.preset_names.filter((name) =>
274-
available_preset_names.includes(name)
275-
)
321+
if (params.preset_name) {
322+
if (available_preset_names.includes(params.preset_name)) {
323+
return [params.preset_name]
324+
}
325+
} else if (params.group_name) {
326+
const preset_names: string[] = []
327+
328+
if (params.group_name == 'Ungrouped') {
329+
for (const preset of all_presets) {
330+
if (!preset.chatbot) break
331+
if (preset.isDefault && !get_is_preset_disabled(preset)) {
332+
preset_names.push(preset.name)
333+
}
334+
}
335+
} else {
336+
const group_index = all_presets.findIndex(
337+
(p) => p.name == params.group_name
338+
)
276339

277-
if (valid_presets.length > 0) {
278-
return valid_presets
340+
if (group_index != -1) {
341+
for (let i = group_index + 1; i < all_presets.length; i++) {
342+
const preset = all_presets[i]
343+
if (!preset.chatbot) {
344+
break
345+
} else if (preset.isDefault && !get_is_preset_disabled(preset)) {
346+
preset_names.push(preset.name)
347+
}
348+
}
349+
}
350+
}
351+
if (preset_names.length > 0) {
352+
return preset_names
279353
}
280354
} else {
281-
// preset_names is undefined, try to use last selection
282-
const last_choice = params.context.workspaceState.get<string>(
283-
LAST_GROUP_OR_PRESET_CHOICE_STATE_KEY
284-
)
355+
// Both preset_name and group_name are undefined.
356+
// This indicates a generic "send" action, where we should
357+
// use the last selected preset/group or prompt the user.
358+
// It also handles cases where a specified preset/group was not found.
359+
}
285360

286-
if (last_choice == PRESET) {
287-
const last_preset = params.context.workspaceState.get<string>(
288-
LAST_SELECTED_PRESET_KEY
361+
if (!params.show_quick_pick) {
362+
if (!params.preset_name && !params.group_name) {
363+
// Try to use last selection if "Send" button is clicked without specific preset/group
364+
const last_choice = params.context.workspaceState.get<string>(
365+
LAST_GROUP_OR_PRESET_CHOICE_STATE_KEY
289366
)
290-
if (
291-
last_preset !== undefined &&
292-
available_preset_names.includes(last_preset)
293-
) {
294-
return [last_preset]
367+
368+
if (last_choice == PRESET) {
369+
const last_preset = params.context.workspaceState.get<string>(
370+
LAST_SELECTED_PRESET_KEY
371+
)
372+
if (
373+
last_preset !== undefined &&
374+
available_preset_names.includes(last_preset)
375+
) {
376+
return [last_preset]
377+
}
378+
} else if (last_choice == GROUP) {
379+
const last_group = params.context.workspaceState.get<string>(
380+
LAST_SELECTED_GROUP_STATE_KEY
381+
)
382+
if (last_group) {
383+
if (last_group == 'Ungrouped') {
384+
const first_group_index = all_presets.findIndex((p) => !p.chatbot)
385+
const relevant_presets =
386+
first_group_index == -1
387+
? all_presets
388+
: all_presets.slice(0, first_group_index)
389+
const preset_names = relevant_presets
390+
.filter((p) => p.isDefault && !get_is_preset_disabled(p))
391+
.map((p) => p.name)
392+
if (preset_names.length > 0) return preset_names
393+
} else {
394+
const group_index = all_presets.findIndex((p) => p.name == last_group)
395+
const preset_names: string[] = []
396+
if (group_index != -1) {
397+
for (let i = group_index + 1; i < all_presets.length; i++) {
398+
const preset = all_presets[i]
399+
if (!preset.chatbot) {
400+
break // next group
401+
}
402+
if (preset.isDefault && !get_is_preset_disabled(preset)) {
403+
preset_names.push(preset.name)
404+
}
405+
}
406+
}
407+
if (preset_names.length > 0) return preset_names
408+
}
409+
}
295410
}
296-
} else if (last_choice == GROUP) {
297-
const last_group = params.context.workspaceState.get<string>(
298-
LAST_SELECTED_GROUP_STATE_KEY
411+
} else {
412+
const last_choice = params.context.workspaceState.get<string>(
413+
LAST_GROUP_OR_PRESET_CHOICE_STATE_KEY
299414
)
300-
if (last_group) {
301-
if (last_group == 'Ungrouped') {
302-
const first_group_index = all_presets.findIndex((p) => !p.chatbot)
303-
const relevant_presets =
304-
first_group_index == -1
305-
? all_presets
306-
: all_presets.slice(0, first_group_index)
307-
const preset_names = relevant_presets
308-
.filter((p) => p.isDefault)
309-
.map((p) => p.name)
310-
if (preset_names.length > 0) return preset_names
311-
} else {
312-
const group_index = all_presets.findIndex((p) => p.name == last_group)
313-
const preset_names: string[] = []
314-
if (group_index != -1) {
315-
for (let i = group_index + 1; i < all_presets.length; i++) {
316-
const preset = all_presets[i]
317-
if (!preset.chatbot) {
318-
break // next group
319-
}
320-
if (preset.isDefault) {
321-
preset_names.push(preset.name)
415+
416+
if (last_choice == PRESET) {
417+
const last_preset = params.context.workspaceState.get<string>(
418+
LAST_SELECTED_PRESET_KEY
419+
)
420+
if (
421+
last_preset !== undefined &&
422+
available_preset_names.includes(last_preset)
423+
) {
424+
return [last_preset]
425+
}
426+
} else if (last_choice == GROUP) {
427+
const last_group = params.context.workspaceState.get<string>(
428+
LAST_SELECTED_GROUP_STATE_KEY
429+
)
430+
if (last_group) {
431+
if (last_group == 'Ungrouped') {
432+
const first_group_index = all_presets.findIndex((p) => !p.chatbot)
433+
const relevant_presets =
434+
first_group_index == -1
435+
? all_presets
436+
: all_presets.slice(0, first_group_index)
437+
const preset_names = relevant_presets
438+
.filter((p) => p.isDefault && !get_is_preset_disabled(p))
439+
.map((p) => p.name)
440+
if (preset_names.length > 0) return preset_names
441+
} else {
442+
const group_index = all_presets.findIndex((p) => p.name == last_group)
443+
const preset_names: string[] = []
444+
if (group_index != -1) {
445+
for (let i = group_index + 1; i < all_presets.length; i++) {
446+
const preset = all_presets[i]
447+
if (!preset.chatbot) {
448+
break // next group
449+
}
450+
if (preset.isDefault && !get_is_preset_disabled(preset)) {
451+
preset_names.push(preset.name)
452+
}
322453
}
323454
}
455+
if (preset_names.length > 0) return preset_names
324456
}
325-
if (preset_names.length > 0) return preset_names
326457
}
327458
}
328459
}
@@ -467,7 +598,7 @@ async function resolve_presets(params: {
467598
? all_presets
468599
: all_presets.slice(0, first_group_index)
469600
preset_names = relevant_presets
470-
.filter((p) => p.isDefault)
601+
.filter((p) => p.isDefault && !get_is_preset_disabled(p))
471602
.map((p) => p.name)
472603
} else {
473604
const group_index = all_presets.findIndex((p) => p.name == group_name)
@@ -477,7 +608,7 @@ async function resolve_presets(params: {
477608
if (!preset.chatbot) {
478609
break // next group
479610
}
480-
if (preset.isDefault) {
611+
if (preset.isDefault && !get_is_preset_disabled(preset)) {
481612
preset_names.push(preset.name)
482613
}
483614
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,9 @@ export class ViewProvider implements vscode.WebviewViewProvider {
274274
} else if (message.command == 'SEND_PROMPT') {
275275
await handle_send_prompt({
276276
provider: this,
277-
preset_names: message.preset_names
277+
preset_name: message.preset_name,
278+
group_name: message.group_name,
279+
show_quick_pick: message.show_quick_pick
278280
})
279281
} else if (message.command == 'PREVIEW_PRESET') {
280282
await handle_preview_preset(this, message)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ export const View = () => {
265265
vscode={vscode}
266266
on_preset_edit={(preset) => {
267267
set_updating_preset(preset)
268+
set_updated_preset(preset)
268269
}}
269270
is_connected={is_connected}
270271
on_show_intro={() => set_active_view('intro')}

packages/vscode/src/view/frontend/home/Home.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,16 @@ export const Home: React.FC<Props> = (props) => {
201201
}
202202
}
203203

204-
const handle_initialize_chats = async (params: {
205-
preset_names?: string[]
204+
const handle_initialize_chats = (params: {
205+
preset_name?: string
206+
group_name?: string
207+
show_quick_pick?: boolean
206208
}) => {
207209
post_message(props.vscode, {
208210
command: 'SEND_PROMPT',
209-
preset_names: params.preset_names
211+
preset_name: params.preset_name,
212+
group_name: params.group_name,
213+
show_quick_pick: params.show_quick_pick
210214
})
211215

212216
update_chat_history(instructions)

0 commit comments

Comments
 (0)