Execution state for one run of an Agent's gather, plan, act and verify loop, as driven by the AgentOrchestrator. The row holds only the small pointer and status fields needed to find, claim and resume a run. The payload - the plan so far, the tool call awaiting consent, budget counters - is not stored here; it lives as a JSON blob in content storage under agent-runs, and the LLM message history stays in ai-lib's conversation storage, referenced by the conversation id. State changes go through the claim, pause, complete, fail and expire transitions rather than by setting status directly, because the claim is what stops two processes from processing the same paused run. The entity is not exported to script code apart from rowId, so an app cannot drive or forge a run's state machine.

Group: Database Entities

Implements: Serializable, Relational


Properties

PropertyReturnsDescription
adminOrgOrganisationThe tenant this run belongs to, copied from the agent when the run is created so the expiry sweep can filter by organisation without joining to the agent. Never null for a persisted run.
agentAgentThe agent this run executes on behalf of. The agent's owner supplies the security context every phase of the run executes under. Never null for a persisted run.
awaitingSinceDate
channelStringWhich channel this run reaches its owner through, given as the sourceApp identifier, for example Slack or admin-lib. The expiry sweep runs off a timer with no request and no conversation in hand, so this is what lets it announce an expiry back over the channel the consent request went out on.
chatItemIdStringThe chat item carrying the consent block this run is waiting on, set when the run pauses for consent. This is a pointer only: the tool name, its arguments and the already-executed flag all live on that chat item, which is what the UI renders and what a resume validates against, so there is exactly one record of what was approved.
claimedAtDate
completedDateDate
conversationIdStringOpaque key into ai-lib's conversation storage holding the message history for this run. The messages themselves are not duplicated onto this row. Null for a run with no conversation behind it.
correlationTokenStringOpaque token generated when the run is created and embedded in outbound consent requests, so a reply arriving over an async channel can be matched back to this run. Unique across all runs and never null.
createdDateDate
currentPhaseStringWhich step of the orchestrator loop this run has reached: gather, plan, act or verify, matching the PHASE constants on this class. A new run starts in gather.
expiresAtDate
idlongDatabase identifier for this run, assigned when the run is first saved.
lastErrorStringShort diagnostic message recorded when the run failed, truncated to 2000 characters. Null unless the run has failed.
modifiedDateDate
parentRunAgentRunThe run which delegated to this one, when this run is a sub-agent. Null for a root run started directly rather than by delegation.
pendingSpecialistStringThe specialist whose delegated run asked for the gated call, when the consent request arose inside a delegation. This matters on resume rather than being merely descriptive: a specialist's tools are not in the delegating agent's own whitelist, so the approved call has to be re-delegated to that specialist instead of being run directly.
pendingToolIdStringThe model's call id for the gated tool call, ie which request on the pending chat item this run is waiting on. Set only while the run is awaiting consent.
replyParamsStringThe channel's own routing information as JSON - a Slack channel and thread, an email address, or whatever else that channel needs to deliver a message. Channels are marketplace apps that own their own protocols, so the value is carried and handed back untouched and is never interpreted here.
statusStringWhere the run sits in its lifecycle: running, awaiting_consent, completed, failed or expired, matching the STATUS constants on this class. Only the state transition methods change it.

Methods

getId() · getAgent() · getAdminOrg() · getParentRun() · getConversationId() · getChatItemId() · getPendingToolId() · getPendingSpecialist() · getChannel() · getReplyParams() · getCurrentPhase() · getStatus() · getCorrelationToken() · getLastError() · rowId()

getId()

Returns: long

Database identifier for this run, assigned when the run is first saved.

getAgent()

Returns: Agent

The agent this run executes on behalf of. The agent's owner supplies the security context every phase of the run executes under. Never null for a persisted run.

getAdminOrg()

Returns: Organisation

The tenant this run belongs to, copied from the agent when the run is created so the expiry sweep can filter by organisation without joining to the agent. Never null for a persisted run.

getParentRun()

Returns: AgentRun

The run which delegated to this one, when this run is a sub-agent. Null for a root run started directly rather than by delegation.

getConversationId()

Returns: String

Opaque key into ai-lib's conversation storage holding the message history for this run. The messages themselves are not duplicated onto this row. Null for a run with no conversation behind it.

getChatItemId()

Returns: String

The chat item carrying the consent block this run is waiting on, set when the run pauses for consent. This is a pointer only: the tool name, its arguments and the already-executed flag all live on that chat item, which is what the UI renders and what a resume validates against, so there is exactly one record of what was approved.

getPendingToolId()

Returns: String

The model's call id for the gated tool call, ie which request on the pending chat item this run is waiting on. Set only while the run is awaiting consent.

getPendingSpecialist()

Returns: String

The specialist whose delegated run asked for the gated call, when the consent request arose inside a delegation. This matters on resume rather than being merely descriptive: a specialist's tools are not in the delegating agent's own whitelist, so the approved call has to be re-delegated to that specialist instead of being run directly.

getChannel()

Returns: String

Which channel this run reaches its owner through, given as the sourceApp identifier, for example Slack or admin-lib. The expiry sweep runs off a timer with no request and no conversation in hand, so this is what lets it announce an expiry back over the channel the consent request went out on.

getReplyParams()

Returns: String

The channel's own routing information as JSON - a Slack channel and thread, an email address, or whatever else that channel needs to deliver a message. Channels are marketplace apps that own their own protocols, so the value is carried and handed back untouched and is never interpreted here.

getCurrentPhase()

Returns: String

Which step of the orchestrator loop this run has reached: gather, plan, act or verify, matching the PHASE constants on this class. A new run starts in gather.

getStatus()

Returns: String

Where the run sits in its lifecycle: running, awaiting_consent, completed, failed or expired, matching the STATUS constants on this class. Only the state transition methods change it.

getCorrelationToken()

Returns: String

Opaque token generated when the run is created and embedded in outbound consent requests, so a reply arriving over an async channel can be matched back to this run. Unique across all runs and never null.

getLastError()

Returns: String

Short diagnostic message recorded when the run failed, truncated to 2000 characters. Null unless the run has failed.

rowId()

Returns: Long

The database identifier for this run, as the generic row id used across Kademi entities. Same value as the id.

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