Sagents.Mode.Steps (Sagents v0.4.0)

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.

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.

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.