diff options
author | A.J. Shulman <Shulman.aj@gmail.com> | 2025-04-10 12:41:42 -0400 |
---|---|---|
committer | A.J. Shulman <Shulman.aj@gmail.com> | 2025-04-10 12:41:42 -0400 |
commit | aa3f1228567102dffe38aa5c9e916dfcb41218fc (patch) | |
tree | cb78edefc2ee0ed7b2592abfcc1118195bce9f55 | |
parent | 6e8f05495dfcf7d64bdc424503f874fece85e291 (diff) |
getting rid of single field edits.
-rw-r--r-- | src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts | 316 |
1 files changed, 122 insertions, 194 deletions
diff --git a/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts b/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts index a3d86287d..eeb9091f8 100644 --- a/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts +++ b/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts @@ -26,22 +26,11 @@ const parameterDefinitions: ReadonlyArray<Parameter> = [ description: 'The ID of the document to get or edit metadata for. Required for "edit", optional for "get", ignored for "list", "getFieldOptions", and "create"', }, { - name: 'fieldName', - type: 'string', - required: false, - description: 'The name of the field to edit. Required for single field edits. Ignored if fieldEdits is provided', - }, - { - name: 'fieldValue', - type: 'string', - required: false, - description: 'The new value for the field. Required for single field edits. Can be a string, number, or boolean value depending on the field type', - }, - { name: 'fieldEdits', type: 'string', required: false, - description: 'JSON array of field edits for editing multiple fields at once. Each item should have fieldName and fieldValue. Example: [{"fieldName":"layout_autoHeight","fieldValue":false},{"fieldName":"height","fieldValue":300}]', + description: + 'JSON array of field edits for editing fields. Each item should have fieldName and fieldValue. For single field edits, use an array with one item. Example: [{"fieldName":"layout_autoHeight","fieldValue":false},{"fieldName":"height","fieldValue":300}]', }, { name: 'title', @@ -101,13 +90,9 @@ IMPORTANT: Some fields have dependencies that must be handled for edits to work - When editing "height", first set "layout_autoHeight" to false (as a boolean value, not a string) - When editing "width", first set "layout_autoWidth" to false (as a boolean value, not a string) - Check document metadata to identify other similar dependencies -- You can edit dependent fields in a single operation using the fieldEdits parameter - -Example: To change document height, first disable auto-height: -1. {... inputs: { action: "edit", documentId: "doc123", fieldName: "layout_autoHeight", fieldValue: false }} -2. {... inputs: { action: "edit", documentId: "doc123", fieldName: "height", fieldValue: 300 }} +- All edits are done using the fieldEdits parameter which accepts an array of fields to modify -OR using multi-field edit (recommended for dependent fields): +Example: To change document height, disable auto-height and set height in a single operation: {... inputs: { action: "edit", documentId: "doc123", fieldEdits: [ { fieldName: "layout_autoHeight", fieldValue: false }, { fieldName: "height", fieldValue: 300 } @@ -135,9 +120,9 @@ To CREATE a new document: - After creation, you can edit the document with more specific properties To EDIT document metadata: -- Use action="edit" with required documentId, and either: - 1. fieldName + fieldValue for single field edits, OR - 2. fieldEdits for updating multiple fields at once +- Use action="edit" with required parameters: + - documentId: The ID of the document to edit + - fieldEdits: JSON array of fields to edit, each with fieldName and fieldValue - The tool will determine the correct document location automatically - Field names can be provided with or without leading underscores (e.g., both "width" and "_width" work) - Common fields like "width" and "height" are automatically mapped to "_width" and "_height" @@ -146,7 +131,7 @@ To EDIT document metadata: SPECIAL FIELD HANDLING: - Text fields: When editing the 'text' field, provide simple plain text - Example: {...inputs: { action: "edit", documentId: "doc123", fieldName: "text", fieldValue: "Hello world" }} + Example: {...inputs: { action: "edit", documentId: "doc123", fieldEdits: [{ fieldName: "text", fieldValue: "Hello world" }] }} The tool will automatically convert your text to the proper RichTextField format - Width/Height: Set layout_autoHeight/layout_autoWidth to false before editing @@ -163,7 +148,7 @@ OR HANDLING DEPENDENT FIELDS: - When editing some fields, you may need to update related dependent fields - For example, when changing "height", you should also set "layout_autoHeight" to false -- Use the fieldEdits parameter to update dependent fields in a single operation (recommended): +- Use the fieldEdits parameter to update dependent fields in a single operation: {...inputs: { action: "edit", documentId: "doc123", fieldEdits: [ { fieldName: "layout_autoHeight", fieldValue: false }, { fieldName: "height", fieldValue: 300 } @@ -189,13 +174,13 @@ Examples: - To list all documents: { action: "list" } - To get all document metadata: { action: "get" } - To get metadata for a specific document: { action: "get", documentId: "doc123" } -- To edit a single field: { action: "edit", documentId: "doc123", fieldName: "backgroundColor", fieldValue: "#ff0000" } -- To edit a width property: { action: "edit", documentId: "doc123", fieldName: "width", fieldValue: 300 } -- To edit text content: { action: "edit", documentId: "doc123", fieldName: "text", fieldValue: "Simple plain text goes here" } -- To disable auto-height: { action: "edit", documentId: "doc123", fieldName: "layout_autoHeight", fieldValue: false } +- To edit a single field: { action: "edit", documentId: "doc123", fieldEdits: [{ fieldName: "backgroundColor", fieldValue: "#ff0000" }] } +- To edit a width property: { action: "edit", documentId: "doc123", fieldEdits: [{ fieldName: "width", fieldValue: 300 }] } +- To edit text content: { action: "edit", documentId: "doc123", fieldEdits: [{ fieldName: "text", fieldValue: "Simple plain text goes here" }] } +- To disable auto-height: { action: "edit", documentId: "doc123", fieldEdits: [{ fieldName: "layout_autoHeight", fieldValue: false }] } - To create a text document: { action: "create", title: "My Notes", data: "This is my note content", doc_type: "text" } - To create a web document: { action: "create", title: "Google", data: "https://www.google.com", doc_type: "web" } -- To edit height with its dependent field together (recommended): +- To edit height with its dependent field together: { action: "edit", documentId: "doc123", fieldEdits: [ { fieldName: "layout_autoHeight", fieldValue: false }, { fieldName: "height", fieldValue: 200 } @@ -1030,137 +1015,92 @@ export class DocumentMetadataTool extends BaseTool<DocumentMetadataToolParamsTyp ]; } - // Check if we're doing a multi-field edit or a single field edit - if (args.fieldEdits) { - try { - // Parse fieldEdits array - const edits = JSON.parse(String(args.fieldEdits)); - if (!Array.isArray(edits) || edits.length === 0) { - return [ - { - type: 'text', - text: 'Error: fieldEdits must be a non-empty array of field edits.', - }, - ]; - } - - // Track results for all edits - const results: { - success: boolean; - message: string; - fieldName?: string; - originalFieldName?: string; - newValue?: any; - warning?: string; - }[] = []; - - let allSuccessful = true; - - // Process each edit - for (const edit of edits) { - // Get fieldValue in its original form - let fieldValue = edit.fieldValue; - - // Only convert to string if it's neither boolean nor number - if (typeof fieldValue !== 'boolean' && typeof fieldValue !== 'number') { - fieldValue = String(fieldValue); - } - - const fieldName = String(edit.fieldName); - - // Edit the field - const result = this.editDocumentField(documentId, fieldName, fieldValue); - - console.log(`DocumentMetadataTool: Edit field result for ${fieldName}:`, result); - - // Add to results - results.push(result); - - // Update success status - if (!result.success) { - allSuccessful = false; - } - } - - // Format response based on results - let responseText = ''; - if (allSuccessful) { - responseText = `Successfully edited ${results.length} fields on document ${documentId}:\n`; - results.forEach(result => { - responseText += `- Field '${result.originalFieldName}': updated to ${JSON.stringify(result.newValue)}\n`; - - // Add any warnings - if (result.warning) { - responseText += ` Warning: ${result.warning}\n`; - } - }); - } else { - responseText = `Errors occurred while editing fields on document ${documentId}:\n`; - results.forEach(result => { - if (result.success) { - responseText += `- Field '${result.originalFieldName}': updated to ${JSON.stringify(result.newValue)}\n`; - - // Add any warnings - if (result.warning) { - responseText += ` Warning: ${result.warning}\n`; - } - } else { - responseText += `- Error editing '${result.originalFieldName}': ${result.message}\n`; - } - }); - } - - // Get the updated metadata to return - const updatedMetadata = this.getDocumentMetadata(documentId); + // Check for fieldEdits parameter + if (!args.fieldEdits) { + return [ + { + type: 'text', + text: 'Error: fieldEdits is required for edit actions. Please provide a JSON array of field edits.', + }, + ]; + } + try { + // Parse fieldEdits array + const edits = JSON.parse(String(args.fieldEdits)); + if (!Array.isArray(edits) || edits.length === 0) { return [ { type: 'text', - text: `${responseText}\nUpdated metadata:\n${JSON.stringify(updatedMetadata, null, 2)}`, - }, - ]; - } catch (error) { - return [ - { - type: 'text', - text: `Error processing fieldEdits: ${error instanceof Error ? error.message : String(error)}`, - }, - ]; - } - } else { - // Single field edit (original behavior) - if (!args.fieldName) { - return [ - { - type: 'text', - text: 'Error: Field name and field value are required for edit actions.', + text: 'Error: fieldEdits must be a non-empty array of field edits.', }, ]; } - // Get fieldValue in its original form - we'll handle conversion in editDocumentField - let fieldValue = args.fieldValue; + // Track results for all edits + const results: { + success: boolean; + message: string; + fieldName?: string; + originalFieldName?: string; + newValue?: any; + warning?: string; + }[] = []; + + let allSuccessful = true; + + // Process each edit + for (const edit of edits) { + // Get fieldValue in its original form + let fieldValue = edit.fieldValue; + + // Only convert to string if it's neither boolean nor number + if (typeof fieldValue !== 'boolean' && typeof fieldValue !== 'number') { + fieldValue = String(fieldValue); + } - // Only convert to string if it's neither boolean nor number - if (typeof fieldValue !== 'boolean' && typeof fieldValue !== 'number') { - fieldValue = String(fieldValue); - } + const fieldName = String(edit.fieldName); - const fieldName = String(args.fieldName); + // Edit the field + const result = this.editDocumentField(documentId, fieldName, fieldValue); - // Edit the field - const result = this.editDocumentField(documentId, fieldName, fieldValue); + console.log(`DocumentMetadataTool: Edit field result for ${fieldName}:`, result); - console.log('DocumentMetadataTool: Edit field result:', result); + // Add to results + results.push(result); - if (!result.success) { - return [{ type: 'text', text: result.message }]; + // Update success status + if (!result.success) { + allSuccessful = false; + } } - // Include warning if present - let responseText = result.message; - if (result.warning) { - responseText += `\n\n${result.warning}`; + // Format response based on results + let responseText = ''; + if (allSuccessful) { + responseText = `Successfully edited ${results.length} fields on document ${documentId}:\n`; + results.forEach(result => { + responseText += `- Field '${result.originalFieldName}': updated to ${JSON.stringify(result.newValue)}\n`; + + // Add any warnings + if (result.warning) { + responseText += ` Warning: ${result.warning}\n`; + } + }); + } else { + responseText = `Errors occurred while editing fields on document ${documentId}:\n`; + results.forEach(result => { + if (result.success) { + responseText += `- Field '${result.originalFieldName}': updated to ${JSON.stringify(result.newValue)}\n`; + + // Add any warnings + if (result.warning) { + responseText += ` Warning: ${result.warning}\n`; + } + } else { + responseText += `- Error editing '${result.originalFieldName}': ${result.message}\n`; + } + }); } // Get the updated metadata to return @@ -1172,6 +1112,13 @@ export class DocumentMetadataTool extends BaseTool<DocumentMetadataToolParamsTyp text: `${responseText}\nUpdated metadata:\n${JSON.stringify(updatedMetadata, null, 2)}`, }, ]; + } catch (error) { + return [ + { + type: 'text', + text: `Error processing fieldEdits: ${error instanceof Error ? error.message : String(error)}`, + }, + ]; } } @@ -1291,9 +1238,9 @@ You can now use the "edit" action to modify additional properties of this docume Next steps: 1. Use the "getFieldOptions" action to understand available editable/addable fields/properties and their dependencies. -2. To modify this document, use: { action: "edit", documentId: "${createdDoc.id}", fieldName: "property", fieldValue: "value" } +2. To modify this document, use: { action: "edit", documentId: "${createdDoc.id}", fieldEdits: [{"fieldName":"property","fieldValue":"value"}] } 3. To add styling, consider setting backgroundColor, fontColor, or other properties -4. For text documents, you can edit the content with: { action: "edit", documentId: "${createdDoc.id}", fieldName: "text", fieldValue: "New content" } +4. For text documents, you can edit the content with: { action: "edit", documentId: "${createdDoc.id}", fieldEdits: [{"fieldName":"text","fieldValue":"New content"}] } Full metadata for the created document: ${JSON.stringify(createdMetadata, null, 2)}`, @@ -1347,43 +1294,39 @@ ${JSON.stringify(createdMetadata, null, 2)}`, return !!(params.title && params.data && params.doc_type); } - // For edit action, validate either single field edit or multiple field edits + // For edit action, validate fieldEdits is provided if (params.action === 'edit') { - // If fieldEdits is provided, it must be valid and we'll ignore fieldName/fieldValue - if (params.fieldEdits) { - try { - // Parse fieldEdits and validate its structure - const edits = JSON.parse(String(params.fieldEdits)); - - // Ensure it's an array - if (!Array.isArray(edits)) { - console.log('fieldEdits is not an array'); - return false; - } + if (!params.documentId || !params.fieldEdits) { + return false; + } - // Ensure each item has fieldName and fieldValue - for (const edit of edits) { - if (!edit.fieldName) { - console.log('An edit is missing fieldName'); - return false; - } - if (edit.fieldValue === undefined) { - console.log('An edit is missing fieldValue'); - return false; - } - } + try { + // Parse fieldEdits and validate its structure + const edits = JSON.parse(String(params.fieldEdits)); - // Everything looks good with fieldEdits - return !!params.documentId; // Just ensure documentId is provided - } catch (error) { - console.log('Error parsing fieldEdits:', error); + // Ensure it's an array + if (!Array.isArray(edits)) { + console.log('fieldEdits is not an array'); return false; } - } else { - // Traditional single field edit - if (!params.documentId || !params.fieldName || params.fieldValue === undefined) { - return false; + + // Ensure each item has fieldName and fieldValue + for (const edit of edits) { + if (!edit.fieldName) { + console.log('An edit is missing fieldName'); + return false; + } + if (edit.fieldValue === undefined) { + console.log('An edit is missing fieldValue'); + return false; + } } + + // Everything looks good with fieldEdits + return true; + } catch (error) { + console.log('Error parsing fieldEdits:', error); + return false; } } @@ -1402,21 +1345,6 @@ ${JSON.stringify(createdMetadata, null, 2)}`, return true; } - // Allow for numeric or boolean fieldValue even though the type is defined as string - if (params.fieldValue !== undefined) { - if (typeof params.fieldValue === 'number') { - console.log('Numeric fieldValue detected, will be converted to string'); - // We'll convert it later, so don't fail validation - return true; - } - - if (typeof params.fieldValue === 'boolean') { - console.log('Boolean fieldValue detected, will be converted appropriately'); - // We'll handle boolean conversion in the execute method - return true; - } - } - return true; } @@ -1434,7 +1362,7 @@ ${JSON.stringify(createdMetadata, null, 2)}`, case 'get': return 'The "get" action accepts an optional documentId parameter.'; case 'edit': - return 'The "edit" action requires documentId, fieldName, and fieldValue parameters, or documentId and fieldEdits parameters for multi-field edits.'; + return 'The "edit" action requires documentId and fieldEdits parameters. fieldEdits must be a JSON array of field edits.'; case 'list': return 'The "list" action does not require any additional parameters.'; case 'getFieldOptions': |