crates/migrator/src/migrations.rs π
@@ -63,3 +63,9 @@ pub(crate) mod m_2025_05_05 {
pub(crate) use settings::SETTINGS_PATTERNS;
}
+
+pub(crate) mod m_2025_05_08 {
+ mod settings;
+
+ pub(crate) use settings::SETTINGS_PATTERNS;
+}
Oleksiy Syvokon created
As a byproduct, this fixes bug where it's impossible to change Agent
profile
Closes #30000
Release Notes:
- N/A
crates/migrator/src/migrations.rs | 6 +
crates/migrator/src/migrations/m_2025_05_08/settings.rs | 26 ++++++
crates/migrator/src/migrator.rs | 42 +++++++++++
crates/migrator/src/patterns.rs | 4
crates/migrator/src/patterns/settings.rs | 15 +++
5 files changed, 91 insertions(+), 2 deletions(-)
@@ -63,3 +63,9 @@ pub(crate) mod m_2025_05_05 {
pub(crate) use settings::SETTINGS_PATTERNS;
}
+
+pub(crate) mod m_2025_05_08 {
+ mod settings;
+
+ pub(crate) use settings::SETTINGS_PATTERNS;
+}
@@ -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))
+}
@@ -140,6 +140,10 @@ pub fn migrate_settings(text: &str) -> Result<Option<String>> {
migrations::m_2025_05_05::SETTINGS_PATTERNS,
&SETTINGS_QUERY_2025_05_05,
),
+ (
+ migrations::m_2025_05_08::SETTINGS_PATTERNS,
+ &SETTINGS_QUERY_2025_05_08,
+ ),
];
run_migrations(text, migrations)
}
@@ -230,6 +234,10 @@ define_query!(
SETTINGS_QUERY_2025_05_05,
migrations::m_2025_05_05::SETTINGS_PATTERNS
);
+define_query!(
+ SETTINGS_QUERY_2025_05_08,
+ migrations::m_2025_05_08::SETTINGS_PATTERNS
+);
// custom query
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"
+ }
+ }
+ "#,
+ ),
+ );
+ }
}
@@ -8,6 +8,6 @@ pub(crate) use keymap::{
pub(crate) use settings::{
SETTINGS_ASSISTANT_PATTERN, SETTINGS_ASSISTANT_TOOLS_PATTERN,
- SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN, SETTINGS_LANGUAGES_PATTERN,
- SETTINGS_NESTED_KEY_VALUE_PATTERN, SETTINGS_ROOT_KEY_VALUE_PATTERN,
+ SETTINGS_DUPLICATED_AGENT_PATTERN, SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN,
+ SETTINGS_LANGUAGES_PATTERN, SETTINGS_NESTED_KEY_VALUE_PATTERN, SETTINGS_ROOT_KEY_VALUE_PATTERN,
};
@@ -93,3 +93,18 @@ pub const SETTINGS_EDIT_PREDICTIONS_ASSISTANT_PATTERN: &str = r#"(document
(#eq? @edit_predictions "edit_predictions")
(#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")
+)"#;