codetether-agent 4.5.2

A2A-native AI coding agent for the CodeTether ecosystem
Documentation
use std::process::Command;

#[test]
fn rlm_fails_fast_without_provider() {
    let output = Command::new(env!("CARGO_BIN_EXE_codetether"))
        .args([
            "rlm",
            "Find all functions",
            "--content",
            "fn main() {}",
            "--json",
        ])
        .env("CODETETHER_DISABLE_ENV_FALLBACK", "1")
        .env("VAULT_ADDR", "http://127.0.0.1:1")
        .env("VAULT_TOKEN", "dummy")
        .env_remove("OPENROUTER_API_KEY")
        .env_remove("OPENAI_API_KEY")
        .env_remove("ANTHROPIC_API_KEY")
        .env_remove("GOOGLE_API_KEY")
        .env_remove("CODETETHER_LOCAL_CUDA")
        .env_remove("LOCAL_CUDA_MODEL")
        .env_remove("CODETETHER_LOCAL_CUDA_MODEL")
        .env_remove("LOCAL_CUDA_MODEL_PATH")
        .env_remove("CODETETHER_LOCAL_CUDA_MODEL_PATH")
        .env_remove("LOCAL_CUDA_TOKENIZER_PATH")
        .env_remove("CODETETHER_LOCAL_CUDA_TOKENIZER_PATH")
        .env_remove("LOCAL_CUDA_ARCH")
        .env_remove("CODETETHER_LOCAL_CUDA_ARCH")
        .output()
        .expect("run codetether rlm");

    assert!(
        !output.status.success(),
        "expected fail-fast; stdout={}",
        String::from_utf8_lossy(&output.stdout)
    );
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(
        stderr.contains("No usable RLM provider found"),
        "unexpected stderr: {stderr}"
    );
}

#[test]
fn rlm_explicit_local_cuda_does_not_fallback() {
    let output = Command::new(env!("CARGO_BIN_EXE_codetether"))
        .args([
            "rlm",
            "Find all functions",
            "--content",
            "fn main() {}",
            "--json",
            "--model",
            "local_cuda/qwen3.5-9b",
        ])
        .env("VAULT_ADDR", "http://127.0.0.1:1")
        .env("VAULT_TOKEN", "dummy")
        .env("OPENROUTER_API_KEY", "dummy-openrouter-key")
        .env("CODETETHER_LOCAL_CUDA", "1")
        .env_remove("LOCAL_CUDA_MODEL_PATH")
        .env_remove("LOCAL_CUDA_TOKENIZER_PATH")
        .env_remove("CODETETHER_LOCAL_CUDA_MODEL_PATH")
        .env_remove("CODETETHER_LOCAL_CUDA_TOKENIZER_PATH")
        .output()
        .expect("run codetether rlm");

    assert!(
        !output.status.success(),
        "expected explicit local_cuda config error; stdout={}",
        String::from_utf8_lossy(&output.stdout)
    );
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(
        stderr.contains("local_cuda selected explicitly but runtime is not configured")
            || stderr.contains("local_cuda selected explicitly but provider is unavailable"),
        "unexpected stderr: {stderr}"
    );
}

#[test]
fn rlm_configured_local_cuda_does_not_silently_fallback() {
    let output = Command::new(env!("CARGO_BIN_EXE_codetether"))
        .args([
            "rlm",
            "Find all functions",
            "--content",
            "fn main() {}",
            "--json",
        ])
        .env("VAULT_ADDR", "http://127.0.0.1:1")
        .env("VAULT_TOKEN", "dummy")
        .env("OPENROUTER_API_KEY", "dummy-openrouter-key")
        .env("LOCAL_CUDA_MODEL_PATH", "/tmp/nonexistent-model.gguf")
        .env(
            "LOCAL_CUDA_TOKENIZER_PATH",
            "/tmp/nonexistent-tokenizer.json",
        )
        .output()
        .expect("run codetether rlm");

    assert!(
        !output.status.success(),
        "expected local_cuda availability error; stdout={}",
        String::from_utf8_lossy(&output.stdout)
    );
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(
        stderr.contains("Local CUDA is configured but unavailable"),
        "unexpected stderr: {stderr}"
    );
}