@@ -1090,17 +1090,41 @@ void AcpSessionView::onMetadataChanged()
10901090 if (!m_model) return ;
10911091 m_updatingSelectors = true ;
10921092
1093- // Models combo.
1093+ // Models combo. Prefer the top-level models catalog; if the agent
1094+ // doesn't surface one, fall back to a `model` config option (Claude Code
1095+ // exposes the picker only via configOptions, never the models array).
10941096 m_modelCombo->clear ();
1097+ m_modelConfigOptionId.clear ();
10951098 const auto &models = m_model->availableModels ();
1096- for (const auto &m : models) {
1097- m_modelCombo->addItem (m.name .isEmpty () ? m.id : m.name , m.id );
1098- }
1099- if (!m_model->currentModelId ().isEmpty ()) {
1100- const int idx = m_modelCombo->findData (m_model->currentModelId ());
1101- if (idx >= 0 ) m_modelCombo->setCurrentIndex (idx);
1099+ if (!models.isEmpty ()) {
1100+ for (const auto &m : models) {
1101+ m_modelCombo->addItem (m.name .isEmpty () ? m.id : m.name , m.id );
1102+ }
1103+ if (!m_model->currentModelId ().isEmpty ()) {
1104+ const int idx = m_modelCombo->findData (m_model->currentModelId ());
1105+ if (idx >= 0 ) m_modelCombo->setCurrentIndex (idx);
1106+ }
1107+ } else {
1108+ for (const auto &opt : m_model->configOptions ()) {
1109+ const QString idLower = opt.id .toLower ();
1110+ const QString catLower = opt.category .toLower ();
1111+ const bool matches = idLower == QLatin1String (" model" )
1112+ || catLower == QLatin1String (" model" );
1113+ if (!matches) continue ;
1114+ m_modelConfigOptionId = opt.id ;
1115+ for (const auto &ch : opt.options ) {
1116+ const QString label = ch.name .isEmpty () ? ch.value : ch.name ;
1117+ if (!label.isEmpty ()) m_modelCombo->addItem (label, ch.value );
1118+ }
1119+ const QString currentVal = opt.currentValue .toString ();
1120+ if (!currentVal.isEmpty ()) {
1121+ const int idx = m_modelCombo->findData (currentVal);
1122+ if (idx >= 0 ) m_modelCombo->setCurrentIndex (idx);
1123+ }
1124+ break ;
1125+ }
11021126 }
1103- m_modelCombo->setVisible (!models. isEmpty () );
1127+ m_modelCombo->setVisible (m_modelCombo-> count () > 0 );
11041128
11051129 // Modes combo.
11061130 m_modeCombo->clear ();
@@ -1160,8 +1184,11 @@ void AcpSessionView::onMetadataChanged()
11601184 const QString agentId = m_connection->definition ().id ;
11611185 if (!agentId.isEmpty ()) {
11621186 const QString curModel = m_model->currentModelId ();
1163- if (!curModel.isEmpty ())
1164- m_registry->setAgentPreference (agentId, QStringLiteral (" model" ), curModel);
1187+ if (!curModel.isEmpty ()) {
1188+ const QString modelKey = m_modelConfigOptionId.isEmpty ()
1189+ ? QStringLiteral (" model" ) : m_modelConfigOptionId;
1190+ m_registry->setAgentPreference (agentId, modelKey, curModel);
1191+ }
11651192
11661193 const QString curMode = m_model->currentModeId ();
11671194 if (!curMode.isEmpty ())
@@ -1471,10 +1498,17 @@ void AcpSessionView::onModelComboChanged(int index)
14711498 if (m_updatingSelectors || !m_connection || index < 0 ) return ;
14721499 const QString id = m_modelCombo->itemData (index).toString ();
14731500 if (id.isEmpty ()) return ;
1474- m_connection->setModel (id);
1501+ // Config-option-backed picker (Claude Code) → session/set_config; the
1502+ // dedicated session/set_model channel only applies to the models array.
1503+ const QString prefKey = m_modelConfigOptionId.isEmpty ()
1504+ ? QStringLiteral (" model" ) : m_modelConfigOptionId;
1505+ if (!m_modelConfigOptionId.isEmpty ()) {
1506+ m_connection->setConfigOption (m_modelConfigOptionId, id);
1507+ } else {
1508+ m_connection->setModel (id);
1509+ }
14751510 if (m_registry) {
1476- m_registry->setAgentPreference (m_connection->definition ().id ,
1477- QStringLiteral (" model" ), id);
1511+ m_registry->setAgentPreference (m_connection->definition ().id , prefKey, id);
14781512 }
14791513}
14801514
@@ -1518,13 +1552,29 @@ void AcpSessionView::applySavedPreferences()
15181552 if (agentId.isEmpty ()) return ;
15191553
15201554 // Model: send only if the saved id exists in the catalog and differs.
1521- const QString savedModel = m_registry->agentPreference (agentId, QStringLiteral (" model" ));
1555+ // Config-option-backed pickers (Claude Code) restore via session/set_config.
1556+ const QString modelPrefKey = m_modelConfigOptionId.isEmpty ()
1557+ ? QStringLiteral (" model" ) : m_modelConfigOptionId;
1558+ const QString savedModel = m_registry->agentPreference (agentId, modelPrefKey);
15221559 if (!savedModel.isEmpty () && savedModel != m_model->currentModelId ()) {
1523- for (const auto &m : m_model->availableModels ()) {
1524- if (m.id == savedModel) {
1525- m_connection->setModel (savedModel);
1560+ if (!m_modelConfigOptionId.isEmpty ()) {
1561+ for (const auto &opt : m_model->configOptions ()) {
1562+ if (opt.id != m_modelConfigOptionId) continue ;
1563+ for (const auto &ch : opt.options ) {
1564+ if (ch.value == savedModel) {
1565+ m_connection->setConfigOption (m_modelConfigOptionId, savedModel);
1566+ break ;
1567+ }
1568+ }
15261569 break ;
15271570 }
1571+ } else {
1572+ for (const auto &m : m_model->availableModels ()) {
1573+ if (m.id == savedModel) {
1574+ m_connection->setModel (savedModel);
1575+ break ;
1576+ }
1577+ }
15281578 }
15291579 }
15301580
0 commit comments