@formio/uag 1.4.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,22 +1,25 @@
1
- # The Form.io "Universal Agent Gateway" (UAG)
2
- The Universal Agent Gateway (UAG) is an exciting new technology that brings JSON powered (model driven) [Form.io](https://form.io) forms to AI Agents. Leveraging the power of the [**Model Context Protocol (MCP)**](https://modelcontextprotocol.io/docs/getting-started/intro), this library provides AI Agents with **dynamic context** of how to interface with any backend system using Form.io JSON Forms as the common language between these agents and Enterprise systems.
1
+ # The Form.io Universal Agent Gateway (UAG)
2
+ The Universal Agent Gateway (UAG) introduces the power of [Form.io](https://form.io) forms to AI agents.
3
+
4
+ The Form.io UAG uses the [**Model Context Protocol (MCP)**](https://modelcontextprotocol.io/docs/getting-started/intro) to enable Form.io interaction through an AI agent workflow. By providing AI agents with the **dynamic context** of how to use Form.io JSON forms, the UAG allows a user to interact with any aspect of their enterprise system served by the Form.io Platform directly through their AI agent.
3
5
 
4
6
  ---
5
7
 
6
8
  ## Table of Contents
7
9
 
8
- - [The Form.io "Universal Agent Gateway" (UAG)](#the-formio-universal-agent-gateway-uag)
9
- - [Introduction](#introduction)
10
- - [How it works](#how-it-works)
10
+ - [The Form.io Universal Agent Gateway (UAG)](#the-formio-universal-agent-gateway-uag)
11
+ - [Introduction](#introduction)
12
+ - [The Model Context Protocol (MCP)](#the-model-context-protocol-mcp)
13
+ - [Dynamic Context](#dynamic-context)
14
+ - [The Role of the UAG](#the-role-of-the-uag)
11
15
  - [Technical Overview](#technical-overview)
12
16
  - [MCP Tools](#pre-defined-mcp-tools-providing-dynamic-context)
13
17
  - [Custom Modules](#custom-modules)
14
18
  - [Module Documentation](./module)
15
- - [Getting Started](#getting-started)
16
- - [Example Local Deployment](./examples/local)
17
- - [Runtime Environments](#runtime-environments)
18
- - [Node.js (Express):](#nodejs-express)
19
- - [Docker](#docker)
19
+ - [Deploying UAG](#deploying-uag)
20
+ - [Runtime Environments](#runtime-environments)
21
+ - [Docker](#docker)
22
+ - [Node.js (Express)](#nodejs-express)
20
23
  - [Environment Variables](#environment-variables)
21
24
  - [Running on Public Domain](#running-on-public-domain)
22
25
  - [Using with Form.io Enterprise Server](#using-with-formio-enterprise-server)
@@ -24,71 +27,83 @@ The Universal Agent Gateway (UAG) is an exciting new technology that brings JSON
24
27
  ---
25
28
 
26
29
  ## Introduction
27
- The core purpose of the UAG is to provide AI Agents the ability to understand dynamic data structures defined from JSON form definitions. It accomplishes this goal by combining two innovative Open Source technologies.
30
+ The core purpose of the UAG is to equip AI agents with the ability to forward a user's inputs to the Form.io platform. It allows the AI agent to apply natural language requests, scanned documents, and any other input it can parse into Form.io functionality, as defined by selected forms and fields.
31
+
32
+ ### The Model Context Protocol (MCP)
33
+ The Model Context Protocol (MCP) is an open-source standard for connecting AI applications to external systems.
34
+
35
+ The MCP essentially puts an AI agent's hands on the controls of an external system. In the case of Form.io, the MCP describes a discrete set of tools the AI agent can use to interact with forms, fields, and submissions. While some tools are delivered off-the-shelf, this functionality can be extended, modified, or refined through custom built modules.
28
36
 
29
- - [**Form.io JSON Forms**](https://form.io): The Form.io platform enables deterministic data collection through the use of JSON form definitions created with a drag-and-drop form builder interface. Once created, these forms serve as more than just a front-end interface for humans to "fill out", but rather serve as a standard data model contract between applications and any backend processes that depend on that data. It ensures that every system is speaking the same language and provides human-in-the-loop experiences (through rendered forms) to collect, audit, and report on the data exchanges between many complex data driven systems. Here is a visual graphic showing how the Form JSON serves as the "centerpiece" contract to ensure data integrity throughout your Enterprise.
37
+ ### Dynamic Context
38
+ What does it mean to say MCP provides a dynamic context for how to use these tools?
30
39
 
31
- ![](./examples/images/form-interfaces.png)
40
+ The power of AI agents is their ability to parse free-form inputs, like natural language, and infer a user's intent rather than take rote input like a command line. The dynamic context delivered by MCP gives the AI agent guidance on how to correlate the user's prompt to the tools and data available within Form.io. When the AI agent receives a prompt, it uses this dynamic context to determine what tool it should use, what elements of the prompt are inputs to that tool, and what additional input might be necessary.
32
41
 
33
- - [**Model Context Protocol (MCP)**](https://modelcontextprotocol.io/docs/getting-started/intro): The Model Context Protocol (MCP) is a standard for connecting AI Applications to external systems. It achieves this by providing AI Agents with "context" so that they can understand how to interact with the external systems. When combined with the Form.io's dynamic JSON forms, the "context" that is provided to the AI Agents is also dynamic in nature making it so that AI Agent interactions can easily be controlled via the Form JSON models that are defined by Form.io
42
+ ### The Role of the UAG
43
+ The UAG is the package that contains everything sitting between the Form.io Platform and the AI agent.
44
+ It contains the stock MCP server, the authorization infrastructure, and any custom tools or modules that extend the functionality.
34
45
 
35
- ## How it works
46
+ By equipping an AI agent with Form.io capabilities, the UAG brings the AI agent much deeper into the broader application ecosystem.
47
+ Form.io's drag-and-drop Form Builder simultaneously defines the look of the form and the structure of the data. This makes it easy to use data collected through Form.io forms elsewhere in an application or as an input to other enterprise systems.
48
+ ![](./examples/images/form-interfaces.png)
49
+
50
+ When the UAG is able to map the freeform inputs that an AI agent receives to the data model defined by a form, it means that data can be quickly supplied to the enterprise tools that depend on the Form.io platform without additional interpretation or transformation.
51
+ This allows the UAG and Form.io to serve as a reliable middleware between an AI agent and countless other systems.
36
52
 
37
- The UAG provides **dynamic context** to AI Agents though the introduction of new MCP "tools" that describe the dynamic form structures to AI Agents so that they understand how to properly structure the data being processed by those agents. This cabability allows for Developers to treat AI Agents as they would any other Human who is submitting a form, and ensure that the AI Agents stay "on the rails" without requiring extensive domain specific agent training methods to accomplish the same goal. But more imporantly, the UAG offers Enterprises the ability to create trustworthy data interfaces through the use of dynamic and composable JSON data model definitions created and managed through Form.io. This not only enforces deterministic data interactions from AI Agents, but also provides an auditable human-in-the-loop experience through the provided Form.io Open Source and Enterprise portal applications.
53
+ The same role-based access control that governs all Form.io forms and submissions still applies to any interaction through the UAG. This addresses many potential issues some users may have with connecting AI agents to enterprise systems.
38
54
 
39
- Here is a visual graphic of the layers provided by the UAG to achieve a trusted and deterministic interface between AI Agents to external systems through the UAG + Form.io Server.
55
+ Here is a visual graphic of the layers provided by the UAG to achieve a trusted and deterministic interface between AI Agents to external systems through the UAG + Form.io Server.
40
56
 
41
- ![](./examples/images/agents_to_formio.png)
57
+ ![](./examples/images/agents_to_formio.png)
42
58
 
43
59
  ## Technical Overview
44
- The UAG can be thought of as consisting of many "layers" of functionality, broken up between the actions that fetch dynamic context and the ones that submit deterministic data structures. The following layers are leveraged within the UAG.
45
-
46
- 1. **MCP Interface**: The entry point of the UAG is the MCP interface that sits between the AI Agent and the tools that are executed on the server.
47
- 2. **Authorization**: As part of the MCP specification, every interaction betwen the AI Agent and the backend service must pass through an Authorization process leveraging OIDC (PKCE) authentication. The UAG takes this process one step further, however, by adding an OIDC (PKCE) authentication layer on top of the existing authentication flexibilities that Form.io already provides. Because of this, it is possible to authenticate with the UAG if you are using SAML, Form.io Authentication, OIDC, or even Custom Authentication processes through the Form.io platform.
48
- 3. [**Pre-defined MCP Tools providing Dynamic Context**](#pre-defined-mcp-tools-providing-dynamic-context): The UAG utilizes the MCP to provide a number of pre-defined tools that provide AI Agents with dynamic context based on the Forms and Resources within the Form.io platform. These tools are described in more detail in a section below.
49
- 4. **Custom Tools** (provided by a [Custom Module](#custom-modules)): This enables developers to introduce any new tools that can leverage the Form.io forms and submission data structures to provide additional capabilities introduced to the AI Agents. This would allow for custom agent interactions to achieve certain goals for specific use cases.
50
- 5. **Custom Actions** (provided by a [Custom Module](#custom-modules)): Enables developers to create composable middleware that will be executed once all data provided by the AI agent has been sanitized and validated. This provides the ability to interface the data collected from AI Agents with any backend system or workflow.
51
- 6. **Built-in Actions**: In addition to any custom actions that my be introduced via a Module, the UAG also supports a handlful of existing Actions that can be assigned to any form or resource. Actions such as the **Webhook** that will send a REST api call to any endpoint once any submission has been made by an AI Agent. This can be used to point to any serverless function to instigate backend workflows that are triggered from the interactions from AI Agents.
52
- 7. **Pre-defined Forms and Resources** (provided by a [Custom Module](#custom-modules)): Allows for a developer to release a "module" that provides default data structures to the AI Agent. This would be useful if a developer wishes to create a module that achieves a specific goal where the data structures required for that goal need to follow a pre-determined set of fields provided by a form or resource. For example, if a developer wishes to release a CRM module for the UAG, then it would make sense that the module would also provide the default **Customer** and **Company** resources that commonly accompany most CRM implementations.
53
- 8. **Custom Database** (provided by a [Custom Module](#custom-modules)): By default, the UAG performs the data collection and retrieval via a "Submission Proxy", whereas the data is submitted via REST API to either the Enterprise Server project or the Open Source server. This, however, could be modified to send the data directly to and from a Database. This can be achieved via the Database Interface provided from the UAG. For more information, see the **Module** documentation. This feature does require that the UAG is connected to the Enterprise Server.
60
+ The UAG can be thought of as consisting of many layers of functionality. Each layer is broadly either serving to fetch dynamic context, or submit deterministic data structures. The following layers are leveraged within the UAG:
61
+
62
+ 1. **MCP Interface**: The entry point of the UAG is the MCP interface that sits between the AI agent and the tools that are executed on the server.
63
+ 2. **Authorization**: As part of the MCP specification, every interaction between the AI agent and the backend service must pass through an Authorization process leveraging OIDC (PKCE) authentication. The UAG takes this process one step further, however, by adding an OIDC (PKCE) authentication layer on top of the existing authentication flexibilities that Form.io already provides. Because of this, it is possible to authenticate with the UAG if you are using SAML, Form.io Authentication, OIDC, or even Custom Authentication processes through the Form.io platform.
64
+ 3. [**Pre-defined MCP Tools providing Dynamic Context**](#pre-defined-mcp-tools-providing-dynamic-context): The UAG utilizes the MCP to provide a number of pre-defined tools that provide AI agents with dynamic context based on the Forms and Resources marked as compatible within the Form.io platform. These tools are described in more detail in a section below.
65
+ 4. **Custom Tools** (provided by [Custom Modules](#custom-modules)): This enables developers to introduce any new tools that can leverage Form.io forms and submission data structures to provide additional capabilities introduced to the AI agents. This would allow for custom agent interactions to achieve certain goals for specific use cases.
66
+ 5. **Custom Actions** (provided by [Custom Modules](#custom-modules)): Enables developers to create composable middleware that will be executed once all data provided by the AI agent has been sanitized and validated. This provides the ability to interface the data collected from AI agents with any backend system or workflow.
67
+ 6. **Built-in Actions**: In addition to any custom actions introduced via a Module, the UAG supports a handful of existing Actions that can be assigned to any form or resource. Actions such as the **Webhook** that will send a REST API call to any endpoint once any submission has been made by an AI agent. This can be used to point to any serverless function to instigate backend workflows that are triggered from the interactions from AI agents.
68
+ 7. **Pre-defined Forms and Resources** (provided by [Custom Modules](#custom-modules)): Allows a developer to release a module that provides default data structures to the AI agent. This would be useful if a developer wishes to create a module that achieves a specific goal, where the data structures required for that goal need to follow a pre-determined set of fields provided by a form or resource. For example, if a developer wishes to release a CRM module for the UAG, then it would make sense that the module would also provide the default **Customer** and **Company** resources that commonly accompany most CRM implementations.
69
+ 8. **Custom Database** (provided by [Custom Module](#custom-modules)): By default, the UAG performs the data collection and retrieval via a "Submission Proxy", whereas the data is submitted via REST API to either the Enterprise Server project or the Open Source server. This, however, could be modified to send the data directly to and from a Database. This can be achieved via the Database Interface provided from the UAG. For more information, see the **Module** documentation. This feature does require that the UAG is connected to the Enterprise Server.
54
70
 
55
71
  Here is a diagram to understand how all of these layers are organized to make up the UAG.
56
72
 
57
73
  ![](./examples/images/uag-overview.png)
58
74
 
59
- For each of these layers, the following documentation applies...
60
-
61
75
  ### Pre-defined MCP Tools providing Dynamic Context
62
76
  The following tools provided by the UAG can be described as follows:
63
77
 
64
- | Tool Name | Tool Description |
65
- |-------------------|----------------------------------------------------------------------------------|
66
- | get_forms | Provides the AI Agent an understanding of what Forms are available. It will only return forms that have been tagged **uag**. |
67
- | get_form_fields | Once a form has been identified by the AI Agent that the user wishes to engage with (using natural language), this tool provides the AI Agent a high level overview of all the fields needed (along with the field data path) to submit that form. |
68
- | get_field_info | Once the fields have been determined using the `get_form_fields` tool, this tool is used to get specific information about the requested fields, such as validation, conditionals, input formats, etc. This tool provides the AI Agent the ability to undersand how to "format" and structure the data that is sent to the MCP server. |
69
- | collect_field_data | This tool provides the AI Agent a mechanism to dynamically collect the required information from the user. It is capable of collecting many fields at once, and also provides the AI agent the ability to understand what required fields are missing and what is needed to complete its goal. This tool supports complex, yet structured, data collecting through multiple "nested" data constructs such as Nested Forms and Table structured data (datagrid, editgrid). |
70
- | confirm_form_submission | This tool provides the AI Agent the ability to confirm all the information it has collected before a submission has been made. It allows the AI Agent the ability to get a confirmation from the user before it submits the form. |
71
- | submit_completed_form | This tool provides the AI Agent the ability to submit all of the data collected from the user to complete the form submission.
72
- | find_submissions | A very powerful tool that provides the AI Agent the ability to understand how to query for data within the form. This enables the user to say something like "What is the email address of Joe Smith who is the CTO of Microsoft?" and it will format the query responsible for finding that record within the Form.io database.
73
- | submission_update | Provides the AI agent the ability to update an existing record with any additional information. This also has the awareness to "append", "prepend", and perform any other operations on the data in congruence with how the user has requested the data be updated.
78
+ | Tool Name | Tool Description |
79
+ |-----------------|----------------------|
80
+ | get_forms | Provides the AI agent with a list of available forms. <br/>It will only return forms that have been tagged `uag`. |
81
+ | get_form_fields | When the AI agent infers the user intends to use a specific form, this tool provides the agent with a high level overview of all the fields needed (along with the field data path) to submit that form. |
82
+ | get_field_info | Once the fields have been determined using `get_form_fields`, this tool provides specific information about the requested fields, such as validation, conditionals, input formats, etc. <br/>This tool instructs the AI agent on how to format and structure the data that is sent to the MCP server. |
83
+ | collect_field_data | Provides the AI agent with a mechanism to dynamically collect the required information from the user. It can parse the user's input into multiple fields at once, and will identify additional inputs from the user if needed. <br/>This tool supports complex and structured data collection and is compatible with nested or multi-value fields like nested forms, data grids, etc. |
84
+ | confirm_form_submission | This tool is used to provide a summary of all data collected before a submission is made to the form. |
85
+ | submit_completed_form | Provides the AI agent with the ability to submit all of the data collected from the user to create the form submission. |
86
+ | find_submissions | Enables the agent to parse a user's natural language request into a query for a submission, or a specific field of a particular submission. |
87
+ | submission_update | Provides the AI agent with the ability to update an existing submission, either by supplying unfilled fields or updating existing ones if allowed. Provides the AI agent with the context of the existing field values, allowing inline changes or edits. |
74
88
 
75
89
  ### Custom Modules
76
- While the UAG can be used as a stand-alone system to enable the interaction between AI Agents and dynamic JSON forms, the true power of this platform will be realized when developers extend the capabilities of this platform to solve industry specific use cases through the use of Custom Modules and Tools. It is possible for a developer to create a **Module** that introduces a number of custom tools, actions, and pre-defined resources and forms to achieve interactions with industry specific technologies.
90
+ While the UAG can be used as a stand-alone system to enable the interaction between AI agents and dynamic JSON forms, the true power of this platform will be realized when developers extend the capabilities of this platform to solve industry specific use cases through the use of Custom Modules and Tools. It is possible for a developer to create a **Module** that introduces a number of custom tools, actions, and pre-defined resources and forms to achieve interactions with industry specific technologies.
77
91
 
78
- For example, by creating a UAG Module for Salesforce, you can produce a system that can dynamically provide Customer and Company resource data structures to any AI Agent, and then through the use of Custom Actions, you can integrate that structured data directly to Salesforce via their own API's as the following image illustrates.
92
+ For example, by creating a UAG Module for Salesforce, you can produce a system that can dynamically provide Customer and Company resource data structures to any AI agent, and then through the use of Custom Actions, you can integrate that structured data directly to Salesforce via their own API's as the following image illustrates.
79
93
 
80
94
  <sub>This is just an example.</sub>
81
95
  ![](./examples/images/uag-custom-module.png)
82
96
 
83
97
  Custom modules are able to achieve this custom integration capabilities through the use of the following mechanisms:
84
98
 
85
- 1. **Pre-defined Form and Resources**: Using the Form.io template system, a custom module can include a template export of a Form.io project that includes a number of Forms, Resources, and Actions (as well as any Roles and Permissions associated with them). By using the module, this will then automatically "register" these assets so that the AI Agent is immediately aware of those assets. For example, if your module includes a Customer resource with "First Name", "Last Name", and "Email" and you use that module. If you then simply ask an AI Agent, "I would like to add a new Customer" the agent will automatically be aware of the context for the customer data structures and know exactly what your intent is when making that request.
86
- 2. **Custom Actions**: Actions can be thought of as composable middleware functions that allow for configurable Express.js middleware function to be attached to any Form and Resource, and then be executed once the data being submitted by an AI Agent has already passed through the proper data validations and sanitizations. These can be used to provide custom integrations to backend processes and workflows.
87
- 3. **Custom Tools**: In addition to providing custom actions, a Module can also introduce custom MCP Tools to provide bespoke interaction capabilities between the UAG and the AI Agents for any industry specific purposes.
99
+ 1. **Pre-defined Form and Resources**: Using the Form.io template system, a custom module can include a template export of a Form.io project that includes a number of Forms, Resources, and Actions (as well as any Roles and Permissions associated with them). By using the module, this will then automatically "register" these assets so that the AI agent is immediately aware of those assets.
100
+ For example, imagine a module includes a Customer resource with "First Name", "Last Name", and "Email" fields. If you then simply ask an AI agent, "I would like to add a new Customer" the agent will automatically be aware of the context for the customer data structures and know exactly what your intent is when making that request.
101
+ 2. **Custom Actions**: Actions can be thought of as composable middleware functions that allow for configurable Express.js middleware functions to be attached to any Form and Resource, and then to be executed once the data being submitted by an AI agent has passed through the proper data validations and sanitization. These can be used to provide custom integrations to backend processes and workflows.
102
+ 3. **Custom Tools**: In addition to providing custom actions, a Module can also introduce custom MCP Tools to provide bespoke interaction capabilities between the UAG and the AI agents for any industry specific purposes.
88
103
  4. **Custom Authentication**: A module can also modify the "authentication" landing page to assist with any custom requirements that are needed around Authentication.
89
104
  5. **Behavior Overrides**: A module also has the ability to "override" any default behavior from the UAG. This ensures that whomever is using a certain module can "tweak" certain tools and responses to achieve better results as it pertains their their industry specific needs.
90
105
 
91
- It is our goal to enable developers to build and contribute their own Custom modules to the broader community through Github and NPM. For example, once these modules proliferate, it may be possible to install the salesforce module for UAG with the following.
106
+ Form.io aims to enable developers to build and contribute their own custom modules to the broader community through GitHub and NPM. For example, once these modules proliferate, it may be possible to install the salesforce module for UAG with the following.
92
107
 
93
108
  <sub>This is just an example.</sub>
94
109
  ```
@@ -122,93 +137,33 @@ try {
122
137
 
123
138
  To get started in building your own custom module, go to the help documentation at [Modules Readme](./module/Readme.md).
124
139
 
125
- ## Getting Started
126
- The quickest way to become familar with the UAG is to first walk through our Local Example, and run it on your local machine. This will allow you to see how the UAG leverages the power of Form.io to connect with an AI Agent to provide dynamic context. All of this can be ran locally for free without any subscriptions required!
127
-
128
- **[Go to Local Example &raquo;](examples/local)**
140
+ ## Deploying UAG
141
+ The following sections describe the process of creating a running instance of UAG, connecting it to the Form.io Platform, and configuring an AI agent to use it.
129
142
 
130
- ## Runtime Environments
131
- There are currently two run-time environments that work with the UAG. **Node.js (Express)** and **Docker**.
143
+ This documentation focuses on using UAG with Form.io Open Source. For documentation on using UAG with Form.io Enterprise, refer to [Help.Form.io/UAG](https://help.form.io/uag).
132
144
 
133
- ### Node.js (Express):
134
- With the Node.js environment, you can import the UAG within a locally running Node.js and Express.js envioronment. This works by first importing the UAG module and "use"ing it within an Express.js application. First, you will install the uag inside of your Node.js Express application like the following.
145
+ ### Local Example
146
+ The quickest way to become familiar with the UAG is to first walk through our Local Example, which will spin up a local instance of Form.io Open Source and UAG. This can then be connected to an AI agent, which will have the ability to interact with the included example forms. The local example can be run entirely free, with no trial or license required.
135
147
 
136
- ```npm install --save @formio/uag```
137
-
138
- or
148
+ **[Go to Local Example &raquo;](examples/local)**
139
149
 
140
- ```yarn add @formio/uag```
150
+ ### Runtime Environments
151
+ There are currently two run-time environments that work with the UAG:
152
+ -[**Docker**](#docker)
153
+ -[**Node.js (Express)**](#nodejs-express)
141
154
 
142
- You can then mount the UAG within your Express application like the following example shows.
143
-
144
- ```js
145
- import 'dotenv/config';
146
- import Express from 'express';
147
- import { UAGServer } from '@formio/uag';
148
- try {
149
- (async function () {
150
- const server = new UAGServer();
151
- const app = Express();
152
- app.use(await server.router());
153
- const port = process.env.PORT || 3200;
154
- app.listen(port, () => {
155
- console.log(`Form.io UAG server running on port ${port}`);
156
- console.log(`Visit http://localhost:${port} to access the application`);
157
- });
158
- })();
159
- } catch (error) {
160
- console.error('Failed to start server:', error);
161
- process.exit(1);
162
- }
163
- ```
164
-
165
- There is also a way to extend the functionality of the UAG through the use of modules, which is documented in the [Modules Readme](./module/Readme.md)
166
155
 
167
156
  ### Docker
168
- In addition to running the UAG in Node.js, you can also run the UAG within the Docker environment. This enables a wide range of deployment options into common hosting environments such as AWS and Azure as well as allow for the use in common orchestration runtimes such as Kubernetes and Docker Compose. The container that you will use for running the UAG is as follows.
157
+ Running the UAG in Docker enables a wide range of deployment options into common hosting environments such as AWS and Azure. Additionally, it allows for the use of common orchestration runtimes such as Kubernetes and Docker Compose. The container that you will run the UAG is as follows:
169
158
 
170
159
  ```
171
160
  formio/uag
172
161
  ```
173
162
 
174
- This container can be ran as a standalone container using the common **docker run** command, or inside of a **docker-compose.yml** (for Docker Compose). To see an example of using UAG with Docker Compose, we recommend taking a look at the [Local Example](./examples/local).
175
-
176
- #### Docker Run
177
- Here are some examples of running the UAG using the ```docker run``` command.
178
-
179
- **UAG pointed to an Open Source server**
180
- ```
181
- docker run -d \
182
- -e "PROJECT=https://forms.mysite.com" \
183
- -e "ADMIN_KEY=CHANGEME" \
184
- -e "JWT_SECRET=CHANGEME" \
185
- -e "BASE_URL=https://forms.mysite.com" \
186
- -e "LOGIN_FORM=https://forms.mysite.com/user/login" \
187
- -e "PORT=3200" \
188
- --restart unless-stopped \
189
- --network formio \
190
- --name formio-uag \
191
- -p 3200:3200 \
192
- formio/uag:rc
193
- ```
163
+ This container can be run in two ways:
164
+ - [**Docker-Compose.yml**](#docker-compose-recommended) - The recommended method, deploys with of a Docker Compose multicontainer.
165
+ - [**Docker Run**](#docker-run) - a standalone container using the common `docker run` command.
194
166
 
195
- **UAG pointed to an Form.io Enterprise Server**
196
- ```
197
- docker run -d \
198
- -e "PROJECT=https://forms.mysite.com/myproject" \
199
- -e "PROJECT_KEY=CHANGEME" \
200
- -e "UAG_LICENSE=YOUR-LICENSE" \
201
- -e "JWT_SECRET=CHANGEME" \
202
- -e "PORTAL_SECRET=CHANGEME" \
203
- -e "BASE_URL=https://forms.mysite.com" \
204
- -e "LOGIN_FORM=https://forms.mysite.com/myproject/user/login" \
205
- -e "PORT=3200" \
206
- --restart unless-stopped \
207
- --network formio \
208
- --name formio-uag \
209
- -p 3200:3200 \
210
- formio/uag:rc
211
- ```
212
167
 
213
168
  #### Docker Compose (Recommended)
214
169
  The recommended way to launching the UAG is through Docker Compose. This enables you to orchestrate several of the containers to run within a single instance to provide a more seamless and simple way of managing your deployments. Here is a simple example of how to run both the Form.io UAG + Form.io OSS server on the same instance.
@@ -242,7 +197,7 @@ services:
242
197
  ports:
243
198
  - "3000:3000"
244
199
  formio-uag:
245
- image: formio/uag:rc
200
+ image: formio/uag
246
201
  restart: always
247
202
  links:
248
203
  - formio
@@ -267,11 +222,48 @@ This can be run by typing the following...
267
222
  docker compose up -d
268
223
  ```
269
224
 
225
+ #### Docker Run
226
+ Here are some examples of running the UAG using the ```docker run``` command.
227
+
228
+ **UAG pointed to an Open Source server**
229
+ ```
230
+ docker run -d \
231
+ -e "PROJECT=https://forms.mysite.com" \
232
+ -e "ADMIN_KEY=CHANGEME" \
233
+ -e "JWT_SECRET=CHANGEME" \
234
+ -e "BASE_URL=https://forms.mysite.com" \
235
+ -e "LOGIN_FORM=https://forms.mysite.com/user/login" \
236
+ -e "PORT=3200" \
237
+ --restart unless-stopped \
238
+ --network formio \
239
+ --name formio-uag \
240
+ -p 3200:3200 \
241
+ formio/uag
242
+ ```
243
+
244
+ **UAG pointed to an Form.io Enterprise Server**
245
+ ```
246
+ docker run -d \
247
+ -e "PROJECT=https://forms.mysite.com/myproject" \
248
+ -e "PROJECT_KEY=CHANGEME" \
249
+ -e "UAG_LICENSE=YOUR-LICENSE" \
250
+ -e "JWT_SECRET=CHANGEME" \
251
+ -e "PORTAL_SECRET=CHANGEME" \
252
+ -e "BASE_URL=https://forms.mysite.com" \
253
+ -e "LOGIN_FORM=https://forms.mysite.com/myproject/user/login" \
254
+ -e "PORT=3200" \
255
+ --restart unless-stopped \
256
+ --network formio \
257
+ --name formio-uag \
258
+ -p 3200:3200 \
259
+ formio/uag
260
+ ```
261
+
270
262
  Once it is running, you can then navigate to the following to access both the OSS Deployment + UAG Server
271
263
  - http://localhost:3000: The Form.io OSS Server
272
264
  - http://localhost:3200: The UAG Server
273
265
 
274
- In both the Node.js runtime environemnt as well as Docker, the way to control the UAG is thorugh the use of **Environment Variables** and **Modules**.
266
+ In both the Node.js runtime environmnt as well as Docker, the way to control the UAG is through the use of **Environment Variables** and **Modules**.
275
267
 
276
268
  ### Environment Variables
277
269
  This module can be configured in many ways. One of those ways is through the use of Environment Variables, which are documented as follows.
@@ -279,26 +271,37 @@ This module can be configured in many ways. One of those ways is through the use
279
271
  | Variable | Description | Example |
280
272
  |----------|-------------|---------|
281
273
  | PROJECT | The API Endpoint to either an Enterprise project endpoint, or the OSS server url. | http://localhost:3000 |
282
- | PROJECT_KEY | (Enterprise Only) Either a Project API Key (for Form.io Enterprise) or the ADMIN_KEY for Community Edition. | CHANGEME |
283
- | ADMIN_KEY | (OSS Only) Allows you to provide the ADMIN_KEY to install and connect to the OSS Server. | CHANGEME |
274
+ | PROJECT_KEY | (Enterprise Only) Either a Project API Key (for Form.io Enterprise) or the ADMIN_KEY for Open Source. | CHANGEME |
275
+ | ADMIN_KEY | (Open Source Only) Allows you to provide the ADMIN_KEY to install and connect to the OSS Server. | CHANGEME |
284
276
  | UAG_LICENSE | The license to run the UAG against a Form.io Enterprise Deployment. | |
277
+ | PROJECT_TTL | The project cache TTL in seconds. This controls the amount of time to check for any "changes" that have been made to the project to refresh any forms and resources within the UAG. | 900 |
285
278
  | PORT | The port you wish to run the server on. | 3200 |
286
279
  | DEBUG | Variable used to perform debug logs of server activity | formio.* |
287
280
  | PORTAL_SECRET | Enterprise Only: Allows you to connect to the UAG from the Form.io Enterprise Portal. | CHANGEME |
288
281
  | JWT_SECRET | A secret used to generate and validate JWT tokens generated through the authentication process of the UAG. This does not need to match the JWT_SECRET of the Enterprise Server that it is connected to. | CHANGEME |
289
- | PORTAL_SECRET | (Enterprise Only) Used to connect the UAG server with the Enterprise Portal | CHANGEME |
290
282
  | JWT_EXPIRE_TIME | The expiration for the jwt secret. | 3600 |
291
- | MONGO | (Enterprise Only) Allows you to connect the UAG directly to a mongo database vs. having to redirect the submissions to the Form.io Submission APIs. | |
283
+ | MONGO | (Enterprise Only) Allows you to connect the UAG directly to a mongo database, rather than having to redirect the submissions to the Form.io Submission APIs. | |
292
284
  | MONGO_CONFIG | JSON configuration for the Node.js Mongo Driver. | |
293
- | BASE_URL | The public URL that the UAG is hosted on. This allows for proper OIDC authentication and allows for the authentication callbacks to point to the correct url. | https://ai.onform.io |
285
+ | BASE_URL | The public URL that the UAG is hosted on. This allows for proper OIDC authentication and allows for the authentication callbacks to point to the correct url. | https://forms.yoursite.com |
294
286
  | LOGIN_FORM | The public URL to the Login Form JSON endpoint. | https://mysite.com/project/user/login |
295
287
  | CORS | The cors domain, or the JSON configuration to configure the "cors" node.js module cross domain resource sharing. | *.* |
296
288
 
289
+ ### Project Cache and TTL
290
+ By default, the UAG uses a TTL to "fetch" any of the project assets and register them and cache them into the UAG. What this means is that if you make any changes to your underlying project forms and resources (either directly or through a deployment), you need to wait a maximum of the TTL setting (in seconds) to see any updates that have been made. For example, if the TTL is set to 900 (or 15 minutes), and you make a change to any forms and resources, you must wait at most 15 minutes to see any of these changes take effect into the UAG. It should be noted that when a "refresh" occurs, an API call to the "export" method is called on the underlying project endpoint. This is a processor intensive API call, so it is not recommended to set the TTL to any value less than 60. A value of 0 is interpreted as "No TTL", which means the only way to refresh the project forms and resourcs, a UAG reboot is necessary.
291
+
292
+ Here is a table explaining how this parameter can be used.
293
+
294
+ | Environment Variable | Value | Result |
295
+ |----------|-------------|---------|
296
+ | PROJECT_TTL | 0 | No TTL (refresh) will occur. This can be used to "disable" any refresh and ensure the ONLY way to refetch updated forms and resources, you must reboot the UAG server. |
297
+ | PROJECT_TTL | 60 | Check for changes every minute |
298
+ | PROJECT_TTL | 3600 | Check for changes every hour |
299
+
297
300
  ### Running on Public Domain
298
- In order to run the UAG on a public domain, it is very important to provide the proper configurations so that any AI Agent can properly authenticate. There are 3 different "domain" environment variables that matter, and it is important to understand how to configure them depending on your use case:
301
+ In order to run the UAG on a public domain, it is very important to provide the proper configurations so that any AI agent can properly authenticate. There are 3 different "domain" environment variables that matter, and it is important to understand how to configure them depending on your use case:
299
302
 
300
303
  #### PROJECT
301
- The ```PROJECT``` environment variable is used to establish a connetion from the UAG server to the project endpoint (for Enterprise) or OSS base url. This does NOT need to be a public DNS entry, but rather a URL that connects the UAG container to the Server container. The following examples illustrate how this would be configured.
304
+ The ```PROJECT``` environment variable is used to establish a connection from the UAG server to the project endpoint (for Enterprise) or OSS base url. This does NOT need to be a public DNS entry, but rather a URL that connects the UAG container to the Server container. The following examples illustrate how this would be configured.
302
305
 
303
306
  ##### Local connection to OSS Server
304
307
  If you are using a local connection, such as within a Docker Compose file, you can configure the ```PROJECT``` environment variable to point directly to the local url as follows.
@@ -314,7 +317,7 @@ services:
314
317
  PORT: 3000
315
318
  ADMIN_KEY: CHANGEME
316
319
  formio-uag:
317
- image: formio/uag:rc
320
+ image: formio/uag
318
321
  restart: always
319
322
  links:
320
323
  - formio
@@ -325,7 +328,7 @@ services:
325
328
  ADMIN_KEY: CHANGEME
326
329
  ```
327
330
 
328
- In this example, we have Docker Compose launching the OSS Form.io container with the ADMIN_KEY set for this deployment, the UAG is connected using ```http://formio:3000``` which is the local Docker network name (provided using the "links" property in the docker compose file)
331
+ In this example, we have Docker Compose launching the OSS Form.io container with the ADMIN_KEY set for this deployment, the UAG is connected using ```http://formio:3000``` which is the local Docker network name (provided using the "links" property in the docker compose file).
329
332
 
330
333
  ##### Local Connection to Enterprise Server Project
331
334
  If you are using the Enterprise Form.io server within a local environment to the UAG, then you will need to ensure that the UAG connects to an independent project using the PROJECT_KEY as follows.
@@ -340,7 +343,7 @@ services:
340
343
  environment:
341
344
  PORT: 3000
342
345
  formio-uag:
343
- image: formio/uag:rc
346
+ image: formio/uag
344
347
  restart: always
345
348
  links:
346
349
  - formio-enterprise
@@ -359,7 +362,7 @@ docker-compose.yml: Connected to Enterprise (formio/formio-enterprise)
359
362
  version: "3.8"
360
363
  services:
361
364
  formio-uag:
362
- image: formio/uag:rc
365
+ image: formio/uag
363
366
  restart: always
364
367
  environment:
365
368
  PROJECT: https://forms.mydomain.com/myproject
@@ -371,7 +374,7 @@ docker-compose.yml: Connected to Open Source (formio/formio)
371
374
  version: "3.8"
372
375
  services:
373
376
  formio-uag:
374
- image: formio/uag:rc
377
+ image: formio/uag
375
378
  restart: always
376
379
  environment:
377
380
  PROJECT: https://forms.mydomain.com
@@ -379,58 +382,68 @@ services:
379
382
  ```
380
383
 
381
384
  #### BASE_URL
382
- The ```BASE_URL``` is used to communicate to the AI Agent the public domain that is hosting the UAG server. This value is provided within the ```.well-known``` definitions for the OIDC (PKCE) authentication. If this is not correct, then the AI Agent will not be able to authenticate into the UAG.
385
+ The ```BASE_URL``` is used to communicate to the AI agent the public domain that is hosting the UAG server. This value is provided within the ```.well-known``` definitions for the OIDC (PKCE) authentication. If this is not correct, then the AI agent will not be able to authenticate into the UAG.
383
386
 
384
- **This needs to be the publically accessible domain that you are hosting your UAG.**
387
+ **This needs to be the publicly accessible domain that you are hosting your UAG.**
385
388
 
386
389
  For example, ```BASE_URL: https://forms.mysite.com```.
387
390
 
388
391
  #### LOGIN_FORM
389
- This is the publically accessible URL to the Login form of your Project or OSS deployment. This provides the URL that is loaded when the user navigates to ```{{ BASE_URL }}/auth/authorize```. If you navigate to this URL, and the page says that you cannot load the form, then this is because your LOGIN_FORM environment variable is not pointing to the correct form JSON endpoint of your project.
392
+ This is the publicly accessible URL to the Login form of your Project or OSS deployment. This provides the URL that is loaded when the user navigates to ```{{ BASE_URL }}/auth/authorize```. If you navigate to this URL, and the page says that you cannot load the form, then this is because your LOGIN_FORM environment variable is not pointing to the correct form JSON endpoint of your project.
390
393
 
391
394
  For example:
392
395
  - Enterprise Example: ```LOGIN_FORM: https://forms.mysite.com/myproject/user/login```
393
396
  - OSS Example: ```LOGIN_FORM: https://forms.mysite.com/user/login```
394
397
 
395
- ## Using with Form.io Enterprise Server
396
- If you are using the UAG with the Form.io Enterprise Server, you unlock several benefits with regards to managing the Forms and Resources within the UAG. Some of the features that you gain with our Enterprise Server are as follows:
397
-
398
- - **Form Revisions** - Our form revision system provides a way to keep track of any changes made to any forms, and associate those changes with the submission data that is submitted against those revisions. This feature enables you to ensure that if any form schemas change, that the data submitted for that form correlates with the revision of the form in which it was submitted. In addition to this powerful feature, you can also leverage Form Revisions as a method to "roll-back" any mistakes or regressions caused by form changes. Instead of having to re-train or un-train an AI Agent with any schema, you simply revert to previous revisions and the AI Agent will adjust accordingly.
399
- - **Submission Revisions** - Submission revisions provides a way to keep track of any data changes that have been made to a submission and provides information on who changed the data. This combined with the power of the UAG provides any system the ability to audit any changes in data made by both AI Agents as well as humans in the workflow processes.
400
- - **Stage Versions and Deployments** - Stage versions provides a way to create a "tag" version accross all forms and resources within a project. This ensures that you can stamp a point in time where your AI Agent (which may consume many different forms and resources) interfaces with your whole project in a deterministic way. It also provides a much more elegant "roll-back" mechansism where the entire project of forms and resources can be versioned and deployed independently.
401
- - **Custom Actions** - Through the use of the Developer Portal and remote connections, you can use the Actions UI to manage and configure any custom actions that are configured within your UAG. Once a custom action is registered, via the **Modules** system, you can add that action to a form and configure it using the Form.io Developer Portal.
398
+ ### Node.js (Express):
399
+ With the Node.js environment, you can import the UAG within a locally running Node.js and Express.js environment. This works by first importing the UAG module and "use"ing it within an Express.js application. First, you will install the UAG inside of your Node.js Express application like the following.
402
400
 
403
- ### Running the UAG against the Enterprise Server
404
- In order to run the UAG against an Enterprise Server, you need to provide a few Environment variables that are different from the OSS runtime of this module. The following environment variables are required to run against an Enterprise Project.
401
+ ```npm install --save @formio/uag```
405
402
 
406
- | Variable | Description | Example |
407
- |----------|-------------|---------|
408
- | PROJECT | For the Enterprise Server, this points to the Project Endpoint you wish to bind the UAG to. | https://mydeployment.com/myproject |
409
- | PROJECT_KEY | An API Key for that project, provided within the Project Settings | CHANGEME |
410
- | UAG_LICENSE | This is the licnese provided to you from the Form.io License team. Contact support@form.io to acquire a "temporary" or full license. | |
411
- | PORTAL_SECRET | This enables you to "connect" your Form.io Developer Portal to the UAG so that you can view any custom actions as well as perform deployments to the UAG. | |
403
+ or
412
404
 
413
- Once you have these environment variables in place, you should be able to run the UAG pointed to your Enterprise Project. You can now connect to this UAG from the Developer Portal as follows.
405
+ ```yarn add @formio/uag```
414
406
 
415
- ### Connecting your Developer Portal to the UAG.
416
- Once you have the UAG running in your own environment with a PORTAL_SECRET, you will now create a new Stage within your Developer portal. We can call this UAG.
407
+ You can then mount the UAG within your Express application, as seen in the following example:
417
408
 
418
- <div align="center">
419
- <img src="./examples/images/uag-create-stage.png" alt="Create UAG Stage" width="600">
420
- </div>
409
+ ```js
410
+ import 'dotenv/config';
411
+ import Express from 'express';
412
+ import { UAGServer } from '@formio/uag';
413
+ try {
414
+ (async function () {
415
+ const server = new UAGServer();
416
+ const app = Express();
417
+ app.use(await server.router());
418
+ const port = process.env.PORT || 3200;
419
+ app.listen(port, () => {
420
+ console.log(`Form.io UAG server running on port ${port}`);
421
+ console.log(`Visit http://localhost:${port} to access the application`);
422
+ });
423
+ })();
424
+ } catch (error) {
425
+ console.error('Failed to start server:', error);
426
+ process.exit(1);
427
+ }
428
+ ```
421
429
 
422
- Next, you will click on **Staging** and then connect to your UAG server by providing the PORTAL_SECRET as follows.
430
+ There is also a way to extend the functionality of the UAG through the use of modules, which is documented in the [Modules Readme](./module/Readme.md)
423
431
 
424
- <div align="center">
425
- <img src="./examples/images/connect-uag.png" alt="Connect to UAG" width="600">
426
- </div>
432
+ ## Using with Form.io Enterprise Server
433
+ When using the UAG with the Form.io Enterprise Server, you unlock several benefits with regards to managing the Forms and Resources within the UAG. Some of the features that you gain with our Enterprise Server include:
427
434
 
428
- Now that the UAG is connected, you can then navigate to any Forms and Resources. These are the forms and resources hosted through the UAG.
435
+ - **Form Revisions** - Our form revision system provides a way to keep track of any changes made to any forms, and associate those changes with the submission data that is submitted against those revisions. This feature enables you to ensure that if any form schemas change, that the data submitted for that form correlates with the revision of the form in which it was submitted. In addition to this powerful feature, you can also leverage Form Revisions as a method to "roll-back" any mistakes or regressions caused by form changes. Instead of having to re-train or un-train an AI agent with any schema, you simply revert to previous revisions and the AI agent will adjust accordingly.
436
+ - **Submission Revisions** - Submission revisions provides a way to keep track of any data changes that have been made to a submission and provides information on who changed the data. This combined with the power of the UAG provides any system the ability to audit any changes in data made by both AI agents as well as humans in the workflow processes.
437
+ - **Stage Versions and Deployments** - Stage versions provides a way to create a "tag" version across all forms and resources within a project. This ensures that you can stamp a point in time where your AI agent (which may consume many different forms and resources) interfaces with your whole project in a deterministic way. It also provides a much more elegant "roll-back" mechanism where the entire project of forms and resources can be versioned and deployed independently.
429
438
 
430
- ### Deploying changes to your UAG using Stage Versions
431
- Next, you will simply use the existing Staging and Deployment system from your Developer portal to "deploy" any changes to your UAG. This will allow you to treat the UAG just like you would treat any other stage within your Enterprise deployment. This will allow you to track and any forms and resource changes using the Tag system, and then deploy new versions as well as "roll-back" to any previous versions if a change is made that does to perform as you would expect within the AI Agent enviornment. This is a stark contrast to what Enterprises must deal with "Trained Agents" where it is much harder to "roll back" any training that an agent has gone through.
439
+ ### Running the UAG against the Enterprise Server
440
+ In order to run the UAG against an Enterprise Server, you need to provide a few Environment variables that are different from the OSS runtime of this module. The following environment variables are required to run against an Enterprise Project.
432
441
 
433
- ### Custom Actions within Developer Portal
434
- In addition to managing Tags and Versions within the Developer portal, you can also use the Developer Portal to add Custom Actions to any forms and resources. Within the stage that is connected to the UAG, you can navigate to any Form or Resource, and then click on **Actions**. From there, any actions that show up in the Drop-down list of Actions that you can add to this form, you will see any Custom Actions that are part of your **Module** that you can also attach to your Forms and Resources. From here, you can add custom configurations and settings for each Action instance. It can also be versioned just like any other standard action using the tagging and versioning system.
442
+ | Variable | Description | Example |
443
+ |----------|-------------|---------|
444
+ | PROJECT | For the Enterprise Server, this points to the Project Endpoint you wish to bind the UAG to. | https://mydeployment.com/myproject |
445
+ | PROJECT_KEY | An API Key for that project, provided within the Project Settings | CHANGEME |
446
+ | UAG_LICENSE | This is the license provided to you from the Form.io License team. Contact support@form.io to acquire a "temporary" or full license. | |
435
447
 
448
+ Once you have these environment variables in place, you should be able to run the UAG pointed to your Enterprise Project.
436
449
 
@@ -76,6 +76,13 @@ export declare class UAGFormInterface extends FormInterface {
76
76
  * @returns { boolean } - True if the component is an input component, false otherwise.
77
77
  */
78
78
  inputComponent(component: Component): boolean;
79
+ getEmptyValue(component: Component): {}[] | {
80
+ data: {};
81
+ }[] | {
82
+ data: {};
83
+ } | {
84
+ data?: undefined;
85
+ } | null;
79
86
  /**
80
87
  * Get the relevant fields from the current form. This will return any non-nested input components whose
81
88
  * values have not already been set within the data model. This allows the agent to know what fields still need to be
@@ -223,6 +223,22 @@ class UAGFormInterface extends appserver_1.FormInterface {
223
223
  }
224
224
  return true;
225
225
  }
226
+ getEmptyValue(component) {
227
+ const modelType = core_1.Utils.getModelType(component);
228
+ switch (modelType) {
229
+ case 'nestedArray':
230
+ return [{}];
231
+ case 'nestedDataArray':
232
+ return [{ data: {} }];
233
+ case 'dataObject':
234
+ return { data: {} };
235
+ case 'object':
236
+ case 'map':
237
+ return {};
238
+ default:
239
+ return null;
240
+ }
241
+ }
226
242
  /**
227
243
  * Get the relevant fields from the current form. This will return any non-nested input components whose
228
244
  * values have not already been set within the data model. This allows the agent to know what fields still need to be
@@ -255,8 +271,16 @@ class UAGFormInterface extends appserver_1.FormInterface {
255
271
  name: 'getFields',
256
272
  shouldProcess: () => true,
257
273
  process: async (context) => {
258
- const { component, path, value } = context;
274
+ const { component, path, value, data } = context;
259
275
  if (this.isNestedComponent(component)) {
276
+ // For nested components, we need to always have a value so that the child components
277
+ // are added to the list of fields needing data.
278
+ if (core_1.Utils.isComponentDataEmpty(component, data, path)) {
279
+ const emptyValue = this.getEmptyValue(component);
280
+ if (emptyValue !== null) {
281
+ (0, lodash_1.set)(data, path, emptyValue);
282
+ }
283
+ }
260
284
  nestedPaths.push(path);
261
285
  }
262
286
  },
@@ -301,8 +325,10 @@ class UAGFormInterface extends appserver_1.FormInterface {
301
325
  if (component.validate?.required) {
302
326
  fieldInfo.totalRequired++;
303
327
  }
304
- // If the component hass a value, then skip it.
305
- if ((0, core_1.componentHasValue)(component, value)) {
328
+ // If the value is not empty, then we can skip this field.
329
+ const emptyValue = this.getEmptyValue(component);
330
+ const hasValue = emptyValue === null ? (0, core_1.componentHasValue)(component, value) : !(0, lodash_1.isEqual)(value, emptyValue);
331
+ if (hasValue) {
306
332
  if (component.validate?.required) {
307
333
  fieldInfo.totalRequiredCollected++;
308
334
  }
@@ -9,7 +9,8 @@
9
9
  4. If they do not wish to "Add Another", then use the `get_form_fields` tool to determine if there are any more fields that need to be collected outside of the **<%= parent.label %>** component. If so, use the `collect_field_data` tool to collect that information (make sure to change the `parent_path` parameter to the level above the **<%= parent.label %>** field, or leave empty if we are at the root of the form).
10
10
  <% } else if (parent && (parent.isForm || parent.isContainer)) { %>
11
11
  1. Use the `get_form_fields` tool with `parent_path`="<%= parent.data_path %>" and `criteria`="optional" to check if there are any optional fields. If so, ask the user if they wish to fill any of them out.
12
- 2. If there are no optional fields, or the user declines, then use the `get_form_fields` tool to determine if there are any more fields that need to be collected outside of the <%= parent.label %> component. If so, use the `collect_field_data` tool to collect that information (make sure to change the parent parameter to the level above the <%= parent.label %> field, or leave empty if we are at the root of the form).
12
+ 2. If there are no optional fields, or the user does not wish to add any more values to the <%= parent.label %> component, then use the `get_form_fields` tool to determine if there are any more fields that need to be collected outside of the <%= parent.label %> component. If so, use the `collect_field_data` tool to collect that information (make sure to change the parent parameter to the level above the <%= parent.label %> field, or leave empty if we are at the root of the form).
13
13
  <% } else { %>
14
14
  1. Use the `get_form_fields` tool with `criteria`="optional" to check if there are optional fields. If so, ask the user if they wish to fill any of them out.
15
- 2. If there are no optional fields, or the user declines, then use the `confirm_form_submission` tool to show summary and get confirmation to submit the form.<% } %>
15
+ 2. If there are no optional fields then use the `submit_completed_form` tool to submit the data. If necessary, use the `confirm_form_submission` tool to provide them a summary of the collected values before submission.
16
+ 3. If there are optional fields, but the user does not want to add anything else, use the `submit_completed_form` tool to submit the data. If necessary, use the `confirm_form_submission` tool to provide them a summary of the collected values.<% } %>
@@ -6,9 +6,9 @@ No fields were found matching `criteria`="<%= criteria %>" for <%= parentLabel %
6
6
  <% } else if (parent) { %>
7
7
  - Considering the search was made using a `parent_path` context, try the search again at a higher `parent_path` context.
8
8
  <% } else if (criteria === "optional") { %>
9
- - Since there are no more "optional" fields, use the `confirm_form_submission` tool to ensure all the collected information is correct.
9
+ - Since there are no more "optional" fields, use the `submit_completed_form` tool to submit all the information if the user confirms they wish to do so, if necessary use the `confirm_form_submission` tool to ensure all the collected information is correct.
10
10
  <% } else if (criteria === "required") { %>
11
11
  - Use the `get_form_fields` tool, with `criteria`="optional" to determine if there are any optional fields they wish to provide information for.
12
12
  <% } else { %>
13
- - Use the `confirm_form_submission` tool to ensure all the collected information is correct.
13
+ - Use the `submit_completed_form` tool to submit all the information if the user confirms they wish to do so, if necessary use the `confirm_form_submission` tool to ensure all the collected information is correct.
14
14
  <% } %>
@@ -8,7 +8,7 @@ const confirmSubmission = async (project) => {
8
8
  return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.confirm_form_submission || {}, {
9
9
  name: 'confirm_form_submission',
10
10
  title: 'Confirm Form Submission',
11
- description: 'Show a summary of the collected form data and ask the user for confirmation before submitting',
11
+ description: 'Show a summary of the collected form data if the user wishes to see a summary of the collected data',
12
12
  inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
13
13
  .form_name()
14
14
  .form_data().schema,
@@ -9,7 +9,7 @@ const submitCompletedForm = async (project) => {
9
9
  return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.submit_completed_form || {}, {
10
10
  name: 'submit_completed_form',
11
11
  title: 'Submit Completed Form',
12
- description: 'Submit the completed form data to Form.io API ONLY after the user has explicitly confirmed submission (said "yes", "confirm", etc.)',
12
+ description: 'Submit the completed form data. Should only be used once all the required fields have been collected, and the user has explicitly confirmed submission (e.g. has said "submit", "send", "done", etc)',
13
13
  inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
14
14
  .form_name()
15
15
  .form_data().schema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/uag",
3
- "version": "1.4.3",
3
+ "version": "1.8.0",
4
4
  "description": "The Form.io Universal Agent Gateway (UAG).",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -12,10 +12,10 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "clean": "rm -rf lib",
15
- "build:ts": "tsc",
15
+ "build:ts": "npx tsc",
16
16
  "build:copy-templates": "mkdir -p lib/templates && cp src/templates/*.md lib/templates/",
17
17
  "build": "npm run clean && npm run build:ts && npm run build:copy-templates",
18
- "build:docker": "npm run build && docker build -t formio/uag:rc --platform=linux/amd64 .",
18
+ "build:docker": "npm run build && docker build -t formio/uag --platform=linux/amd64 .",
19
19
  "test": "TS_NODE_PROJECT=tsconfig.test.json mocha --no-node-snapshot",
20
20
  "dev": "tsx --no-node-snapshot index.js",
21
21
  "start": "node --no-node-snapshot index.js"
@@ -23,26 +23,26 @@
23
23
  "author": "",
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@formio/appserver": "^2.3.2",
26
+ "@formio/appserver": "^2.8.0",
27
27
  "@formio/core": "2.5.1-dev.291.6557e4e",
28
- "@modelcontextprotocol/sdk": "^1.21.1",
28
+ "@modelcontextprotocol/sdk": "^1.23.0",
29
29
  "cors": "^2.8.5",
30
30
  "debug": "^4.4.1",
31
31
  "dotenv": "^17.2.1",
32
- "express": "^5.1.0",
32
+ "express": "^5.2.1",
33
33
  "jsonwebtoken": "^9.0.2",
34
34
  "lodash": "^4.17.21",
35
35
  "node-cache": "^5.1.2",
36
- "zod": "^3.25.76"
36
+ "zod": "^4.1.13"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/chai": "^5.2.3",
40
40
  "@types/cors": "^2.8.19",
41
41
  "@types/debug": "^4.1.12",
42
42
  "@types/dotenv": "^8.2.3",
43
- "@types/express": "^5.0.5",
43
+ "@types/express": "^5.0.6",
44
44
  "@types/jsonwebtoken": "^9.0.10",
45
- "@types/lodash": "^4.17.20",
45
+ "@types/lodash": "^4.17.21",
46
46
  "@types/mocha": "^10.0.10",
47
47
  "@types/node": "^24.10.1",
48
48
  "@types/supertest": "^6.0.3",
@@ -51,7 +51,7 @@
51
51
  "supertest": "^7.1.4",
52
52
  "terser": "^5.44.1",
53
53
  "ts-node": "^10.9.2",
54
- "tsx": "^4.20.4",
54
+ "tsx": "^4.21.0",
55
55
  "typescript": "^5.9.3"
56
56
  }
57
57
  }