Skip to content

Commit f735e0f

Browse files
committed
Refactor API and web configuration creation to integrate with update logic and support custom insertion positioning
- from reasoning effort quick pick, remove 'unset' option - standalone quick picks should have close buttons on the right, not back button on the left - rename 'New api configuration' quick pick title to 'new configuration' - once configuration is created, don't save yet, instead open the edit form so that user can set other details. Only after saving from there check for duplicates (in case of API configuration). - 'message' should not be of type any - 'Identical configuration already exists.' should be shown in modal so the user is able to close the form or stay
1 parent 3c7927f commit f735e0f

16 files changed

Lines changed: 304 additions & 201 deletions

‎apps/editor/src/views/actions/create-api-configuration/create-api-configuration.ts‎

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,12 @@ export const create_api_configuration = async (params: {
1818
tool_type: ToolType
1919
create_on_top?: boolean
2020
insertion_index?: number
21-
}): Promise<ApiConfiguration | undefined> => {
21+
}): Promise<
22+
{ config: ApiConfiguration; insertion_index?: number } | undefined
23+
> => {
2224
const providers_manager = new ModelProvidersManager(params.context)
2325
const model_fetcher = new ModelFetcher()
2426

25-
let set_default_api_configuration:
26-
| ((api_configuration: ApiConfiguration | null) => Promise<void>)
27-
| undefined
28-
29-
if (params.tool_type == 'code-at-cursor') {
30-
set_default_api_configuration = (c) =>
31-
providers_manager.set_default_code_completions_api_configuration(c)
32-
} else if (params.tool_type == 'commit-messages') {
33-
set_default_api_configuration = (c) =>
34-
providers_manager.set_default_commit_messages_api_configuration(c)
35-
} else if (params.tool_type == 'intelligent-update') {
36-
set_default_api_configuration = (c) =>
37-
providers_manager.set_default_intelligent_update_api_configuration(c)
38-
} else if (params.tool_type == 'find-relevant-files') {
39-
set_default_api_configuration = (c) =>
40-
providers_manager.set_default_find_relevant_files_api_configuration(c)
41-
} else if (params.tool_type == 'voice-input') {
42-
set_default_api_configuration = (c) =>
43-
providers_manager.set_default_voice_input_api_configuration(c)
44-
} else if (params.tool_type !== 'edit-context') {
45-
throw new Error(`Unknown tool type: ${params.tool_type}`)
46-
}
47-
48-
const api_configurations = await providers_manager.get_api_configurations()
49-
5027
let actual_insertion_index: number | undefined
5128

5229
if (params.insertion_index !== undefined) {
@@ -121,32 +98,12 @@ export const create_api_configuration = async (params: {
12198
temperature: undefined
12299
}
123100

124-
const new_id = get_api_configuration_id(api_configuration_to_add)
125-
126-
if (api_configurations.some((c) => get_api_configuration_id(c) === new_id)) {
127-
vscode.window.showErrorMessage(
128-
dictionary.error_message.CONFIGURATION_ALREADY_EXISTS
129-
)
130-
return undefined
131-
}
132-
133101
if (params.create_on_top) {
134-
api_configurations.unshift(api_configuration_to_add)
135-
} else if (actual_insertion_index !== undefined) {
136-
api_configurations.splice(
137-
actual_insertion_index,
138-
0,
139-
api_configuration_to_add
140-
)
141-
} else {
142-
api_configurations.push(api_configuration_to_add)
102+
actual_insertion_index = 0
143103
}
144104

145-
await providers_manager.save_api_configurations(api_configurations)
146-
147-
if (set_default_api_configuration) {
148-
await set_default_api_configuration(api_configuration_to_add)
105+
return {
106+
config: api_configuration_to_add,
107+
insertion_index: actual_insertion_index
149108
}
150-
151-
return api_configuration_to_add
152109
}

‎apps/editor/src/views/actions/create-api-configuration/interactions/initial-select-provider.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const initial_select_model_provider = async (
4545
} as any,
4646
...model_provider_items
4747
]
48-
quick_pick.title = 'New API Configuration'
48+
quick_pick.title = 'New Configuration'
4949
quick_pick.placeholder = 'Select a model provider'
5050
const close_button: vscode.QuickInputButton = {
5151
iconPath: new vscode.ThemeIcon('close'),

‎apps/editor/src/views/actions/create-web-configuration.ts‎

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import * as vscode from 'vscode'
2-
import { dictionary } from '@shared/constants/dictionary'
32
import { CHATBOTS } from '@shared/constants/chatbots'
43
import { ConfigWebConfigurationFormat } from '@/utils/web-configuration-format-converters'
54
import { generate_unique_name } from '../utils/generate-unique-name'
65

76
export const create_web_configuration = async (params: {
87
placement?: 'top' | 'bottom'
98
reference_index?: number
10-
}): Promise<ConfigWebConfigurationFormat | undefined> => {
9+
}): Promise<
10+
{ config: ConfigWebConfigurationFormat; insertion_index?: number } | undefined
11+
> => {
1112
const config = vscode.workspace.getConfiguration('codeWebChat')
1213
const current_web_configurations =
1314
config.get<ConfigWebConfigurationFormat[]>('webConfigurations', []) || []
@@ -128,20 +129,5 @@ export const create_web_configuration = async (params: {
128129
: undefined
129130
}
130131

131-
const updated_web_configurations = [...current_web_configurations]
132-
if (insertion_index !== undefined) {
133-
updated_web_configurations.splice(insertion_index, 0, new_web_configuration)
134-
} else {
135-
updated_web_configurations.push(new_web_configuration)
136-
}
137-
138-
try {
139-
await config.update('webConfigurations', updated_web_configurations, true)
140-
return new_web_configuration
141-
} catch (error) {
142-
vscode.window.showErrorMessage(
143-
dictionary.error_message.FAILED_TO_CREATE_ITEM('Web Configuration', error)
144-
)
145-
return undefined
146-
}
132+
return { config: new_web_configuration, insertion_index }
147133
}

‎apps/editor/src/views/actions/update-api-configuration/interactions/edit-model-for-api-config.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ export const edit_model_for_api_configuration = async (params: {
6666
quick_pick.items = model_items
6767
quick_pick.title = 'Models'
6868
quick_pick.placeholder = 'Choose a model'
69-
quick_pick.buttons = [vscode.QuickInputButtons.Back]
69+
const close_button: vscode.QuickInputButton = {
70+
iconPath: new vscode.ThemeIcon('close'),
71+
tooltip: 'Close'
72+
}
73+
quick_pick.buttons = [close_button]
7074
if (last_selected_model_id) {
7175
const active = model_items.find(
7276
(item) =>
@@ -84,7 +88,7 @@ export const edit_model_for_api_configuration = async (params: {
8488
quick_pick.hide()
8589
}),
8690
quick_pick.onDidTriggerButton((button) => {
87-
if (button === vscode.QuickInputButtons.Back) {
91+
if (button === close_button) {
8892
quick_pick.hide()
8993
}
9094
}),

‎apps/editor/src/views/actions/update-api-configuration/interactions/edit-provider-for-api-config.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ export const edit_model_provider_for_api_configuration = async (
1818
quick_pick.items = model_provider_items
1919
quick_pick.title = 'Model Providers'
2020
quick_pick.placeholder = 'Select a model provider'
21-
quick_pick.buttons = [vscode.QuickInputButtons.Back]
21+
const close_button: vscode.QuickInputButton = {
22+
iconPath: new vscode.ThemeIcon('close'),
23+
tooltip: 'Close'
24+
}
25+
quick_pick.buttons = [close_button]
2226
if (current_model_provider_name) {
2327
const active = model_provider_items.find(
2428
(p) => p.label === current_model_provider_name
@@ -35,7 +39,7 @@ export const edit_model_provider_for_api_configuration = async (
3539
quick_pick.hide()
3640
}),
3741
quick_pick.onDidTriggerButton((button) => {
38-
if (button === vscode.QuickInputButtons.Back) {
42+
if (button === close_button) {
3943
quick_pick.hide()
4044
}
4145
}),

‎apps/editor/src/views/actions/update-api-configuration/interactions/edit-reasoning-effort-for-api-config.ts‎

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,23 @@ export const edit_reasoning_effort_for_api_config = async (
44
current_effort?: string
55
) => {
66
const effort_options: vscode.QuickPickItem[] = [
7-
{
8-
label: 'Unset',
9-
description: 'Remove reasoning effort from the API configuration'
10-
}
11-
]
12-
13-
effort_options.push(
147
{ label: 'None' },
158
{ label: 'Minimal' },
169
{ label: 'Low' },
1710
{ label: 'Medium' },
1811
{ label: 'High' }
19-
)
12+
]
2013

21-
return await new Promise<string | null | undefined>((resolve) => {
14+
return await new Promise<string | undefined>((resolve) => {
2215
const quick_pick = vscode.window.createQuickPick()
2316
quick_pick.items = effort_options
2417
quick_pick.title = 'Edit API Configuration'
2518
quick_pick.placeholder = 'Select reasoning effort'
26-
quick_pick.buttons = [vscode.QuickInputButtons.Back]
19+
const close_button: vscode.QuickInputButton = {
20+
iconPath: new vscode.ThemeIcon('close'),
21+
tooltip: 'Close'
22+
}
23+
quick_pick.buttons = [close_button]
2724
if (current_effort) {
2825
const active = effort_options.find(
2926
(item) => item.label.toLowerCase() === current_effort.toLowerCase()
@@ -39,16 +36,14 @@ export const edit_reasoning_effort_for_api_config = async (
3936
accepted = true
4037
const selected = quick_pick.selectedItems[0]
4138
if (selected) {
42-
resolve(
43-
selected.label == 'Unset' ? null : selected.label.toLowerCase()
44-
)
39+
resolve(selected.label.toLowerCase())
4540
} else {
4641
resolve(undefined)
4742
}
4843
quick_pick.hide()
4944
}),
5045
quick_pick.onDidTriggerButton((button) => {
51-
if (button === vscode.QuickInputButtons.Back) {
46+
if (button === close_button) {
5247
quick_pick.hide()
5348
}
5449
}),

‎apps/editor/src/views/actions/update-api-configuration/update-api-configuration.ts‎

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,51 @@ import {
55
get_api_configuration_id
66
} from '@/services/model-providers-manager'
77
import { ApiConfiguration } from '@/views/panel/types/messages'
8+
import { ToolType } from '@/views/settings/types/tools'
89

910
export const update_api_configuration = async (params: {
1011
context: vscode.ExtensionContext
1112
updating_api_configuration: ApiConfiguration
1213
updated_api_configuration: ApiConfiguration
1314
origin?: 'cancel' | 'save'
15+
is_new?: boolean
16+
insertion_index?: number
17+
tool_type?: ToolType
1418
}): Promise<{ success: boolean; has_changes: boolean; new_id?: string }> => {
1519
const providers_manager = new ModelProvidersManager(params.context)
20+
21+
if (params.is_new && params.origin === 'cancel') {
22+
return { success: true, has_changes: false }
23+
}
24+
1625
const api_configurations = await providers_manager.get_api_configurations()
1726

18-
const api_configuration_index = api_configurations.findIndex(
19-
(p) => get_api_configuration_id(p) == params.updating_api_configuration.id
20-
)
27+
let api_configuration_index = -1
28+
if (!params.is_new) {
29+
api_configuration_index = api_configurations.findIndex(
30+
(p) => get_api_configuration_id(p) == params.updating_api_configuration.id
31+
)
2132

22-
if (api_configuration_index == -1 && params.origin != 'cancel') {
23-
vscode.window.showErrorMessage(
24-
dictionary.error_message.COULD_NOT_UPDATE_ITEM_NOT_FOUND(
25-
'API configuration',
26-
params.updating_api_configuration.id
33+
if (api_configuration_index == -1 && params.origin != 'cancel') {
34+
vscode.window.showErrorMessage(
35+
dictionary.error_message.COULD_NOT_UPDATE_ITEM_NOT_FOUND(
36+
'API configuration',
37+
params.updating_api_configuration.id
38+
)
2739
)
28-
)
29-
return { success: false, has_changes: false }
40+
return { success: false, has_changes: false }
41+
}
3042
}
3143

3244
const has_changes =
3345
params.updating_api_configuration.id !==
34-
get_api_configuration_id(params.updated_api_configuration)
46+
get_api_configuration_id(params.updated_api_configuration) ||
47+
params.updating_api_configuration.system_instructions_override !==
48+
params.updated_api_configuration.system_instructions_override ||
49+
params.updating_api_configuration.is_pinned !==
50+
params.updated_api_configuration.is_pinned
3551

36-
if (!has_changes) {
52+
if (!has_changes && !params.is_new) {
3753
return { success: true, has_changes: false }
3854
}
3955

@@ -59,36 +75,76 @@ export const update_api_configuration = async (params: {
5975
}
6076

6177
const new_config = {
62-
...api_configurations[api_configuration_index],
78+
...(!params.is_new && api_configuration_index !== -1
79+
? api_configurations[api_configuration_index]
80+
: {}),
6381
model_provider_name: params.updated_api_configuration.model_provider_name,
6482
model: params.updated_api_configuration.model,
6583
temperature: params.updated_api_configuration.temperature,
6684
reasoning_effort: params.updated_api_configuration.reasoning_effort,
6785
system_instructions_override:
68-
params.updated_api_configuration.system_instructions_override
86+
params.updated_api_configuration.system_instructions_override,
87+
is_pinned: params.updated_api_configuration.is_pinned
6988
}
7089

71-
const new_id = get_api_configuration_id(new_config)
90+
const new_id = get_api_configuration_id(new_config as any)
91+
92+
const is_duplicate = params.is_new
93+
? api_configurations.some((c) => get_api_configuration_id(c) === new_id)
94+
: new_id != params.updating_api_configuration.id &&
95+
api_configurations.some((c) => get_api_configuration_id(c) === new_id)
7296

73-
// check if id already exists AND it's not the one we're editing
74-
if (
75-
new_id !== params.updating_api_configuration.id &&
76-
api_configurations.some((c) => get_api_configuration_id(c) === new_id)
77-
) {
78-
vscode.window.showErrorMessage(
79-
dictionary.error_message.CONFIGURATION_ALREADY_EXISTS
97+
if (is_duplicate) {
98+
const discard_button = 'Discard'
99+
const result = await vscode.window.showWarningMessage(
100+
dictionary.error_message.CONFIGURATION_ALREADY_EXISTS,
101+
{ modal: true },
102+
discard_button
80103
)
104+
105+
if (result == discard_button) {
106+
return { success: true, has_changes: false }
107+
}
108+
81109
return { success: false, has_changes: true }
82110
}
83111

84-
if (api_configuration_index !== -1) {
85-
api_configurations[api_configuration_index] = new_config
86-
} else {
87-
api_configurations.push(new_config)
112+
if (params.is_new) {
113+
if (params.insertion_index !== undefined) {
114+
api_configurations.splice(params.insertion_index, 0, new_config as any)
115+
} else {
116+
api_configurations.push(new_config as any)
117+
}
118+
} else if (api_configuration_index !== -1) {
119+
api_configurations[api_configuration_index] = new_config as any
88120
}
89121

90122
await providers_manager.save_api_configurations(api_configurations)
91123

124+
if (params.is_new && params.tool_type) {
125+
if (params.tool_type == 'code-at-cursor') {
126+
await providers_manager.set_default_code_completions_api_configuration(
127+
new_config as any
128+
)
129+
} else if (params.tool_type == 'commit-messages') {
130+
await providers_manager.set_default_commit_messages_api_configuration(
131+
new_config as any
132+
)
133+
} else if (params.tool_type == 'intelligent-update') {
134+
await providers_manager.set_default_intelligent_update_api_configuration(
135+
new_config as any
136+
)
137+
} else if (params.tool_type == 'find-relevant-files') {
138+
await providers_manager.set_default_find_relevant_files_api_configuration(
139+
new_config as any
140+
)
141+
} else if (params.tool_type == 'voice-input') {
142+
await providers_manager.set_default_voice_input_api_configuration(
143+
new_config as any
144+
)
145+
}
146+
}
147+
92148
return {
93149
success: true,
94150
has_changes: true,

0 commit comments

Comments
 (0)