From 656dbe6dc64013215eb312173df398fe4606d788 Mon Sep 17 00:00:00 2001 From: "A.J. Shulman" Date: Tue, 27 May 2025 14:08:11 -0400 Subject: feat: implement dynamic tool creation with deferred webpack rebuild and AI integration Added runtime tool registry to Agent.ts for dynamic tool lookup Implemented CreateNewTool agent tool for AI-driven code analysis and tool generation Enabled deferred saving to avoid interrupting AI workflows with immediate rebuilds Introduced user-controlled modal for confirming tool installation and page reload Added REST API and secure server-side persistence for dynamic tools Built TypeScript validation, transpilation, and sandboxed execution for safe tool handling UI enhancements: modal with blur, responsive design, clear messaging Ensured compatibility with Webpack using dynamic require() calls Full error handling, code validation, and secure storage on client and server sides --- .../nodes/chatbot/chatboxcomponents/ChatBox.scss | 120 +++++++++++++++++++++ .../nodes/chatbot/chatboxcomponents/ChatBox.tsx | 80 ++++++++++++++ 2 files changed, 200 insertions(+) (limited to 'src/client/views/nodes/chatbot/chatboxcomponents') diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss index 31f7be4c4..8e00cbdb7 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss @@ -950,3 +950,123 @@ $font-size-xlarge: 18px; } } } + +/* Tool Reload Modal Styles */ +.tool-reload-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + backdrop-filter: blur(4px); +} + +.tool-reload-modal { + background: white; + border-radius: 12px; + padding: 0; + min-width: 400px; + max-width: 500px; + box-shadow: + 0 20px 25px -5px rgba(0, 0, 0, 0.1), + 0 10px 10px -5px rgba(0, 0, 0, 0.04); + border: 1px solid #e2e8f0; + animation: modalSlideIn 0.3s ease-out; +} + +@keyframes modalSlideIn { + from { + opacity: 0; + transform: scale(0.95) translateY(-20px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +.tool-reload-modal-header { + padding: 24px 24px 16px 24px; + border-bottom: 1px solid #e2e8f0; + + h3 { + margin: 0; + font-size: 18px; + font-weight: 600; + color: #1a202c; + display: flex; + align-items: center; + + &::before { + content: '🛠️'; + margin-right: 8px; + font-size: 20px; + } + } +} + +.tool-reload-modal-content { + padding: 20px 24px; + + p { + margin: 0 0 12px 0; + line-height: 1.5; + color: #4a5568; + + &:last-child { + margin-bottom: 0; + } + + strong { + color: #2d3748; + font-weight: 600; + } + } +} + +.tool-reload-modal-actions { + padding: 16px 24px 24px 24px; + display: flex; + gap: 12px; + justify-content: flex-end; + + button { + padding: 10px 20px; + border-radius: 6px; + font-weight: 500; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + border: none; + + &.primary { + background: #3182ce; + color: white; + + &:hover { + background: #2c5aa0; + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); + } + } + + &.secondary { + background: #f7fafc; + color: #4a5568; + border: 1px solid #e2e8f0; + + &:hover { + background: #edf2f7; + border-color: #cbd5e0; + } + } + } +} diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 470f94a8d..df6c5627c 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -79,6 +79,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { @observable private _citationPopup: { text: string; visible: boolean } = { text: '', visible: false }; @observable private _isFontSizeModalOpen: boolean = false; @observable private _fontSize: 'small' | 'normal' | 'large' | 'xlarge' = 'normal'; + @observable private _toolReloadModal: { visible: boolean; toolName: string } = { visible: false, toolName: '' }; // Private properties for managing OpenAI API, vector store, agent, and UI elements private openai!: OpenAI; // Using definite assignment assertion @@ -125,6 +126,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { // Create an agent with the vectorstore this.agent = new Agent(this.vectorstore, this.retrieveFormattedHistory.bind(this), this.retrieveCSVData.bind(this), this.createImageInDash.bind(this), this.createCSVInDash.bind(this), this.docManager); + // Set up the tool created callback + this.agent.setToolCreatedCallback(this.handleToolCreated); + // Add event listeners this.addScrollListener(); @@ -1159,6 +1163,56 @@ export class ChatBox extends ViewBoxAnnotatableComponent() { this._inputValue = question; }; + /** + * Handles tool creation notification and shows the reload modal + * @param toolName The name of the tool that was created + */ + @action + handleToolCreated = (toolName: string) => { + this._toolReloadModal = { + visible: true, + toolName: toolName, + }; + }; + + /** + * Closes the tool reload modal + */ + @action + closeToolReloadModal = () => { + this._toolReloadModal = { + visible: false, + toolName: '', + }; + }; + + /** + * Handles the reload confirmation and triggers page reload + */ + @action + handleReloadConfirmation = async () => { + // Close the modal first + this.closeToolReloadModal(); + + try { + // Perform the deferred tool save operation + const saveSuccess = await this.agent.performDeferredToolSave(); + + if (saveSuccess) { + console.log('Tool saved successfully, proceeding with reload...'); + } else { + console.warn('Tool save failed, but proceeding with reload anyway...'); + } + } catch (error) { + console.error('Error during deferred tool save:', error); + } + + // Trigger page reload to rebuild webpack and load the new tool + setTimeout(() => { + window.location.reload(); + }, 100); + }; + _dictation: DictationButton | null = null; /** @@ -1434,6 +1488,32 @@ export class ChatBox extends ViewBoxAnnotatableComponent() {
{this._citationPopup.text}
)} + + {/* Tool Reload Modal */} + {this._toolReloadModal.visible && ( +
+
+
+

Tool Created Successfully!

+
+
+

+ The tool {this._toolReloadModal.toolName} has been created and saved successfully. +

+

To make the tool available for future use, the page needs to be reloaded to rebuild the application bundle.

+

Click "Reload Page" to complete the tool installation.

+
+
+ + +
+
+
+ )} ); } -- cgit v1.2.3-70-g09d2