/*
 * Smart GWT (GWT for SmartClient)
 * Copyright 2008 and beyond, Isomorphic Software, Inc.
 *
 * Smart GWT is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.  Smart GWT is also
 * available under typical commercial license terms - see
 * http://smartclient.com/license
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 */
/* sgwtgen */
 
package com.smartgwt.client.ai;


import com.smartgwt.client.event.*;
import com.smartgwt.client.core.*;
import com.smartgwt.client.types.*;
import com.smartgwt.client.data.*;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.events.*;
import com.smartgwt.client.browser.window.*;
import com.smartgwt.client.rpc.*;
import com.smartgwt.client.ai.*;
import com.smartgwt.client.callbacks.*;
import com.smartgwt.client.tools.*;
import com.smartgwt.client.bean.*;
import com.smartgwt.client.widgets.*;
import com.smartgwt.client.widgets.ai.*;
import com.smartgwt.client.widgets.events.*;
import com.smartgwt.client.widgets.form.*;
import com.smartgwt.client.widgets.form.validator.*;
import com.smartgwt.client.widgets.form.fields.*;
import com.smartgwt.client.widgets.tile.*;
import com.smartgwt.client.widgets.tile.events.*;
import com.smartgwt.client.widgets.grid.*;
import com.smartgwt.client.widgets.grid.events.*;
import com.smartgwt.client.widgets.chart.*;
import com.smartgwt.client.widgets.layout.*;
import com.smartgwt.client.widgets.layout.events.*;
import com.smartgwt.client.widgets.menu.*;
import com.smartgwt.client.widgets.tour.*;
import com.smartgwt.client.widgets.notify.*;
import com.smartgwt.client.widgets.rte.*;
import com.smartgwt.client.widgets.rte.events.*;
import com.smartgwt.client.widgets.ace.*;
import com.smartgwt.client.widgets.ace.events.*;
import com.smartgwt.client.widgets.tab.*;
import com.smartgwt.client.widgets.toolbar.*;
import com.smartgwt.client.widgets.tree.*;
import com.smartgwt.client.widgets.tree.events.*;
import com.smartgwt.client.widgets.tableview.*;
import com.smartgwt.client.widgets.viewer.*;
import com.smartgwt.client.widgets.calendar.*;
import com.smartgwt.client.widgets.calendar.events.*;
import com.smartgwt.client.widgets.cube.*;
import com.smartgwt.client.widgets.notify.*;
import com.smartgwt.client.widgets.drawing.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.event.shared.*;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.core.client.JavaScriptObject;

import com.smartgwt.client.util.*;
import com.smartgwt.client.util.events.*;
import com.smartgwt.client.util.workflow.*;
import com.smartgwt.client.util.workflow.Process; // required to override java.lang.Process
import com.smartgwt.client.util.tour.*;


/**
 * Provides class methods for enabling and disabling the use of AI technology, registering and unregistering {@link
 * com.smartgwt.client.ai.AIEngine AI engines}, and performing high-level operations using installed AI engines.
 * @see com.smartgwt.client.docs.AIMocking AI Mocking
 */
@BeanFactory.FrameworkClass
public class AI {


    // ********************* Static Attributes ***********************

    /** 
     * The ID of the default {@link com.smartgwt.client.ai.AIEngine} to use.
     *
     * @param defaultEngineId new defaultEngineId.  Default value is "gpt-4.1".
     */
    public static native void setDefaultEngineId(String defaultEngineId) /*-{
        @com.smartgwt.client.util.JSOHelper::setAttribute(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Ljava/lang/String;)($wnd.isc.AI, "defaultEngineId", defaultEngineId);
    }-*/;


    /** 
     * The ID of the default {@link com.smartgwt.client.ai.AIEngine} to use.
     *
     * @return current value of defaultEngineId
     */
    public static native String getDefaultEngineId() /*-{
        return $wnd.isc.AI.defaultEngineId;
    }-*/;

    /** 
     * The defualt maximum number of retries for any one particular request to AI.
     *
     * @param defaultMaxRetries new defaultMaxRetries.  Default value is 2.
     */
    public static native void setDefaultMaxRetries(int defaultMaxRetries) /*-{
        @com.smartgwt.client.util.JSOHelper::setAttribute(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;I)($wnd.isc.AI, "defaultMaxRetries", defaultMaxRetries);
    }-*/;


    /** 
     * The defualt maximum number of retries for any one particular request to AI.
     *
     * @return current value of defaultMaxRetries
     */
    public static native int getDefaultMaxRetries() /*-{
        var result = $wnd.isc.AI.defaultMaxRetries;
        if (result == null) result = 0;
        return @com.google.gwt.core.client.GWT::isScript()() ? result : result.valueOf();
    }-*/;

    /** 
     * Whether AI is disabled. <p> By default, AI is disabled. This static property must be set to <code>false</code> and the
     * {@link com.smartgwt.client.ai.AI#defaultEngineId default} {@link com.smartgwt.client.ai.AIEngine} must be registered in
     * order to enable the use of AI in the application.
     *
     * @param disabled new disabled.  Default value is true.
     */
    public static native void setDisabled(Boolean disabled) /*-{
        @com.smartgwt.client.util.JSOHelper::setAttribute(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Ljava/lang/Boolean;)($wnd.isc.AI, "disabled", disabled);
    }-*/;


