Interface IPromptServiceHandler<ConnectionConfig, QueryConfig>

Type Parameters:
ConnectionConfig - The type of the connection configuration model used by this prompt service.
QueryConfig - The type of the query configuration model used by this prompt service.
All Known Subinterfaces:
PromptServiceHandlerMixin_JsonConfig<ConnectionConfig, QueryConfig>

public interface IPromptServiceHandler<ConnectionConfig, QueryConfig>
Handler interface for a prompt service that allows for natural language or media data queries, backed by technologies such as large language models (LLMs) or image generation models.

The user can configure prompt connections to a prompt service in the data -> prompt connections backend menu; and specific prompt queries in the form -> "prompt queries" menu. When the user create a new prompt connection, they need to select which type of prompt service they would like to use. Prompt service type implementations are either built-in services included in formcycle; or plugin services provided by a plugin.

Prompt services may differ significantly in how they operate and what features they provide. There is no common standard protocol for prompt services like there is e.g. SQL for interacting with databases. For example, an LLM-based prompt service may support text generation and summarization, while an image generation prompt service may support generating images from text prompts. They may also require or support wildly different configuration parameters. Therefore, services are given full freedom in how they operate. The only commonality is that they are given a JSON value and binary files as input; operate as a black box that does whatever may be needed; and return a JSON value and binary files as output.

Each prompt service type has:

