Poll an agent's logs from the Invoke Agent block
Learn how to poll an agent's logs from a workflow.
Retool Agents Availability | |||
---|---|---|---|
Cloud-hosted | Public beta | ||
Self-hosted (3.280 Edge) | Public beta | ||
Self-hosted (3.196 Stable and later) |
You can view the results of the agent's output with the Result (sync) type. Or, you can poll an agent from an Invoke Agent block to retrieve log information or an agent's response with the Run state (async) type.
Invoke agent
Complete the following steps to add and configure an Invoke Agent block:
- Click and drag to create a new, connected block.
- Select Invoke Agent as the type of block.
- Set Agent to the agent you want to call.
Multi-step functions in agentic workflows
You can write a multi-step function to retrieve the agent's response.
- Create a new function, and name it
getAgentLogs
. - Add two parameters:
agentRunId
andagentId
. - Set the Type to Multi-step. Click the Edit function button to navigate to the multi-step function control flow.
- Click and drag to create a new, connected block.
- Select Invoke Agent as the type of block. Name the block
requestAgentLogs
. - Set the Agent to the agent you want to call.
- Set the Return type to Run state (async).
- Choose JSON as the Input Mode and set the Agent Inputs to the following:
{
"action": "getLogs",
"agentRunId": {{ params.agentRunId }}
}
- Add a Response block with a Status code of
200
and return the following:requestAgentLogs.data
.

The multi-step function
Poll the agent for results
Once you've created a multi-step workflow, you can poll the agent logs for results. There's no need to do this if you are simply using the workflow to trigger the agent invocation.
- Click and drag to create a new, connected block.
- Select the Code block type, and name the block
pollForAgentLogs
. - Paste in the following JavaScript code snippet to populate your block:
// Defines the polling interval (500ms), the max number of attempts (30), and the statuses that indicate the agent is still running (PENDING, IN_PROGRESS).
const SLEEP_DURATION_IN_MS = 500;
const MAX_ITERATIONS = 30;
const AGENT_PENDING_STATUSES = ["PENDING", "IN_PROGRESS"];
// A utility function that returns a promise which resolves after 500ms (used for pausing between polls).
const sleep = () => new Promise(resolve => setTimeout(resolve, SLEEP_DURATION_IN_MS));
// Extracts the agentId and agentRunId from the invokeAgent block. Initializes latestAgentStatus as "PENDING". latestAgentLogs will store the last retrieved logs, and iterations tracks the number of attempts.
const { agentId, agentRunId } = invokeAgent.data;
let latestAgentStatus = "PENDING"; // Initial assumption
let latestAgentLogs;
let iterations = 1;
// Keeps polling as long as the agent is in a pending state and hasn’t exceeded the maximum attempts.
while (AGENT_PENDING_STATUSES.includes(latestAgentStatus) && iterations <= MAX_ITERATIONS) {
console.log(`Beginning iteration ${iterations}/${MAX_ITERATIONS}`);
try {
// Call the multi-step function
const agentLogs = await getAgentLogs(agentRunId, agentId);
console.log({ agentLogs });
latestAgentStatus = agentLogs.data.status;
latestAgentLogs = agentLogs;
} catch (err) {
throw new Error(`Failed to fetch agent logs on iteration ${iterations}: ${err.message}`);
}
// If still pending, wait before the next iteration. If not, exit the loop early.
if (AGENT_PENDING_STATUSES.includes(latestAgentStatus)) {
await sleep();
} else {
break;
}
iterations += 1;
}
// If the status is still not complete after 30 tries, throw an error.
if (AGENT_PENDING_STATUSES.includes(latestAgentStatus)) {
throw new Error(`Agent status is still ${latestAgentStatus} after 30 polling ${MAX_ITERATIONS} attempts.`);
}
// Return the agent response.
return latestAgentLogs;
- Open the Settings, and update the Retry count and Interval (ms). This example uses a Retry count of 1 and an Interval (ms) of 1000.

Polling for agent results