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.

Skip to main content

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

  1. In the left-side menu of the Project page, select Build > AI Agents.
  2. 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

  1. In the General Settings step, fill in the following fields:
  1. 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:

2. Speaking Style

  1. In the Speaking Style step, configure the following settings:

3. Instructions

  1. In the Instructions step, configure the following setting:
 - 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

  1. In the Knowledge Store step, configure the following settings:

5. Data Privacy & Security

  1. In the Data Privacy & Security step, configure the following fields:

6. Job Selection

  1. In the Job Selection step, select one of the following options:

You can create an Agent from scratch using the Cognigy.AI API POST beta/aiagents request.

​ Hire from the Job Market

  1. In the left-side menu on the Project page, select Build > AI Agents.
  2. On the AI Agents page, click Hire AI Agent. The Job Market page displays a list of available AI Agents to hire.
  3. 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.
  4. Check the status of the Hire AI Agent task by clicking in the upper-right corner.
  5. 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:

  1. On the AI Agents page, select + Hire AI Agent. The Job Market page displays a list of available AI Agents to hire.
  2. Hover your cursor over the desired AI Agent template and click > Hire & Configure.
  3. 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.
  4. Click Combine. This action will trigger the Hire AI Agent and Merge Package tasks in the Task Manager.
  5. In the left-side menu of the Project page, select Build > Flows.
  6. 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.

  1. Open the created AI Agent and go to the Jobs tab.
  2. 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.

​ 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:

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

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

Previous Projects\ \ Next

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 }); } }); } } })();