Since:
8.5.0
  • Method Details

    • computeQueryInput

      Given a prompt query, computes the input parameters required to execute the query. The engine will provide the parameters to the executePromptQuery method. The input parameter descriptors are also used for documentation purposes or to generate a user interface for the prompt query workflow action.
      Parameters:
      params - Parameters to the computation, such as the prompt query.
      Returns:
      The list of descriptors for the input of the query.
    • computeQueryOutput

      Given a prompt query, computes the output parameters that will be returned by the executePromptQuery method. The output parameter descriptors are e.g. used for documentation purposes; or by the prompt query workflow action to determine which output parameters are available after executing the prompt query.
      Parameters:
      params - Parameters to the computation, such as the prompt query.
      Returns:
      The list of descriptors for the output of the query.
    • deserializeConnectionConfig

      ConnectionConfig deserializeConnectionConfig(SerializedPromptConfig serializedConfig) throws PromptSerializationException
      Deserializes a serialized prompt connection configuration into a Object object, as previously serialized by serializeConnectionConfig(Object). This method allows you to use a custom serialization format, such as JSON or XML.

      Note: There is no guarantee that the serialized data matches the format you expect. The data may come from a different version of the prompt type service, or from a different prompt type service altogether. You must take the necessary precautions to validate the data and handle errors gracefully. In general, we recommend using the data that can be mapped to your model class, discarding the remaining data, and using defaults for missing data.

      It is recommended, but not required, to store the version of the implementation in the serialized configuration. This allows you to update the configuration in this method when newer versions of the implementation require a different configuration format.

      Parameters:
      serializedConfig - The serialized configuration to deserialize.
      Returns:
      A deserialized connection configuration object.
      Throws:
      PromptSerializationException - If the deserialization fails due to invalid data. You should try to avoid raising an exception where possible, and use defaults for missing or invalid data instead. If this exception is thrown, the prompt connection may not be usable and the user may have to delete and recreate it.
      See Also:
    • deserializeQueryConfig

      QueryConfig deserializeQueryConfig(SerializedPromptConfig serializedConfig) throws PromptSerializationException
      Deserializes a serialized prompt query configuration into a QueryConfig object, as previously serialized by serializeQueryConfig(Object). This method allows you to use a custom serialization format, such as JSON or XML.

      Note: There is no guarantee that the serialized data matches the format you expect. The data may come from a different version of the prompt type service, or from a different prompt type service altogether. You must take the necessary precautions to validate the data and handle errors gracefully. In general, we recommend using the data that can be mapped to your model class, discarding the remaining data, and using defaults for missing data.

      It is recommended, but not required, to store the version of the implementation in the serialized configuration. This allows you to update the configuration in this method when newer versions of the implementation require a different configuration format.

      Parameters:
      serializedConfig - The serialized configuration to deserialize.
      Returns:
      A deserialized query configuration object.
      Throws:
      PromptSerializationException - If the deserialization fails due to invalid data. You should try to avoid raising an exception where possible, and use defaults for missing or invalid data instead. If this exception is thrown, the prompt query may not be usable and the user may have to delete and recreate it.
      See Also:
    • executePromptQuery

      Executes a prompt query using the given parameters, and returns the result of the query.

      This method is given a value for each parameter as defined by computeQueryInput(IPromptComputeQueryInputParams). The prompt engine ensures all required parameters are present. Optional input parameter may be absent.

      This method must return a value for each output parameter as defined by computeQueryOutput(IPromptComputeQueryOutputParams). The prompt engine will check that required parameters are present. Optional output parameters may be absent.

      Parameters:
      params - The parameters for the execution, such as the connection and query configuration, and the values for each input parameter.
      Returns:
      The result of the prompt query execution, with the values for each output parameter.
      Throws:
      PromptExecutionException - If the execution fails due to some reason, e.g. due to a network error or when the quota limit was exceeded. You should throw one of the subclasses of this exception to indicate the appropriate reason of the failure. ExecutionFailedException is the generic fallback if no more specific exception is available.
      RuntimeException - Implementations should not throw a runtime exception. If they do, it is treated as an ExecutionFailedException.
    • getConnectionConfigClass

      default Class<ConnectionConfig> getConnectionConfigClass()
      Gets the class of the connection configuration type parameter.

      The default implementation attempts to read the type of the ConnectionConfig type parameter via reflection. If that does not work, or you need to optimize, override this method and return the type directly.

    • getConnectionViewBeanClass

      default Class<? extends IPromptConnectionBean<ConnectionConfig>> getConnectionViewBeanClass()
      Returns the class of the bean that should be used when editing the properties of a prompt connection. May be null if you do not require any bean or custom logic. When you only wish to access the properties of your configuration, you do have to use a custom bean - the model is available via the expression language variable model. See getConnectionViewXhtml() for further details.

      The default returns null, which uses no extra bean. An extra bean may not be required for simple UIs if you only need to access the properties model.

      Returns:
      The class of the bean to use for editing a prompt connection's configuration.
      See Also:
    • getConnectionViewXhtml

      URL getConnectionViewXhtml() throws MalformedURLException
      This method must return the path to the XHTML page for the custom user interface of a prompt connection. Usually the XHTML file is part of the JAR resources of the module or plugin. In this case, you should return a URL to a JAR file resource (jar:file:/...) like so:
      @Override
      public URL getConnectionViewXhtml() {
        return getClass().getResource("/path/to/view.xhtml");
      }
      

      The contents of this XHTML page is included in the backend menu for prompt connections, already inside a form (i.e. do not add an additional h:form as that would result in an error). You should wrap your custom UI in a naming container to ensure unique IDs that do not clash with other prompt services. Implementations may (but need not) use the components provided by the http://www.xima.de/taglib/xfc/prompt tag library. The following is a recommended template on which you may base your UI:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:xp="http://www.xima.de/taglib/xfc/prompt">
      
        <xp:ui id="CHANGE_THIS_TO_A_UNIQUE_ID">
      
          <!-- Custom section with editors specific to your workflow element -->
          <xp:fieldset legend="#{msg['MyAwesomePromptService.connection.fs.base']}">
            <!-- A simple input field for the API key -->
            <xp:apiKey id="apiKey" value="#{model.apiKey}" required="true"/>
         </xp:fieldset>
      
        </xp:ui>
      </ui:composition>
      

      The XHTML page may access the following expression language variables:

      • model: The deserialized configuration of the connection.
      • msg: A virtual ResourceBundle for the localized messages, backed by the message localizer. Empty when that method returns null. For example, if the resource bundle contains the key prompt.label, you can access the localized message via the EL expression msg['prompt.label']
      • bean: An instance of the bean class returned by getConnectionViewBeanClass. Will be null if that method does not define a bean class.
      The XHTML page may use the following additional search expressions (e.g. for the process and update attributes of a <p:ajax />):
      • @promptUi: Resolves to the closest <xp:ui /> component from the http://www.xima.de/taglib/xfc/prompt tag library.
      • @promptFieldset: Resolves to the closest <xp:promptFieldset /> component from the http://www.xima.de/taglib/xfc/prompt tag library.

      To access the values of an enum or the constants defined by a class, consider using:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:o="http://omnifaces.org/ui">
        <o:importConstants type="my.fully.classified.path.MyEnum" var="MyEnum" loader="#{model}"/>
      </ui:composition>
      
      The loader argument is only required for plugins and ensures that the correct class loader is used that knows about the plugin class. Without the loader attribute, the above is equivalent to the PrimeFaces tag handler <p:importConstants />.
      Returns:
      Path to the XHTML view, must noe be null. If you do return null, it will be treated as an error and an appropriate message is displayed to the user informing them that the properties panel could not be loaded.
      Throws:
      MalformedURLException - This exception is declared for convenience - normally you would use new URL(String) with a constant URL string that should not throw. In case an exception is thrown, it is treated the same as if this returned null.
    • getMessageLocalizer

      IMessageLocalizer getMessageLocalizer()
      Retrieves the message localizer for custom messages, such as localized messages for the configuration UI.
      Returns:
      The resource bundle to use for localized messages.
    • getQueryConfigClass

      default Class<QueryConfig> getQueryConfigClass()
      Gets the class of the query configuration type parameter.

      The default implementation attempts to read the type of the QueryConfig type parameter via reflection. If that does not work, or you need to optimize, override this method and return the type directly.

    • getQueryViewBeanClass

      default Class<? extends IPromptQueryBean<ConnectionConfig, QueryConfig>> getQueryViewBeanClass()
      Returns the class of the bean that should be used when editing the properties of a prompt query. May be null if you do not require any bean or custom logic. When you only wish to access the properties of your configuration, you do have to use a custom bean - the model is available via the expression language variable model. See getQueryViewXhtml() for further details.

      The default returns null, which uses no extra bean. An extra bean may not be required for simple UIs if you only need to access the properties model.

      Returns:
      The class of the bean to use for editing a prompt query's configuration.
      See Also:
    • getQueryViewXhtml

      URL getQueryViewXhtml() throws MalformedURLException
      This method must return the path to the XHTML page for the custom user interface of a prompt query. Usually the XHTML file is part of the JAR resources of the module or plugin. In this case, you should return a URL to a JAR file resource (jar:file:/...) like so:
      @Override
      public URL getQueryViewXhtml() {
        return getClass().getResource("/path/to/view.xhtml");
      }
      

      The contents of this XHTML page is included in the backend menu for prompt queries, already inside a form (i.e. do not add an additional h:form as that would result in an error). You should wrap your custom UI in a naming container to ensure unique IDs that do not clash with other prompt services. Implementations may (but need not) use the components provided by the http://www.xima.de/taglib/xfc/prompt tag library. The following is a recommended template on which you may base your UI:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:xp="http://www.xima.de/taglib/xfc/prompt">
      
        <xp:ui id="CHANGE_THIS_TO_A_UNIQUE_ID">
      
          <!-- Custom section for the UI of your prompt queries -->
          <xp:fieldset legend="#{msg['MyAwesomePromptService.prompt.fs.base']}>
            <!-- A simple select field for the type of the task -->
              <xp:task id="task" value="#{model.task}" options="#{bean.taskTypeOptions}">
                <p:ajax global="false" listener="#{bean.onPromptQueryParamFieldChanged}"
                  process="@this,@promptUi:taskConfig"
                  update="@promptUi:taskConfig" />
              </xp:task>
          </xp:fieldset>
        </xp:ui>
      
      </xp:composition>
      

      The XHTML page may access the following expression language variables:

      • model: The deserialized configuration of the query.
      • msg: A virtual ResourceBundle for the localized messages, backed by the message localizer. Empty when that method returns null. For example, if the resource bundle contains the key prompt.label, you can access the localized message via the EL expression msg['prompt.label']
      • bean: An instance of the bean class returned by getQueryViewBeanClass. Will be null if that method does not define a bean class.
      The XHTML page may use the following additional search expressions (e.g. for the process and update attributes of a <p:ajax />):
      • @promptUi: Resolves to the closest <xp:ui /> component from the http://www.xima.de/taglib/xfc/prompt tag library.
      • @promptFieldset: Resolves to the closest <xp:promptFieldset /> component from the http://www.xima.de/taglib/xfc/prompt tag library.

      To access the values of an enum or the constants defined by a class, consider using:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:o="http://omnifaces.org/ui">
        <o:importConstants type="my.fully.classified.path.MyEnum" var="MyEnum" loader="#{model}"/>
      </ui:composition>
      
      The loader argument is only required for plugins and ensures that the correct class loader is used that knows about the plugin class. Without the loader attribute, the above is equivalent to the PrimeFaces tag handler <p:importConstants />.
      Returns:
      Path to the XHTML view, must noe be null. If you do return null, it will be treated as an error and an appropriate message is displayed to the user informing them that the properties panel could not be loaded.
      Throws:
      MalformedURLException - This exception is declared for convenience - normally you would use new URL(String) with a constant URL string that should not throw. In case an exception is thrown, it is treated the same as if this returned null.
    • getType

      String getType()
      The technical type of this prompt service. Must be unique across all prompt services, including built-in and plugin services. For plugins, we recommend using a prefix to avoid clashes with built-in services and other plugin services, such as the group and artifact ID of the plugin.
      Returns:
      The type of the prompt service.
    • getTypeDisplayDescriptionKey

      String getTypeDisplayDescriptionKey()
      Gets the key for the display description of this type of prompt service, such as "A prompt service that uses OpenAI's GPT-3 model to generate text responses." This might be shown in the prompt service selection UI, to provide further details for getTypeDisplayNameKey().

      The returned key will be localized via getMessageLocalizer().

      Returns:
      The display description of the prompt service, localized for the given locale.
    • getTypeDisplayNameKey

      String getTypeDisplayNameKey()
      Gets the display name of this type of prompt service, such as "OpenAI GPT-3" or "Stable Diffusion". Might e.g. be shown when the user select a prompt service type.

      The returned key will be localized via getMessageLocalizer().

      Returns:
      The display name of the prompt service, localized for the given locale.
    • getTypeIcon

      default IGuiIcon getTypeIcon()
      Gets the icon that should be used to represent this prompt service, such as in the backend menu. The default implementation returns a default neutral icon.
      Returns:
      The icon to use for this prompt service. Must not be null.
    • serializeConnectionConfig

      SerializedPromptConfig serializeConnectionConfig(ConnectionConfig config) throws PromptSerializationException
      Serializes the configuration of a prompt connection into a format that can be stored in a data storage, such as a database or a file. This method allows you to use a custom serialization format, such as JSON or XML.

      It is recommended, but not required, to store the version of the implementation in the serialized configuration. This allows you to update the configuration upon serialization when newer versions of the implementation require a different configuration format.

      Note regarding files: You need to ensure the last modified date is set correctly in the serialized configuration. When saving a prompt connection and the date remains the same, the binary data will not be updated (to avoid reading the data into memory, then writing it back, which is unnecessary). If you change the binary data, you must update the last modified date.

      Parameters:
      config - The configuration of the prompt connection to serialize.
      Returns:
      A serialized representation of the connection configuration, which can be stored in a database or file.
      Throws:
      PromptSerializationException - If the serialization fails due to some reason.
      See Also:
    • serializeQueryConfig

      Serializes the configuration of a prompt query into a format that can be stored in a data storage, such as a database or a file. This method allows you to use a custom serialization format, such as JSON or XML.

      It is recommended, but not required, to store the version of the implementation in the serialized configuration. This allows you to update the configuration upon serialization when newer versions of the implementation require a different configuration format.

      Note regarding files: You need to ensure the last modified date is set correctly in the serialized configuration. When saving a prompt query and the date remains the same, the binary data will not be updated (to avoid reading the data into memory, then writing it back, which is unnecessary). If you change the binary data, you must update the last modified date.

      Parameters:
      config - The configuration of the prompt query to serialize.
      Returns:
      A serialized representation of the query configuration, which can be stored in a database or file.
      Throws:
      PromptSerializationException - If the serialization fails due to some reason.
      See Also:
    • testConnection

      Tests the given prompt service connection to see if it is valid and can be used to execute queries.
      Parameters:
      params - The parameters for the test connection, with the connection configuration and any additional data needed.
      Returns:
      The result of the test connection, with the success status and any error messages.
      Throws:
      Exception - Any exception is treated as connection test failure with an unspecific, and will be reported as such to the user. You should avoid throwing an exception and return a proper error message instead.