keep the order of keys in config.yaml (#5468)

This commit is contained in:
Jack Amadeo
2025-10-30 17:58:44 -04:00
committed by GitHub
parent e586e13d9d
commit 65644ed81f
9 changed files with 141 additions and 166 deletions
Generated
+23 -15
View File
@@ -2633,6 +2633,7 @@ dependencies = [
"fs2",
"futures",
"include_dir",
"indexmap 2.12.0",
"indoc",
"insta",
"jsonschema",
@@ -2900,7 +2901,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap 2.7.1",
"indexmap 2.12.0",
"slab",
"tokio",
"tokio-util",
@@ -2919,7 +2920,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.2.0",
"indexmap 2.7.1",
"indexmap 2.12.0",
"slab",
"tokio",
"tokio-util",
@@ -2963,6 +2964,12 @@ dependencies = [
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
[[package]]
name = "hashlink"
version = "0.8.4"
@@ -3511,13 +3518,14 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.7.1"
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
"hashbrown 0.16.0",
"serde",
"serde_core",
]
[[package]]
@@ -3969,7 +3977,7 @@ dependencies = [
"chrono",
"encoding_rs",
"flate2",
"indexmap 2.7.1",
"indexmap 2.12.0",
"itoa",
"log",
"md-5",
@@ -4872,7 +4880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64 0.22.1",
"indexmap 2.7.1",
"indexmap 2.12.0",
"quick-xml 0.32.0",
"serde",
"time",
@@ -5025,7 +5033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d35f4dc9988d1326b065b4def5e950c3ed727aa03e3151b86cc9e2aec6b03f54"
dependencies = [
"futures",
"indexmap 2.7.1",
"indexmap 2.12.0",
"nix 0.29.0",
"tokio",
"tracing",
@@ -5992,7 +6000,7 @@ version = "1.0.142"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
dependencies = [
"indexmap 2.7.1",
"indexmap 2.12.0",
"itoa",
"memchr",
"ryu",
@@ -6041,7 +6049,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.7.1",
"indexmap 2.12.0",
"serde",
"serde_derive",
"serde_json",
@@ -6067,7 +6075,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.7.1",
"indexmap 2.12.0",
"itoa",
"ryu",
"serde",
@@ -6314,7 +6322,7 @@ dependencies = [
"futures-util",
"hashlink",
"hex",
"indexmap 2.7.1",
"indexmap 2.12.0",
"log",
"memchr",
"once_cell",
@@ -7078,7 +7086,7 @@ version = "0.22.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
dependencies = [
"indexmap 2.7.1",
"indexmap 2.12.0",
"serde",
"serde_spanned",
"toml_datetime",
@@ -7562,7 +7570,7 @@ version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23"
dependencies = [
"indexmap 2.7.1",
"indexmap 2.12.0",
"serde",
"serde_json",
"utoipa-gen",
@@ -8679,7 +8687,7 @@ dependencies = [
"crc32fast",
"crossbeam-utils",
"flate2",
"indexmap 2.7.1",
"indexmap 2.12.0",
"memchr",
"zopfli",
]
+13 -17
View File
@@ -40,26 +40,22 @@ pub fn handle_info(verbose: bool) -> Result<()> {
// Print verbose info if requested
if verbose {
println!("\n{}", style("goose Configuration:").cyan().bold());
match config.load_values() {
Ok(values) => {
if values.is_empty() {
println!(" No configuration values set");
println!(
" Run '{}' to configure goose",
style("goose configure").cyan()
);
} else {
let sorted_values: std::collections::BTreeMap<_, _> =
values.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
let values = config.all_values()?;
if values.is_empty() {
println!(" No configuration values set");
println!(
" Run '{}' to configure goose",
style("goose configure").cyan()
);
} else {
let sorted_values: std::collections::BTreeMap<_, _> =
values.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
if let Ok(yaml) = serde_yaml::to_string(&sorted_values) {
for line in yaml.lines() {
println!(" {}", line);
}
}
if let Ok(yaml) = serde_yaml::to_string(&sorted_values) {
for line in yaml.lines() {
println!(" {}", line);
}
}
Err(e) => println!(" Error loading configuration: {}", e),
}
}
@@ -272,7 +272,7 @@ pub async fn read_all_config() -> Result<Json<ConfigResponse>, StatusCode> {
let config = Config::global();
let values = config
.load_values()
.all_values()
.map_err(|_| StatusCode::UNPROCESSABLE_ENTITY)?;
Ok(Json(ConfigResponse { config: values }))
@@ -509,7 +509,7 @@ pub async fn init_config() -> Result<Json<String>, StatusCode> {
// Use the shared function to load init-config.yaml
match goose::config::base::load_init_config_from_workspace() {
Ok(init_values) => match config.save_values(init_values) {
Ok(init_values) => match config.initialize_if_empty(init_values) {
Ok(_) => Ok(Json("Config initialized successfully".to_string())),
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
},
@@ -584,7 +584,7 @@ pub async fn recover_config() -> Result<Json<String>, StatusCode> {
let config = Config::global();
// Force a reload which will trigger recovery if needed
match config.load_values() {
match config.all_values() {
Ok(values) => {
let recovered_keys: Vec<String> = values.keys().cloned().collect();
if recovered_keys.is_empty() {
+1
View File
@@ -108,6 +108,7 @@ schemars = { version = "1.0.4", default-features = false, features = ["derive"]
insta = "1.43.2"
paste = "1.0.0"
shellexpand = "3.1.1"
indexmap = "2.12.0"
[target.'cfg(target_os = "windows")'.dependencies]
+14
View File
@@ -215,6 +215,8 @@ pub enum ExtensionConfig {
Sse {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
uri: String,
#[serde(default)]
@@ -234,6 +236,8 @@ pub enum ExtensionConfig {
Stdio {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
cmd: String,
args: Vec<String>,
@@ -252,6 +256,8 @@ pub enum ExtensionConfig {
Builtin {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
display_name: Option<String>, // needed for the UI
timeout: Option<u64>,
@@ -265,6 +271,8 @@ pub enum ExtensionConfig {
Platform {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
#[serde(default)]
bundled: Option<bool>,
@@ -276,6 +284,8 @@ pub enum ExtensionConfig {
StreamableHttp {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
uri: String,
#[serde(default)]
@@ -297,6 +307,8 @@ pub enum ExtensionConfig {
Frontend {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
/// The tools provided by the frontend
tools: Vec<Tool>,
@@ -312,6 +324,8 @@ pub enum ExtensionConfig {
InlinePython {
/// The name used to identify this extension
name: String,
#[serde(default)]
#[schema(required)]
description: String,
/// The Python code to execute
code: String,
+62 -82
View File
@@ -5,6 +5,7 @@ use keyring::Entry;
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_yaml::Mapping;
use std::collections::HashMap;
use std::env;
use std::fs::OpenOptions;
@@ -152,6 +153,10 @@ macro_rules! declare_param {
};
}
fn parse_yaml_content(content: &str) -> Result<Mapping, ConfigError> {
serde_yaml::from_str(content).map_err(|e| e.into())
}
impl Config {
/// Get the global configuration instance.
///
@@ -204,8 +209,7 @@ impl Config {
self.config_path.to_string_lossy().to_string()
}
// Load current values from the config file
pub fn load_values(&self) -> Result<HashMap<String, Value>, ConfigError> {
fn load(&self) -> Result<Mapping, ConfigError> {
if self.config_path.exists() {
self.load_values_with_recovery()
} else {
@@ -221,19 +225,27 @@ impl Config {
tracing::info!("No backup found, creating default configuration");
// Try to load from init-config.yaml if it exists, otherwise use empty config
let default_config = self
.load_init_config_if_exists()
.unwrap_or_else(|_| HashMap::new());
let default_config = self.load_init_config_if_exists().unwrap_or_default();
self.create_and_save_default_config(default_config)
}
}
pub fn all_values(&self) -> Result<HashMap<String, Value>, ConfigError> {
self.load().map(|m| {
HashMap::from_iter(m.into_iter().filter_map(|(k, v)| {
k.as_str()
.map(|k| k.to_string())
.zip(serde_json::to_value(v).ok())
}))
})
}
// Helper method to create and save default config with consistent logging
fn create_and_save_default_config(
&self,
default_config: HashMap<String, Value>,
) -> Result<HashMap<String, Value>, ConfigError> {
default_config: Mapping,
) -> Result<Mapping, ConfigError> {
// Try to write the default config to disk
match self.save_values(default_config.clone()) {
Ok(_) => {
@@ -255,12 +267,10 @@ impl Config {
}
}
// Load values with automatic recovery from corruption
fn load_values_with_recovery(&self) -> Result<HashMap<String, Value>, ConfigError> {
fn load_values_with_recovery(&self) -> Result<Mapping, ConfigError> {
let file_content = std::fs::read_to_string(&self.config_path)?;
// First attempt: try to parse the current config
match self.parse_yaml_content(&file_content) {
match parse_yaml_content(&file_content) {
Ok(values) => Ok(values),
Err(parse_error) => {
tracing::warn!(
@@ -277,40 +287,21 @@ impl Config {
// Last resort: create a fresh default config file
tracing::error!("Could not recover config file, creating fresh default configuration. Original error: {}", parse_error);
// Try to load from init-config.yaml if it exists, otherwise use empty config
let default_config = self
.load_init_config_if_exists()
.unwrap_or_else(|_| HashMap::new());
let default_config = self.load_init_config_if_exists().unwrap_or_default();
self.create_and_save_default_config(default_config)
}
}
}
// Parse YAML content into HashMap
fn parse_yaml_content(&self, content: &str) -> Result<HashMap<String, Value>, ConfigError> {
if content.trim().is_empty() {
return Ok(HashMap::new());
}
let yaml_value: serde_yaml::Value = serde_yaml::from_str(content)?;
let json_value: Value = serde_json::to_value(yaml_value)?;
match json_value {
Value::Object(map) => Ok(map.into_iter().collect()),
_ => Ok(HashMap::new()),
}
}
// Try to restore from backup file
fn try_restore_from_backup(&self) -> Result<HashMap<String, Value>, ConfigError> {
fn try_restore_from_backup(&self) -> Result<Mapping, ConfigError> {
let backup_paths = self.get_backup_paths();
for backup_path in backup_paths {
if backup_path.exists() {
match std::fs::read_to_string(&backup_path) {
Ok(backup_content) => {
match self.parse_yaml_content(&backup_content) {
match parse_yaml_content(&backup_content) {
Ok(values) => {
// Successfully parsed backup, restore it as the main config
if let Err(e) = self.save_values(values.clone()) {
@@ -370,13 +361,11 @@ impl Config {
paths
}
// Try to load init-config.yaml from workspace root if it exists
fn load_init_config_if_exists(&self) -> Result<HashMap<String, Value>, ConfigError> {
fn load_init_config_if_exists(&self) -> Result<Mapping, ConfigError> {
load_init_config_from_workspace()
}
// Save current values to the config file
pub fn save_values(&self, values: HashMap<String, Value>) -> Result<(), ConfigError> {
fn save_values(&self, values: Mapping) -> Result<(), ConfigError> {
// Create backup before writing new config
self.create_backup_if_needed()?;
@@ -416,6 +405,15 @@ impl Config {
Ok(())
}
pub fn initialize_if_empty(&self, values: Mapping) -> Result<(), ConfigError> {
let _guard = self.guard.lock().unwrap();
if !self.exists() {
self.save_values(values)
} else {
Ok(())
}
}
// Create backup of current config file if it exists and is valid
fn create_backup_if_needed(&self) -> Result<(), ConfigError> {
if !self.config_path.exists() {
@@ -424,7 +422,7 @@ impl Config {
// Check if current config is valid before backing it up
let current_content = std::fs::read_to_string(&self.config_path)?;
if self.parse_yaml_content(&current_content).is_err() {
if parse_yaml_content(&current_content).is_err() {
// Don't back up corrupted files
return Ok(());
}
@@ -483,8 +481,7 @@ impl Config {
Ok(())
}
// Load current secrets from the keyring
pub fn load_secrets(&self) -> Result<HashMap<String, Value>, ConfigError> {
pub fn all_secrets(&self) -> Result<HashMap<String, Value>, ConfigError> {
match &self.secrets {
SecretStorage::Keyring { service } => {
let entry = Entry::new(service, KEYRING_USERNAME)?;
@@ -585,21 +582,17 @@ impl Config {
/// - The value cannot be deserialized into the requested type
/// - There is an error reading the config file
pub fn get_param<T: for<'de> Deserialize<'de>>(&self, key: &str) -> Result<T, ConfigError> {
// First check environment variables (convert to uppercase)
let env_key = key.to_uppercase();
if let Ok(val) = env::var(&env_key) {
let value = Self::parse_env_value(&val)?;
return Ok(serde_json::from_value(value)?);
}
// Load current values from file
let values = self.load_values()?;
// Then check our stored values
let values = self.load()?;
values
.get(key)
.ok_or_else(|| ConfigError::NotFound(key.to_string()))
.and_then(|v| Ok(serde_json::from_value(v.clone())?))
.and_then(|v| Ok(serde_yaml::from_value(v.clone())?))
}
/// Set a configuration value in the config file (non-secret).
@@ -617,8 +610,8 @@ impl Config {
/// - There is an error serializing the value
pub fn set_param<V: Serialize>(&self, key: &str, value: V) -> Result<(), ConfigError> {
let _guard = self.guard.lock().unwrap();
let mut values = self.load_values()?;
values.insert(key.to_string(), serde_json::to_value(&value)?);
let mut values = self.load()?;
values.insert(serde_yaml::to_value(key)?, serde_yaml::to_value(value)?);
self.save_values(values)
}
@@ -639,8 +632,8 @@ impl Config {
// Lock before reading to prevent race condition.
let _guard = self.guard.lock().unwrap();
let mut values = self.load_values()?;
values.remove(key);
let mut values = self.load()?;
values.shift_remove(key);
self.save_values(values)
}
@@ -670,7 +663,7 @@ impl Config {
}
// Then check keyring
let values = self.load_secrets()?;
let values = self.all_secrets()?;
values
.get(key)
.ok_or_else(|| ConfigError::NotFound(key.to_string()))
@@ -698,7 +691,7 @@ impl Config {
// Lock before reading to prevent race condition.
let _guard = self.guard.lock().unwrap();
let mut values = self.load_secrets()?;
let mut values = self.all_secrets()?;
values.insert(key.to_string(), serde_json::to_value(value)?);
match &self.secrets {
@@ -729,7 +722,7 @@ impl Config {
// Lock before reading to prevent race condition.
let _guard = self.guard.lock().unwrap();
let mut values = self.load_secrets()?;
let mut values = self.all_secrets()?;
values.remove(key);
match &self.secrets {
@@ -754,7 +747,7 @@ impl Config {
/// Load init-config.yaml from workspace root if it exists.
/// This function is shared between the config recovery and the init_config endpoint.
pub fn load_init_config_from_workspace() -> Result<HashMap<String, Value>, ConfigError> {
pub fn load_init_config_from_workspace() -> Result<Mapping, ConfigError> {
let workspace_root = match std::env::current_exe() {
Ok(mut exe_path) => {
while let Some(parent) = exe_path.parent() {
@@ -787,23 +780,7 @@ pub fn load_init_config_from_workspace() -> Result<HashMap<String, Value>, Confi
}
let init_content = std::fs::read_to_string(&init_config_path)?;
let init_values: HashMap<String, Value> =
match serde_yaml::from_str::<serde_yaml::Value>(&init_content) {
Ok(yaml_value) => {
let json_value: Value = serde_json::to_value(yaml_value)?;
match json_value {
Value::Object(map) => map.into_iter().collect(),
_ => HashMap::new(),
}
}
Err(e) => {
tracing::warn!("Failed to parse init-config.yaml: {}", e);
return Err(ConfigError::DeserializeError(e.to_string()));
}
};
tracing::info!("Loaded init-config.yaml with {} keys", init_values.len());
Ok(init_values)
parse_yaml_content(&init_content)
}
#[cfg(test)]
@@ -902,7 +879,7 @@ mod tests {
config.set_param("another_key", 42)?;
config.set_param("third_key", true)?;
let _values = config.load_values()?;
let _values = config.load()?;
let result: Result<String, ConfigError> = config.get_param("key");
assert!(matches!(result, Err(ConfigError::NotFound(_))));
@@ -994,11 +971,11 @@ mod tests {
let temp_file = NamedTempFile::new().unwrap();
let config = Arc::new(Config::new(temp_file.path(), TEST_KEYRING_SERVICE)?);
let barrier = Arc::new(Barrier::new(3)); // For 3 concurrent threads
let values = Arc::new(Mutex::new(HashMap::new()));
let values = Arc::new(Mutex::new(Mapping::new()));
let mut handles = vec![];
// Initialize with empty values
config.save_values(HashMap::new())?;
config.save_values(Default::default())?;
// Spawn 3 threads that will try to write simultaneously
for i in 0..3 {
@@ -1011,7 +988,10 @@ mod tests {
// Get the lock and update values
let mut values = values.lock().unwrap();
values.insert(format!("key{}", i), Value::String(format!("value{}", i)));
values.insert(
serde_yaml::to_value(format!("key{}", i)).unwrap(),
serde_yaml::to_value(format!("value{}", i)).unwrap(),
);
// Write all values
config.save_values(values.clone())?;
@@ -1026,7 +1006,7 @@ mod tests {
}
// Verify all values were written correctly
let final_values = config.load_values()?;
let final_values = config.all_values()?;
// Print the final values for debugging
println!("Final values: {:?}", final_values);
@@ -1088,7 +1068,7 @@ mod tests {
std::fs::write(temp_file.path(), "invalid: yaml: content: [unclosed")?;
// Try to load values - should recover from backup
let recovered_values = config.load_values()?;
let recovered_values = config.all_values()?;
println!("Recovered values: {:?}", recovered_values);
// Should have recovered the data
@@ -1109,7 +1089,7 @@ mod tests {
std::fs::write(temp_file.path(), "invalid: yaml: content: [unclosed")?;
// Try to load values - should create a fresh default config
let recovered_values = config.load_values()?;
let recovered_values = config.all_values()?;
// Should return empty config
assert_eq!(recovered_values.len(), 0);
@@ -1122,7 +1102,7 @@ mod tests {
assert!(parsed.is_mapping());
// Should be able to load it again without issues
let reloaded_values = config.load_values()?;
let reloaded_values = config.all_values()?;
assert_eq!(reloaded_values.len(), 0);
Ok(())
@@ -1140,7 +1120,7 @@ mod tests {
let config = Config::new(config_path, TEST_KEYRING_SERVICE)?;
// Try to load values - should create a fresh default config file
let values = config.load_values()?;
let values = config.all_values()?;
// Should return empty config
assert_eq!(values.len(), 0);
@@ -1154,7 +1134,7 @@ mod tests {
assert!(parsed.is_mapping());
// Should be able to load it again without issues
let reloaded_values = config.load_values()?;
let reloaded_values = config.all_values()?;
assert_eq!(reloaded_values.len(), 0);
Ok(())
@@ -1183,7 +1163,7 @@ mod tests {
assert!(!config_path.exists());
// Try to load values - should recover from backup
let recovered_values = config.load_values()?;
let recovered_values = config.all_values()?;
// Should have recovered the data from backup
assert!(
+21 -45
View File
@@ -1,9 +1,9 @@
use super::base::Config;
use crate::agents::extension::PLATFORM_EXTENSIONS;
use crate::agents::ExtensionConfig;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use serde_yaml::Mapping;
use tracing::warn;
use utoipa::ToSchema;
@@ -27,56 +27,32 @@ pub fn name_to_key(name: &str) -> String {
.to_lowercase()
}
fn get_extensions_map() -> HashMap<String, ExtensionEntry> {
let raw: Value = Config::global()
.get_param::<Value>(EXTENSIONS_CONFIG_KEY)
fn get_extensions_map() -> IndexMap<String, ExtensionEntry> {
let raw: Mapping = Config::global()
.get_param(EXTENSIONS_CONFIG_KEY)
.unwrap_or_else(|err| {
warn!(
"Failed to load {}: {err}. Falling back to empty object.",
EXTENSIONS_CONFIG_KEY
);
Value::Object(serde_json::Map::new())
Default::default()
});
let mut extensions_map: HashMap<String, ExtensionEntry> = match raw {
Value::Object(obj) => {
let mut m = HashMap::with_capacity(obj.len());
for (k, mut v) in obj {
if let Value::Object(ref mut inner) = v {
match inner.get("description") {
Some(Value::Null) | None => {
inner.insert("description".to_string(), Value::String(String::new()));
}
_ => {}
}
}
match serde_json::from_value::<ExtensionEntry>(v.clone()) {
Ok(entry) => {
m.insert(k, entry);
}
Err(err) => {
let bad_json = serde_json::to_string(&v).unwrap_or_else(|e| {
format!("<failed to serialize malformed value: {e}>")
});
warn!(
extension = %k,
error = %err,
bad_json = %bad_json,
"Skipping malformed extension"
);
}
}
let mut extensions_map = IndexMap::with_capacity(raw.len());
for (k, v) in raw {
match (k, serde_yaml::from_value::<ExtensionEntry>(v)) {
(serde_yaml::Value::String(s), Ok(entry)) => {
extensions_map.insert(s, entry);
}
(k, v) => {
warn!(
key = ?k,
value = ?v,
"Skipping malformed extension config entry"
);
}
m
}
other => {
warn!(
"Expected object for {}, got {}. Using empty map.",
EXTENSIONS_CONFIG_KEY, other
);
HashMap::new()
}
};
}
if !extensions_map.is_empty() {
for (name, def) in PLATFORM_EXTENSIONS.iter() {
@@ -99,7 +75,7 @@ fn get_extensions_map() -> HashMap<String, ExtensionEntry> {
extensions_map
}
fn save_extensions_map(extensions: HashMap<String, ExtensionEntry>) {
fn save_extensions_map(extensions: IndexMap<String, ExtensionEntry>) {
let config = Config::global();
if let Err(e) = config.set_param(EXTENSIONS_CONFIG_KEY, &extensions) {
// TODO(jack) why is this just a debug statement?
@@ -124,7 +100,7 @@ pub fn set_extension(entry: ExtensionEntry) {
pub fn remove_extension(key: &str) {
let mut extensions = get_extensions_map();
extensions.remove(key);
extensions.shift_remove(key);
save_extensions_map(extensions);
}
+2 -2
View File
@@ -61,8 +61,8 @@ impl BedrockProvider {
}
};
set_aws_env_vars(config.load_values());
set_aws_env_vars(config.load_secrets());
set_aws_env_vars(config.all_values());
set_aws_env_vars(config.all_secrets());
let sdk_config = aws_config::load_from_env().await;
+2 -2
View File
@@ -53,8 +53,8 @@ impl SageMakerTgiProvider {
}
};
set_aws_env_vars(config.load_values());
set_aws_env_vars(config.load_secrets());
set_aws_env_vars(config.all_values());
set_aws_env_vars(config.all_secrets());
let aws_config = aws_config::load_from_env().await;