Normalize endpoint API root handling

This commit is contained in:
fawney19
2026-05-29 02:29:33 +08:00
parent ef2953038e
commit b59c724455
46 changed files with 1179 additions and 205 deletions
@@ -3,6 +3,11 @@ use crate::handlers::admin::request::AdminGatewayProviderTransportSnapshot;
use serde_json::json;
fn sample_openai_image_transport(provider_type: &str) -> AdminGatewayProviderTransportSnapshot {
let base_url = if provider_type == "custom" {
"https://grok.com/v1/"
} else {
"https://grok.com/"
};
AdminGatewayProviderTransportSnapshot {
provider: crate::provider_transport::snapshot::GatewayProviderTransportProvider {
id: "provider-1".to_string(),
@@ -26,7 +31,7 @@ fn sample_openai_image_transport(provider_type: &str) -> AdminGatewayProviderTra
api_family: None,
endpoint_kind: None,
is_active: true,
base_url: "https://grok.com/".to_string(),
base_url: base_url.to_string(),
header_rules: None,
body_rules: None,
max_retries: None,
+3 -3
View File
@@ -271,7 +271,7 @@ async fn gateway_model_fetch_updates_key_and_syncs_provider_model_whitelist_asso
.clone()
.expect("execution runtime plan should be captured");
assert_eq!(seen_plan.method, "GET");
assert_eq!(seen_plan.url, "https://api.openai.example/v1/models");
assert_eq!(seen_plan.url, "https://api.openai.example/models");
assert_eq!(
seen_plan.headers.get("authorization").map(String::as_str),
Some("Bearer live-secret-api-key")
@@ -322,7 +322,7 @@ async fn gateway_model_fetch_updates_key_and_syncs_provider_model_whitelist_asso
let seen_upstream = Arc::new(Mutex::new(None::<SeenUpstreamRequest>));
let seen_upstream_clone = Arc::clone(&seen_upstream);
let upstream = Router::new().route(
"/v1/models",
"/models",
any(move |request: Request| {
let seen_upstream_inner = Arc::clone(&seen_upstream_clone);
async move {
@@ -538,7 +538,7 @@ async fn gateway_background_model_fetch_updates_key_and_syncs_provider_model_whi
.expect("mutex should lock")
.clone()
.expect("execution runtime plan should be captured");
assert_eq!(seen_plan.url, "https://api.openai.example/v1/models");
assert_eq!(seen_plan.url, "https://api.openai.example/models");
background_tasks.shutdown().await;
execution_runtime_handle.abort();
@@ -365,7 +365,7 @@ async fn gateway_executes_openai_chat_sync_upstream_stream_via_local_finalize_re
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![sample_provider_catalog_provider()],
vec![sample_provider_catalog_endpoint(
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_provider_catalog_key()],
));
@@ -126,7 +126,7 @@ fn sample_local_openai_endpoint() -> StoredProviderCatalogEndpoint {
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -348,7 +348,7 @@ async fn gateway_executes_openai_chat_stream_via_local_decision_gate_without_exe
let (upstream_url, upstream_handle) = start_server(upstream).await;
let (provider_url, provider_handle) = start_server(provider).await;
let mut primary_endpoint = sample_provider_catalog_endpoint();
primary_endpoint.base_url = provider_url.clone();
primary_endpoint.base_url = format!("{provider_url}/v1");
backup_endpoint.base_url = "http://127.0.0.1:9".to_string();
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![sample_provider_catalog_provider(), backup_provider],
@@ -2300,7 +2300,7 @@ async fn gateway_retries_next_local_openai_chat_stream_candidate_after_retryable
);
assert_eq!(
seen_execution_runtime_requests[0].url,
"https://api.openai.primary.example/v1/chat/completions"
"https://api.openai.primary.example/chat/completions"
);
assert_eq!(
seen_execution_runtime_requests[0].authorization,
@@ -2308,7 +2308,7 @@ async fn gateway_retries_next_local_openai_chat_stream_candidate_after_retryable
);
assert_eq!(
seen_execution_runtime_requests[1].url,
"https://api.openai.backup.example/v1/chat/completions"
"https://api.openai.backup.example/chat/completions"
);
assert_eq!(
seen_execution_runtime_requests[1].model,
@@ -1068,7 +1068,7 @@ async fn gateway_routes_openai_responses_stream_image_intent_to_openai_image_pla
"responses-stream-image-bridge",
"image-provider",
"custom",
"https://images.example.com",
"https://images.example.com/v1",
execution_runtime_url,
)
.await;
@@ -234,7 +234,7 @@ async fn ai_execute_stream_pii_redaction_round_trip() {
let seen_provider_request = Arc::new(Mutex::new(None::<SeenProviderStreamRequest>));
let seen_provider_request_clone = Arc::clone(&seen_provider_request);
let provider_app = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(move |request: Request| {
let seen_provider_request_inner = Arc::clone(&seen_provider_request_clone);
async move {
@@ -378,7 +378,7 @@ async fn gateway_skips_unsupported_local_openai_chat_sync_candidate_before_tryin
);
assert_eq!(
seen_execution_runtime_request.url,
"https://api.openai.backup.example/v1/chat/completions"
"https://api.openai.backup.example/chat/completions"
);
assert_eq!(
seen_execution_runtime_request.model,
@@ -1115,7 +1115,7 @@ async fn gateway_retries_next_local_openai_chat_sync_candidate_after_auth_failur
);
assert_eq!(
seen_execution_runtime_requests[0].url,
"https://api.openai.primary.example/v1/chat/completions"
"https://api.openai.primary.example/chat/completions"
);
assert_eq!(
seen_execution_runtime_requests[0].authorization,
@@ -1123,7 +1123,7 @@ async fn gateway_retries_next_local_openai_chat_sync_candidate_after_auth_failur
);
assert_eq!(
seen_execution_runtime_requests[1].url,
"https://api.openai.backup.example/v1/chat/completions"
"https://api.openai.backup.example/chat/completions"
);
assert_eq!(
seen_execution_runtime_requests[1].model,
@@ -233,7 +233,7 @@ async fn proxy_pii_redaction_local_openai_chat_runtime_masks_headers_and_restore
let seen_provider_request = Arc::new(Mutex::new(None::<SeenProviderRequest>));
let seen_provider_request_clone = Arc::clone(&seen_provider_request);
let provider_app = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(move |request: Request| {
let seen_provider_request_inner = Arc::clone(&seen_provider_request_clone);
async move {
@@ -491,7 +491,7 @@ async fn gateway_executes_openai_chat_sync_via_local_decision_gate_without_execu
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -669,7 +669,7 @@ async fn gateway_executes_openai_chat_sync_via_local_decision_gate_without_execu
let (upstream_url, upstream_handle) = start_server(upstream).await;
let (provider_url, provider_handle) = start_server(provider).await;
let mut primary_endpoint = sample_provider_catalog_endpoint();
primary_endpoint.base_url = provider_url.clone();
primary_endpoint.base_url = format!("{provider_url}/v1");
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
vec![sample_provider_catalog_provider(), backup_provider],
{
@@ -871,7 +871,7 @@ async fn gateway_executes_openai_chat_sync_with_regex_model_mapping_in_execution
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -308,7 +308,7 @@ async fn run_sync_redaction_case_with_system_config(
let seen_provider_request = Arc::new(Mutex::new(None::<SeenProviderRequest>));
let seen_provider_request_clone = Arc::clone(&seen_provider_request);
let provider_app = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(move |request: Request| {
let seen_provider_request_inner = Arc::clone(&seen_provider_request_clone);
async move {
@@ -631,7 +631,7 @@ async fn ai_execute_pii_redaction_restores_executed_candidate_session_after_late
let seen_provider_request = Arc::new(Mutex::new(None::<SeenProviderRequest>));
let seen_provider_request_clone = Arc::clone(&seen_provider_request);
let provider_app = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(move |request: Request| {
let seen_provider_request_inner = Arc::clone(&seen_provider_request_clone);
async move {
@@ -486,7 +486,7 @@ async fn gateway_converts_gemini_image_sync_to_openai_image_provider_impl() {
StoredProviderCatalogProvider::new(
"provider-openai-image-bridge-1".to_string(),
"openai".to_string(),
Some("https://api.openai.com".to_string()),
Some("https://api.openai.com/v1".to_string()),
"openai".to_string(),
)
.expect("provider should build")
@@ -514,7 +514,7 @@ async fn gateway_converts_gemini_image_sync_to_openai_image_provider_impl() {
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.com".to_string(),
"https://api.openai.com/v1".to_string(),
None,
None,
Some(2),
+3 -2
View File
@@ -540,7 +540,7 @@ async fn gateway_cancels_openai_video_task_via_internal_async_task_endpoint() {
"format_converted": false
},
"transport": {
"upstream_base_url": "https://api.openai.example",
"upstream_base_url": "https://api.openai.example/v1",
"provider_name": "openai-video",
"provider_id": "provider-1",
"endpoint_id": "endpoint-1",
@@ -670,6 +670,7 @@ async fn gateway_cancels_openai_video_task_via_internal_async_task_endpoint_with
);
task.external_task_id = Some("ext-video-task-123".to_string());
let (upstream_url, upstream_handle) = start_server(upstream).await;
let upstream_api_root = format!("{upstream_url}/v1");
task.request_metadata = Some(json!({
"rust_local_snapshot": {
"OpenAi": {
@@ -702,7 +703,7 @@ async fn gateway_cancels_openai_video_task_via_internal_async_task_endpoint_with
"format_converted": false
},
"transport": {
"upstream_base_url": upstream_url,
"upstream_base_url": upstream_api_root,
"provider_name": "openai-video",
"provider_id": "provider-1",
"endpoint_id": "endpoint-1",
+1 -1
View File
@@ -172,7 +172,7 @@ async fn gateway_exposes_request_id_header_for_local_execution_response() {
]));
let provider = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(|_request: Request| async move {
Json(json!({
"id": "chatcmpl-direct-audit-123",
@@ -847,7 +847,7 @@ async fn gateway_fetches_allowed_models_immediately_when_creating_key_with_auto_
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![],
));
@@ -1662,7 +1662,7 @@ async fn gateway_overwrites_allowed_models_immediately_when_enabling_auto_fetch(
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![key],
));
@@ -1770,7 +1770,7 @@ async fn gateway_fetches_allowed_models_immediately_when_enabling_auto_fetch_fro
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![key],
));
@@ -1878,7 +1878,7 @@ async fn gateway_refreshes_allowed_models_when_updating_include_patterns_with_au
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![key],
));
@@ -1982,7 +1982,7 @@ async fn gateway_refreshes_allowed_models_when_updating_exclude_patterns_with_au
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![key],
));
@@ -175,7 +175,7 @@ async fn gateway_handles_admin_provider_query_models_fetches_upstream_for_select
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
None,
@@ -432,7 +432,7 @@ async fn gateway_handles_admin_provider_query_models_with_openai_responses_endpo
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
None,
@@ -649,7 +649,7 @@ async fn gateway_handles_admin_provider_query_models_respecting_key_api_formats(
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
None,
@@ -669,7 +669,7 @@ async fn gateway_handles_admin_provider_query_models_respecting_key_api_formats(
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
None,
@@ -798,7 +798,7 @@ async fn gateway_handles_admin_provider_query_models_aggregating_active_keys() {
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
None,
@@ -1007,7 +1007,7 @@ async fn gateway_handles_admin_provider_query_test_model_locally_with_trusted_ad
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_key(
"key-openai-primary",
@@ -1066,7 +1066,7 @@ async fn gateway_handles_admin_provider_query_embedding_model_test() {
assert_eq!(plan.key_id, "key-siliconflow-embedding");
assert_eq!(plan.client_api_format, "openai:embedding");
assert_eq!(plan.provider_api_format, "openai:embedding");
assert_eq!(plan.url, "https://api.siliconflow.example/v1/embeddings");
assert_eq!(plan.url, "https://api.siliconflow.example/embeddings");
assert_eq!(plan.model_name.as_deref(), Some("Qwen/Qwen3-Embedding-4B"));
assert!(!plan.stream);
assert_eq!(
@@ -1546,7 +1546,7 @@ async fn gateway_handles_admin_provider_query_jina_embedding_model_test() {
assert_eq!(plan.key_id, "key-jina-embedding");
assert_eq!(plan.client_api_format, "openai:embedding");
assert_eq!(plan.provider_api_format, "jina:embedding");
assert_eq!(plan.url, "https://api.jina.example/v1/embeddings");
assert_eq!(plan.url, "https://api.jina.example/embeddings");
assert_eq!(plan.model_name.as_deref(), Some("jina-embeddings-v3"));
assert!(!plan.stream);
assert_eq!(
@@ -1775,7 +1775,7 @@ async fn gateway_handles_admin_provider_query_rerank_model_test() {
assert_eq!(plan.key_id, "key-jina-rerank");
assert_eq!(plan.client_api_format, "openai:rerank");
assert_eq!(plan.provider_api_format, "jina:rerank");
assert_eq!(plan.url, "https://api.jina.example/v1/rerank");
assert_eq!(plan.url, "https://api.jina.example/rerank");
assert_eq!(
plan.model_name.as_deref(),
Some("jina-reranker-v2-base-multilingual")
@@ -2736,7 +2736,7 @@ async fn gateway_handles_admin_provider_query_test_model_failover_locally_with_t
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![
sample_key(
@@ -3504,7 +3504,7 @@ async fn gateway_handles_non_kiro_multi_model_failover_locally() {
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_key(
"key-openai-primary",
@@ -3799,7 +3799,7 @@ async fn gateway_handles_openai_image_test_model_locally() {
"endpoint-openai-image",
"provider-openai",
"openai:image",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_key(
"key-openai-image",
@@ -4112,13 +4112,13 @@ async fn gateway_prefers_supported_non_kiro_endpoint_when_api_format_is_omitted(
"endpoint-openai-cli",
"provider-openai",
"openai:responses",
"https://api.openai.example",
"https://api.openai.example/v1",
),
sample_endpoint(
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
),
],
vec![
@@ -4215,7 +4215,7 @@ async fn gateway_prefers_transport_supported_non_kiro_endpoint_when_api_format_i
"endpoint-openai-chat-unsupported",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
);
unsupported_endpoint.header_rules = Some(json!({"invalid": true}));
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
@@ -4226,7 +4226,7 @@ async fn gateway_prefers_transport_supported_non_kiro_endpoint_when_api_format_i
"endpoint-openai-chat-supported",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
),
],
vec![sample_key(
@@ -4322,7 +4322,7 @@ async fn gateway_prefers_supported_non_kiro_endpoint_with_compatible_key_when_ap
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
),
],
vec![sample_key(
@@ -4411,13 +4411,13 @@ async fn gateway_uses_compatible_cli_endpoint_when_api_format_is_omitted() {
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
),
sample_endpoint(
"endpoint-openai-cli",
"provider-openai",
"openai:responses",
"https://api.openai.example",
"https://api.openai.example/v1",
),
],
vec![sample_key(
@@ -4503,14 +4503,14 @@ async fn gateway_uses_runnable_cli_endpoint_after_chat_preference_when_api_forma
"endpoint-openai-chat-unsupported",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
);
unsupported_chat_endpoint.header_rules = Some(json!({"invalid": true}));
let cli_endpoint = sample_endpoint(
"endpoint-openai-cli-runnable",
"provider-openai",
"openai:responses",
"https://api.openai.example",
"https://api.openai.example/v1",
);
let mut shared_key = sample_key(
"key-openai-shared",
@@ -4604,7 +4604,7 @@ async fn gateway_handles_openai_responses_test_model_failover_locally() {
"endpoint-openai-cli",
"provider-openai",
"openai:responses",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_key(
"key-openai-cli",
@@ -4698,7 +4698,7 @@ async fn gateway_handles_claude_cli_test_model_locally() {
"endpoint-claude-cli",
"provider-claude",
"claude:messages",
"https://api.anthropic.example",
"https://api.anthropic.example/v1",
)],
vec![sample_key(
"key-claude-cli",
@@ -4786,7 +4786,7 @@ async fn gateway_uses_compatible_claude_cli_endpoint_when_api_format_is_omitted(
"endpoint-claude-cli",
"provider-claude",
"claude:messages",
"https://api.anthropic.example",
"https://api.anthropic.example/v1",
)],
vec![sample_key(
"key-claude-cli",
@@ -4875,7 +4875,7 @@ async fn gateway_handles_claude_cli_test_model_failover_locally() {
"endpoint-claude-cli",
"provider-claude",
"claude:messages",
"https://api.anthropic.example",
"https://api.anthropic.example/v1",
)],
vec![sample_key(
"key-claude-cli",
@@ -5653,7 +5653,7 @@ async fn gateway_handles_admin_provider_query_test_model_failover_with_single_mo
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![sample_key(
"key-openai-alias",
@@ -5766,7 +5766,7 @@ async fn gateway_retries_non_kiro_failover_after_http_error_without_message() {
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![
sample_key(
@@ -5886,7 +5886,7 @@ async fn gateway_retries_non_kiro_failover_after_success_status_without_body() {
"endpoint-openai-chat",
"provider-openai",
"openai:chat",
"https://api.openai.example",
"https://api.openai.example/v1",
)],
vec![
sample_key(
@@ -2516,7 +2516,7 @@ async fn gateway_handles_admin_usage_curl_locally_with_trusted_admin_principal()
assert_eq!(payload["method"], "POST");
assert_eq!(
payload["url"],
"https://api.openai.example/v1/chat/completions"
"https://api.openai.example/chat/completions"
);
assert_eq!(payload["headers"]["Content-Type"], "application/json");
assert_eq!(payload["headers"]["Authorization"], "Bearer provider-real");
@@ -2536,7 +2536,7 @@ async fn gateway_handles_admin_usage_curl_locally_with_trusted_admin_principal()
);
let curl = payload["curl"].as_str().expect("curl should be string");
assert!(curl.contains("curl"));
assert!(curl.contains("https://api.openai.example/v1/chat/completions"));
assert!(curl.contains("https://api.openai.example/chat/completions"));
assert!(curl.contains("Content-Type: application/json"));
assert!(curl.contains("Authorization: Bearer provider-real"));
assert!(curl.contains("\"model\":\"gpt-5-target\""));
@@ -569,7 +569,7 @@ async fn gateway_cancels_admin_video_task_locally_with_trusted_admin_principal()
"format_converted": false
},
"transport": {
"upstream_base_url": "https://api.openai.example",
"upstream_base_url": "https://api.openai.example/v1",
"provider_name": "openai-video",
"provider_id": "provider-openai",
"endpoint_id": "endpoint-1",
@@ -304,7 +304,7 @@ fn assert_embedding_execution_plan(plan: &ExecutionPlan) {
assert_eq!(plan.client_api_format, "openai:embedding");
assert_eq!(plan.provider_api_format, "openai:embedding");
assert_eq!(plan.method, "POST");
assert_eq!(plan.url, "https://api.openai.example/v1/embeddings");
assert_eq!(plan.url, "https://api.openai.example/embeddings");
assert_eq!(plan.model_name.as_deref(), Some("text-embedding-3-small"));
let body = plan.body.json_body.as_ref().expect("json request body");
assert_eq!(body["model"], "upstream-embedding");
@@ -112,7 +112,7 @@ fn assert_rerank_execution_plan(plan: &ExecutionPlan) {
assert_eq!(plan.client_api_format, "openai:rerank");
assert_eq!(plan.provider_api_format, "openai:rerank");
assert_eq!(plan.method, "POST");
assert_eq!(plan.url, "https://api.openai.example/v1/rerank");
assert_eq!(plan.url, "https://api.openai.example/rerank");
assert_eq!(plan.model_name.as_deref(), Some("bge-reranker-base"));
let body = plan.body.json_body.as_ref().expect("json request body");
assert_eq!(body["model"], "upstream-rerank");
@@ -1932,7 +1932,7 @@ async fn gateway_handles_public_test_connection_without_hitting_fallback_probe()
let provider_hits = Arc::new(Mutex::new(0usize));
let provider_hits_clone = Arc::clone(&provider_hits);
let provider = Router::new().route(
"/v1/chat/completions",
"/chat/completions",
any(move |request: Request| {
let provider_hits_inner = Arc::clone(&provider_hits_clone);
async move {
+1 -1
View File
@@ -140,7 +140,7 @@ pub(super) fn sample_local_openai_endpoint() -> StoredProviderCatalogEndpoint {
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -68,7 +68,7 @@ const OPENAI_SPEC: ProviderSpec = ProviderSpec {
global_model_id: "global-model-openai-usage-pricing-1",
global_model_name: "gpt-5",
provider_model_name: "gpt-5-upstream",
upstream_base_url: "https://api.openai.example",
upstream_base_url: "https://api.openai.example/v1",
upstream_secret: "sk-upstream-openai-usage-pricing",
};
@@ -82,7 +82,7 @@ const CLAUDE_SPEC: ProviderSpec = ProviderSpec {
global_model_id: "global-model-claude-usage-pricing-1",
global_model_name: "claude-sonnet-4-5",
provider_model_name: "claude-sonnet-4-5-upstream",
upstream_base_url: "https://api.anthropic.example",
upstream_base_url: "https://api.anthropic.example/v1",
upstream_secret: "sk-upstream-claude-usage-pricing",
};
@@ -715,7 +715,7 @@ async fn gateway_executes_openai_video_remix_via_data_backed_local_follow_up_wit
"format_converted": false
},
"transport": {
"upstream_base_url": "https://api.openai.example",
"upstream_base_url": "https://api.openai.example/v1",
"provider_name": "openai-video",
"provider_id": "provider-openai-video-local-1",
"endpoint_id": "endpoint-openai-video-local-1",
@@ -69,7 +69,7 @@ async fn gateway_executes_openai_video_delete_via_reconstructed_data_backed_loca
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -165,7 +165,7 @@ async fn gateway_background_video_task_poller_refreshes_due_openai_task_from_rep
let (execution_runtime_url, execution_runtime_handle) = start_server(execution_runtime).await;
let repository = Arc::new(InMemoryVideoTaskRepository::default());
repository
.upsert(sample_due_openai_task("https://api.openai.example"))
.upsert(sample_due_openai_task("https://api.openai.example/v1"))
.await
.expect("task upsert should succeed");
@@ -268,9 +268,10 @@ async fn gateway_background_video_task_poller_refreshes_due_openai_task_from_rep
);
let (upstream_url, upstream_handle) = start_server(upstream).await;
let upstream_api_root = format!("{upstream_url}/v1");
let repository = Arc::new(InMemoryVideoTaskRepository::default());
repository
.upsert(sample_due_openai_task(&upstream_url))
.upsert(sample_due_openai_task(&upstream_api_root))
.await
.expect("task upsert should succeed");
@@ -66,7 +66,7 @@ async fn gateway_executes_openai_video_content_from_reconstructed_data_task_with
)
.expect("endpoint should build")
.with_transport_fields(
"https://api.openai.example".to_string(),
"https://api.openai.example/v1".to_string(),
None,
None,
Some(2),
@@ -359,7 +359,7 @@ fn seed_captures_transport_metadata_from_execution_plan() {
};
assert_eq!(
seed.transport.upstream_base_url,
"https://api.openai.example"
"https://api.openai.example/v1"
);
assert_eq!(seed.transport.provider_id, "provider-123");
assert_eq!(seed.transport.endpoint_id, "endpoint-123");