@formio/uag 1.9.0-rc.2 → 1.9.0-rc.4

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
@@ -84,7 +84,8 @@ The following tools provided by the UAG can be described as follows:
84
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
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
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. |
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. |
88
+ | agent_provide_data | Enables an AI Agent to be able to analyze existing submission data according to rules defined with a configurable **Criteria**. It will then instruct the Agent to provide generated data for fields configured for a specific **persona** using the `submission_update` tool. Please read the [**Agent Provided Data**](#agent-provide-data) section for more information about this toolset. |
88
89
 
89
90
  ### Custom Modules
90
91
  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.
@@ -429,6 +430,61 @@ try {
429
430
 
430
431
  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)
431
432
 
433
+ ## Agentic Workflows
434
+ One of the more powerful features of the **UAG** is the `agent_process_data` tool. This tool provides the ability to instruct a generically trained agent how to analyze existing submission data, and then produce its own data by following a configurable **Criteria**. This behavior historically could only be achieved using a specifically trained agent, which does not provide any benefits of dynamic configurability that the Form.io platform offers. This tool is able to achieve this goal by providing a generally trained agent with the necessary "context" it needs to accurately produce its own data as part of an automated workflow. This feature is particularly helpful if you wish to utilize the UAG within an Agentic Workflow, where the AI Agent is capable of understanding structured data, and then contribute its own data by following the configured **Criteria** "context" provided by the UAG.
435
+
436
+ For example, let's suppose you wish to automate the backend administration behind a College Application Process. In this example, a potential student submits an application that consists of many different fields of data, such as Academnics, Extra curricular activities, Honors, Volunteer work, as well as possibly written Essays. Historically, these applications would be reviewed by an administrator in order to assess the candidates qualifications for acceptance. With the `agent_provide_data` tool, it is now possible to automate this process as the following diagram illustrates.
437
+
438
+ ![](./examples/images/uag-agent-provide-data.png)
439
+
440
+ To achieve this feat, the `agent_provide_data` tool utilizes the following information, which is then fed to the Generally trained agent to produce its own submission data.
441
+
442
+ - **Existing Submission Data**: In order for the agent to be able to contribute its own data, it must first have an existing submission to be used as the data that it will analyze according to the configured **Criteria**.
443
+ - **Criteria**: This is a piece of content that provides the agent the **Criteria** to follow when analyzing the data, but also provides instructions on how the agent should populate the **Required Fields**.
444
+ - **Required Fields**: These are the form fields which the Agent is required to fill out as part of the `agent_provide_data` process.
445
+
446
+ ### Setup
447
+ To configure a form to use the `agent_provide_data` tool, you must first designate a section of your form that will be read and used by the AI Agent. This is similar to what you would see in a form that says "For Office Use Only", but instead of a Human contributing to the values of this section, it will be an automated AI Agent. There are two types of fields that can be added to a form to configure it for use by the `agent_provide_data` tool: **Criteria** and **Agent Fields**
448
+
449
+ #### Agent "Criteria" component
450
+ The first thing that needs to be configured is a special **Content Component** that instructs the AI Agent how to interpret the data. For example, here is a Criteria content block that was written to instruct an AI Agent on how to assess the submission of a College Application Essay.
451
+
452
+ ![](./examples/images/criteria-example.png)
453
+
454
+ The goal of this content is to be written as you would write an instruction manual for a new employee who needs to learn how to analyze and understand the submission data that is provided. It is also used to instruct the AI Agent on how to populate the form values that are configured for that criteria. Once this criteria is written, It will then need to be "flagged" as a UAG field by adding a property called `uag` and the value of that property is to be thought of as the `persona` of the Agent. This provides the ability to have more than one agent assume different roles as it analyzes the submission data to provide their own values. In addition, the "criteria" content will also need to be provided a `uagField` property with the value equal to `criteria`. Below is what a properly configured `uag` criteria content component looks like.
455
+
456
+ ![](./examples/images/criteria-properties.png)
457
+
458
+ Once you have added this `Criteria` **Content Component** to your form, the next object is to add the fields you wish for the Agent to populate. These are called the **Agent Fields**.
459
+
460
+ #### Agent Fields
461
+ Anywhere in your form, you can drag and drop fields that can be flagged as Agent fields. Using the example above, imagine your form has a "For Office Use Only" section (maybe a Panel). Within this panel, the first thing you see is a Content Component with instructions on how the following fields should be filled out. This is the `Criteria` we just described. The next thing that follows are the fields that the Agent needs to populate. Any field that with a property of `uag` set to the same value as the `Criteria` content component will be used as the Agent fields.
462
+
463
+ For example, lets suppose that we have created a form for College Application essays. Below the **Criteria** may be some fields that the Agent needs to "score" the essays according to the provided **Criteria**. This may look like the following...
464
+
465
+ ![](./examples/images/agent-fields.png)
466
+
467
+ In order to "flag" each of these fields as Agent Fields, you simply need to add the `uag` property with the same persona flag that was giving to the `Criteria` content.
468
+
469
+ ![](./examples/images/agent-field-property.png)
470
+
471
+ **Nested Components**
472
+ It is also possible to "flag" a collection of fields with the `uag` property. This can be done by wrapping all of these fields within a **Nested Component** (such as Panel, Container, Fieldset, etc), and then all the fields within this nested component will be added to the context of that agent with that persona.
473
+
474
+ ### Multiple Persona's per form
475
+ It is also possible to achieve multiple persona's per-form. This is very helpful if there are several isolated evaluations that need to occur within a process. For example, if we look at the flow chart diagram shown above, we can see a College Application Form. The first agentic evaluation occurs when the form is submitted by the applicant, where their application is assessed to be accepted or not. From that point, IF the applicant is accepted, a completely different evaluation needs to occur to award Financial Aid or even Scholarships to the applicant. These would require completely different criteria to assess the submission data differently from one another.
476
+
477
+ To achieve this, you simply need to "flag" the components `uag` property value differently with the persona that applies for that field. For the example above, you would add a Content component to assess the if the applicant should be accepted, and then provide the following `uag` property to that content. `uag="application"`. Any fields that need to be filled out by the AI Agent for application approval would also be flagged with the property `uag="application"`. Then, in a different section of the form, you would create a separate Content component with the criteria for the financial admin AI Agent. This content would be flagged with the property `uag="finance"`. Any fields that the finance admin AI Agent need to fill out would also be flagged with `uag="finance"`. This provides a truely flexible and dynamic AI engagement where multiple generically trained agents can be "taught" dynamically how to read and interpret data that is only relevant to that part of the agentic process.
478
+
479
+ ## Integrations
480
+ In order to a aid in the "agentification" of the UAG, we have also provided some "integrations" that can be used to directly communicate with the Generically trained AI Agents to utilize the UAG to accomplish automated AI Agent behaviors. This involves providing a single API endpoint that is capable of triggering the AI Agent process along with the connections to your deployed UAG. These API endpoints can then be triggered using a simple Webhook action within a form to start an Agentic process as the result of a Form submission.
481
+
482
+ These integrations can be found within the **integrations** folder. The following **integrations** are provided to enable automated Agentic workflows.
483
+
484
+ - [Claude Integration](./integrations/claude)
485
+
486
+ Please click on one of these integration links to read how they work.
487
+
432
488
  ## Using with Form.io Enterprise Server
433
489
  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:
434
490
 
@@ -1,4 +1,4 @@
1
- import { AuthRequest, FormInterface, InterpolatedError } from "@formio/appserver";
1
+ import { AppServerForm, AuthRequest, FormInterface, InterpolatedError } from "@formio/appserver";
2
2
  import { Component, Submission, DataObject } from "@formio/core";
3
3
  import { UAGForm } from "./config";
4
4
  import { ParentInfo } from "./tools";
@@ -15,6 +15,7 @@ export type UAGComponentInfo = {
15
15
  }[];
16
16
  prompt?: string;
17
17
  nested?: boolean;
18
+ rule?: string;
18
19
  };
