@@ -2,12 +2,13 @@ import * as vscode from 'vscode'
22import {
33 ModelProvidersManager ,
44 ReasoningEffort ,
5- get_tool_config_id
5+ get_tool_config_id ,
6+ ToolConfig
67} from '@/services/model-providers-manager'
78import { dictionary } from '@shared/constants/dictionary'
89import { Logger } from '@shared/utils/logger'
910import { 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
1213export 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 )
0 commit comments