cargo fmt

This commit is contained in:
2026-04-27 22:51:07 +09:00
parent bcaa4645f7
commit 7a0ed7d744
62 changed files with 485 additions and 527 deletions
+8 -10
View File
@@ -53,9 +53,7 @@ pub enum ResolveError {
MalformedRef(String),
#[error("model.ref points to unknown provider `{0}`")]
UnknownProvider(String),
#[error(
"model.ref omitted; manifest must specify scheme, model_id, and auth (missing: {0})"
)]
#[error("model.ref omitted; manifest must specify scheme, model_id, and auth (missing: {0})")]
InlineMissing(&'static str),
}
@@ -259,8 +257,8 @@ pub fn resolve_with_catalogs(
models: &[ModelEntry],
) -> Result<ModelConfig, ResolveError> {
if let Some(ref_str) = &manifest.ref_ {
let (provider_id, ref_model_id) = split_ref(ref_str)
.ok_or_else(|| ResolveError::MalformedRef(ref_str.clone()))?;
let (provider_id, ref_model_id) =
split_ref(ref_str).ok_or_else(|| ResolveError::MalformedRef(ref_str.clone()))?;
let provider = providers
.iter()
.find(|p| p.id == provider_id)
@@ -371,10 +369,7 @@ mod tests {
let cfg = resolve_with_catalogs(&manifest, &providers, &models).unwrap();
assert_eq!(cfg.scheme, SchemeKind::Anthropic);
assert_eq!(cfg.model_id, "claude-sonnet-4-6");
assert_eq!(
cfg.base_url.as_deref(),
Some("https://api.anthropic.com")
);
assert_eq!(cfg.base_url.as_deref(), Some("https://api.anthropic.com"));
match cfg.auth {
AuthRef::ApiKey { env, file } => {
assert_eq!(env.as_deref(), Some("INSOMNIA_API_KEY_ANTHROPIC"));
@@ -382,7 +377,10 @@ mod tests {
}
_ => panic!("expected ApiKey auth from provider hint"),
}
assert!(cfg.capability.is_some(), "should fall back to provider.default_capability");
assert!(
cfg.capability.is_some(),
"should fall back to provider.default_capability"
);
}
#[test]
+21 -11
View File
@@ -44,7 +44,9 @@ impl AuthSnapshot {
let refresh_token = tokens
.get("refresh_token")
.and_then(Value::as_str)
.ok_or_else(|| CodexAuthError::MalformedAuthJson("missing tokens.refresh_token".into()))?
.ok_or_else(|| {
CodexAuthError::MalformedAuthJson("missing tokens.refresh_token".into())
})?
.to_string();
let id_token = tokens
@@ -58,9 +60,7 @@ impl AuthSnapshot {
.get("account_id")
.and_then(Value::as_str)
.map(str::to_string)
.or_else(|| {
super::jwt::parse_chatgpt_claims(&id_token).and_then(|c| c.account_id)
})
.or_else(|| super::jwt::parse_chatgpt_claims(&id_token).and_then(|c| c.account_id))
.ok_or_else(|| {
CodexAuthError::MalformedAuthJson(
"missing account_id in both tokens and id_token claims".into(),
@@ -131,7 +131,10 @@ pub async fn persist_refreshed(
}
raw.as_object_mut()
.ok_or_else(|| CodexAuthError::MalformedAuthJson("auth.json not an object".into()))?
.insert("last_refresh".into(), Value::String(Utc::now().to_rfc3339()));
.insert(
"last_refresh".into(),
Value::String(Utc::now().to_rfc3339()),
);
write_atomic(path, raw)?;
AuthSnapshot::from_value(raw.clone())
@@ -139,9 +142,8 @@ pub async fn persist_refreshed(
fn write_atomic(path: &Path, value: &Value) -> Result<(), CodexAuthError> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).map_err(|e| {
CodexAuthError::Io(format!("create_dir_all {}: {e}", parent.display()))
})?;
std::fs::create_dir_all(parent)
.map_err(|e| CodexAuthError::Io(format!("create_dir_all {}: {e}", parent.display())))?;
}
let json = serde_json::to_vec_pretty(value)
.map_err(|e| CodexAuthError::Io(format!("serialize: {e}")))?;
@@ -203,7 +205,10 @@ mod tests {
assert_eq!(snap.account_id, "acc-1");
assert!(snap.last_refresh.is_some());
// 未知フィールドが raw に保持されている
assert_eq!(snap.raw.get("OPENAI_API_KEY").and_then(Value::as_str), Some("sk-extra"));
assert_eq!(
snap.raw.get("OPENAI_API_KEY").and_then(Value::as_str),
Some("sk-extra")
);
}
#[tokio::test]
@@ -238,7 +243,10 @@ mod tests {
"agent_identity":{"workspace_id":"w","agent_runtime_id":"r","agent_private_key":"k","registered_at":"x"}
}"#,
);
let updated = persist_refreshed(&path, None, Some("new-acc".into()), Some("new-ref".into())).await.unwrap();
let updated =
persist_refreshed(&path, None, Some("new-acc".into()), Some("new-ref".into()))
.await
.unwrap();
assert_eq!(updated.access_token, "new-acc");
assert_eq!(updated.refresh_token, "new-ref");
// 未知フィールド agent_identity が保たれる
@@ -258,7 +266,9 @@ mod tests {
);
// 既存ファイルを 644 に変えてから persist → 600 に直るか
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o644)).unwrap();
persist_refreshed(&path, None, Some("a2".into()), None).await.unwrap();
persist_refreshed(&path, None, Some("a2".into()), None)
.await
.unwrap();
let mode = std::fs::metadata(&path).unwrap().permissions().mode() & 0o777;
assert_eq!(mode, 0o600);
}
+27 -15
View File
@@ -23,10 +23,7 @@ use std::sync::Arc;
use async_trait::async_trait;
use chrono::{Duration, Utc};
use llm_worker::llm_client::{
ClientError,
auth::AuthProvider,
};
use llm_worker::llm_client::{ClientError, auth::AuthProvider};
use reqwest::header::{HeaderName, HeaderValue};
use tokio::sync::Mutex;
@@ -66,8 +63,8 @@ impl CodexAuthProvider {
let codex_home = if let Ok(p) = std::env::var("CODEX_HOME") {
PathBuf::from(p)
} else {
let home = std::env::var("HOME")
.map_err(|_| ClientError::Config("HOME not set".into()))?;
let home =
std::env::var("HOME").map_err(|_| ClientError::Config("HOME not set".into()))?;
PathBuf::from(home).join(".codex")
};
Ok(Self::new(codex_home))
@@ -142,7 +139,9 @@ impl CodexAuthProvider {
Ok(new_snap)
}
fn build_headers(snap: &AuthSnapshot) -> Result<Vec<(HeaderName, HeaderValue)>, CodexAuthError> {
fn build_headers(
snap: &AuthSnapshot,
) -> Result<Vec<(HeaderName, HeaderValue)>, CodexAuthError> {
let mut out = Vec::with_capacity(5);
let auth_val = HeaderValue::from_str(&format!("Bearer {}", snap.access_token))
@@ -151,10 +150,7 @@ impl CodexAuthProvider {
let acc_val = HeaderValue::from_str(&snap.account_id)
.map_err(|e| CodexAuthError::InvalidHeader(format!("ChatGPT-Account-Id: {e}")))?;
out.push((
HeaderName::from_static("chatgpt-account-id"),
acc_val,
));
out.push((HeaderName::from_static("chatgpt-account-id"), acc_val));
// Cloudflare WAF は ChatGPT backend アクセス元を `originator` /
// `User-Agent` で識別する。Codex CLI が送る固定値を流用しないと
@@ -186,7 +182,10 @@ impl CodexAuthProvider {
#[async_trait]
impl AuthProvider for CodexAuthProvider {
async fn headers(&self) -> Result<Vec<(HeaderName, HeaderValue)>, ClientError> {
let snap = self.ensure_fresh().await.map_err(CodexAuthError::to_client_error)?;
let snap = self
.ensure_fresh()
.await
.map_err(CodexAuthError::to_client_error)?;
Self::build_headers(&snap).map_err(CodexAuthError::to_client_error)
}
}
@@ -247,7 +246,10 @@ mod tests {
let provider = CodexAuthProvider::new(dir.path().to_path_buf());
let headers = provider.headers().await.unwrap();
let names: Vec<_> = headers.iter().map(|(n, _)| n.as_str().to_string()).collect();
let names: Vec<_> = headers
.iter()
.map(|(n, _)| n.as_str().to_string())
.collect();
assert!(names.contains(&"authorization".to_string()));
assert!(names.contains(&"chatgpt-account-id".to_string()));
assert!(!names.contains(&"x-openai-fedramp".to_string()));
@@ -276,7 +278,12 @@ mod tests {
#[tokio::test]
async fn refreshes_when_expired_and_persists() {
let dir = tempfile::tempdir().unwrap();
let path = write_auth(dir.path(), Utc::now().timestamp() - 60, false, "old-refresh");
let path = write_auth(
dir.path(),
Utc::now().timestamp() - 60,
false,
"old-refresh",
);
// refresh エンドポイントを mock。新しい JWT (将来 exp) を返す
let server = MockServer::start().await;
@@ -315,7 +322,12 @@ mod tests {
#[tokio::test]
async fn permanent_refresh_failure_surfaces_login_message() {
let dir = tempfile::tempdir().unwrap();
write_auth(dir.path(), Utc::now().timestamp() - 60, false, "bad-refresh");
write_auth(
dir.path(),
Utc::now().timestamp() - 60,
false,
"bad-refresh",
);
let server = MockServer::start().await;
Mock::given(method("POST"))
+4 -1
View File
@@ -97,7 +97,10 @@ fn extract_error_code(body: &str) -> Option<String> {
return Some(s.to_string());
}
}
value.get("code").and_then(|v| v.as_str()).map(str::to_string)
value
.get("code")
.and_then(|v| v.as_str())
.map(str::to_string)
}
#[cfg(test)]
+2 -7
View File
@@ -58,10 +58,7 @@ pub enum ProviderError {
/// 1. `AuthRef::ApiKey { env, .. }` で env が指定されていればその変数を参照
/// 2. そうでなければ scheme 既定の環境変数 (`SchemeKind::default_env_var`)
/// 3. それでも無ければ `file` を読む(絶対パスのみ)
fn resolve_auth(
scheme: SchemeKind,
auth: &AuthRef,
) -> Result<ResolvedAuth, ProviderError> {
fn resolve_auth(scheme: SchemeKind, auth: &AuthRef) -> Result<ResolvedAuth, ProviderError> {
match auth {
AuthRef::None => Ok(ResolvedAuth::None),
AuthRef::ApiKey { env, file } => {
@@ -161,9 +158,7 @@ pub fn build_client(manifest: &ModelManifest) -> Result<Box<dyn LlmClient>, Prov
/// `ModelManifest` から既に `catalog::resolve_model_manifest` を通した
/// ケース(factory / spawn 経路でカタログ引きを 1 回だけにしたい等)で
/// 使う。
pub fn build_client_from_config(
config: &ModelConfig,
) -> Result<Box<dyn LlmClient>, ProviderError> {
pub fn build_client_from_config(config: &ModelConfig) -> Result<Box<dyn LlmClient>, ProviderError> {
build_from_config(config)
}