use crate::core::engine::Engine;
use crate::core::state::{DispatchOutcome, TaskSpec};
use crate::types::CapToken;
use crate::worker::adapter::SpawnerAdapter;
use async_trait::async_trait;
pub mod compiler;
pub mod loader;
pub mod store;
use mlua_flow_ir::{AsyncDispatcher, EvalError};
use serde_json::Value;
use std::sync::Arc;
pub use mlua_swarm_schema::OperatorKind as SchemaOperatorKind;
pub use mlua_swarm_schema::{
current_schema_version, default_global_agent_kind, AgentDef, AgentKind, AgentMeta,
AgentProfile, Blueprint, BlueprintMetadata, BlueprintOrigin, CompilerHints, CompilerStrategy,
OperatorDef, SpawnerHints, CURRENT_SCHEMA_VERSION,
};
pub struct EngineDispatcher {
engine: Engine,
op_token: CapToken,
spawner: Arc<dyn SpawnerAdapter>,
}
impl EngineDispatcher {
pub fn with_spawner(
engine: Engine,
op_token: CapToken,
spawner: Arc<dyn SpawnerAdapter>,
) -> Self {
Self {
engine,
op_token,
spawner,
}
}
}
#[async_trait]
impl AsyncDispatcher for EngineDispatcher {
async fn dispatch(&self, ref_: &str, input: Value) -> Result<Value, EvalError> {
let directive = match &input {
Value::String(s) => s.clone(),
other => other.to_string(),
};
let tid = self
.engine
.start_task(
&self.op_token,
TaskSpec {
agent: ref_.to_string(),
initial_directive: directive,
},
)
.await
.map_err(|e| EvalError::DispatcherError {
ref_: ref_.to_string(),
msg: format!("start_task: {e}"),
})?;
let outcome = self
.engine
.dispatch_attempt_with(&self.op_token, &tid, &self.spawner)
.await;
match outcome {
Ok(DispatchOutcome::Pass(v)) => Ok(v),
Ok(DispatchOutcome::Blocked(v)) => Err(EvalError::DispatcherError {
ref_: ref_.to_string(),
msg: format!("blocked: {v}"),
}),
Ok(other) => Err(EvalError::DispatcherError {
ref_: ref_.to_string(),
msg: format!("non-terminal outcome: {:?}", other),
}),
Err(e) => Err(EvalError::DispatcherError {
ref_: ref_.to_string(),
msg: format!("dispatch_attempt: {e}"),
}),
}
}
}