diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72af60760..8b733225a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -257,6 +257,7 @@ jobs: if: steps.optout.outputs.skip != 'true' env: VERSION: '0.17.0' + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail curl -fsSL https://install.iii.dev/iii/main/install.sh -o /tmp/install-iii.sh diff --git a/approval-gate/Cargo.lock b/approval-gate/Cargo.lock index 3a19d21c4..a831d2e52 100644 --- a/approval-gate/Cargo.lock +++ b/approval-gate/Cargo.lock @@ -92,7 +92,7 @@ dependencies = [ "clap", "futures", "harness", - "iii-sdk", + "iii-sdk 0.20.0-alpha.2", "regex", "schemars", "serde", @@ -545,14 +545,14 @@ dependencies = [ [[package]] name = "harness" -version = "1.1.3" +version = "1.1.12" dependencies = [ "anyhow", "async-trait", "clap", "globset", - "iii-helpers", - "iii-sdk", + "iii-helpers 0.21.2-next.1", + "iii-sdk 0.21.2-next.1", "jsonschema", "schemars", "serde", @@ -825,6 +825,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "iii-helpers" +version = "0.21.2-next.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030839b177b118574ca2f8c03030f33948cd353eb774127f281d200428a4918d" +dependencies = [ + "futures-util", + "opentelemetry", + "opentelemetry-http", + "opentelemetry_sdk", + "reqwest", + "schemars", + "serde", + "serde_json", + "sysinfo", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + [[package]] name = "iii-sdk" version = "0.20.0-alpha.2" @@ -834,7 +855,28 @@ dependencies = [ "async-trait", "futures-util", "hostname", - "iii-helpers", + "iii-helpers 0.20.0-alpha.2", + "reqwest", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", +] + +[[package]] +name = "iii-sdk" +version = "0.21.2-next.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1837ea510df889a7f9c9d7b3432c962946674f54741de7e6ec6e8ad2534ee83c" +dependencies = [ + "async-trait", + "futures-util", + "hostname", + "iii-helpers 0.21.2-next.1", "reqwest", "schemars", "serde", diff --git a/provider-anthropic/Cargo.lock b/provider-anthropic/Cargo.lock index e464e3172..9a01c8864 100644 --- a/provider-anthropic/Cargo.lock +++ b/provider-anthropic/Cargo.lock @@ -776,7 +776,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.5" +version = "1.0.6" dependencies = [ "async-trait", "clap", diff --git a/provider-anthropic/src/thinking.rs b/provider-anthropic/src/thinking.rs index f09faa65a..391b23288 100644 --- a/provider-anthropic/src/thinking.rs +++ b/provider-anthropic/src/thinking.rs @@ -42,8 +42,14 @@ pub struct ThinkingBuild { pub fn build_thinking_config(level: Option, model: Option<&Model>) -> ThinkingBuild { let mut warnings = Vec::new(); let Some(level) = level else { + // Parity with xai reasoning models, which surface reasoning by default: + // with no explicit level, still request adaptive thinking on models that + // definitely support it (server default effort, so no output_config). + // Gate on Some(true), not the permissive path — an implicit default must + // never 400 on a non-thinking or unknown model. + let config = (model.and_then(|m| m.supports_thinking) == Some(true)).then_some(ADAPTIVE); return ThinkingBuild { - config: None, + config, effort: None, warnings, }; @@ -99,13 +105,31 @@ mod tests { } #[test] - fn absent_level_means_off() { + fn absent_level_defaults_on_for_thinking_models() { + // Parity with xai: no explicit level still surfaces reasoning on a model + // that supports thinking, at the server's default effort (no output_config). let built = build_thinking_config(None, Some(&model(Some(true), Some(true)))); - assert_eq!(built.config, None); + assert_eq!(built.config, Some(ADAPTIVE)); assert_eq!(built.effort, None); assert!(built.warnings.is_empty()); } + #[test] + fn absent_level_stays_off_without_thinking_support() { + // No implicit default when support is unknown or explicitly false, so the + // default can never 400 a non-thinking model. + for m in [ + None, + Some(model(None, None)), + Some(model(Some(false), None)), + ] { + let built = build_thinking_config(None, m.as_ref()); + assert_eq!(built.config, None); + assert_eq!(built.effort, None); + assert!(built.warnings.is_empty()); + } + } + #[test] fn levels_map_to_adaptive_with_effort() { let m = model(Some(true), Some(true)); diff --git a/provider-llamacpp/Cargo.lock b/provider-llamacpp/Cargo.lock index 2ed2d0994..2d190330a 100644 --- a/provider-llamacpp/Cargo.lock +++ b/provider-llamacpp/Cargo.lock @@ -738,7 +738,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.4" +version = "1.0.6" dependencies = [ "async-trait", "clap", diff --git a/provider-openai-codex/Cargo.lock b/provider-openai-codex/Cargo.lock index 0e55a80a6..d78dc0f6b 100644 --- a/provider-openai-codex/Cargo.lock +++ b/provider-openai-codex/Cargo.lock @@ -776,7 +776,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.2" +version = "1.0.6" dependencies = [ "async-trait", "clap", diff --git a/provider-openai-codex/src/stream_fn.rs b/provider-openai-codex/src/stream_fn.rs index 0a94f1b17..2f799725c 100644 --- a/provider-openai-codex/src/stream_fn.rs +++ b/provider-openai-codex/src/stream_fn.rs @@ -92,17 +92,17 @@ async fn fetch_fresh_credential(iii: &IIIClient) -> Option { .ok() .flatten() { - if near_expiry(&cred) { - if matches!( + if near_expiry(&cred) + && matches!( router_client::refresh_if_available(iii, PROVIDER_ID).await, Ok(true) - ) { - return router_client::get_token_if_available(iii, PROVIDER_ID) - .await - .ok() - .flatten() - .or(Some(cred)); - } + ) + { + return router_client::get_token_if_available(iii, PROVIDER_ID) + .await + .ok() + .flatten() + .or(Some(cred)); } return Some(cred); } diff --git a/provider-openai/Cargo.lock b/provider-openai/Cargo.lock index c5d7e516f..9981b5a08 100644 --- a/provider-openai/Cargo.lock +++ b/provider-openai/Cargo.lock @@ -776,7 +776,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.5" +version = "1.0.6" dependencies = [ "async-trait", "clap", diff --git a/provider-xai/Cargo.lock b/provider-xai/Cargo.lock index 2a991938c..19f0b31c7 100644 --- a/provider-xai/Cargo.lock +++ b/provider-xai/Cargo.lock @@ -776,7 +776,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.2" +version = "1.0.6" dependencies = [ "async-trait", "clap", diff --git a/provider-zai/Cargo.lock b/provider-zai/Cargo.lock index dc0ab926e..cd1746b5d 100644 --- a/provider-zai/Cargo.lock +++ b/provider-zai/Cargo.lock @@ -776,7 +776,7 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "llm-router" -version = "1.0.4" +version = "1.0.6" dependencies = [ "async-trait", "clap",