Skip to content

Commit 8b7cbb4

Browse files
committed
Refactor configuration editing logic into shared helper functions
1 parent 6d718cd commit 8b7cbb4

11 files changed

Lines changed: 481 additions & 1230 deletions

packages/vscode/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "gemini-coder",
33
"displayName": "Code Web Chat",
44
"description": "CWC connects VS Code with ChatGPT, Gemini, Claude, and 10+ more",
5-
"version": "1.369.0",
5+
"version": "1.370.0",
66
"scripts": {
77
"build": "npx vsce package --no-dependencies",
88
"vscode:prepublish": "rimraf out && npm run compile",

packages/vscode/src/commands/code-completion-commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const get_code_completion_config = async (
5959
config_index?: number,
6060
view_provider?: ViewProvider
6161
): Promise<{ provider: any; config: any } | undefined> => {
62-
let code_completions_configs =
62+
const code_completions_configs =
6363
await api_providers_manager.get_code_completions_tool_configs()
6464

6565
if (code_completions_configs.length == 0) {
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import * as vscode from 'vscode'
2+
import {
3+
ApiProvidersManager,
4+
Provider,
5+
ToolConfig
6+
} from '@/services/api-providers-manager'
7+
import {
8+
ModelFetcher,
9+
MODELS_ROUTE_NOT_FOUND_ERROR
10+
} from '@/services/model-fetcher'
11+
import { PROVIDERS } from '@shared/constants/providers'
12+
import { Logger } from '@shared/utils/logger'
13+
14+
export const initial_select_provider = async (
15+
providers_manager: ApiProvidersManager
16+
): Promise<Provider | undefined> => {
17+
const providers = await providers_manager.get_providers()
18+
19+
if (providers.length === 0) {
20+
vscode.window.showWarningMessage(
21+
'No API providers configured. Please add an API provider first on the "API Providers" page.'
22+
)
23+
return
24+
}
25+
26+
const provider_items = providers.map((p) => ({ label: p.name, provider: p }))
27+
const selected = await vscode.window.showQuickPick(provider_items, {
28+
title: 'Select a Provider'
29+
})
30+
31+
return selected?.provider
32+
}
33+
34+
export const initial_select_model = async (
35+
model_fetcher: ModelFetcher,
36+
provider: Provider
37+
): Promise<string | undefined> => {
38+
try {
39+
const base_url =
40+
provider.type == 'built-in'
41+
? PROVIDERS[provider.name]?.base_url
42+
: provider.base_url
43+
if (!base_url)
44+
throw new Error(`Base URL not found for provider ${provider.name}`)
45+
46+
const models = await model_fetcher.get_models({
47+
base_url,
48+
api_key: provider.api_key
49+
})
50+
51+
if (models.length > 0) {
52+
const model_items = models.map((model) => ({
53+
label: model.name || model.id,
54+
description: model.name ? model.id : undefined,
55+
detail: model.description
56+
}))
57+
const selected = await vscode.window.showQuickPick(model_items, {
58+
title: 'Select Model',
59+
placeHolder: 'Choose an AI model'
60+
})
61+
if (selected) return selected.description || selected.label
62+
return // User cancelled
63+
}
64+
} catch (error) {
65+
Logger.error({
66+
function_name: 'initial_select_model',
67+
message: 'Failed to fetch models',
68+
data: error
69+
})
70+
if (
71+
error instanceof Error &&
72+
error.message == MODELS_ROUTE_NOT_FOUND_ERROR
73+
) {
74+
vscode.window.showInformationMessage(
75+
`The '/models' route was not found for ${provider.name}. This might mean the provider does not support listing models.`
76+
)
77+
} else {
78+
vscode.window.showErrorMessage(
79+
`Failed to fetch models: ${
80+
error instanceof Error ? error.message : String(error)
81+
}`
82+
)
83+
}
84+
}
85+
86+
return await vscode.window.showInputBox({
87+
title: 'Enter Model Name',
88+
prompt: 'Could not fetch models. Please enter a model name (ID).'
89+
})
90+
}
91+
92+
export const edit_provider_for_config = async (
93+
providers_manager: ApiProvidersManager
94+
) => {
95+
const providers = await providers_manager.get_providers()
96+
const provider_items = providers.map((p) => ({
97+
label: p.name,
98+
detail: p.type,
99+
provider: p
100+
}))
101+
const selected_provider_item = await vscode.window.showQuickPick(
102+
provider_items,
103+
{ title: 'Select a Provider' }
104+
)
105+
if (selected_provider_item) {
106+
return {
107+
provider_name: selected_provider_item.provider.name,
108+
provider_type: selected_provider_item.provider.type
109+
}
110+
}
111+
return undefined
112+
}
113+
114+
export const edit_model_for_config = async (
115+
config: ToolConfig,
116+
providers_manager: ApiProvidersManager,
117+
model_fetcher: ModelFetcher
118+
) => {
119+
const provider_from_manager = await providers_manager.get_provider(
120+
config.provider_name
121+
)
122+
if (!provider_from_manager) {
123+
vscode.window.showErrorMessage(
124+
`Provider ${config.provider_name} not found.`
125+
)
126+
return undefined
127+
}
128+
129+
const base_url =
130+
provider_from_manager.type == 'built-in'
131+
? PROVIDERS[provider_from_manager.name]?.base_url
132+
: provider_from_manager.base_url
133+
134+
if (!base_url) {
135+
vscode.window.showErrorMessage(
136+
`Base URL not found for provider ${config.provider_name}.`
137+
)
138+
return undefined
139+
}
140+
141+
let new_model_value: string | undefined
142+
let model_selected = false
143+
144+
try {
145+
const models = await model_fetcher.get_models({
146+
base_url,
147+
api_key: provider_from_manager.api_key
148+
})
149+
150+
if (models.length > 0) {
151+
const model_items = models.map((model) => ({
152+
label: model.name || model.id,
153+
description: model.name ? model.id : undefined,
154+
detail: model.description
155+
}))
156+
const selected_model_item = await vscode.window.showQuickPick(
157+
model_items,
158+
{ title: 'Select Model', placeHolder: 'Choose an AI model' }
159+
)
160+
if (selected_model_item) {
161+
new_model_value =
162+
selected_model_item.description || selected_model_item.label
163+
model_selected = true
164+
}
165+
} else {
166+
vscode.window.showWarningMessage(
167+
`No models found for ${config.provider_name}. You can enter model name manually.`
168+
)
169+
}
170+
} catch (error) {
171+
Logger.error({
172+
function_name: 'edit_model_for_config',
173+
message: 'Failed to fetch models',
174+
data: error
175+
})
176+
if (
177+
error instanceof Error &&
178+
error.message == MODELS_ROUTE_NOT_FOUND_ERROR
179+
) {
180+
vscode.window.showInformationMessage(
181+
`The '/models' route was not found for ${config.provider_name}. This might mean the provider does not support listing models. You can enter model name manually.`
182+
)
183+
} else {
184+
vscode.window.showErrorMessage(
185+
`Failed to fetch models: ${
186+
error instanceof Error ? error.message : String(error)
187+
}`
188+
)
189+
}
190+
}
191+
192+
if (!model_selected) {
193+
const new_model_input = await vscode.window.showInputBox({
194+
title: 'Enter Model Name',
195+
value: config.model,
196+
prompt: `Enter a model name (ID)`
197+
})
198+
if (new_model_input !== undefined) new_model_value = new_model_input
199+
}
200+
201+
if (new_model_value !== undefined) return new_model_value.trim()
202+
return undefined
203+
}
204+
205+
export const edit_temperature_for_config = async (config: ToolConfig) => {
206+
const new_temp_str = await vscode.window.showInputBox({
207+
title: 'Edit Temperature',
208+
value: String(config.temperature),
209+
prompt: 'Enter a value between 0 and 2',
210+
validateInput: (value) => {
211+
const num = parseFloat(value)
212+
if (isNaN(num) || num < 0 || num > 2) {
213+
return 'Please enter a number between 0 and 2.'
214+
}
215+
return null
216+
}
217+
})
218+
if (new_temp_str !== undefined) return parseFloat(new_temp_str)
219+
return undefined
220+
}
221+
222+
export const edit_reasoning_effort_for_config = async () => {
223+
const effort_options: ('auto' | 'low' | 'medium' | 'high')[] = [
224+
'auto',
225+
'low',
226+
'medium',
227+
'high'
228+
]
229+
const selected_effort = await vscode.window.showQuickPick(effort_options, {
230+
title: 'Select Reasoning Effort'
231+
})
232+
return selected_effort
233+
}
234+
235+
export const edit_instructions_placement_for_config = async () => {
236+
const placement_options: ('above-and-below' | 'below-only')[] = [
237+
'above-and-below',
238+
'below-only'
239+
]
240+
const selected_placement = await vscode.window.showQuickPick(
241+
placement_options,
242+
{ title: 'Select Instructions Placement' }
243+
)
244+
return selected_placement
245+
}
246+
247+
export const edit_max_concurrency_for_config = async (config: ToolConfig) => {
248+
const new_concurrency_str = await vscode.window.showInputBox({
249+
title: 'Edit Max Concurrency',
250+
value: String(config.max_concurrency ?? 1),
251+
prompt: 'Enter a number for max concurrency',
252+
validateInput: (value) => {
253+
const num = parseInt(value, 10)
254+
if (isNaN(num) || !Number.isInteger(num) || num < 1) {
255+
return 'Please enter a whole number greater than or equal to 1.'
256+
}
257+
return null
258+
}
259+
})
260+
if (new_concurrency_str !== undefined)
261+
return parseInt(new_concurrency_str, 10)
262+
return undefined
263+
}

0 commit comments

Comments
 (0)