Manage AI Agents - Cognigy Documentation
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Updated in 2026.6 To manage a new generation of AI Agents, Cognigy.AI introduces the AI Agent Management interface, where you can create, edit, and delete AI Agents.
Create AI Agents
You can create an AI Agent from scratch or hire an AI Agent from the Job Market, designed for your industry, such as airlines, food services, or sales, and customize it to fit your business needs.To create an AI Agent, select one of the following options:
Create from Scratch
GUI
API
- In the left-side menu of the Project page, select Build > AI Agents.
- Click Create AI Agent if you are creating an AI Agent for the first time, or click + New AI Agent on the AI Agents page if you have created at least one AI Agent before. Configure the following settings:
1. General Settings
- In the General Settings step, fill in the following fields:
- Name — enter a name for your AI Agent. This name will be visible to end users when the AI Agent greets them in the chat or when one AI Agent transfers the conversation to another AI Agent. For example,
Hello, my name is Sara. How can I help you?orOur support specialist Alex will help with this question, transferring the conversation now.- Description — enter a description of the AI Agent that shapes its behavior and enhances its ability to understand the desired communication style. For example, describe the AI Agent as follows:
Anna works at ACME and is highly skilled at making customers feel comfortable.
- Description — enter a description of the AI Agent that shapes its behavior and enhances its ability to understand the desired communication style. For example, describe the AI Agent as follows:
- In the Avatar section, select avatar of your choice or upload your custom one by clicking + next to avatars. You can use any image as an avatar for your AI Agent, or create a Cognigy-style avatar using the Cognigy.AI PSD template. To open and customize the template, you will need Adobe Photoshop or Paint.net with the PSD plugin installed. The requirements for the avatar are as follows:
- Use an alpha channel for a transparent background.
- Set the recommended width to 136px.
- Set the recommended height to 184px.
- Save the file as
.png. - Include
_optimizedin the file name.
2. Speaking Style
- In the Speaking Style step, configure the following settings:
Set up Style— configure how the AI Agent’s choice of wording is influenced by the selected speaking style, which can affect the tone and clarity of its responses:
Concise/Comprehensive — adjust the slider to the left for brief responses and to the right for detailed responses.
- Formal/Informal — adjust the slider to the left for more casual and conversational responses, and to the right for professional and structured responses.
- Voice Configuration — assign a specific voice to your AI Agent if you want to use your AI Agent as a voice-based assistant. To configure this setting, ensure you have installed Voice Gateway and set up the Voice Preview provider. Then, fill in the fields following the same process you used for Set Session Config Node:
TTS Vendor — select the text-to-speech provider for your AI Agent. This setting determines which service will convert the AI Agent’s text responses into speech.
- TTS Language — select the language that your AI Agent will use for speech output. Ensure this language aligns with the preferred language of the end user.
- TTS Voice — select the voice from the selected TTS vendor. This setting allows you to customize the tone, gender, and style of your AI Agent’s voice.
- TTS Label — select the alternative name of the TTS vendor, as specified in the Voice Gateway Self-Service Portal. If you have multiple speech services from the same vendor, use the label to specify which service to use.
- Disable TTS Audio Caching — by default, this setting is deactivated. With caching enabled, previously requested TTS audio is stored in the AI Agent cache, and repeated requests for the same audio text will use the cached result instead of sending another request. With caching disabled, the AI Agent stores the TTS audio but doesn’t use it; each request is sent directly to the speech provider. Note that disabling caching can increase TTS costs. For detailed information, contact your speech provider.
- Language Configuration — by default, this setting is activated. Deactivate automatic language detection to ensure the AI Agent always responds in the language defined by your instructions. This setting provides predictable and consistent responses, preventing unintended language switching when users say or type words from more than one language. When active, this setting also simplifies the system prompt, giving you clearer control over language behavior.
3. Instructions
- In the Instructions step, configure the following setting:
- Instructions — provide special instructions to your AI Agent in bullet-point form. For example:
- Greet users warmly and professionally.
- Keep responses concise; expand only if requested.
- Start with a formal tone; adjust as needed.
- Share troubleshooting links for technical issues.
- Apologize if errors occur, then correct promptly.
4. Knowledge Store
- In the Knowledge Store step, configure the following settings:
Knowledge Store Type — select or upload a knowledge source that the AI Agent will use to access information from the documents you provide. By accessing and understanding these knowledge bases, the AI Agent can deliver more accurate, context-aware, and helpful responses to user queries. You need to configure an embedding model to use Knowledge AI. Select one of the following options:
Choose existing Knowledge Store — select the Knowledge Store that the AI Agent will use to access information from the documents you provide.
- Upload Knowledge Source — upload documents with supported formats, such as PDF, text, DOCX, PPTX, or CTXT file formats. The CTXT file format has restrictions. For more information, refer to the CTXT article.
- Upload URL Knowledge Source — enter the URL of the web page to be used as a Knowledge Source. This type of Knowledge Source has restrictions. For more information, refer to the Web Page article.
5. Data Privacy & Security
- In the Data Privacy & Security step, configure the following fields:
Contact Profile Information — select which information the AI Agent should use from the Cognigy Contact Profile:
None — no data will be used from the Contact Profile. This option is selected by default.
- Selected Profile Fields — enter specific fields from the Contact Profile for targeted data use. Specify the field using the Profile keys format and press
Enterto apply it. - Complete Profile — use all fields from the Contact Profile to provide comprehensive user details.
- Profile Memories — use the Memories field from the Contact Profile.
- Safety Instructions— adjust the AI Agent’s safety settings to guide content generation, interactions, and responses, ensuring compliance with ethical, legal, and operational standards. Although these settings reduce risks, occasional unexpected outputs may still occur. The selected safety instructions are included in the prompt to enhance safety, which may increase token usage. Select the safety instructions you want to apply:
- Selected Profile Fields — enter specific fields from the Contact Profile for targeted data use. Specify the field using the Profile keys format and press
Avoid harmful content — prevent generating content that could be harmful, offensive, or abusive to end users.
- Avoid ungrounded content — prevent generating content that is based on speculation or unsupported claims, ensuring it is reliable and verifiable.
- Avoid copyright infringements — prevent generating content that violates intellectual property rights or uses copyrighted material without authorization.
- Prevent jailbreak and manipulations — prevent attempts to bypass security measures or manipulate the AI Agent into producing unauthorized or unsafe content.
6. Job Selection
- In the Job Selection step, select one of the following options:
- Default — create an AI Agent with a predefined Flow, then click Create & Configure LLM to save changes and open the Flow with the created AI Agent. If you haven’t added an LLM before, the system will prompt you to configure a model to ensure your AI-driven Flow works.
- Personality Only — create an AI Agent without a predefined Flow, then click Create to save changes.
- Job — select one of the available jobs you want to assign to the AI Agent, then click Create to save changes.
You can create an Agent from scratch using the Cognigy.AI API POST beta/aiagents request.
Hire from the Job Market
GUI
API
- In the left-side menu on the Project page, select Build > AI Agents.
- On the AI Agents page, click Hire AI Agent. The Job Market page displays a list of available AI Agents to hire.
- Hover your cursor over the desired AI Agent template and click Hire. This action will trigger the Hire AI Agent task in the Task Manager.
- Check the status of the Hire AI Agent task by clicking in the upper-right corner.
- Once the task is complete, go to Build > Flows and find the Flow with the AI Agent name from the template you installed.
You can hire an Agent from the Job Market using the Cognigy.AI API POST beta/aiagents/hire request.
Combine Custom and Hired AI Agents
You can reassign your custom AI Agent to take on the responsibilities of the hired AI Agent. To do this, hire an AI Agent from the Job Market and configure their interaction by defining which functions and personality traits should be combined. This approach lets you combine the strengths of both AI Agents: ready-made job functions from the hired AI Agent and your brand’s AI Agent persona from your custom AI Agent.To combine custom and hired AI Agents, follow these steps:
- On the AI Agents page, select + Hire AI Agent. The Job Market page displays a list of available AI Agents to hire.
- Hover your cursor over the desired AI Agent template and click > Hire & Configure.
- In the Select an AI Agent to Combine window, use the search field to find an AI Agent by name, then select the AI Agent from the list.
- Click Combine. This action will trigger the Hire AI Agent and Merge Package tasks in the Task Manager.
- In the left-side menu of the Project page, select Build > Flows.
- Select the Flow that belongs to the hired AI Agent. In the Flow, you will see an AI Agent Node with your custom AI Agent persona.
Configure Jobs and Tools for AI Agents
When you create an AI Agent from scratch or add one from the Job Market, you can add or change jobs and tools in the AI Agent configuration.
- Open the created AI Agent and go to the Jobs tab.
- Fill in the following fields:
- Job Name — enter a title for the job you want to assign to the AI Agent. For example,
Customer Support Specialist. - Job Description — enter a description of the job that outlines the responsibilities and tasks associated with the role. For example,
Handle customer inquiries, provide product information, and resolve issues efficiently. - Instructions and Context — provide specific instructions or guidelines that the AI Agent should follow while performing its job. For example,
Always respond politely, escalate complex issues to a human agent, and ensure customer satisfaction.
- Job Name — enter a title for the job you want to assign to the AI Agent. For example,
Configure Tools for AI Agents
In the Tools section, click Add Tool to add tools that the AI Agent can use to perform its job. Select one of the following options:
Regular Tool
MCP
Knowledge
Send Email
Handover to AI Agent
Handover to Human Agent
Execute Workflow Tool
A tool is a specific task that an AI Agent can perform. The AI Agent can call tools to perform different tasks, such as retrieving information from a database or interacting with an external API. Fill in the following fields:
Tool
| Parameter | Type | Description |
|---|---|---|
| Tool ID | CognigyScript | Provide a meaningful name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). For example, update_user-1. |
| Description | CognigyScript | Provide a detailed description of what the tool does, when it should be used, and its parameters. |
Parameters
Configure the parameters that will be collected by the AI Agent before the tool is called. You can switch between the Graphical and JSON editors. When editing the JSON, follow the JSON Schema specification.
| Parameter | Type | Description |
|---|---|---|
| Use Parameters | Toggle | Activate this toggle to add parameters in addition to the tool name and description. The AI Agent will collect all data it needs and call a Tool with these parameters filled as arguments. These values can be accessed directly in the input.aiAgent.toolArgs object. |
| Name | Text | Specify the name of the parameter. The name should be clear and concise, and describe the purpose of the parameter. |
| Type | Selector | Select a type of the parameter: - String — a sequence of characters. For example, "hello", "123".- Number — a numerical value, which can be either an integer (for example, 5) or a floating point number (for example, 3.14).- Boolean — a logical value representing true or false.- Array — a collection of elements, which can contain multiple values of any type. For example, ["apple", "banana", "cherry"].- Object — a collection of key-value pairs, where each key is a string and the value can be of any type. For example, {"name": "John", "age": 30}. |
| Description | Text | Explain what the parameter means by providing a brief description of the parameter’s usage. |
| Enum (optional) | Enum | Define a set of values that the parameter can accept. The enum restricts the input to one of the specified values, ensuring only valid options are chosen. The enum is only available for string-type parameters in the Graphical editor. For other types, use the JSON editor. May not be supported by all LLM providers. |
| Add Parameter | Button | Add a new parameter. |
Debug Settings
| Parameter | Type | Description |
|---|---|---|
| Debug Message when called | Toggle | Enable the output of a debug message when the tool is called to provide detailed information about the tool call. |
Advanced
| Parameter | Type | Description |
|---|---|---|
| Condition | CognigyScript | The tool will be enabled only if the condition is evaluated as true. If false, the tool isn’t part of the AI Agent’s Tools within this execution. For example, when using the unlock_account tool, you can specify a condition like context.accountStatus === "locked". This checks the value in the context, and if it is missing or different, the tool will not be enabled. |
An MCP tool connects to a remote MCP server to load tools that the AI Agent can execute. Fill in the following fields:
MCP Tool
| Parameter | Type | Description |
|---|---|---|
| Name | CognigyScript | Provide a name for the MCP connection. This name helps you identify the source of the loaded tool. |
| MCP Server SSE URL | CognigyScript | Provide the URL to an SSE (Server-Sent Events) endpoint from a remote MCP server. Ensure that you connect only to trusted MCP servers. |
| Timeout | Slider | Set the timeout time for the MCP connection in seconds. |
Authentication
| Parameter | Type | Description |
|---|---|---|
| Authentication Type | Selector | The authentication type to use for the MCP server connection. Select one of the following options: - None — no authentication. This option is used by default. - OAuth2 — authenticate using OAuth 2.0, which provides improved security and control compared to API keys. OAuth 2.0 supports scoped permissions, expiring tokens, and reduced exposure through short-lived tokens. If you want to use a different authentication method, such as an API key, you can add it as a custom header in Custom Headers of the Advanced section. |
| OAuth2 Parameters | Selector | Opens the fields required to configure OAuth 2.0 authentication. These fields allow the AI Agent to securely request and use access tokens when communicating with the MCP server. Configure the following fields: - Connection Name — enter a descriptive name for the connection, for example, MCP Tool OAuth.- OAuth URL — enter the token endpoint URL exposed by the MCP server, for example: https://mcp.example.com/oauth2/token.- Client ID — enter the application (client) ID issued by the MCP server. - Client Secret — enter the application secret issued by the MCP server. Keep it secure. - Scope — add a list of scopes that define the permissions required by your application, for example: read write admin. Separate multiple scopes with spaces. |
Debug Settings
| Parameter | Type | Description |
|---|---|---|
| Debug Loaded Tools | Toggle | Enable this parameter to display a debug message listing all tools loaded from the MCP server. The debug message also includes tools filtered out in the Advanced section. This parameter shows whether tools were loaded from the cache or directly from the MCP server. |
| Debug with Parameters | Toggle | Enable this parameter to include the Tool Parameters in the debug message. |
| Debug calling Tool | Toggle | Enable the output of a debug message when the tool is called to provide detailed information about the tool call. |
Advanced
| Parameter | Type | Description |
|---|---|---|
| Cache Tools | Toggle | Disables caching of loaded tools while developing. Ensure that caching is enabled in production for performance reasons. The caching time is 10 minutes. In debug mode, you can verify whether the cache was used. To do this, make sure Debug Loaded Tools is enabled. For more information, see the Debug Settings section. |
| Condition | CognigyScript | Sets the condition under which the tool will be activated. If the condition is evaluated as false, the tool isn’t part of the AI Agent’s Tools during execution. For example, when using the unlock_account tool, you can specify a condition like context.accountStatus === "locked". This checks the value in the context, and if it is missing or different, the tool will not be enabled. |
| Tool Filter | Selector | Controls if tools should be excluded from execution. You can select one of the following options: - None — no tool filtering is applied, and all tools are available for execution. This option is selected by default. - Whitelist — only tools on the list are allowed for execution, while all other tools are excluded. - Blacklist — tools on the list are excluded from execution, while all other tools remain available. |
| Blacklist | CognigyScript | The parameter appears if you select Blacklist in Tool Filter. Specify the tools that should be blocked from execution. Specify only one tool per field. |
| Whitelist | CognigyScript | This parameter appears if you select Whitelist in Tool Filter. Specify the tools you want to allow for execution. Specify only one tool per field. |
| Custom Headers | - | Sets custom authentication headers to send with the request to the MCP server. Use the Key and Value fields to enter a header. The Value field supports CognigyScript. After entering the header key, new empty Key and Value fields are automatically added, in case you need to add more headers. Alternatively, you can click Show JSON Editor and enter the headers in the code field. |
You can add multiple tools to the AI Agent. The recommended maximum number of tools is 20. The following video shows an MCP Tool example:
Upskill AI Agents with the Model Context Protocol (MCP) - YouTube
Tap to unmute
Upskill AI Agents with the Model Context Protocol (MCP) NiCE Cognigy
NiCE Cognigy2.97K subscribers
A Knowledge tool is a tool that allows the AI Agent to directly access Knowledge Stores to provide context-aware responses. Fill in the following fields:
Tool
| Parameter | Type | Description |
|---|---|---|
| Knowledge Store | Selector | Select a Knowledge Store. |
| Tool ID | CognigyScript | Enter a name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). If you use more than one Knowledge tool, the tool ID provides context to trigger the correct Knowledge tool. In this case, enter a clear tool ID for each Knowledge tool, for example, search_appliances. |
| Description | CognigyScript | Enter instructions to guide the AI Agent to call the Knowledge tool. The description field provides context to trigger the Knowledge tool. If you want to use more than one Knowledge tool, enter clear instructions for the cases when each Knowledge tool should be used. For example, Find the answer to prompts or questions about appliances by searching the attached data sources. Use this tool when a customer asks about appliance items such as washing machines, dryers, and other household appliances. Focus exclusively on a knowledge search and does not execute tasks like small talk, calculations, or script running. |
Debug Settings
Advanced
| Parameter | Type | Description |
|---|---|---|
| Top K | Slider | Set how many Knowledge Chunks to return. Providing more results gives the AI Agent additional context, but it also increases noise and token usage. |
| Store Location | Selector | Select whether and where to store the knowledge search results. Select one of the following options: - Don’t store — the content isn’t stored. This option is set by default. - Input — the content is stored in the Input object. - Context — the content is stored in the Context object. |
| Input Key to store result | CognigyScript | Appears when Store Location is set to Input. The property in the Input object where the result is stored. For example, input.knowledgeSearch. |
| Context Key to store result | CognigyScript | Appears when Store Location is set to Context. The property in the Context object where the result is stored. For example, context.knowledgeSearch. |
| Source Tags | CognigyScript | Enter Knowledge Source Tags to refine the scope of your knowledge search, including only the most relevant Knowledge Chunks in the Knowledge Store. Before entering tags, ensure they are included in the Knowledge Sources. Add tags by entering each separately and pressing Enter. Max 5 tags. When multiple Source Tags are specified, the Search Extract Output Node defaults to the AND operator, meaning it only considers Sources that have all specified tags. To change this behavior, adjust the Match Type for Source Tags parameter. |
| Match type for Source Tags | Selector | The operator to filter Knowledge Sources by Source Tags. Select one of the following options: - AND — the default value, requires all Source Tags to match across multiple Knowledge Sources. Consider the following example: there are Knowledge Sources with Source Tags S-a, S-b, and S-c. When you use the AND operator to filter by S-a and S-b, only Sources with both Tags S-a and S-b are included in the search results.- OR — requires at least one Source Tag to match across multiple Knowledge Sources. Consider the following example: there are Knowledge Sources with Source Tags S-a, S-b, and S-c. When you use the OR operator to filter by S-a or S-b, any Source with either Tag S-a or S-b is included in the search results. |
| Condition | CognigyScript | The Knowledge tool is activated only if the condition is evaluated as true. If false, the tool isn’t included in the current execution. For example, when using the Knowledge tool, you can enter a condition such as context.productCategory === "appliances". This checks the value in the context, and if it is missing or different, the tool isn’t activated. |
The Send Email tool lets your AI Agent send emails directly to users. The Send Email tool has the capabilities and restrictions as the Email Notification Node but is more flexible. While the Email Notification Node sends emails at a fixed step in a Flow, the Send Email tool allows the AI Agent to send emails dynamically, based on user input, conversation context, or instructions. This tool makes automation more flexible and minimizes extra Flow steps.
Tool
| Parameter | Type | Description |
|---|---|---|
| Tool ID | CognigyScript | Provide a meaningful name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). The default name is send_email. |
| Description | CognigyScript | Provide a detailed description of what the tool should do. The default description is Create and send a new email message. |
| Recipient TO Email Addresses | CognigyScript | A comma-separated list of email addresses to which the email will be sent. |
Debug Settings
Advanced
The Handover to AI Agent tool lets you transfer a conversation to another AI Agent in the same or a different Flow. This approach ensures that different AI Agents share the same conversation context and can handle specific tasks, and that multi-step conversations run smoothly across Flows.
Tool
| Parameter | Type | Description |
|---|---|---|
| Tool ID | CognigyScript | Provide a meaningful name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). The default name is handover_to_ai_agent. |
| Description | CognigyScript | Describe what the receiving AI Agent should do. For example: Handle product recommendations, Perform technical troubleshooting, or Assist with billing questions. Be specific so the handover rules clearly indicate when the conversation should be handed over to the receiving AI Agent. |
| Select Flow | Selector | Select the target Flow to hand over to. The list includes only Flows that contain AI Agent Nodes. |
| Select Node | Selector | Select the AI Agent Node to hand over to. |
Debug Settings
Advanced
The Handover to Human Agent tool lets you transfer a conversation to a human agent through handover providers. This tool allows your AI Agents to refer complex tasks to a human agent if they can’t address the user’s request.
Tool
| Parameter | Type | Description |
|---|---|---|
| Tool ID | CognigyScript | Provide a meaningful name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). The default name is handover_to_human_agent. |
| Description | CognigyScript | Describe the situation when the AI Agent should refer to a human agent. For example: Use this tool if the user explicitly asks for a human., or Use this tool if you fail to answer the user's question three times.. Be specific so the handover rules clearly indicate when the conversation should be handed over to the receiving human agent. |
| Handover Provider | Selector | Select the handover provider from the list and configure the handover accordingly. The Legacy option is selected by default, meaning the Node configuration points to the settings in Deploy > Endpoints > Handover Settings. To select a provider from the list, you need to either migrate your settings to the Handover Providers interface or create this handover provider from scratch. |
| Handover Accepted Message | CognigyScript | The message to be outputted when the handover is requested. |
| Repeat Handover Accepted Message | Toggle | Enable to repeatedly output the Handover Accepted Message if the user sends a message while waiting in the queue for an agent. |
Live Agent Settings
| Parameter | Description |
|---|---|
| Live Agent Inbox Id | Enter the Inbox ID that you obtained in the previous step. |
| Skills | Enter a list of skills that should be used to filter the available agents. For example, technical support, billing. |
| Languages | Enter a list of languages that should be used to filter the available agents. For example, english, spanish. |
| Priority | Select a priority for the conversation from the list. For example, Urgent. |
| Get Queue Position | Enable the system to retrieve the end user’s current queue position. This parameter is inactive by default. |
| Update Interval | Specify the interval, in seconds, for how often to receive updates on the queue status. This parameter appears if Get Queue Position is selected. |
| Get Estimated Wait Time | Enable the retrieval of the estimated wait time for the end user. This parameter is inactive by default. |
| Wait Time Update Interval | Set the interval, in seconds, for how often to receive updates on estimated wait time. This parameter appears if Get Estimated Wait Time is selected. |
| Alternative Update | The alternative update options when certain conditions are met. This parameter is inactive by default. |
| Maximum Queue Position | Set the threshold for the maximum queue position. If this threshold is reached, the alternative text is sent. This parameter appears if Alternative Update is selected. |
| Maximum Estimated Wait Time | Define the maximum estimated wait time in milliseconds. If this duration is exceeded, the alternative text is sent. This parameter appears if Alternative Update is selected. |
| Alternative Text | The message to be sent when either the maximum queue position or maximum wait time is reached. This parameter appears if Alternative Update is selected. |
| Enable User Connects Message | Notify human agents when an end user reconnects to the chat. The parameter is enabled by default. When the parameter is enabled, the message User joined the conversation appears in the chat as soon as the end user returns to the chat tab by clicking the ← (back arrow) at the top bar in the browser, after having opened a new URL on the same tab as the chat. |
| Enable User Disconnects Message | Notify human agents when an end user disconnects from the chat. The parameter is enabled by default. When the parameter is enabled, the message User left the conversation is sent as soon as the end user closes the tab with the chat or switches to a new URL address within the current tab. |
For more information, read the Live Agent Handover Setup and Real-Time Queue Notifications documentation.
Chatwoot Settings
| Parameter | Description |
|---|---|
| Chatwoot Inbox Id | Enter the Chatwoot Inbox ID. You can find the Inbox ID in your Chatwoot URL. For example, https://app.chatwoot.com/app/account/6607/inbox/5446, where the Inbox ID is 5446. For more information, read the Chatwoot handover provider documentation. |
Salesforce Chat Settings
| Parameter | Description |
|---|---|
| Send Transcript as first message | Activate this parameter to allow Salesforce to receive the conversation transcript as the first message. This setting is turned off by default. |
| Button ID | Enter the ID of the Button you created in the Salesforce installation. This setting will override the default Button ID that you specified in the Endpoint configuration. You can use different Button IDs for individual Handover to Agent Nodes. |
| Pre-chat Entities | Enter the pre-chat entities. For more information, read the Salesforce Handover documentation. |
| Pre-chat Details | Enter the pre-chat details. For more information, read the Salesforce Handover documentation. |
NiCE CXone Settings
| Parameter | Description |
|---|---|
| Send Transcript as first message | Activate this parameter to allow NiCE CXone to receive the conversation transcript as the first message when the handover begins. This setting is turned on by default. |
Genesys Settings
| Parameter | Description |
|---|---|
| Language | Specify a language for the conversation. For example, english, spanish, german. |
| Skills | Define skills for the conversation. For example, escalation. |
| Priority | Set the priority for the conversation. For example, 1. If a priority is set, it triggers a flow in Genesys to prioritize or de-prioritize the conversation within the queue. Note that this functionality requires the appropriate flow to be set up in Genesys. |
| Enable User Connects Message | Notify human agents when an end user reconnects to the chat. The parameter is enabled by default. When the parameter is enabled, the message User joined the conversation appears in the chat as soon as the end user returns to the chat tab by clicking the ← (back arrow) at the top bar in the browser, after having opened a new URL on the same tab as the chat. |
| Enable User Disconnects Message | Notify human agents when an end user disconnects from the chat. The parameter is enabled by default. When the parameter is enabled, the message User left the conversation is sent as soon as the end user closes the tab with the chat or switches to a new URL address within the current tab. |
| Custom Attributes | Add custom attributes in JSON format to include additional information the handover. For more information, refer to Genesys Cloud Open Messaging. |
Example for the Custom Attributes parameter:
{
"section": "section A",
"region": "Europe"
}
For more information, read the Genesys Cloud Guest Chat and Genesys Cloud Open Messaging documentation.
8x8 Settings
| Parameter | Description |
|---|---|
| 8x8 Channel Id | Specify the channel ID that you created during the 8x8 configuration. You can find this ID in the 8x8 admin console. Navigate to Channels > Chat API. In the channel list, find the channel that you created. Copy the ID from the channel row. |
| 8x8 Queue Id | Specify the header value required for authenticating API calls to the 8x8 system. You can find this ID in the 8x8 admin console. Navigate to Channels > Chat API. In the channel list, find the channel that you created. Copy the Queue ID from the channel row. |
| 8x8 JSON properties | Extend 8x8 properties with custom JSON. |
For more information, read the 8x8 Handover Setup documentation.
RingCentral Engage Settings
| Parameter | Type | Description |
|---|---|---|
| Additional Category Ids | CognigyScript | IDs to be passed to the RingCentral Engage handover provider. |
| Enable User Connects Message | Toggle | Notify human agents when an end user reconnects to the chat. The parameter is enabled by default. When the parameter is enabled, the message User joined the conversation appears in the chat as soon as the end user returns to the chat tab by clicking the ← (back arrow) at the top bar in the browser, after having opened a new URL on the same tab as the chat. |
| Enable User Disconnects Message | Toggle | Notify human agents when an end user disconnects from the chat. The parameter is enabled by default. When the parameter is enabled, the message User left the conversation is sent as soon as the end user closes the tab with the chat or switches to a new URL address within the current tab. |
For more information, read the RingCentral Engage Integration documentation.
Cancel Handover Options
| Parameter | Type | Description |
|---|---|---|
| Cancel Intent | CognigyScript | The Intent the user has to trigger to cancel the Handover request. |
| Cancel Button Text | CognigyScript | The text for a quick reply button that cancels the Handover request when clicked. |
On Resolve Options
| Parameter | Type | Description |
|---|---|---|
| Flow Continuation | List | - Below this Node – the user is taken to the Node below the Handover Node once the agent resolves the conversation. In this case, the user would continue in a different flow, but the starting point would be the Node below the Handover Node. - At current AgentInject Entrypoint – the user continues the chat at the current agent inject entrypoint. This option allows the agent to guide the user to a specific part of the chat and then give control back to the user. |
| Send resolve event to Virtual Agent | Toggle | Sending an event when the AI Agent resolves a conversation. |
Event Settings
| Parameter | Type | Description |
|---|---|---|
| Send Queue Event | Toggle | Sends an event to the Flow once the handover is queued. |
| Send Active Event | Toggle | Sends an event to the Flow once the handover is active. |
Debug Settings
Advanced
The Execute Workflow tool lets the AI Agent execute another Flow. After the target Flow executes, the conversation returns to the AI Agent.The target Flow inherits the Context object from the AI Agent. If the Context object is changed during the target Flow execution, these changes are also available to the AI Agent.
| Parameter | Description |
|---|---|
| Tool ID | Provide a meaningful name as a tool ID. This ID can contain only letters, numbers, underscores (_), or dashes (-). The default name is execute_workflow. |
| Description | Describe when to trigger the AI Agent to execute the target Flow. For example, if you have a specific Flow for dealing with package returns, enter: Use this tool if the user explicitly asks to return a package.. Be specific so the AI Agent only executes the target Flow when necessary. |
| Target Flow | Select the target Flow that the AI Agent executes when this tool is called. Click to open the target Flow. |
| Select Node | Select the target Node in the target Flow that the AI Agent executes. You must set the Node you want to select as an Entrypoint with the Set Entrypoint setting before you can select it. |
Debug Settings
| Parameter | Type | Description |
|---|---|---|
| Debug Message when called | Toggle | Activate the output of a debug message when the tool is called to provide detailed information about the tool call. |
Advanced
| Parameter | Type | Description |
|---|---|---|
| Parse Intents | Toggle | Sets whether Intents should be parsed in the target Flow. This parameter is activated by default. If this parameter is activated, Cognigy NLU reparses the Intents in the target Flow based on text in the Input object. Then, Cognigy NLU generates Intent scores using the Intents from the target Flow instead of the ones from the current Flow. |
| Parse Slots | Toggle | Sets whether Slots should be parsed in the target Flow. This parameter is activated by default. If this parameter is activated, Cognigy NLU reparses the Slots in the target Flow based on text in the Input object. Then, Cognigy NLU generates Slot scores using the Slots from the target Flow instead of the ones from the current Flow. |
| Absorb Context | Toggle | Sets whether the default Context object of the target Flow is used in the context of the Flow the AI Agent is currently in. If the default Context of the target Flow has a value, it is copied into the Context object of the AI Agent as soon as the target Flow is executed. |
Configure AI Agent Settings for Each Job
Configure more settings for managing AI Agents:
Memory Handling
| Parameter | Type | Description |
|---|---|---|
| Long-Term Memory Injection | Selector | Allow the AI Agent to access Contact Profile information for the current user. Select one of the following options: - None – no memory. - Inherit from AI Agent – use the settings specified in the AI Agent creation settings. - Inject full Contact Profile – use all information from the Contact Profile. - Inject Contact Memories only – use information only from the Memories field in the Contact Profile. - Inject selected Profile fields – use information from specific fields in the Contact Profile. |
| Selected Profile Fields | Text | This parameter appears when the Inject selected Profile fields option is enabled. Enter specific fields from the Contact Profile for targeted data use. Specify the field using the Profile keys format and press Enter to apply it. |
| Short-Term Memory Injection | CognigyScript | Specify a static string or a dynamic value via CognigyScript to make available to the AI Agent in the current turn. |
Grounding Knowledge
| Parameter | Type | Description |
|---|---|---|
| Knowledge Injection | Selector | Use the Knowledge AI feature for the AI Agent. Select one of the following options: - Never — do not use the Knowledge Stores. - When Required — let the AI Agent decide when querying the Knowledge Stores is required to help the user. - Once for Each User Input — query the Knowledge Store(s) after each user input. Note that executing a query on every user input can lead to increased costs and latency. |
| Use AI Agent Knowledge | Toggle | The parameter appears when you select either When Required or Once for Each User Input. Enable to use the Knowledge Store configured in the AI Agent. The Knowledge Store configured within the AI Agent creation settings will be used. |
| Use Job Knowledge | Toggle | The parameter appears when you select either When Required or Once for Each User Input. Enable this option to configure a specific Knowledge Store for this particular job, allowing the AI Agent to access job-specific data or resources. |
| Job Knowledge Store | Selector | The parameter appears when you select either When Required or Once for Each User Input. The parameter appears when the Use Job Knowledge option is enabled. Select a specific Knowledge Store for this AI Agent’s job. |
| Top K | Slider | The parameter appears when you select either When Required or Once for Each User Input. Specify how many Knowledge Chunks to return. Providing more results gives the AI Agent additional context, but it also increases noise and token usage. |
| Source Tags | CognigyScript | The parameter appears when you select either When Required or Once for Each User Input. The tags serve to refine the scope of your knowledge search, allowing you to include only the most pertinent sections of the knowledge base and, as a result, improve the accuracy of search outputs. Before specifying tags, ensure that they were provided during the creation of the Knowledge Sources. Add Tags by specifying each Tag separately and pressing ++enter++. The maximum number of tags is 5. When you specify multiple Source Tags, the Search Extract Output Node defaults to an AND operator, meaning it only considers Sources that have all the specified Tags. This approach ensures the search results are precise and highly relevant to the end user’s query. To change this behavior, go to the Match Types for Source Tags parameter. |
| Match type for Source Tags | Select | The parameter appears when you select either When Required or Once for Each User Input. The operator to filter Knowledge Sources by Source Tags. Select one of the following options: - AND — the default value, requires all tags to match across multiple Knowledge Sources. Consider the following example: there are Knowledge Sources with Tags S-a, S-b, and S-c. When you use the AND operator to filter by S-a and S-b, only Sources with both Tags S-a and S-b will be included in the search results.- OR — requires at least one tag to match across multiple Knowledge Sources. Consider the following example: there are Knowledge Sources with Tags S-a, S-b, and S-c. When you use the OR operator to filter by S-a or S-b, any Source with either Tag S-a or S-b will be included in the search results. |
| Generate Search Prompt | Toggle | The parameter appears when you select Once for Each User Input. This parameter is enabled by default and allows you to generate a context-aware search prompt before executing the knowledge search. Note that enabling this parameter may lead to increased cost and latency. |
Storage and Streaming Options
| Parameter | Type | Description |
|---|---|---|
| How to handle the result | Select | Determine how to handle the prompt result: - Store in Input — stores the AI Agent result in the Input object. To print the prompt result, refer to the configured Context key in a Say Node or enable the Output result immediately option. - Store in Context — stores the result in the Context object. To print the prompt result, refer to the configured Context key in a Say Node or enable the Output result immediately option. - Stream to Output — streams the result directly into the output. This means that chunks coming from the prompt response will be output directly into the conversation chat as soon as a Stream Buffer Flush Token is matched, and you don’t need to use the AI Agent Output Token and Say Node. By default, this result won’t be stored in either the Input or the Context. You can change this behavior by activating the Store Copy in Input option. |
| Input Key to store Result | CognigyScript | The parameter appears when you select either Store in Input or Stream to Output. The result is stored in the input.aiAgentOutput object by default. You can specify another value, but the AI Agent Output Token will not work if the value is changed. |
| Context Key to store Result | CognigyScript | The parameter appears when Store in Context is selected. The result is stored in the context.aiAgentOutput object by default. You can specify another key. |
| Stream Buffer Flush Tokens | Text Array | The parameter appears when Stream to Output is selected. It defines tokens that trigger the stream buffer to flush to the output. The tokens can be punctuation marks or symbols, such as \n. |
| Output result immediately | Toggle | The parameter appears when you select either Store in Input or Store in Context. This parameter allows you to output results immediately without using the Say Node and AI Agent Output token. |
| Store Copy in Input | Toggle | The parameter appears when Stream to Output is selected. In addition to streaming the result to the output, store a copy in the Input object by specifying a value in the Input Key to store Result field. |
Voice
| Parameter | Type | Description |
|---|---|---|
| Voice Setting | Select | Configure the voice settings for the AI Agent Job. This parameter determines how the AI Agent selects the voice for text-to-speech (TTS) output. Select one of the following options: - - Inherit from AI Agent — use the voice settings defined in the AI Agent creation settings. - - Use Job Voice – apply custom voice settings specific to this job, allowing the AI Agent to adapt to the particular role it performs. For example, if you create a marketing AI Agent, the voice can be more engaging, friendly, and persuasive. However, if the same AI Agent performs a different role, such as customer support, the voice might be more neutral, empathetic, and formal. |
| TTS Vendor | Dropdown | Select a TTS vendor from the list or add a custom one. Note that the AI Agent Node doesn’t support TTS Labels to distinguish configurations from the same TTS vendor. To use TTS Labels, add a Set Session Config Node before the AI Agent Node in the Flow editor. |
| Custom (Vendor) | CognigyScript | The Custom parameter appears when you select Custom from the TTS Vendor list. Specify the custom TTS Vendor. For preinstalled providers, use all lowercase letters, for example, microsoft, google, aws. For custom providers, use the name that you specified on the Speech Service page in the Voice Gateway Self-Service Portal. |
| TTS Language | Dropdown | Define the language of the voice AI Agent output. Ensure this language aligns with the preferred language of the end user. |
| Custom (Language) | CognigyScript | The Custom parameter appears when you select Custom from the TTS Language list. Specify the language of the AI Agent output. The format depends on the option selected in the TTS vendor; check your TTS vendor documentation. The typical format is as follows: de-DE, fr-FR, en-US. |
| TTS Voice | Dropdown | Define the voice that should be used for the voice AI Agent output. This parameter allows you to customize the AI Agent’s voice by defining its tone, gender, style, and regional specifics, making conversations more personalized and aligned with your brand and target audience. |
| Custom (Voice) | CognigyScript | The Custom parameter appears when you select Custom from the TTS Voice list. Use this parameter to specify a custom voice, which is often required for region-specific voices. The format depends on the option selected in TTS Vendor and typically follows the pattern language-region-VoiceName. For example, de-DE-ConradNeural for German (Germany) male voice or en-US-JennyNeural for English (US) female voice. |
| TTS Label | CognigyScript | The alternative name of the TTS vendor is the one you specify in the Voice Gateway Self-Service Portal. If you have created multiple speech services from the same vendor, use the label to specify which service to use. |
| Disable TTS Audio Caching | Toggle | Disables TTS audio caching. By default, the setting is deactivated. In this case, previously requested TTS audio results are stored in the AI Agent cache. When a new TTS request is made and the audio text has been previously requested, the AI Agent retrieves the cached result instead of sending another request to the TTS provider. When the setting is activated, the AI Agent caches TTS results but doesn’t use them. In this case, each request is directly sent to your speech provider. Note that disabling caching can increase TTS costs. For detailed information, contact your speech provider. |
Tool Settings
| Parameter | Type | Description |
|---|---|---|
| Tool Choice | Selector | If supported by your LLM Model, this will determine how tools should be selected by the AI Agent: - Auto — tools (or none) are automatically selected by the AI Agent when needed. - Required — your AI Agent will always use one of its Tools. - None — your AI Agent won’t use a tool. |
| Use Strict mode | Toggle | When the parameter is enabled, strict mode (if supported by the LLM provider) ensures that the arguments passed to a tool call precisely match the expected parameters. Enabling this feature can help prevent errors. However, it may cause a slight delay in the response, especially during the first call after making changes. |
Image Handling
| Parameter | Type | Description |
|---|---|---|
| Process Images | Toggle | Enable the AI Agent to read and understand images attachments. Make sure that your LLM provider supports image processing; refer to your provider’s documentation. In addition, make sure that attachments are supported by and activated in your Endpoint, for example, Webchat. |
| Images in Transcript | Selector | Configure how images older than the last turn are handled to reduce token usage: - Minify — reduces the size of these images to 512x512px. - Drop — excludes the images. - Keep — sends the max size (this option consumes more tokens). Limitations and token consumption depend on the LLM used. |
Advanced
| Parameter | Type | Description |
|---|---|---|
| LLM | Selector | Select a model that supports the AI Agent Node feature. The selected Default model is the model that you specified in Settings > Generative AI Settings of your Project. Select the model that you added earlier while configuring Agentic AI feature. This model will manage your AI Agent. |
| AI Agent Base Version | Selector | Select the base version of the AI Agent to use: - Fixed Version — select a specific version, such as 1.0, to ensure stability and avoid potential breaking changes. Use this version in production environments or for critical workflows. The version dropdown will be updated as future versions of the AI Agent Node are released.- Latest — use the most recent version of the AI Agent Node. While this version ensures access to the latest features, it may cause breaking changes that require manual updates. When upgrading to a fixed version or switching to the latest, always test your AI Agent carefully to ensure it works with the selected version. |
| Timeout | Number | Define the maximum number of milliseconds to wait for a response from the LLM provider. |
| Maximum Completion Tokens | Slider | Define the maximum number of tokens that can be used during a process to manage costs. However, if the limit is set too low, the output may be incomplete, as the process could be cut off before it finishes. For example, if you set the maximum tokens to 100, the model will stop generating content once it reaches 100 tokens. This number would be roughly equal to 100 words, depending on the language and tokenization method. |
| Temperature | Slider | Define the sampling temperature, which ranges between 0 and 1. Higher values, such as 0.8, make the output more random, while lower values, such as 0.2, make it more focused and deterministic. |
| Include Rich Media Context | Toggle | Controls whether the text from the Textual Description field in Say, Question, and Optional Questions Nodes is added to the AI Agent’s prompt. This text provides AI Agents with additional information, improving their responses. If you have filled in a Textual Description field in other Nodes, this text is added to the prompt as context for rich media, such as Text with Quick Replies. If the Textual Description field is empty, the button titles and alt text from the rich media are added to the prompt. By default, the Include Rich Media Context parameter is active. When this parameter is inactive, nothing related to the rich media is added to the prompt. Examples: - If Textual Description is filled in: Textual Description: Select your preferred delivery option: Standard Delivery or Express Delivery.Quick Replies buttons: Standard Delivery, Express Delivery.Context added to the prompt: Select your preferred delivery option: Standard Delivery or Express Delivery.- If Textual Description is empty: Textual Description: empty. Quick Replies buttons: Standard Delivery, Express Delivery.Context added to the prompt: Standard Delivery, Express Delivery.- If Include Rich Media Context is inactive: No information related to the rich media is added to the prompt. |
Error Handling
| Parameter | Type | Description |
|---|---|---|
| Log to System Logs | Toggle | Log errors to the system logs. They can be viewed on the Logs page of your Project. The parameter is inactive by default. |
| Store in Input | Toggle | Store errors in the Input object. |
| Select Error Handling Approach | Select | You can select one of the Error Handling options: - Stop Flow Execution — terminate the current Flow execution. - Continue Flow Execution — allow the Flow to continue executing, bypassing the error and proceeding to the next steps. - Go to Node — redirect the workflow to a specific Node in the Flow, which can be useful for error recovery or customized error handling. |
| Select Flow | Select | The parameter appears when Go to Node is selected. Select a Flow from the available options. |
| Select Node | Select | The parameter appears when Go to Node is selected. Select a Node from the available options. |
| Error Message (optional) | CognigyScript | Add the optional message to the output if the AI Agent Node fails. |
Debug Settings
| Parameter | Type | Description |
|---|---|---|
| Log Job Execution | Toggle | Send a debug message with the current AI Agent Job configuration. The message appears in the Interaction Panel when debug mode is enabled. The parameter is active by default. |
| Log Knowledge Results | Toggle | Send a debug message containing the result from a knowledge search. The message appears in the Interaction Panel when debug mode is enabled. The parameter is inactive by default. |
| Show Token Count | Toggle | Send a debug message containing the input, output, and total token count. The message appears in the Interaction Panel when debug mode is enabled. Cognigy.AI uses the GPT-3 tokenizer algorithm, so actual token usage may vary depending on the model used. The parameter is inactive by default. |
| Log System Prompt | Toggle | Send a debug message containing the system prompt. The message appears in the Interaction Panel when debug mode is enabled. The parameter is inactive by default. |
| Log LLM Latency | Toggle | Send a debug message containing key latency metrics for the request to the model, including the time taken for the first output and the total time to complete the request. The message appears in the Interaction Panel when debug mode is enabled. The parameter is inactive by default. |
| Log Tool Definitions | Toggle | Send a debug message containing information about the configured AI Agent tools. The message appears in the Interaction Panel when debug mode is enabled. The parameter is inactive by default. |
To test and refine the job settings, use the Interaction Panel on the right side of the screen.To view the AI Agent’s Flow in detail, click Advanced Editor in the upper-right corner.One AI Agent can have multiple jobs. To add another job, click Add Job in the bottom-left corner. Note that each job corresponds to one Flow.
Other Operations
GUI
API
CLI
You can view and delete AI Agents, and copy their Reference ID in Build > AI Agents.
You can create, edit, and delete AI Agents using Cognigy.AI API.
You can clone and edit AI Agents using Cognigy.AI CLI.
More Information
Last modified onJune 23, 2026
Ctrl+I
ChatVoice
Click the call button to start talking.
Cognigy AssistantReady to talk
Connecting…
Powered by Cognigy.AI
Cookie Consent
We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for.
With your consent, you're helping us make our documentation better. To find out more about the cookies we use, see our Privacy Policy.
Accept
'; cachedClickBlockingCode = css + js; return cachedClickBlockingCode; }
// Helper: Inject click-blocking code into iframe function injectClickBlocking(iframeDoc) { if (!iframeDoc || !iframeDoc.head) return false;
try { const style = iframeDoc.createElement('style'); style.textContent = 'a,button,input,select,textarea,[onclick],[role="button"],input[type="button"],input[type="submit"],[href],[tabindex]:not([tabindex="-1"]){pointer-events:none!important;cursor:default!important}a:hover,button:hover{cursor:default!important;opacity:0.7!important}'; iframeDoc.head.appendChild(style);
const script = iframeDoc.createElement('script'); script.textContent = '(function(){var preventClick=function(e){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();return false;};document.addEventListener("click",preventClick,true);document.addEventListener("mousedown",preventClick,true);document.addEventListener("mouseup",preventClick,true);document.addEventListener("touchstart",preventClick,true);document.addEventListener("touchend",preventClick,true);document.addEventListener("contextmenu",preventClick,true);window.addEventListener("beforeunload",function(e){e.preventDefault();e.returnValue="";return "";},true);try{Object.defineProperty(window,"location",{value:{href:"#",replace:function(){},assign:function(){}},writable:false,configurable:false});}catch(e){}var originalPushState=history.pushState;history.pushState=function(){return false;};var originalReplaceState=history.replaceState;history.replaceState=function(){return false;};var originalOpen=window.open;window.open=function(){return null;};var allElements=document.querySelectorAll("*");for(var i=0;i 0 || replacedViewers.length > 0) { const currentUrl = window.location.href; if (!processedUrls.has(currentUrl)) { processedUrls.add(currentUrl); lastUrl = currentUrl; } return; }
const currentUrl = window.location.href; if (currentUrl === lastUrl && lastUrl !== null && processedUrls.has(currentUrl)) { return; }
// Optimized: Use cached viewer query const viewers = getUninitializedViewers();
if (viewers.length === 0) { if (periodicCheckInterval) { clearInterval(periodicCheckInterval); periodicCheckInterval = null; } return; }
// Final safety check if (viewers.length > 0) { if (currentUrl === lastUrl && lastUrl !== null && processedUrls.has(currentUrl)) { viewers.forEach(function(viewer) { viewer.setAttribute('data-initialized', 'true'); }); return; }
if (currentUrl === lastUrl && lastUrl !== null) { if (existingContainers.length > 0) { processedUrls.add(currentUrl); viewers.forEach(function(viewer) { viewer.setAttribute('data-initialized', 'true'); }); return; } } }
isInitializing = true; let processedAny = false;
// Optimized: Process viewers in batch viewers.forEach(function(viewer) { if (processedElements.has(viewer) || viewer.hasAttribute('data-initialized')) { return; }
if (viewer.closest('.single-page-viewer-container')) { return; }
if (!viewer.parentNode) { return; }
const isInContentArea = contentArea === document.body || contentArea.contains(viewer); if (!isInContentArea) { return; }
const src = viewer.getAttribute('data-src'); const hint = viewer.getAttribute('data-hint') || ''; const defaultZoom = parseFloat(viewer.getAttribute('data-zoom')) || DEFAULT_ZOOM; const dataHeight = viewer.getAttribute('data-height'); const height = dataHeight ? parseFloat(dataHeight) : null;
if (!src) { // Don't set isInitializing = false here - it affects all viewers in the loop return; }
processedElements.add(viewer); viewer.setAttribute('data-initialized', 'true');
let zoom = defaultZoom;
// Optimized: Use document fragment for DOM construction const fragment = document.createDocumentFragment(); const container = document.createElement('div'); container.className = 'single-page-viewer-container';
const wrapper = document.createElement('div'); wrapper.className = 'single-page-viewer-wrapper';
const controlsBar = document.createElement('div'); controlsBar.className = 'single-page-viewer-controls';
if (hint) { const hintDiv = document.createElement('div'); hintDiv.className = 'single-page-viewer-hint'; hintDiv.innerHTML = '' + hint + ''; controlsBar.appendChild(hintDiv); }
const iframeWrapper = document.createElement('div'); iframeWrapper.className = 'single-page-viewer-iframe-wrapper'; iframeWrapper._scrollHandlerAdded = false;
// Optimized: Get height without temporary DOM manipulation const baseHeightFromCSS = height || NORMAL_HEIGHT;
const scaleDiv = document.createElement('div'); scaleDiv.className = 'single-page-viewer-scale'; const initialHeight = baseHeightFromCSS; scaleDiv.style.cssText = 'transform: scale(' + zoom + '); transform-origin: top left; width: ' + (100 / zoom) + '%; height: ' + initialHeight + 'px; transition: transform 0.2s ease;';
const iframe = document.createElement('iframe'); let iframeSrc = src; if (iframeSrc && !iframeSrc.startsWith('http') && !iframeSrc.startsWith('//')) { if (!iframeSrc.startsWith('/')) { iframeSrc = '/' + iframeSrc; } }
iframe.title = 'Single Page Viewer'; iframe.className = 'single-page-viewer-iframe'; iframe.style.width = '100%'; iframe.style.height = initialHeight + 'px'; iframe.loading = 'lazy'; iframe.setAttribute('scrolling', 'no'); iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-forms allow-popups allow-modals');
const clickBlocker = document.createElement('div'); clickBlocker.className = 'single-page-viewer-click-blocker';
if (iframeSrc.endsWith('.html') && !iframeSrc.startsWith('http')) { fetch(iframeSrc) .then(function(response) { return response.text().then(function(htmlContent) { if (htmlContent.includes('Page Not Found') || (htmlContent.includes('__next') && htmlContent.includes('mintlify') && !htmlContent.includes('Page saved with SingleFile'))) { throw new Error('Received 404 page instead of HTML file.'); } const blockingCode = getClickBlockingCode(); if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', blockingCode + ''); } else if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', '' + blockingCode); } else { if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', '' + blockingCode + ''); } else { htmlContent = blockingCode + htmlContent; } } iframe.srcdoc = htmlContent; }); }); } else { iframe.src = iframeSrc; }
iframe.addEventListener('load', function() { setTimeout(function() { updateIframeDimensions(iframeWrapper, scaleDiv, iframe, zoom); }, 100);
try { const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; injectClickBlocking(iframeDoc); } catch (e) { // Cross-origin iframe - cannot block clicks } }, { once: true });
iframe.addEventListener('error', function() { // Iframe failed to load - error handling is silent }, { once: true });
scaleDiv.appendChild(iframe); iframeWrapper.appendChild(scaleDiv); if (!iframeSrc.endsWith('.html') || iframeSrc.startsWith('http')) { iframeWrapper.appendChild(clickBlocker); }
if (hint) { wrapper.appendChild(controlsBar); } wrapper.appendChild(iframeWrapper); container.appendChild(wrapper); fragment.appendChild(container);
try { if (viewer.parentNode) { if (viewer === contentArea || viewer.id === 'content-area') { isInitializing = false; return; }
const viewerId = 'viewer-' + Date.now() + '-' + Math.random().toString(36).slice(2, 11); viewer.id = viewerId; viewer.setAttribute('data-viewer-id', viewerId); container.setAttribute('data-viewer-id', viewerId);
// Optimized: Single DOM insertion using fragment if (viewer.nextSibling) { viewer.parentNode.insertBefore(fragment, viewer.nextSibling); } else { viewer.parentNode.appendChild(fragment); }
// Batch style updates Object.assign(viewer.style, { display: 'none', visibility: 'hidden', position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', opacity: '0', pointerEvents: 'none', margin: '0', padding: '0' });
viewer.setAttribute('data-initialized', 'true'); viewer.setAttribute('data-viewer-replaced', 'true');
processedAny = true; invalidateQueryCache();
requestAnimationFrame(function() { updateIframeDimensions(iframeWrapper, scaleDiv, iframe, zoom); }); } } catch (e) { isInitializing = false; return; } });
if (processedAny) { const currentUrl = window.location.href; processedUrls.add(currentUrl); lastUrl = currentUrl; invalidateQueryCache(); }
isInitializing = false; }
// Wait for content area to be available function waitForContentArea(callback, maxAttempts, attempt) { attempt = attempt || 0; maxAttempts = maxAttempts || 20;
const contentArea = document.querySelector('#content-area') || document.querySelector('.mdx-content');
if (contentArea && document.contains(contentArea)) { cachedContentArea = contentArea; callback(); } else if (attempt < maxAttempts) { setTimeout(function() { waitForContentArea(callback, maxAttempts, attempt + 1); }, 500); } else { cachedContentArea = document.body; callback(); } }
// Optimized: Initialize with better state management function initialize() { const currentUrl = window.location.href; if (lastUrl !== currentUrl && lastUrl !== null) { lastUrl = currentUrl; processedUrls.clear(); invalidateQueryCache(); }
if (typeof window !== 'undefined') { window.__lastFullUrl = window.location.href; }
if (lastThemeClass === null && document.documentElement) { lastThemeClass = document.documentElement.className; }
if (!themeObserver && document.documentElement) { themeObserver = new MutationObserver(function(mutations) { for (let i = 0; i < mutations.length; i++) { const mutation = mutations[i]; if (mutation.type === 'attributes' && mutation.attributeName === 'class') { const currentThemeClass = document.documentElement.className; if (lastThemeClass !== null && lastThemeClass !== currentThemeClass) { themeToggleInProgress = true;
// Optimized: Lock containers synchronously const contentArea = getContentArea(); if (contentArea) { const containers = getContainers(true); containers.forEach(function(container) { if (container.getAttribute('data-position-locked') !== 'true') { const rect = container.getBoundingClientRect(); Object.assign(container.style, { position: 'fixed', top: rect.top + 'px', left: rect.left + 'px', width: rect.width + 'px', zIndex: '9999', margin: '0' }); container.setAttribute('data-position-locked', 'true'); containerPositions.set(container, { top: rect.top, left: rect.left, width: rect.width, height: rect.height }); } }); }
let repositionAttempts = 0; const maxRepositionAttempts = 30;
const repositionInterval = setInterval(function() { repositionAttempts++; repositionContainersAfterThemeToggleCore(); // Use core function for immediate repositioning if (repositionAttempts >= maxRepositionAttempts) { clearInterval(repositionInterval); } }, 100);
setTimeout(function() { clearInterval(repositionInterval); themeToggleInProgress = false; repositionContainersAfterThemeToggleCore(); // Use core function for final repositioning unlockContainers(); }, 3000); } lastThemeClass = currentThemeClass; } } });
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); }
if (typeof MutationObserver !== 'undefined') { setupObserver(); }
waitForContentArea(function() { setTimeout(function() { initSinglePageViewers(); setTimeout(function() { const remaining = getUninitializedViewers(true); if (remaining.length > 0) { initSinglePageViewers(); } }, INIT_DELAY); }, INIT_DELAY); }); }
// Optimized: Lock/unlock containers function lockContainersInPlace() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = getContainers(true); containerPositions.clear();
requestAnimationFrame(function() { containers.forEach(function(container) { if (container.getAttribute('data-position-locked') !== 'true') { const rect = container.getBoundingClientRect(); Object.assign(container.style, { position: 'fixed', top: rect.top + 'px', left: rect.left + 'px', width: rect.width + 'px', zIndex: '9999', margin: '0' }); container.setAttribute('data-position-locked', 'true'); containerPositions.set(container, { top: rect.top, left: rect.left, width: rect.width, height: rect.height }); } }); }); }
function unlockContainers() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = Array.from( contentArea.querySelectorAll('.single-page-viewer-container[data-position-locked="true"]') );
containers.forEach(function(container) { Object.assign(container.style, { position: '', top: '', left: '', width: '', zIndex: '', margin: '' }); container.removeAttribute('data-position-locked'); // Clean up container position from Map to prevent memory leak containerPositions.delete(container); });
containerPositions.clear(); }
// Optimized: Reposition containers with better DOM operations // Core repositioning function (not debounced for immediate use) function repositionContainersAfterThemeToggleCore() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = getContainers(true);
containers.forEach(function(container) { const viewerId = container.getAttribute('data-viewer-id'); if (!viewerId) return;
let viewer = document.getElementById(viewerId);
if (!viewer) { const iframe = container.querySelector('iframe'); if (iframe && iframe.src) { const allViewers = contentArea.querySelectorAll('[data-single-page-viewer]'); for (let i = 0; i < allViewers.length; i++) { const v = allViewers[i]; if (v.getAttribute('data-src') === iframe.src) { viewer = v; viewer.id = viewerId; viewer.setAttribute('data-viewer-id', viewerId); Object.assign(viewer.style, { display: 'none', visibility: 'hidden', position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', opacity: '0', pointerEvents: 'none', margin: '0', padding: '0' }); viewer.setAttribute('data-initialized', 'true'); viewer.setAttribute('data-viewer-replaced', 'true'); break; } } } }
if (viewer && viewer.parentNode) { if (container.getAttribute('data-position-locked') === 'true') { unlockContainers(); }
const viewerIndex = Array.from(viewer.parentNode.children).indexOf(viewer); const containerIndex = Array.from(viewer.parentNode.children).indexOf(container);
if (containerIndex !== viewerIndex + 1) { // CRITICAL: Check if container is actually a child before removing if (container.parentNode && container.parentNode.contains(container)) { try { container.parentNode.removeChild(container); } catch (e) { return; // Skip repositioning if removal failed } } if (viewer.nextSibling) { viewer.parentNode.insertBefore(container, viewer.nextSibling); } else { viewer.parentNode.appendChild(container); } } else if (container.parentNode !== viewer.parentNode) { // CRITICAL: Check if container is actually a child before removing if (container.parentNode && container.parentNode.contains(container)) { try { container.parentNode.removeChild(container); } catch (e) { return; // Skip repositioning if removal failed } } if (viewer.nextSibling) { viewer.parentNode.insertBefore(container, viewer.nextSibling); } else { viewer.parentNode.appendChild(container); } } } });
invalidateQueryCache(); }
// Debounced version for non-critical repositioning const repositionContainersAfterThemeToggle = debounce(repositionContainersAfterThemeToggleCore, REPOSITION_DEBOUNCE);
// Optimized: Observer setup with better filtering let observer = null; let containerPositionObserver = null; let fallbackObserver = null; // Track fallback observer for cleanup
function setupContainerPositionObserver() { if (typeof MutationObserver === 'undefined') return;
const contentArea = getContentArea(); if (!contentArea || !document.contains(contentArea)) { setTimeout(setupContainerPositionObserver, 500); return; }
if (containerPositionObserver) { containerPositionObserver.disconnect(); }
containerPositionObserver = new MutationObserver(function(mutations) { if (themeToggleInProgress) { // Use core function (not debounced) for immediate repositioning during theme toggle requestAnimationFrame(repositionContainersAfterThemeToggleCore); return; }
let needsReposition = false; for (let i = 0; i < mutations.length && !needsReposition; i++) { if (mutations[i].type === 'childList') { needsReposition = true; } }
if (needsReposition) { clearTimeout(containerPositionObserver._timeout); containerPositionObserver._timeout = setTimeout(repositionContainersAfterThemeToggle, REPOSITION_DEBOUNCE); } });
containerPositionObserver.observe(contentArea, { childList: true, subtree: true, attributes: false, characterData: false });
containerPositionObserver._timeout = null; }
// Optimized: Main observer with better early exits function setupObserver() { if (typeof MutationObserver === 'undefined') return;
const contentArea = getContentArea(); if (!contentArea || !document.contains(contentArea)) { setTimeout(setupObserver, 500); return; }
if (contentArea === document.documentElement || contentArea === document.body) { return; }
if (observer) { const currentObserved = observer._observedElement; if (currentObserved === contentArea && document.contains(contentArea)) { return; } if (currentObserved) { observer.disconnect(); } observer = null; }
observer = new MutationObserver(function(mutations) { if (themeToggleInProgress) return;
let hasNewViewer = false; for (let i = 0; i < mutations.length && !hasNewViewer; i++) { const mutation = mutations[i]; if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let j = 0; j < mutation.addedNodes.length && !hasNewViewer; j++) { const node = mutation.addedNodes[j]; if (node.nodeType === 1 && node.hasAttribute && node.hasAttribute('data-single-page-viewer') && !node.hasAttribute('data-initialized') && !node.hasAttribute('data-viewer-replaced')) { hasNewViewer = true; } } } }
if (hasNewViewer) { // Use core function for immediate repositioning when new viewer detected repositionContainersAfterThemeToggleCore(); setTimeout(repositionContainersAfterThemeToggleCore, 10); setTimeout(repositionContainersAfterThemeToggleCore, 50); setTimeout(repositionContainersAfterThemeToggleCore, 200); }
clearTimeout(observerTimeout); observerTimeout = setTimeout(function() { if (themeToggleInProgress) return;
let hasNewViewer = false; for (let i = 0; i < mutations.length && !hasNewViewer; i++) { const mutation = mutations[i];
if (mutation.target === document.documentElement || mutation.target === document.body) { continue; }
if (mutation.type === 'attributes' && mutation.attributeName === 'class' && mutation.target === document.documentElement) { continue; }
if (mutation.type === 'attributes' && mutation.attributeName === 'data-initialized') { const target = mutation.target; if (target && target.hasAttribute && target.hasAttribute('data-single-page-viewer') && !target.hasAttribute('data-initialized')) { hasNewViewer = true; } }
if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let j = 0; j < mutation.addedNodes.length && !hasNewViewer; j++) { const node = mutation.addedNodes[j]; if (node.nodeType === 1 && node.hasAttribute && node.hasAttribute('data-single-page-viewer') && !node.hasAttribute('data-initialized')) { hasNewViewer = true; } } } }
if (hasNewViewer) { invalidateQueryCache(); initSinglePageViewers(); } }, OBSERVER_DEBOUNCE); });
observer.observe(contentArea, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-initialized'], characterData: false });
observer._observedElement = contentArea; setupContainerPositionObserver(); }
function start() { setupObserver(); initialize(); }
function checkAndInitialize() { if (isInitializing) return;
const currentUrl = window.location.href; if (currentUrl === lastUrl && lastUrl !== null) { return; }
const contentArea = document.querySelector('#content-area') || document.querySelector('.mdx-content'); if (contentArea) { const viewers = getUninitializedViewers(true); if (viewers.length > 0) { cachedContentArea = contentArea; setupObserver(); initialize(); } } }
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { setTimeout(start, 100); }
if (typeof window !== 'undefined' && window.next) { let initialLoadAttempts = 0; const maxInitialAttempts = 4; const attemptDelays = [200, 500, 1000, 2000]; const initialUrl = window.location.href;
attemptDelays.forEach(function(delay) { setTimeout(function() { if (initialLoadAttempts < maxInitialAttempts) { initialLoadAttempts++; if (window.location.href === initialUrl) { checkAndInitialize(); } } }, delay); }); }
window.addEventListener('popstate', function(e) { const currentUrl = window.location.href; if (currentUrl !== lastUrl) { handleNavigation(); } });
if (typeof window !== 'undefined') { if (window.next && window.next.router && window.next.router.events) { window.next.router.events.on('routeChangeComplete', function(url) { lastUrl = window.location.href; isInitializing = false; pendingInitCall = false; if (navigationTimeout) { clearTimeout(navigationTimeout); navigationTimeout = null; } invalidateContentAreaCache(); invalidateQueryCache(); setTimeout(function() { setupObserver(); initialize(); }, 300); });
window.next.router.events.on('routeChangeStart', function(url) { isInitializing = false; pendingInitCall = false; }); }
if (!window.next || !window.next.router) { const originalPushState = history.pushState; const originalReplaceState = history.replaceState;
history.pushState = function() { originalPushState.apply(history, arguments); setTimeout(function() { if (window.location.href !== lastUrl) { handleNavigation(); } }, 0); };
history.replaceState = function() { originalReplaceState.apply(history, arguments); setTimeout(function() { if (window.location.href !== lastUrl) { handleNavigation(); } }, 0); }; } }
document.addEventListener('visibilitychange', function() { if (!document.hidden) { isInitializing = false; startPeriodicCheck(); if (!pendingInitCall) { pendingInitCall = true; setTimeout(function() { pendingInitCall = false; initSinglePageViewers(); }, INIT_DELAY / 2); } } });
function startPeriodicCheck() { if (periodicCheckInterval) return;
periodicCheckInterval = setInterval(function() { const uninitialized = getUninitializedViewers(true); if (uninitialized.length === 0) { clearInterval(periodicCheckInterval); periodicCheckInterval = null; } else if (!isInitializing) { initSinglePageViewers(); } }, 2000); }
setTimeout(startPeriodicCheck, INIT_DELAY * 2);
window.__singlePageViewerInit = function() { const currentUrl = window.location.href; if (currentUrl === lastUrl) { return; }
isInitializing = false; pendingInitCall = false; lastUrl = currentUrl; invalidateContentAreaCache(); invalidateQueryCache(); setupObserver(); initialize(); };
window.__singlePageViewerCheck = function() { invalidateQueryCache(); initSinglePageViewers(); }; })();
// Optimized: Second IIFE for navigation handling (function() { 'use strict';
let lastPathname = window.location.pathname; let lastInitializedPathname = window.location.pathname;
function checkAndInit() { const currentPathname = window.location.pathname; if (currentPathname === lastInitializedPathname) { return; }
lastInitializedPathname = currentPathname; if (typeof window !== 'undefined') { window.__lastFullUrl = window.location.href; }
if (window.__singlePageViewerInit) { window.__singlePageViewerInit(); } }
function runInit() { if (window.__singlePageViewerInit) { setTimeout(checkAndInit, 100); } else { let attempts = 0; const maxAttempts = 50; const checkInterval = setInterval(function() { attempts++; if (window.__singlePageViewerInit) { clearInterval(checkInterval); setTimeout(checkAndInit, 100); } else if (attempts >= maxAttempts) { clearInterval(checkInterval); } }, 100); } }
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); } else { setTimeout(runInit, 100); }
if (typeof window !== 'undefined' && window.next && window.next.router && window.next.router.events) { window.next.router.events.on('routeChangeComplete', function(url) { lastPathname = window.location.pathname; setTimeout(checkAndInit, 300); }); }
setInterval(function() { const currentPathname = window.location.pathname; if (currentPathname !== lastPathname) { lastPathname = currentPathname; setTimeout(checkAndInit, 300); } }, 500);
if (typeof MutationObserver !== 'undefined') { let fallbackObserverTimeout = null; // Store in outer scope for cleanup tracking fallbackObserver = new MutationObserver(function(mutations) { if (fallbackObserverTimeout) { clearTimeout(fallbackObserverTimeout); } fallbackObserverTimeout = setTimeout(function() { const contentArea = document.querySelector('#content-area'); if (contentArea) { const uninitialized = contentArea.querySelectorAll( '[data-single-page-viewer]:not([data-initialized]):not(.single-page-viewer-container [data-single-page-viewer])' ); if (uninitialized.length > 0) { const currentPathname = window.location.pathname; if (currentPathname !== lastInitializedPathname) { setTimeout(checkAndInit, 200); } } } }, 500); });
if (document.body) { fallbackObserver.observe(document.body, { childList: true, subtree: true }); } else { document.addEventListener('DOMContentLoaded', function() { if (document.body) { fallbackObserver.observe(document.body, { childList: true, subtree: true }); } }); } } })();