Skip to content

Commit 1d0a245

Browse files
committed
Replace last-selected config tracking with recently-used lists across all API tool configurations
1 parent a3e9037 commit 1d0a245

11 files changed

Lines changed: 259 additions & 172 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ Code Web Chat is a free and open-source (FOSS), independent AI coding toolkit fo
1919
- APIs—_[Google](https://aistudio.google.com/api-keys), [OpenAI](https://platform.openai.com/api-keys), [OpenRouter](https://openrouter.ai/settings/keys), [local Ollama](https://ollama.com/search), etc._
2020

2121
**Apply responses**—interactive multi-file changes integration \
22-
**Fully-featured**code at cursor, commit messages, etc. \
23-
🫰 **Cost-efficient**optimized [prompt caching](https://platform.openai.com/docs/guides/prompt-caching) across tasks \
22+
**Fully-featured**tab completions, commit messages, etc. \
23+
🫰 **Cost-efficient**[prompt caching](https://platform.openai.com/docs/guides/prompt-caching) utilization across tasks \
2424
**Privacy-first**—strict zero telemetry policy
2525

2626
<p>

apps/editor/src/commands/code-at-cursor-commands.ts

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ import {
1010
import { Logger } from '@shared/utils/logger'
1111
import he from 'he'
1212
import { PROVIDERS } from '@shared/constants/providers'
13-
import {
14-
LAST_SELECTED_CODE_AT_CURSOR_CONFIG_ID_STATE_KEY,
15-
RECENTLY_USED_CODE_AT_CURSOR_CONFIG_IDS_STATE_KEY
16-
} from '@/constants/state-keys'
13+
import { RECENTLY_USED_CODE_AT_CURSOR_CONFIG_IDS_STATE_KEY } from '@/constants/state-keys'
1714
import { ToolConfig } from '@/services/model-providers-manager'
1815
import { PanelProvider } from '@/views/panel/backend/panel-provider'
1916
import { dictionary } from '@shared/constants/dictionary'
@@ -86,13 +83,14 @@ const get_code_at_cursor_config = async (
8683
if (default_config) {
8784
selected_config = default_config
8885
} else {
89-
const last_selected_id = context.workspaceState.get<string>(
90-
LAST_SELECTED_CODE_AT_CURSOR_CONFIG_ID_STATE_KEY
86+
const recents = context.workspaceState.get<string[]>(
87+
RECENTLY_USED_CODE_AT_CURSOR_CONFIG_IDS_STATE_KEY
9188
)
89+
const last_selected_id = recents?.[0]
9290
if (last_selected_id) {
9391
selected_config =
9492
code_at_cursor_configs.find(
95-
(c) => get_tool_config_id(c) === last_selected_id
93+
(c) => get_tool_config_id(c) == last_selected_id
9694
) || null
9795
}
9896
if (!selected_config && code_at_cursor_configs.length > 0) {
@@ -180,16 +178,9 @@ const get_code_at_cursor_config = async (
180178
quick_pick.placeholder = 'Select code at cursor configuration'
181179
quick_pick.matchOnDescription = true
182180

183-
const last_selected_id = context.workspaceState.get<string>(
184-
LAST_SELECTED_CODE_AT_CURSOR_CONFIG_ID_STATE_KEY
185-
)
186-
187181
const items = quick_pick.items as (vscode.QuickPickItem & { id: string })[]
188-
const last_selected_item = items.find((item) => item.id == last_selected_id)
189182

190-
if (last_selected_item) {
191-
quick_pick.activeItems = [last_selected_item]
192-
} else if (items.length > 0) {
183+
if (items.length > 0) {
193184
const first_selectable = items.find(
194185
(i) => i.kind != vscode.QuickPickItemKind.Separator
195186
)
@@ -209,11 +200,6 @@ const get_code_at_cursor_config = async (
209200
return
210201
}
211202

212-
context.workspaceState.update(
213-
LAST_SELECTED_CODE_AT_CURSOR_CONFIG_ID_STATE_KEY,
214-
selected.id
215-
)
216-
217203
let recents =
218204
context.workspaceState.get<string[]>(
219205
RECENTLY_USED_CODE_AT_CURSOR_CONFIG_IDS_STATE_KEY

apps/editor/src/commands/generate-commit-message-command/utils/get-commit-message-config.ts

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import * as vscode from 'vscode'
22
import {
33
ModelProvidersManager,
44
ReasoningEffort,
5-
get_tool_config_id
5+
get_tool_config_id,
6+
ToolConfig
67
} from '@/services/model-providers-manager'
78
import { dictionary } from '@shared/constants/dictionary'
89
import { Logger } from '@shared/utils/logger'
910
import { PROVIDERS } from '@shared/constants/providers'
10-
import { LAST_SELECTED_COMMIT_MESSAGES_CONFIG_ID_STATE_KEY } from '@/constants/state-keys'
11+
import { RECENTLY_USED_COMMIT_MESSAGES_CONFIG_IDS_STATE_KEY } from '@/constants/state-keys'
1112

1213
export interface CommitMessageConfig {
1314
provider_name: string
@@ -42,45 +43,99 @@ export const get_commit_message_config = async (
4243
if (configs.length == 1) {
4344
commit_message_config = configs[0]
4445
} else if (configs.length > 1) {
46+
const create_items = () => {
47+
const recent_ids =
48+
context.workspaceState.get<string[]>(
49+
RECENTLY_USED_COMMIT_MESSAGES_CONFIG_IDS_STATE_KEY
50+
) || []
51+
52+
const matched_recent_configs: ToolConfig[] = []
53+
const remaining_configs: ToolConfig[] = []
54+
55+
configs.forEach((config) => {
56+
const id = get_tool_config_id(config)
57+
if (recent_ids.includes(id)) {
58+
matched_recent_configs.push(config)
59+
} else {
60+
remaining_configs.push(config)
61+
}
62+
})
63+
64+
matched_recent_configs.sort((a, b) => {
65+
const id_a = get_tool_config_id(a)
66+
const id_b = get_tool_config_id(b)
67+
return recent_ids.indexOf(id_a) - recent_ids.indexOf(id_b)
68+
})
69+
70+
const recent_configs = matched_recent_configs
71+
const other_configs = remaining_configs
72+
73+
const map_config_to_item = (config: ToolConfig) => {
74+
const description_parts = [config.provider_name]
75+
if (config.reasoning_effort) {
76+
description_parts.push(`${config.reasoning_effort}`)
77+
}
78+
if (config.temperature != null) {
79+
description_parts.push(`${config.temperature}`)
80+
}
81+
82+
return {
83+
label: config.model,
84+
description: description_parts.join(' · '),
85+
config,
86+
id: get_tool_config_id(config)
87+
}
88+
}
89+
90+
const items: (vscode.QuickPickItem & {
91+
config?: ToolConfig
92+
id?: string
93+
})[] = []
94+
95+
if (recent_configs.length > 0) {
96+
items.push({
97+
label: 'recently used',
98+
kind: vscode.QuickPickItemKind.Separator
99+
})
100+
items.push(...recent_configs.map(map_config_to_item))
101+
}
102+
103+
if (other_configs.length > 0) {
104+
if (recent_configs.length > 0) {
105+
items.push({
106+
label: 'other configurations',
107+
kind: vscode.QuickPickItemKind.Separator
108+
})
109+
}
110+
items.push(...other_configs.map(map_config_to_item))
111+
}
112+
113+
return items
114+
}
115+
45116
const quick_pick = vscode.window.createQuickPick()
46117
const close_button = {
47118
iconPath: new vscode.ThemeIcon('close'),
48119
tooltip: 'Close'
49120
}
50121

51122
quick_pick.buttons = [close_button]
52-
quick_pick.items = configs.map((config, index) => {
53-
const description_parts = [config.provider_name]
54-
if (config.reasoning_effort) {
55-
description_parts.push(`${config.reasoning_effort}`)
56-
}
57-
if (config.temperature != null) {
58-
description_parts.push(`${config.temperature}`)
59-
}
60-
61-
return {
62-
label: config.model,
63-
description: description_parts.join(' · '),
64-
config,
65-
index,
66-
id: get_tool_config_id(config)
67-
}
68-
})
123+
quick_pick.items = create_items()
69124
quick_pick.title = 'Configurations'
70125
quick_pick.placeholder = 'Select configuration'
71126
quick_pick.matchOnDescription = true
72127

73-
const last_selected_id = context.workspaceState.get<string>(
74-
LAST_SELECTED_COMMIT_MESSAGES_CONFIG_ID_STATE_KEY
75-
)
76-
const last_selected_item = (
77-
quick_pick.items as (vscode.QuickPickItem & { id: string })[]
78-
).find((item) => item.id == last_selected_id)
79-
80-
if (last_selected_item) {
81-
quick_pick.activeItems = [last_selected_item]
82-
} else if (quick_pick.items.length > 0) {
83-
quick_pick.activeItems = [quick_pick.items[0]]
128+
const items = quick_pick.items as (vscode.QuickPickItem & {
129+
id: string
130+
})[]
131+
132+
if (items.length > 0) {
133+
const first_selectable = items.find(
134+
(i) => i.kind != vscode.QuickPickItemKind.Separator
135+
)
136+
if (first_selectable) {
137+
quick_pick.activeItems = [first_selectable]
138+
}
84139
}
85140

86141
commit_message_config = await new Promise<
@@ -97,11 +152,20 @@ export const get_commit_message_config = async (
97152
const selected = quick_pick.selectedItems[0] as any
98153
quick_pick.hide()
99154

100-
if (selected) {
155+
if (selected && selected.config) {
156+
let recents =
157+
context.workspaceState.get<string[]>(
158+
RECENTLY_USED_COMMIT_MESSAGES_CONFIG_IDS_STATE_KEY
159+
) || []
160+
recents = [
161+
selected.id,
162+
...recents.filter((id) => id != selected.id)
163+
]
101164
context.workspaceState.update(
102-
LAST_SELECTED_COMMIT_MESSAGES_CONFIG_ID_STATE_KEY,
103-
selected.id
165+
RECENTLY_USED_COMMIT_MESSAGES_CONFIG_IDS_STATE_KEY,
166+
recents
104167
)
168+
105169
resolve(selected.config)
106170
} else {
107171
resolve(undefined)

apps/editor/src/constants/state-keys.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,11 @@ export const LAST_APPLY_CONTEXT_OPTION_STATE_KEY = 'last-apply-context-option'
1212
export const CONTEXT_CHECKED_PATHS_STATE_KEY = 'context-checked-paths'
1313
export const CONTEXT_CHECKED_URLS_STATE_KEY = 'context-checked-urls'
1414
export const CONTEXT_CHECKED_TIMESTAMPS_STATE_KEY = 'context-checked-timestamps'
15-
export const LAST_SELECTED_CODE_AT_CURSOR_CONFIG_ID_STATE_KEY =
16-
'lastSelectedCodeAtCursorConfigId'
17-
export const LAST_SELECTED_PRUNE_CONTEXT_CONFIG_ID_STATE_KEY =
18-
'lastSelectedPruneContextConfigId'
19-
export const LAST_SELECTED_EDIT_CONTEXT_CONFIG_ID_STATE_KEY =
20-
'lastSelectedEditContextConfigId'
21-
export const LAST_SELECTED_COMMIT_MESSAGES_CONFIG_ID_STATE_KEY =
22-
'lastSelectedCommitMessagesConfigId'
23-
export const LAST_SELECTED_INTELLIGENT_UPDATE_CONFIG_ID_STATE_KEY =
24-
'lastSelectedIntelligentUpdateConfigId'
2515
export const LAST_CONTEXT_MERGE_REPLACE_OPTION_STATE_KEY =
2616
'last-context-merge-replace-option'
2717
export const LAST_REFACTOR_INSTRUCTION_SOURCE_STATE_KEY =
2818
'last-refactor-instruction-source'
2919
export const LAST_REFACTOR_INSTRUCTION_STATE_KEY = 'last-refactor-instruction'
30-
3120
export const LAST_SELECTED_SYMBOL_STATE_KEY = 'last-selected-symbol'
3221
export const LAST_SELECTED_CONTEXT_SOURCE_IN_SYMBOLS_QUICK_PICK_STATE_KEY =
3322
'last-selected-context-source-in-symbols-quick-pick'
@@ -70,6 +59,10 @@ export const RECENTLY_USED_PRUNE_CONTEXT_CONFIG_IDS_STATE_KEY =
7059
'recently-used-prune-context-config-ids'
7160
export const RECENTLY_USED_EDIT_CONTEXT_CONFIG_IDS_STATE_KEY =
7261
'recently-used-edit-context-config-ids'
62+
export const RECENTLY_USED_COMMIT_MESSAGES_CONFIG_IDS_STATE_KEY =
63+
'recently-used-commit-messages-config-ids'
64+
export const RECENTLY_USED_INTELLIGENT_UPDATE_CONFIG_IDS_STATE_KEY =
65+
'recently-used-intelligent-update-config-ids'
7366

7467
export const get_presets_collapsed_state_key = (web_prompt_type: string) =>
7568
`presets-collapsed-${web_prompt_type}`

0 commit comments

Comments
 (0)