(
formTree: FieldTree<unknown>,
options: {name: string; description: string},
injector: Injector,
)
| 36 | }; |
| 37 | |
| 38 | async function initWebMcpForm( |
| 39 | formTree: FieldTree<unknown>, |
| 40 | options: {name: string; description: string}, |
| 41 | injector: Injector, |
| 42 | ) { |
| 43 | const node = formTree() as FieldNode; |
| 44 | const inputSchema = inferSchemaFromFieldNode(node); |
| 45 | |
| 46 | if (!inputSchema) { |
| 47 | throw new Error( |
| 48 | `Could not accurately infer WebMCP schema for form "${options.name}". ` + |
| 49 | `Ensure that the form model does not contain null, undefined, empty arrays, or unsupported types.`, |
| 50 | ); |
| 51 | } |
| 52 | |
| 53 | await declareExperimentalWebMcpTool( |
| 54 | { |
| 55 | name: options.name, |
| 56 | description: options.description, |
| 57 | inputSchema, |
| 58 | execute: async (args: Record<string, unknown>) => { |
| 59 | // Populate the form with changes from the agent. |
| 60 | node.value.set(args); |
| 61 | |
| 62 | // Trigger form submission. |
| 63 | const success = await submit(formTree); |
| 64 | |
| 65 | // Report the result to the agent. |
| 66 | if (success) { |
| 67 | return {content: [{type: 'text', text: 'Form submitted successfully.'}]}; |
| 68 | } else { |
| 69 | const errorMessages = node |
| 70 | .errorSummary() |
| 71 | .map((err) => { |
| 72 | const fieldName = (err.fieldTree() as FieldNode).structure.pathKeys().join('.'); |
| 73 | return `${fieldName ? `${fieldName}: ` : ''}${err.message || err.kind}`; |
| 74 | }) |
| 75 | .join('\n'); |
| 76 | return {content: [{type: 'text', text: `Form submission failed:\n${errorMessages}`}]}; |
| 77 | } |
| 78 | }, |
| 79 | }, |
| 80 | injector, |
| 81 | ); |
| 82 | } |
| 83 | |
| 84 | /** Infers the JSON schema from a specific form field. */ |
| 85 | function inferSchemaFromFieldNode(node: FieldNode): JsonSchemaForInference | undefined { |
no test coverage detected