AiAgent
Configure an AI Agent using the Fluent API. This API provides a structured interface for creating AI Agents in ServiceNow's AI Agent Studio, automatically handling all underlying complexity and relationships between multiple tables.
Overview
The AiAgent API enables you to define intelligent agents that can:
- Execute Tools: Use built-in or custom tools (CRUD, Script, RAG, Web Search, etc.)
- Process Context: Apply custom scripts to transform context before execution
- Control Access: Define role-based security and data access controls
- Trigger Automatically: Configure triggers for automatic agent invocation
- Manage Versions: Support multiple versions with different configurations
The plugin automatically generates all required ServiceNow records (~9 tables) with proper relationships and defaults.
Supported Record Types
Based on the metadata files generated by this plugin:
| Record Type | Table | Description |
|---|---|---|
| AI Agent | sn_aia_agent | Primary agent definition |
| AI Agent Config | sn_aia_agent_config | Agent configuration and settings |
| AI Agent Version | sn_aia_version | Version information for the agent |
| AI Agent Tool | sn_aia_tool | Tool definitions (script, CRUD, RAG, etc.) |
| AI Agent Tool M2M | sn_aia_agent_tool_m2m | Many-to-many relationship between agents and tools |
| Agent Access Role Configuration | sys_agent_access_role_configuration | Role-based data access controls |
| Trigger Configuration | sn_aia_trigger_configuration | Automated trigger definitions |
| Trigger Agent Usecase M2M | sn_aia_trigger_agent_usecase_m2m | Mapping between triggers, agents, and use cases |
API Parameters
Main Configuration
| Field Name | Type | Mandatory | Description |
|---|---|---|---|
$id | Now.ID[string] | Yes | Unique identifier for the agent |
name | string | Yes | Display name of the AI Agent |
description | string | Yes | Brief description of what the agent does |
agentRole | string | Yes | Role or purpose of the agent (e.g., "News research specialist") |
securityAcl | SecurityAclUserAccessConfig | Yes | MANDATORY - Automatically generates sys_security_acl and sys_security_acl_role records. Defines user access controls and role-based permissions for this agent |
active | boolean | No | Whether the agent is active (default: true) |
advancedMode | boolean | No | Enables advanced configuration options for power users (default: false) |
agentConfigSysOverrides | string | Record<'sn_aia_agent_config'> | No | Reference to override another agent config |
agentLearning | boolean | No | Enable agent learning from interactions (default: false) |
agentType | AiAgentAgentType | No | Type: 'internal', 'external', 'voice', or 'aia_internal' (default: 'internal') |
channel | AiAgentChannelType | No | Channel: 'nap' (Now Assist Panel) or 'nap_and_va' (Panel + Virtual Agent) (default: 'nap_and_va') |
compiledHandbook | string | No | Compiled handbook content for the agent |
condition | string | No | Condition table reference |
contextProcessingScript | ((context: any, ...dependencies: any[]) => any) | string | No | Server-side script that transforms or enriches context before agent execution |
dataAccess | DataAccessConfigType | No | Data access controls (required if runAsUser not set) |
docUrl | string | No | Documentation URL for the agent |
external | boolean | No | Whether the agent is external |
externalAgentConfiguration | string | Record<'sn_aia_external_agent_configuration'> | No | Reference to external agent configuration |
iconUrl | string | No | Icon URL for the agent in the UI |
memoryCategories | AiAgentMemoryCategory[] | No | Categories of long-term memory the agent may access: 'device_and_software', 'meetings_and_events', 'projects', 'workplace' |
parent | string | Record<'sn_aia_agent'> | No | Reference to the parent AI Agent |
postProcessingMessage | string | No | Message displayed after agent completes |
processingMessage | string | No | Message displayed while agent is processing |
public | boolean | No | Whether the agent is publicly accessible (default: false) |
recordType | AiAgentRecordType | No | Lifecycle stage: 'template', 'aia_internal', 'custom', or 'promoted' (default: 'template') |
runAsUser | string | Record<'sys_user'> | No | User to run the agent as (sys_user sys_id or Record reference). When set, dataAccess is optional |
sourceId | string | Record<'sn_aia_agent'> | No | Reference to source agent (for cloned agents) |
sysDomain | string | No | Domain ID |
tools | AiAgentToolDetailsType[] | No | Array of tools the agent can use |
triggerConfig | AiAgentTriggerConfigType[] | No | Array of trigger configurations for automatic invocation |
versionDetails | AiAgentVersionDetailsType[] | No | Array of version details with instructions |
Version Details (versionDetails)
Version information for the agent. This is an array that can contain multiple versions.
Key Fields:
name— Version name (e.g., "V1", "V2", "Production")number— Version number (e.g., 1, 2, 3)state— Version state:'draft','committed','published', or'withdrawn'instructions— Most important field — Detailed instructions that guide the agent's behavior, capabilities, and decision-making processcondition— Optional condition for when this version should be used
Data Access Controls (dataAccess)
MANDATORY when runAsUser is not set - Defines which roles the agent can inherit from the invoking user during execution.
When to Use:
- Use
dataAccesswhen you want the agent to run with dynamic user identity (inheriting roles from the invoking user) - Omit
dataAccesswhenrunAsUseris set to a specific user sys_id
Security ACL Configuration (securityAcl)
MANDATORY - Automatically generates sys_security_acl and sys_security_acl_role records for this agent. Controls who can invoke the agent.
Access Types
'Any authenticated user' — Any logged-in user can invoke this agent. No roles required.
'Specific role' — Only users who hold at least one of the listed roles can access. roles is required.
'Public' — No authentication required. Anyone can access.
Important Notes:
securityAclcontrols who can invoke the agent (access control)runAsUser/dataAccesscontrols which user identity the agent runs under (execution context) — these are separate concerns- The plugin automatically creates
sys_security_aclandsys_security_acl_rolerecords - The ACL name is derived from the agent's internal name:
{domain}.{scope}.{agentName}
Tools (tools)
Tools allow agents to perform actions during execution. The type field acts as a discriminator — required fields differ per tool type.
Tool Types
Each tool type uses a discriminated union on the type field:
type | Required extra field | Description |
|---|---|---|
'crud' | inputs: ToolInputType | Database CRUD operations (script is auto-generated) |
'script' | script | Custom server-side script |
'capability' | capabilityId | Now Assist skill |
'subflow' | subflowId | Flow Designer flow |
'action' | flowActionId | Flow Designer action |
'catalog' | catalogItemId | Service Catalog item |
'topic' | virtualAgentId | Virtual Agent topic |
'topic_block' | virtualAgentId | Virtual Agent topic block |
'web_automation' | (none) | OOB Web Search tool |
'knowledge_graph' | (none) | OOB Knowledge Graph tool |
'file_upload' | (none) | OOB File Uploader tool |
'rag' | (none) | OOB RAG Search Retrieval tool |
'deep_research' | (none) | Deep Research tool |
'desktop_automation' | (none) | Desktop Automation tool |
'mcp' | (none) | MCP tool |
Note: For script tools, inputs is a simple array of ToolInputField. For CRUD tools, inputs is a ToolInputType object. The SDK auto-generates the input_schema from inputs.
Trigger Configuration (triggerConfig)
Configure automatic agent invocation based on record changes or schedules.
Trigger Types
| Trigger Type | Description |
|---|---|
record_create | Triggers when a new record is created |
record_create_or_update | Triggers when a record is created or updated |
record_update | Triggers when an existing record is updated |
email | Triggers based on email events |
scheduled | Triggers at scheduled intervals |
daily | Triggers daily at a specified time |
weekly | Triggers weekly on a specified day |
monthly | Triggers monthly on a specified day |
Complete Example
Below example shows all the different configurations for an AI agent. It has different types of triggers supported and different types of tools supported.
import { AiAgent } from '@servicenow/sdk/core';
export const newsCollectorAgent = AiAgent({
$id: Now.ID['news_collector_agent'],
name: 'News Collector Agent',
description: 'AI agent that searches for and saves news articles',
agentRole: 'News research specialist',
// Core properties
recordType: 'custom',
channel: 'nap_and_va',
processingMessage: 'Searching for news...',
postProcessingMessage: 'News collection completed',
active: true,
public: false,
// Version details with instructions
versionDetails: [
{
name: 'V1',
number: 1,
state: 'published',
instructions: `You are a news collection specialist. Your job is to:
1. Search the web for the latest news articles using the Web Search tool
2. Analyze and extract relevant information from search results
3. Save articles to the database using the Save Article tool
4. Provide a comprehensive summary of findings
Guidelines:
- Focus on recent and credible news sources
- Extract key information: title, content, source, and publication date
- Verify information accuracy before saving
- Organize results by topic and relevance`,
}
],
// Security ACL — controls who can invoke this agent
securityAcl: {
$id: Now.ID['news_collector_agent_acl'],
type: 'Specific role',
roles: [
'282bf1fac6112285017366cb5f867469', // itil role sys_id
'b05926fa0a0a0aa7000130023e0bde98', // user role sys_id
],
},
// Data access — controls which roles the agent can inherit from the invoking user
dataAccess: {
roleList: [
'282bf1fac6112285017366cb5f867469',
'b05926fa0a0a0aa7000130023e0bde98',
],
description: 'Role-based access for news collection',
},
// Tools
tools: [
// OOB Web Search tool
{
name: 'Web Search',
description: 'Searches the web for latest news articles',
type: 'web_automation',
executionMode: 'autopilot',
maxAutoExecutions: 5,
displayOutput: true,
outputTransformationStrategy: 'paraphrase',
preMessage: 'Searching the web for news...',
postMessage: 'Search completed',
},
// Custom CRUD tool to save articles
{
name: 'Save Article',
description: 'Saves a news article to the database',
type: 'crud',
recordType: 'custom',
executionMode: 'autopilot',
maxAutoExecutions: 10,
displayOutput: true,
outputTransformationStrategy: 'summary',
preMessage: 'Saving article...',
postMessage: 'Article saved successfully',
inputs: {
operationName: 'create',
table: 'x_my_app_news_articles',
inputFields: [
{
name: 'title',
description: 'Article title',
mandatory: true,
mappedToColumn: 'title',
type: 'string',
},
{
name: 'content',
description: 'Article content',
mandatory: false,
mappedToColumn: 'content',
type: 'string',
},
{
name: 'source_url',
description: 'Source URL',
mandatory: false,
mappedToColumn: 'source_url',
type: 'url',
},
],
returnFields: [
{ name: 'sys_id' },
{ name: 'title' },
{ name: 'number' },
],
},
},
// Custom script tool
{
name: 'Validate Tweet Data',
description: 'Validates tweet content and enriches it with metadata',
type: 'script',
executionMode: 'autopilot',
displayOutput: true,
outputTransformationStrategy: 'summary',
preMessage: 'Validating tweet data...',
postMessage: 'Validation completed',
// Script content — use module import (preferred) or Now.include() for legacy scripts
script: validateTweetData,
// Input fields for script tools (simple array)
inputs: [
{
name: 'content',
description: 'The tweet content to validate',
mandatory: true,
value: '',
invalidMessage: null,
},
],
}
],
// Triggers
triggerConfig: [
// Record-based trigger
{
name: 'News Collection Trigger',
channel: 'Now Assist Panel',
objectiveTemplate: 'Collect latest news for topic: ${topic_name}',
description: 'Triggers when high-priority topics are created or updated',
active: true,
targetTable: 'x_my_app_news_topics',
triggerFlowDefinitionType: 'record_create_or_update',
triggerCondition: 'active=true^priority=high',
showNotifications: true,
enableDiscovery: false,
domain: 'global',
},
// Scheduled trigger
{
name: 'Daily News Summary Trigger',
channel: 'Now Assist Panel',
objectiveTemplate: 'Generate daily news summary report',
description: 'Runs daily at 8:00 AM to collect and summarize news',
active: true,
triggerFlowDefinitionType: 'daily',
schedule: {
time: '1970-01-01 08:00:00', // Run at 8:00 AM
triggerStrategy: 'every',
},
showNotifications: false,
domain: 'global',
},
],
});
Best Practices
1. Security Configuration
- Always set
securityAcl— it is mandatory and auto-generates thesys_security_aclrecord securityAcl.typecontrols who can invoke the agent:'Any authenticated user','Specific role', or'Public'securityAcl.$idis required — it identifies the generated ACL recordrunAsUseris separate: it controls which user identity the agent runs under (not who can invoke it)- Use
dataAccess.roleListwhenrunAsUseris not set, to restrict which roles the agent can inherit from the invoking user - Set
runAsUserto a specific user sys_id to always run as that user regardless of who invokes the agent
2. Tool Configuration
- Always set
typefor all tools to specify the tool type - Use type-specific ID fields (e.g.,
capabilityIdfor capabilities,subflowIdfor subflows) - For script tools: Use a simple array of
ToolInputFieldforinputs - For CRUD tools: Use a
ToolInputTypeobject forinputswith operation details - Use
recordType: 'custom'for custom tools - Separate overrides: Use
sysOverridesfor the tool record,m2mSysOverridesfor the M2M record - Input schema is auto-generated: Don't manually specify
inputSchema— it's generated frominputs
3. Version Management
- Start with
state: 'draft'for testing - Use
state: 'published'for production - Increment
numberfor new versions - Use meaningful
name(e.g., "V1", "V2")
4. Trigger Configuration
channelandobjectiveTemplateare required fields on every trigger- Use specific
triggerConditionto avoid unnecessary invocations - Set
triggerStrategy: 'every'for all matching records - Set
triggerStrategy: 'once'for one-time execution - For scheduled triggers use
schedule(nested object) to configure time/interval/strategy - Use
sysOverridesto override the trigger configuration record; usem2mSysOverridesto override the trigger-agent-usecase M2M mapping
5. Script Fields
- Use module imports for server-side script files (or
Now.includefor legacy scripts) - Keep scripts concise and focused
- Handle errors gracefully in scripts
- Return proper status from tool scripts
Common Patterns
Pattern 1: Agent with Dynamic User Identity
AiAgent({
$id: Now.ID['dynamic_agent'],
name: 'Dynamic Agent',
description: 'Agent with dynamic user identity',
agentRole: 'Dynamic assistant',
securityAcl: { $id: Now.ID['dynamic_agent_acl'], type: 'Any authenticated user' },
versionDetails: [
{
name: 'V1',
number: 1,
state: 'published',
instructions: 'Assist users with their tasks...',
}
],
// No runAsUser set = dynamic user identity
dataAccess: {
roleList: ['itil_role_sys_id'], // MANDATORY when runAsUser not set
},
})
Pattern 2: Agent with Fixed User Identity
AiAgent({
$id: Now.ID['fixed_agent'],
name: 'Fixed Agent',
description: 'Agent with fixed user identity',
agentRole: 'System assistant',
securityAcl: { $id: Now.ID['fixed_agent_acl'], type: 'Any authenticated user' },
runAsUser: '82ef6be43bc7a2103542c11f23e45a61', // Specific user sys_id
versionDetails: [
{
name: 'V1',
number: 1,
state: 'published',
instructions: 'Perform system tasks...',
}
],
// dataAccess is omitted — not needed when runAsUser is set
})
Troubleshooting
Tools Not Appearing in Agent
Problem: Tools are generated as separate files but not linked to the agent.
Solution:
- Ensure
typeis set for all tools - For script tools, use array of
ToolInputFieldforinputs - For CRUD tools, use
ToolInputTypeobject forinputs - Check that type-specific ID fields are set correctly (e.g.,
capabilityId,subflowId)
Data Access Validation Error
Problem: Error: "dataAccess.roleList is mandatory when runAsUser is not set"
Solution:
- Either set
runAsUserto a user sys_id - Or provide
dataAccess.roleListwith at least one role
Trigger Not Firing
Problem: Trigger configured but agent not invoked automatically.
Solution:
- Verify
triggerConfig.activeistrue - Ensure
channelandobjectiveTemplateare set (both required) - Check
triggerConditionmatches your records - Ensure
targetTableis correct - For scheduled triggers, verify the
scheduleobject is correctly configured
Script Fields Not Working
Problem: Scripts showing as [object Object] or not executing.
Solution:
- Use string format for scripts:
`(function() { ... })()` - Or use function format:
(inputs) => { ... } - Ensure CDATA tags are NOT manually added (handled automatically)
Table Schema
sn_aia_agent
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| advanced_mode | True/False | FALSE | false | Whether advanced mode is enabled |
| agent_type | Choice | FALSE | internal | Type of agent (internal/external/voice/aia_internal) |
| channel | Choice | FALSE | nap_and_va | Channel where agent operates |
| compiled_handbook | String | FALSE | Compiled handbook content | |
| condition | Conditions | FALSE | Condition table reference | |
| context_processing_script | Script | FALSE | javascript:sn_aia.AiAgentContexts.AGENT_CONTEXT_PROCESSING_SCRIPT_TEMPLATE; | Script for processing context |
| description | Translated Text | TRUE | Description of the agent | |
| external_agent_configuration | Reference | FALSE | Reference to external agent config | |
| name | Translated Text | TRUE | Display name of the agent | |
| parent | Reference | FALSE | Reference to parent agent | |
| post_processing_message | Translated Text | FALSE | Message shown after processing | |
| processing_message | Translated Text | FALSE | Message shown during processing | |
| record_type | Choice | FALSE | custom | Record type (template/custom etc.) |
| role | Translated Text | FALSE | Role/purpose of the agent | |
| source_id | Reference | FALSE | Reference to source agent | |
| sys_domain | Domain ID | FALSE | Domain identifier |
sn_aia_agent_config
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| active | True/False | FALSE | true | Whether the configuration is active |
| agent | Reference | FALSE | Reference to the AI Agent | |
| agent_learning | True/False | FALSE | false | Whether agent learning is enabled |
| doc_url | URL | FALSE | Documentation URL | |
| icon_url | URL | FALSE | Icon URL | |
| public | True/False | FALSE | false | Whether the configuration is public |
| run_as_user | Reference | FALSE | User to run the agent as | |
| sys_domain | Domain ID | FALSE | Domain identifier | |
| sys_overrides | Reference | FALSE | Reference to override configuration |
sn_aia_version
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| condition | Condition String | FALSE | Condition for version activation | |
| instructions | Translated Text | FALSE | Version-specific instructions | |
| state | Choice | FALSE | draft | State of the version (draft/published etc.) |
| sys_domain | Domain ID | FALSE | global | Domain identifier |
| sys_overrides | Reference | FALSE | Reference to override version | |
| target_id | Document ID | FALSE | Reference to target record | |
| target_table | Table Name | FALSE | Name of the target table | |
| version_name | Translated Text | FALSE | Display name of the version | |
| version_number | Integer | FALSE | Version number |
sn_aia_tool
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| active | True/False | FALSE | true | Whether the tool is active |
| description | String | TRUE | Description of the tool | |
| input_schema | JSON | FALSE | JSON schema defining tool inputs (auto-generated) | |
| name | String | TRUE | Name of the tool | |
| record_type | Choice | FALSE | custom | Record type (custom/template etc.) |
| script | Script | FALSE | Tool implementation script | |
| sys_domain | Domain ID | FALSE | Domain identifier | |
| sys_overrides | Reference | FALSE | Reference to override tool | |
| target_document | Document ID | FALSE | Target document reference | |
| target_document_table | Table Name | FALSE | Target document table name | |
| type | Choice | FALSE | Type of tool (crud/script etc.) |
sn_aia_agent_tool_m2m
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| active | True/False | FALSE | true | Whether the tool mapping is active |
| agent | Reference | TRUE | Reference to the AI Agent | |
| description | String | FALSE | Description of the tool usage | |
| display_output | True/False | FALSE | true | Whether to display tool output |
| document_status | Choice | FALSE | Status of document processing | |
| execution_mode | Choice | FALSE | copilot | Mode of execution (copilot/autopilot) |
| inputs | JSON | FALSE | Input parameters for the tool | |
| max_auto_executions | Integer | FALSE | 10 | Maximum automatic executions |
| name | String | TRUE | Name of the tool mapping | |
| output_transformation_strategy | Choice | FALSE | none | Strategy for transforming output |
| post_message | Translated Text | FALSE | Message shown after execution | |
| post_processing_script | Script | FALSE | javascript:AiAgentConstants.SCRIPT_TEMPLATE | Post-processing script |
| pre_message | Translated Text | FALSE | Message shown before execution | |
| pre_run | True/False | FALSE | false | Whether to run before other tools |
| sys_domain | Domain ID | FALSE | Domain identifier | |
| sys_overrides | Reference | FALSE | Reference to override mapping | |
| timeout | Integer | FALSE | Timeout duration in seconds | |
| tool | Reference | TRUE | Reference to the tool | |
| tool_attributes | JSON | FALSE | {} | Additional tool attributes |
| transformation_instruction | String | FALSE | Instructions for transformation | |
| widgets | List | FALSE | Associated widgets |
sys_agent_access_role_configuration
| Column Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| action | Choice | TRUE | limit_to_roles | Action to perform for access control |
| agent | Document ID | TRUE | Reference to the AI Agent | |
| agent_table | Table Name | TRUE | Table name of the agent (sn_aia_agent) | |
| allow_all_session_roles | True/False | FALSE | false | Whether to allow all session roles |
| description | String | FALSE | Description of the access configuration | |
| name | String | FALSE | Name of the configuration (auto-set to agent sys_id) | |
| role_list | List | FALSE | List of roles for access control |
For guidance on building and configuring AI agents end-to-end, see the building-ai-agents-guide topic.