mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
Clarify ranked minimal candidate selection
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use aether_data::DataLayerError;
|
use aether_data::DataLayerError;
|
||||||
use aether_data_contracts::repository::candidate_selection::StoredMinimalCandidateSelectionRow;
|
use aether_data_contracts::repository::candidate_selection::StoredMinimalCandidateSelectionRow;
|
||||||
use aether_scheduler_core::{
|
use aether_scheduler_core::{
|
||||||
auth_constraints_allow_api_format, build_minimal_candidate_selection,
|
auth_constraints_allow_api_format, build_ranked_minimal_candidate_selection,
|
||||||
collect_global_model_names_for_required_capability, enumerate_minimal_candidate_selection,
|
collect_global_model_names_for_required_capability, enumerate_minimal_candidate_selection,
|
||||||
normalize_api_format, resolve_requested_global_model_name, row_supports_requested_model,
|
normalize_api_format, resolve_requested_global_model_name, row_supports_requested_model,
|
||||||
BuildMinimalCandidateSelectionInput, SchedulerAuthConstraints,
|
BuildMinimalCandidateSelectionInput, SchedulerAuthConstraints,
|
||||||
@@ -161,7 +161,7 @@ pub(crate) async fn read_minimal_candidate_selection_with_priority_mode_and_affi
|
|||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
};
|
};
|
||||||
let auth_constraints = auth_snapshot.map(auth_snapshot_constraints);
|
let auth_constraints = auth_snapshot.map(auth_snapshot_constraints);
|
||||||
build_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
build_ranked_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
||||||
rows,
|
rows,
|
||||||
normalized_api_format: &normalized_api_format,
|
normalized_api_format: &normalized_api_format,
|
||||||
requested_model_name,
|
requested_model_name,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use aether_data_contracts::repository::video_tasks::{
|
|||||||
UpsertVideoTask, VideoTaskLookupKey, VideoTaskStatus, VideoTaskWriteRepository,
|
UpsertVideoTask, VideoTaskLookupKey, VideoTaskStatus, VideoTaskWriteRepository,
|
||||||
};
|
};
|
||||||
use aether_scheduler_core::{
|
use aether_scheduler_core::{
|
||||||
build_minimal_candidate_selection, BuildMinimalCandidateSelectionInput,
|
build_ranked_minimal_candidate_selection, BuildMinimalCandidateSelectionInput,
|
||||||
SchedulerAuthConstraints, SchedulerPriorityMode,
|
SchedulerAuthConstraints, SchedulerPriorityMode,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
@@ -622,7 +622,7 @@ async fn data_state_reads_minimal_candidate_selection_with_auth_filters() {
|
|||||||
.map(|items| items.to_vec()),
|
.map(|items| items.to_vec()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let selection = build_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
let selection = build_ranked_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
||||||
rows,
|
rows,
|
||||||
normalized_api_format: "openai:chat",
|
normalized_api_format: "openai:chat",
|
||||||
requested_model_name: "gpt-4.1",
|
requested_model_name: "gpt-4.1",
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ fn scheduler_candidate_runtime_paths_depend_on_scheduler_core_and_state_trait()
|
|||||||
"candidate/mod.rs should depend on core minimal candidate DTO"
|
"candidate/mod.rs should depend on core minimal candidate DTO"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!candidate_mod.contains("build_minimal_candidate_selection"),
|
!candidate_mod.contains("build_ranked_minimal_candidate_selection"),
|
||||||
"candidate/mod.rs should not own the core minimal candidate builder anymore"
|
"candidate/mod.rs should not own the core minimal candidate builder anymore"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
@@ -487,7 +487,7 @@ fn scheduler_candidate_runtime_paths_depend_on_scheduler_core_and_state_trait()
|
|||||||
let core_candidate_selection =
|
let core_candidate_selection =
|
||||||
read_workspace_file("crates/aether-scheduler-core/src/candidate/selection.rs");
|
read_workspace_file("crates/aether-scheduler-core/src/candidate/selection.rs");
|
||||||
for expected in [
|
for expected in [
|
||||||
"build_minimal_candidate_selection",
|
"build_ranked_minimal_candidate_selection",
|
||||||
"apply_scheduler_candidate_ranking",
|
"apply_scheduler_candidate_ranking",
|
||||||
] {
|
] {
|
||||||
assert!(
|
assert!(
|
||||||
@@ -571,7 +571,7 @@ fn scheduler_candidate_runtime_paths_depend_on_scheduler_core_and_state_trait()
|
|||||||
"data/candidate_selection.rs should depend on core requested-model resolver"
|
"data/candidate_selection.rs should depend on core requested-model resolver"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
candidate_selection.contains("build_minimal_candidate_selection"),
|
candidate_selection.contains("build_ranked_minimal_candidate_selection"),
|
||||||
"data/candidate_selection.rs should depend on core minimal candidate builder"
|
"data/candidate_selection.rs should depend on core minimal candidate builder"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub use selectability::{
|
|||||||
auth_api_key_concurrency_limit_reached, candidate_is_selectable_with_runtime_state,
|
auth_api_key_concurrency_limit_reached, candidate_is_selectable_with_runtime_state,
|
||||||
candidate_runtime_skip_reason_with_state, CandidateRuntimeSelectabilityInput,
|
candidate_runtime_skip_reason_with_state, CandidateRuntimeSelectabilityInput,
|
||||||
};
|
};
|
||||||
pub use selection::build_minimal_candidate_selection;
|
pub use selection::build_ranked_minimal_candidate_selection;
|
||||||
pub use types::{
|
pub use types::{
|
||||||
BuildMinimalCandidateSelectionInput, SchedulerMinimalCandidateSelectionCandidate,
|
BuildMinimalCandidateSelectionInput, SchedulerMinimalCandidateSelectionCandidate,
|
||||||
SchedulerPriorityMode,
|
SchedulerPriorityMode,
|
||||||
@@ -33,7 +33,7 @@ mod tests {
|
|||||||
use aether_data_contracts::repository::provider_catalog::StoredProviderCatalogKey;
|
use aether_data_contracts::repository::provider_catalog::StoredProviderCatalogKey;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
auth_api_key_concurrency_limit_reached, build_minimal_candidate_selection,
|
auth_api_key_concurrency_limit_reached, build_ranked_minimal_candidate_selection,
|
||||||
candidate_is_selectable_with_runtime_state, candidate_supports_required_capability,
|
candidate_is_selectable_with_runtime_state, candidate_supports_required_capability,
|
||||||
collect_global_model_names_for_required_capability, BuildMinimalCandidateSelectionInput,
|
collect_global_model_names_for_required_capability, BuildMinimalCandidateSelectionInput,
|
||||||
CandidateRuntimeSelectabilityInput, SchedulerMinimalCandidateSelectionCandidate,
|
CandidateRuntimeSelectabilityInput, SchedulerMinimalCandidateSelectionCandidate,
|
||||||
@@ -186,18 +186,19 @@ mod tests {
|
|||||||
allowed_api_formats: Some(vec!["OPENAI:CHAT".to_string()]),
|
allowed_api_formats: Some(vec!["OPENAI:CHAT".to_string()]),
|
||||||
allowed_models: Some(vec!["gpt-5".to_string()]),
|
allowed_models: Some(vec!["gpt-5".to_string()]),
|
||||||
};
|
};
|
||||||
let candidates = build_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
let candidates =
|
||||||
rows: vec![sample_row("1"), disallowed],
|
build_ranked_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
||||||
normalized_api_format: "openai:chat",
|
rows: vec![sample_row("1"), disallowed],
|
||||||
requested_model_name: "gpt-5",
|
normalized_api_format: "openai:chat",
|
||||||
resolved_global_model_name: "gpt-5",
|
requested_model_name: "gpt-5",
|
||||||
require_streaming: false,
|
resolved_global_model_name: "gpt-5",
|
||||||
required_capabilities: None,
|
require_streaming: false,
|
||||||
auth_constraints: Some(&constraints),
|
required_capabilities: None,
|
||||||
affinity_key: None,
|
auth_constraints: Some(&constraints),
|
||||||
priority_mode: SchedulerPriorityMode::Provider,
|
affinity_key: None,
|
||||||
})
|
priority_mode: SchedulerPriorityMode::Provider,
|
||||||
.expect("candidate selection should build");
|
})
|
||||||
|
.expect("candidate selection should build");
|
||||||
|
|
||||||
assert_eq!(candidates.len(), 1);
|
assert_eq!(candidates.len(), 1);
|
||||||
assert_eq!(candidates[0].provider_id, "provider-1");
|
assert_eq!(candidates[0].provider_id, "provider-1");
|
||||||
@@ -264,18 +265,19 @@ mod tests {
|
|||||||
matching_capability.provider_priority = 10;
|
matching_capability.provider_priority = 10;
|
||||||
|
|
||||||
let required_capabilities = serde_json::json!({"cache_1h": true});
|
let required_capabilities = serde_json::json!({"cache_1h": true});
|
||||||
let candidates = build_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
let candidates =
|
||||||
rows: vec![missing_capability, matching_capability],
|
build_ranked_minimal_candidate_selection(BuildMinimalCandidateSelectionInput {
|
||||||
normalized_api_format: "openai:chat",
|
rows: vec![missing_capability, matching_capability],
|
||||||
requested_model_name: "gpt-5",
|
normalized_api_format: "openai:chat",
|
||||||
resolved_global_model_name: "gpt-5",
|
requested_model_name: "gpt-5",
|
||||||
require_streaming: false,
|
resolved_global_model_name: "gpt-5",
|
||||||
required_capabilities: Some(&required_capabilities),
|
require_streaming: false,
|
||||||
auth_constraints: None,
|
required_capabilities: Some(&required_capabilities),
|
||||||
affinity_key: None,
|
auth_constraints: None,
|
||||||
priority_mode: SchedulerPriorityMode::Provider,
|
affinity_key: None,
|
||||||
})
|
priority_mode: SchedulerPriorityMode::Provider,
|
||||||
.expect("candidate selection should build");
|
})
|
||||||
|
.expect("candidate selection should build");
|
||||||
|
|
||||||
assert_eq!(candidates.len(), 2);
|
assert_eq!(candidates.len(), 2);
|
||||||
assert_eq!(candidates[0].key_id, "key-2");
|
assert_eq!(candidates[0].key_id, "key-2");
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use super::types::{
|
|||||||
BuildMinimalCandidateSelectionInput, SchedulerMinimalCandidateSelectionCandidate,
|
BuildMinimalCandidateSelectionInput, SchedulerMinimalCandidateSelectionCandidate,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build_minimal_candidate_selection(
|
pub fn build_ranked_minimal_candidate_selection(
|
||||||
input: BuildMinimalCandidateSelectionInput<'_>,
|
input: BuildMinimalCandidateSelectionInput<'_>,
|
||||||
) -> Result<Vec<SchedulerMinimalCandidateSelectionCandidate>, DataLayerError> {
|
) -> Result<Vec<SchedulerMinimalCandidateSelectionCandidate>, DataLayerError> {
|
||||||
let priority_mode = input.priority_mode;
|
let priority_mode = input.priority_mode;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub use auth::{
|
|||||||
auth_constraints_allow_provider, provider_matches_allowed_value, SchedulerAuthConstraints,
|
auth_constraints_allow_provider, provider_matches_allowed_value, SchedulerAuthConstraints,
|
||||||
};
|
};
|
||||||
pub use candidate::{
|
pub use candidate::{
|
||||||
auth_api_key_concurrency_limit_reached, build_minimal_candidate_selection,
|
auth_api_key_concurrency_limit_reached, build_ranked_minimal_candidate_selection,
|
||||||
candidate_is_selectable_with_runtime_state, candidate_runtime_skip_reason_with_state,
|
candidate_is_selectable_with_runtime_state, candidate_runtime_skip_reason_with_state,
|
||||||
candidate_supports_required_capability, collect_global_model_names_for_required_capability,
|
candidate_supports_required_capability, collect_global_model_names_for_required_capability,
|
||||||
enumerate_minimal_candidate_selection, requested_capability_priority_for_candidate,
|
enumerate_minimal_candidate_selection, requested_capability_priority_for_candidate,
|
||||||
|
|||||||
Reference in New Issue
Block a user