fix(aionui-ai-agent): derive models from configOptions when models field is absent#401
Open
JerryLiu369 wants to merge 2 commits into
Open
fix(aionui-ai-agent): derive models from configOptions when models field is absent#401JerryLiu369 wants to merge 2 commits into
JerryLiu369 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a fallback path to derive advertised models from ACP configOptions (category "model") when the legacy models field is absent, so the frontend can still render a model selector (e.g. for agents like OpenCode).
Changes:
- Import ACP schema types needed to interpret
configOptionsmodel select entries. - Add
derive_models_from_config_optionsto convert a"model"select option intoSessionModelState. - Apply the derived models fallback in new-session, reconcile/new-session, and load-session flows.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+43
to
+68
| for opt in config_options { | ||
| if opt.category.as_ref() != Some(&SessionConfigOptionCategory::Model) { | ||
| continue; | ||
| } | ||
| if let SessionConfigKind::Select(ref select) = opt.kind { | ||
| let current_model_id = AcpModelId::new(select.current_value.0.as_ref()); | ||
| let available: Vec<ModelInfo> = match &select.options { | ||
| SessionConfigSelectOptions::Ungrouped(options) => options | ||
| .iter() | ||
| .map(|o| ModelInfo::new(AcpModelId::new(o.value.0.as_ref()), o.name.clone())) | ||
| .collect(), | ||
| SessionConfigSelectOptions::Grouped(groups) => groups | ||
| .iter() | ||
| .flat_map(|g: &SessionConfigSelectGroup| &g.options) | ||
| .map(|o| ModelInfo::new(AcpModelId::new(o.value.0.as_ref()), o.name.clone())) | ||
| .collect(), | ||
| // `SessionConfigSelectOptions` is non-exhaustive; future variants | ||
| // are treated as having no model entries. | ||
| _ => Vec::new(), | ||
| }; | ||
| if available.is_empty() { | ||
| return None; | ||
| } | ||
| return Some(SessionModelState::new(current_model_id, available)); | ||
| } | ||
| } |
Comment on lines
86
to
95
| if let Some(models) = session_response.models { | ||
| session.apply_advertised_models(models); | ||
| } else if let Some(ref config_options) = session_response.config_options { | ||
| // `configOptions` with category "model" is the ACP-recommended | ||
| // way to advertise models; fall back to it when `models` is | ||
| // absent (e.g. OpenCode). | ||
| if let Some(models) = derive_models_from_config_options(config_options) { | ||
| session.apply_advertised_models(models); | ||
| } | ||
| } |
…eld is absent Per the ACP spec, configOptions with category "model" is the stable, recommended way for agents to advertise available models. Some agents (e.g. OpenCode) use this exclusively and omit the legacy models field. When session/new or session/load responses lack the models field but contain a "model" configOption, derive a SessionModelState from it so the frontend model selector renders correctly. Handles Ungrouped, Grouped, and non-exhaustive option variants.
…x clippy - Extract shared model-application logic into apply_advertised_models() to eliminate duplication across three session flows (new, resume, load) and prevent future drift. - Collapse nested if-let into && let to satisfy clippy::collapsible_if. - Continue scanning config_options when a model category yields an empty list, rather than returning None prematurely.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When using OpenCode as an ACP agent, the model selector in the frontend shows "首次连接后将显示可用模型列表" and never loads the model list. Claude and Codex are not affected.
Root Cause
OpenCode advertises available models exclusively through
configOptions(withcategory: "model"), omitting the dedicatedmodelsfield insession/newandsession/loadresponses. AionCore only readssession_response.models, so the model info is alwaysNonefor OpenCode.Per the ACP spec,
configOptionsis the stable, recommended way for agents to advertise models. Themodelsfield is legacy.Fix
Add
derive_models_from_config_options()that extracts aSessionModelStatefrom a"model"category configOption when themodelsfield is absent. Applied as anelse iffallback in all three session creation/restoration paths:open_session_new()— new sessionsession/loadbranch — Codex/OpenCode session resumeHandles
Ungrouped,Grouped, and non-exhaustiveSessionConfigSelectOptionsvariants.Testing
Verified on Windows dev build: OpenCode model selector now populates correctly with all 58 models. Claude/Codex behavior unchanged.