Skip to content

Commit be4a81e

Browse files
authored
fix(assistant): preserve builtin override selections (#535)
## Summary - Preserve user-selected built-in assistant `engine` overrides across bootstrap/restart. - Preserve user-edited built-in assistant model and permission defaults when built-in definitions are materialized. - Add a regression test for bootstrap preserving built-in assistant engine/default overrides. ## Test Plan - [x] cargo test -p aionui-assistant bootstrap_preserves_builtin_user_engine_and_defaults_overrides - [x] cargo test -p aionui-assistant builtin - [x] cargo test -p aionui-assistant - [x] cargo clippy -p aionui-assistant -- -D warnings - [x] cargo fmt --all -- --check - [x] git diff --check - [x] just push partial gate: migration immutability, cargo check, workspace clippy, cargo fmt completed - [ ] just push / cargo nextest run --workspace was intentionally stopped at user request; full checks to be run separately --------- Co-authored-by: kaizhou-lab <18323274+kaizhou-lab@users.noreply.github.com> Co-authored-by: zk <>
1 parent c5a7b50 commit be4a81e

1 file changed

Lines changed: 69 additions & 5 deletions

File tree

crates/aionui-assistant/src/service.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,30 @@ impl AssistantService {
136136
let (definition_id, assistant_id) = self
137137
.resolve_definition_identity("builtin", Some(&builtin.id), &builtin.id)
138138
.await?;
139+
let existing_definition = self
140+
.definition_repo
141+
.get_by_id(&definition_id)
142+
.await
143+
.map_err(|e| AssistantError::Internal(format!("get builtin definition: {e}")))?;
139144
let agent_id = self.resolve_agent_id_for_agent_ref(&builtin.agent_ref).await?;
145+
let default_model_mode = existing_definition
146+
.as_ref()
147+
.filter(|definition| definition.source == "builtin")
148+
.map(|definition| definition.default_model_mode.as_str())
149+
.unwrap_or("auto");
150+
let default_model_value = existing_definition
151+
.as_ref()
152+
.filter(|definition| definition.source == "builtin")
153+
.and_then(|definition| definition.default_model_value.as_deref());
154+
let default_permission_mode = existing_definition
155+
.as_ref()
156+
.filter(|definition| definition.source == "builtin")
157+
.map(|definition| definition.default_permission_mode.as_str())
158+
.unwrap_or("auto");
159+
let default_permission_value = existing_definition
160+
.as_ref()
161+
.filter(|definition| definition.source == "builtin")
162+
.and_then(|definition| definition.default_permission_value.as_deref());
140163

141164
self.definition_repo
142165
.upsert(&UpsertAssistantDefinitionParams {
@@ -163,10 +186,10 @@ impl AssistantService {
163186
rule_inline_content: None,
164187
recommended_prompts: &recommended_prompts,
165188
recommended_prompts_i18n: &recommended_prompts_i18n,
166-
default_model_mode: "auto",
167-
default_model_value: None,
168-
default_permission_mode: "auto",
169-
default_permission_value: None,
189+
default_model_mode,
190+
default_model_value,
191+
default_permission_mode,
192+
default_permission_value,
170193
default_skills_mode: "fixed",
171194
default_skill_ids: &default_skill_ids,
172195
custom_skill_names: &custom_skill_names,
@@ -239,12 +262,18 @@ impl AssistantService {
239262
continue;
240263
};
241264

265+
let existing_state = self
266+
.state_repo
267+
.get(&definition.id)
268+
.await
269+
.map_err(|e| AssistantError::Internal(format!("get assistant overlay: {e}")))?;
270+
242271
self.state_repo
243272
.upsert(&UpsertAssistantOverlayParams {
244273
assistant_definition_id: &definition.id,
245274
enabled: override_row.enabled,
246275
sort_order: override_row.sort_order,
247-
agent_id_override: None,
276+
agent_id_override: existing_state.as_ref().and_then(|row| row.agent_id_override.as_deref()),
248277
last_used_at: override_row.last_used_at,
249278
})
250279
.await
@@ -3255,6 +3284,41 @@ mod tests {
32553284
assert_eq!(detail.defaults.permission.value.as_deref(), Some("default"));
32563285
}
32573286

3287+
#[tokio::test]
3288+
async fn bootstrap_preserves_builtin_user_engine_and_defaults_overrides() {
3289+
let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await;
3290+
fx.service
3291+
.update(
3292+
"builtin-office",
3293+
UpdateAssistantRequest {
3294+
agent_id: Some("2d23ff1c".into()),
3295+
defaults: Some(AssistantDefaultsRequest {
3296+
model: Some(AssistantDefaultScalarRequest {
3297+
mode: "fixed".into(),
3298+
value: Some("gemini-2.5-pro".into()),
3299+
}),
3300+
permission: Some(AssistantDefaultScalarRequest {
3301+
mode: "fixed".into(),
3302+
value: Some("default".into()),
3303+
}),
3304+
..Default::default()
3305+
}),
3306+
..Default::default()
3307+
},
3308+
)
3309+
.await
3310+
.unwrap();
3311+
3312+
fx.service.bootstrap_assistant_storage().await.unwrap();
3313+
3314+
let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap();
3315+
assert_eq!(detail.engine.agent_id, "2d23ff1c");
3316+
assert_eq!(detail.defaults.model.mode, "fixed");
3317+
assert_eq!(detail.defaults.model.value.as_deref(), Some("gemini-2.5-pro"));
3318+
assert_eq!(detail.defaults.permission.mode, "fixed");
3319+
assert_eq!(detail.defaults.permission.value.as_deref(), Some("default"));
3320+
}
3321+
32583322
#[tokio::test]
32593323
async fn update_generated_rejects() {
32603324
let fx = fixture_with_options(FixtureOpts {

0 commit comments

Comments
 (0)