agent

Agentic execution: tool-call loops, result types, and response validation.

Agentic execution: tool-call loops, result types, and response validation.

class AgentLoop(client, tool_registry, max_rounds=5, tool_timeout=30.0, continue_on_tool_error=True)[source]

Bases: object

Executes agentic tool-call loops for a single prompt.

Usage:

loop = AgentLoop(client, tool_registry, max_rounds=5) result = loop.execute(

prompt=”Search for information about X”, tools=[“search_tool”, “calculate”],

)

Parameters:
__init__(client, tool_registry, max_rounds=5, tool_timeout=30.0, continue_on_tool_error=True)[source]

Initialize the agent loop.

Parameters:
  • client (FFAIClientBase) – AI client to use for LLM calls.

  • tool_registry (ToolRegistry) – Registry of tools available for execution.

  • max_rounds (int) – Maximum number of tool-call rounds.

  • tool_timeout (float) – Timeout in seconds for individual tool execution.

  • continue_on_tool_error (bool) – Whether to continue the loop if a tool fails.

Return type:

None

execute(prompt, tools, tool_choice='auto', **kwargs)[source]

Execute the agentic loop.

Calls the LLM with the prompt and available tools. If the response contains tool calls, executes them and feeds results back. Repeats until no tool calls or max_rounds is reached.

Parameters:
  • prompt (str) – The user prompt.

  • tools (list[str]) – List of tool names to make available.

  • tool_choice (str) – Tool selection strategy (“auto”, “none”, etc.).

  • **kwargs (Any) – Additional parameters passed to generate_response().

Returns:

AgentResult with response, tool call records, and round/LLM counts.

Return type:

AgentResult

class AgentResult(response='', tool_calls=<factory>, total_rounds=0, total_llm_calls=0, status='success')[source]

Bases: object

Result of an agentic execution loop.

Parameters:
response

The final response text from the LLM.

Type:

str

tool_calls

List of tool call records from all rounds.

Type:

list[ffai.agent.agent_result.ToolCallRecord]

total_rounds

Number of rounds executed.

Type:

int

total_llm_calls

Total number of LLM API calls made.

Type:

int

status

Execution status - “success”, “failed”, or “max_rounds_exceeded”.

Type:

Literal[‘success’, ‘failed’, ‘max_rounds_exceeded’]

response: str = ''
tool_calls: list[ToolCallRecord]
total_rounds: int = 0
total_llm_calls: int = 0
status: Literal['success', 'failed', 'max_rounds_exceeded'] = 'success'
property tool_calls_count: int

Total number of tool calls made.

property last_tool_name: str

Name of the last tool called, or empty string if no tools used.

property failed_tool_calls: list[ToolCallRecord]

List of tool calls that resulted in errors.

to_dict()[source]

Convert to dictionary for serialization.

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Parameters:

data (dict[str, Any])

Return type:

AgentResult

class ResponseValidator(client, model=None, temperature=0.1)[source]

Bases: object

Validates LLM responses using a second LLM as judge.

Usage:

validator = ResponseValidator(client) result = validator.validate(

response=”The answer is 42”, criteria=”Must provide a numerical answer”,

) if result.passed:

print(“Response is valid”)

Parameters:
  • client (FFAIClientBase) – FFAIClientBase used for validation LLM calls.

  • model (str | None) – Model to use for validation (defaults to client model).

  • temperature (float) – Temperature for validation calls (low for consistency).

validate(response, criteria, max_retries=2, re_execute_fn=None)[source]

Validate a response against criteria.

Parameters:
  • response (str) – The response text to validate.

  • criteria (str) – Validation criteria description.

  • max_retries (int) – Maximum re-execution attempts on failure.

  • re_execute_fn (Any | None) – Optional callable that accepts an augmented prompt and returns a new response string. If provided, failed validations trigger re-execution with the rejection reason.

Returns:

ValidationResult with pass/fail status and critique.

Return type:

ValidationResult

class ToolCallRecord(round, tool_name, tool_call_id='', arguments=<factory>, result='', duration_ms=0.0, error=None)[source]

Bases: object

Record of a single tool call within an agentic loop.

Parameters:
round

The round number (1-indexed) when this call was made.

Type:

int

tool_name

Name of the tool that was called.

Type:

str

tool_call_id

Provider-specific ID for the tool call.

Type:

str

arguments

Arguments passed to the tool.

Type:

dict[str, Any]

result

The tool’s return value as a string.

Type:

str

duration_ms

Wall-clock duration of tool execution in milliseconds.

Type:

float

error

Error message if the tool execution failed, None otherwise.

Type:

str | None

round: int
tool_name: str
tool_call_id: str = ''
arguments: dict[str, Any]
result: str = ''
duration_ms: float = 0.0
error: str | None = None
to_dict()[source]

Convert to dictionary for serialization.

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Parameters:

data (dict[str, Any])

