Skip to content

Commit 52980db

Browse files
committed
Replace the QuickPick-based API configuration editing flow with a dedicated React form and remove duplicate configuration functionality
- current behavior: api configurations are edited in a quick pick. Expected behavior: 'api configurations' editing follows how we edit 'web configurations' - remove ability to duplicate 'web configuration' - remove ability to duplicate 'api configuration'
1 parent e0f9e4f commit 52980db

36 files changed

Lines changed: 806 additions & 847 deletions

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

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import * as vscode from 'vscode'
2+
import { dictionary } from '@shared/constants/dictionary'
3+
import {
4+
ModelProvidersManager,
5+
get_api_configuration_id
6+
} from '@/services/model-providers-manager'
7+
import { ApiConfiguration } from '../panel/types/messages'
8+
9+
export const update_api_configuration = async (params: {
10+
context: vscode.ExtensionContext
11+
updating_api_configuration: ApiConfiguration
12+
updated_api_configuration: ApiConfiguration
13+
origin?: 'cancel' | 'save'
14+
}): Promise<{ success: boolean; has_changes: boolean; new_id?: string }> => {
15+
const providers_manager = new ModelProvidersManager(params.context)
16+
const api_configurations = await providers_manager.get_api_configurations()
17+
18+
const api_configuration_index = api_configurations.findIndex(
19+
(p) => get_api_configuration_id(p) == params.updating_api_configuration.id
20+
)
21+
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
27+
)
28+
)
29+
return { success: false, has_changes: false }
30+
}
31+
32+
const has_changes =
33+
params.updating_api_configuration.id !==
34+
get_api_configuration_id(params.updated_api_configuration)
35+
36+
if (!has_changes) {
37+
return { success: true, has_changes: false }
38+
}
39+
40+
if (params.origin == 'cancel') {
41+
const save_changes_button = 'Save'
42+
const result = await vscode.window.showWarningMessage(
43+
dictionary.information_message.CONFIRM_SAVE_CHANGES_TO_ITEM(
44+
'API configuration'
45+
),
46+
{
47+
modal: true,
48+
detail:
49+
dictionary.information_message.UNSAVED_CHANGES_TO_ITEM_WILL_BE_LOST(
50+
'API configuration'
51+
)
52+
},
53+
save_changes_button
54+
)
55+
56+
if (result != save_changes_button) {
57+
return { success: true, has_changes: false }
58+
}
59+
}
60+
61+
const new_config = {
62+
...api_configurations[api_configuration_index],
63+
model_provider_name: params.updated_api_configuration.model_provider_name,
64+
model: params.updated_api_configuration.model,
65+
temperature: params.updated_api_configuration.temperature,
66+
reasoning_effort: params.updated_api_configuration.reasoning_effort,
67+
system_instructions_override:
68+
params.updated_api_configuration.system_instructions_override
69+
}
70+
71+
const new_id = get_api_configuration_id(new_config)
72+
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
80+
)
81+
return { success: false, has_changes: true }
82+
}
83+
84+
if (api_configuration_index !== -1) {
85+
api_configurations[api_configuration_index] = new_config
86+
} else {
87+
api_configurations.push(new_config)
88+
}
89+
90+
await providers_manager.save_api_configurations(api_configurations)
91+
92+
return {
93+
success: true,
94+
has_changes: true,
95+
new_id
96+
}
97+
}

‎apps/editor/src/views/actions/upsert-api-configuration/interactions/edit-system-instructions-override-for-api-config.ts‎

Lines changed: 0 additions & 37 deletions
This file was deleted.

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

Lines changed: 0 additions & 55 deletions
This file was deleted.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
export * from './edit-model-for-api-config'
22
export * from './edit-provider-for-api-config'
33
export * from './edit-reasoning-effort-for-api-config'
4-
export * from './edit-system-instructions-override-for-api-config'
5-
export * from './edit-temperature-for-api-config'
64
export * from './initial-select-model'
75
export * from './initial-select-provider'
86
export * from './verify-model'
7+
export * from './verify-reasoning-effort'
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import * as vscode from 'vscode'
2+
import axios from 'axios'
3+
import { ModelProvider } from '@/services/model-providers-manager'
4+
import { apply_reasoning_effort } from '@/utils/apply-reasoning-effort'
5+
6+
export const verify_reasoning_effort = async (params: {
7+
endpoint_url: string
8+
api_key?: string
9+
model: string
10+
reasoning_effort: string
11+
model_provider: ModelProvider
12+
cancellation_token: vscode.CancellationToken
13+
}): Promise<void> => {
14+
const cancel_source = axios.CancelToken.source()
15+
16+
const disposable = params.cancellation_token.onCancellationRequested(() => {
17+
cancel_source.cancel('User cancelled')
18+
})
19+
20+
const body = {
21+
model: params.model,
22+
messages: [
23+
{
24+
role: 'user',
25+
content: 'Respond with "Hello!" and nothing else.'
26+
}
27+
],
28+
stream: true
29+
}
30+
31+
apply_reasoning_effort({
32+
body,
33+
model_provider: params.model_provider,
34+
reasoning_effort: params.reasoning_effort as any
35+
})
36+
37+
try {
38+
const response = await axios.post(
39+
params.endpoint_url + '/chat/completions',
40+
body,
41+
{
42+
headers: {
43+
...(params.api_key
44+
? { ['Authorization']: `Bearer ${params.api_key}` }
45+
: {}),
46+
['Content-Type']: 'application/json'
47+
},
48+
responseType: 'stream',
49+
cancelToken: cancel_source.token
50+
}
51+
)
52+
53+
await new Promise<void>((resolve, reject) => {
54+
const stream = response.data
55+
56+
stream.on('data', () => {
57+
cancel_source.cancel('Verified')
58+
resolve()
59+
})
60+
61+
stream.on('error', (err: any) => {
62+
reject(err)
63+
})
64+
65+
stream.on('end', () => {
66+
resolve()
67+
})
68+
})
69+
} catch (error) {
70+
if (axios.isCancel(error)) {
71+
if (error.message == 'Verified') {
72+
return
73+
}
74+
if (error.message == 'User cancelled') {
75+
throw new Error('Cancelled')
76+
}
77+
}
78+
throw error
79+
} finally {
80+
disposable.dispose()
81+
}
82+
}

0 commit comments

Comments
 (0)