Refactor subagent and workflow domain models; migrate access tiers and events to domain module

- Moved `AccessTier` and `SubagentEvent` enums to `zesdex_domain::subagent`.
- Consolidated workflow-related types into `zesdex_domain::workflow`.
- Updated references across the codebase to use the new domain models.
- Refactored tool execution logic to utilize a new `ToolExecutor` trait.
- Enhanced `AgentTurnService` to handle tool calls and events more effectively.
- Adjusted API handlers and state management to align with new domain structure.
This commit is contained in:
asepharyana
2026-07-21 06:42:53 +07:00
parent 552bc5bc63
commit 802346f909
31 changed files with 968 additions and 870 deletions
+56
View File
@@ -0,0 +1,56 @@
use std::future::Future;
use anyhow::Result;
use zesdex_application::agent::ToolExecutor;
use crate::tools::{all_tools, Tool, ToolCtx};
use tracing::debug;
pub struct InfrastructureToolExecutor {
ctx: ToolCtx,
tools: Vec<Box<dyn Tool>>,
}
impl InfrastructureToolExecutor {
pub fn new(ctx: ToolCtx) -> Self {
Self {
ctx,
tools: all_tools(),
}
}
}
impl ToolExecutor for InfrastructureToolExecutor {
fn execute(
&self,
tool_name: &str,
args: &serde_json::Value,
) -> impl Future<Output = Result<String>> + Send {
// Find the tool by name
let tool_opt = self.tools.iter().find(|t| t.name() == tool_name);
let ctx = self.ctx.clone();
let args = args.clone();
async move {
match tool_opt {
Some(tool) => {
// Tool::run is synchronous, so we run it in a blocking task if needed
// For now, since they run fast and we are transitioning, we can just block in place.
// Or tokio::task::spawn_blocking:
let tool_name = tool.name().to_string();
let t_ctx = ctx.clone();
let t_args = args.clone();
// Because Tool isn't easily cloned, we might just block on the current thread,
// or use tokio::task::block_in_place if we're in a tokio runtime.
// But `tool.run` takes `&self`, and we have `&self` borrowed.
// For now we just call it directly.
tokio::task::block_in_place(move || {
tool.run(&ctx, &args)
})
}
None => {
anyhow::bail!("Unknown tool: {}", tool_name)
}
}
}
}
}
+1
View File
@@ -30,6 +30,7 @@ pub mod spawn;
pub mod utility;
pub mod web_search;
pub mod workflow;
pub mod executor;
pub use git::git_cred;
pub use git::git_operator;
@@ -200,7 +200,8 @@ impl Tool for ParallelDelegate {
// Consolidate results
if synthesize && results.len() > 1 {
let consolidated = consolidate_results(&results, &base_url, &api_key, &model)?;
let rt = tokio::runtime::Runtime::new()?;
let consolidated = rt.block_on(consolidate_results(&results, &base_url, &api_key, &model))?;
Ok(format!(
"## Parallel Delegation Complete\n\n**Task:** {task}\n**Parallel agents:** {}\n\n{}",
results.len(),
@@ -249,8 +250,9 @@ async fn auto_split_task(
let user_msg =
zesdex_domain::core::ChatMessage::user(format!("Task: {task}\n\nSplit into {max_parallel} parallel directives:"));
use zesdex_application::ports::ProviderService;
match client
.chat_with_tools_non_streaming(&[sys_msg, user_msg], None, Some(2048), Some(0.4), None)
.chat(&[sys_msg, user_msg], None, Some(2048), Some(0.4)).await
{
Ok((response, _)) => {
let text = response.content.unwrap_or_default();
@@ -339,7 +341,7 @@ fn fallback_split(task: &str, max_parallel: usize) -> Vec<(String, AccessTier)>
}
/// Use LLM to consolidate multiple agent results into a single response.
fn consolidate_results(
async fn consolidate_results(
results: &[(usize, String, String)],
base_url: &str,
api_key: &str,
@@ -367,7 +369,8 @@ fn consolidate_results(
"Consolidate the following parallel agent outputs:\n\n{summary}"
));
match client.chat_with_tools_non_streaming(&[sys_msg, user_msg], None, Some(2048), Some(0.3), None) {
use zesdex_application::ports::ProviderService;
match client.chat(&[sys_msg, user_msg], None, Some(2048), Some(0.3)).await {
Ok((response, _)) => Ok(response.content.unwrap_or_else(|| summary.clone())),
Err(e) => {
warn!(error = %e, "consolidation LLM call failed, using raw concatenation");
+2 -5
View File
@@ -14,10 +14,7 @@ use crate::tools::{arg_str, Tool, ToolCtx};
use crate::workflow::engine::execution::execute_workflow;
use crate::workflow::hive_mind::cycle::execute_cycle;
use crate::workflow::hive_mind::synthesis::synthesize_consensus;
use crate::workflow::hive_mind::types::{
CognitiveCycle, NodeDirective, NodeOutput,
};
use crate::workflow::script::WorkflowScript;
use zesdex_domain::workflow::{CognitiveCycle, NodeDirective, NodeOutput, WorkflowScript};
/// Execute a multi-step workflow defined in YAML.
///
@@ -49,7 +46,7 @@ impl Tool for WorkflowRun {
#[instrument(skip(self, ctx, args))]
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
let yaml = arg_str(args, "workflow_yaml")?;
let script = WorkflowScript::parse(&yaml)?;
let script = crate::workflow::script::parse_workflow_script(&yaml)?;
info!(
"Workflow started: {} ({} phases)",
script.name,