Skip to main content

GraphActionExecutor

Trait GraphActionExecutor 

Source
pub trait GraphActionExecutor: Send + Sync {
    // Required methods
    fn execute_llm_infer<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        action: &'life1 NodeAction,
        state: &'life2 mut GraphState,
    ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn execute_tool_call<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        tool_name: &'life1 str,
        args: &'life2 Value,
        state: &'life3 mut GraphState,
    ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait;
    fn execute_paradigm_switch<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        paradigm: &'life1 str,
        state: &'life2 mut GraphState,
    ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn parse_decision<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        response: &'life1 InferenceResponse,
        state: &'life2 mut GraphState,
    ) -> Pin<Box<dyn Future<Output = Result<GraphDecision>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
}
Expand description

Trait for executing graph node actions with full AgentLoop integration.

This is the P2-2 bridge — when a concrete implementation (from oneai-agent) is provided, the StateGraphExecutor delegates LlmInfer and ToolCall nodes to the AgentLoop’s full pipeline instead of directly calling provider.infer() and tool.execute(). This means:

  • LlmInfer: Gets proper tool definitions (filtered by paradigm config), domain pack tool decorators, PreInfer/PostInfer hooks, context assembly, and the OutputParser for decision parsing.
  • ToolCall: Gets PreToolUse/PostToolUse hooks, domain permission checks, approval gate interaction, and error recovery.
  • SwitchParadigm: Changes the active paradigm (updates tool filter and system prompt for subsequent nodes).

The DirectProviderActionExecutor provides backward-compatible behavior (direct provider + tool execution, no AgentLoop integration). It’s used when no AgentLoop is available (e.g., standalone StateGraph execution).

Required Methods§

Source

fn execute_llm_infer<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, action: &'life1 NodeAction, state: &'life2 mut GraphState, ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Execute an LLM inference node — using full AgentLoop infrastructure.

When include_tool_definitions is true, builds tool definitions based on tool_filter_override or the active paradigm’s tool set. This is critical for ReAct loops — the model needs tools to decide whether to call them.

After inference, the response is parsed into a GraphDecision and stored in state.parsed_decision for edge condition routing.

Source

fn execute_tool_call<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, tool_name: &'life1 str, args: &'life2 Value, state: &'life3 mut GraphState, ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Execute a tool call node — using AgentLoop’s permission and hooks.

When a GraphActionExecutor from oneai-agent is used, this method runs PreToolUse hooks, checks domain permissions, interacts with the approval gate, executes the tool, runs PostToolUse hooks, and handles error recovery.

Source

fn execute_paradigm_switch<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, paradigm: &'life1 str, state: &'life2 mut GraphState, ) -> Pin<Box<dyn Future<Output = Result<ActionResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Execute a paradigm switch node.

Updates state.active_paradigm and clears state.parsed_decision. Subsequent LlmInfer nodes will use the new paradigm’s tool set and system prompt.

Source

fn parse_decision<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, response: &'life1 InferenceResponse, state: &'life2 mut GraphState, ) -> Pin<Box<dyn Future<Output = Result<GraphDecision>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Parse an LLM response into a GraphDecision.

Uses the same OutputParser as the AgentLoop for consistent decision parsing. Stores the result in state.parsed_decision.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§