19
20
  export type UAGData = Array<{
20
21
  label: string;
@@ -48,8 +49,15 @@ export type FormFieldInfo = {
48
49
  components: UAGComponentInfo[];
49
50
  };
50
51
  };
52
+ export type UAGFields = {
53
+ persona: string;
54
+ criteria: string;
55
+ components: Record<string, UAGComponentInfo>;
56
+ };
51
57
  export declare class UAGFormInterface extends FormInterface {
52
58
  uag: UAGForm | null;
59
+ uagFields: Record<string, UAGFields>;
60
+ setComponent(form: AppServerForm, component: Component, path: string): void;
53
61
  getComponentFormat(component: Component): string;
54
62
  getComponentInfo(component: Component, path: string): UAGComponentInfo;
55
63
  isMultiple(component: Component | undefined): boolean;
@@ -121,4 +129,5 @@ export declare class UAGFormInterface extends FormInterface {
121
129
  convertToSubmission(data?: Record<string, any>): Submission;
122
130
  formatData(data?: DataObject): UAGData;
123
131
  formatSubmission(submission: Submission): UAGSubmission;
132
+ htmlToMarkdown(html: string): string;
124
133
  }
@@ -4,10 +4,46 @@ exports.UAGFormInterface = void 0;
4
4
  const appserver_1 = require("@formio/appserver");
5
5
  const core_1 = require("@formio/core");
6
6
  const lodash_1 = require("lodash");
7
+ const node_html_markdown_1 = require("node-html-markdown");
7
8
  class UAGFormInterface extends appserver_1.FormInterface {
8
9
  constructor() {
9
10
  super(...arguments);
10
11
  this.uag = null;
12
+ this.uagFields = {};
13
+ }
14
+ setComponent(form, component, path) {
15
+ if (form.tags?.includes('uag') && component.properties?.uag) {
16
+ const persona = component.properties?.uag;
17
+ if (!this.uagFields) {
18
+ this.uagFields = {};
19
+ }
20
+ let uagFields = this.uagFields[persona];
21
+ if (!uagFields) {
22
+ uagFields = { components: {} };
23
+ }
24
+ if (component.properties?.uagField) {
25
+ const property = component.properties?.uagField;
26
+ if (component?.html) {
27
+ uagFields[property] = this.htmlToMarkdown(component.html);
28
+ }
29
+ }
30
+ else {
31
+ if (component.components) {
32
+ core_1.Utils.eachComponent(component.components, (subComp, subPath) => {
33
+ const compInfo = this.getComponentInfo(subComp, `${path}.${subPath}`);
34
+ compInfo.rule = this.getComponentValueRule(subComp);
35
+ uagFields.components[compInfo.path] = compInfo;
36
+ });
37
+ }
38
+ else {
39
+ const compInfo = this.getComponentInfo(component, path);
40
+ compInfo.rule = this.getComponentValueRule(component);
41
+ uagFields.components[compInfo.path] = compInfo;
42
+ }
43
+ }
44
+ this.uagFields[persona] = uagFields;
45
+ }
46
+ return super.setComponent(form, component, path);
11
47
  }
12
48
  getComponentFormat(component) {
13
49
  switch (component.type) {
@@ -401,8 +437,13 @@ class UAGFormInterface extends appserver_1.FormInterface {
401
437
  formatData(data = {}) {
402
438
  const uagData = [];
403
439
  let prefix = '';
440
+ let withinUAG = false;
404
441
  core_1.Utils.eachComponentData(this.form?.components || [], data, (component, data, row, path) => {
405
442
  let value = (0, lodash_1.get)(data, path);
443
+ if (component.key === 'uag' || withinUAG) {
444
+ withinUAG = true;
445
+ return true;
446
+ }
406
447
  if (this.isNestedComponent(component)) {
407
448
  uagData.push({
408
449
  prefix,
@@ -413,6 +454,11 @@ class UAGFormInterface extends appserver_1.FormInterface {
413
454
  prefix += ' ';
414
455
  }
415
456
  else if (this.inputComponent(component) && (0, core_1.componentHasValue)(component, value)) {
457
+ if (typeof value === 'string' &&
458
+ ((component.editor === 'ckeditor') ||
459
+ (component.editor === 'quill'))) {
460
+ value = this.htmlToMarkdown(value);
461
+ }
416
462
  uagData.push({
417
463
  prefix,
418
464
  path,
@@ -424,6 +470,9 @@ class UAGFormInterface extends appserver_1.FormInterface {
424
470
  if (this.isNestedComponent(component)) {
425
471
  prefix = prefix.slice(0, -3);
426
472
  }
473
+ if (component.key === 'uag' || withinUAG) {
474
+ withinUAG = false;
475
+ }
427
476
  });
428
477
  return uagData;
429
478
  }
@@ -435,5 +484,13 @@ class UAGFormInterface extends appserver_1.FormInterface {
435
484
  modified: submission.modified
436
485
  };
437
486
  }
487
+ htmlToMarkdown(html) {
488
+ return node_html_markdown_1.NodeHtmlMarkdown.translate(html, {
489
+ bulletMarker: '-',
490
+ emDelimiter: '*',
491
+ strongDelimiter: '**',
492
+ indent: ' '
493
+ });
494
+ }
438
495
  }
439
496
  exports.UAGFormInterface = UAGFormInterface;
@@ -56,7 +56,6 @@ class UAGProjectInterface extends appserver_1.ProjectInterface {
56
56
  async router() {
57
57
  const router = await super.router();
58
58
  const uagRouter = (0, router_1.UAGRouter)(this);
59
- router.use('/uag', (req, res, next) => this.authorizeRequest(req, res, next), uagRouter);
60
59
  router.use('/mcp', (req, res, next) => this.authorizeRequest(req, res, next), uagRouter);
61
60
  return router;
62
61
  }
package/lib/config.d.ts CHANGED
@@ -43,6 +43,7 @@ export type UAGToolOverride = {
43
43
  submit_completed_form?: ToolInfo;
44
44
  submission_update?: ToolInfo;
45
45
  find_submissions?: ToolInfo;
46
+ agent_provide_data?: ToolInfo;
46
47
  };
47
48
  export interface UAGConfig extends ServerConfig {
48
49
  baseUrl?: string;
package/lib/template.d.ts CHANGED
@@ -31,8 +31,11 @@ export declare enum ResponseTemplate {
31
31
  fieldValidationErrors = "fieldValidationErrors",
32
32
  fields = "fields",
33
33
  fieldList = "fieldList",
34
+ fieldValues = "fieldValues",
34
35
  getAvailableForms = "getAvailableForms",
35
- noFormsAvailable = "noFormsAvailable"
36
+ noFormsAvailable = "noFormsAvailable",
37
+ uagComponentNotFound = "uagComponentNotFound",
38
+ agentProcessData = "agentProcessData"
36
39
  }
37
40
  export declare class UAGTemplate {
38
41
  config: UAGTemplateConfig;
package/lib/template.js CHANGED
@@ -69,8 +69,11 @@ var ResponseTemplate;
69
69
  ResponseTemplate["fieldValidationErrors"] = "fieldValidationErrors";
70
70
  ResponseTemplate["fields"] = "fields";
71
71
  ResponseTemplate["fieldList"] = "fieldList";
72
+ ResponseTemplate["fieldValues"] = "fieldValues";
72
73
  ResponseTemplate["getAvailableForms"] = "getAvailableForms";
73
74
  ResponseTemplate["noFormsAvailable"] = "noFormsAvailable";
75
+ ResponseTemplate["uagComponentNotFound"] = "uagComponentNotFound";
76
+ ResponseTemplate["agentProcessData"] = "agentProcessData";
74
77
  })(ResponseTemplate || (exports.ResponseTemplate = ResponseTemplate = {}));
75
78
  class UAGTemplate {
76
79
  constructor(config = {}) {
@@ -0,0 +1,19 @@
1
+ Please read and understand the following **--- CRITERIA ---** section. This section provides instructions on how to analyze the **--- SUBMISSION ---** section that follows. Your objective is to provide values defined within the **--- REQUIRED FIELDS ---** section, and then to submit those values using the `agent_submit_data` tool.
2
+
3
+ --- CRITERIA ---
4
+ <%= criteria %>
5
+ --- END OF CRITERIA ---
6
+
7
+ Please analyze the following submission data according to the rules defined in the **--- CRITERIA ---** section.
8
+
9
+ --- SUBMISSION ---
10
+ <%= values %>
11
+ --- END OF SUBMISSION ---
12
+
13
+ Now, provide values for the following **--- REQUIRED FIELDS ---** by analyzing the **--- SUBMISSION ---** data according to the rules specified within the **--- CRITERIA ---** section.
14
+
15
+ --- REQUIRED FIELDS ---
16
+ <%= fields %>
17
+ --- END OF REQUIRED FIELDS ---
18
+
19
+ Once you have created values for the **--- REQUIRED FIELDS ---**, use the `submission_update` tool to update the submission with these values.
@@ -2,4 +2,5 @@
2
2
  - **<%= field.label %>**
3
3
  - data_path: "<%= field.path %>"
4
4
  - field_type: <%= field.type %><% if (field.description) { %>
5
- - Description: <%= field.description %><% } %><% }); %>
5
+ - Description: <%= field.description %><% } %><% if (field.rule) { %>
6
+ - Value Rule: "<%= field.rule %>"<% } %><% }); %>
@@ -0,0 +1,4 @@
1
+ <% data.forEach(function(item) { %><%= item.prefix %>
2
+ Question: **<%= item.label %>**:
3
+ - Answer: `<%= item.value %>`
4
+ <% }); %>
@@ -3,7 +3,7 @@ Successfully updated the record in <%= form.title %>!
3
3
  - created: <%= created %>
4
4
  - modified: <%= modified %>
5
5
 
6
- **Updated Fields (<%= totalFieldsUpdated %> total):** (It is VERY important to show the values to the user exactly as they were submitted/posted)
6
+ **Updated Fields (<%= totalFieldsUpdated %> total):**
7
7
  <% updateSummary.forEach(function(update) { %>
8
8
  - **<%= update.data_path %>:**
9
9
  - Previous: "<%= update.previous_value %>"
@@ -0,0 +1,11 @@
1
+ <% if (error === 'no_uag') { %>
2
+ There are no `uag` fields present within the provided form. In order to use the `agent_provide_data` tool, you must first flag certain fields as the **Criteria** and **Agent Fields**.
3
+ - **Criteria**: A content component with properties `uag="<%= persona %>"` and `uagField="criteria"`. Within the content of this component, provide detailed instructions (criteria) for the agent to follow when analyzing the data.
4
+ - **Agent Fields**: Any fields you wish the agent to populate with its own data, you must flag those fields with the property `uag="<%= persona %>"`. These fields will then be handed to the AI Agent as required fields for them to populate according to the provided **Criteria**.
5
+ <% } %>
6
+ <% if (error === 'no_criteria') { %>
7
+ No `criteria` field was found within this form with the properties `uag="<%= persona %>"` and `uagField="criteria"`. To add `criteria`, add a Content component to the form and then give it the following properties: `uag="<%= persona %>"` and `uagField="criteria"`. Within the content of this component, provide detailed instructions (the criteria) for the agent to follow when analyzing the data.
8
+ <% } %>
9
+ <% if (error === 'no_fields') { %>
10
+ There are no `uag` fields within this form under the provided `persona=<%= persona %>` that are available for the AI Agent to provide values for. To flag a field as fillable by the AI Agent, you must add the property and value `uag="<%= persona %>"`
11
+ <% } %>
@@ -108,6 +108,11 @@ export declare class SchemaBuilder {
108
108
  * @returns
109
109
  */
110
110
  parent_path(): this;
111
+ /**
112
+ * The agent persona "type" to use when processing the existing submission data. The persona provides context to the agent on how to interpret and understand the data within the form submission. If not provided, the default persona defined within the form's UAG settings will be used.
113
+ * @returns
114
+ */
115
+ persona(): this;
111
116
  /**
112
117
  * An array of field updates to apply to the `form_data`.
113
118
  * Each update specifies the `data_path` and the complete new value.
@@ -153,6 +153,14 @@ class SchemaBuilder {
153
153
  this.schema.parent_path = zod_1.default.string().optional().describe('The `data_path` of the parent component that contains nested components. Use this parameter if collecting data for fields within a specific nested component within a form. To find the `parent_path`, you can use the `get_field_info` tool, and use the `data_path` of any component that ****Has Nested Components**** = ✅ Yes. If not provided, the tool assumes data is being collected for the root form.');
154
154
  return this;
155
155
  }
156
+ /**
157
+ * The agent persona "type" to use when processing the existing submission data. The persona provides context to the agent on how to interpret and understand the data within the form submission. If not provided, the default persona defined within the form's UAG settings will be used.
158
+ * @returns
159
+ */
160
+ persona() {
161
+ this.schema.persona = zod_1.default.string().optional().describe('The agent persona "type" to use when processing the existing submission data. The persona provides context to the agent on how to interpret and understand the data within the form submission. If not provided, the default persona defined within the form\'s UAG settings will be used.');
162
+ return this;
163
+ }
156
164
  /**
157
165
  * An array of field updates to apply to the `form_data`.
158
166
  * Each update specifies the `data_path` and the complete new value.
@@ -0,0 +1,3 @@
1
+ import { UAGProjectInterface } from "../UAGProjectInterface";
2
+ import { ToolInfo } from "./utils";
3
+ export declare const agentProvideData: (project: UAGProjectInterface) => Promise<ToolInfo>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentProvideData = void 0;
4
+ const template_1 = require("../template");
5
+ const lodash_1 = require("lodash");
6
+ const SchemaBuilder_1 = require("./SchemaBuilder");
7
+ const agentProvideData = async (project) => {
8
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.agent_provide_data || {}, {
9
+ name: 'agent_provide_data',
10
+ title: 'Agent Provide Data',
11
+ description: 'Provides a mechanism for agents to process existing submission data, understand it, and then to provide additional data values provided a criteria and form context.',
12
+ inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
13
+ .form_name()
14
+ .submission_id()
15
+ .persona().schema,
16
+ execute: async ({ form_name, submission_id, persona }, extra) => {
17
+ const form = await project.getForm(form_name);
18
+ if (!form) {
19
+ return project.mcpResponse(template_1.ResponseTemplate.formNotFound, { formName: form_name }, true);
20
+ }
21
+ const uag = persona ? form.uagFields[persona] : Object.values(form.uagFields)[0];
22
+ if (!uag) {
23
+ return project.mcpResponse(template_1.ResponseTemplate.uagComponentNotFound, {
24
+ persona: persona || 'default',
25
+ error: 'no_uag'
26
+ }, true);
27
+ }
28
+ const submission = await form.loadSubmission(submission_id, extra.authInfo);
29
+ if (!submission) {
30
+ return project.mcpResponse(template_1.ResponseTemplate.submissionNotFound, {
31
+ form: form.form,
32
+ submissionId: submission_id
33
+ }, true);
34
+ }
35
+ if (!uag.criteria) {
36
+ return project.mcpResponse(template_1.ResponseTemplate.uagComponentNotFound, {
37
+ persona: persona || 'default',
38
+ error: 'no_criteria'
39
+ }, true);
40
+ }
41
+ const agentFields = Object.values(uag.components);
42
+ if (agentFields.length === 0) {
43
+ return project.mcpResponse(template_1.ResponseTemplate.uagComponentNotFound, {
44
+ persona: persona || 'default',
45
+ error: 'no_fields'
46
+ }, true);
47
+ }
48
+ // Collect more required fields.
49
+ return project.mcpResponse(template_1.ResponseTemplate.agentProcessData, {
50
+ persona: persona || 'default',
51
+ criteria: uag.criteria,
52
+ values: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.fieldValues, {
53
+ data: form.formatData(submission.data)
54
+ }),
55
+ fields: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.fieldList, { fields: agentFields })
56
+ });
57
+ }
58
+ });
59
+ };
60
+ exports.agentProvideData = agentProvideData;
@@ -31,6 +31,7 @@ const findSubmission_1 = require("./findSubmission");
31
31
  Object.defineProperty(exports, "findSubmission", { enumerable: true, get: function () { return findSubmission_1.findSubmission; } });
32
32
  const submissionUpdate_1 = require("./submissionUpdate");
33
33
  Object.defineProperty(exports, "submissionUpdate", { enumerable: true, get: function () { return submissionUpdate_1.submissionUpdate; } });
34
+ const agentProvideData_1 = require("./agentProvideData");
34
35
  __exportStar(require("./utils"), exports);
35
36
  const getTools = async (project) => {
36
37
  return [
@@ -41,7 +42,8 @@ const getTools = async (project) => {
41
42
  await (0, confirmSubmission_1.confirmSubmission)(project),
42
43
  await (0, submitForm_1.submitCompletedForm)(project),
43
44
  await (0, findSubmission_1.findSubmission)(project),
44
- await (0, submissionUpdate_1.submissionUpdate)(project)
45
+ await (0, submissionUpdate_1.submissionUpdate)(project),
46
+ await (0, agentProvideData_1.agentProvideData)(project)
45
47
  ];
46
48
  };
47
49
  exports.getTools = getTools;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/uag",
3
- "version": "1.9.0-rc.2",
3
+ "version": "1.9.0-rc.4",
4
4
  "description": "The Form.io Universal Agent Gateway (UAG).",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -15,7 +15,7 @@
15
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 --platform=linux/amd64 .",
18
+ "build:docker": "npm run build && docker build -t formio/uag:rc --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,17 +23,18 @@
23
23
  "author": "",
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@formio/appserver": "^2.9.0",
26
+ "@formio/appserver": "^2.11.0",
27
27
  "@formio/core": "2.5.1-dev.291.6557e4e",
28
- "@modelcontextprotocol/sdk": "^1.25.2",
29
- "cors": "^2.8.5",
28
+ "@modelcontextprotocol/sdk": "^1.25.3",
29
+ "cors": "^2.8.6",
30
30
  "debug": "^4.4.1",
31
31
  "dotenv": "^17.2.1",
32
32
  "express": "^5.2.1",
33
33
  "jsonwebtoken": "^9.0.2",
34
- "lodash": "^4.17.21",
34
+ "lodash": "^4.17.23",
35
35
  "node-cache": "^5.1.2",
36
- "zod": "^4.3.5"
36
+ "node-html-markdown": "^2.0.0",
37
+ "zod": "^4.3.6"
37
38
  },
38
39
  "devDependencies": {
39
40
  "@types/chai": "^5.2.3",
@@ -44,12 +45,12 @@
44
45
  "@types/jsonwebtoken": "^9.0.10",
45
46
  "@types/lodash": "^4.17.23",
46
47
  "@types/mocha": "^10.0.10",
47
- "@types/node": "^25.0.6",
48
+ "@types/node": "^25.1.0",
48
49
  "@types/supertest": "^6.0.3",
49
50
  "chai": "^6.2.2",
50
51
  "mocha": "^11.7.5",
51
52
  "supertest": "^7.2.2",
52
- "terser": "^5.44.1",
53
+ "terser": "^5.46.0",
53
54
  "ts-node": "^10.9.2",
54
55
  "tsx": "^4.21.0",
55
56
  "typescript": "^5.9.3"