mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
Normalize canonical API formats
This commit is contained in:
@@ -524,7 +524,7 @@ async fn gateway_handles_admin_api_keys_update_locally_with_trusted_admin_princi
|
||||
"rate_limit": null,
|
||||
"concurrent_limit": 12,
|
||||
"allowed_providers": ["gemini"],
|
||||
"allowed_api_formats": ["gemini:chat"],
|
||||
"allowed_api_formats": ["gemini:generate_content"],
|
||||
"allowed_models": ["gemini-2.5-pro"],
|
||||
"expires_at": "2030-03-04",
|
||||
"auto_delete_on_expiry": true,
|
||||
@@ -541,7 +541,10 @@ async fn gateway_handles_admin_api_keys_update_locally_with_trusted_admin_princi
|
||||
assert_eq!(payload["rate_limit"], serde_json::Value::Null);
|
||||
assert_eq!(payload["concurrent_limit"], json!(12));
|
||||
assert_eq!(payload["allowed_providers"], json!(["gemini"]));
|
||||
assert_eq!(payload["allowed_api_formats"], json!(["gemini:chat"]));
|
||||
assert_eq!(
|
||||
payload["allowed_api_formats"],
|
||||
json!(["gemini:generate_content"])
|
||||
);
|
||||
assert_eq!(payload["allowed_models"], json!(["gemini-2.5-pro"]));
|
||||
assert_eq!(payload["auto_delete_on_expiry"], json!(true));
|
||||
assert_eq!(payload["wallet"]["limit_mode"], json!("unlimited"));
|
||||
|
||||
@@ -469,7 +469,7 @@ async fn gateway_exports_admin_provider_key_locally_with_trusted_admin_principal
|
||||
let mut key = sample_key(
|
||||
"key-kiro-a",
|
||||
"provider-kiro",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"oauth-access-token",
|
||||
);
|
||||
key.auth_type = "oauth".to_string();
|
||||
@@ -1569,7 +1569,12 @@ async fn gateway_handles_admin_keys_grouped_by_format_locally_with_trusted_admin
|
||||
key_a.health_by_format = Some(json!({"openai:chat": {"health_score": 0.8}}));
|
||||
key_a.circuit_breaker_by_format = Some(json!({"openai:chat": {"open": false}}));
|
||||
|
||||
let mut key_b = sample_key("key-claude-a", "provider-claude", "claude:chat", "sk-ant-a");
|
||||
let mut key_b = sample_key(
|
||||
"key-claude-a",
|
||||
"provider-claude",
|
||||
"claude:messages",
|
||||
"sk-ant-a",
|
||||
);
|
||||
key_b.internal_priority = 20;
|
||||
key_b.request_count = Some(2);
|
||||
key_b.success_count = Some(1);
|
||||
@@ -1592,7 +1597,7 @@ async fn gateway_handles_admin_keys_grouped_by_format_locally_with_trusted_admin
|
||||
sample_endpoint(
|
||||
"endpoint-claude-chat",
|
||||
"provider-claude",
|
||||
"claude:chat",
|
||||
"claude:messages",
|
||||
"https://api.claude.example",
|
||||
),
|
||||
],
|
||||
@@ -1633,7 +1638,7 @@ async fn gateway_handles_admin_keys_grouped_by_format_locally_with_trusted_admin
|
||||
"https://api.openai.example"
|
||||
);
|
||||
assert_eq!(payload["openai:chat"][0]["capabilities"], json!(["1h缓存"]));
|
||||
assert_eq!(payload["claude:chat"][0]["provider_active"], false);
|
||||
assert_eq!(payload["claude:messages"][0]["provider_active"], false);
|
||||
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
|
||||
|
||||
gateway_handle.abort();
|
||||
|
||||
@@ -472,7 +472,7 @@ async fn gateway_refreshes_admin_provider_quota_locally_for_kiro_with_trusted_ad
|
||||
)
|
||||
.expect("key should build")
|
||||
.with_transport_fields(
|
||||
Some(json!(["claude:cli"])),
|
||||
Some(json!(["claude:messages"])),
|
||||
encrypted_api_key,
|
||||
Some(encrypted_auth_config),
|
||||
None,
|
||||
@@ -495,7 +495,7 @@ async fn gateway_refreshes_admin_provider_quota_locally_for_kiro_with_trusted_ad
|
||||
vec![sample_endpoint(
|
||||
"endpoint-kiro-cli",
|
||||
"provider-kiro",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"https://q.us-west-2.amazonaws.com",
|
||||
)],
|
||||
vec![key],
|
||||
@@ -830,7 +830,7 @@ async fn gateway_refreshes_admin_provider_quota_locally_for_antigravity_with_tru
|
||||
)
|
||||
.expect("key should build")
|
||||
.with_transport_fields(
|
||||
Some(json!(["gemini:chat"])),
|
||||
Some(json!(["gemini:generate_content"])),
|
||||
encrypt_python_fernet_plaintext(DEVELOPMENT_ENCRYPTION_KEY, "ya29.ant-token")
|
||||
.expect("api key ciphertext should build"),
|
||||
Some(encrypted_auth_config),
|
||||
@@ -854,7 +854,7 @@ async fn gateway_refreshes_admin_provider_quota_locally_for_antigravity_with_tru
|
||||
vec![sample_endpoint(
|
||||
"endpoint-antigravity-chat",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"https://daily-cloudcode-pa.googleapis.com",
|
||||
)],
|
||||
vec![key],
|
||||
|
||||
@@ -53,7 +53,7 @@ fn sample_admin_gemini_endpoint() -> StoredProviderCatalogEndpoint {
|
||||
StoredProviderCatalogEndpoint::new(
|
||||
"endpoint-gemini-admin-1".to_string(),
|
||||
"provider-gemini-admin-1".to_string(),
|
||||
"gemini:chat".to_string(),
|
||||
"gemini:generate_content".to_string(),
|
||||
Some("gemini".to_string()),
|
||||
Some("chat".to_string()),
|
||||
true,
|
||||
@@ -83,12 +83,12 @@ fn sample_admin_gemini_key(id: &str, name: &str, secret: &str) -> StoredProvider
|
||||
)
|
||||
.expect("key should build")
|
||||
.with_transport_fields(
|
||||
Some(json!(["gemini:chat"])),
|
||||
Some(json!(["gemini:generate_content"])),
|
||||
encrypt_python_fernet_plaintext(DEVELOPMENT_ENCRYPTION_KEY, secret)
|
||||
.expect("api key should encrypt"),
|
||||
None,
|
||||
None,
|
||||
Some(json!({"gemini:chat": 1})),
|
||||
Some(json!({"gemini:generate_content": 1})),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
|
||||
@@ -885,7 +885,7 @@ async fn gateway_handles_admin_pool_list_keys_with_quota_compatibility_fields()
|
||||
let mut key = sample_key(
|
||||
"key-antigravity-a",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"sk-antigravity",
|
||||
);
|
||||
key.name = "quota-key".to_string();
|
||||
@@ -1008,7 +1008,7 @@ async fn gateway_includes_pool_quota_and_compat_fields_in_list_keys_response() {
|
||||
let mut key = sample_key(
|
||||
"key-antigravity-oauth",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"oauth-placeholder",
|
||||
);
|
||||
key.name = "quota key".to_string();
|
||||
@@ -1133,7 +1133,7 @@ async fn gateway_prefers_status_snapshot_antigravity_quota_over_stale_metadata()
|
||||
let mut key = sample_key(
|
||||
"key-antigravity-snapshot-fresh",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"oauth-placeholder",
|
||||
);
|
||||
key.name = "antigravity snapshot fresh".to_string();
|
||||
@@ -1248,7 +1248,7 @@ async fn gateway_renders_gemini_cli_account_quota_from_status_snapshot() {
|
||||
let mut key = sample_key(
|
||||
"key-gemini-cli-snapshot",
|
||||
"provider-gemini-cli",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"oauth-placeholder",
|
||||
);
|
||||
key.name = "gemini cli snapshot".to_string();
|
||||
@@ -1700,7 +1700,7 @@ async fn gateway_marks_exhausted_kiro_pool_key_as_blocked_when_flag_enabled() {
|
||||
let mut key = sample_key(
|
||||
"key-kiro-exhausted",
|
||||
"provider-kiro",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"oauth-placeholder",
|
||||
);
|
||||
key.name = "kiro exhausted".to_string();
|
||||
@@ -1773,7 +1773,7 @@ async fn gateway_prefers_status_snapshot_kiro_quota_over_stale_metadata() {
|
||||
let mut key = sample_key(
|
||||
"key-kiro-snapshot-fresh",
|
||||
"provider-kiro",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"oauth-placeholder",
|
||||
);
|
||||
key.name = "kiro snapshot fresh".to_string();
|
||||
|
||||
@@ -980,7 +980,7 @@ async fn gateway_handles_admin_provider_query_test_model_for_kiro_locally() {
|
||||
assert_eq!(plan.provider_id, "provider-kiro");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-kiro-cli");
|
||||
assert_eq!(plan.key_id, "key-kiro-primary");
|
||||
assert_eq!(plan.provider_api_format, "claude:cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:messages");
|
||||
assert_eq!(plan.model_name.as_deref(), Some("claude-sonnet-4-upstream"));
|
||||
Json(json!({
|
||||
"request_id": plan.request_id,
|
||||
@@ -1011,7 +1011,7 @@ async fn gateway_handles_admin_provider_query_test_model_for_kiro_locally() {
|
||||
let mut key = sample_key(
|
||||
"key-kiro-primary",
|
||||
"provider-kiro",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"__placeholder__",
|
||||
);
|
||||
key.auth_type = "oauth".to_string();
|
||||
@@ -1038,9 +1038,9 @@ async fn gateway_handles_admin_provider_query_test_model_for_kiro_locally() {
|
||||
vec![StoredProviderCatalogEndpoint::new(
|
||||
"endpoint-kiro-cli".to_string(),
|
||||
"provider-kiro".to_string(),
|
||||
"claude:cli".to_string(),
|
||||
"claude:messages".to_string(),
|
||||
Some("claude".to_string()),
|
||||
Some("cli".to_string()),
|
||||
Some("messages".to_string()),
|
||||
true,
|
||||
)
|
||||
.expect("endpoint should build")
|
||||
@@ -1076,7 +1076,7 @@ async fn gateway_handles_admin_provider_query_test_model_for_kiro_locally() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-kiro",
|
||||
"model_name": "claude-sonnet-4-upstream",
|
||||
"api_format": "claude:cli"
|
||||
"api_format": "claude:messages"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -1148,7 +1148,7 @@ async fn gateway_handles_admin_provider_query_test_model_failover_for_kiro_local
|
||||
let mut provider = sample_provider("provider-kiro", "Kiro", 10);
|
||||
provider.provider_type = "kiro".to_string();
|
||||
let build_key = |id: &str| {
|
||||
let mut key = sample_key(id, "provider-kiro", "claude:cli", "__placeholder__");
|
||||
let mut key = sample_key(id, "provider-kiro", "claude:messages", "__placeholder__");
|
||||
key.auth_type = "oauth".to_string();
|
||||
key.encrypted_auth_config = Some(
|
||||
aether_crypto::encrypt_python_fernet_plaintext(
|
||||
@@ -1175,9 +1175,9 @@ async fn gateway_handles_admin_provider_query_test_model_failover_for_kiro_local
|
||||
vec![StoredProviderCatalogEndpoint::new(
|
||||
"endpoint-kiro-cli".to_string(),
|
||||
"provider-kiro".to_string(),
|
||||
"claude:cli".to_string(),
|
||||
"claude:messages".to_string(),
|
||||
Some("claude".to_string()),
|
||||
Some("cli".to_string()),
|
||||
Some("messages".to_string()),
|
||||
true,
|
||||
)
|
||||
.expect("endpoint should build")
|
||||
@@ -1217,7 +1217,7 @@ async fn gateway_handles_admin_provider_query_test_model_failover_for_kiro_local
|
||||
"mode": "direct",
|
||||
"model_name": "claude-sonnet-4-upstream",
|
||||
"failover_models": ["claude-sonnet-4-upstream"],
|
||||
"api_format": "claude:cli",
|
||||
"api_format": "claude:messages",
|
||||
"request_id": "provider-test-kiro"
|
||||
}))
|
||||
.send()
|
||||
@@ -1295,7 +1295,7 @@ async fn gateway_retries_kiro_failover_after_http_error_without_message() {
|
||||
let mut provider = sample_provider("provider-kiro", "Kiro", 10);
|
||||
provider.provider_type = "kiro".to_string();
|
||||
let build_key = |id: &str| {
|
||||
let mut key = sample_key(id, "provider-kiro", "claude:cli", "__placeholder__");
|
||||
let mut key = sample_key(id, "provider-kiro", "claude:messages", "__placeholder__");
|
||||
key.auth_type = "oauth".to_string();
|
||||
key.encrypted_auth_config = Some(
|
||||
aether_crypto::encrypt_python_fernet_plaintext(
|
||||
@@ -1322,9 +1322,9 @@ async fn gateway_retries_kiro_failover_after_http_error_without_message() {
|
||||
vec![StoredProviderCatalogEndpoint::new(
|
||||
"endpoint-kiro-cli".to_string(),
|
||||
"provider-kiro".to_string(),
|
||||
"claude:cli".to_string(),
|
||||
"claude:messages".to_string(),
|
||||
Some("claude".to_string()),
|
||||
Some("cli".to_string()),
|
||||
Some("messages".to_string()),
|
||||
true,
|
||||
)
|
||||
.expect("endpoint should build")
|
||||
@@ -1364,7 +1364,7 @@ async fn gateway_retries_kiro_failover_after_http_error_without_message() {
|
||||
"mode": "direct",
|
||||
"model_name": "claude-sonnet-4-upstream",
|
||||
"failover_models": ["claude-sonnet-4-upstream"],
|
||||
"api_format": "claude:cli",
|
||||
"api_format": "claude:messages",
|
||||
"request_id": "provider-test-kiro-empty-error"
|
||||
}))
|
||||
.send()
|
||||
@@ -1677,13 +1677,13 @@ async fn gateway_returns_stub_for_transport_unsupported_non_kiro_provider() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-antigravity-gemini",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"https://cloudcode-pa.googleapis.com",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-antigravity-gemini",
|
||||
"provider-antigravity",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"sk-test-antigravity",
|
||||
)],
|
||||
));
|
||||
@@ -1707,7 +1707,7 @@ async fn gateway_returns_stub_for_transport_unsupported_non_kiro_provider() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-antigravity",
|
||||
"model": "gemini-2.5-pro",
|
||||
"api_format": "gemini:chat"
|
||||
"api_format": "gemini:generate_content"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -1969,7 +1969,7 @@ async fn gateway_prefers_supported_non_kiro_endpoint_with_compatible_key_when_ap
|
||||
sample_endpoint(
|
||||
"endpoint-gemini-chat",
|
||||
"provider-openai",
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"https://api.gemini.example",
|
||||
),
|
||||
sample_endpoint(
|
||||
@@ -2315,7 +2315,7 @@ async fn gateway_handles_claude_cli_test_model_locally() {
|
||||
assert_eq!(plan.provider_id, "provider-claude");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-claude-cli");
|
||||
assert_eq!(plan.key_id, "key-claude-cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:messages");
|
||||
assert_eq!(plan.url, "https://api.anthropic.example/v1/messages");
|
||||
assert_eq!(plan.model_name.as_deref(), Some("claude-sonnet-4-5"));
|
||||
Json(json!({
|
||||
@@ -2351,13 +2351,13 @@ async fn gateway_handles_claude_cli_test_model_locally() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"https://api.anthropic.example",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"sk-test-claude-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2380,7 +2380,7 @@ async fn gateway_handles_claude_cli_test_model_locally() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-claude",
|
||||
"model": "claude-sonnet-4-5",
|
||||
"api_format": "claude:cli"
|
||||
"api_format": "claude:messages"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -2404,7 +2404,7 @@ async fn gateway_uses_compatible_claude_cli_endpoint_when_api_format_is_omitted(
|
||||
"/v1/execute/sync",
|
||||
any(move |Json(plan): Json<ExecutionPlan>| async move {
|
||||
assert_eq!(plan.endpoint_id, "endpoint-claude-cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:messages");
|
||||
assert_eq!(plan.key_id, "key-claude-cli");
|
||||
Json(json!({
|
||||
"request_id": plan.request_id,
|
||||
@@ -2439,13 +2439,13 @@ async fn gateway_uses_compatible_claude_cli_endpoint_when_api_format_is_omitted(
|
||||
vec![sample_endpoint(
|
||||
"endpoint-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"https://api.anthropic.example",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"sk-test-claude-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2493,7 +2493,7 @@ async fn gateway_handles_claude_cli_test_model_failover_locally() {
|
||||
assert_eq!(plan.provider_id, "provider-claude");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-claude-cli");
|
||||
assert_eq!(plan.key_id, "key-claude-cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:cli");
|
||||
assert_eq!(plan.provider_api_format, "claude:messages");
|
||||
assert_eq!(plan.model_name.as_deref(), Some("claude-sonnet-4-5"));
|
||||
Json(json!({
|
||||
"request_id": plan.request_id,
|
||||
@@ -2528,13 +2528,13 @@ async fn gateway_handles_claude_cli_test_model_failover_locally() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"https://api.anthropic.example",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-claude-cli",
|
||||
"provider-claude",
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"sk-test-claude-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2559,7 +2559,7 @@ async fn gateway_handles_claude_cli_test_model_failover_locally() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-claude",
|
||||
"failover_models": ["claude-sonnet-4-5"],
|
||||
"api_format": "claude:cli"
|
||||
"api_format": "claude:messages"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -2586,7 +2586,7 @@ async fn gateway_handles_gemini_cli_test_model_locally() {
|
||||
assert_eq!(plan.provider_id, "provider-gemini");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-gemini-cli");
|
||||
assert_eq!(plan.key_id, "key-gemini-cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:generate_content");
|
||||
assert_eq!(
|
||||
plan.url,
|
||||
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent"
|
||||
@@ -2625,13 +2625,13 @@ async fn gateway_handles_gemini_cli_test_model_locally() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"https://generativelanguage.googleapis.com",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"sk-test-gemini-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2654,7 +2654,7 @@ async fn gateway_handles_gemini_cli_test_model_locally() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-gemini",
|
||||
"model": "gemini-2.5-pro",
|
||||
"api_format": "gemini:cli"
|
||||
"api_format": "gemini:generate_content"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -2680,7 +2680,7 @@ async fn gateway_handles_gemini_cli_test_model_with_oauth_header_fallback() {
|
||||
assert_eq!(plan.provider_id, "provider-gemini");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-gemini-cli");
|
||||
assert_eq!(plan.key_id, "key-gemini-cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:generate_content");
|
||||
assert_eq!(
|
||||
plan.url,
|
||||
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent"
|
||||
@@ -2721,7 +2721,7 @@ async fn gateway_handles_gemini_cli_test_model_with_oauth_header_fallback() {
|
||||
let mut key = sample_key(
|
||||
"key-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"cached-gemini-cli-token",
|
||||
);
|
||||
key.auth_type = "oauth".to_string();
|
||||
@@ -2737,7 +2737,7 @@ async fn gateway_handles_gemini_cli_test_model_with_oauth_header_fallback() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"https://generativelanguage.googleapis.com",
|
||||
)],
|
||||
vec![key],
|
||||
@@ -2761,7 +2761,7 @@ async fn gateway_handles_gemini_cli_test_model_with_oauth_header_fallback() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-gemini",
|
||||
"model": "gemini-2.5-pro",
|
||||
"api_format": "gemini:cli"
|
||||
"api_format": "gemini:generate_content"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
@@ -2785,7 +2785,7 @@ async fn gateway_uses_compatible_gemini_cli_endpoint_when_api_format_is_omitted(
|
||||
"/v1/execute/sync",
|
||||
any(move |Json(plan): Json<ExecutionPlan>| async move {
|
||||
assert_eq!(plan.endpoint_id, "endpoint-gemini-cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:generate_content");
|
||||
assert_eq!(plan.key_id, "key-gemini-cli");
|
||||
Json(json!({
|
||||
"request_id": plan.request_id,
|
||||
@@ -2820,13 +2820,13 @@ async fn gateway_uses_compatible_gemini_cli_endpoint_when_api_format_is_omitted(
|
||||
vec![sample_endpoint(
|
||||
"endpoint-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"https://generativelanguage.googleapis.com",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"sk-test-gemini-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2874,7 +2874,7 @@ async fn gateway_handles_gemini_cli_test_model_failover_locally() {
|
||||
assert_eq!(plan.provider_id, "provider-gemini");
|
||||
assert_eq!(plan.endpoint_id, "endpoint-gemini-cli");
|
||||
assert_eq!(plan.key_id, "key-gemini-cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:cli");
|
||||
assert_eq!(plan.provider_api_format, "gemini:generate_content");
|
||||
assert_eq!(plan.model_name.as_deref(), Some("gemini-2.5-pro"));
|
||||
Json(json!({
|
||||
"request_id": plan.request_id,
|
||||
@@ -2909,13 +2909,13 @@ async fn gateway_handles_gemini_cli_test_model_failover_locally() {
|
||||
vec![sample_endpoint(
|
||||
"endpoint-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"https://generativelanguage.googleapis.com",
|
||||
)],
|
||||
vec![sample_key(
|
||||
"key-gemini-cli",
|
||||
"provider-gemini",
|
||||
"gemini:cli",
|
||||
"gemini:generate_content",
|
||||
"sk-test-gemini-cli",
|
||||
)],
|
||||
));
|
||||
@@ -2940,7 +2940,7 @@ async fn gateway_handles_gemini_cli_test_model_failover_locally() {
|
||||
.json(&json!({
|
||||
"provider_id": "provider-gemini",
|
||||
"failover_models": ["gemini-2.5-pro"],
|
||||
"api_format": "gemini:cli"
|
||||
"api_format": "gemini:generate_content"
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
|
||||
@@ -585,7 +585,7 @@ async fn gateway_handles_admin_providers_summary_list_locally_with_trusted_admin
|
||||
sample_endpoint(
|
||||
"endpoint-anthropic-chat",
|
||||
"provider-anthropic",
|
||||
"claude:chat",
|
||||
"claude:messages",
|
||||
"https://api.anthropic.example",
|
||||
),
|
||||
],
|
||||
|
||||
@@ -482,9 +482,9 @@ async fn gateway_handles_admin_usage_aggregation_stats_locally_with_trusted_admi
|
||||
);
|
||||
usage_3.provider_id = Some("provider-anthropic".to_string());
|
||||
usage_3.total_tokens = usage_3.input_tokens;
|
||||
usage_3.api_format = Some("claude:cli".to_string());
|
||||
usage_3.api_format = Some("claude:messages".to_string());
|
||||
usage_3.api_family = Some("claude".to_string());
|
||||
usage_3.endpoint_api_format = Some("claude:cli".to_string());
|
||||
usage_3.endpoint_api_format = Some("claude:messages".to_string());
|
||||
usage_3.provider_api_family = Some("claude".to_string());
|
||||
|
||||
let usage_repository = Arc::new(InMemoryUsageReadRepository::seed(vec![
|
||||
@@ -558,7 +558,7 @@ async fn gateway_handles_admin_usage_aggregation_stats_locally_with_trusted_admi
|
||||
assert_eq!(api_format_items.len(), 2);
|
||||
assert_eq!(api_format_items[0]["api_format"], "openai:chat");
|
||||
assert_eq!(api_format_items[0]["output_tokens"], 40);
|
||||
assert_eq!(api_format_items[1]["api_format"], "claude:cli");
|
||||
assert_eq!(api_format_items[1]["api_format"], "claude:messages");
|
||||
assert_eq!(api_format_items[1]["output_tokens"], 20);
|
||||
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ async fn gateway_handles_admin_user_detail_routes_locally_with_trusted_admin_pri
|
||||
"username": "alice_updated",
|
||||
"role": "admin",
|
||||
"allowed_providers": ["openai", "anthropic"],
|
||||
"allowed_api_formats": ["openai:chat", "gemini:chat"],
|
||||
"allowed_api_formats": ["openai:chat", "gemini:generate_content"],
|
||||
"allowed_models": ["gpt-4.1", "gemini-2.5-pro"],
|
||||
"rate_limit": 120,
|
||||
"is_active": false,
|
||||
|
||||
@@ -501,7 +501,7 @@ async fn gateway_locally_denies_disallowed_claude_api_format_without_hitting_con
|
||||
assert_eq!(payload["error"]["type"], "http_error");
|
||||
assert_eq!(
|
||||
payload["error"]["message"],
|
||||
"当前密钥不允许访问 claude:chat 格式"
|
||||
"当前密钥不允许访问 claude:messages 格式"
|
||||
);
|
||||
assert_eq!(*auth_context_hits.lock().expect("mutex should lock"), 0);
|
||||
assert_eq!(*public_hits.lock().expect("mutex should lock"), 0);
|
||||
@@ -625,7 +625,7 @@ async fn gateway_locally_denies_disallowed_gemini_model_without_hitting_control_
|
||||
let mut snapshot = sample_currently_usable_auth_snapshot("key-gemini-123", "user-gemini-123");
|
||||
snapshot.api_key_allowed_providers = Some(vec!["gemini".to_string()]);
|
||||
snapshot.user_allowed_providers = Some(vec!["gemini".to_string()]);
|
||||
snapshot.api_key_allowed_api_formats = Some(vec!["gemini:chat".to_string()]);
|
||||
snapshot.api_key_allowed_api_formats = Some(vec!["gemini:generate_content".to_string()]);
|
||||
snapshot.api_key_allowed_models = Some(vec!["gemini-1.5-pro".to_string()]);
|
||||
let repository = Arc::new(InMemoryAuthApiKeySnapshotRepository::seed(vec![(
|
||||
Some(hash_api_key("gemini-client-key-123")),
|
||||
|
||||
Reference in New Issue
Block a user