Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T08:07:02.596Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

settings.rs

162 lines · 5.1 KB · rust
1use anyhow::Result;
2use serde_json::Value;
3
4use crate::migrations::migrate_settings;
5
6const AGENT_SERVERS_KEY: &str = "agent_servers";
7
8struct BuiltinMapping {
9    old_key: &'static str,
10    registry_key: &'static str,
11}
12
13const BUILTIN_MAPPINGS: &[BuiltinMapping] = &[
14    BuiltinMapping {
15        old_key: "gemini",
16        registry_key: "gemini",
17    },
18    BuiltinMapping {
19        old_key: "claude",
20        registry_key: "claude-acp",
21    },
22    BuiltinMapping {
23        old_key: "codex",
24        registry_key: "codex-acp",
25    },
26];
27
28const REGISTRY_COMPATIBLE_FIELDS: &[&str] = &[
29    "env",
30    "default_mode",
31    "default_model",
32    "favorite_models",
33    "default_config_options",
34    "favorite_config_option_values",
35];
36
37pub fn migrate_builtin_agent_servers_to_registry(value: &mut Value) -> Result<()> {
38    migrate_settings(value, &mut migrate_one)
39}
40
41fn migrate_one(obj: &mut serde_json::Map<String, Value>) -> Result<()> {
42    let Some(agent_servers) = obj.get_mut(AGENT_SERVERS_KEY) else {
43        return Ok(());
44    };
45    let Some(servers_map) = agent_servers.as_object_mut() else {
46        return Ok(());
47    };
48
49    for mapping in BUILTIN_MAPPINGS {
50        migrate_builtin_entry(servers_map, mapping);
51    }
52
53    Ok(())
54}
55
56fn migrate_builtin_entry(
57    servers_map: &mut serde_json::Map<String, Value>,
58    mapping: &BuiltinMapping,
59) {
60    // Check if the old key exists and needs migration before taking ownership.
61    let needs_migration = servers_map
62        .get(mapping.old_key)
63        .and_then(|v| v.as_object())
64        .is_some_and(|obj| !obj.contains_key("type"));
65
66    if !needs_migration {
67        return;
68    }
69
70    // When the registry key differs from the old key and the target already
71    // exists, just remove the stale old entry to avoid overwriting user data.
72    if mapping.old_key != mapping.registry_key && servers_map.contains_key(mapping.registry_key) {
73        servers_map.remove(mapping.old_key);
74        return;
75    }
76
77    let Some(old_entry) = servers_map.remove(mapping.old_key) else {
78        return;
79    };
80    let Some(old_obj) = old_entry.as_object() else {
81        return;
82    };
83
84    let has_command = old_obj.contains_key("command");
85    let ignore_system_version = old_obj
86        .get("ignore_system_version")
87        .and_then(|v| v.as_bool());
88
89    // A custom entry is needed when the user configured a custom binary
90    // or explicitly opted into using the system version via
91    // `ignore_system_version: false` (only meaningful for gemini).
92    let needs_custom = has_command
93        || (mapping.old_key == "gemini" && matches!(ignore_system_version, Some(false)));
94
95    if needs_custom {
96        let local_key = format!("{}-custom", mapping.registry_key);
97
98        // Don't overwrite an existing `-custom` entry.
99        if servers_map.contains_key(&local_key) {
100            return;
101        }
102
103        let mut custom_obj = serde_json::Map::new();
104        custom_obj.insert("type".to_string(), Value::String("custom".to_string()));
105
106        if has_command {
107            if let Some(command) = old_obj.get("command") {
108                custom_obj.insert("command".to_string(), command.clone());
109            }
110            if let Some(args) = old_obj.get("args") {
111                if !args.as_array().is_some_and(|a| a.is_empty()) {
112                    custom_obj.insert("args".to_string(), args.clone());
113                }
114            }
115        } else {
116            // ignore_system_version: false — the user wants the binary from $PATH
117            custom_obj.insert(
118                "command".to_string(),
119                Value::String(mapping.old_key.to_string()),
120            );
121        }
122
123        // Carry over all compatible fields to the custom entry.
124        for &field in REGISTRY_COMPATIBLE_FIELDS {
125            if let Some(value) = old_obj.get(field) {
126                match value {
127                    Value::Array(arr) if arr.is_empty() => continue,
128                    Value::Object(map) if map.is_empty() => continue,
129                    Value::Null => continue,
130                    _ => {
131                        custom_obj.insert(field.to_string(), value.clone());
132                    }
133                }
134            }
135        }
136
137        servers_map.insert(local_key, Value::Object(custom_obj));
138    } else {
139        // Build a registry entry with compatible fields only.
140        let mut registry_obj = serde_json::Map::new();
141        registry_obj.insert("type".to_string(), Value::String("registry".to_string()));
142
143        for &field in REGISTRY_COMPATIBLE_FIELDS {
144            if let Some(value) = old_obj.get(field) {
145                match value {
146                    Value::Array(arr) if arr.is_empty() => continue,
147                    Value::Object(map) if map.is_empty() => continue,
148                    Value::Null => continue,
149                    _ => {
150                        registry_obj.insert(field.to_string(), value.clone());
151                    }
152                }
153            }
154        }
155
156        servers_map.insert(
157            mapping.registry_key.to_string(),
158            Value::Object(registry_obj),
159        );
160    }
161}
162
Served at tenant.openagents/omega Member data and write actions are omitted.