settings: Migration for fixing duplicated agent keys (#30237)

As a byproduct, this fixes bug where it's impossible to change Agent
profile

Closes #30000 

Release Notes:

- N/A
This commit is contained in:
Oleksiy Syvokon 2025-05-08 15:38:19 +03:00 committed by GitHub
parent 9f6809a28d
commit 3cc8850a58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 91 additions and 2 deletions

View file

@ -63,3 +63,9 @@ pub(crate) mod m_2025_05_05 {
pub(crate) use settings::SETTINGS_PATTERNS; pub(crate) use settings::SETTINGS_PATTERNS;
} }
pub(crate) mod m_2025_05_08 {
mod settings;
pub(crate) use settings::SETTINGS_PATTERNS;
}

View file

@ -0,0 +1,26 @@
use std::ops::Range;
use tree_sitter::{Query, QueryMatch};
use crate::{MigrationPatterns, patterns::SETTINGS_DUPLICATED_AGENT_PATTERN};
pub const SETTINGS_PATTERNS: MigrationPatterns =
&[(SETTINGS_DUPLICATED_AGENT_PATTERN, comment_duplicated_agent)];
fn comment_duplicated_agent(
contents: &str,
mat: &QueryMatch,
query: &Query,
) -> Option<(Range<usize>, String)> {
let pair_ix = query.capture_index_for_name("pair1")?;
let mut range = mat.nodes_for_capture_index(pair_ix).next()?.byte_range();
// Include the comma into the commented region
let rtext = &contents[range.end..];
if let Some(comma_index) = rtext.find(',') {
range.end += comma_index + 1;
}
let value = contents[range.clone()].to_string();
let commented_value = format!("/* Duplicated key auto-commented: {value} */");
Some((range, commented_value))
}

View file

@ -140,6 +140,10 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
migrations::m_2025_05_05::SETTINGS_PATTERNS, migrations::m_2025_05_05::SETTINGS_PATTERNS,
&SETTINGS_QUERY_2025_05_05, &SETTINGS_QUERY_2025_05_05,
), ),
(
migrations::m_2025_05_08::SETTINGS_PATTERNS,
&SETTINGS_QUERY_2025_05_08,
),
]; ];
run_migrations(text, migrations) run_migrations(text, migrations)
} }
@ -230,6 +234,10 @@ define_query!(
SETTINGS_QUERY_2025_05_05, SETTINGS_QUERY_2025_05_05,
migrations::m_2025_05_05::SETTINGS_PATTERNS migrations::m_2025_05_05::SETTINGS_PATTERNS
); );
define_query!(
SETTINGS_QUERY_2025_05_08,
migrations::m_2025_05_08::SETTINGS_PATTERNS
);
// custom query // custom query
static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock<Query> = LazyLock::new(|| { static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock<Query> = LazyLock::new(|| {
@ -743,4 +751,38 @@ mod tests {
), ),
); );
} }
#[test]
fn test_comment_duplicated_agent() {
assert_migrate_settings(
r#"{
"agent": {
"name": "assistant-1",
"model": "gpt-4", // weird formatting
"utf8": "привіт"
},
"something": "else",
"agent": {
"name": "assistant-2",
"model": "gemini-pro"
}
}
"#,
Some(
r#"{
/* Duplicated key auto-commented: "agent": {
"name": "assistant-1",
"model": "gpt-4", // weird formatting
"utf8": "привіт"
}, */
"something": "else",
"agent": {
"name": "assistant-2",
"model": "gemini-pro"
}
}
"#,
),
);
}
} }

View file

@ -8,6 +8,6 @@ pub(crate) use keymap::{
pub(crate) use settings::{ pub(crate) use settings::{
SETTINGS_ASSISTANT_PATTERN, SETTINGS_ASSISTANT_TOOLS_PATTERN, SETTINGS_ASSISTANT_PATTERN, SETTINGS_ASSISTANT_TOOLS_PATTERN,
SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN, SETTINGS_LANGUAGES_PATTERN, SETTINGS_DUPLICATED_AGENT_PATTERN, SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN,
SETTINGS_NESTED_KEY_VALUE_PATTERN, SETTINGS_ROOT_KEY_VALUE_PATTERN, SETTINGS_LANGUAGES_PATTERN, SETTINGS_NESTED_KEY_VALUE_PATTERN, SETTINGS_ROOT_KEY_VALUE_PATTERN,
}; };

View file

@ -93,3 +93,18 @@ pub const SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN: &str = r#"(document
(#eq? @edit_predictions "edit_predictions") (#eq? @edit_predictions "edit_predictions")
(#eq? @enabled_in_assistant "enabled_in_assistant") (#eq? @enabled_in_assistant "enabled_in_assistant")
)"#; )"#;
pub const SETTINGS_DUPLICATED_AGENT_PATTERN: &str = r#"(document
(object
(pair
key: (string (string_content) @agent1)
value: (_)
) @pair1
(pair
key: (string (string_content) @agent2)
value: (_)
)
)
(#eq? @agent1 "agent")
(#eq? @agent2 "agent")
)"#;