@memberjunction/ng-ai-test-harness 5.22.0 → 5.24.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.
@@ -1 +1 @@
1
- {"version":3,"file":"test-harness-custom-window.component.js","sourceRoot":"","sources":["../../src/lib/test-harness-custom-window.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, ViewChild, OnDestroy, AfterViewInit, Renderer2, ElementRef, ChangeDetectorRef } from '@angular/core';\nimport { WindowComponent } from '@progress/kendo-angular-dialog';\nimport { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';\nimport { Metadata } from '@memberjunction/core';\nimport { AITestHarnessComponent } from './ai-test-harness.component';\n\nexport interface CustomWindowData {\n agentId?: string;\n agent?: MJAIAgentEntityExtended;\n promptId?: string;\n prompt?: MJAIPromptEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialDataContext?: Record<string, any>;\n initialTemplateData?: Record<string, any>;\n initialTemplateVariables?: Record<string, any>;\n selectedModelId?: string;\n mode?: 'agent' | 'prompt';\n}\n\n@Component({\n standalone: false,\n selector: 'mj-test-harness-custom-window',\n template: `\n <kendo-window\n #kendoWindow\n [title]=\"windowTitle\"\n [width]=\"width\"\n [height]=\"height\"\n [top]=\"windowTop\"\n [left]=\"windowLeft\"\n [minWidth]=\"isMinimized ? 400 : 800\"\n [minHeight]=\"isMinimized ? 60 : 600\"\n [draggable]=\"true\"\n [resizable]=\"!isMinimized\"\n [state]=\"windowState\"\n [class.minimized-window]=\"isMinimized\"\n (close)=\"onClose()\"\n (stateChange)=\"onStateChange($event)\"\n (resize)=\"onWindowResize()\">\n \n <kendo-window-titlebar>\n <div class=\"window-title\">\n @if (mode === 'agent' && agent?.LogoURL) {\n <img [src]=\"agent?.LogoURL\" class=\"title-logo\" alt=\"Agent logo\" />\n } @else if (mode === 'agent') {\n <i class=\"fa-solid fa-robot title-icon\"></i>\n } @else {\n <i class=\"fa-solid fa-comment-dots title-icon\"></i>\n }\n <span>{{ windowTitle }}</span>\n </div>\n <div class=\"window-actions\">\n <button \n (click)=\"minimize()\"\n title=\"Minimize\"\n class=\"window-action-btn\">\n <i class=\"fa-solid fa-window-minimize\"></i>\n </button>\n <button \n (click)=\"toggleMaximize()\"\n [title]=\"isMaximized ? 'Restore' : 'Maximize'\"\n class=\"window-action-btn\">\n <i class=\"fa-solid\" [class.fa-window-maximize]=\"!isMaximized\" [class.fa-window-restore]=\"isMaximized\"></i>\n </button>\n <button \n (click)=\"closeButtonClick()\"\n title=\"Close\"\n class=\"window-action-btn\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </kendo-window-titlebar>\n \n <div class=\"window-content\">\n @if (loading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"'Loading ' + (mode === 'agent' ? 'AI Agent' : 'AI Prompt') + '...'\" size=\"large\"></mj-loading>\n </div>\n }\n @else if (error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <p>{{ error }}</p>\n </div>\n }\n @else {\n <mj-ai-test-harness\n [entity]=\"(agent || prompt) || null\"\n [mode]=\"mode\"\n [isVisible]=\"true\"\n (runOpened)=\"onRunOpened($event)\">\n </mj-ai-test-harness>\n }\n </div>\n </kendo-window>\n `,\n styles: [`\n :host {\n display: contents;\n }\n \n /* Remove animation for snappy performance\n ::ng-deep .window-transition {\n transition: all 0.6s ease-in-out !important;\n } */\n \n ::ng-deep .minimized-window {\n .k-window-content {\n display: none !important;\n }\n \n .k-window-titlebar {\n border-radius: 4px !important;\n }\n }\n \n .window-title {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n \n .title-icon {\n color: #666;\n font-size: 16px;\n }\n \n .title-logo {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n }\n \n .window-actions {\n display: flex;\n gap: 4px;\n align-items: center;\n }\n \n .window-action-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &:hover {\n background-color: rgba(0, 0, 0, 0.08);\n }\n \n i {\n font-size: 14px;\n color: #666;\n }\n }\n \n .window-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n \n .loading-container,\n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n }\n \n .error-container {\n color: #dc3545;\n \n i {\n font-size: 3rem;\n }\n }\n \n mj-ai-test-harness {\n flex: 1;\n overflow: hidden;\n }\n \n /* Ensure Kendo Window content wrapper maintains proper height */\n ::ng-deep .k-window-content {\n display: flex;\n flex-direction: column;\n }\n `]\n})\nexport class TestHarnessCustomWindowComponent implements OnInit, OnDestroy, AfterViewInit {\n @ViewChild('kendoWindow', { static: false }) kendoWindow!: WindowComponent;\n @ViewChild(AITestHarnessComponent, { static: false }) testHarness?: AITestHarnessComponent;\n @Input() data: CustomWindowData = {};\n @Output() closeWindow = new EventEmitter<void>();\n @Output() minimizeWindow = new EventEmitter<void>();\n @Output() restoreWindow = new EventEmitter<void>();\n @Output() executionStateChange = new EventEmitter<{ windowId?: string; isExecuting: boolean }>();\n \n windowTitle = 'AI Test Harness';\n width: number = 1200;\n height: number = 800;\n windowTop: number = 100;\n windowLeft: number = 100;\n loading = true;\n error = '';\n windowState: 'default' | 'minimized' | 'maximized' = 'default';\n isMaximized = false;\n isMinimized = false;\n \n // Store original dimensions for restore\n private originalWidth: number = 1200;\n private originalHeight: number = 800;\n private originalTop: number = 100;\n private originalLeft: number = 100;\n \n // Minimized dimensions\n private readonly MINIMIZED_WIDTH = 400;\n private readonly MINIMIZED_HEIGHT = 60;\n \n agent?: MJAIAgentEntityExtended;\n prompt?: MJAIPromptEntityExtended;\n mode: 'agent' | 'prompt' = 'agent';\n \n private metadata = new Metadata();\n \n constructor(\n private renderer: Renderer2,\n private elementRef: ElementRef,\n private cdr: ChangeDetectorRef\n ) {}\n \n ngOnInit() {\n // Set window dimensions\n this.width = this.convertToNumber(this.data.width) || 1200;\n this.height = this.convertToNumber(this.data.height) || 800;\n \n // Store original dimensions\n this.originalWidth = this.width;\n this.originalHeight = this.height;\n \n // Calculate centered position\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n this.windowLeft = Math.max(0, (windowWidth - this.width) / 2);\n this.windowTop = Math.max(0, (windowHeight - this.height) / 2);\n \n // Store original position\n this.originalLeft = this.windowLeft;\n this.originalTop = this.windowTop;\n \n // Determine mode\n this.mode = this.data.mode || (this.data.promptId || this.data.prompt ? 'prompt' : 'agent');\n \n // Load entity\n this.loadEntity();\n }\n \n async loadEntity() {\n try {\n if (this.mode === 'agent') {\n if (this.data.agent) {\n this.agent = this.data.agent;\n this.windowTitle = this.data.title || `Test: ${this.agent.Name}`;\n } else if (this.data.agentId) {\n const agentEntity = await this.metadata.GetEntityObject<MJAIAgentEntityExtended>('MJ: AI Agents');\n await agentEntity.Load(this.data.agentId);\n if (agentEntity.IsSaved) {\n this.agent = agentEntity;\n this.windowTitle = this.data.title || `Test: ${this.agent.Name}`;\n } else {\n throw new Error('Agent not found');\n }\n } else {\n throw new Error('No agent provided');\n }\n } else {\n if (this.data.prompt) {\n this.prompt = this.data.prompt;\n this.windowTitle = this.data.title || `Test: ${this.prompt.Name}`;\n } else if (this.data.promptId) {\n const promptEntity = await this.metadata.GetEntityObject<MJAIPromptEntityExtended>('MJ: AI Prompts');\n await promptEntity.Load(this.data.promptId);\n if (promptEntity.IsSaved) {\n this.prompt = promptEntity;\n this.windowTitle = this.data.title || `Test: ${this.prompt.Name}`;\n } else {\n throw new Error('Prompt not found');\n }\n } else {\n throw new Error('No prompt provided');\n }\n }\n \n this.loading = false;\n } catch (err: any) {\n this.error = err.message || 'Failed to load entity';\n this.loading = false;\n }\n }\n \n onClose() {\n // When the Kendo Window's close event fires (from the default X button),\n // emit our closeWindow event to notify the window manager\n this.closeWindow.emit();\n }\n \n closeButtonClick() {\n // When our custom close button is clicked, emit the close event\n // This will trigger the window to close and call our onClose handler\n if (this.kendoWindow) {\n this.kendoWindow.close.emit();\n } else {\n // If kendoWindow is not available, directly emit the close event\n this.onClose();\n }\n }\n \n onStateChange(state: 'default' | 'minimized' | 'maximized') {\n this.windowState = state;\n this.isMaximized = state === 'maximized';\n this.isMinimized = state === 'minimized';\n \n // Handle restore from minimized\n if (this.isMinimized && state !== 'minimized') {\n this.restoreFromMinimized();\n }\n \n // Adjust content height on any state change\n if (state !== 'minimized') {\n setTimeout(() => this.adjustContentHeight(), 100);\n }\n }\n \n onWindowResize() {\n // Handle Kendo Window resize event\n if (!this.isMinimized) {\n // Use a small delay to ensure the DOM has updated\n setTimeout(() => this.adjustContentHeight(), 50);\n }\n }\n \n onRunOpened(event: { runId: string; runType: 'agent' | 'prompt' }) {\n // Auto-minimize the test harness window when a run is opened\n this.minimize();\n }\n \n minimize() {\n if (!this.isMinimized) {\n // Store current dimensions before minimizing\n this.originalWidth = this.width;\n this.originalHeight = this.height;\n this.originalTop = this.windowTop;\n this.originalLeft = this.windowLeft;\n \n // Hide the window when minimized (dock will show icon)\n this.isMinimized = true;\n this.minimizeWindow.emit();\n \n // Hide the window element\n let windowElement = this.elementRef.nativeElement.querySelector('.k-window');\n if (!windowElement && this.elementRef.nativeElement.closest) {\n windowElement = this.elementRef.nativeElement.closest('.k-window');\n }\n if (windowElement) {\n this.renderer.setStyle(windowElement, 'display', 'none');\n }\n }\n }\n \n restoreFromMinimized() {\n this.width = this.originalWidth;\n this.height = this.originalHeight;\n this.windowTop = this.originalTop;\n this.windowLeft = this.originalLeft;\n this.windowState = 'default';\n this.isMinimized = false;\n \n // Show the window element\n let windowElement = this.elementRef.nativeElement.querySelector('.k-window');\n if (!windowElement && this.elementRef.nativeElement.closest) {\n windowElement = this.elementRef.nativeElement.closest('.k-window');\n }\n if (windowElement) {\n this.renderer.setStyle(windowElement, 'display', 'block');\n }\n \n // Update position after state change\n setTimeout(() => {\n this.updateWindowPosition();\n \n // Force Angular change detection\n this.cdr.detectChanges();\n \n // Force the Kendo Window to recalculate its internal dimensions\n if (this.kendoWindow) {\n // Trigger resize event to fix content sizing\n window.dispatchEvent(new Event('resize'));\n \n // Use the shared method to adjust content height\n this.adjustContentHeight();\n }\n }, 100);\n \n // Emit restore event\n this.restoreWindow.emit();\n }\n \n toggleMaximize() {\n if (this.isMinimized) {\n // First restore from minimized, then maximize\n this.restoreFromMinimized();\n setTimeout(() => {\n this.windowState = 'maximized';\n this.isMaximized = true;\n }, 600);\n } else {\n this.windowState = this.isMaximized ? 'default' : 'maximized';\n this.isMaximized = !this.isMaximized;\n }\n }\n \n private convertToNumber(value: string | number | undefined): number | undefined {\n if (!value) return undefined;\n if (typeof value === 'number') return value;\n \n // Handle percentage values\n if (value.endsWith('vw') || value.endsWith('vh')) {\n const percentage = parseFloat(value) / 100;\n if (value.endsWith('vw')) {\n return window.innerWidth * percentage;\n } else {\n return window.innerHeight * percentage;\n }\n }\n \n // Handle pixel values\n if (value.endsWith('px')) {\n return parseFloat(value);\n }\n \n // Try to parse as number\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n }\n \n ngAfterViewInit() {\n // Set initial position if needed\n setTimeout(() => {\n this.updateWindowPosition();\n this.adjustContentHeight();\n }, 100);\n \n // Set up execution tracking\n this.setupExecutionTracking();\n \n // Set up window resize listener\n this.setupResizeListener();\n }\n \n private adjustContentHeight() {\n // Ensure the window content wrapper has proper height\n const contentWrapper = this.elementRef.nativeElement.querySelector('.k-window-content');\n if (contentWrapper && this.kendoWindow) {\n // Get the actual window element to check current dimensions\n const windowElement = this.elementRef.nativeElement.querySelector('.k-window') ||\n this.elementRef.nativeElement.closest('.k-window');\n \n // Update our tracked dimensions if the window has been resized\n if (windowElement) {\n const rect = windowElement.getBoundingClientRect();\n if (rect.width > 0) this.width = rect.width;\n if (rect.height > 0) this.height = rect.height;\n }\n \n // Calculate the actual content height (window height minus titlebar and some padding)\n const windowHeight = this.height;\n const titlebarHeight = 40; // Titlebar height\n const bottomPadding = 10; // Extra space to prevent clipping\n const contentHeight = windowHeight - titlebarHeight - bottomPadding;\n \n this.renderer.setStyle(contentWrapper, 'height', `${contentHeight}px`);\n this.renderer.setStyle(contentWrapper, 'display', 'flex');\n this.renderer.setStyle(contentWrapper, 'flex-direction', 'column');\n }\n \n // Also update the test harness container\n const testHarnessContainer = this.elementRef.nativeElement.querySelector('mj-ai-test-harness');\n if (testHarnessContainer) {\n this.renderer.setStyle(testHarnessContainer, 'flex', '1');\n this.renderer.setStyle(testHarnessContainer, 'height', '100%');\n this.renderer.setStyle(testHarnessContainer, 'overflow', 'hidden');\n }\n }\n \n private setupResizeListener() {\n // Debounced resize handler\n let resizeTimeout: any;\n const handleResize = () => {\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => {\n if (!this.isMinimized) {\n this.adjustContentHeight();\n }\n }, 100);\n };\n \n // Listen for window resize events\n window.addEventListener('resize', handleResize);\n \n // Store the handler for cleanup\n (this as any).resizeHandler = handleResize;\n \n // Note: Kendo Window resize events are handled by the (resize) event binding in the template\n }\n\n private setupExecutionTracking() {\n // Use a timer to check the test harness execution state\n // This is needed because the test harness doesn't emit events for execution state changes\n if (this.testHarness) {\n // Initial state\n let lastExecutingState = false;\n \n // Check execution state periodically\n const checkInterval = setInterval(() => {\n if (this.testHarness && this.testHarness.isExecuting !== lastExecutingState) {\n lastExecutingState = this.testHarness.isExecuting;\n this.executionStateChange.emit({ isExecuting: lastExecutingState });\n }\n }, 100);\n \n // Store interval for cleanup\n (this as any).executionCheckInterval = checkInterval;\n }\n }\n \n ngOnDestroy() {\n // Clean up execution tracking interval\n if ((this as any).executionCheckInterval) {\n clearInterval((this as any).executionCheckInterval);\n }\n \n // Clean up resize listener\n if ((this as any).resizeHandler) {\n window.removeEventListener('resize', (this as any).resizeHandler);\n }\n \n // Ensure window is properly closed and cleaned up\n if (this.kendoWindow) {\n this.kendoWindow.close.emit();\n }\n }\n \n private updateWindowPosition() {\n // Find the window element - it might be in the parent if we're inside a wrapper\n let windowElement = this.elementRef.nativeElement.querySelector('.k-window');\n if (!windowElement && this.elementRef.nativeElement.closest) {\n windowElement = this.elementRef.nativeElement.closest('.k-window');\n }\n \n if (windowElement && (this.windowTop !== undefined || this.windowLeft !== undefined)) {\n if (this.windowTop !== undefined) {\n this.renderer.setStyle(windowElement, 'top', `${this.windowTop}px`);\n }\n if (this.windowLeft !== undefined) {\n this.renderer.setStyle(windowElement, 'left', `${this.windowLeft}px`);\n }\n }\n }\n}"]}
1
+ {"version":3,"file":"test-harness-custom-window.component.js","sourceRoot":"","sources":["../../src/lib/test-harness-custom-window.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, ViewChild, OnDestroy, AfterViewInit, ChangeDetectorRef, inject } from '@angular/core';\nimport { MJWindowComponent } from '@memberjunction/ng-ui-components';\nimport { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';\nimport { Metadata } from '@memberjunction/core';\nimport { AITestHarnessComponent } from './ai-test-harness.component';\n\nexport interface CustomWindowData {\n agentId?: string;\n agent?: MJAIAgentEntityExtended;\n promptId?: string;\n prompt?: MJAIPromptEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialDataContext?: Record<string, unknown>;\n initialTemplateData?: Record<string, unknown>;\n initialTemplateVariables?: Record<string, unknown>;\n selectedModelId?: string;\n mode?: 'agent' | 'prompt';\n}\n\n@Component({\n standalone: false,\n selector: 'mj-test-harness-custom-window',\n template: `\n <mj-window\n #mjWindow\n [Visible]=\"WindowVisible\"\n [Title]=\"''\"\n [Width]=\"Width\"\n [Height]=\"Height\"\n [Top]=\"WindowTop\"\n [Left]=\"WindowLeft\"\n [MinWidth]=\"IsMinimized ? 400 : 800\"\n [MinHeight]=\"IsMinimized ? 60 : 600\"\n [Draggable]=\"true\"\n [Resizable]=\"!IsMinimized\"\n [State]=\"WindowState\"\n (Close)=\"OnClose()\"\n (StateChange)=\"OnStateChange($event)\"\n (Resize)=\"OnWindowResize()\">\n\n <mj-window-titlebar>\n <div class=\"window-title\">\n @if (Mode === 'agent' && Agent?.LogoURL) {\n <img [src]=\"Agent?.LogoURL\" class=\"title-logo\" alt=\"Agent logo\" />\n } @else if (Mode === 'agent') {\n <i class=\"fa-solid fa-robot title-icon\"></i>\n } @else {\n <i class=\"fa-solid fa-comment-dots title-icon\"></i>\n }\n <span>{{ WindowTitle }}</span>\n </div>\n <div class=\"window-actions\">\n <button\n (click)=\"Minimize()\"\n title=\"Minimize\"\n class=\"window-action-btn\">\n <i class=\"fa-solid fa-window-minimize\"></i>\n </button>\n <button\n (click)=\"ToggleMaximize()\"\n [title]=\"IsMaximized ? 'Restore' : 'Maximize'\"\n class=\"window-action-btn\">\n <i class=\"fa-solid\" [class.fa-window-maximize]=\"!IsMaximized\" [class.fa-window-restore]=\"IsMaximized\"></i>\n </button>\n <button\n (click)=\"CloseButtonClick()\"\n title=\"Close\"\n class=\"window-action-btn\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </mj-window-titlebar>\n\n <div class=\"window-content\">\n @if (Loading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"'Loading ' + (Mode === 'agent' ? 'AI Agent' : 'AI Prompt') + '...'\" size=\"large\"></mj-loading>\n </div>\n }\n @else if (Error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <p>{{ Error }}</p>\n </div>\n }\n @else {\n <mj-ai-test-harness\n [entity]=\"(Agent || Prompt) || null\"\n [mode]=\"Mode\"\n [isVisible]=\"true\"\n (runOpened)=\"OnRunOpened($event)\">\n </mj-ai-test-harness>\n }\n </div>\n </mj-window>\n `,\n styles: [`\n :host {\n display: contents;\n }\n\n .window-title {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n\n .title-icon {\n color: var(--mj-text-muted);\n font-size: 16px;\n }\n\n .title-logo {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n }\n\n .window-actions {\n display: flex;\n gap: 4px;\n align-items: center;\n }\n\n .window-action-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n border-radius: var(--mj-radius-sm);\n transition: var(--mj-transition-colors);\n display: flex;\n align-items: center;\n justify-content: center;\n\n &:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n i {\n font-size: 14px;\n color: var(--mj-text-muted);\n }\n }\n\n .window-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .loading-container,\n .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n }\n\n .error-container {\n color: var(--mj-status-error);\n\n i {\n font-size: 3rem;\n }\n }\n\n mj-ai-test-harness {\n flex: 1;\n overflow: hidden;\n }\n\n /* Ensure mj-window body fills available space for the test harness */\n :host ::ng-deep .mj-window-body {\n display: flex;\n flex-direction: column;\n padding: 0;\n }\n\n /* Hide the default close button since we have custom titlebar actions */\n :host ::ng-deep .mj-window-close {\n display: none;\n }\n `]\n})\nexport class TestHarnessCustomWindowComponent implements OnInit, OnDestroy, AfterViewInit {\n @ViewChild('mjWindow', { static: false }) MjWindow!: MJWindowComponent;\n @ViewChild(AITestHarnessComponent, { static: false }) TestHarness?: AITestHarnessComponent;\n @Input() Data: CustomWindowData = {};\n @Output() CloseWindow = new EventEmitter<void>();\n @Output() MinimizeWindow = new EventEmitter<void>();\n @Output() RestoreWindow = new EventEmitter<void>();\n @Output() ExecutionStateChange = new EventEmitter<{ windowId?: string; isExecuting: boolean }>();\n\n WindowTitle = 'AI Test Harness';\n WindowVisible = false;\n Width: number = 1200;\n Height: number = 800;\n WindowTop: number = 100;\n WindowLeft: number = 100;\n Loading = true;\n Error = '';\n WindowState: 'default' | 'maximized' = 'default';\n IsMaximized = false;\n IsMinimized = false;\n\n // Store original dimensions for restore\n private originalWidth: number = 1200;\n private originalHeight: number = 800;\n private originalTop: number = 100;\n private originalLeft: number = 100;\n\n Agent?: MJAIAgentEntityExtended;\n Prompt?: MJAIPromptEntityExtended;\n Mode: 'agent' | 'prompt' = 'agent';\n\n private metadata = new Metadata();\n private executionCheckInterval: ReturnType<typeof setInterval> | null = null;\n private cdr = inject(ChangeDetectorRef);\n\n ngOnInit() {\n // Set window dimensions\n this.Width = this.convertToNumber(this.Data.width) || 1200;\n this.Height = this.convertToNumber(this.Data.height) || 800;\n\n // Store original dimensions\n this.originalWidth = this.Width;\n this.originalHeight = this.Height;\n\n // Calculate centered position\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n this.WindowLeft = Math.max(0, (viewportWidth - this.Width) / 2);\n this.WindowTop = Math.max(0, (viewportHeight - this.Height) / 2);\n\n // Store original position\n this.originalLeft = this.WindowLeft;\n this.originalTop = this.WindowTop;\n\n // Determine mode\n this.Mode = this.Data.mode || (this.Data.promptId || this.Data.prompt ? 'prompt' : 'agent');\n\n // Set initial title from data if available\n if (this.Data.title) {\n this.WindowTitle = this.Data.title;\n } else if (this.Data.agent) {\n this.WindowTitle = `Test: ${this.Data.agent.Name}`;\n } else if (this.Data.prompt) {\n this.WindowTitle = `Test: ${this.Data.prompt.Name}`;\n }\n\n // Show window now that position is calculated\n this.WindowVisible = true;\n\n // Load entity\n this.LoadEntity();\n }\n\n async LoadEntity() {\n try {\n if (this.Mode === 'agent') {\n await this.loadAgent();\n } else {\n await this.loadPrompt();\n }\n this.Loading = false;\n this.cdr.detectChanges();\n } catch (err: unknown) {\n this.Error = err instanceof Error ? err.message : 'Failed to load entity';\n this.Loading = false;\n this.cdr.detectChanges();\n }\n }\n\n private async loadAgent() {\n if (this.Data.agent) {\n this.Agent = this.Data.agent;\n this.WindowTitle = this.Data.title || `Test: ${this.Agent.Name}`;\n } else if (this.Data.agentId) {\n const agentEntity = await this.metadata.GetEntityObject<MJAIAgentEntityExtended>('MJ: AI Agents');\n await agentEntity.Load(this.Data.agentId);\n if (agentEntity.IsSaved) {\n this.Agent = agentEntity;\n this.WindowTitle = this.Data.title || `Test: ${this.Agent.Name}`;\n } else {\n throw new Error('Agent not found');\n }\n } else {\n throw new Error('No agent provided');\n }\n }\n\n private async loadPrompt() {\n if (this.Data.prompt) {\n this.Prompt = this.Data.prompt;\n this.WindowTitle = this.Data.title || `Test: ${this.Prompt.Name}`;\n } else if (this.Data.promptId) {\n const promptEntity = await this.metadata.GetEntityObject<MJAIPromptEntityExtended>('MJ: AI Prompts');\n await promptEntity.Load(this.Data.promptId);\n if (promptEntity.IsSaved) {\n this.Prompt = promptEntity;\n this.WindowTitle = this.Data.title || `Test: ${this.Prompt.Name}`;\n } else {\n throw new Error('Prompt not found');\n }\n } else {\n throw new Error('No prompt provided');\n }\n }\n\n OnClose() {\n this.CloseWindow.emit();\n }\n\n CloseButtonClick() {\n this.OnClose();\n }\n\n OnStateChange(state: 'default' | 'maximized') {\n this.WindowState = state;\n this.IsMaximized = state === 'maximized';\n }\n\n OnWindowResize() {\n // Window was resized — no special handling needed as mj-window tracks dimensions internally\n }\n\n OnRunOpened(_event: { runId: string; runType: 'agent' | 'prompt' }) {\n // Auto-minimize the test harness window when a run is opened\n this.Minimize();\n }\n\n Minimize() {\n if (!this.IsMinimized) {\n // Store current dimensions before minimizing\n this.originalWidth = this.Width;\n this.originalHeight = this.Height;\n this.originalTop = this.WindowTop;\n this.originalLeft = this.WindowLeft;\n\n // Hide the window when minimized (dock will show icon)\n this.IsMinimized = true;\n this.WindowVisible = false;\n this.MinimizeWindow.emit();\n this.cdr.detectChanges();\n }\n }\n\n RestoreFromMinimized() {\n this.Width = this.originalWidth;\n this.Height = this.originalHeight;\n this.WindowTop = this.originalTop;\n this.WindowLeft = this.originalLeft;\n this.WindowState = 'default';\n this.IsMinimized = false;\n this.IsMaximized = false;\n this.WindowVisible = true;\n\n this.cdr.detectChanges();\n\n // Emit restore event\n this.RestoreWindow.emit();\n }\n\n ToggleMaximize() {\n if (this.IsMinimized) {\n // First restore from minimized, then maximize\n this.RestoreFromMinimized();\n setTimeout(() => {\n this.WindowState = 'maximized';\n this.IsMaximized = true;\n this.cdr.detectChanges();\n }, 100);\n } else {\n this.WindowState = this.IsMaximized ? 'default' : 'maximized';\n this.IsMaximized = !this.IsMaximized;\n }\n }\n\n private convertToNumber(value: string | number | undefined): number | undefined {\n if (!value) return undefined;\n if (typeof value === 'number') return value;\n\n // Handle percentage values\n if (value.endsWith('vw') || value.endsWith('vh')) {\n const percentage = parseFloat(value) / 100;\n if (value.endsWith('vw')) {\n return window.innerWidth * percentage;\n } else {\n return window.innerHeight * percentage;\n }\n }\n\n // Handle pixel values\n if (value.endsWith('px')) {\n return parseFloat(value);\n }\n\n // Try to parse as number\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n }\n\n ngAfterViewInit() {\n // Set up execution tracking\n this.setupExecutionTracking();\n }\n\n private setupExecutionTracking() {\n // Use a timer to check the test harness execution state\n if (this.TestHarness) {\n let lastExecutingState = false;\n\n this.executionCheckInterval = setInterval(() => {\n if (this.TestHarness && this.TestHarness.isExecuting !== lastExecutingState) {\n lastExecutingState = this.TestHarness.isExecuting;\n this.ExecutionStateChange.emit({ isExecuting: lastExecutingState });\n }\n }, 100);\n }\n }\n\n ngOnDestroy() {\n if (this.executionCheckInterval) {\n clearInterval(this.executionCheckInterval);\n }\n }\n}\n"]}
@@ -60,9 +60,9 @@ export class TestHarnessWindowManagerService {
60
60
  hostElement: document.createElement('div')
61
61
  });
