@@ -52,6 +52,7 @@ local uv = vim.uv
5252--- @field _on_session_update function | nil
5353--- @field _modes { currentModeId : string , availableModes : table[] }| nil
5454--- @field _models { currentModelId : string , availableModels : table[] }| nil
55+ --- @field _model_config_id string | nil The configOptions ID for the model selector
5556--- @field methods table
5657local Connection = {}
5758
@@ -367,9 +368,9 @@ function Connection:_establish_session()
367368 self ._modes = session_data .modes
368369 log :debug (" [acp::_establish_session] %s modes: %s" , source , session_data .modes )
369370 end
370- if session_data .models then
371- self . _models = session_data .models
372- log :debug (" [acp::_establish_session] %s models: %s " , source , session_data . models )
371+ if session_data .configOptions then
372+ self : _apply_config_options ( session_data .configOptions )
373+ log :debug (" [acp::_establish_session] %s config options applied " , source )
373374 end
374375 end
375376
@@ -700,6 +701,8 @@ local DISPATCH = {
700701 self :handle_available_commands_update (m .params .sessionId , m .params .update .availableCommands )
701702 elseif m .params .update and m .params .update .sessionUpdate == " current_mode_update" then
702703 self :handle_current_mode_update (m .params .sessionId , m .params .update .modeId )
704+ elseif m .params .update and m .params .update .sessionUpdate == " config_option_update" then
705+ self :handle_config_option_update (m .params .sessionId , m .params .update .configOptions )
703706 elseif m .params .update and m .params .update .sessionUpdate == " session_info_update" then
704707 self :handle_session_info_update (m .params .sessionId , m .params .update )
705708 elseif self ._loading_session and self ._on_session_update then
@@ -854,6 +857,47 @@ function Connection:handle_available_commands_update(session_id, commands)
854857 acp_commands .register_commands (session_id , commands )
855858end
856859
860+ --- Extract model information from ACP configOptions
861+ --- Ref: https://agentclientprotocol.com/protocol/schema#setsessionconfigoptionrequest
862+ --- @param config_options table[] Array of SessionConfigOption
863+ function Connection :_apply_config_options (config_options )
864+ for _ , opt in ipairs (config_options ) do
865+ if opt .category == " model" and opt .type == " select" then
866+ self ._model_config_id = opt .id
867+
868+ local available = {}
869+ for _ , item in ipairs (opt .options or {}) do
870+ if item .group then
871+ for _ , model in ipairs (item .options or {}) do
872+ table.insert (available , { modelId = model .value , name = model .name })
873+ end
874+ else
875+ table.insert (available , { modelId = item .value , name = item .name })
876+ end
877+ end
878+
879+ self ._models = {
880+ availableModels = available ,
881+ currentModelId = opt .currentValue ,
882+ }
883+ break
884+ end
885+ end
886+ end
887+
888+ --- Handle config_option_update notification
889+ --- @param session_id string
890+ --- @param config_options table[] | nil
891+ --- @return nil
892+ function Connection :handle_config_option_update (session_id , config_options )
893+ if not session_id or session_id ~= self .session_id then
894+ return
895+ end
896+ if type (config_options ) == " table" then
897+ self :_apply_config_options (config_options )
898+ end
899+ end
900+
857901--- Handle current_mode_update notification
858902--- @param session_id string
859903--- @param mode_id string
@@ -960,20 +1004,56 @@ function Connection:get_models()
9601004 return self ._models
9611005end
9621006
963- --- Set a model
1007+ --- Set a model via session/set_config_option
9641008--- @param model_id string The ID of the model to switch to
9651009--- @return boolean success
9661010function Connection :set_model (model_id )
967- return self :_set_session_property ({
1011+ if not self .session_id then
1012+ log :error (" [acp::set_model] Connection not established" )
1013+ return false
1014+ end
1015+
1016+ if not self ._models or not self ._model_config_id then
1017+ log :error (" [acp::set_model] Agent does not support changing models" )
1018+ return false
1019+ end
1020+
1021+ local valid = false
1022+ for _ , item in ipairs (self ._models .availableModels or {}) do
1023+ if item .modelId == model_id then
1024+ valid = true
1025+ break
1026+ end
1027+ end
1028+
1029+ if not valid then
1030+ log :error (" [acp::set_model] Invalid model ID: %s" , model_id )
1031+ return false
1032+ end
1033+
1034+ if model_id == self ._models .currentModelId then
1035+ return true
1036+ end
1037+
1038+ local result = self :send_rpc_request (METHODS .SESSION_SET_CONFIG_OPTION , {
1039+ sessionId = self .session_id ,
1040+ configId = self ._model_config_id ,
9681041 value = model_id ,
969- collection = self ._models ,
970- items_key = " availableModels" ,
971- current_key = " currentModelId" ,
972- id_key = " modelId" ,
973- rpc_method = METHODS .SESSION_SET_MODEL ,
974- rpc_param_key = " modelId" ,
975- label = " model" ,
9761042 })
1043+
1044+ if not result then
1045+ log :error (" [acp::set_model] Failed to set model to %s" , model_id )
1046+ return false
1047+ end
1048+
1049+ if result .configOptions then
1050+ self :_apply_config_options (result .configOptions )
1051+ else
1052+ self ._models .currentModelId = model_id
1053+ end
1054+
1055+ log :debug (" [acp::set_model] Changed model to %s" , model_id )
1056+ return true
9771057end
9781058
9791059--- Shared helper to validate and set a session property (mode or model)
0 commit comments