fix(TASK-046): make inspection flags look-don't-touch and pin the contracts
- Skip the builtins bootstrap, function-binary build, and tool-scope rebuild for inspection-only runs (--info/--list-*/--mcp-list/ --list-secrets without --agent/--role): a pristine COYOTE_CONFIG_DIR now stays byte-empty (was 269 files written before dispatch) - Tolerate a model-less default config on the inspection surface via AppConfig::from_config_lenient + Model::default() in bootstrap; strict 'No available model' behavior unchanged for the REPL path and all mutating mcp/vault flags - --list-secrets degrades to an rc=0 informational message in sandbox mode (mutating vault flags still fail there), pinned by test - Add the 041.7-4 regression test: a malformed COYOTE_<NAME>_GLOBAL_TOOLS env override logs the debug message and leaves global_tools untouched - Adopt scripts/usage-probe-inspection.sh (10 flags: rc=0 + zero writes, output required only for --info) and add binary-level tests/inspection_flags.rs, incl. the agent+--info still-bootstraps pin
This commit is contained in:
9 files changed
+389
-31
No files matched your search
@@ -210,6 +210,18 @@ impl Default for AppConfig {
|
||||
|
||||
impl AppConfig {
|
||||
pub fn from_config(config: super::Config) -> Result<Self> {
|
||||
Self::from_config_impl(config, true)
|
||||
}
|
||||
|
||||
/// Like [`Self::from_config`], but tolerates a config with no resolvable
|
||||
/// model: `model_id` stays empty instead of failing with "No available
|
||||
/// model". For inspection readouts (--info, --list-*, --mcp-list,
|
||||
/// --list-secrets), which render model fields as absent/default.
|
||||
pub fn from_config_lenient(config: super::Config) -> Result<Self> {
|
||||
Self::from_config_impl(config, false)
|
||||
}
|
||||
|
||||
fn from_config_impl(config: super::Config, require_model: bool) -> Result<Self> {
|
||||
let mut app_config = Self {
|
||||
model_id: config.model_id,
|
||||
temperature: config.temperature,
|
||||
@@ -306,7 +318,13 @@ impl AppConfig {
|
||||
}
|
||||
app_config.setup_document_loaders();
|
||||
app_config.setup_user_agent();
|
||||
app_config.resolve_model()?;
|
||||
if require_model {
|
||||
app_config.resolve_model()?;
|
||||
} else {
|
||||
// Model-less is fine here: model_id stays empty and inspection
|
||||
// callers substitute Model::default().
|
||||
let _ = app_config.resolve_model();
|
||||
}
|
||||
app_config.validate_reasoning_effort()?;
|
||||
Ok(app_config)
|
||||
}
|
||||
@@ -1269,6 +1287,18 @@ mod tests {
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_config_errors_when_no_model_available() {
|
||||
let result = AppConfig::from_config(Config::default());
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_config_lenient_tolerates_missing_model() {
|
||||
let app = AppConfig::from_config_lenient(Config::default()).unwrap();
|
||||
assert!(app.model_id.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_model_keeps_explicit_model_id() {
|
||||
let mut app = AppConfig {
|
||||
|
||||
Reference in new issue
Block a user