Sagents.Mode.Steps (Sagents v0.8.0-rc.13)

Copy Markdown

Sagents-specific pipeline steps for custom execution modes.

These steps handle concerns that belong at the agent layer, not the LLMChain layer: HITL interrupts and state propagation from tool results.

Summary

Functions

Check if the LLM response contains tool calls that need human approval.

Until-tool termination that fires only on a successful matching result.

Decide whether to loop or return, with until_tool contract enforcement.

Propagate state updates from tool results into the chain's custom_context.

Functions

check_pre_tool_hitl(terminal, opts)

Check if the LLM response contains tool calls that need human approval.

Reads middleware list from opts :middleware. Inspects chain.exchanged_messages for tool calls that match the HITL policy.

Returns {:interrupt, chain, interrupt_data} if approval is needed.

check_until_tool_success(terminal, opts)

Until-tool termination that fires only on a successful matching result.

Like LangChain's check_until_tool/2, but ignores tool results with is_error: true. When the target tool is called but returns an error, the pipeline continues ({:continue, chain}) so the loop re-runs and the LLM sees the error result and can correct the call. This is the default behavior for until_tool; pass until_tool_success: false to use name-only matching.

Reads :tool_names from opts (a list of tool-name strings, populated by Sagents.Modes.AgentExecution).

continue_or_done_safe(terminal, run_fn, opts)

Decide whether to loop or return, with until_tool contract enforcement.

This is a safer variant of LangChain's continue_or_done/3 that adds enforcement of the "until_tool" contract: if the LLM stops (needs_response becomes false) without ever calling the target tool, it returns an error instead of {:ok, chain}.

If the target tool WAS called, check_until_tool/2 would have already converted the pipeline to {:ok, chain, tool_result}, which passes through here as a terminal.

When until_tool_active is false or absent in opts

  • {:continue, chain} with needs_response: true -> calls run_fn.(chain, opts) (loop)
  • {:continue, chain} with needs_response: false -> {:ok, chain} (normal completion)
  • Any terminal tuple -> pass through unchanged

When until_tool_active is true in opts

  • {:continue, chain} with needs_response: true -> calls run_fn.(chain, opts) (loop)
  • {:continue, chain} with needs_response: false -> {:error, chain, %LangChainError{...}}
  • Any terminal tuple -> pass through unchanged

propagate_state(terminal, opts)

Propagate state updates from tool results into the chain's custom_context.

After tool execution, tools may have returned State structs as processed_content. This step extracts those deltas and merges them into custom_context.state.