Skip to content

Commit efac831

Browse files
committed
Support template variables in prompt template quick pick
- rename to 'handle prompt template quick pick' - upon opening should highlight first (the most recent) item, not 'add new' - add back arrow from 'enter variable', allowing going back to previous input/initial list of prompt templates - when going 'back' to the list, change highlight to the item that was attempted to use
1 parent 9d50bfb commit efac831

4 files changed

Lines changed: 132 additions & 15 deletions

File tree

apps/editor/src/views/prompt/backend/message-handlers/handle-show-prompt-template-quick-pick.ts renamed to apps/editor/src/views/prompt/backend/message-handlers/handle-prompt-template-quick-pick.ts

Lines changed: 118 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type PromptTemplate = {
1212

1313
const ADD_NEW_TEMPLATE_LABEL = '$(add) New prompt template...'
1414

15-
export const handle_show_prompt_template_quick_pick = async (
15+
export const handle_prompt_template_quick_pick = async (
1616
prompt_view_provider: PromptViewProvider
1717
): Promise<void> => {
1818
const prompt_type: WebPromptType | ApiPromptType | undefined =
@@ -220,10 +220,16 @@ export const handle_show_prompt_template_quick_pick = async (
220220

221221
templates_quick_pick.items = create_template_items(prompt_templates)
222222

223+
const first_template_item = templates_quick_pick.items.find((i) => i.template)
224+
if (first_template_item) {
225+
templates_quick_pick.activeItems = [first_template_item]
226+
}
227+
223228
const disposables: vscode.Disposable[] = []
224229
let is_disposed = false
225230
let notification_count = 0
226231
let is_template_accepted = false
232+
let is_entering_variables = false
227233

228234
disposables.push(
229235
templates_quick_pick.onDidTriggerButton((_button) => {
@@ -262,14 +268,15 @@ export const handle_show_prompt_template_quick_pick = async (
262268
templates_quick_pick.show()
263269
}
264270
}
271+
272+
is_editing_template = false
265273
} else if (
266274
'template' in selected_template &&
267275
selected_template.template &&
268276
typeof selected_template.index == 'number'
269277
) {
270-
is_template_accepted = true
278+
is_entering_variables = true
271279
templates_quick_pick.hide()
272-
is_disposed = true
273280

274281
// Move the selected template to the top of the list for easier access next time
275282
if (selected_template.index > 0) {
@@ -300,13 +307,106 @@ export const handle_show_prompt_template_quick_pick = async (
300307
])
301308
]
302309

310+
const variable_values: Record<string, string> = {}
311+
let cancelled = false
312+
let go_back_to_templates = false
313+
303314
if (variables.length > 0) {
304-
for (const variable of variables) {
305-
const value = await vscode.window.showInputBox({
306-
title: 'Enter Variable',
307-
placeHolder: variable
315+
let i = 0
316+
while (i < variables.length) {
317+
const variable = variables[i]
318+
319+
const result = await new Promise<{
320+
value?: string
321+
back: boolean
322+
cancel: boolean
323+
}>((resolve) => {
324+
const input = vscode.window.createInputBox()
325+
input.title = 'Enter Variable'
326+
input.placeholder = variable
327+
input.value = variable_values[variable] || ''
328+
input.buttons = [vscode.QuickInputButtons.Back]
329+
330+
let resolved = false
331+
const input_disposables: vscode.Disposable[] = []
332+
333+
input_disposables.push(
334+
input.onDidTriggerButton((button) => {
335+
if (button === vscode.QuickInputButtons.Back) {
336+
resolved = true
337+
input.hide()
338+
resolve({ back: true, cancel: false })
339+
}
340+
}),
341+
input.onDidAccept(() => {
342+
resolved = true
343+
const val = input.value
344+
input.hide()
345+
resolve({ value: val, back: false, cancel: false })
346+
}),
347+
input.onDidHide(() => {
348+
if (!resolved) {
349+
resolve({ cancel: true, back: false })
350+
}
351+
input_disposables.forEach((d) => d.dispose())
352+
input.dispose()
353+
})
354+
)
355+
356+
input.show()
308357
})
309358

359+
if (result.cancel) {
360+
cancelled = true
361+
break
362+
}
363+
364+
if (result.back) {
365+
if (i === 0) {
366+
go_back_to_templates = true
367+
break
368+
} else {
369+
i--
370+
continue
371+
}
372+
}
373+
374+
if (result.value !== undefined) {
375+
variable_values[variable] = result.value
376+
i++
377+
}
378+
}
379+
380+
if (cancelled) {
381+
is_entering_variables = false
382+
is_disposed = true
383+
prompt_view_provider.send_message({
384+
command: 'FOCUS_PROMPT_FIELD'
385+
})
386+
disposables.forEach((d) => d.dispose())
387+
return
388+
}
389+
390+
if (go_back_to_templates) {
391+
is_entering_variables = false
392+
templates_quick_pick.items = create_template_items(
393+
prompt_templates,
394+
templates_quick_pick.value
395+
)
396+
397+
const attempted_item = templates_quick_pick.items.find(
398+
(i) => i.template === selected_template.template
399+
)
400+
if (attempted_item) {
401+
templates_quick_pick.activeItems = [attempted_item]
402+
}
403+
404+
templates_quick_pick.show()
405+
return
406+
}
407+
408+
for (const variable of variables) {
409+
const value = variable_values[variable]
310410
if (value) {
311411
const double_regex = new RegExp(
312412
`\\{\\{\\s*${variable.replace(
@@ -328,6 +428,10 @@ export const handle_show_prompt_template_quick_pick = async (
328428
}
329429
}
330430

431+
is_entering_variables = false
432+
is_template_accepted = true
433+
is_disposed = true
434+
331435
const current_text = prompt_view_provider.current_instruction
332436
const is_after_slash = current_text
333437
.slice(0, prompt_view_provider.caret_position)
@@ -340,6 +444,7 @@ export const handle_show_prompt_template_quick_pick = async (
340444
prompt_view_provider.send_message({
341445
command: 'FOCUS_PROMPT_FIELD'
342446
})
447+
disposables.forEach((d) => d.dispose())
343448
}
344449
}),
345450
templates_quick_pick.onDidChangeValue((value) => {
@@ -459,9 +564,14 @@ export const handle_show_prompt_template_quick_pick = async (
459564
}
460565
}),
461566
templates_quick_pick.onDidHide(() => {
462-
if (is_editing_template || notification_count > 0) {
567+
if (
568+
is_editing_template ||
569+
notification_count > 0 ||
570+
is_entering_variables
571+
) {
463572
// We are editing a template, which involves showing input boxes that hide the quick pick.
464573
// Or we are showing a dialog (warning/info message) which also hides the quick pick.
574+
// Or we are filling out variables for the template which hides the quick pick.
465575
// We don't want to dispose of everything in these cases.
466576
return
467577
}

‎apps/editor/src/views/prompt/backend/message-handlers/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export * from './handle-save-instructions'
1515
export * from './handle-reorder-web-configurations'
1616
export * from './handle-toggle-pinned-web-configuration'
1717
export * from './handle-autofill'
18-
export * from './handle-show-prompt-template-quick-pick'
18+
export * from './handle-prompt-template-quick-pick'
1919
export * from './handle-create-web-configuration'
2020
export * from './handle-update-web-configuration'
2121
export * from './handle-pick-chatbot'

‎apps/editor/src/views/prompt/backend/prompt-view-provider.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
handle_get_mode,
4343
handle_get_workspace_state,
4444
handle_get_version,
45-
handle_show_prompt_template_quick_pick,
45+
handle_prompt_template_quick_pick,
4646
handle_get_api_configurations,
4747
handle_reorder_api_configurations,
4848
handle_toggle_pinned_api_configuration,
@@ -751,7 +751,7 @@ export class PromptViewProvider implements vscode.WebviewViewProvider {
751751
} else if (message.command == 'MAKE_API_CALL') {
752752
await handle_make_api_call(this, message)
753753
} else if (message.command == 'SHOW_PROMPT_TEMPLATE_QUICK_PICK') {
754-
await handle_show_prompt_template_quick_pick(this)
754+
await handle_prompt_template_quick_pick(this)
755755
} else if (message.command == 'GET_WEB_PROMPT_TYPE') {
756756
handle_get_web_prompt_type(this)
757757
} else if (message.command == 'CANCEL_API_REQUEST') {
Lines changed: 11 additions & 4 deletions
Loading

0 commit comments

Comments
 (0)