use std::collections::HashMap;
use crate::types::{LoraConfig, WorkerId};
use super::batch::DecisionResponse;
use super::worker::Guidance;
use crate::context::TaskContext;
#[derive(Debug, Clone)]
pub enum ManagementStrategy {
EveryTick,
FixedInterval { interval: u64 },
CompletionBased {
max_wait_ticks: u64,
},
Hybrid {
preferred_interval: u64,
force_after_ticks: u64,
},
EscalationBased {
interval: u64,
immediate_on_escalation: bool,
},
}
impl Default for ManagementStrategy {
fn default() -> Self {
ManagementStrategy::FixedInterval { interval: 10 }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ManagerId(pub usize);
#[derive(Debug, Clone)]
pub struct BatchDecisionRequest {
pub manager_id: ManagerId,
pub requests: Vec<WorkerDecisionRequest>,
}
use crate::context::ResolvedContext;
#[derive(Debug, Clone)]
pub struct WorkerDecisionRequest {
pub worker_id: WorkerId,
pub query: String,
pub context: ResolvedContext,
pub lora: Option<LoraConfig>,
}
#[derive(Debug, Clone, Default)]
pub struct AsyncTaskRequest {
pub task_type: String,
pub params: HashMap<String, String>,
}
#[derive(Default, Clone)]
pub struct ManagementDecision {
pub guidances: HashMap<WorkerId, Guidance>,
pub strategy_update: Option<ManagementStrategy>,
pub async_tasks: Vec<AsyncTaskRequest>,
}
impl ManagementDecision {
pub fn with_guidance(mut self, worker_id: WorkerId, guidance: Guidance) -> Self {
self.guidances.insert(worker_id, guidance);
self
}
pub fn broadcast_guidance(mut self, worker_ids: &[WorkerId], guidance: Guidance) -> Self {
for &id in worker_ids {
self.guidances.insert(id, guidance.clone());
}
self
}
}
pub trait ManagerAgent: Send + Sync {
fn prepare(&self, context: &TaskContext) -> BatchDecisionRequest;
fn finalize(
&self,
context: &TaskContext,
responses: Vec<(WorkerId, DecisionResponse)>,
) -> ManagementDecision;
fn id(&self) -> ManagerId;
fn name(&self) -> &str;
}
impl ManagerAgent for Box<dyn ManagerAgent> {
fn prepare(&self, context: &TaskContext) -> BatchDecisionRequest {
(**self).prepare(context)
}
fn finalize(
&self,
context: &TaskContext,
responses: Vec<(WorkerId, DecisionResponse)>,
) -> ManagementDecision {
(**self).finalize(context, responses)
}
fn id(&self) -> ManagerId {
(**self).id()
}
fn name(&self) -> &str {
(**self).name()
}
}