    /** 
     * Whether AI is disabled. <p> By default, AI is disabled. This static property must be set to <code>false</code> and the
     * {@link com.smartgwt.client.ai.AI#defaultEngineId default} {@link com.smartgwt.client.ai.AIEngine} must be registered in
     * order to enable the use of AI in the application.
     *
     * @return current value of disabled
     */
    public static native Boolean getDisabled() /*-{
        var result = $wnd.isc.AI.disabled;
        if (result == null) return null;
        if (!@com.google.gwt.core.client.GWT::isScript()()) result = result.valueOf();
        return @com.smartgwt.client.util.JSOHelper::toBoolean(Z)(result);
    }-*/;


    // ********************* Static Methods ***********************

	/**
     * Alias for {@link com.smartgwt.client.ai.AI#addSpoofedResponses addSpoofedResponses()}.
     * @param responses mock response entries
     */
    public static native void addMockResponses(Map[] responses) /*-{
        $wnd.isc.AI.addMockResponses(@com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(responses));
    }-*/;


	/**
     * Asks AI to answer a question about the data of the application.
     * @param question The text of the end-user's question or their request for an answer to a data question.
     */
    public static native void askDataQuestion(String question) /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.askDataQuestion()");
        $wnd.isc.AI.askDataQuestion(question);
    }-*/;

	/**
     * Asks AI to answer a question about the data of the application.
     * @param question The text of the end-user's question or their request for an answer to a data question.
     */
    public static native void askDataQuestion(UserAIRequest question) /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.askDataQuestion()");
        $wnd.isc.AI.askDataQuestion(question.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;

    /**
     * See {@link AI#askDataQuestion(java.lang.String, com.smartgwt.client.data.DataSource[], com.smartgwt.client.ai.DataQuestionSettings, com.smartgwt.client.callbacks.AskDataQuestionResultCallback) askDataQuestion()}
     */
    public static void askDataQuestion(String question, DataSource... dataSources){
        askDataQuestion(question, dataSources, null, null);
    }

    /**
     * See {@link AI#askDataQuestion(com.smartgwt.client.ai.UserAIRequest, com.smartgwt.client.data.DataSource[], com.smartgwt.client.ai.DataQuestionSettings, com.smartgwt.client.callbacks.AskDataQuestionResultCallback) askDataQuestion()}
     */
    public static void askDataQuestion(UserAIRequest question, DataSource... dataSources){
        askDataQuestion(question, dataSources, null, null);
    }
    /**
     * See {@link AI#askDataQuestion(java.lang.String, com.smartgwt.client.data.DataSource[], com.smartgwt.client.ai.DataQuestionSettings, com.smartgwt.client.callbacks.AskDataQuestionResultCallback) askDataQuestion()}
     */
    public static void askDataQuestion(String question, DataSource[] dataSources, DataQuestionSettings settings){
        askDataQuestion(question, dataSources, settings, null);
    }

    /**
     * See {@link AI#askDataQuestion(com.smartgwt.client.ai.UserAIRequest, com.smartgwt.client.data.DataSource[], com.smartgwt.client.ai.DataQuestionSettings, com.smartgwt.client.callbacks.AskDataQuestionResultCallback) askDataQuestion()}
     */
    public static void askDataQuestion(UserAIRequest question, DataSource[] dataSources, DataQuestionSettings settings){
        askDataQuestion(question, dataSources, settings, null);
    }
	/**
     * Asks AI to answer a question about the data of the application.
     * @param question The text of the end-user's question or their request for an answer to a data question.
     * @param dataSources The available data sources. All data sources in the array must have a global ID.  If <code>null</code>, then the array
     * of all DataSources available to the AI module is used.
     * @param settings Settings to use when answering the data question.
     * @param callback The callback to call with the result.
     */
    public static native void askDataQuestion(String question, DataSource[] dataSources, DataQuestionSettings settings, AskDataQuestionResultCallback callback) /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.askDataQuestion()");
        $wnd.isc.AI.askDataQuestion(question, @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(dataSources), settings == null ? null : settings.@com.smartgwt.client.core.DataClass::getJsObj()(), 
			$entry( function(result, dataQuestion) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.AskDataQuestionResultCallback::execute(Lcom/smartgwt/client/ai/DataQuestionResult;Lcom/smartgwt/client/ai/DataQuestion;)(
					result != null ? @com.smartgwt.client.ai.DataQuestionResult::new(Lcom/google/gwt/core/client/JavaScriptObject;)(result) : null, 
					dataQuestion != null ? @com.smartgwt.client.ai.DataQuestion::new(Lcom/google/gwt/core/client/JavaScriptObject;)(dataQuestion) : null
				);
			}));
    }-*/;

	/**
     * Asks AI to answer a question about the data of the application.
     * @param question The text of the end-user's question or their request for an answer to a data question.
     * @param dataSources The available data sources. All data sources in the array must have a global ID.  If <code>null</code>, then the array
     * of all DataSources available to the AI module is used.
     * @param settings Settings to use when answering the data question.
     * @param callback The callback to call with the result.
     */
    public static native void askDataQuestion(UserAIRequest question, DataSource[] dataSources, DataQuestionSettings settings, AskDataQuestionResultCallback callback) /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.askDataQuestion()");
        $wnd.isc.AI.askDataQuestion(question.@com.smartgwt.client.core.DataClass::getJsObj()(), @com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(dataSources), settings == null ? null : settings.@com.smartgwt.client.core.DataClass::getJsObj()(), 
			$entry( function(result, dataQuestion) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.AskDataQuestionResultCallback::execute(Lcom/smartgwt/client/ai/DataQuestionResult;Lcom/smartgwt/client/ai/DataQuestion;)(
					result != null ? @com.smartgwt.client.ai.DataQuestionResult::new(Lcom/google/gwt/core/client/JavaScriptObject;)(result) : null, 
					dataQuestion != null ? @com.smartgwt.client.ai.DataQuestion::new(Lcom/google/gwt/core/client/JavaScriptObject;)(dataQuestion) : null
				);
			}));
    }-*/;


	/**
     * Cancels a data question if not already canceled.
     * @param questionId The ID of the data question to cancel.
     */
    public static native void cancelDataQuestion(String questionId) /*-{
        $wnd.isc.AI.cancelDataQuestion(questionId);
    }-*/;


	/**
     * Alias for {@link com.smartgwt.client.ai.AI#clearSpoofedResponses clearSpoofedResponses()}.
     */
    public static native void clearMockResponses() /*-{
        $wnd.isc.AI.clearMockResponses();
    }-*/;


	/**
     * Primary entry point for the AI Assist system.  Routes a user request to the most appropriate registered {@link
     * com.smartgwt.client.ai.AIServiceDescriptor AI service} by running the AIDelegator &mdash; see the {@link
     * com.smartgwt.client.docs.AiAssist AI Assist overview} for the full registration and routing model. <p> Behavior: <ul>  
     * <li>If no services are registered, logs a warning and returns.</li>   <li>If only one service is registered, invokes it
     * directly (no AI call).</li>   <li>Otherwise, runs the AIDelegator to ask the AI which service best       matches the
     * user's intent, then calls that service's       <code>invoke()</code>.</li>   <li>If the AI call fails or returns an
     * unknown service name, falls back to the       first registered service so the request is never silently dropped.</li>
     * </ul> <p> Services are resolved by walking the component hierarchy from <code>context.focusCanvas</code> upward (see
     * {@link com.smartgwt.client.ai.AI#getAIServicesForContext getAIServicesForContext()}), so canvas-scoped services
     * registered via {@link com.smartgwt.client.widgets.Canvas#registerAIService Canvas.registerAIService()} take precedence
     * over globals of the same name. <p> Built-in UI entry points &mdash; AIAssistItem and {@link
     * com.smartgwt.client.util.VoiceAssist} &mdash; call this method automatically.  Application code typically calls it
     * directly only when building its own entry point.
     * @param userPrompt the user's request text
     * @see com.smartgwt.client.ai.AI#registerAIService
     * @see com.smartgwt.client.widgets.Canvas#registerAIService
     * @see com.smartgwt.client.ai.AI#delegatorPrompts
     */
    public static native void delegate(String userPrompt) /*-{
        $wnd.isc.AI.delegate(userPrompt);
    }-*/;

    /**
     * See {@link AI#delegate(java.lang.String, Map, com.smartgwt.client.core.Function) delegate()}
     */
    public static void delegate(String userPrompt, Map context){
        delegate(userPrompt, context, null);
    }

	/**
     * Primary entry point for the AI Assist system.  Routes a user request to the most appropriate registered {@link
     * com.smartgwt.client.ai.AIServiceDescriptor AI service} by running the AIDelegator &mdash; see the {@link
     * com.smartgwt.client.docs.AiAssist AI Assist overview} for the full registration and routing model. <p> Behavior: <ul>  
     * <li>If no services are registered, logs a warning and returns.</li>   <li>If only one service is registered, invokes it
     * directly (no AI call).</li>   <li>Otherwise, runs the AIDelegator to ask the AI which service best       matches the
     * user's intent, then calls that service's       <code>invoke()</code>.</li>   <li>If the AI call fails or returns an
     * unknown service name, falls back to the       first registered service so the request is never silently dropped.</li>
     * </ul> <p> Services are resolved by walking the component hierarchy from <code>context.focusCanvas</code> upward (see
     * {@link com.smartgwt.client.ai.AI#getAIServicesForContext getAIServicesForContext()}), so canvas-scoped services
     * registered via {@link com.smartgwt.client.widgets.Canvas#registerAIService Canvas.registerAIService()} take precedence
     * over globals of the same name. <p> Built-in UI entry points &mdash; AIAssistItem and {@link
     * com.smartgwt.client.util.VoiceAssist} &mdash; call this method automatically.  Application code typically calls it
     * directly only when building its own entry point.
     * @param userPrompt the user's request text
     * @param context optional context with <code>rootCanvas</code> and/or        <code>focusCanvas</code>.  <code>focusCanvas</code> is used
     * for        component-scoped service resolution; if omitted, the canvas with keyboard        focus is used
     * @param callback optional callback fired when delegation completes,        with arguments <code>(serviceName, fellBack)</code>. 
     * <code>fellBack</code>        is truthy if the first-service fallback was used
     * @see com.smartgwt.client.ai.AI#registerAIService
     * @see com.smartgwt.client.widgets.Canvas#registerAIService
     * @see com.smartgwt.client.ai.AI#delegatorPrompts
     */
    public static native void delegate(String userPrompt, Map context, Function callback) /*-{
        $wnd.isc.AI.delegate(userPrompt, context == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(context), 
			$entry( function() { 
				if(callback!=null) callback.@com.smartgwt.client.core.Function::execute()(
				);
			}));
    }-*/;
	

	/**
     * Collects AI services available for a given context by walking the component hierarchy from <code>focusCanvas</code>
     * upward and merging with global services. Component-level registrations shadow global ones of the same name.
     * @param focusCanvas the canvas that currently has focus (may be null)
     *
     * @return merged map of service name to {@link com.smartgwt.client.ai.AIServiceDescriptor}
     */
    public static native Map getAIServicesForContext(Canvas focusCanvas) /*-{
        var ret = $wnd.isc.AI.getAIServicesForContext(focusCanvas == null ? null : focusCanvas.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()());
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Returns an array of summaries (see {@link com.smartgwt.client.ai.AI#getDataSourceSummary getDataSourceSummary()}) for
     * the specified DataSources, or all registered application DataSources if no list is provided.  The <code>settings</code>
     * parameter is passed through to each {@link com.smartgwt.client.ai.AI#getDataSourceSummary getDataSourceSummary()} call.
     *
     * @return array of summary objects
     */
    public static native Map[] getDataSourceSummaries() /*-{
        var ret = $wnd.isc.AI.getDataSourceSummaries();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

    /**
     * See {@link AI#getDataSourceSummaries(java.lang.String[], Map) getDataSourceSummaries()}
     */
    public static Map[] getDataSourceSummaries(String[] dataSourceNames){
        return getDataSourceSummaries(dataSourceNames, null);
    }

	/**
     * Returns an array of summaries (see {@link com.smartgwt.client.ai.AI#getDataSourceSummary getDataSourceSummary()}) for
     * the specified DataSources, or all registered application DataSources if no list is provided.  The <code>settings</code>
     * parameter is passed through to each {@link com.smartgwt.client.ai.AI#getDataSourceSummary getDataSourceSummary()} call.
     * @param dataSourceNames DataSource     IDs to summarize; defaults to     {@link com.smartgwt.client.ai.AI#getDataSourceNames
     * getDataSourceNames()}
     * @param settings passed through to     {@link com.smartgwt.client.ai.AI#getDataSourceSummary getDataSourceSummary()}
     *
     * @return array of summary objects
     */
    public static native Map[] getDataSourceSummaries(String[] dataSourceNames, Map settings) /*-{
        var ret = $wnd.isc.AI.getDataSourceSummaries(@com.smartgwt.client.util.JSOHelper::convertToJavaScriptArray([Ljava/lang/Object;)(dataSourceNames), settings == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(settings));
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;
	

	/**
     * Returns a structured summary of a DataSource at a configurable detail level.  In <code>"compact"</code> mode (default),
     * only identity metadata, primary key, and foreign key relationships are included ? suitable for large-app DS selection
     * where full field listings would exceed the AI context window.  Higher detail levels progressively add field information
     * via an <code>otherFields</code> property. <P> <b>Detail levels</b> (set via <code>settings.detail</code>): <ul>
     * <li><code>"compact"</code> ? ID, title, description,     fieldCount, pk, fk.  No field list.</li>
     * <li><code>"salientNames"</code> ? adds     <code>otherFields</code> as an array of field name     strings for
     * salient/critical fields (PK and FK fields     already shown in <code>pk</code>/<code>fk</code> are     excluded).</li>
     * <li><code>"salientTyped"</code> ? like salientNames but     each entry is an object with <code>name</code>,    
     * <code>type</code>, and optionally <code>required</code>     and <code>valueMap</code>.</li> <li><code>"allTyped"</code>
     * ? like salientTyped but     includes all fields, not just salient ones.</li> <li><code>"full"</code> ? all fields with
     * the full     {@link com.smartgwt.client.ai.AI#getSalientFieldAttributes salientFieldAttributes} attribute mask.</li>
     * </ul> <P> <b>Settings</b>: <ul> <li><code>detail</code> (String) ? one of the levels     above; default
     * <code>"compact"</code>.</li> <li><code>maxFields</code> (Integer) ? cap on the number     of fields in
     * <code>otherFields</code>.</li> <li><code>excludeHousekeeping</code> (Boolean) ? omit     auto-populated fields (creator,
     * modifier,     creatorTimestamp, modifierTimestamp); default     <code>true</code> for all modes except    
     * <code>"full"</code>.</li> <li><code>includeData</code> (String) ? if set,     includes representative data samples from 
     * available client-side caches.  Values:     <code>"fieldValues"</code> (per-field unique     sample values added as
     * <code>sampleValues</code>     on each field entry) or <code>"records"</code>     (whole sample records added as    
     * <code>sampleRecords</code>).  Data is sourced     from clientOnly cacheData, cacheAllData     cacheResultSet, or any
     * default-fetch (no     operationId) ResultSet observing the DataSource     ? no server requests are triggered.</li>
     * <li><code>dataSampleCount</code> (Integer) ? maximum     unique sample values per field (fieldValues     mode) or sample
     * records (records mode);     default 3.</li> <li><code>dataSampleMaxSearch</code> (Integer) ?     maximum cache records
     * to scan when collecting     unique sample values; default 100.</li> </ul>
     * @param dataSource DataSource or ID
     *
     * @return structured summary
     * @see com.smartgwt.client.ai.AI#getDataSourceSummaries
     */
    public static native Map getDataSourceSummary(DataSource dataSource) /*-{
        var ret = $wnd.isc.AI.getDataSourceSummary(dataSource == null ? null : dataSource.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()());
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns a structured summary of a DataSource at a configurable detail level.  In <code>"compact"</code> mode (default),
     * only identity metadata, primary key, and foreign key relationships are included ? suitable for large-app DS selection
     * where full field listings would exceed the AI context window.  Higher detail levels progressively add field information
     * via an <code>otherFields</code> property. <P> <b>Detail levels</b> (set via <code>settings.detail</code>): <ul>
     * <li><code>"compact"</code> ? ID, title, description,     fieldCount, pk, fk.  No field list.</li>
     * <li><code>"salientNames"</code> ? adds     <code>otherFields</code> as an array of field name     strings for
     * salient/critical fields (PK and FK fields     already shown in <code>pk</code>/<code>fk</code> are     excluded).</li>
     * <li><code>"salientTyped"</code> ? like salientNames but     each entry is an object with <code>name</code>,    
     * <code>type</code>, and optionally <code>required</code>     and <code>valueMap</code>.</li> <li><code>"allTyped"</code>
     * ? like salientTyped but     includes all fields, not just salient ones.</li> <li><code>"full"</code> ? all fields with
     * the full     {@link com.smartgwt.client.ai.AI#getSalientFieldAttributes salientFieldAttributes} attribute mask.</li>
     * </ul> <P> <b>Settings</b>: <ul> <li><code>detail</code> (String) ? one of the levels     above; default
     * <code>"compact"</code>.</li> <li><code>maxFields</code> (Integer) ? cap on the number     of fields in
     * <code>otherFields</code>.</li> <li><code>excludeHousekeeping</code> (Boolean) ? omit     auto-populated fields (creator,
     * modifier,     creatorTimestamp, modifierTimestamp); default     <code>true</code> for all modes except    
     * <code>"full"</code>.</li> <li><code>includeData</code> (String) ? if set,     includes representative data samples from 
     * available client-side caches.  Values:     <code>"fieldValues"</code> (per-field unique     sample values added as
     * <code>sampleValues</code>     on each field entry) or <code>"records"</code>     (whole sample records added as    
     * <code>sampleRecords</code>).  Data is sourced     from clientOnly cacheData, cacheAllData     cacheResultSet, or any
     * default-fetch (no     operationId) ResultSet observing the DataSource     ? no server requests are triggered.</li>
     * <li><code>dataSampleCount</code> (Integer) ? maximum     unique sample values per field (fieldValues     mode) or sample
     * records (records mode);     default 3.</li> <li><code>dataSampleMaxSearch</code> (Integer) ?     maximum cache records
     * to scan when collecting     unique sample values; default 100.</li> </ul>
     * @param dataSource DataSource or ID
     *
     * @return structured summary
     * @see com.smartgwt.client.ai.AI#getDataSourceSummaries
     */
    public static native Map getDataSourceSummary(String dataSource) /*-{
        var ret = $wnd.isc.AI.getDataSourceSummary(dataSource);
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns a structured summary of a DataSource at a configurable detail level.  In <code>"compact"</code> mode (default),
     * only identity metadata, primary key, and foreign key relationships are included ? suitable for large-app DS selection
     * where full field listings would exceed the AI context window.  Higher detail levels progressively add field information
     * via an <code>otherFields</code> property. <P> <b>Detail levels</b> (set via <code>settings.detail</code>): <ul>
     * <li><code>"compact"</code> ? ID, title, description,     fieldCount, pk, fk.  No field list.</li>
     * <li><code>"salientNames"</code> ? adds     <code>otherFields</code> as an array of field name     strings for
     * salient/critical fields (PK and FK fields     already shown in <code>pk</code>/<code>fk</code> are     excluded).</li>
     * <li><code>"salientTyped"</code> ? like salientNames but     each entry is an object with <code>name</code>,    
     * <code>type</code>, and optionally <code>required</code>     and <code>valueMap</code>.</li> <li><code>"allTyped"</code>
     * ? like salientTyped but     includes all fields, not just salient ones.</li> <li><code>"full"</code> ? all fields with
     * the full     {@link com.smartgwt.client.ai.AI#getSalientFieldAttributes salientFieldAttributes} attribute mask.</li>
     * </ul> <P> <b>Settings</b>: <ul> <li><code>detail</code> (String) ? one of the levels     above; default
     * <code>"compact"</code>.</li> <li><code>maxFields</code> (Integer) ? cap on the number     of fields in
     * <code>otherFields</code>.</li> <li><code>excludeHousekeeping</code> (Boolean) ? omit     auto-populated fields (creator,
     * modifier,     creatorTimestamp, modifierTimestamp); default     <code>true</code> for all modes except    
     * <code>"full"</code>.</li> <li><code>includeData</code> (String) ? if set,     includes representative data samples from 
     * available client-side caches.  Values:     <code>"fieldValues"</code> (per-field unique     sample values added as
     * <code>sampleValues</code>     on each field entry) or <code>"records"</code>     (whole sample records added as    
     * <code>sampleRecords</code>).  Data is sourced     from clientOnly cacheData, cacheAllData     cacheResultSet, or any
     * default-fetch (no     operationId) ResultSet observing the DataSource     ? no server requests are triggered.</li>
     * <li><code>dataSampleCount</code> (Integer) ? maximum     unique sample values per field (fieldValues     mode) or sample
     * records (records mode);     default 3.</li> <li><code>dataSampleMaxSearch</code> (Integer) ?     maximum cache records
     * to scan when collecting     unique sample values; default 100.</li> </ul>
     * @param dataSource DataSource or ID
     * @param settings detail level and field options
     *
     * @return structured summary
     * @see com.smartgwt.client.ai.AI#getDataSourceSummaries
     */
    public static native Map getDataSourceSummary(DataSource dataSource, Map settings) /*-{
        var ret = $wnd.isc.AI.getDataSourceSummary(dataSource == null ? null : dataSource.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()(), settings == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(settings));
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns a structured summary of a DataSource at a configurable detail level.  In <code>"compact"</code> mode (default),
     * only identity metadata, primary key, and foreign key relationships are included ? suitable for large-app DS selection
     * where full field listings would exceed the AI context window.  Higher detail levels progressively add field information
     * via an <code>otherFields</code> property. <P> <b>Detail levels</b> (set via <code>settings.detail</code>): <ul>
     * <li><code>"compact"</code> ? ID, title, description,     fieldCount, pk, fk.  No field list.</li>
     * <li><code>"salientNames"</code> ? adds     <code>otherFields</code> as an array of field name     strings for
     * salient/critical fields (PK and FK fields     already shown in <code>pk</code>/<code>fk</code> are     excluded).</li>
     * <li><code>"salientTyped"</code> ? like salientNames but     each entry is an object with <code>name</code>,    
     * <code>type</code>, and optionally <code>required</code>     and <code>valueMap</code>.</li> <li><code>"allTyped"</code>
     * ? like salientTyped but     includes all fields, not just salient ones.</li> <li><code>"full"</code> ? all fields with
     * the full     {@link com.smartgwt.client.ai.AI#getSalientFieldAttributes salientFieldAttributes} attribute mask.</li>
     * </ul> <P> <b>Settings</b>: <ul> <li><code>detail</code> (String) ? one of the levels     above; default
     * <code>"compact"</code>.</li> <li><code>maxFields</code> (Integer) ? cap on the number     of fields in
     * <code>otherFields</code>.</li> <li><code>excludeHousekeeping</code> (Boolean) ? omit     auto-populated fields (creator,
     * modifier,     creatorTimestamp, modifierTimestamp); default     <code>true</code> for all modes except    
     * <code>"full"</code>.</li> <li><code>includeData</code> (String) ? if set,     includes representative data samples from 
     * available client-side caches.  Values:     <code>"fieldValues"</code> (per-field unique     sample values added as
     * <code>sampleValues</code>     on each field entry) or <code>"records"</code>     (whole sample records added as    
     * <code>sampleRecords</code>).  Data is sourced     from clientOnly cacheData, cacheAllData     cacheResultSet, or any
     * default-fetch (no     operationId) ResultSet observing the DataSource     ? no server requests are triggered.</li>
     * <li><code>dataSampleCount</code> (Integer) ? maximum     unique sample values per field (fieldValues     mode) or sample
     * records (records mode);     default 3.</li> <li><code>dataSampleMaxSearch</code> (Integer) ?     maximum cache records
     * to scan when collecting     unique sample values; default 100.</li> </ul>
     * @param dataSource DataSource or ID
     * @param settings detail level and field options
     *
     * @return structured summary
     * @see com.smartgwt.client.ai.AI#getDataSourceSummaries
     */
    public static native Map getDataSourceSummary(String dataSource, Map settings) /*-{
        var ret = $wnd.isc.AI.getDataSourceSummary(dataSource, settings == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(settings));
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Returns the {@link com.smartgwt.client.ai.AIEngine} having the given engine ID.
     *
     * @return the <code>AIEngine</code>, or <code>null</code> if the <code>AIEngine</code> could not be found.
     */
    public static native AIEngine getEngine() /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.getEngine()");
        var ret = $wnd.isc.AI.getEngine();
        if(ret == null) return null;
        return @com.smartgwt.client.ai.AIEngine::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns the {@link com.smartgwt.client.ai.AIEngine} having the given engine ID.
     * @param engineId the engineId of the <code>AIEngine</code> to get. If not specified, {@link com.smartgwt.client.ai.AI#defaultEngineId
     * defaultEngineId} is used.
     *
     * @return the <code>AIEngine</code>, or <code>null</code> if the <code>AIEngine</code> could not be found.
     */
    public static native AIEngine getEngine(String engineId) /*-{
        @com.smartgwt.client.ai.AI::checkModuleLoaded(Ljava/lang/String;)("call AI.getEngine()");
        var ret = $wnd.isc.AI.getEngine(engineId);
        if(ret == null) return null;
        return @com.smartgwt.client.ai.AIEngine::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;
	

	/**
     * Returns the current {@link com.smartgwt.client.ai.AI#mockingPolicy mockingPolicy}. The return value is always one of
     * <code>"none"</code>, <code>"auto"</code>, or <code>"interactive"</code>; the legacy {@link
     * com.smartgwt.client.ai.AI#responseSpoofingMode responseSpoofingMode} values <code>"hybrid"</code> and
     * <code>"full"</code> are normalized before returning.
     *
     * @return The current mocking policy: "none", "auto", or "interactive"
     */
    public static native String getMockingPolicy() /*-{
        var ret = $wnd.isc.AI.getMockingPolicy();
        return ret;
    }-*/;


	/**
     * Returns the map of all globally registered AI services (name to descriptor).
     *
     * @return map of service name to {@link com.smartgwt.client.ai.AIServiceDescriptor}
     */
    public static native Map getRegisteredAIServices() /*-{
        var ret = $wnd.isc.AI.getRegisteredAIServices();
        return @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;


	/**
     * Returns display records for all built-in {@link com.smartgwt.client.ai.AIEngine AI engines}, suitable for populating a
     * UI grid or list.  Each record has the following properties: <ul> <li><code>engineId</code> &mdash; the engine ID (use as
     * <code>ai.defaultEngineId</code> in server.properties)</li> <li><code>name</code> &mdash; a human-readable model
     * name</li> <li><code>provider</code> &mdash; the AI service provider (OpenAI, Google, etc.)</li>
     * <li><code>apiKeyProperty</code> &mdash; the <code>server.properties</code> key that     holds this provider's API key
     * (e.g. <code>OpenAI.api.key</code>), or     <code>null</code> for engines that use provider-specific configuration</li>
     * </ul> Custom engines added via {@link com.smartgwt.client.ai.AI#registerEngine registerEngine()} are not included.
     *
     * @return engine display records
     * @see com.smartgwt.client.ai.AI#getSupportedEngineIds
     */
    public static native Map[] getSupportedEngineData() /*-{
        var ret = $wnd.isc.AI.getSupportedEngineData();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns display records for all built-in {@link com.smartgwt.client.ai.AIEngine AI engines}, suitable for populating a
     * UI grid or list.  Each record has the following properties: <ul> <li><code>engineId</code> &mdash; the engine ID (use as
     * <code>ai.defaultEngineId</code> in server.properties)</li> <li><code>name</code> &mdash; a human-readable model
     * name</li> <li><code>provider</code> &mdash; the AI service provider (OpenAI, Google, etc.)</li>
     * <li><code>apiKeyProperty</code> &mdash; the <code>server.properties</code> key that     holds this provider's API key
     * (e.g. <code>OpenAI.api.key</code>), or     <code>null</code> for engines that use provider-specific configuration</li>
     * </ul> Custom engines added via {@link com.smartgwt.client.ai.AI#registerEngine registerEngine()} are not included.
     * @param foundationalOnly pass <code>true</code> to return only     foundational AI chat/completion models, excluding specialized engines such as 
     * embedding models and vector database engines.  Use this when presenting a list     of engines a user can select as
     * {@link com.smartgwt.client.ai.AI#defaultEngineId defaultEngineId}.
     *
     * @return engine display records
     * @see com.smartgwt.client.ai.AI#getSupportedEngineIds
     */
    public static native Map[] getSupportedEngineData(boolean foundationalOnly) /*-{
        var ret = $wnd.isc.AI.getSupportedEngineData(foundationalOnly);
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;
	

	/**
     * Returns the engine IDs of all built-in {@link com.smartgwt.client.ai.AIEngine AI engines} ? those available without
     * registration, provided the appropriate API key is set in {@link com.smartgwt.client.docs.Server_properties
     * server.properties}. <p> Note that custom engines added via {@link com.smartgwt.client.ai.AI#registerEngine
     * registerEngine()} are not included.
     *
     * @return the engine IDs of matching built-in AI engines
     * @see com.smartgwt.client.ai.AI#getSupportedEngineData
     * @see com.smartgwt.client.ai.AI#getEngine
     */
    public static native String[] getSupportedEngineIds() /*-{
        var ret = $wnd.isc.AI.getSupportedEngineIds();
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfString(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;

	/**
     * Returns the engine IDs of all built-in {@link com.smartgwt.client.ai.AIEngine AI engines} ? those available without
     * registration, provided the appropriate API key is set in {@link com.smartgwt.client.docs.Server_properties
     * server.properties}. <p> Note that custom engines added via {@link com.smartgwt.client.ai.AI#registerEngine
     * registerEngine()} are not included.
     * @param foundationalOnly pass <code>true</code> to return only     foundational AI chat/completion models, excluding specialized engines such as 
     * embedding models and vector database engines.  Use this when presenting a list     of engines a user can select as
     * {@link com.smartgwt.client.ai.AI#defaultEngineId defaultEngineId}.
     *
     * @return the engine IDs of matching built-in AI engines
     * @see com.smartgwt.client.ai.AI#getSupportedEngineData
     * @see com.smartgwt.client.ai.AI#getEngine
     */
    public static native String[] getSupportedEngineIds(boolean foundationalOnly) /*-{
        var ret = $wnd.isc.AI.getSupportedEngineIds(foundationalOnly);
        if(ret == null) return null;
        return @com.smartgwt.client.util.ConvertTo::arrayOfString(Lcom/google/gwt/core/client/JavaScriptObject;)(ret);
    }-*/;
	

	/**
     * Determines whether AI support is enabled. {@link com.smartgwt.client.ai.AI#disabled disabled} must be set to
     * <code>false</code> and the default {@link com.smartgwt.client.ai.AIEngine} must be registered in order to enable the use
     * of AI.
     *
     * @return <code>true</code> if the use of AI is enabled; <code>false</code> otherwise.
     * @see com.smartgwt.client.ai.AI#disabled
     * @see com.smartgwt.client.ai.AI#defaultEngineId
     */
    public static native boolean isEnabled() /*-{
        var ret = $wnd.isc.AI.isEnabled();
        return ret == null ? false : ret;
    }-*/;


	/**
     * Pauses a data question if not already paused or canceled.
     * @param questionId The ID of the data question to pause.
     */
    public static native void pauseDataQuestion(String questionId) /*-{
        $wnd.isc.AI.pauseDataQuestion(questionId);
    }-*/;


	/**
     * Registers an AI service globally so {@link com.smartgwt.client.ai.AI#delegate delegate()} can discover and invoke it.
     * Global services are available regardless of which component has focus. <p> To register a service scoped to a specific
     * component (and its descendants), use {@link com.smartgwt.client.widgets.Canvas#registerAIService
     * Canvas.registerAIService()} instead &mdash; canvas-scoped services shadow global ones with the same name. <p> See the
     * {@link com.smartgwt.client.docs.AiAssist AI Assist overview} for the registration model and an end-to-end example.
     * @param service the service to register
     * @see com.smartgwt.client.widgets.Canvas#registerAIService
     * @see com.smartgwt.client.ai.AI#unregisterAIService
     * @see com.smartgwt.client.ai.AI#delegate
     */
    public static native void registerAIService(AIServiceDescriptor service) /*-{
        $wnd.isc.AI.registerAIService(service.@com.smartgwt.client.core.DataClass::getJsObj()());
    }-*/;


	/**
     * Registers the given {@link com.smartgwt.client.ai.AIEngine}.
     * @param engine The <code>AIEngine</code> to register.
     *
     * @return <code>true</code> if the <code>AIEngine</code> was successfully registered; <code>false</code> otherwise.
     * @see com.smartgwt.client.ai.AI#unregisterEngine
     */
    public static native boolean registerEngine(AIEngine engine) /*-{
        var ret = $wnd.isc.AI.registerEngine(engine == null ? null : engine.@com.smartgwt.client.core.BaseClass::getOrCreateJsObj()());
        return ret == null ? false : ret;
    }-*/;


	/**
     * Resumes a data question if paused.
     * @param questionId The ID of the data question to resume.
     */
    public static native void resumeDataQuestion(String questionId) /*-{
        $wnd.isc.AI.resumeDataQuestion(questionId);
    }-*/;


	/**
     * Evaluates the given {@link com.smartgwt.client.docs.DynamicStrings dynamic string} to form a prompt string that is then
     * sent as the request to the default AI engine. <p> Within <code>dynamicString</code>, any evaluated JavaScript
     * expressions have access to all of the values in the <code>context</code> ValueMap.
     * @param dynamicString A dynamic string.
     * See {@link com.smartgwt.client.docs.DynamicString DynamicString}
     * @param context A map from each in-scope {@link com.smartgwt.client.docs.Identifier} to its value.
     * @param callback The callback to fire with the response from AI.
     */
    public static native void sendPrompt(String dynamicString, Map context, AIResponseCallback callback) /*-{
        $wnd.isc.AI.sendPrompt(dynamicString, context == null ? null : @com.smartgwt.client.util.JSOHelper::convertMapToJavascriptObject(Ljava/util/Map;)(context), 
			$entry( function(aiResponse, aiRequest) { 
				if(callback!=null) callback.@com.smartgwt.client.callbacks.AIResponseCallback::execute(Lcom/smartgwt/client/ai/AIResponse;Lcom/smartgwt/client/ai/AIRequest;)(
					@com.smartgwt.client.ai.AIResponse::new(Lcom/google/gwt/core/client/JavaScriptObject;)(aiResponse), 
					@com.smartgwt.client.ai.AIRequest::new(Lcom/google/gwt/core/client/JavaScriptObject;)(aiRequest)
				);
			}));
    }-*/;


	/**
     * Sets {@link com.smartgwt.client.ai.AI#mockingPolicy mockingPolicy}. Pass one of <code>"none"</code>,
     * <code>"auto"</code>, or <code>"interactive"</code>.
     * @param policy The mocking policy: "none", "auto", or "interactive"
     */
    public static native void setMockingPolicy(String policy) /*-{
        $wnd.isc.AI.setMockingPolicy(policy);
    }-*/;


	/**
     * Removes a previously registered global AI service.
     * @param name the name of the service to remove
     */
    public static native void unregisterAIService(String name) /*-{
        $wnd.isc.AI.unregisterAIService(name);
    }-*/;


	/**
     * Unregisters an {@link com.smartgwt.client.ai.AIEngine} specified by its ID.
     * @param engineId the ID of the <code>AIEngine</code> to unregister.
     *
     * @return <code>true</code> if the <code>AIEngine</code> was successfully unregistered; <code>false</code> otherwise.
     * @see com.smartgwt.client.ai.AI#registerEngine
     */
    public static native boolean unregisterEngine(String engineId) /*-{
        var ret = $wnd.isc.AI.unregisterEngine(engineId);
        return ret == null ? false : ret;
    }-*/;


    // ***********************************************************



    /**
     * Reports whether the optional AI module is loaded for the page.
     * @return true if and only if the AI module has been loaded
     */
    public static native boolean moduleLoaded() /*-{
        return $wnd.isc.AI != null;
    }-*/;

    public static void checkModuleLoaded (String faultingAction) {
        if (!moduleLoaded()) {
            String errorMessage = "Attempt to " + faultingAction +
                ".  This requires the optional AI module which is " + 
                (SC.hasAI() ? "not currently loaded." : "not present in this build.");
            SC.logWarn(errorMessage);
            throw new UnsupportedOperationException(errorMessage);
        }
    }


}
