Immutable definition of an AI agent, parsed from an XML file. An AgentDef supplies the system prompt (instructions), the events and timers it responds to, the functions it may call, and the workflows it can run; AgentService loads these from bundled app resources and per-tenant overrides, and AgentManager instantiates them as Agent instances that act on behalf of a user. An AgentDef is scoped to a list of user groups, and users may be permitted to override specific properties (such as a timer's schedule) rather than the whole definition. All mutation happens through withXXX methods that return a new copy, since the parsed definition itself never changes. Written as the agent element, the root of an agent XML file.

Group: AI Agents


Properties

PropertyReturnsDescription
allowedOverridesList<String>Which properties of this definition a user is allowed to override, and how. Each entry is of the form property=mode1,mode2 where property is the name of a property on AgentDef and each mode is one of add, edit or remove.
allowPlanningbooleanWhether this agent may spend a call deciding an approach before it acts. Off unless authored, because planning is a real cost paid on every turn and most agents answer questions rather than carry out multi-step work, for which the round trip buys nothing. Turning it on does not mean every turn is planned: the plan call's first job is to say whether the task needs one, so a definition that allows planning still skips it for the trivial questions it is mostly asked.
assetTypeNameStringThe asset type name used to find the list of Assets the agent draws on as knowledge.
attributesMap<String,Serializable>Arbitrary name/value pairs attached to this definition.
availableSubAgentsList<String>The specialists this agent may delegate to, identified by AgentDef name. This is an explicit allow list for the same reason functions is one, a level up: which specialists this agent may use, rather than implicitly every specialist the tenant happens to have. Empty or null for a specialist agent, which delegates to nobody.
descriptionStringWhat this agent is for, in one line, written for a different agent's planning to read when deciding whether to delegate here. Distinct from the title (a display name) and the instructions (the system prompt used when running as this agent) - this is the compressed substitute for knowing the specialist's tools, letting a root agent route correctly without holding the whole tool catalogue in context.
eventsList<AgentDefEventHandler>The event handlers this agent responds to. An account may add its own, replace one the app declares by name, or disable one, without taking a copy of the definition - see AgentManager.saveAccountEventHandlers.
functionsList<String>Names of the functions this agent is permitted to call.
groupsList<String>Names of the user groups whose members may use this agent. A user only needs to belong to one of them.
instructionsStringThe system prompt for this agent. May be templated with kcode, which is evaluated before the prompt is sent.
journeysList<String>Names of the journeys this agent is allowed to start in order to carry out a workflow.
modelStringAn exact model name this agent must run on, overriding {@link #getModelTier()}. <p> An escape hatch, not the normal case: it is right when an agent has been tuned against one model's specific behaviour, or when reproducing a problem on a named model. Left set, it also means the agent silently keeps running an old model after better ones arrive, which is the failure tiers exist to prevent - so prefer a tier unless there is a reason not to.
modelTierStringWhat kind of model this agent needs, as a {@code LlmModelTier} name - {@code fast}, {@code balanced} or {@code deep}. <p> This is the field to set. It says what the agent's work is like, which does not change, rather than which model does it best today, which does: a tier is re-resolved on every run, so an agent picks up a better model when one is enabled without its definition being touched. Naming a model outright - see {@link #getModel()} - pins the agent to it and opts out of that.
nameStringPortable identifier for this definition, taken from the name of the XML file it was parsed from, including the .xml suffix.
overrideGenerationIntegerWhich generation of the definition model this stored override was saved against, or null if it predates generations. <p> The problem this exists for: until definitions came from apps, a copy was written into every tenant on first use. Those copies override what the app supplies, and a stored copy wins outright - so a tenant that never customised anything was nonetheless pinned forever to whatever the definition looked like on the day it was first used. When the definition then changes shape - as it did when the root agent stopped holding domain tools and started delegating - those tenants silently keep the old shape, and get an agent that no longer works the way it is designed to. <p> So an override has to say which world it was written for. One saved against an older generation is <b>superseded</b>: it is kept, and still visible, but it no longer overrides the app. Saving it again adopts it into the current generation, which is what an administrator who does want their version does.
skillsList<AgentSkillDef>The skills this agent may read, ie short reference documents it pulls into context only when the task calls for one. <p> Distinct from {@link #getAssetTypeName() knowledge assets}, which are loaded whole into every turn. A skill is the opposite trade: only its name, purpose and keywords are standing context, and the body is fetched by the agent when it decides it is relevant. That makes a skill the right home for material that is long, that only some tasks need, and that would otherwise crowd out the conversation - a query cookbook, a house style, the steps of an occasional procedure. <p> They live on the definition rather than being uploaded per tenant because definitions come from apps and have no per-tenant instantiation: a skill has to travel with the agent that knows how to use it.
timersList<AgentDefTimer>The timers this agent responds to, each firing its own instructions on a recurring schedule.
titleStringDisplay title for this agent, shown to users choosing or configuring an agent.
workflowsList<AgentWorkflowDef>The workflows this agent is able to execute, each a named series of steps.

Methods

withTitle(String newTitle) · withInstructions(String newInstructions) · withTimers(List<AgentDefTimer> timerList) · withEvents(List<AgentDefEventHandler> eventList) · withFunctions(List<String> functionList) · withAttributes(Map<String,Serializable> attributeMap) · getDescription() · withDescription(String newDescription) · getAvailableSubAgents() · withAvailableSubAgents(List<String> newAvailableSubAgents) · isAllowPlanning() · withAllowPlanning(Boolean newAllowPlanning) · withGroups(List<String> groupList) · withTimer(String timerName, String timerInstructions, int multiples, String units, String time) · withEvent(String eventName, String eventInstructions, String scope, Integer bufferSecs, Integer bufferSize) · getName() · getTitle() · getAssetTypeName() · getInstructions() · getTimers() · getEvents() · getWorkflows() · getFunctions() · getSkills() · withSkills(List<AgentSkillDef> skillList) · withSkill(String skillName, String skillTitle, String skillDescription, String keywords, String content) · withSkill(String skillName, String skillTitle, String skillDescription, String keywords, String content, Boolean alwaysRead) · getAttributes() · getJourneys() · getGroups() · getAllowedOverrides() · timer(String timerName) · event(String eventDefName)

withTitle(String newTitle)

Returns: AgentDef

Returns a copy of this definition with the given display title.

ParameterDescription
newTitlethe display title

withInstructions(String newInstructions)

Returns: AgentDef

Returns a copy of this definition with the given instructions, ie system prompt.

ParameterDescription
newInstructionsthe instructions text, which may be templated with kcode

withTimers(List<AgentDefTimer> timerList)

Returns: AgentDef

Returns a copy of this definition with the given list of timers, replacing any existing timers.

ParameterDescription
timerListthe timers to set; copied, so later changes to the caller's list do not leak in

withEvents(List<AgentDefEventHandler> eventList)

Returns: AgentDef

Returns a copy of this definition with the given list of event handlers, replacing any existing handlers.

ParameterDescription
eventListthe event handlers to set; copied, so later changes to the caller's list do not leak in

withFunctions(List<String> functionList)

Returns: AgentDef

Returns a copy of this definition with the given list of allowed function names, replacing any existing functions.

ParameterDescription
functionListnames of the functions this agent may call; copied, so later changes to the caller's list do not leak in

withAttributes(Map<String,Serializable> attributeMap)

Returns: AgentDef

Returns a copy of this definition with the given arbitrary name/value pairs, following the same immutable-wither pattern used throughout this class.

ParameterDescription
attributeMapthe attributes to set; copied, so later changes to the caller's map do not leak in

getDescription()

Returns: String

What this agent is for, in one line, written for a different agent's planning to read when deciding whether to delegate here. Distinct from the title (a display name) and the instructions (the system prompt used when running as this agent) - this is the compressed substitute for knowing the specialist's tools, letting a root agent route correctly without holding the whole tool catalogue in context.

withDescription(String newDescription)

Returns: AgentDef

Returns a copy of this definition with the given routing description.

ParameterDescription
newDescriptionthe routing description

getAvailableSubAgents()

Returns: List<String>

The specialists this agent may delegate to, identified by AgentDef name. This is an explicit allow list for the same reason functions is one, a level up: which specialists this agent may use, rather than implicitly every specialist the tenant happens to have. Empty or null for a specialist agent, which delegates to nobody.

withAvailableSubAgents(List<String> newAvailableSubAgents)

Returns: AgentDef

Returns a copy of this definition with the given list of delegate specialists.

ParameterDescription
newAvailableSubAgentsspecialist AgentDef names this agent may delegate to

isAllowPlanning()

Returns: boolean

Whether this agent may spend a call deciding an approach before it acts. Off unless authored, because planning is a real cost paid on every turn and most agents answer questions rather than carry out multi-step work, for which the round trip buys nothing. Turning it on does not mean every turn is planned: the plan call's first job is to say whether the task needs one, so a definition that allows planning still skips it for the trivial questions it is mostly asked.

withAllowPlanning(Boolean newAllowPlanning)

Returns: AgentDef

Returns a copy of this definition with the given planning permission.

ParameterDescription
newAllowPlanningwhether planning is permitted; null is the same as false

withGroups(List<String> groupList)

Returns: AgentDef

Returns a copy of this definition restricted to the given user groups.

ParameterDescription
groupListnames of the groups whose members may use this agent

withTimer(String timerName, String timerInstructions, int multiples, String units, String time)

Returns: AgentDef

Returns a copy of this definition with an additional timer appended to its existing timers.

ParameterDescription
timerNameportable identifier for the new timer
timerInstructionsinstructions to run when the timer fires
multipleshow many units between firings, eg 3 for "every 3 days"
unitsthe time unit the timer runs on, one of the values returned by getTimerUnits
timeif set, the time of day the timeout is adjusted to

withEvent(String eventName, String eventInstructions, String scope, Integer bufferSecs, Integer bufferSize)

Returns: AgentDef

Returns a copy of this definition with an additional event handler appended to its existing handlers.

ParameterDescription
eventNamethe funnel event name to listen for
eventInstructionsinstructions to run when the event fires
scopenull to match the event regardless of profile, or a scope constant such as SCOPE_CUST_PROFILE to match only events for the lead's own profile
bufferSecsif set, buffer matching events for up to this many seconds before firing with the recorded events
bufferSizeif set, buffer up to this many matching events before firing

getName()

Returns: String

Portable identifier for this definition, taken from the name of the XML file it was parsed from, including the .xml suffix.

getTitle()

Returns: String

Display title for this agent, shown to users choosing or configuring an agent.

getAssetTypeName()

Returns: String

The asset type name used to find the list of Assets the agent draws on as knowledge.

getInstructions()

Returns: String

The system prompt for this agent. May be templated with kcode, which is evaluated before the prompt is sent.

getTimers()

Returns: List<AgentDefTimer>

The timers this agent responds to, each firing its own instructions on a recurring schedule.

getEvents()

Returns: List<AgentDefEventHandler>

The event handlers this agent responds to. An account may add its own, replace one the app declares by name, or disable one, without taking a copy of the definition - see AgentManager.saveAccountEventHandlers.

getWorkflows()

Returns: List<AgentWorkflowDef>

The workflows this agent is able to execute, each a named series of steps.

getFunctions()

Returns: List<String>

Names of the functions this agent is permitted to call.

getSkills()

Returns: List<AgentSkillDef>

The skills this agent may read, ie short reference documents it pulls into context only when the task calls for one. <p> Distinct from {@link #getAssetTypeName() knowledge assets}, which are loaded whole into every turn. A skill is the opposite trade: only its name, purpose and keywords are standing context, and the body is fetched by the agent when it decides it is relevant. That makes a skill the right home for material that is long, that only some tasks need, and that would otherwise crowd out the conversation - a query cookbook, a house style, the steps of an occasional procedure. <p> They live on the definition rather than being uploaded per tenant because definitions come from apps and have no per-tenant instantiation: a skill has to travel with the agent that knows how to use it.

withSkills(List<AgentSkillDef> skillList)

Returns: AgentDef

Returns a copy of this definition with the given skills, replacing any existing ones.

ParameterDescription
skillListthe skills to set; copied, so later changes to the caller's list do not leak in

withSkill(String skillName, String skillTitle, String skillDescription, String keywords, String content)

Returns: AgentDef

Returns a copy of this definition with one more skill appended to its existing ones.

ParameterDescription
skillNamethe identifier the agent names when it reads this skill, eg {@code chart-playbook}
skillTitlea display title
skillDescriptionone line saying what the skill covers, shown to the agent in its instructions
keywordscomma separated words and phrases that should make the agent reach for this skill
contentthe skill itself, as markdown. Second level headings become the sections a partial read can ask for

withSkill(String skillName, String skillTitle, String skillDescription, String keywords, String content, Boolean alwaysRead)

Returns: AgentDef

Returns a copy of this definition with one more skill appended, saying whether it is standing context.

ParameterDescription
skillNamethe identifier the agent names when it reads this skill
skillTitlea display title
skillDescriptionone line saying what the skill covers
keywordscomma separated words and phrases that should make the agent reach for this skill
contentthe skill itself, as markdown
alwaysReadtrue to put the whole body in front of the agent every turn rather than indexing it - see {@link AgentSkillDef#isAlwaysRead()}

getAttributes()

Returns: Map<String,Serializable>

Arbitrary name/value pairs attached to this definition.

getJourneys()

Returns: List<String>

Names of the journeys this agent is allowed to start in order to carry out a workflow.

getGroups()

Returns: List<String>

Names of the user groups whose members may use this agent. A user only needs to belong to one of them.

getAllowedOverrides()

Returns: List<String>

Which properties of this definition a user is allowed to override, and how. Each entry is of the form property=mode1,mode2 where property is the name of a property on AgentDef and each mode is one of add, edit or remove.

timer(String timerName)

Returns: AgentDefTimer

Finds the timer with the given name among this definition's timers.

ParameterDescription
timerNamethe timer's name to look up

event(String eventDefName)

Returns: AgentDefEventHandler

Finds the event handler with the given name among this definition's event handlers.

ParameterDescription
eventDefNamethe event handler's name to look up
To get full access to the Kademi Hub existing customers can login here, or new customers can register here.