Return type:

ToolCallRecord

Classes

class AgentLoop(client, tool_registry, max_rounds=5, tool_timeout=30.0, continue_on_tool_error=True)[source]

Bases: object

Executes agentic tool-call loops for a single prompt.

Usage:

loop = AgentLoop(client, tool_registry, max_rounds=5) result = loop.execute(

prompt=”Search for information about X”, tools=[“search_tool”, “calculate”],

)

Parameters:
__init__(client, tool_registry, max_rounds=5, tool_timeout=30.0, continue_on_tool_error=True)[source]

Initialize the agent loop.

Parameters:
  • client (FFAIClientBase) – AI client to use for LLM calls.

  • tool_registry (ToolRegistry) – Registry of tools available for execution.

  • max_rounds (int) – Maximum number of tool-call rounds.

  • tool_timeout (float) – Timeout in seconds for individual tool execution.

  • continue_on_tool_error (bool) – Whether to continue the loop if a tool fails.

Return type:

None

execute(prompt, tools, tool_choice='auto', **kwargs)[source]

Execute the agentic loop.

Calls the LLM with the prompt and available tools. If the response contains tool calls, executes them and feeds results back. Repeats until no tool calls or max_rounds is reached.

Parameters:
  • prompt (str) – The user prompt.

  • tools (list[str]) – List of tool names to make available.

  • tool_choice (str) – Tool selection strategy (“auto”, “none”, etc.).

  • **kwargs (Any) – Additional parameters passed to generate_response().

Returns:

AgentResult with response, tool call records, and round/LLM counts.

Return type:

AgentResult

class AgentResult(response='', tool_calls=<factory>, total_rounds=0, total_llm_calls=0, status='success')[source]

Bases: object

Result of an agentic execution loop.

Parameters:
response

The final response text from the LLM.

Type:

str

tool_calls

List of tool call records from all rounds.

Type:

list[ffai.agent.agent_result.ToolCallRecord]

total_rounds

Number of rounds executed.

Type:

int

total_llm_calls

Total number of LLM API calls made.

Type:

int

status

Execution status - “success”, “failed”, or “max_rounds_exceeded”.

Type:

Literal[‘success’, ‘failed’, ‘max_rounds_exceeded’]

response: str = ''
tool_calls: list[ToolCallRecord]
total_rounds: int = 0
total_llm_calls: int = 0
status: Literal['success', 'failed', 'max_rounds_exceeded'] = 'success'
property tool_calls_count: int

Total number of tool calls made.

property last_tool_name: str

Name of the last tool called, or empty string if no tools used.

property failed_tool_calls: list[ToolCallRecord]

List of tool calls that resulted in errors.

to_dict()[source]

Convert to dictionary for serialization.

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Parameters:

data (dict[str, Any])

Return type:

AgentResult

class ResponseValidator(client, model=None, temperature=0.1)[source]

Bases: object

Validates LLM responses using a second LLM as judge.

Usage:

validator = ResponseValidator(client) result = validator.validate(

response=”The answer is 42”, criteria=”Must provide a numerical answer”,

) if result.passed:

print(“Response is valid”)

Parameters:
  • client (FFAIClientBase) – FFAIClientBase used for validation LLM calls.

  • model (str | None) – Model to use for validation (defaults to client model).

  • temperature (float) – Temperature for validation calls (low for consistency).

validate(response, criteria, max_retries=2, re_execute_fn=None)[source]

Validate a response against criteria.

Parameters:
  • response (str) – The response text to validate.

  • criteria (str) – Validation criteria description.

  • max_retries (int) – Maximum re-execution attempts on failure.

  • re_execute_fn (Any | None) – Optional callable that accepts an augmented prompt and returns a new response string. If provided, failed validations trigger re-execution with the rejection reason.

Returns:

ValidationResult with pass/fail status and critique.

Return type:

ValidationResult

class ToolCallRecord(round, tool_name, tool_call_id='', arguments=<factory>, result='', duration_ms=0.0, error=None)[source]

Bases: object

Record of a single tool call within an agentic loop.

Parameters:
round

The round number (1-indexed) when this call was made.

Type:

int

tool_name

Name of the tool that was called.

Type:

str

tool_call_id

Provider-specific ID for the tool call.

Type:

str

arguments

Arguments passed to the tool.

Type:

dict[str, Any]

result

The tool’s return value as a string.

Type:

str

duration_ms

Wall-clock duration of tool execution in milliseconds.

Type:

float

error

Error message if the tool execution failed, None otherwise.

Type:

str | None

round: int
tool_name: str
tool_call_id: str = ''
arguments: dict[str, Any]
result: str = ''
duration_ms: float = 0.0
error: str | None = None
to_dict()[source]

Convert to dictionary for serialization.

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Create from dictionary.

Parameters:

data (dict[str, Any])

Return type:

ToolCallRecord