Collects the settings for one agent turn, obtained from AgentOrchestratorManager.newRun and run by calling execute. Not thread safe, and intended to be used once and discarded. Annotated because the script sandbox's class filter whitelists by class, not by what returned it - without this, script code could call newRun but not then use what it got back. Same reason AgentManager.AgentDefBuilder carries it.

Group: Builders


Methods

requiredTools(List<String> requiredTools) · persistAs(Long agentId, String conversationId) · resumingConsentOn(String chatItemId, String toolId) · approvedCall(String toolName, String argumentsJson, String callId) · instructions(String instructions) · userMessage(String userMessage) · history(List<Map<String,Object>> history) · budgetBoost(Integer budgetBoost) · reasoningEffort(String reasoningEffort) · modelTier(String modelTier) · functions(List<String> functions) · sourceApp(String sourceApp) · profileId(String profileId) · execute()

requiredTools(List<String> requiredTools)

Returns: RunBuilder

Names tools this turn is not finished without, so Verify can send the run back to Plan if the model claimed the work without doing it. This is where FunctionCallAgentWorkflowStepCompletionType - "did function X get called" - maps onto the phase model. Left unset for open-ended chat, where there is no such thing as a required call.

ParameterDescription
requiredToolstool names as the model would call them, or null for none

persistAs(Long agentId, String conversationId)

Returns: RunBuilder

Records this turn against a persisted AgentRun, so the run has a durable identity beyond the request that started it. Optional: without it the loop still runs, just with no row - which is what the orchestrator's own unit tests do, and what a caller that has nothing to resume can keep doing. With it, a run that pauses for consent can be picked up later from any node.

ParameterDescription
agentIdthe {@code Agent} this run acts for
conversationIdthe ai-lib conversation this turn belongs to, so a resume can find its way back to the transcript

resumingConsentOn(String chatItemId, String toolId)

Returns: RunBuilder

Marks this turn as continuing the run that paused on a given consent request, rather than starting a new one. The in-page confirm button posts the chat item and tool id, not a token, so the run is found from those. Getting this wrong is not cosmetic: the paused row would never settle, and the expiry sweep would later close a request the owner had actually approved. Falls back to a fresh run if nothing matches - a conversation that paused before runs were persisted still has to be approvable.

ParameterDescription
chatItemIdthe chat item carrying the consent block
toolIdthe model's call id for the gated call

approvedCall(String toolName, String argumentsJson, String callId)

Returns: RunBuilder

Resumes a run the owner paused by approving a consent-gated call. The approved call runs first and exactly as approved - no fresh planning turn - so what executes is what the owner was shown. Establishing that the approval is genuine, and that it has not already been used, is the caller's job: by the time it reaches here it is taken as given.

ParameterDescription
toolNamethe tool that was approved, as the model originally named it
argumentsJsonthe exact arguments it was approved to run with
callIdthe model's original call id, so the replayed call pairs with its result

instructions(String instructions)

Returns: RunBuilder

Sets the system prompt for this turn.

ParameterDescription
instructionsthe assembled system prompt for this agent

userMessage(String userMessage)

Returns: RunBuilder

Sets this turn's user prompt.

ParameterDescription
userMessagethe prompt for this turn, or null if the instructions are self-contained

history(List<Map<String,Object>> history)

Returns: RunBuilder

Seeds the prior turns of the conversation, so the model has memory of what came before this one.

ParameterDescription
historythe conversation so far as Responses API input items, as ai-lib's {@code ConversationContext} assembles them, or null for a run with no memory. These are sent to the model but are not echoed back in the result, so the caller does not re-persist them

budgetBoost(Integer budgetBoost)

Returns: RunBuilder

Multiplies this run's ceilings, for work nobody is waiting on. The standard budget is sized for an interactive turn. A run started by an event handler is not one: it runs unattended and is often asked a question that takes real digging. See {@link AgentBudget.Builder#budgetBoost} for why the spawn count is deliberately left alone.

ParameterDescription
budgetBoostthe multiple, clamped to 1..{@link AgentBudget#MAX_BUDGET_BOOST}, or null for the standard budget

reasoningEffort(String reasoningEffort)

Returns: RunBuilder

How hard this run should think, overriding what the definitions involved ask for. Effort is normally a per-phase property of a definition, tuned for what that phase usually does - Act, in particular, defaults to {@code low} because it is mostly deciding which tool to call next. That reasoning does not hold for every kind of work: in an investigation, deciding what to look at next <i>given what just came back</i> is the analysis, not a mechanical step. This is how a caller says which kind of run this is. Applies to every phase, and is passed down to any specialist this run delegates to - the specialist is where the work happens, so an override that stopped at the root would change nothing that matters.

ParameterDescription
reasoningEffortan effort such as {@code high}, or null to leave each definition to its own settings

modelTier(String modelTier)

Returns: RunBuilder

Runs this turn on a given class of model, whatever the definitions involved ask for. For when something about the turn rather than about the agent decides what it is worth spending - an event handler whose job is forensics rather than a lookup. It applies to the specialists too: they are where the work happens, so an override that stopped at the root would change little.

ParameterDescription
modelTiera tier name such as {@code deep}, or null to let each definition choose

functions(List<String> functions)

Returns: RunBuilder

Restricts which tools this turn may call.

ParameterDescription
functionsthe agent's tool whitelist ({@code AgentDef.functions}), or null for no whitelist

sourceApp(String sourceApp)

Returns: RunBuilder

Names the app this turn runs on behalf of, so it can be reported on the Before/AfterPromptFunctionCall events.

ParameterDescription
sourceAppapp name, for the Before/AfterPromptFunctionCall events

profileId(String profileId)

Returns: RunBuilder

Names the profile acting for this turn, so it can be reported on the Before/AfterPromptFunctionCall events.

ParameterDescription
profileIdthe acting profile id, for those same events

execute()

Returns: Map<String,Object>

Runs one agent turn through the gather/plan/act/verify loop. All four phases do real work now. Gather loads the agent's knowledge assets, Plan states an approach when the definition allows it and the task is not trivial, Act carries it out, and Verify checks the result against both the required tools and the stated plan. An agent that configures neither knowledge nor planning still behaves as the legacy loop does, because both phases then skip.

To get full access to the Kademi Hub existing customers can login here, or new customers can register here.