62
62
  // Set component data
63
- componentRef.instance.data = data;
63
+ componentRef.instance.Data = data;
64
64
  // Handle window events
65
- componentRef.instance.closeWindow.subscribe(() => {
65
+ componentRef.instance.CloseWindow.subscribe(() => {
66
66
  this.closeWindow(windowId);
67
67
  resultSubject.next({
68
68
  success: true
@@ -70,37 +70,37 @@ export class TestHarnessWindowManagerService {
70
70
  resultSubject.complete();
71
71
  });
72
72
  // Handle minimize event
73
- componentRef.instance.minimizeWindow.subscribe(() => {
74
- const title = componentRef.instance.windowTitle;
73
+ componentRef.instance.MinimizeWindow.subscribe(() => {
74
+ const title = componentRef.instance.WindowTitle;
75
75
  let icon = 'fa-solid fa-flask'; // default
76
76
  let iconUrl;
77
77
  // Get the appropriate icon based on mode and entity
78
- if (componentRef.instance.mode === 'agent' && componentRef.instance.agent) {
78
+ if (componentRef.instance.Mode === 'agent' && componentRef.instance.Agent) {
79
79
  // For agents, use LogoURL since MJAIAgentEntityExtended doesn't have IconClass
80
- if (componentRef.instance.agent.LogoURL) {
81
- iconUrl = componentRef.instance.agent.LogoURL;
80
+ if (componentRef.instance.Agent.LogoURL) {
81
+ iconUrl = componentRef.instance.Agent.LogoURL;
82
82
  icon = undefined; // Clear icon when using URL
83
83
  }
84
84
  else {
85
85
  icon = 'fa-solid fa-robot'; // Default agent icon
86
86
  }
87
87
  }
88
- else if (componentRef.instance.mode === 'prompt') {
88
+ else if (componentRef.instance.Mode === 'prompt') {
89
89
  icon = 'fa-solid fa-comment-dots'; // Default prompt icon
90
90
  }
91
91
  // Add to dock with icon or iconUrl
92
92
  this.dockService.addWindow(windowId, title, icon, () => {
93
93
  // Restore callback
94
- componentRef.instance.restoreFromMinimized();
94
+ componentRef.instance.RestoreFromMinimized();
95
95
  }, iconUrl);
96
96
  });
97
97
  // Handle restore event
98
- componentRef.instance.restoreWindow.subscribe(() => {
98
+ componentRef.instance.RestoreWindow.subscribe(() => {
99
99
  // Remove from dock
100
100
  this.dockService.removeWindow(windowId);
101
101
  });
102
102
  // Handle execution state changes
103
- componentRef.instance.executionStateChange.subscribe((state) => {
103
+ componentRef.instance.ExecutionStateChange.subscribe((state) => {
104
104
  if (state.isExecuting) {
105
105
  // Show indeterminate progress (spinning/pulsing)
106
106
  this.dockService.updateWindowProgress(windowId, 50); // 50% for indeterminate animation
@@ -1 +1 @@
1
- {"version":3,"file":"test-harness-window-manager.service.js","sourceRoot":"","sources":["../../src/lib/test-harness-window-manager.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, ComponentRef, ApplicationRef, Injector, createComponent, ViewContainerRef } from '@angular/core';\nimport { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';\nimport { TestHarnessCustomWindowComponent, CustomWindowData } from './test-harness-custom-window.component';\nimport { Observable, Subject } from 'rxjs';\nimport { TestResult } from './test-harness-window.service';\nimport { WindowDockService } from './window-dock.service';\n\ninterface WindowInfo {\n componentRef: ComponentRef<TestHarnessCustomWindowComponent>;\n usedViewContainerRef: boolean;\n}\n\n/**\n * Service for managing test harness windows for AI Agents and AI Prompts.\n * Creates Kendo Window components with custom titlebar including minimize button.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestHarnessWindowManagerService {\n private openWindows = new Map<string, WindowInfo>();\n private windowCounter = 0;\n \n constructor(\n private appRef: ApplicationRef,\n private injector: Injector,\n private dockService: WindowDockService\n ) {}\n \n /**\n * Opens the AI Agent Test Harness in a window\n */\n openAgentTestHarness(options: {\n agentId?: string;\n agent?: MJAIAgentEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialDataContext?: Record<string, any>;\n initialTemplateData?: Record<string, any>;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n const data: CustomWindowData = {\n agentId: options.agentId,\n agent: options.agent,\n title: options.title,\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialDataContext: options.initialDataContext,\n initialTemplateData: options.initialTemplateData,\n mode: 'agent'\n };\n \n return this.createWindow(data, options.viewContainerRef);\n }\n \n /**\n * Opens the AI Prompt Test Harness in a window\n */\n openPromptTestHarness(options: {\n promptId?: string;\n prompt?: MJAIPromptEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialTemplateVariables?: Record<string, any>;\n selectedModelId?: string;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n const data: CustomWindowData = {\n promptId: options.promptId,\n prompt: options.prompt,\n title: options.title || 'Test AI Prompt',\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialTemplateVariables: options.initialTemplateVariables,\n selectedModelId: options.selectedModelId,\n mode: 'prompt'\n };\n \n return this.createWindow(data, options.viewContainerRef);\n }\n \n /**\n * Creates a test harness window\n */\n private createWindow(data: CustomWindowData, viewContainerRef?: ViewContainerRef): Observable<TestResult> {\n const resultSubject = new Subject<TestResult>();\n const windowId = `test-harness-${++this.windowCounter}`;\n \n // Create component\n const componentRef = createComponent(TestHarnessCustomWindowComponent, {\n environmentInjector: this.appRef.injector,\n elementInjector: this.injector,\n hostElement: document.createElement('div')\n });\n \n // Set component data\n componentRef.instance.data = data;\n \n // Handle window events\n componentRef.instance.closeWindow.subscribe(() => {\n this.closeWindow(windowId);\n resultSubject.next({\n success: true\n });\n resultSubject.complete();\n });\n \n // Handle minimize event\n componentRef.instance.minimizeWindow.subscribe(() => {\n const title = componentRef.instance.windowTitle;\n let icon: string | undefined = 'fa-solid fa-flask'; // default\n let iconUrl: string | undefined;\n \n // Get the appropriate icon based on mode and entity\n if (componentRef.instance.mode === 'agent' && componentRef.instance.agent) {\n // For agents, use LogoURL since MJAIAgentEntityExtended doesn't have IconClass\n if (componentRef.instance.agent.LogoURL) {\n iconUrl = componentRef.instance.agent.LogoURL;\n icon = undefined; // Clear icon when using URL\n } else {\n icon = 'fa-solid fa-robot'; // Default agent icon\n }\n } else if (componentRef.instance.mode === 'prompt') {\n icon = 'fa-solid fa-comment-dots'; // Default prompt icon\n }\n \n // Add to dock with icon or iconUrl\n this.dockService.addWindow(windowId, title, icon, () => {\n // Restore callback\n componentRef.instance.restoreFromMinimized();\n }, iconUrl);\n });\n \n // Handle restore event\n componentRef.instance.restoreWindow.subscribe(() => {\n // Remove from dock\n this.dockService.removeWindow(windowId);\n });\n \n // Handle execution state changes\n componentRef.instance.executionStateChange.subscribe((state) => {\n if (state.isExecuting) {\n // Show indeterminate progress (spinning/pulsing)\n this.dockService.updateWindowProgress(windowId, 50); // 50% for indeterminate animation\n } else {\n // Clear progress\n this.dockService.updateWindowProgress(windowId, undefined);\n }\n });\n \n // Attach to DOM\n if (viewContainerRef) {\n // When using viewContainerRef, the view is automatically attached to Angular\n viewContainerRef.insert(componentRef.hostView);\n } else {\n // When appending to document.body, we need to manually attach to Angular\n document.body.appendChild(componentRef.location.nativeElement);\n this.appRef.attachView(componentRef.hostView);\n }\n \n // Store reference with info about how it was created\n this.openWindows.set(windowId, {\n componentRef,\n usedViewContainerRef: !!viewContainerRef\n });\n \n return resultSubject.asObservable();\n }\n \n /**\n * Closes a specific window\n */\n private closeWindow(windowId: string) {\n const windowInfo = this.openWindows.get(windowId);\n if (windowInfo) {\n // Remove from dock if minimized\n this.dockService.removeWindow(windowId);\n \n // Only detach from appRef if we attached it manually (not using viewContainerRef)\n if (!windowInfo.usedViewContainerRef) {\n this.appRef.detachView(windowInfo.componentRef.hostView);\n }\n windowInfo.componentRef.destroy();\n this.openWindows.delete(windowId);\n }\n }\n \n /**\n * Closes all open windows\n */\n closeAllWindows() {\n this.openWindows.forEach((windowInfo, id) => {\n this.closeWindow(id);\n });\n }\n}"]}
1
+ {"version":3,"file":"test-harness-window-manager.service.js","sourceRoot":"","sources":["../../src/lib/test-harness-window-manager.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, ComponentRef, ApplicationRef, Injector, createComponent, ViewContainerRef } from '@angular/core';\nimport { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';\nimport { TestHarnessCustomWindowComponent, CustomWindowData } from './test-harness-custom-window.component';\nimport { Observable, Subject } from 'rxjs';\nimport { TestResult } from './test-harness-window.service';\nimport { WindowDockService } from './window-dock.service';\n\ninterface WindowInfo {\n componentRef: ComponentRef<TestHarnessCustomWindowComponent>;\n usedViewContainerRef: boolean;\n}\n\n/**\n * Service for managing test harness windows for AI Agents and AI Prompts.\n * Creates Kendo Window components with custom titlebar including minimize button.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestHarnessWindowManagerService {\n private openWindows = new Map<string, WindowInfo>();\n private windowCounter = 0;\n \n constructor(\n private appRef: ApplicationRef,\n private injector: Injector,\n private dockService: WindowDockService\n ) {}\n \n /**\n * Opens the AI Agent Test Harness in a window\n */\n openAgentTestHarness(options: {\n agentId?: string;\n agent?: MJAIAgentEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialDataContext?: Record<string, any>;\n initialTemplateData?: Record<string, any>;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n const data: CustomWindowData = {\n agentId: options.agentId,\n agent: options.agent,\n title: options.title,\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialDataContext: options.initialDataContext,\n initialTemplateData: options.initialTemplateData,\n mode: 'agent'\n };\n \n return this.createWindow(data, options.viewContainerRef);\n }\n \n /**\n * Opens the AI Prompt Test Harness in a window\n */\n openPromptTestHarness(options: {\n promptId?: string;\n prompt?: MJAIPromptEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialTemplateVariables?: Record<string, any>;\n selectedModelId?: string;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n const data: CustomWindowData = {\n promptId: options.promptId,\n prompt: options.prompt,\n title: options.title || 'Test AI Prompt',\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialTemplateVariables: options.initialTemplateVariables,\n selectedModelId: options.selectedModelId,\n mode: 'prompt'\n };\n \n return this.createWindow(data, options.viewContainerRef);\n }\n \n /**\n * Creates a test harness window\n */\n private createWindow(data: CustomWindowData, viewContainerRef?: ViewContainerRef): Observable<TestResult> {\n const resultSubject = new Subject<TestResult>();\n const windowId = `test-harness-${++this.windowCounter}`;\n \n // Create component\n const componentRef = createComponent(TestHarnessCustomWindowComponent, {\n environmentInjector: this.appRef.injector,\n elementInjector: this.injector,\n hostElement: document.createElement('div')\n });\n \n // Set component data\n componentRef.instance.Data = data;\n\n // Handle window events\n componentRef.instance.CloseWindow.subscribe(() => {\n this.closeWindow(windowId);\n resultSubject.next({\n success: true\n });\n resultSubject.complete();\n });\n\n // Handle minimize event\n componentRef.instance.MinimizeWindow.subscribe(() => {\n const title = componentRef.instance.WindowTitle;\n let icon: string | undefined = 'fa-solid fa-flask'; // default\n let iconUrl: string | undefined;\n\n // Get the appropriate icon based on mode and entity\n if (componentRef.instance.Mode === 'agent' && componentRef.instance.Agent) {\n // For agents, use LogoURL since MJAIAgentEntityExtended doesn't have IconClass\n if (componentRef.instance.Agent.LogoURL) {\n iconUrl = componentRef.instance.Agent.LogoURL;\n icon = undefined; // Clear icon when using URL\n } else {\n icon = 'fa-solid fa-robot'; // Default agent icon\n }\n } else if (componentRef.instance.Mode === 'prompt') {\n icon = 'fa-solid fa-comment-dots'; // Default prompt icon\n }\n\n // Add to dock with icon or iconUrl\n this.dockService.addWindow(windowId, title, icon, () => {\n // Restore callback\n componentRef.instance.RestoreFromMinimized();\n }, iconUrl);\n });\n\n // Handle restore event\n componentRef.instance.RestoreWindow.subscribe(() => {\n // Remove from dock\n this.dockService.removeWindow(windowId);\n });\n\n // Handle execution state changes\n componentRef.instance.ExecutionStateChange.subscribe((state) => {\n if (state.isExecuting) {\n // Show indeterminate progress (spinning/pulsing)\n this.dockService.updateWindowProgress(windowId, 50); // 50% for indeterminate animation\n } else {\n // Clear progress\n this.dockService.updateWindowProgress(windowId, undefined);\n }\n });\n \n // Attach to DOM\n if (viewContainerRef) {\n // When using viewContainerRef, the view is automatically attached to Angular\n viewContainerRef.insert(componentRef.hostView);\n } else {\n // When appending to document.body, we need to manually attach to Angular\n document.body.appendChild(componentRef.location.nativeElement);\n this.appRef.attachView(componentRef.hostView);\n }\n \n // Store reference with info about how it was created\n this.openWindows.set(windowId, {\n componentRef,\n usedViewContainerRef: !!viewContainerRef\n });\n \n return resultSubject.asObservable();\n }\n \n /**\n * Closes a specific window\n */\n private closeWindow(windowId: string) {\n const windowInfo = this.openWindows.get(windowId);\n if (windowInfo) {\n // Remove from dock if minimized\n this.dockService.removeWindow(windowId);\n \n // Only detach from appRef if we attached it manually (not using viewContainerRef)\n if (!windowInfo.usedViewContainerRef) {\n this.appRef.detachView(windowInfo.componentRef.hostView);\n }\n windowInfo.componentRef.destroy();\n this.openWindows.delete(windowId);\n }\n }\n \n /**\n * Closes all open windows\n */\n closeAllWindows() {\n this.openWindows.forEach((windowInfo, id) => {\n this.closeWindow(id);\n });\n }\n}"]}
@@ -1,73 +1,19 @@
1
- import { ViewContainerRef } from '@angular/core';
2
- import { WindowService } from '@progress/kendo-angular-dialog';
3
- import { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';
4
- import { Observable } from 'rxjs';
5
1
  import * as i0 from "@angular/core";
6
2
  export interface TestResult {
7
3
  success: boolean;
8
- result?: any;
4
+ result?: unknown;
9
5
  error?: string;
10
6
  executionTime?: number;
11
7
  tokensUsed?: number;
12
8
  cost?: number;
13
9
  }
14
10
  /**
15
- * Service for managing test harness windows for AI Agents and AI Prompts.
16
- * Uses Kendo Window component which provides maximize and close functionality.
17
- *
18
- * Note: Kendo Window created via WindowService does not include a minimize button
19
- * in the titlebar. The window supports maximize/restore and close actions only.
20
- * To add minimize functionality, a custom window component with custom titlebar
21
- * would need to be implemented.
11
+ * @deprecated Use TestHarnessWindowManagerService instead.
12
+ * This service previously used Kendo WindowService to open test harness windows.
13
+ * It is retained only because the TestResult interface is exported from here
14
+ * and consumed by other services.
22
15
  */
23
16
  export declare class TestHarnessWindowService {
24
- private windowService;
25
- private openWindows;
26
- private windowCounter;
27
- constructor(windowService: WindowService);
28
- /**
29
- * Opens the AI Agent Test Harness in a window
30
- */
31
- openAgentTestHarness(options: {
32
- agentId?: string;
33
- agent?: MJAIAgentEntityExtended;
34
- title?: string;
35
- width?: string | number;
36
- height?: string | number;
37
- initialDataContext?: Record<string, any>;
38
- initialTemplateData?: Record<string, any>;
39
- viewContainerRef?: ViewContainerRef;
40
- }): Observable<TestResult>;
41
- /**
42
- * Opens the AI Prompt Test Harness in a window
43
- */
44
- openPromptTestHarness(options: {
45
- promptId?: string;
46
- prompt?: MJAIPromptEntityExtended;
47
- title?: string;
48
- width?: string | number;
49
- height?: string | number;
50
- initialTemplateVariables?: Record<string, any>;
51
- selectedModelId?: string;
52
- promptRunId?: string;
53
- viewContainerRef?: ViewContainerRef;
54
- }): Observable<TestResult>;
55
- /**
56
- * Opens a test harness window
57
- */
58
- private openWindow;
59
- /**
60
- * Closes a specific window
61
- */
62
- private closeWindow;
63
- /**
64
- * Closes all open windows
65
- */
66
- closeAllWindows(): void;
67
- /**
68
- * Helper method to convert string dimensions to pixel numbers
69
- */
70
- private convertToNumber;
71
17
  static ɵfac: i0.ɵɵFactoryDeclaration<TestHarnessWindowService, never>;
72
18
  static ɵprov: i0.ɵɵInjectableDeclaration<TestHarnessWindowService>;
73
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"test-harness-window.service.d.ts","sourceRoot":"","sources":["../../src/lib/test-harness-window.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,aAAa,EAA6B,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAEjG,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE3C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,qBAGa,wBAAwB;IAIrB,OAAO,CAAC,aAAa;IAHjC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,aAAa,CAAK;gBAEN,aAAa,EAAE,aAAa;IAEhD;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE;QAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,uBAAuB,CAAC;QAChC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACvC,GAAG,UAAU,CAAC,UAAU,CAAC;IAe1B;;OAEG;IACH,qBAAqB,CAAC,OAAO,EAAE;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,wBAAwB,CAAC;QAClC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACzB,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACvC,GAAG,UAAU,CAAC,UAAU,CAAC;IAqB1B;;OAEG;IACH,OAAO,CAAC,UAAU;IA2DlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAcnB;;OAEG;IACH,eAAe;IAOf;;OAEG;IACH,OAAO,CAAC,eAAe;yCA/Jd,wBAAwB;6CAAxB,wBAAwB;CAsLpC"}
1
+ {"version":3,"file":"test-harness-window.service.d.ts","sourceRoot":"","sources":["../../src/lib/test-harness-window.service.ts"],"names":[],"mappings":";AAEA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAGa,wBAAwB;yCAAxB,wBAAwB;6CAAxB,wBAAwB;CACpC"}
@@ -1,166 +1,13 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { AITestHarnessWindowComponent } from './ai-test-harness-window.component';
3
- import { Subject } from 'rxjs';
4
2
  import * as i0 from "@angular/core";
5
- import * as i1 from "@progress/kendo-angular-dialog";
6
3
  /**
7
- * Service for managing test harness windows for AI Agents and AI Prompts.
8
- * Uses Kendo Window component which provides maximize and close functionality.
9
- *
10
- * Note: Kendo Window created via WindowService does not include a minimize button
11
- * in the titlebar. The window supports maximize/restore and close actions only.
12
- * To add minimize functionality, a custom window component with custom titlebar
13
- * would need to be implemented.
4
+ * @deprecated Use TestHarnessWindowManagerService instead.
5
+ * This service previously used Kendo WindowService to open test harness windows.
6
+ * It is retained only because the TestResult interface is exported from here
7
+ * and consumed by other services.
14
8
  */
15
9
  export class TestHarnessWindowService {
16
- constructor(windowService) {
17
- this.windowService = windowService;
18
- this.openWindows = new Map();
19
- this.windowCounter = 0;
20
- }
21
- /**
22
- * Opens the AI Agent Test Harness in a window
23
- */
24
- openAgentTestHarness(options) {
25
- const data = {
26
- agentId: options.agentId,
27
- agent: options.agent,
28
- title: options.title,
29
- width: options.width || '90vw',
30
- height: options.height || '90vh',
31
- initialDataContext: options.initialDataContext,
32
- initialTemplateData: options.initialTemplateData,
33
- mode: 'agent'
34
- };
35
- return this.openWindow(data, options.viewContainerRef);
36
- }
37
- /**
38
- * Opens the AI Prompt Test Harness in a window
39
- */
40
- openPromptTestHarness(options) {
41
- console.log('🎯 openPromptTestHarness called with options:', options);
42
- console.log('📌 promptRunId:', options.promptRunId);
43
- const data = {
44
- promptId: options.promptId,
45
- prompt: options.prompt,
46
- title: options.title || 'Test AI Prompt',
47
- width: options.width || '90vw',
48
- height: options.height || '90vh',
49
- initialTemplateVariables: options.initialTemplateVariables,
50
- selectedModelId: options.selectedModelId,
51
- promptRunId: options.promptRunId,
52
- mode: 'prompt'
53
- };
54
- console.log('📦 Final AITestHarnessWindowData:', data);
55
- return this.openWindow(data, options.viewContainerRef);
56
- }
57
- /**
58
- * Opens a test harness window
59
- */
60
- openWindow(data, viewContainerRef) {
61
- const resultSubject = new Subject();
62
- const windowId = `test-harness-${++this.windowCounter}`;
63
- const windowSettings = {
64
- title: data.title || 'AI Test Harness',
65
- content: AITestHarnessWindowComponent,
66
- width: this.convertToNumber(data.width) || 1200,
67
- height: this.convertToNumber(data.height) || 800,
68
- minWidth: 800,
69
- minHeight: 600,
70
- draggable: true,
71
- resizable: true,
72
- state: 'default',
73
- cssClass: 'test-harness-window-wrapper'
74
- };
75
- if (viewContainerRef) {
76
- windowSettings.appendTo = viewContainerRef;
77
- }
78
- const windowRef = this.windowService.open(windowSettings);
79
- this.openWindows.set(windowId, windowRef);
80
- // Pass data to the component
81
- const componentRef = windowRef.content;
82
- if (componentRef && componentRef.instance) {
83
- componentRef.instance.data = data;
84
- // Handle window close
85
- componentRef.instance.closeWindow.subscribe(() => {
86
- this.closeWindow(windowId);
87
- // Don't complete the observable here, as the window.result will handle it
88
- });
89
- }
90
- // Handle window close via close button
91
- windowRef.result.subscribe({
92
- next: (result) => {
93
- this.openWindows.delete(windowId);
94
- resultSubject.next({
95
- success: true,
96
- result: result
97
- });
98
- resultSubject.complete();
99
- },
100
- error: (error) => {
101
- this.openWindows.delete(windowId);
102
- resultSubject.next({
103
- success: false,
104
- error: error.message || 'Test failed'
105
- });
106
- resultSubject.complete();
107
- }
108
- });
109
- return resultSubject.asObservable();
110
- }
111
- /**
112
- * Closes a specific window
113
- */
114
- closeWindow(windowId) {
115
- const windowRef = this.openWindows.get(windowId);
116
- if (windowRef) {
117
- try {
118
- windowRef.close();
119
- this.openWindows.delete(windowId);
120
- }
121
- catch (error) {
122
- console.error('Error closing window:', error);
123
- // Force delete from map even if close fails
124
- this.openWindows.delete(windowId);
125
- }
126
- }
127
- }
128
- /**
129
- * Closes all open windows
130
- */
131
- closeAllWindows() {
132
- this.openWindows.forEach((windowRef, id) => {
133
- windowRef.close();
134
- });
135
- this.openWindows.clear();
136
- }
137
- /**
138
- * Helper method to convert string dimensions to pixel numbers
139
- */
140
- convertToNumber(value) {
141
- if (!value)
142
- return undefined;
143
- if (typeof value === 'number')
144
- return value;
145
- // Handle percentage values
146
- if (value.endsWith('vw') || value.endsWith('vh')) {
147
- const percentage = parseFloat(value) / 100;
148
- if (value.endsWith('vw')) {
149
- return window.innerWidth * percentage;
150
- }
151
- else {
152
- return window.innerHeight * percentage;
153
- }
154
- }
155
- // Handle pixel values
156
- if (value.endsWith('px')) {
157
- return parseFloat(value);
158
- }
159
- // Try to parse as number
160
- const parsed = parseFloat(value);
161
- return isNaN(parsed) ? undefined : parsed;
162
- }
163
- static { this.ɵfac = function TestHarnessWindowService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestHarnessWindowService)(i0.ɵɵinject(i1.WindowService)); }; }
10
+ static { this.ɵfac = function TestHarnessWindowService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestHarnessWindowService)(); }; }
164
11
  static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TestHarnessWindowService, factory: TestHarnessWindowService.ɵfac, providedIn: 'root' }); }
165
12
  }
166
13
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestHarnessWindowService, [{
@@ -168,5 +15,5 @@ export class TestHarnessWindowService {
168
15
  args: [{
169
16
  providedIn: 'root'
170
17
  }]
171
- }], () => [{ type: i1.WindowService }], null); })();
18
+ }], null, null); })();
172
19
  //# sourceMappingURL=test-harness-window.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-harness-window.service.js","sourceRoot":"","sources":["../../src/lib/test-harness-window.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, ViewContainerRef, ComponentRef } from '@angular/core';\nimport { WindowService, WindowRef, WindowSettings } from '@progress/kendo-angular-dialog';\nimport { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';\nimport { AITestHarnessWindowComponent, AITestHarnessWindowData } from './ai-test-harness-window.component';\nimport { Observable, Subject } from 'rxjs';\n\nexport interface TestResult {\n success: boolean;\n result?: any;\n error?: string;\n executionTime?: number;\n tokensUsed?: number;\n cost?: number;\n}\n\n/**\n * Service for managing test harness windows for AI Agents and AI Prompts.\n * Uses Kendo Window component which provides maximize and close functionality.\n * \n * Note: Kendo Window created via WindowService does not include a minimize button\n * in the titlebar. The window supports maximize/restore and close actions only.\n * To add minimize functionality, a custom window component with custom titlebar\n * would need to be implemented.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestHarnessWindowService {\n private openWindows = new Map<string, WindowRef>();\n private windowCounter = 0;\n \n constructor(private windowService: WindowService) {}\n \n /**\n * Opens the AI Agent Test Harness in a window\n */\n openAgentTestHarness(options: {\n agentId?: string;\n agent?: MJAIAgentEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialDataContext?: Record<string, any>;\n initialTemplateData?: Record<string, any>;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n const data: AITestHarnessWindowData = {\n agentId: options.agentId,\n agent: options.agent,\n title: options.title,\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialDataContext: options.initialDataContext,\n initialTemplateData: options.initialTemplateData,\n mode: 'agent'\n };\n \n return this.openWindow(data, options.viewContainerRef);\n }\n \n /**\n * Opens the AI Prompt Test Harness in a window\n */\n openPromptTestHarness(options: {\n promptId?: string;\n prompt?: MJAIPromptEntityExtended;\n title?: string;\n width?: string | number;\n height?: string | number;\n initialTemplateVariables?: Record<string, any>;\n selectedModelId?: string;\n promptRunId?: string;\n viewContainerRef?: ViewContainerRef;\n }): Observable<TestResult> {\n console.log('🎯 openPromptTestHarness called with options:', options);\n console.log('📌 promptRunId:', options.promptRunId);\n \n const data: AITestHarnessWindowData = {\n promptId: options.promptId,\n prompt: options.prompt,\n title: options.title || 'Test AI Prompt',\n width: options.width || '90vw',\n height: options.height || '90vh',\n initialTemplateVariables: options.initialTemplateVariables,\n selectedModelId: options.selectedModelId,\n promptRunId: options.promptRunId,\n mode: 'prompt'\n };\n \n console.log('📦 Final AITestHarnessWindowData:', data);\n \n return this.openWindow(data, options.viewContainerRef);\n }\n \n /**\n * Opens a test harness window\n */\n private openWindow(data: AITestHarnessWindowData, viewContainerRef?: ViewContainerRef): Observable<TestResult> {\n const resultSubject = new Subject<TestResult>();\n const windowId = `test-harness-${++this.windowCounter}`;\n \n const windowSettings: WindowSettings = {\n title: data.title || 'AI Test Harness',\n content: AITestHarnessWindowComponent,\n width: this.convertToNumber(data.width) || 1200,\n height: this.convertToNumber(data.height) || 800,\n minWidth: 800,\n minHeight: 600,\n draggable: true,\n resizable: true,\n state: 'default',\n cssClass: 'test-harness-window-wrapper'\n };\n \n if (viewContainerRef) {\n windowSettings.appendTo = viewContainerRef;\n }\n \n const windowRef = this.windowService.open(windowSettings);\n this.openWindows.set(windowId, windowRef);\n \n // Pass data to the component\n const componentRef = windowRef.content as ComponentRef<AITestHarnessWindowComponent>;\n if (componentRef && componentRef.instance) {\n componentRef.instance.data = data;\n \n // Handle window close\n componentRef.instance.closeWindow.subscribe(() => {\n this.closeWindow(windowId);\n // Don't complete the observable here, as the window.result will handle it\n });\n }\n \n // Handle window close via close button\n windowRef.result.subscribe({\n next: (result) => {\n this.openWindows.delete(windowId);\n resultSubject.next({\n success: true,\n result: result\n });\n resultSubject.complete();\n },\n error: (error) => {\n this.openWindows.delete(windowId);\n resultSubject.next({\n success: false,\n error: error.message || 'Test failed'\n });\n resultSubject.complete();\n }\n });\n \n return resultSubject.asObservable();\n }\n \n /**\n * Closes a specific window\n */\n private closeWindow(windowId: string) {\n const windowRef = this.openWindows.get(windowId);\n if (windowRef) {\n try {\n windowRef.close();\n this.openWindows.delete(windowId);\n } catch (error) {\n console.error('Error closing window:', error);\n // Force delete from map even if close fails\n this.openWindows.delete(windowId);\n }\n }\n }\n \n /**\n * Closes all open windows\n */\n closeAllWindows() {\n this.openWindows.forEach((windowRef, id) => {\n windowRef.close();\n });\n this.openWindows.clear();\n }\n \n /**\n * Helper method to convert string dimensions to pixel numbers\n */\n private convertToNumber(value: string | number | undefined): number | undefined {\n if (!value) return undefined;\n if (typeof value === 'number') return value;\n \n // Handle percentage values\n if (value.endsWith('vw') || value.endsWith('vh')) {\n const percentage = parseFloat(value) / 100;\n if (value.endsWith('vw')) {\n return window.innerWidth * percentage;\n } else {\n return window.innerHeight * percentage;\n }\n }\n \n // Handle pixel values\n if (value.endsWith('px')) {\n return parseFloat(value);\n }\n \n // Try to parse as number\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n }\n}"]}
1
+ {"version":3,"file":"test-harness-window.service.js","sourceRoot":"","sources":["../../src/lib/test-harness-window.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;;AAW3C;;;;;GAKG;AAIH,MAAM,OAAO,wBAAwB;yHAAxB,wBAAwB;uEAAxB,wBAAwB,WAAxB,wBAAwB,mBAFrB,MAAM;;iFAET,wBAAwB;cAHpC,UAAU;eAAC;gBACR,UAAU,EAAE,MAAM;aACrB","sourcesContent":["import { Injectable } from '@angular/core';\n\nexport interface TestResult {\n success: boolean;\n result?: unknown;\n error?: string;\n executionTime?: number;\n tokensUsed?: number;\n cost?: number;\n}\n\n/**\n * @deprecated Use TestHarnessWindowManagerService instead.\n * This service previously used Kendo WindowService to open test harness windows.\n * It is retained only because the TestResult interface is exported from here\n * and consumed by other services.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestHarnessWindowService {\n}\n"]}
package/dist/module.d.ts CHANGED
@@ -8,21 +8,14 @@ import * as i6 from "./lib/agent-execution-monitor.component";
8
8
  import * as i7 from "./lib/agent-execution-node.component";
9
9
  import * as i8 from "@angular/common";
10
10
  import * as i9 from "@angular/forms";
11
- import * as i10 from "@progress/kendo-angular-buttons";
12
- import * as i11 from "@progress/kendo-angular-dialog";
13
- import * as i12 from "@progress/kendo-angular-dropdowns";
14
- import * as i13 from "@progress/kendo-angular-inputs";
15
- import * as i14 from "@progress/kendo-angular-layout";
16
- import * as i15 from "@progress/kendo-angular-notification";
17
- import * as i16 from "@progress/kendo-angular-indicators";
18
- import * as i17 from "@progress/kendo-angular-tooltip";
19
- import * as i18 from "@progress/kendo-angular-icons";
20
- import * as i19 from "@memberjunction/ng-container-directives";
21
- import * as i20 from "@memberjunction/ng-code-editor";
22
- import * as i21 from "@memberjunction/ng-shared-generic";
11
+ import * as i10 from "@memberjunction/ng-ui-components";
12
+ import * as i11 from "angular-split";
13
+ import * as i12 from "@memberjunction/ng-container-directives";
14
+ import * as i13 from "@memberjunction/ng-code-editor";
15
+ import * as i14 from "@memberjunction/ng-shared-generic";
23
16
  export declare class AITestHarnessModule {
24
17
  static ɵfac: i0.ɵɵFactoryDeclaration<AITestHarnessModule, never>;
25
- static ɵmod: i0.ɵɵNgModuleDeclaration<AITestHarnessModule, [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i5.JsonViewerWindowComponent, typeof i6.AgentExecutionMonitorComponent, typeof i7.ExecutionNodeComponent], [typeof i8.CommonModule, typeof i9.FormsModule, typeof i9.ReactiveFormsModule, typeof i10.ButtonsModule, typeof i11.DialogsModule, typeof i11.WindowModule, typeof i12.DropDownsModule, typeof i13.InputsModule, typeof i14.LayoutModule, typeof i15.NotificationModule, typeof i16.IndicatorsModule, typeof i17.TooltipsModule, typeof i18.IconsModule, typeof i19.ContainerDirectivesModule, typeof i20.CodeEditorModule, typeof i21.SharedGenericModule], [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i6.AgentExecutionMonitorComponent, typeof i5.JsonViewerWindowComponent]>;
18
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AITestHarnessModule, [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i5.JsonViewerWindowComponent, typeof i6.AgentExecutionMonitorComponent, typeof i7.ExecutionNodeComponent], [typeof i8.CommonModule, typeof i9.FormsModule, typeof i9.ReactiveFormsModule, typeof i10.MJWindowComponent, typeof i10.MJWindowTitlebarComponent, typeof i10.MJButtonDirective, typeof i10.MJDropdownComponent, typeof i10.MJNumericInputComponent, typeof i10.MJSwitchComponent, typeof i10.MJAccordionPanelComponent, typeof i10.MJDialogComponent, typeof i10.MJDialogTitlebarComponent, typeof i10.MJDialogActionsComponent, typeof i11.AngularSplitModule, typeof i12.ContainerDirectivesModule, typeof i13.CodeEditorModule, typeof i14.SharedGenericModule], [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i6.AgentExecutionMonitorComponent, typeof i5.JsonViewerWindowComponent]>;
26
19
  static ɵinj: i0.ɵɵInjectorDeclaration<AITestHarnessModule>;
27
20
  }
28
21
  //# sourceMappingURL=module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoCA,qBA6Ca,mBAAmB;yCAAnB,mBAAmB;0CAAnB,mBAAmB;0CAAnB,mBAAmB;CAAI"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAoCA,qBA6Ca,mBAAmB;yCAAnB,mBAAmB;0CAAnB,mBAAmB;0CAAnB,mBAAmB;CAAI"}