@formio/uag 1.3.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.
Files changed (64) hide show
  1. package/LICENSE.txt +19 -0
  2. package/README.md +336 -0
  3. package/lib/UAGFormInterface.d.ts +113 -0
  4. package/lib/UAGFormInterface.js +371 -0
  5. package/lib/UAGProjectInterface.d.ts +26 -0
  6. package/lib/UAGProjectInterface.js +96 -0
  7. package/lib/config.d.ts +54 -0
  8. package/lib/config.js +2 -0
  9. package/lib/index.d.ts +16 -0
  10. package/lib/index.js +43 -0
  11. package/lib/router.d.ts +3 -0
  12. package/lib/router.js +74 -0
  13. package/lib/template.d.ts +54 -0
  14. package/lib/template.js +120 -0
  15. package/lib/templates/allFieldsCollected.md +17 -0
  16. package/lib/templates/collectedData.md +5 -0
  17. package/lib/templates/confirmFormSubmission.md +18 -0
  18. package/lib/templates/fieldCollectedNext.md +14 -0
  19. package/lib/templates/fieldList.md +5 -0
  20. package/lib/templates/fieldRules.md +4 -0
  21. package/lib/templates/fieldValidationErrors.md +7 -0
  22. package/lib/templates/fields.md +19 -0
  23. package/lib/templates/formNotFound.md +1 -0
  24. package/lib/templates/formSubmitted.md +7 -0
  25. package/lib/templates/getAvailableForms.md +18 -0
  26. package/lib/templates/getFormFields.md +16 -0
  27. package/lib/templates/getFormFieldsEmpty.md +4 -0
  28. package/lib/templates/getFormFieldsError.md +7 -0
  29. package/lib/templates/getFormFieldsInfo.md +6 -0
  30. package/lib/templates/getOptionalFields.md +19 -0
  31. package/lib/templates/noFormsAvailable.md +3 -0
  32. package/lib/templates/noSubmissionsFound.md +11 -0
  33. package/lib/templates/submissionNotFound.md +6 -0
  34. package/lib/templates/submissionPartialIdAmbiguous.md +12 -0
  35. package/lib/templates/submissionPartialIdNotFound.md +12 -0
  36. package/lib/templates/submissionSearchError.md +8 -0
  37. package/lib/templates/submissionUpdateError.md +6 -0
  38. package/lib/templates/submissionUpdated.md +15 -0
  39. package/lib/templates/submissionsFound.md +25 -0
  40. package/lib/templates/submitValidationError.md +7 -0
  41. package/lib/templates/submittedData.md +4 -0
  42. package/lib/tools/SchemaBuilder.d.ts +136 -0
  43. package/lib/tools/SchemaBuilder.js +192 -0
  44. package/lib/tools/collectData.d.ts +3 -0
  45. package/lib/tools/collectData.js +72 -0
  46. package/lib/tools/confirmSubmission.d.ts +3 -0
  47. package/lib/tools/confirmSubmission.js +56 -0
  48. package/lib/tools/findSubmission.d.ts +3 -0
  49. package/lib/tools/findSubmission.js +165 -0
  50. package/lib/tools/getFieldInfo.d.ts +3 -0
  51. package/lib/tools/getFieldInfo.js +41 -0
  52. package/lib/tools/getFormFields.d.ts +3 -0
  53. package/lib/tools/getFormFields.js +99 -0
  54. package/lib/tools/getForms.d.ts +3 -0
  55. package/lib/tools/getForms.js +38 -0
  56. package/lib/tools/index.d.ts +13 -0
  57. package/lib/tools/index.js +47 -0
  58. package/lib/tools/submissionUpdate.d.ts +3 -0
  59. package/lib/tools/submissionUpdate.js +79 -0
  60. package/lib/tools/submitForm.d.ts +3 -0
  61. package/lib/tools/submitForm.js +62 -0
  62. package/lib/tools/utils.d.ts +28 -0
  63. package/lib/tools/utils.js +27 -0
  64. package/package.json +57 -0
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFieldInfo = void 0;
4
+ const template_1 = require("../template");
5
+ const lodash_1 = require("lodash");
6
+ const SchemaBuilder_1 = require("./SchemaBuilder");
7
+ const error = require('debug')('formio:uag:getFieldInfo:error');
8
+ const getFieldInfo = async (project) => {
9
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.get_field_info || {}, {
10
+ name: 'get_field_info',
11
+ title: 'Get Field(s) Info',
12
+ description: 'Get detailed information about a specific field(s) that have been provided from the user. It is used to understand the properties, validation rules, and options of the specific field(s) the user has provided values for. This purpose of this tool is to provide detailed information for any field(s) (provided using the `field_paths` parameter) to help understand the structure and requirements of a form. PREREQUISITE: This tool should be called after the `get_form_fields` tool has been called AND once the user has provided some values for the provided fields.',
13
+ inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
14
+ .form_name()
15
+ .field_paths().schema,
16
+ execute: async ({ form_name, field_paths }, 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
+ try {
22
+ // Get the fields at the specified data path (or root if not provided).
23
+ const fields = await form.getFields({ data: {} }, extra.authInfo, field_paths);
24
+ // Show the form fields based on the criteria.
25
+ return project.mcpResponse(template_1.ResponseTemplate.getFormFieldsInfo, {
26
+ fields: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.fields, {
27
+ fields: fields.required.components.concat(fields.optional.components)
28
+ }),
29
+ });
30
+ }
31
+ catch (err) {
32
+ error('Error extracting form fields:', err);
33
+ return project.mcpResponse(template_1.ResponseTemplate.getFormFieldsError, {
34
+ form: form.form,
35
+ error: err instanceof Error ? err.message : 'Unknown error'
36
+ }, true);
37
+ }
38
+ }
39
+ });
40
+ };
41
+ exports.getFieldInfo = getFieldInfo;
@@ -0,0 +1,3 @@
1
+ import { UAGProjectInterface } from "../UAGProjectInterface";
2
+ import { ToolInfo } from "./utils";
3
+ export declare const getFormFields: (project: UAGProjectInterface) => Promise<ToolInfo>;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFormFields = void 0;
4
+ const template_1 = require("../template");
5
+ const utils_1 = require("./utils");
6
+ const lodash_1 = require("lodash");
7
+ const SchemaBuilder_1 = require("./SchemaBuilder");
8
+ const error = require('debug')('formio:uag:getFormFields:error');
9
+ const getFormFields = async (project) => {
10
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.get_form_fields || {}, {
11
+ name: 'get_form_fields',
12
+ title: 'Get Form Fields',
13
+ description: 'Get high level overview of the fields that are present in a form, and to understand the "rules" on how the data for each field type should be collected. The purpose of this tool is to determine what fields the user is requesting (and to understand how to format that values for that data), and use that to create a list of field data_path\'s that the user is providing context for. This list can then be provided to the `get_field_info` tool to determine the specific field level information for those fields (validation, required, collection rules, etc). PREREQUISITE: You must call the `get_forms` tool first to understand what forms are available to submit and the permissions associated with those forms.',
14
+ inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
15
+ .form_name()
16
+ .form_data()
17
+ .criteria()
18
+ .parent().schema,
19
+ execute: async ({ form_name, form_data, criteria, parent }, extra) => {
20
+ const form = await project.getForm(form_name);
21
+ if (!form) {
22
+ return project.mcpResponse(template_1.ResponseTemplate.formNotFound, { formName: form_name }, true);
23
+ }
24
+ try {
25
+ // Ensure the parent is null if the type or data_path is missing.
26
+ if (!parent?.data_path || !parent.type) {
27
+ parent = undefined;
28
+ }
29
+ // Get the submission data.
30
+ const submission = form.convertToSubmission(form_data);
31
+ // Get the fields at the specified data path (or root if not provided).
32
+ const fields = await form.getFields(submission, extra.authInfo, parent?.data_path);
33
+ // If the agent requests optional fields, but there are still requird fields to fill out, then force required
34
+ // and inform the agent of this change.
35
+ let message = '';
36
+ if (criteria == 'optional' && fields.required.components.length > 0) {
37
+ criteria = 'required';
38
+ message = 'You requested "optional" fields, but the user is not finished collecting required information. Please finish collecting the following required fields first.\n\n';
39
+ }
40
+ // Determine which fields to show based on the criteria.
41
+ const criteriaFields = criteria === 'all' ?
42
+ [...fields.required.components, ...fields.optional.components] :
43
+ criteria === 'required' ? fields.required.components : fields.optional.components;
44
+ if (criteriaFields.length === 0) {
45
+ return project.mcpResponse(template_1.ResponseTemplate.getFormFieldsEmpty, {
46
+ parent,
47
+ parentLabel: (0, utils_1.getParentLabel)(parent),
48
+ type: (0, lodash_1.upperFirst)(criteria),
49
+ form: form.form,
50
+ });
51
+ }
52
+ // Determine the rules based on the criteria.
53
+ const criteriaRules = criteria === 'all' ?
54
+ { ...fields.required.rules, ...fields.optional.rules } :
55
+ criteria === 'required' ? fields.required.rules : fields.optional.rules;
56
+ let totalType = fields.total;
57
+ if (criteria === 'required') {
58
+ totalType = fields.totalRequired;
59
+ }
60
+ else if (criteria === 'optional') {
61
+ totalType = fields.total - fields.totalRequired;
62
+ }
63
+ const totalCollected = Object.keys(form_data || {}).length;
64
+ let totalTypeCollected = 0;
65
+ if (criteria === 'required') {
66
+ totalTypeCollected = fields.totalRequiredCollected;
67
+ }
68
+ else if (criteria === 'optional') {
69
+ totalTypeCollected = totalCollected - fields.totalRequiredCollected;
70
+ }
71
+ else {
72
+ totalTypeCollected = totalCollected;
73
+ }
74
+ // Show the form fields based on the criteria.
75
+ return project.mcpResponse(template_1.ResponseTemplate.getFormFields, {
76
+ message,
77
+ parent,
78
+ parentLabel: (0, utils_1.getParentLabel)(parent, form.form),
79
+ parentDataPath: (0, utils_1.getParentDataPath)(parent, fields.rowIndex),
80
+ type: (0, lodash_1.upperFirst)(criteria),
81
+ rules: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.fieldRules, { rules: Object.entries(criteriaRules) }),
82
+ fieldList: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.fieldList, { fields: criteriaFields }),
83
+ totalFields: fields.total,
84
+ totalType,
85
+ totalCollected,
86
+ totalTypeCollected
87
+ });
88
+ }
89
+ catch (err) {
90
+ error('Error extracting form fields:', err);
91
+ return project.mcpResponse(template_1.ResponseTemplate.getFormFieldsError, {
92
+ form: form.form,
93
+ error: err instanceof Error ? err.message : 'Unknown error'
94
+ }, true);
95
+ }
96
+ }
97
+ });
98
+ };
99
+ exports.getFormFields = getFormFields;
@@ -0,0 +1,3 @@
1
+ import { UAGProjectInterface } from "../UAGProjectInterface";
2
+ import { ToolInfo } from "./utils";
3
+ export declare const getForms: (project: UAGProjectInterface) => Promise<ToolInfo>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getForms = void 0;
4
+ const lodash_1 = require("lodash");
5
+ const template_1 = require("../template");
6
+ const getForms = async (project) => {
7
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.get_forms || {}, {
8
+ name: 'get_forms',
9
+ title: 'Get Available Forms',
10
+ description: 'Get a list of all available forms with their descriptions. Use this tool when a user expresses intent to add, create, submit, fill out, register for something (e.g., "I want to add a new Contact", "I need to submit a User Registration", "I met a contact who was the CMO", "What was the email of the contact"). This tool can also be used when they ask what forms are available.',
11
+ inputSchema: {},
12
+ execute: async ({}, extra) => {
13
+ const forms = Object.values(project.forms).filter(form => form.uag);
14
+ if (forms.length === 0) {
15
+ return project.mcpResponse(template_1.ResponseTemplate.noFormsAvailable, {
16
+ message: 'No forms are currently available in this project.'
17
+ });
18
+ }
19
+ // Check the forms to ensure the user can submit them.
20
+ return project.mcpResponse(template_1.ResponseTemplate.getAvailableForms, {
21
+ forms: forms.map(form => {
22
+ const perms = extra.authInfo.formPermissions(form);
23
+ const hasAccess = perms.create || perms.update || perms.read;
24
+ const uagForm = form.uag;
25
+ return {
26
+ name: uagForm?.name,
27
+ title: uagForm?.title,
28
+ description: uagForm?.description || `Form for ${uagForm?.title} data entry`,
29
+ permissions: perms,
30
+ hasAccess
31
+ };
32
+ }),
33
+ totalForms: forms.length
34
+ });
35
+ }
36
+ });
37
+ };
38
+ exports.getForms = getForms;
@@ -0,0 +1,13 @@
1
+ import { getForms } from "./getForms";
2
+ import { getFormFields } from "./getFormFields";
3
+ import { getFieldInfo } from "./getFieldInfo";
4
+ import { collectData } from "./collectData";
5
+ import { confirmSubmission } from "./confirmSubmission";
6
+ import { submitCompletedForm } from "./submitForm";
7
+ import { findSubmission } from "./findSubmission";
8
+ import { submissionUpdate } from "./submissionUpdate";
9
+ import { ToolInfo } from "./utils";
10
+ import { UAGProjectInterface } from "../UAGProjectInterface";
11
+ export * from './utils';
12
+ export { getForms, getFormFields, getFieldInfo, collectData, confirmSubmission, submitCompletedForm, findSubmission, submissionUpdate };
13
+ export declare const getTools: (project: UAGProjectInterface) => Promise<ToolInfo[]>;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getTools = exports.submissionUpdate = exports.findSubmission = exports.submitCompletedForm = exports.confirmSubmission = exports.collectData = exports.getFieldInfo = exports.getFormFields = exports.getForms = void 0;
18
+ const getForms_1 = require("./getForms");
19
+ Object.defineProperty(exports, "getForms", { enumerable: true, get: function () { return getForms_1.getForms; } });
20
+ const getFormFields_1 = require("./getFormFields");
21
+ Object.defineProperty(exports, "getFormFields", { enumerable: true, get: function () { return getFormFields_1.getFormFields; } });
22
+ const getFieldInfo_1 = require("./getFieldInfo");
23
+ Object.defineProperty(exports, "getFieldInfo", { enumerable: true, get: function () { return getFieldInfo_1.getFieldInfo; } });
24
+ const collectData_1 = require("./collectData");
25
+ Object.defineProperty(exports, "collectData", { enumerable: true, get: function () { return collectData_1.collectData; } });
26
+ const confirmSubmission_1 = require("./confirmSubmission");
27
+ Object.defineProperty(exports, "confirmSubmission", { enumerable: true, get: function () { return confirmSubmission_1.confirmSubmission; } });
28
+ const submitForm_1 = require("./submitForm");
29
+ Object.defineProperty(exports, "submitCompletedForm", { enumerable: true, get: function () { return submitForm_1.submitCompletedForm; } });
30
+ const findSubmission_1 = require("./findSubmission");
31
+ Object.defineProperty(exports, "findSubmission", { enumerable: true, get: function () { return findSubmission_1.findSubmission; } });
32
+ const submissionUpdate_1 = require("./submissionUpdate");
33
+ Object.defineProperty(exports, "submissionUpdate", { enumerable: true, get: function () { return submissionUpdate_1.submissionUpdate; } });
34
+ __exportStar(require("./utils"), exports);
35
+ const getTools = async (project) => {
36
+ return [
37
+ await (0, getForms_1.getForms)(project),
38
+ await (0, getFormFields_1.getFormFields)(project),
39
+ await (0, getFieldInfo_1.getFieldInfo)(project),
40
+ await (0, collectData_1.collectData)(project),
41
+ await (0, confirmSubmission_1.confirmSubmission)(project),
42
+ await (0, submitForm_1.submitCompletedForm)(project),
43
+ await (0, findSubmission_1.findSubmission)(project),
44
+ await (0, submissionUpdate_1.submissionUpdate)(project)
45
+ ];
46
+ };
47
+ exports.getTools = getTools;
@@ -0,0 +1,3 @@
1
+ import { UAGProjectInterface } from "../UAGProjectInterface";
2
+ import { ToolInfo } from "./utils";
3
+ export declare const submissionUpdate: (project: UAGProjectInterface) => Promise<ToolInfo>;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.submissionUpdate = void 0;
4
+ const template_1 = require("../template");
5
+ const lodash_1 = require("lodash");
6
+ const SchemaBuilder_1 = require("./SchemaBuilder");
7
+ const error = require('debug')('formio:uag:submissionUpdate:error');
8
+ const submissionUpdate = async (project) => {
9
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.submission_update || {}, {
10
+ name: 'submission_update',
11
+ title: 'Submission Update',
12
+ description: 'Apply multiple planned field updates to a selected submission after the user confirmed they wish to update the record.',
13
+ inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
14
+ .form_name()
15
+ .submission_id()
16
+ .updates().schema,
17
+ execute: async ({ form_name, submission_id, updates }, extra) => {
18
+ const form = await project.getForm(form_name);
19
+ if (!form) {
20
+ return project.mcpResponse(template_1.ResponseTemplate.formNotFound, { formName: form_name }, true);
21
+ }
22
+ try {
23
+ // Get the current submission
24
+ const currentSubmission = await form.loadSubmission(submission_id, extra.authInfo);
25
+ if (!currentSubmission) {
26
+ return project.mcpResponse(template_1.ResponseTemplate.submissionNotFound, {
27
+ form: form.form,
28
+ submissionId: submission_id
29
+ }, true);
30
+ }
31
+ // Apply all field updates and track changes
32
+ const updatedData = { ...currentSubmission.data };
33
+ const updateSummary = [];
34
+ for (const update of updates) {
35
+ const previousValue = (0, lodash_1.get)(updatedData, update.data_path);
36
+ (0, lodash_1.set)(updatedData, update.data_path, update.new_value);
37
+ updateSummary.push({
38
+ data_path: update.data_path,
39
+ new_value: update.new_value,
40
+ previous_value: previousValue || ''
41
+ });
42
+ }
43
+ // Update the submission via API with all changes
44
+ const submission = await form.submit({
45
+ ...currentSubmission,
46
+ data: updatedData
47
+ }, extra.authInfo);
48
+ if (!submission) {
49
+ return project.mcpResponse(template_1.ResponseTemplate.submissionUpdateError, {
50
+ form: form.form,
51
+ submissionId: submission_id,
52
+ error: 'Unknown error during update'
53
+ }, true);
54
+ }
55
+ // Format the updated submission for display
56
+ return project.mcpResponse(template_1.ResponseTemplate.submissionUpdated, {
57
+ form: form.form,
58
+ submissionId: submission_id,
59
+ created: submission.created,
60
+ modified: submission.modified,
61
+ updateSummary: updateSummary,
62
+ totalFieldsUpdated: updateSummary.length,
63
+ dataSummary: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.collectedData, {
64
+ data: form.formatData(submission.data)
65
+ }),
66
+ });
67
+ }
68
+ catch (err) {
69
+ error('Error updating submission:', err);
70
+ return project.mcpResponse(template_1.ResponseTemplate.submissionUpdateError, {
71
+ form: form.form,
72
+ submissionId: submission_id,
73
+ error: err instanceof Error ? err.message : 'Unknown error'
74
+ }, true);
75
+ }
76
+ }
77
+ });
78
+ };
79
+ exports.submissionUpdate = submissionUpdate;
@@ -0,0 +1,3 @@
1
+ import { ToolInfo } from "./utils";
2
+ import { UAGProjectInterface } from "../UAGProjectInterface";
3
+ export declare const submitCompletedForm: (project: UAGProjectInterface) => Promise<ToolInfo>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.submitCompletedForm = void 0;
4
+ const template_1 = require("../template");
5
+ const lodash_1 = require("lodash");
6
+ const SchemaBuilder_1 = require("./SchemaBuilder");
7
+ const debug = require('debug')('formio:uag:submitForm');
8
+ const submitCompletedForm = async (project) => {
9
+ return (0, lodash_1.defaultsDeep)(project.config?.toolOverrides?.submit_completed_form || {}, {
10
+ name: 'submit_completed_form',
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.)',
13
+ inputSchema: (new SchemaBuilder_1.SchemaBuilder(project))
14
+ .form_name()
15
+ .form_data().schema,
16
+ execute: async ({ form_name, form_data }, 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
+ try {
22
+ let submission = form.convertToSubmission(form_data);
23
+ const submitted = await form.submit(submission, extra.authInfo);
24
+ if (submitted)
25
+ submission = submitted;
26
+ if (!submission) {
27
+ return project.mcpResponse(template_1.ResponseTemplate.submitValidationError, {
28
+ validationErrors: ['Unknown error during submission']
29
+ }, true);
30
+ }
31
+ debug(`Form submitted: ${form_name} with submission ID: ${submission._id}`);
32
+ return project.mcpResponse(template_1.ResponseTemplate.formSubmitted, {
33
+ form: form.form,
34
+ data: submission.data,
35
+ submissionId: submission._id,
36
+ submittedFieldsCount: Object.keys(form_data).length,
37
+ dataSummary: project.uagTemplate?.renderTemplate(template_1.ResponseTemplate.collectedData, {
38
+ data: form.formatData(submission.data)
39
+ }),
40
+ });
41
+ }
42
+ catch (err) {
43
+ const errors = [];
44
+ if (err && err.name === 'ValidationError' && err.details) {
45
+ for (const detail of err.details) {
46
+ if (detail.message) {
47
+ errors.push({
48
+ label: detail.context?.label || 'Field',
49
+ path: detail.context?.path,
50
+ message: detail.message
51
+ });
52
+ }
53
+ }
54
+ }
55
+ return project.mcpResponse(template_1.ResponseTemplate.submitValidationError, {
56
+ validationErrors: errors.length ? errors : [{ message: err.message || 'Unknown error during submission' }]
57
+ }, true);
58
+ }
59
+ }
60
+ });
61
+ };
62
+ exports.submitCompletedForm = submitCompletedForm;
@@ -0,0 +1,28 @@
1
+ import { ZodRawShape } from "zod";
2
+ import { Form } from '@formio/core';
3
+ export type ToolInfo = {
4
+ name?: string;
5
+ title?: string;
6
+ description?: string;
7
+ inputSchema?: ZodRawShape | undefined;
8
+ execute?: any;
9
+ };
10
+ export type ParentInfo = {
11
+ type: string;
12
+ label?: string;
13
+ data_path?: string;
14
+ isForm?: boolean;
15
+ isTable?: boolean;
16
+ isContainer?: boolean;
17
+ };
18
+ export type DataUpdate = {
19
+ data_path: string;
20
+ new_value: any;
21
+ };
22
+ export type SearchQuery = {
23
+ data_path: string;
24
+ search_value: string;
25
+ operator: string;
26
+ };
27
+ export declare function getParentLabel(parent?: ParentInfo, form?: Form): string;
28
+ export declare function getParentDataPath(parent?: ParentInfo, rowIndex?: number): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getParentLabel = getParentLabel;
4
+ exports.getParentDataPath = getParentDataPath;
5
+ function getParentLabel(parent, form) {
6
+ let parentLabel = form ? `the **${form.title} (${form.name})** form` : 'this form';
7
+ if (parent?.isTable) {
8
+ parentLabel = `this row within the **${parent.label}** component`;
9
+ }
10
+ else if (parent?.isForm) {
11
+ parentLabel = `the **${parent.label}** nested form`;
12
+ }
13
+ else if (parent?.isContainer) {
14
+ parentLabel = `the **${parent.label}** container component`;
15
+ }
16
+ return parentLabel;
17
+ }
18
+ function getParentDataPath(parent, rowIndex = -1) {
19
+ let parentDataPath = parent?.data_path || '';
20
+ if (parentDataPath && (rowIndex >= 0)) {
21
+ parentDataPath += `[${rowIndex}]`;
22
+ }
23
+ if (parent?.isForm) {
24
+ parentDataPath += '.data';
25
+ }
26
+ return parentDataPath;
27
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@formio/uag",
3
+ "version": "1.3.0",
4
+ "description": "The Form.io Universal Agent Gateway (UAG).",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "engines": {
8
+ "node": ">=22.0.0"
9
+ },
10
+ "files": [
11
+ "lib"
12
+ ],
13
+ "scripts": {
14
+ "clean": "rm -rf lib",
15
+ "build:ts": "tsc",
16
+ "build:copy-templates": "mkdir -p lib/templates && cp src/templates/*.md lib/templates/",
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 .",
19
+ "test": "TS_NODE_PROJECT=tsconfig.test.json mocha --no-node-snapshot",
20
+ "dev": "tsx --no-node-snapshot index.js",
21
+ "start": "node --no-node-snapshot index.js"
22
+ },
23
+ "author": "",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@formio/appserver": "^2.3.1",
27
+ "@formio/core": "2.5.1-dev.291.6557e4e",
28
+ "@modelcontextprotocol/sdk": "^1.21.0",
29
+ "cors": "^2.8.5",
30
+ "debug": "^4.4.1",
31
+ "dotenv": "^17.2.1",
32
+ "express": "^5.1.0",
33
+ "jsonwebtoken": "^9.0.2",
34
+ "lodash": "^4.17.21",
35
+ "node-cache": "^5.1.2",
36
+ "zod": "^3.25.76"
37
+ },
38
+ "devDependencies": {
39
+ "@types/chai": "^5.2.3",
40
+ "@types/cors": "^2.8.19",
41
+ "@types/debug": "^4.1.12",
42
+ "@types/dotenv": "^8.2.3",
43
+ "@types/express": "^5.0.5",
44
+ "@types/jsonwebtoken": "^9.0.10",
45
+ "@types/lodash": "^4.17.20",
46
+ "@types/mocha": "^10.0.10",
47
+ "@types/node": "^24.10.0",
48
+ "@types/supertest": "^6.0.3",
49
+ "chai": "^6.0.1",
50
+ "mocha": "^11.7.4",
51
+ "supertest": "^7.1.4",
52
+ "terser": "^5.43.1",
53
+ "ts-node": "^10.9.2",
54
+ "tsx": "^4.20.4",
55
+ "typescript": "^5.9.3"
56
+ }
57
+ }