fix: --generate-models parsed before vault initialization
This commit is contained in:
5 files changed
+37
-23
No files matched your search
@@ -46,9 +46,6 @@ jobs:
|
|||||||
if: steps.duckdb-extensions.outputs.cache-hit != 'true'
|
if: steps.duckdb-extensions.outputs.cache-hit != 'true'
|
||||||
run: cargo test --all duckdb
|
run: cargo test --all duckdb
|
||||||
|
|
||||||
# Coyote loads its config before handling --generate-models/--list-models, and a
|
|
||||||
# bare non-TTY runner has no config file (and no way to answer the first-run
|
|
||||||
# prompt), so point COYOTE_CONFIG_DIR at a throwaway dir with a minimal stub.
|
|
||||||
- name: Write stub config
|
- name: Write stub config
|
||||||
run: |
|
run: |
|
||||||
COYOTE_CONFIG_DIR="$(mktemp -d)"
|
COYOTE_CONFIG_DIR="$(mktemp -d)"
|
||||||
|
|||||||
@@ -42,9 +42,14 @@ impl AppState {
|
|||||||
config: Arc<AppConfig>,
|
config: Arc<AppConfig>,
|
||||||
log_path: Option<PathBuf>,
|
log_path: Option<PathBuf>,
|
||||||
start_mcp_servers: bool,
|
start_mcp_servers: bool,
|
||||||
|
lenient_vault: bool,
|
||||||
abort_signal: AbortSignal,
|
abort_signal: AbortSignal,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let vault = Arc::new(Vault::init(&config)?);
|
let vault = if lenient_vault {
|
||||||
|
Arc::new(Vault::init_lenient(&config))
|
||||||
|
} else {
|
||||||
|
Arc::new(Vault::init(&config)?)
|
||||||
|
};
|
||||||
|
|
||||||
let mcp_registry = McpRegistry::init(
|
let mcp_registry = McpRegistry::init(
|
||||||
log_path,
|
log_path,
|
||||||
|
|||||||
+7
-2
@@ -705,6 +705,10 @@ impl Config {
|
|||||||
Self::load_from_file(&config_path)?
|
Self::load_from_file(&config_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if info_flag {
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
|
|
||||||
let bootstrap_app = AppConfig {
|
let bootstrap_app = AppConfig {
|
||||||
vault_password_file: config.vault_password_file.clone(),
|
vault_password_file: config.vault_password_file.clone(),
|
||||||
secrets_provider: config.secrets_provider.clone(),
|
secrets_provider: config.secrets_provider.clone(),
|
||||||
@@ -712,7 +716,7 @@ impl Config {
|
|||||||
};
|
};
|
||||||
let vault = Vault::init(&bootstrap_app)?;
|
let vault = Vault::init(&bootstrap_app)?;
|
||||||
let (parsed_config, missing_secrets) = interpolate_secrets(&content, &vault)?;
|
let (parsed_config, missing_secrets) = interpolate_secrets(&content, &vault)?;
|
||||||
if !missing_secrets.is_empty() && !info_flag {
|
if !missing_secrets.is_empty() {
|
||||||
debug!(
|
debug!(
|
||||||
"Global config references secrets that are missing from the vault: {missing_secrets:?}"
|
"Global config references secrets that are missing from the vault: {missing_secrets:?}"
|
||||||
);
|
);
|
||||||
@@ -723,7 +727,7 @@ impl Config {
|
|||||||
missing_secrets
|
missing_secrets
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if !parsed_config.is_empty() && !info_flag {
|
if !parsed_config.is_empty() {
|
||||||
debug!("Global config is invalid once secrets are injected: {parsed_config}");
|
debug!("Global config is invalid once secrets are injected: {parsed_config}");
|
||||||
let new_config = Self::load_from_str(&parsed_config).with_context(|| {
|
let new_config = Self::load_from_str(&parsed_config).with_context(|| {
|
||||||
formatdoc!(
|
formatdoc!(
|
||||||
@@ -735,6 +739,7 @@ impl Config {
|
|||||||
})?;
|
})?;
|
||||||
config = new_config;
|
config = new_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -102,7 +102,6 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
let info_flag = cli.info
|
let info_flag = cli.info
|
||||||
|| cli.sync_models
|
|| cli.sync_models
|
||||||
|| cli.generate_models.is_some()
|
|
||||||
|| cli.list_models
|
|| cli.list_models
|
||||||
|| cli.list_roles
|
|| cli.list_roles
|
||||||
|| cli.list_agents
|
|| cli.list_agents
|
||||||
@@ -118,6 +117,10 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
let log_path = setup_logger(cli.acp_server)?;
|
let log_path = setup_logger(cli.acp_server)?;
|
||||||
|
|
||||||
|
if let Some(path) = &cli.generate_models {
|
||||||
|
return catalog::generate_models_file(path).await;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(version) = &cli.update {
|
if let Some(version) = &cli.update {
|
||||||
let version = version.clone();
|
let version = version.clone();
|
||||||
let force = cli.force;
|
let force = cli.force;
|
||||||
@@ -250,6 +253,7 @@ async fn main() -> Result<()> {
|
|||||||
app_config,
|
app_config,
|
||||||
log_path,
|
log_path,
|
||||||
start_mcp_servers,
|
start_mcp_servers,
|
||||||
|
info_flag,
|
||||||
abort_signal.clone(),
|
abort_signal.clone(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
@@ -297,10 +301,6 @@ async fn run(
|
|||||||
return sync_models(url.as_deref(), abort_signal.clone()).await;
|
return sync_models(url.as_deref(), abort_signal.clone()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = &cli.generate_models {
|
|
||||||
return catalog::generate_models_file(path).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
if cli.list_models {
|
if cli.list_models {
|
||||||
for model in list_models(ctx.app.config.as_ref(), ModelType::Chat) {
|
for model in list_models(ctx.app.config.as_ref(), ModelType::Chat) {
|
||||||
println!("{}", model.id());
|
println!("{}", model.id());
|
||||||
|
|||||||
+19
-12
@@ -96,14 +96,25 @@ impl Vault {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(config: &AppConfig) -> Result<Self> {
|
pub fn init(config: &AppConfig) -> Result<Self> {
|
||||||
if env::var_os(SANDBOX_ENV_FLAG).is_some() {
|
let mut vault = Self::init_lenient(config);
|
||||||
return Ok(Self {
|
if !vault.sandbox_mode
|
||||||
sandbox_mode: true,
|
&& let SupportedProvider::Local { provider_def } = &mut vault.provider
|
||||||
..Self::default()
|
{
|
||||||
});
|
ensure_password_file_initialized(provider_def)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut provider = match &config.secrets_provider {
|
Ok(vault)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_lenient(config: &AppConfig) -> Self {
|
||||||
|
if env::var_os(SANDBOX_ENV_FLAG).is_some() {
|
||||||
|
return Self {
|
||||||
|
sandbox_mode: true,
|
||||||
|
..Self::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let provider = match &config.secrets_provider {
|
||||||
Some(p) => p.clone(),
|
Some(p) => p.clone(),
|
||||||
None => SupportedProvider::Local {
|
None => SupportedProvider::Local {
|
||||||
provider_def: LocalProvider {
|
provider_def: LocalProvider {
|
||||||
@@ -113,14 +124,10 @@ impl Vault {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let SupportedProvider::Local { provider_def } = &mut provider {
|
Self {
|
||||||
ensure_password_file_initialized(provider_def)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
provider,
|
provider,
|
||||||
sandbox_mode: false,
|
sandbox_mode: false,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_password_file(&self) -> Result<PathBuf> {
|
pub fn local_password_file(&self) -> Result<PathBuf> {
|
||||||
|
|||||||
Reference in new issue
Block a user