mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-10 11:19:50 +08:00
refactor ai serving modules and crates
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub trait AiExecutionAttempt {
|
||||
fn execution_plan(&self) -> &aether_contracts::ExecutionPlan;
|
||||
|
||||
fn report_kind(&self) -> Option<String>;
|
||||
|
||||
fn report_context(&self) -> Option<serde_json::Value>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AiAttemptLoopOutcome<Response, Exhaustion> {
|
||||
Responded(Response),
|
||||
Exhausted(Exhaustion),
|
||||
NoPath,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AiAttemptLoopPort<Attempt>: Send + Sync
|
||||
where
|
||||
Attempt: AiExecutionAttempt + Send + Sync + 'static,
|
||||
{
|
||||
type Response: Send;
|
||||
type Exhaustion: Send;
|
||||
type Error: Send;
|
||||
|
||||
async fn execute_attempt(
|
||||
&self,
|
||||
attempt: &Attempt,
|
||||
) -> Result<Option<Self::Response>, Self::Error>;
|
||||
|
||||
async fn mark_unused_attempts(&self, attempts: Vec<Attempt>) -> Result<(), Self::Error>;
|
||||
|
||||
async fn build_exhaustion(
|
||||
&self,
|
||||
last_plan: aether_contracts::ExecutionPlan,
|
||||
last_report_context: Option<serde_json::Value>,
|
||||
) -> Result<Self::Exhaustion, Self::Error>;
|
||||
}
|
||||
|
||||
pub async fn run_ai_attempt_loop<Port, Attempt>(
|
||||
port: &Port,
|
||||
attempts: Vec<Attempt>,
|
||||
) -> Result<AiAttemptLoopOutcome<Port::Response, Port::Exhaustion>, Port::Error>
|
||||
where
|
||||
Port: AiAttemptLoopPort<Attempt>,
|
||||
Attempt: AiExecutionAttempt + Send + Sync + 'static,
|
||||
{
|
||||
let mut remaining = attempts.into_iter();
|
||||
let mut last_attempted = None;
|
||||
|
||||
while let Some(attempt) = remaining.next() {
|
||||
last_attempted = Some((attempt.execution_plan().clone(), attempt.report_context()));
|
||||
if let Some(response) = port.execute_attempt(&attempt).await? {
|
||||
port.mark_unused_attempts(remaining.collect()).await?;
|
||||
return Ok(AiAttemptLoopOutcome::Responded(response));
|
||||
}
|
||||
}
|
||||
|
||||
let Some((last_plan, last_report_context)) = last_attempted else {
|
||||
return Ok(AiAttemptLoopOutcome::NoPath);
|
||||
};
|
||||
|
||||
Ok(AiAttemptLoopOutcome::Exhausted(
|
||||
port.build_exhaustion(last_plan, last_report_context)
|
||||
.await?,
|
||||
))
|
||||
}
|
||||
|
||||
impl AiExecutionAttempt for crate::dto::AiSyncAttempt {
|
||||
fn execution_plan(&self) -> &aether_contracts::ExecutionPlan {
|
||||
&self.plan
|
||||
}
|
||||
|
||||
fn report_kind(&self) -> Option<String> {
|
||||
self.report_kind.clone()
|
||||
}
|
||||
|
||||
fn report_context(&self) -> Option<serde_json::Value> {
|
||||
self.report_context.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl AiExecutionAttempt for crate::dto::AiStreamAttempt {
|
||||
fn execution_plan(&self) -> &aether_contracts::ExecutionPlan {
|
||||
&self.plan
|
||||
}
|
||||
|
||||
fn report_kind(&self) -> Option<String> {
|
||||
self.report_kind.clone()
|
||||
}
|
||||
|
||||
fn report_context(&self) -> Option<serde_json::Value> {
|
||||
self.report_context.clone()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user