Skip to Content
Core EngineexecuteStep

executeStep

Problem

Inside a ReAct loop, each individual step — calling the provider, checking for tool calls, executing tools, and updating the conversation — has to be coordinated carefully. Doing this manually in every agent adds complexity and breaks separation of concerns.


Solution

executeStep handles one complete step of the agent loop. It calls your provider, detects tool calls, runs the matching tools, appends results to the conversation, and tells the loop whether the agent is finished or needs another step.

You typically do not call this directly. reActLoop calls it internally on every iteration. But it is exported so you can use it in custom loop implementations.


Feature & Use-Case

Use executeStep directly when:

  • You are building a custom agent loop with special exit conditions
  • You need step-level control — pause between steps, inspect conversation state, or log per-step output
  • You want to wrap each step with your own retry or permission logic

Import

import { executeStep } from "llm-layer-engine";

Function Signature

async function executeStep(input: StepInput): Promise<{ conversation: Message[]; toolCalls: number; errors: number; isFinished: boolean; finalResult: string; }>

Parameters (StepInput)

ParameterTypeRequiredDescription
providerLLMProviderYour LangChain-compatible provider
configAgentConfigModel name, temperature, provider ref
toolsTool[]Tools the provider can call (pass [] if none)
conversationMessage[]Full current conversation history

Return Value

FieldTypeDescription
conversationMessage[]Updated conversation after this step
toolCallsnumberHow many tool calls happened in this step
errorsnumber1 if the step threw an error, else 0
isFinishedbooleantrue when agent has a final text answer
finalResultstringThe agent’s final answer (empty if not finished)

Example — Custom Loop with Step Inspection

import { executeStep } from "llm-layer-engine"; import type { LLMProvider, Message, Tool, AgentConfig } from "llm-layer-engine"; const config: AgentConfig = { provider: myProvider, model: "claude-3-5-sonnet-20241022", temperature: 0.6, }; let conversation: Message[] = [ { role: "system", content: "You are a helpful assistant." }, { role: "user", content: "Search for the latest Node.js version." }, ]; const tools: Tool[] = [searchTool]; let stepCount = 0; const maxSteps = 6; while (stepCount < maxSteps) { const step = await executeStep({ provider: myProvider, config, tools, conversation, }); // Inspect mid-loop console.log(`Step ${stepCount + 1} — toolCalls: ${step.toolCalls}`); conversation = step.conversation; stepCount++; if (step.isFinished) { console.log("Final Answer:", step.finalResult); break; } }

Conclusion

executeStep is the atomic unit of the ReAct loop. For most use-cases, let reActLoop manage it. Reach for executeStep directly only when you need fine-grained control over loop behavior — custom pause logic, per-step logging, or conditional early exits.

Last updated on