Skip to content

fix(aionui-ai-agent): derive models from configOptions when models field is absent#401

Open
JerryLiu369 wants to merge 2 commits into
iOfficeAI:mainfrom
JerryLiu369:fix/derive-models-from-config-options
Open

fix(aionui-ai-agent): derive models from configOptions when models field is absent#401
JerryLiu369 wants to merge 2 commits into
iOfficeAI:mainfrom
JerryLiu369:fix/derive-models-from-config-options

Conversation

@JerryLiu369
Copy link
Copy Markdown

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 (with category: "model"), omitting the dedicated models field in session/new and session/load responses. AionCore only reads session_response.models, so the model info is always None for OpenCode.

Per the ACP spec, configOptions is the stable, recommended way for agents to advertise models. The models field is legacy.

Fix

Add derive_models_from_config_options() that extracts a SessionModelState from a "model" category configOption when the models field is absent. Applied as an else if fallback in all three session creation/restoration paths:

  • open_session_new() — new session
  • claude-meta-resume branch — Claude session/new on resume
  • session/load branch — Codex/OpenCode session resume

Handles Ungrouped, Grouped, and non-exhaustive SessionConfigSelectOptions variants.

Testing

Verified on Windows dev build: OpenCode model selector now populates correctly with all 58 models. Claude/Codex behavior unchanged.

Copilot AI review requested due to automatic review settings June 4, 2026 12:20
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 configOptions model select entries.
  • Add derive_models_from_config_options to convert a "model" select option into SessionModelState.
  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants