use super::*;
#[test]
fn zero_mid_loop_trim_tokens_is_disabled() {
assert_eq!(effective_mid_loop_trim_tokens(None, Some(0)), None);
assert_eq!(effective_mid_loop_trim_tokens(Some(0), Some(5_000)), None);
assert_eq!(
effective_mid_loop_trim_tokens(None, Some(5_000)),
Some(5_000)
);
assert_eq!(
effective_mid_loop_trim_tokens(Some(3_000), Some(5_000)),
Some(3_000)
);
assert_eq!(effective_mid_loop_trim_tokens(None, None), None);
}
#[test]
fn today_date_matches_utc_calendar() {
let before = chrono::Utc::now().format("%Y-%m-%d").to_string();
let got = today_date();
let after = chrono::Utc::now().format("%Y-%m-%d").to_string();
assert!(
got == before || got == after,
"today_date()={got} not in [{before}, {after}]"
);
}
#[test]
fn keep_alive_str_default_and_configured() {
assert_eq!(keep_alive_str(&newt_core::Config::default()), "5m");
let cfg = newt_core::Config {
tui: Some(newt_core::TuiConfig {
keep_alive: "30m".into(),
..Default::default()
}),
..Default::default()
};
assert_eq!(keep_alive_str(&cfg), "30m");
}
#[test]
fn markdown_enabled_resolves_config_session_and_color() {
use newt_core::MarkdownMode;
let cfg_with = |m: MarkdownMode| newt_core::Config {
tui: Some(newt_core::TuiConfig {
markdown: m,
..Default::default()
}),
..Default::default()
};
let _guard = newt_core::test_guard::GlobalSettingsGuard::acquire();
newt_core::process_env::remove_var("NEWT_MARKDOWN");
assert!(markdown_enabled(&newt_core::Config::default(), true));
assert!(!markdown_enabled(&newt_core::Config::default(), false));
assert!(!markdown_enabled(&cfg_with(MarkdownMode::Off), true));
assert!(markdown_enabled(&cfg_with(MarkdownMode::On), true));
assert!(!markdown_enabled(&cfg_with(MarkdownMode::On), false));
newt_core::process_env::set_var("NEWT_MARKDOWN", "off");
assert!(!markdown_enabled(&cfg_with(MarkdownMode::On), true));
newt_core::process_env::set_var("NEWT_MARKDOWN", "on");
assert!(markdown_enabled(&cfg_with(MarkdownMode::Off), true));
assert!(
!markdown_enabled(&cfg_with(MarkdownMode::Off), false),
"color still gates it: ANSI needs color"
);
newt_core::process_env::remove_var("NEWT_MARKDOWN");
assert!(!markdown_enabled(&cfg_with(MarkdownMode::Off), true));
}
#[test]
fn context_manager_resolves_session_config_default() {
use newt_core::{ContextConfig, ContextManager};
let cfg_with = |m: ContextManager| newt_core::Config {
context: Some(ContextConfig {
manager: m,
..Default::default()
}),
..Default::default()
};
assert_eq!(
context_manager(&newt_core::Config::default(), None),
ContextManager::Standard
);
assert_eq!(
context_manager(&cfg_with(ContextManager::Progressive), None),
ContextManager::Progressive
);
assert_eq!(
context_manager(
&cfg_with(ContextManager::Progressive),
Some(ContextManager::Standard)
),
ContextManager::Standard
);
}
#[test]
fn compaction_trigger_policy_resolves_session_config_default() {
use newt_core::{CompactionTriggerPolicy, ContextConfig};
let cfg_with = |policy: CompactionTriggerPolicy| newt_core::Config {
context: Some(ContextConfig {
compaction_trigger_policy: policy,
..Default::default()
}),
..Default::default()
};
let _guard = newt_core::test_guard::GlobalSettingsGuard::acquire();
newt_core::process_env::remove_var("NEWT_COMPACTION_TRIGGER");
assert_eq!(
compaction_trigger_policy(&newt_core::Config::default()),
CompactionTriggerPolicy::HeadroomAware
);
assert_eq!(
compaction_trigger_policy_source(&newt_core::Config::default()),
"default"
);
assert_eq!(
compaction_trigger_policy(&cfg_with(CompactionTriggerPolicy::MessageCount)),
CompactionTriggerPolicy::MessageCount
);
assert_eq!(
compaction_trigger_policy_source(&cfg_with(CompactionTriggerPolicy::MessageCount)),
"config"
);
newt_core::process_env::set_var(
"NEWT_COMPACTION_TRIGGER",
CompactionTriggerPolicy::HeadroomAware.keyword(),
);
assert_eq!(
compaction_trigger_policy(&cfg_with(CompactionTriggerPolicy::MessageCount)),
CompactionTriggerPolicy::HeadroomAware
);
assert_eq!(
compaction_trigger_policy_source(&cfg_with(CompactionTriggerPolicy::MessageCount)),
"session"
);
newt_core::process_env::remove_var("NEWT_COMPACTION_TRIGGER");
assert_eq!(
compaction_trigger_policy(&cfg_with(CompactionTriggerPolicy::MessageCount)),
CompactionTriggerPolicy::MessageCount
);
}
#[test]
fn context_features_resolves_preset_config_session() {
use newt_core::{
BackendKind, ContextConfig, ContextFeature as F, ContextFeatures, ContextManager,
};
let cloud = context_features(
&newt_core::Config::default(),
ContextManager::Standard,
&ContextFeatures::default(),
BackendKind::Openai,
);
assert!(cloud.get(F::ToolOffload));
assert!(cloud.get(F::Semantic));
assert!(cloud.get(F::Scratchpad));
assert!(cloud.get(F::Scheduled));
let mut cfg_feats = ContextFeatures::default();
cfg_feats.set(F::Semantic, Some(true));
let cfg = newt_core::Config {
context: Some(ContextConfig {
manager: ContextManager::Standard,
features: cfg_feats,
..Default::default()
}),
..Default::default()
};
assert!(context_features(
&cfg,
ContextManager::Standard,
&ContextFeatures::default(),
BackendKind::Openai,
)
.get(F::Semantic));
let mut sess = ContextFeatures::default();
sess.set(F::Semantic, Some(false));
assert!(
!context_features(&cfg, ContextManager::Standard, &sess, BackendKind::Openai)
.get(F::Semantic)
);
}
#[test]
fn context_features_local_backend_defaults_plan_semantic_ledger_on() {
use newt_core::{
BackendKind, ContextConfig, ContextFeature as F, ContextFeatures, ContextManager,
};
let local = context_features(
&newt_core::Config::default(),
ContextManager::Standard,
&ContextFeatures::default(),
BackendKind::Ollama,
);
assert!(local.get(F::ToolOffload));
assert!(local.get(F::Scratchpad));
assert!(local.get(F::Semantic));
assert!(local.get(F::Scheduled));
let mut off = ContextFeatures::default();
off.set(F::Scheduled, Some(false));
off.set(F::ToolOffload, Some(false));
let cfg = newt_core::Config {
context: Some(ContextConfig {
manager: ContextManager::Standard,
features: off,
..Default::default()
}),
..Default::default()
};
let resolved = context_features(
&cfg,
ContextManager::Standard,
&ContextFeatures::default(),
BackendKind::Ollama,
);
assert!(
!resolved.get(F::Scheduled),
"explicit off overrides the local default"
);
assert!(
!resolved.get(F::ToolOffload),
"explicit off overrides default-on offload"
);
assert!(resolved.get(F::Scratchpad), "untouched feature stays on");
}
#[test]
fn handle_context_command_dispatch() {
use newt_core::{BackendKind, CompactionTriggerPolicy, ContextFeatures, ContextManager};
let _guard = newt_core::test_guard::GlobalSettingsGuard::acquire();
newt_core::process_env::remove_var("NEWT_COMPACTION_TRIGGER");
let cfg = newt_core::Config::default();
let none = ContextFeatures::default();
let run = |rest: &str| handle_context_command(rest, &cfg, None, &none, BackendKind::Openai);
let r = run("");
assert!(r.lines[0].contains("context manager: standard"));
assert!(r.lines[0].contains("features on: tool_offload"));
assert!(r.lines[1].contains("headroom_aware (default)"));
assert!(r.set_manager.is_none() && r.set_feature.is_none());
assert!(run("compaction").lines[0].contains("headroom_aware (default)"));
assert_eq!(
run("compaction message_count").set_compaction_trigger_policy,
Some(CompactionTriggerPolicyOverride::Set(
CompactionTriggerPolicy::MessageCount
))
);
assert_eq!(
run("compaction HEADROOM_AWARE").set_compaction_trigger_policy,
Some(CompactionTriggerPolicyOverride::Set(
CompactionTriggerPolicy::HeadroomAware
)),
"the command accepts the canonical policy parser's case-insensitive form"
);
newt_core::process_env::set_var(
"NEWT_COMPACTION_TRIGGER",
CompactionTriggerPolicy::MessageCount.keyword(),
);
let session_status = handle_context_command("", &cfg, None, &none, BackendKind::Openai);
assert!(session_status.lines[1].contains("message_count (session)"));
let r = handle_context_command("compaction reset", &cfg, None, &none, BackendKind::Openai);
assert_eq!(
r.set_compaction_trigger_policy,
Some(CompactionTriggerPolicyOverride::Reset)
);
assert!(r.lines[0].contains("headroom_aware (default)"));
assert!(run("compaction nope").lines[0].contains("unknown compaction trigger policy"));
assert_eq!(
run("manager standard").set_manager,
Some(ContextManager::Standard)
);
let r = run("manager progressive");
assert!(r.set_manager.is_none());
assert!(r.lines[0].contains("not yet available"));
assert!(run("manager bogus").lines[0].contains("unknown context manager"));
let r = run("feature");
assert!(r.lines.iter().any(|l| l.contains("scratchpad")));
assert!(r.lines.iter().any(|l| l.contains("tool_offload")));
assert_eq!(
r.lines
.iter()
.filter(|l| l.contains("not yet available"))
.count(),
1
);
let r = run("feature provenance on");
assert!(r.set_feature.is_none());
assert!(r.lines[0].contains("not yet available") && r.lines[0].contains("#584"));
assert!(run("feature handles on").lines[0].contains("not yet available"));
assert!(run("feature bogus on").lines[0].contains("unknown context feature"));
assert!(run("feature scratchpad maybe").lines[0].contains("unknown toggle"));
assert!(run("wat").lines[0].contains("unknown /context subcommand"));
assert!(run("feature semantic").lines[0].contains("context feature semantic: on"));
assert!(run("semantic").lines[0].contains("context feature semantic: on"));
let mut feats = ContextFeatures::default();
feats.set(newt_core::ContextFeature::Provenance, Some(true));
let cfg_on = newt_core::Config {
context: Some(newt_core::ContextConfig {
manager: ContextManager::Standard,
features: feats,
..Default::default()
}),
..Default::default()
};
let r = handle_context_command(
"feature provenance off",
&cfg_on,
None,
&none,
BackendKind::Openai,
);
assert!(
r.set_feature.is_none(),
"an unavailable feature is never applied"
);
assert!(
r.lines[0].contains("staying on"),
"message reflects the config-forced ON state: {:?}",
r.lines[0]
);
assert!(
handle_context_command("", &cfg_on, None, &none, BackendKind::Openai).lines[0]
.contains("provenance (pending #584)"),
"bare status annotates a config-on-but-unavailable feature as pending"
);
let r = run("feature tool_offload on");
assert_eq!(
r.set_feature,
Some((newt_core::ContextFeature::ToolOffload, true))
);
assert!(!r.lines[0].contains("not yet available"), "{:?}", r.lines);
let r = run("feature state on");
assert_eq!(
r.set_feature,
Some((newt_core::ContextFeature::Scratchpad, true))
);
assert_eq!(
run("feature retrieval on").set_feature,
Some((newt_core::ContextFeature::Semantic, true))
);
assert_eq!(
run("semantic on").set_feature,
Some((newt_core::ContextFeature::Semantic, true))
);
assert_eq!(
run("feature experience on").set_feature,
Some((newt_core::ContextFeature::Experiential, true))
);
assert_eq!(
run("feature compiled on").set_feature,
Some((newt_core::ContextFeature::Scheduled, true))
);
}
#[test]
fn context_stats_text_composes_budget_compression_and_features() {
use newt_core::{CompactionTriggerPolicy, CompressCounters, ContextFeatureSet};
let counters = CompressCounters {
compressions: 3,
strikes: 1,
disabled: false,
last_reclaim: Some(0.42),
};
let features = ContextFeatureSet::default();
let none = context_stats_text(
None,
&counters,
CompactionTriggerPolicy::HeadroomAware,
"default",
features,
None,
None,
None,
None,
None,
);
assert_eq!(none[0], "context stats");
assert!(none.iter().any(|l| l.contains("budget: not yet measured")));
assert!(none
.iter()
.any(|l| l.contains("automatic compaction: headroom_aware (default)")));
let s = context_stats_text(
Some((899_000, Some(1_024_000))),
&counters,
CompactionTriggerPolicy::MessageCount,
"session",
features,
None,
None,
None,
None,
None,
);
let joined = s.join("\n");
assert!(joined.contains("899k/1024k"), "{joined}");
assert!(joined.contains("% of the send window"), "{joined}");
assert!(joined.contains("automatic compaction: message_count (session)"));
assert!(joined.contains("compressions this session: 3"), "{joined}");
assert!(joined.contains("reclaimed 42%"), "{joined}");
for f in newt_core::ContextFeature::ALL {
assert!(joined.contains(f.keyword()), "missing {}", f.keyword());
}
assert_eq!(
s.iter().filter(|l| l.contains("(pending #")).count(),
1,
"only provenance still pending (the other five shipped)"
);
let mut on = ContextFeatureSet::default();
on.set(newt_core::ContextFeature::ToolOffload, true);
on.set(newt_core::ContextFeature::Scratchpad, true);
on.set(newt_core::ContextFeature::Semantic, true);
on.set(newt_core::ContextFeature::Experiential, true);
on.set(newt_core::ContextFeature::Scheduled, true);
let imp = context_stats_text(
None,
&counters,
CompactionTriggerPolicy::HeadroomAware,
"config",
on,
Some((3, 48_000)),
Some((5, 12_000)),
Some((42, 60_000)),
Some((7, 9_000)),
Some((4, 2)),
)
.join("\n");
assert!(
imp.contains("[on ] tool_offload — 3 offloaded (~48k chars elided)"),
"{imp}"
);
assert!(
imp.contains("[on ] scratchpad — 5 keys (~12k chars)"),
"{imp}"
);
assert!(
imp.contains("[on ] semantic — 42 chunks indexed (~60k chars)"),
"{imp}"
);
assert!(
imp.contains("[on ] experiential — 7 experiences (~9k chars)"),
"{imp}"
);
assert!(
imp.contains("[on ] scheduled — 2/4 plan steps done"),
"{imp}"
);
assert!(context_stats_text(
Some((10, Some(0))),
&counters,
CompactionTriggerPolicy::HeadroomAware,
"default",
features,
None,
None,
None,
None,
None
)
.iter()
.any(|l| l.contains("not yet measured")));
let unknown_window = context_stats_text(
Some((31_000, None)),
&counters,
CompactionTriggerPolicy::HeadroomAware,
"default",
features,
None,
None,
None,
None,
None,
)
.join("\n");
assert!(unknown_window.contains("31k/?"), "{unknown_window}");
}
#[test]
fn mid_loop_trim_threshold_clamps_below_round_cap() {
assert_eq!(mid_loop_trim_threshold(&newt_core::Config::default()), 37);
let cfg = newt_core::Config {
tui: Some(newt_core::TuiConfig {
max_tool_rounds: 7,
..Default::default()
}),
..Default::default()
};
assert_eq!(mid_loop_trim_threshold(&cfg), 4);
let cfg = newt_core::Config {
tui: Some(newt_core::TuiConfig {
max_tool_rounds: 25,
mid_loop_trim_threshold: 5,
..Default::default()
}),
..Default::default()
};
assert_eq!(mid_loop_trim_threshold(&cfg), 5);
}
#[test]
fn timeout_helpers_default_and_configured() {
let empty = newt_core::Config::default();
assert_eq!(connect_timeout_secs(&empty), 5);
assert_eq!(inference_timeout_secs(&empty), 120);
let cfg = newt_core::Config {
tui: Some(newt_core::TuiConfig {
connect_timeout_secs: 9,
inference_timeout_secs: 300,
..Default::default()
}),
..Default::default()
};
assert_eq!(connect_timeout_secs(&cfg), 9);
assert_eq!(inference_timeout_secs(&cfg), 300);
}
#[test]
fn build_check_cmd_reads_config() {
assert_eq!(build_check_cmd(&newt_core::Config::default()), None);
let cfg = newt_core::Config {
tui: Some(newt_core::TuiConfig {
build_check_cmd: Some("cargo check -q".into()),
..Default::default()
}),
..Default::default()
};
assert_eq!(build_check_cmd(&cfg).as_deref(), Some("cargo check -q"));
}
#[test]
fn resolve_workspace_none_uses_current_dir() {
let cwd = std::env::current_dir().unwrap();
assert_eq!(resolve_workspace(None), cwd.to_string_lossy());
}
#[test]
fn expand_prompt_tokens_replaces_all_tokens() {
let out = expand_prompt_tokens("\\w|\\W|\\v|\\m|\\M", "/tmp/proj", "gpt-4.1", true);
assert_eq!(out, format!("proj|/tmp/proj|{VERSION}|gpt-4.1|vi"));
let host = expand_prompt_tokens("on \\h!", "/tmp/proj", "m", false);
assert!(!host.contains("\\h"), "got: {host}");
assert!(host.starts_with("on ") && host.ends_with('!'));
}
#[test]
fn resolver_default_backend_beats_the_openai_heuristic() {
let _g = crate::test_env_guard::env_write_guard();
let ollama = newt_core::BackendConfig {
name: "gpu-runner".into(),
endpoint: "http://gpu-runner:11434".into(),
model: Some("m1".into()),
kind: Some(newt_core::BackendKind::Ollama),
..Default::default()
};
let vllm = newt_core::BackendConfig {
name: "dgx1-8000".into(),
endpoint: "http://dgx1:8000".into(),
kind: Some(newt_core::BackendKind::Openai),
serving: Some(newt_core::Serving::Instance),
..Default::default()
};
let resolved = |cfg: newt_core::Config| newt_core::ResolvedConfig::unrequested(cfg);
let cfg = newt_core::Config {
backends: vec![ollama.clone(), vllm.clone()],
..Default::default()
};
let c = resolve_backend_choice(&resolved(cfg.clone())).expect("resolves");
assert_eq!(c.name, "dgx1-8000");
assert_eq!(
c.active_model, None,
"unset model stays empty until adopted"
);
assert_eq!(c.route_serving(), Some(newt_core::Serving::Instance));
let mut with_default = cfg;
with_default.default_backend = Some("gpu-runner".into());
let c = resolve_backend_choice(&resolved(with_default)).expect("resolves");
assert_eq!(c.name, "gpu-runner");
assert_eq!(c.active_model.as_deref(), Some("m1"));
let solo = newt_core::Config {
backends: vec![ollama],
..Default::default()
};
assert_eq!(
resolve_backend_choice(&resolved(solo))
.expect("resolves")
.name,
"gpu-runner"
);
}
#[test]
fn ready_line_names_the_backend_protocol() {
let l = ready_line(
"0.6.8",
"qwen3.6:27b",
"http://REDACTED-HOST:11434",
newt_core::BackendKind::Ollama,
);
assert!(
l.contains("qwen3.6:27b @ http://REDACTED-HOST:11434 (ollama)"),
"{l}"
);
let v = ready_line(
"0.6.8",
"m",
"http://dgx1:8000",
newt_core::BackendKind::Openai,
);
assert!(v.contains("@ http://dgx1:8000 (openai)"), "{v}");
}
#[test]
fn resolve_embeddings_target_decouples_or_uses_explicit_protocol() {
use newt_core::BackendKind;
let cfg = newt_core::SemanticConfig {
embeddings_api: Some(BackendKind::Ollama),
..Default::default()
};
let (url, kind, key) =
resolve_embeddings_target(&cfg, "http://dgx1:8000", BackendKind::Openai, Some("sk-x"));
assert_eq!(url, "http://dgx1:8000");
assert_eq!(kind, BackendKind::Ollama);
assert_eq!(key.as_deref(), Some("sk-x"));
let cfg = newt_core::SemanticConfig {
embeddings_endpoint: Some("http://REDACTED-HOST:11434".to_string()),
..Default::default()
};
let (url, kind, key) =
resolve_embeddings_target(&cfg, "http://dgx1:8000", BackendKind::Openai, Some("sk-x"));
assert_eq!(url, "http://REDACTED-HOST:11434");
assert_eq!(kind, BackendKind::Ollama);
assert_eq!(key, None);
let cfg = newt_core::SemanticConfig {
embeddings_api: Some(BackendKind::Openai),
..cfg
};
let (_, kind, _) = resolve_embeddings_target(&cfg, "http://x", BackendKind::Ollama, None);
assert_eq!(kind, BackendKind::Openai);
}
#[test]
fn embeddings_backend_is_embedded_by_default_or_embedded_api() {
let mut cfg = newt_core::SemanticConfig::default();
assert!(embeddings_backend_is_embedded(&cfg)); cfg.embeddings_endpoint = Some("http://REDACTED-HOST:11434".to_string());
assert!(!embeddings_backend_is_embedded(&cfg));
cfg.embeddings_endpoint = None;
cfg.embeddings_api = Some(newt_core::BackendKind::Ollama);
assert!(!embeddings_backend_is_embedded(&cfg));
cfg.embeddings_api = Some(newt_core::BackendKind::Openai);
assert!(!embeddings_backend_is_embedded(&cfg));
cfg.embeddings_api = Some(newt_core::BackendKind::Embedded);
assert!(embeddings_backend_is_embedded(&cfg));
}
#[test]
fn semantic_zero_index_hint_matches_embedder_path() {
let embedded = newt_core::SemanticConfig::default();
let hint = semantic_zero_index_hint(&embedded);
assert!(hint.contains("newt models pull-embed"), "got: {hint}");
assert!(hint.contains("embedding_model_path"), "got: {hint}");
let http = newt_core::SemanticConfig {
embeddings_endpoint: Some("http://REDACTED-HOST:11434".to_string()),
..Default::default()
};
assert!(semantic_zero_index_hint(&http).contains("Ollama/OpenAI"));
}
#[test]
fn semantic_embedder_preflight_skips_unavailable_embedded_path() {
let embedded = newt_core::SemanticConfig::default();
let reason = semantic_embedder_unavailable_reason(&embedded)
.expect("default semantic embeddings select the embedded path");
#[cfg(not(feature = "embedded"))]
assert!(
reason.contains("lacks the `embedded` feature"),
"got: {reason}"
);
#[cfg(feature = "embedded")]
assert!(reason.contains("embedding_model_path"), "got: {reason}");
}
#[test]
fn effective_embedding_model_path_precedence() {
use std::path::PathBuf;
assert_eq!(
effective_embedding_model_path(
Some("/explicit/path".to_string()),
Some(PathBuf::from("/pulled/default"))
),
Some("/explicit/path".to_string())
);
assert_eq!(
effective_embedding_model_path(None, Some(PathBuf::from("/pulled/default"))),
Some("/pulled/default".to_string())
);
assert_eq!(effective_embedding_model_path(None, None), None);
}
#[test]
fn semantic_zero_index_and_unavailable_reason_name_the_pull_command() {
let embedded = newt_core::SemanticConfig::default();
#[cfg(feature = "embedded")]
{
let reason = semantic_embedder_unavailable_reason(&embedded).expect("no model → a reason");
assert!(reason.contains("newt models pull-embed"), "got: {reason}");
}
assert!(semantic_zero_index_hint(&embedded).contains("newt models pull-embed"));
}
#[test]
fn semantic_embedder_preflight_allows_explicit_http_embeddings() {
let http = newt_core::SemanticConfig {
embeddings_api: Some(newt_core::BackendKind::Ollama),
..Default::default()
};
assert!(semantic_embedder_unavailable_reason(&http).is_none());
}
#[tokio::test]
async fn build_semantic_embedder_selects_embedded_path() {
let cfg = newt_core::SemanticConfig::default();
let embedder = build_semantic_embedder(&cfg, "http://unused", inf_kind_ollama(), None);
let err = embedder.embed("x").await.unwrap_err().to_string();
assert!(
err.contains("embedded"),
"expected the embedded path's error, got: {err}"
);
}
#[tokio::test]
async fn make_embedded_embedder_without_model_path_fails_closed() {
let embedder = make_embedded_embedder("bge-small-en-v1.5".to_string(), None);
let err = embedder.embed("x").await.unwrap_err().to_string();
#[cfg(feature = "embedded")]
assert!(err.contains("embedding_model_path"), "got: {err}");
#[cfg(not(feature = "embedded"))]
assert!(err.contains("--features embedded"), "got: {err}");
}
#[tokio::test]
async fn build_semantic_embedder_http_branch_constructs() {
let cfg = newt_core::SemanticConfig {
embeddings_api: Some(newt_core::BackendKind::Ollama),
..Default::default()
};
let _embedder =
build_semantic_embedder(&cfg, "http://localhost:11434", inf_kind_ollama(), None);
}
fn inf_kind_ollama() -> newt_core::BackendKind {
newt_core::BackendKind::Ollama
}
#[test]
fn resolve_backend_choice_prefers_openai_backend() {
let cfg = newt_core::Config {
backends: vec![newt_core::BackendConfig {
name: "vllm".into(),
endpoint: "http://vllm.example:8000".into(),
model: Some("qwen3:32b".into()),
model_path: None,
tiers: vec![],
kind: Some(newt_core::BackendKind::Openai),
api: Default::default(),
api_key_file: None,
api_key_env: None,
..Default::default()
}],
..Default::default()
};
let cfg = newt_core::ResolvedConfig::unrequested(cfg);
let choice = crate::env_resolution_tests::with_env_vars(
&[],
&["NEWT_DGX_MODEL", "NEWT_BACKEND", "NEWT_PROVIDER"],
|| resolve_backend_choice(&cfg).expect("resolves"),
);
assert_eq!(choice.kind, newt_core::BackendKind::Openai);
assert_eq!(choice.url, "http://vllm.example:8000");
assert_eq!(choice.active_model.as_deref(), Some("qwen3:32b"));
assert!(choice.api_key.is_none(), "no key configured → None");
}
#[test]
fn resolve_backend_choice_marks_absent_kind_for_probe() {
let cfg = newt_core::Config {
backends: vec![newt_core::BackendConfig {
name: "dgx1-llama".into(),
endpoint: "http://host:8000".into(),
kind: None,
..Default::default()
}],
..Default::default()
};
let cfg = newt_core::ResolvedConfig::unrequested(cfg);
let choice = crate::env_resolution_tests::with_env_vars(
&[],
&[
"NEWT_DGX_MODEL",
"NEWT_BACKEND",
"NEWT_PROVIDER",
"NEWT_DGX_OLLAMA_URL",
"NEWT_DGX_HOST",
],
|| resolve_backend_choice(&cfg).expect("resolves"),
);
assert!(choice.kind_needs_probe, "absent kind must probe at adopt");
assert_eq!(choice.name, "dgx1-llama");
assert_eq!(choice.url, "http://host:8000");
}
#[test]
fn resolve_backend_choice_explicit_kind_skips_probe_flag() {
let cfg = newt_core::ResolvedConfig::unrequested(newt_core::Config {
backends: vec![newt_core::BackendConfig {
name: "local".into(),
endpoint: "http://127.0.0.1:11434".into(),
kind: Some(newt_core::BackendKind::Ollama),
..Default::default()
}],
..Default::default()
});
let choice = crate::env_resolution_tests::with_env_vars(
&[],
&[
"NEWT_DGX_MODEL",
"NEWT_BACKEND",
"NEWT_PROVIDER",
"NEWT_DGX_OLLAMA_URL",
"NEWT_DGX_HOST",
],
|| resolve_backend_choice(&cfg).expect("resolves"),
);
assert!(!choice.kind_needs_probe);
assert_eq!(choice.kind, newt_core::BackendKind::Ollama);
}
struct ConfigDirPin {
_dir: tempfile::TempDir,
prev: Option<std::ffi::OsString>,
}
impl ConfigDirPin {
fn new() -> Self {
let dir = tempfile::tempdir().unwrap();
let prev = std::env::var_os("NEWT_CONFIG_DIR");
std::env::set_var("NEWT_CONFIG_DIR", dir.path());
Self { _dir: dir, prev }
}
}
impl Drop for ConfigDirPin {
fn drop(&mut self) {
match self.prev.take() {
Some(v) => std::env::set_var("NEWT_CONFIG_DIR", v),
None => std::env::remove_var("NEWT_CONFIG_DIR"),
}
}
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn adopt_detects_openai_when_kind_absent() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/v1/models"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"data": [{"id": "nemotron"}]
})))
.mount(&server)
.await;
let mut choice = BackendChoice {
kind_needs_probe: true,
api_key: None,
..BackendChoice::synthesized(
"dgx1-llama",
server.uri(),
newt_core::BackendKind::Ollama, None,
)
};
let lines = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.kind, newt_core::BackendKind::Openai);
assert!(!choice.kind_needs_probe);
assert_eq!(choice.active_model.as_deref(), Some("nemotron"));
assert!(
lines.iter().any(|l| l.contains("detected openai")),
"status lines={lines:?}"
);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn adopt_detects_ollama_when_kind_absent() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/api/tags"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"models": [{"name": "llama3.1:8b"}]
})))
.mount(&server)
.await;
let mut choice = BackendChoice {
kind_needs_probe: true,
api_key: None,
..BackendChoice::synthesized(
"local",
server.uri(),
newt_core::BackendKind::Openai, None,
)
};
let _ = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.kind, newt_core::BackendKind::Ollama);
assert_eq!(choice.active_model.as_deref(), Some("llama3.1:8b"));
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn adopt_respects_explicit_kind_without_detect() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/v1/models"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"data": [{"id": "should-not-adopt"}]
})))
.mount(&server)
.await;
let mut choice = BackendChoice {
kind_needs_probe: false,
api_key: None,
declared_model: Some("configured".into()),
..BackendChoice::synthesized(
"pinned-ollama",
server.uri(),
newt_core::BackendKind::Ollama,
Some("configured".into()),
)
};
let lines = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.kind, newt_core::BackendKind::Ollama);
assert_eq!(
choice.active_model.as_deref(),
Some("configured"),
"keep file hint when ollama probe fails"
);
assert!(
lines.iter().any(|l| l.contains("unreachable")),
"explicit ollama against openai-only endpoint should report unreachable, not detect; lines={lines:?}"
);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn adopt_detects_authenticated_openai_with_bearer() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{header, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/v1/models"))
.and(header("authorization", "Bearer secret-token"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"data": [{"id": "gated-model"}]
})))
.mount(&server)
.await;
let mut choice = BackendChoice {
kind_needs_probe: true,
api_key: Some("secret-token".into()),
..BackendChoice::synthesized("gated", server.uri(), newt_core::BackendKind::Ollama, None)
};
let _ = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.kind, newt_core::BackendKind::Openai);
assert_eq!(choice.active_model.as_deref(), Some("gated-model"));
}
#[test]
fn resolve_modal_choice_honors_an_initially_warm_candidate() {
let served = vec!["A".to_string(), "B".to_string()];
assert_eq!(
resolve_modal_choice(Some(("A".to_string(), served))).as_deref(),
Some("A")
);
}
#[test]
fn resolve_modal_choice_honors_a_candidate_the_outer_probe_never_saw() {
let picker_served = vec!["A".to_string(), "B".to_string(), "C".to_string()];
assert_eq!(
resolve_modal_choice(Some(("C".to_string(), picker_served))).as_deref(),
Some("C")
);
}
#[test]
fn resolve_modal_choice_refuses_a_pick_no_longer_served() {
let served = vec!["A".to_string(), "B".to_string()];
assert_eq!(
resolve_modal_choice(Some(("gone".to_string(), served))),
None
);
}
#[test]
fn resolve_modal_choice_is_none_on_cancel() {
assert_eq!(resolve_modal_choice(None), None);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn finish_adoption_picks_the_ambiguous_default_from_the_pickers_own_roster() {
let _pin = ConfigDirPin::new();
let mut choice = BackendChoice::synthesized(
"mux",
"http://127.0.0.1:1".into(),
newt_core::BackendKind::Ollama,
None,
);
let lines = finish_adoption_with_picker(
&mut choice,
Vec::new(),
vec!["A".into(), "B".into()],
vec!["A".into(), "B".into()],
None,
|_choice| Some(("C".to_string(), vec!["A".into(), "B".into(), "C".into()])),
);
assert_eq!(choice.active_model.as_deref(), Some("C"));
assert!(
lines
.iter()
.any(|l| l.contains("backend default → C (picked)")),
"lines={lines:?}"
);
assert!(
!lines.iter().any(|l| l.contains("none is configured")),
"no-model refusal must not fire when the picker resolved a choice; lines={lines:?}"
);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn finish_adoption_refuses_when_the_picker_is_cancelled() {
let _pin = ConfigDirPin::new();
let mut choice = BackendChoice::synthesized(
"mux",
"http://127.0.0.1:1".into(),
newt_core::BackendKind::Ollama,
None,
);
let lines = finish_adoption_with_picker(
&mut choice,
Vec::new(),
vec!["A".into(), "B".into()],
vec!["A".into(), "B".into()],
None,
|_choice| None, );
assert_eq!(choice.active_model, None);
assert!(
lines.iter().any(|l| l.contains("none is configured")),
"lines={lines:?}"
);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn finish_adoption_refuses_a_pick_the_picker_no_longer_serves() {
let _pin = ConfigDirPin::new();
let mut choice = BackendChoice::synthesized(
"mux",
"http://127.0.0.1:1".into(),
newt_core::BackendKind::Ollama,
None,
);
let lines = finish_adoption_with_picker(
&mut choice,
Vec::new(),
vec!["A".into(), "B".into()],
vec!["A".into(), "B".into()],
None,
|_choice| Some(("gone".to_string(), vec!["A".into(), "B".into()])),
);
assert_eq!(choice.active_model, None);
assert!(
lines.iter().any(|l| l.contains("none is configured")),
"lines={lines:?}"
);
}
#[test]
fn prewarm_applies_is_url_equality_modulo_trailing_slash() {
assert!(crate::prewarm_applies(
"http://gpu:11434",
"http://gpu:11434/"
));
assert!(!crate::prewarm_applies(
"http://gpu:11434",
"http://other:11434"
));
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn issue_2248_minimal_openai_props_reaches_the_dispatch_budget() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
let model = "example/model:Q8_0";
Mock::given(method("GET"))
.and(path("/v1/models"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"data": [{"id": model}, {"id": "other-model"}]
})))
.mount(&server)
.await;
Mock::given(method("GET"))
.and(path("/props"))
.and(query_param("model", model))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"default_generation_settings": {"n_ctx": 131072}
})))
.expect(1)
.mount(&server)
.await;
let mut choice = BackendChoice::synthesized(
"minimal",
server.uri(),
newt_core::BackendKind::Openai,
Some(model.into()),
);
choice.declared_model = Some(model.into());
choice.configured_kind = Some(newt_core::BackendKind::Openai);
choice.api_needs_probe = true;
assert!(choice.route_serving().is_none());
let _ = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.active_model.as_deref(), Some(model));
assert_eq!(choice.context_window, Some(131072));
let cached = crate::probe::CapabilityEntry {
max_ok_input: Some(24646),
safe_context: Some(24646),
..Default::default()
};
let cfg = newt_core::Config::default();
let community = newt_core::tuning::CommunityTunings::default();
let resolved = crate::context_window::resolve(crate::context_window::facts_for(
&cfg,
choice.kind,
model,
choice.context_window,
&cached,
&community,
None,
None,
));
assert_eq!(resolved.full_window, Some(131072));
assert_eq!(resolved.safe_context, Some(104857));
let budget = newt_core::agentic::initial_context_input_budget(
choice.kind,
choice.api,
resolved.num_ctx,
80,
None,
None,
Default::default(),
Default::default(),
resolved.max_ok_input,
resolved.safe_context,
);
assert_eq!(
budget,
Some(104857),
"learned 24646 must not cap the probed window"
);
}
#[serial_test::serial(real_fs)]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn issue_2248_effective_props_overrides_requested_launch_budget() {
let _pin = ConfigDirPin::new();
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, MockServer, ResponseTemplate};
let server = MockServer::start().await;
let model = "example/model:Q8_0";
Mock::given(method("GET"))
.and(path("/v1/models"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"data": [{"id": model, "status": {"value": "loaded",
"args": ["llama-server", "-c", "262144", "-np", "2"]}},
{"id": "other-model"}]
})))
.mount(&server)
.await;
Mock::given(method("GET"))
.and(path("/props"))
.and(query_param("model", model))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"default_generation_settings": {"n_ctx": 65536}
})))
.expect(1)
.mount(&server)
.await;
let mut choice = BackendChoice::synthesized(
"minimal",
server.uri(),
newt_core::BackendKind::Openai,
Some(model.into()),
);
choice.declared_model = Some(model.into());
choice.configured_kind = Some(newt_core::BackendKind::Openai);
choice.api_needs_probe = true;
assert!(choice.route_serving().is_none());
let _ = adopt_backend_choice(&mut choice, None);
assert_eq!(choice.active_model.as_deref(), Some(model));
assert_eq!(choice.context_window, Some(65536));
let cached = crate::probe::CapabilityEntry {
max_ok_input: Some(24646),
safe_context: Some(24646),
..Default::default()
};
let cfg = newt_core::Config::default();
let community = newt_core::tuning::CommunityTunings::default();
let resolved = crate::context_window::resolve(crate::context_window::facts_for(
&cfg,
choice.kind,
model,
choice.context_window,
&cached,
&community,
None,
None,
));
assert_eq!(resolved.full_window, Some(65536));
assert_eq!(resolved.safe_context, Some(52428));
let budget = newt_core::agentic::initial_context_input_budget(
choice.kind,
choice.api,
resolved.num_ctx,
80,
None,
None,
Default::default(),
Default::default(),
resolved.max_ok_input,
resolved.safe_context,
);
assert_eq!(
budget,
Some(52428),
"learned 24646 must not cap the probed window"
);
}