mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
fix(model-fetch): 提取获取计划请求,并使网关运行时与共享构建器保持一致
- 将 build_execution_plan 的散参数收敛为 ModelFetchExecutionPlanRequest,消除 clippy too_many_arguments - 在 aether-gateway 的 model_fetch runtime 中显式依赖 build_models_fetch_execution_plan - 补充共享 models fetch plan builder 的运行时测试覆盖
This commit is contained in:
@@ -365,7 +365,9 @@ mod tests {
|
|||||||
use aether_data_contracts::repository::provider_catalog::{
|
use aether_data_contracts::repository::provider_catalog::{
|
||||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||||
};
|
};
|
||||||
use aether_model_fetch::{ModelFetchAssociationStore, ModelFetchTransportRuntime};
|
use aether_model_fetch::{
|
||||||
|
build_models_fetch_execution_plan, ModelFetchAssociationStore, ModelFetchTransportRuntime,
|
||||||
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
@@ -746,6 +748,30 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn gateway_runtime_state_supports_shared_models_fetch_plan_builder() {
|
||||||
|
let state = TestState::default();
|
||||||
|
let transport = sample_transport(
|
||||||
|
"openai",
|
||||||
|
"provider-openai",
|
||||||
|
"endpoint-openai-chat",
|
||||||
|
"key-openai-chat",
|
||||||
|
"openai:chat",
|
||||||
|
"api_key",
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let plan = build_models_fetch_execution_plan(&state, &transport)
|
||||||
|
.await
|
||||||
|
.expect("shared models fetch plan should build");
|
||||||
|
|
||||||
|
assert_eq!(plan.method, "GET");
|
||||||
|
assert_eq!(plan.provider_id, "provider-openai");
|
||||||
|
assert_eq!(plan.endpoint_id, "endpoint-openai-chat");
|
||||||
|
assert_eq!(plan.key_id, "key-openai-chat");
|
||||||
|
assert_eq!(plan.model_name.as_deref(), Some("models"));
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn model_fetch_uses_preset_models_without_endpoint() {
|
async fn model_fetch_uses_preset_models_without_endpoint() {
|
||||||
let provider = sample_provider("provider-codex", "codex");
|
let provider = sample_provider("provider-codex", "codex");
|
||||||
|
|||||||
@@ -67,6 +67,17 @@ pub async fn build_models_fetch_execution_plan(
|
|||||||
build_standard_models_fetch_execution_plan(runtime, transport, None).await
|
build_standard_models_fetch_execution_plan(runtime, transport, None).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ModelFetchExecutionPlanRequest {
|
||||||
|
method: String,
|
||||||
|
url: String,
|
||||||
|
headers: BTreeMap<String, String>,
|
||||||
|
content_type: Option<String>,
|
||||||
|
body: RequestBody,
|
||||||
|
client_api_format: String,
|
||||||
|
provider_api_format: String,
|
||||||
|
model_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn build_standard_models_fetch_execution_plan(
|
pub async fn build_standard_models_fetch_execution_plan(
|
||||||
runtime: &(impl ModelFetchTransportRuntime + ?Sized),
|
runtime: &(impl ModelFetchTransportRuntime + ?Sized),
|
||||||
transport: &GatewayProviderTransportSnapshot,
|
transport: &GatewayProviderTransportSnapshot,
|
||||||
@@ -96,18 +107,20 @@ pub async fn build_standard_models_fetch_execution_plan(
|
|||||||
build_execution_plan(
|
build_execution_plan(
|
||||||
runtime,
|
runtime,
|
||||||
transport,
|
transport,
|
||||||
"GET",
|
ModelFetchExecutionPlanRequest {
|
||||||
upstream_url,
|
method: "GET".to_string(),
|
||||||
headers,
|
url: upstream_url,
|
||||||
None,
|
headers,
|
||||||
RequestBody {
|
content_type: None,
|
||||||
json_body: None,
|
body: RequestBody {
|
||||||
body_bytes_b64: None,
|
json_body: None,
|
||||||
body_ref: None,
|
body_bytes_b64: None,
|
||||||
|
body_ref: None,
|
||||||
|
},
|
||||||
|
client_api_format: provider_api_format.clone(),
|
||||||
|
provider_api_format,
|
||||||
|
model_name: Some("models".to_string()),
|
||||||
},
|
},
|
||||||
provider_api_format.clone(),
|
|
||||||
provider_api_format,
|
|
||||||
Some("models".to_string()),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -148,14 +161,16 @@ pub async fn build_antigravity_fetch_available_models_plan(
|
|||||||
build_execution_plan(
|
build_execution_plan(
|
||||||
runtime,
|
runtime,
|
||||||
transport,
|
transport,
|
||||||
"POST",
|
ModelFetchExecutionPlanRequest {
|
||||||
url,
|
method: "POST".to_string(),
|
||||||
headers,
|
url,
|
||||||
Some("application/json".to_string()),
|
headers,
|
||||||
RequestBody::from_json(json!({ "project": project_id })),
|
content_type: Some("application/json".to_string()),
|
||||||
"gemini:chat".to_string(),
|
body: RequestBody::from_json(json!({ "project": project_id })),
|
||||||
ANTIGRAVITY_FETCH_PROVIDER_API_FORMAT.to_string(),
|
client_api_format: "gemini:chat".to_string(),
|
||||||
Some("fetchAvailableModels".to_string()),
|
provider_api_format: ANTIGRAVITY_FETCH_PROVIDER_API_FORMAT.to_string(),
|
||||||
|
model_name: Some("fetchAvailableModels".to_string()),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -180,20 +195,22 @@ pub async fn build_gemini_cli_load_code_assist_plan(
|
|||||||
build_execution_plan(
|
build_execution_plan(
|
||||||
runtime,
|
runtime,
|
||||||
transport,
|
transport,
|
||||||
"POST",
|
ModelFetchExecutionPlanRequest {
|
||||||
"https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist".to_string(),
|
method: "POST".to_string(),
|
||||||
headers,
|
url: "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist".to_string(),
|
||||||
Some("application/json".to_string()),
|
headers,
|
||||||
RequestBody::from_json(json!({
|
content_type: Some("application/json".to_string()),
|
||||||
"metadata": {
|
body: RequestBody::from_json(json!({
|
||||||
"ideType": "ANTIGRAVITY",
|
"metadata": {
|
||||||
"platform": "PLATFORM_UNSPECIFIED",
|
"ideType": "ANTIGRAVITY",
|
||||||
"pluginType": "GEMINI",
|
"platform": "PLATFORM_UNSPECIFIED",
|
||||||
}
|
"pluginType": "GEMINI",
|
||||||
})),
|
}
|
||||||
"gemini:cli".to_string(),
|
})),
|
||||||
GEMINI_CLI_LOAD_CODE_ASSIST_PROVIDER_API_FORMAT.to_string(),
|
client_api_format: "gemini:cli".to_string(),
|
||||||
Some("loadCodeAssist".to_string()),
|
provider_api_format: GEMINI_CLI_LOAD_CODE_ASSIST_PROVIDER_API_FORMAT.to_string(),
|
||||||
|
model_name: Some("loadCodeAssist".to_string()),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -219,18 +236,20 @@ pub async fn build_vertex_models_fetch_execution_plan(
|
|||||||
build_execution_plan(
|
build_execution_plan(
|
||||||
runtime,
|
runtime,
|
||||||
transport,
|
transport,
|
||||||
"GET",
|
ModelFetchExecutionPlanRequest {
|
||||||
url.trim().to_string(),
|
method: "GET".to_string(),
|
||||||
headers,
|
url: url.trim().to_string(),
|
||||||
None,
|
headers,
|
||||||
RequestBody {
|
content_type: None,
|
||||||
json_body: None,
|
body: RequestBody {
|
||||||
body_bytes_b64: None,
|
json_body: None,
|
||||||
body_ref: None,
|
body_bytes_b64: None,
|
||||||
|
body_ref: None,
|
||||||
|
},
|
||||||
|
client_api_format: api_format.to_string(),
|
||||||
|
provider_api_format: api_format.to_string(),
|
||||||
|
model_name: Some("models".to_string()),
|
||||||
},
|
},
|
||||||
api_format.to_string(),
|
|
||||||
api_format.to_string(),
|
|
||||||
Some("models".to_string()),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -238,15 +257,19 @@ pub async fn build_vertex_models_fetch_execution_plan(
|
|||||||
async fn build_execution_plan(
|
async fn build_execution_plan(
|
||||||
runtime: &(impl ModelFetchTransportRuntime + ?Sized),
|
runtime: &(impl ModelFetchTransportRuntime + ?Sized),
|
||||||
transport: &GatewayProviderTransportSnapshot,
|
transport: &GatewayProviderTransportSnapshot,
|
||||||
method: &str,
|
request: ModelFetchExecutionPlanRequest,
|
||||||
url: String,
|
|
||||||
headers: BTreeMap<String, String>,
|
|
||||||
content_type: Option<String>,
|
|
||||||
body: RequestBody,
|
|
||||||
client_api_format: String,
|
|
||||||
provider_api_format: String,
|
|
||||||
model_name: Option<String>,
|
|
||||||
) -> Result<ExecutionPlan, String> {
|
) -> Result<ExecutionPlan, String> {
|
||||||
|
let ModelFetchExecutionPlanRequest {
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
content_type,
|
||||||
|
body,
|
||||||
|
client_api_format,
|
||||||
|
provider_api_format,
|
||||||
|
model_name,
|
||||||
|
} = request;
|
||||||
|
|
||||||
Ok(ExecutionPlan {
|
Ok(ExecutionPlan {
|
||||||
request_id: format!(
|
request_id: format!(
|
||||||
"req-model-fetch-{}-{}",
|
"req-model-fetch-{}-{}",
|
||||||
@@ -258,7 +281,7 @@ async fn build_execution_plan(
|
|||||||
provider_id: transport.provider.id.clone(),
|
provider_id: transport.provider.id.clone(),
|
||||||
endpoint_id: transport.endpoint.id.clone(),
|
endpoint_id: transport.endpoint.id.clone(),
|
||||||
key_id: transport.key.id.clone(),
|
key_id: transport.key.id.clone(),
|
||||||
method: method.to_string(),
|
method,
|
||||||
url,
|
url,
|
||||||
headers,
|
headers,
|
||||||
content_type,
|
content_type,
|
||||||
|
|||||||
Reference in New Issue
Block a user