@memberjunction/ng-ai-test-harness 2.55.0 → 2.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/lib/agent-execution-monitor.component.d.ts +9 -0
  2. package/dist/lib/agent-execution-monitor.component.d.ts.map +1 -1
  3. package/dist/lib/agent-execution-monitor.component.js +68 -10
  4. package/dist/lib/agent-execution-monitor.component.js.map +1 -1
  5. package/dist/lib/agent-execution-node.component.d.ts +1 -0
  6. package/dist/lib/agent-execution-node.component.d.ts.map +1 -1
  7. package/dist/lib/agent-execution-node.component.js +88 -39
  8. package/dist/lib/agent-execution-node.component.js.map +1 -1
  9. package/dist/lib/ai-test-harness-dialog.service.d.ts +7 -14
  10. package/dist/lib/ai-test-harness-dialog.service.d.ts.map +1 -1
  11. package/dist/lib/ai-test-harness-dialog.service.js +21 -95
  12. package/dist/lib/ai-test-harness-dialog.service.js.map +1 -1
  13. package/dist/lib/ai-test-harness-window.component.d.ts +37 -0
  14. package/dist/lib/ai-test-harness-window.component.d.ts.map +1 -0
  15. package/dist/lib/ai-test-harness-window.component.js +171 -0
  16. package/dist/lib/ai-test-harness-window.component.js.map +1 -0
  17. package/dist/lib/ai-test-harness.component.d.ts +26 -1
  18. package/dist/lib/ai-test-harness.component.d.ts.map +1 -1
  19. package/dist/lib/ai-test-harness.component.js +299 -219
  20. package/dist/lib/ai-test-harness.component.js.map +1 -1
  21. package/dist/lib/test-harness-custom-window.component.d.ts +78 -0
  22. package/dist/lib/test-harness-custom-window.component.d.ts.map +1 -0
  23. package/dist/lib/test-harness-custom-window.component.js +528 -0
  24. package/dist/lib/test-harness-custom-window.component.js.map +1 -0
  25. package/dist/lib/test-harness-window-manager.service.d.ts +59 -0
  26. package/dist/lib/test-harness-window-manager.service.d.ts.map +1 -0
  27. package/dist/lib/test-harness-window-manager.service.js +163 -0
  28. package/dist/lib/test-harness-window-manager.service.js.map +1 -0
  29. package/dist/lib/test-harness-window.service.d.ts +73 -0
  30. package/dist/lib/test-harness-window.service.d.ts.map +1 -0
  31. package/dist/lib/test-harness-window.service.js +164 -0
  32. package/dist/lib/test-harness-window.service.js.map +1 -0
  33. package/dist/lib/window-dock.service.d.ts +32 -0
  34. package/dist/lib/window-dock.service.d.ts.map +1 -0
  35. package/dist/lib/window-dock.service.js +125 -0
  36. package/dist/lib/window-dock.service.js.map +1 -0
  37. package/dist/module.d.ts +19 -17
  38. package/dist/module.d.ts.map +1 -1
  39. package/dist/module.js +23 -4
  40. package/dist/module.js.map +1 -1
  41. package/dist/public-api.d.ts +6 -1
  42. package/dist/public-api.d.ts.map +1 -1
  43. package/dist/public-api.js +6 -1
  44. package/dist/public-api.js.map +1 -1
  45. package/package.json +8 -8
  46. package/dist/lib/test-harness-dialog.service.d.ts +0 -151
  47. package/dist/lib/test-harness-dialog.service.d.ts.map +0 -1
  48. package/dist/lib/test-harness-dialog.service.js +0 -234
  49. package/dist/lib/test-harness-dialog.service.js.map +0 -1
@@ -0,0 +1,163 @@
1
+ import { Injectable, createComponent } from '@angular/core';
2
+ import { TestHarnessCustomWindowComponent } from './test-harness-custom-window.component';
3
+ import { Subject } from 'rxjs';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "./window-dock.service";
6
+ /**
7
+ * Service for managing test harness windows for AI Agents and AI Prompts.
8
+ * Creates Kendo Window components with custom titlebar including minimize button.
9
+ */
10
+ export class TestHarnessWindowManagerService {
11
+ constructor(appRef, injector, dockService) {
12
+ this.appRef = appRef;
13
+ this.injector = injector;
14
+ this.dockService = dockService;
15
+ this.openWindows = new Map();
16
+ this.windowCounter = 0;
17
+ }
18
+ /**
19
+ * Opens the AI Agent Test Harness in a window
20
+ */
21
+ openAgentTestHarness(options) {
22
+ const data = {
23
+ agentId: options.agentId,
24
+ agent: options.agent,
25
+ title: options.title,
26
+ width: options.width || '90vw',
27
+ height: options.height || '90vh',
28
+ initialDataContext: options.initialDataContext,
29
+ initialTemplateData: options.initialTemplateData,
30
+ mode: 'agent'
31
+ };
32
+ return this.createWindow(data, options.viewContainerRef);
33
+ }
34
+ /**
35
+ * Opens the AI Prompt Test Harness in a window
36
+ */
37
+ openPromptTestHarness(options) {
38
+ const data = {
39
+ promptId: options.promptId,
40
+ prompt: options.prompt,
41
+ title: options.title || 'Test AI Prompt',
42
+ width: options.width || '90vw',
43
+ height: options.height || '90vh',
44
+ initialTemplateVariables: options.initialTemplateVariables,
45
+ selectedModelId: options.selectedModelId,
46
+ mode: 'prompt'
47
+ };
48
+ return this.createWindow(data, options.viewContainerRef);
49
+ }
50
+ /**
51
+ * Creates a test harness window
52
+ */
53
+ createWindow(data, viewContainerRef) {
54
+ const resultSubject = new Subject();
55
+ const windowId = `test-harness-${++this.windowCounter}`;
56
+ // Create component
57
+ const componentRef = createComponent(TestHarnessCustomWindowComponent, {
58
+ environmentInjector: this.appRef.injector,
59
+ elementInjector: this.injector,
60
+ hostElement: document.createElement('div')
61
+ });
62
+ // Set component data
63
+ componentRef.instance.data = data;
64
+ // Handle window events
65
+ componentRef.instance.closeWindow.subscribe(() => {
66
+ this.closeWindow(windowId);
67
+ resultSubject.next({
68
+ success: true
69
+ });
70
+ resultSubject.complete();
71
+ });
72
+ // Handle minimize event
73
+ componentRef.instance.minimizeWindow.subscribe(() => {
74
+ const title = componentRef.instance.windowTitle;
75
+ let icon = 'fa-solid fa-flask'; // default
76
+ let iconUrl;
77
+ // Get the appropriate icon based on mode and entity
78
+ if (componentRef.instance.mode === 'agent' && componentRef.instance.agent) {
79
+ // For agents, use LogoURL since AIAgentEntity doesn't have IconClass
80
+ if (componentRef.instance.agent.LogoURL) {
81
+ iconUrl = componentRef.instance.agent.LogoURL;
82
+ icon = undefined; // Clear icon when using URL
83
+ }
84
+ else {
85
+ icon = 'fa-solid fa-robot'; // Default agent icon
86
+ }
87
+ }
88
+ else if (componentRef.instance.mode === 'prompt') {
89
+ icon = 'fa-solid fa-comment-dots'; // Default prompt icon
90
+ }
91
+ // Add to dock with icon or iconUrl
92
+ this.dockService.addWindow(windowId, title, icon, () => {
93
+ // Restore callback
94
+ componentRef.instance.restoreFromMinimized();
95
+ }, iconUrl);
96
+ });
97
+ // Handle restore event
98
+ componentRef.instance.restoreWindow.subscribe(() => {
99
+ // Remove from dock
100
+ this.dockService.removeWindow(windowId);
101
+ });
102
+ // Handle execution state changes
103
+ componentRef.instance.executionStateChange.subscribe((state) => {
104
+ if (state.isExecuting) {
105
+ // Show indeterminate progress (spinning/pulsing)
106
+ this.dockService.updateWindowProgress(windowId, 50); // 50% for indeterminate animation
107
+ }
108
+ else {
109
+ // Clear progress
110
+ this.dockService.updateWindowProgress(windowId, undefined);
111
+ }
112
+ });
113
+ // Attach to DOM
114
+ if (viewContainerRef) {
115
+ // When using viewContainerRef, the view is automatically attached to Angular
116
+ viewContainerRef.insert(componentRef.hostView);
117
+ }
118
+ else {
119
+ // When appending to document.body, we need to manually attach to Angular
120
+ document.body.appendChild(componentRef.location.nativeElement);
121
+ this.appRef.attachView(componentRef.hostView);
122
+ }
123
+ // Store reference with info about how it was created
124
+ this.openWindows.set(windowId, {
125
+ componentRef,
126
+ usedViewContainerRef: !!viewContainerRef
127
+ });
128
+ return resultSubject.asObservable();
129
+ }
130
+ /**
131
+ * Closes a specific window
132
+ */
133
+ closeWindow(windowId) {
134
+ const windowInfo = this.openWindows.get(windowId);
135
+ if (windowInfo) {
136
+ // Remove from dock if minimized
137
+ this.dockService.removeWindow(windowId);
138
+ // Only detach from appRef if we attached it manually (not using viewContainerRef)
139
+ if (!windowInfo.usedViewContainerRef) {
140
+ this.appRef.detachView(windowInfo.componentRef.hostView);
141
+ }
142
+ windowInfo.componentRef.destroy();
143
+ this.openWindows.delete(windowId);
144
+ }
145
+ }
146
+ /**
147
+ * Closes all open windows
148
+ */
149
+ closeAllWindows() {
150
+ this.openWindows.forEach((windowInfo, id) => {
151
+ this.closeWindow(id);
152
+ });
153
+ }
154
+ static { this.ɵfac = function TestHarnessWindowManagerService_Factory(t) { return new (t || TestHarnessWindowManagerService)(i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.Injector), i0.ɵɵinject(i1.WindowDockService)); }; }
155
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TestHarnessWindowManagerService, factory: TestHarnessWindowManagerService.ɵfac, providedIn: 'root' }); }
156
+ }
157
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestHarnessWindowManagerService, [{
158
+ type: Injectable,
159
+ args: [{
160
+ providedIn: 'root'
161
+ }]
162
+ }], () => [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i1.WindowDockService }], null); })();
163
+ //# sourceMappingURL=test-harness-window-manager.service.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,73 @@
1
+ import { ViewContainerRef } from '@angular/core';
2
+ import { WindowService } from '@progress/kendo-angular-dialog';
3
+ import { AIAgentEntity, AIPromptEntity } from '@memberjunction/core-entities';
4
+ import { Observable } from 'rxjs';
5
+ import * as i0 from "@angular/core";
6
+ export interface TestResult {
7
+ success: boolean;
8
+ result?: any;
9
+ error?: string;
10
+ executionTime?: number;
11
+ tokensUsed?: number;
12
+ cost?: number;
13
+ }
14
+ /**
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.
22
+ */
23
+ 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?: AIAgentEntity;
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?: AIPromptEntity;
47
+ title?: string;
48
+ width?: string | number;
49
+ height?: string | number;
50
+ initialTemplateVariables?: Record<string, any>;
51
+ selectedModelId?: string;
52
+ viewContainerRef?: ViewContainerRef;
53
+ }): Observable<TestResult>;
54
+ /**
55
+ * Opens a test harness window
56
+ */
57
+ private openWindow;
58
+ /**
59
+ * Closes a specific window
60
+ */
61
+ private closeWindow;
62
+ /**
63
+ * Closes all open windows
64
+ */
65
+ closeAllWindows(): void;
66
+ /**
67
+ * Helper method to convert string dimensions to pixel numbers
68
+ */
69
+ private convertToNumber;
70
+ static ɵfac: i0.ɵɵFactoryDeclaration<TestHarnessWindowService, never>;
71
+ static ɵprov: i0.ɵɵInjectableDeclaration<TestHarnessWindowService>;
72
+ }
73
+ //# sourceMappingURL=test-harness-window.service.d.ts.map
@@ -0,0 +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,aAAa,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE9E,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,aAAa,CAAC;QACtB,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,cAAc,CAAC;QACxB,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,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACvC,GAAG,UAAU,CAAC,UAAU,CAAC;IAe1B;;OAEG;IACH,OAAO,CAAC,UAAU;IA8DlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,eAAe;IAOf;;OAEG;IACH,OAAO,CAAC,eAAe;yCArJd,wBAAwB;6CAAxB,wBAAwB;CA4KpC"}
@@ -0,0 +1,164 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { AITestHarnessWindowComponent } from './ai-test-harness-window.component';
3
+ import { Subject } from 'rxjs';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@progress/kendo-angular-dialog";
6
+ /**
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.
14
+ */
15
+ 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
+ const data = {
42
+ promptId: options.promptId,
43
+ prompt: options.prompt,
44
+ title: options.title || 'Test AI Prompt',
45
+ width: options.width || '90vw',
46
+ height: options.height || '90vh',
47
+ initialTemplateVariables: options.initialTemplateVariables,
48
+ selectedModelId: options.selectedModelId,
49
+ mode: 'prompt'
50
+ };
51
+ return this.openWindow(data, options.viewContainerRef);
52
+ }
53
+ /**
54
+ * Opens a test harness window
55
+ */
56
+ openWindow(data, viewContainerRef) {
57
+ const resultSubject = new Subject();
58
+ const windowId = `test-harness-${++this.windowCounter}`;
59
+ const windowSettings = {
60
+ title: data.title || 'AI Test Harness',
61
+ content: AITestHarnessWindowComponent,
62
+ width: this.convertToNumber(data.width) || 1200,
63
+ height: this.convertToNumber(data.height) || 800,
64
+ minWidth: 800,
65
+ minHeight: 600,
66
+ draggable: true,
67
+ resizable: true,
68
+ state: 'default',
69
+ cssClass: 'test-harness-window-wrapper'
70
+ };
71
+ if (viewContainerRef) {
72
+ windowSettings.appendTo = viewContainerRef;
73
+ }
74
+ const windowRef = this.windowService.open(windowSettings);
75
+ this.openWindows.set(windowId, windowRef);
76
+ // Pass data to the component
77
+ const componentRef = windowRef.content;
78
+ if (componentRef && componentRef.instance) {
79
+ componentRef.instance.data = data;
80
+ // Handle window close
81
+ componentRef.instance.closeWindow.subscribe(() => {
82
+ this.closeWindow(windowId);
83
+ resultSubject.next({
84
+ success: true
85
+ });
86
+ resultSubject.complete();
87
+ });
88
+ }
89
+ // Handle window close via close button
90
+ windowRef.result.subscribe({
91
+ next: (result) => {
92
+ this.openWindows.delete(windowId);
93
+ resultSubject.next({
94
+ success: true,
95
+ result: result
96
+ });
97
+ resultSubject.complete();
98
+ },
99
+ error: (error) => {
100
+ this.openWindows.delete(windowId);
101
+ resultSubject.next({
102
+ success: false,
103
+ error: error.message || 'Test failed'
104
+ });
105
+ resultSubject.complete();
106
+ }
107
+ });
108
+ return resultSubject.asObservable();
109
+ }
110
+ /**
111
+ * Closes a specific window
112
+ */
113
+ closeWindow(windowId) {
114
+ const windowRef = this.openWindows.get(windowId);
115
+ if (windowRef) {
116
+ windowRef.close();
117
+ this.openWindows.delete(windowId);
118
+ }
119
+ }
120
+ /**
121
+ * Closes all open windows
122
+ */
123
+ closeAllWindows() {
124
+ this.openWindows.forEach((windowRef, id) => {
125
+ windowRef.close();
126
+ });
127
+ this.openWindows.clear();
128
+ }
129
+ /**
130
+ * Helper method to convert string dimensions to pixel numbers
131
+ */
132
+ convertToNumber(value) {
133
+ if (!value)
134
+ return undefined;
135
+ if (typeof value === 'number')
136
+ return value;
137
+ // Handle percentage values
138
+ if (value.endsWith('vw') || value.endsWith('vh')) {
139
+ const percentage = parseFloat(value) / 100;
140
+ if (value.endsWith('vw')) {
141
+ return window.innerWidth * percentage;
142
+ }
143
+ else {
144
+ return window.innerHeight * percentage;
145
+ }
146
+ }
147
+ // Handle pixel values
148
+ if (value.endsWith('px')) {
149
+ return parseFloat(value);
150
+ }
151
+ // Try to parse as number
152
+ const parsed = parseFloat(value);
153
+ return isNaN(parsed) ? undefined : parsed;
154
+ }
155
+ static { this.ɵfac = function TestHarnessWindowService_Factory(t) { return new (t || TestHarnessWindowService)(i0.ɵɵinject(i1.WindowService)); }; }
156
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TestHarnessWindowService, factory: TestHarnessWindowService.ɵfac, providedIn: 'root' }); }
157
+ }
158
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestHarnessWindowService, [{
159
+ type: Injectable,
160
+ args: [{
161
+ providedIn: 'root'
162
+ }]
163
+ }], () => [{ type: i1.WindowService }], null); })();
164
+ //# sourceMappingURL=test-harness-window.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-harness-window.service.js","sourceRoot":"","sources":["../../src/lib/test-harness-window.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkC,MAAM,eAAe,CAAC;AAG3E,OAAO,EAAE,4BAA4B,EAA2B,MAAM,oCAAoC,CAAC;AAC3G,OAAO,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;;;AAW3C;;;;;;;;GAQG;AAIH,MAAM,OAAO,wBAAwB;IAIjC,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAHxC,gBAAW,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC3C,kBAAa,GAAG,CAAC,CAAC;IAEyB,CAAC;IAEpD;;OAEG;IACH,oBAAoB,CAAC,OASpB;QACG,MAAM,IAAI,GAA4B;YAClC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,IAAI,EAAE,OAAO;SAChB,CAAC;QAEF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,OASrB;QACG,MAAM,IAAI,GAA4B;YAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,gBAAgB;YACxC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;YAC1D,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,IAAI,EAAE,QAAQ;SACjB,CAAC;QAEF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,IAA6B,EAAE,gBAAmC;QACjF,MAAM,aAAa,GAAG,IAAI,OAAO,EAAc,CAAC;QAChD,MAAM,QAAQ,GAAG,gBAAgB,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAExD,MAAM,cAAc,GAAmB;YACnC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,iBAAiB;YACtC,OAAO,EAAE,4BAA4B;YACrC,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI;YAC/C,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG;YAChD,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,6BAA6B;SAC1C,CAAC;QAEF,IAAI,gBAAgB,EAAE,CAAC;YACnB,cAAc,CAAC,QAAQ,GAAG,gBAAgB,CAAC;QAC/C,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAE1C,6BAA6B;QAC7B,MAAM,YAAY,GAAG,SAAS,CAAC,OAAqD,CAAC;QACrF,IAAI,YAAY,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YACxC,YAAY,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;YAElC,sBAAsB;YACtB,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE;gBAC7C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC3B,aAAa,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,IAAI;iBAChB,CAAC,CAAC;gBACH,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACP,CAAC;QAED,uCAAuC;QACvC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC;YACvB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;gBACb,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAClC,aAAa,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,MAAM;iBACjB,CAAC,CAAC;gBACH,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;gBACb,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAClC,aAAa,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,aAAa;iBACxC,CAAC,CAAC;gBACH,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC;SACJ,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC,YAAY,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,QAAgB;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,SAAS,EAAE,CAAC;YACZ,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,eAAe;QACX,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE;YACvC,SAAS,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,KAAkC;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5C,2BAA2B;QAC3B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;YAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACJ,OAAO,MAAM,CAAC,WAAW,GAAG,UAAU,CAAC;YAC3C,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,CAAC;yFA3KQ,wBAAwB;uEAAxB,wBAAwB,WAAxB,wBAAwB,mBAFrB,MAAM;;iFAET,wBAAwB;cAHpC,UAAU;eAAC;gBACR,UAAU,EAAE,MAAM;aACrB"}
@@ -0,0 +1,32 @@
1
+ import { ApplicationRef, Injector } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export interface DockItem {
4
+ windowId: string;
5
+ title: string;
6
+ icon?: string;
7
+ iconUrl?: string;
8
+ restoreCallback: () => void;
9
+ progress?: number;
10
+ }
11
+ export declare class WindowDockComponent {
12
+ dockItems: DockItem[];
13
+ addItem(item: DockItem): void;
14
+ removeItem(windowId: string): void;
15
+ restoreWindow(item: DockItem): void;
16
+ getTruncatedTitle(title: string): string;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<WindowDockComponent, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<WindowDockComponent, "mj-window-dock", never, {}, {}, never, never, true, never>;
19
+ }
20
+ export declare class WindowDockService {
21
+ private appRef;
22
+ private injector;
23
+ private dockComponent?;
24
+ constructor(appRef: ApplicationRef, injector: Injector);
25
+ private ensureDockExists;
26
+ addWindow(windowId: string, title: string, icon?: string, restoreCallback?: () => void, iconUrl?: string, progress?: number): void;
27
+ removeWindow(windowId: string): void;
28
+ updateWindowProgress(windowId: string, progress: number | undefined): void;
29
+ static ɵfac: i0.ɵɵFactoryDeclaration<WindowDockService, never>;
30
+ static ɵprov: i0.ɵɵInjectableDeclaration<WindowDockService>;
31
+ }
32
+ //# sourceMappingURL=window-dock.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-dock.service.d.ts","sourceRoot":"","sources":["../../src/lib/window-dock.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,cAAc,EAAE,QAAQ,EAAmB,MAAM,eAAe,CAAC;;AAE/G,MAAM,WAAW,QAAQ;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAmGa,mBAAmB;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAM;IAE3B,OAAO,CAAC,IAAI,EAAE,QAAQ;IAItB,UAAU,CAAC,QAAQ,EAAE,MAAM;IAI3B,aAAa,CAAC,IAAI,EAAE,QAAQ;IAK5B,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;yCAhB/B,mBAAmB;2CAAnB,mBAAmB;CAsB/B;AAED,qBAGa,iBAAiB;IAItB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAJpB,OAAO,CAAC,aAAa,CAAC,CAAoC;gBAG9C,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,QAAQ;IAG9B,OAAO,CAAC,gBAAgB;IAcxB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAc3H,YAAY,CAAC,QAAQ,EAAE,MAAM;IAa7B,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS;yCAjD1D,iBAAiB;6CAAjB,iBAAiB;CAyD7B"}
@@ -0,0 +1,125 @@
1
+ import { Injectable, Component, createComponent } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ const _forTrack0 = ($index, $item) => $item.windowId;
4
+ function WindowDockComponent_For_2_Template(rf, ctx) { if (rf & 1) {
5
+ const _r1 = i0.ɵɵgetCurrentView();
6
+ i0.ɵɵelementStart(0, "div", 2);
7
+ i0.ɵɵlistener("click", function WindowDockComponent_For_2_Template_div_click_0_listener() { const item_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.restoreWindow(item_r2)); });
8
+ i0.ɵɵelement(1, "i");
9
+ i0.ɵɵelementStart(2, "span", 3);
10
+ i0.ɵɵtext(3);
11
+ i0.ɵɵelementEnd()();
12
+ } if (rf & 2) {
13
+ const item_r2 = ctx.$implicit;
14
+ const ctx_r2 = i0.ɵɵnextContext();
15
+ i0.ɵɵproperty("title", item_r2.title);
16
+ i0.ɵɵadvance();
17
+ i0.ɵɵclassMap(item_r2.icon);
18
+ i0.ɵɵadvance(2);
19
+ i0.ɵɵtextInterpolate(ctx_r2.getTruncatedTitle(item_r2.title));
20
+ } }
21
+ export class WindowDockComponent {
22
+ constructor() {
23
+ this.dockItems = [];
24
+ }
25
+ addItem(item) {
26
+ this.dockItems.push(item);
27
+ }
28
+ removeItem(windowId) {
29
+ this.dockItems = this.dockItems.filter(item => item.windowId !== windowId);
30
+ }
31
+ restoreWindow(item) {
32
+ item.restoreCallback();
33
+ this.removeItem(item.windowId);
34
+ }
35
+ getTruncatedTitle(title) {
36
+ // Remove "Test: " prefix for the label to save space
37
+ const cleanTitle = title.startsWith('Test: ') ? title.substring(6) : title;
38
+ // Truncate to first 8 characters for the label
39
+ return cleanTitle.length > 8 ? cleanTitle.substring(0, 8) + '...' : cleanTitle;
40
+ }
41
+ static { this.ɵfac = function WindowDockComponent_Factory(t) { return new (t || WindowDockComponent)(); }; }
42
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WindowDockComponent, selectors: [["mj-window-dock"]], standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 3, vars: 0, consts: [[1, "window-dock"], [1, "dock-item", 3, "title"], [1, "dock-item", 3, "click", "title"], [1, "dock-item-label"]], template: function WindowDockComponent_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "div", 0);
44
+ i0.ɵɵrepeaterCreate(1, WindowDockComponent_For_2_Template, 4, 4, "div", 1, _forTrack0);
45
+ i0.ɵɵelementEnd();
46
+ } if (rf & 2) {
47
+ i0.ɵɵadvance();
48
+ i0.ɵɵrepeater(ctx.dockItems);
49
+ } }, styles: ["[_nghost-%COMP%] {\n position: fixed;\n bottom: 10px;\n right: 10px;\n z-index: 10001;\n }\n \n .window-dock[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n background: #f0f4f8;\n border: 1px solid #d0d8e0;\n border-radius: 8px;\n padding: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n \n .dock-item[_ngcontent-%COMP%] {\n width: 64px;\n height: 72px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n padding: 8px 4px;\n \n &:hover {\n background-color: rgba(255, 255, 255, 0.8);\n transform: translateY(-2px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 28px;\n color: #2c5282;\n }\n \n .dock-item-label {\n font-size: 11px;\n color: #4a5568;\n text-align: center;\n line-height: 1.2;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .dock-item-progress {\n position: absolute;\n bottom: 2px;\n left: 2px;\n right: 2px;\n height: 3px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 2px;\n overflow: hidden;\n }\n \n .dock-item-progress-bar {\n height: 100%;\n background: #0076B6; \n\n transition: width 0.3s ease;\n }\n \n \n\n .dock-item-progress-bar[style*=\"width: 50%\"] {\n animation: _ngcontent-%COMP%_pulse-progress 1.5s ease-in-out infinite;\n }\n }\n \n @keyframes _ngcontent-%COMP%_pulse-progress {\n 0% { opacity: 0.6; width: 30%; }\n 50% { opacity: 1; width: 70%; }\n 100% { opacity: 0.6; width: 30%; }\n }"] }); }
50
+ }
51
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WindowDockComponent, [{
52
+ type: Component,
53
+ args: [{ selector: 'mj-window-dock', standalone: true, imports: [], template: `
54
+ <div class="window-dock">
55
+ @for (item of dockItems; track item.windowId) {
56
+ <div class="dock-item"
57
+ [title]="item.title"
58
+ (click)="restoreWindow(item)">
59
+ <i [class]="item.icon"></i>
60
+ <span class="dock-item-label">{{ getTruncatedTitle(item.title) }}</span>
61
+ </div>
62
+ }
63
+ </div>
64
+ `, styles: ["\n :host {\n position: fixed;\n bottom: 10px;\n right: 10px;\n z-index: 10001;\n }\n \n .window-dock {\n display: flex;\n gap: 12px;\n background: #f0f4f8;\n border: 1px solid #d0d8e0;\n border-radius: 8px;\n padding: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n \n .dock-item {\n width: 64px;\n height: 72px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n padding: 8px 4px;\n \n &:hover {\n background-color: rgba(255, 255, 255, 0.8);\n transform: translateY(-2px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 28px;\n color: #2c5282;\n }\n \n .dock-item-label {\n font-size: 11px;\n color: #4a5568;\n text-align: center;\n line-height: 1.2;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .dock-item-progress {\n position: absolute;\n bottom: 2px;\n left: 2px;\n right: 2px;\n height: 3px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 2px;\n overflow: hidden;\n }\n \n .dock-item-progress-bar {\n height: 100%;\n background: #0076B6; /* MJ blue color */\n transition: width 0.3s ease;\n }\n \n /* Pulse animation for indeterminate progress (50%) */\n .dock-item-progress-bar[style*=\"width: 50%\"] {\n animation: pulse-progress 1.5s ease-in-out infinite;\n }\n }\n \n @keyframes pulse-progress {\n 0% { opacity: 0.6; width: 30%; }\n 50% { opacity: 1; width: 70%; }\n 100% { opacity: 0.6; width: 30%; }\n }\n "] }]
65
+ }], null, null); })();
66
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WindowDockComponent, { className: "WindowDockComponent", filePath: "lib/window-dock.service.ts", lineNumber: 111 }); })();
67
+ export class WindowDockService {
68
+ constructor(appRef, injector) {
69
+ this.appRef = appRef;
70
+ this.injector = injector;
71
+ }
72
+ ensureDockExists() {
73
+ if (!this.dockComponent) {
74
+ // Create dock component
75
+ this.dockComponent = createComponent(WindowDockComponent, {
76
+ environmentInjector: this.appRef.injector,
77
+ elementInjector: this.injector
78
+ });
79
+ // Attach to DOM
80
+ document.body.appendChild(this.dockComponent.location.nativeElement);
81
+ this.appRef.attachView(this.dockComponent.hostView);
82
+ }
83
+ }
84
+ addWindow(windowId, title, icon, restoreCallback, iconUrl, progress) {
85
+ this.ensureDockExists();
86
+ if (this.dockComponent) {
87
+ this.dockComponent.instance.addItem({
88
+ windowId,
89
+ title,
90
+ icon,
91
+ iconUrl,
92
+ restoreCallback: restoreCallback || (() => { }),
93
+ progress
94
+ });
95
+ }
96
+ }
97
+ removeWindow(windowId) {
98
+ if (this.dockComponent) {
99
+ this.dockComponent.instance.removeItem(windowId);
100
+ // If no more items, remove the dock
101
+ if (this.dockComponent.instance.dockItems.length === 0) {
102
+ this.appRef.detachView(this.dockComponent.hostView);
103
+ this.dockComponent.destroy();
104
+ this.dockComponent = undefined;
105
+ }
106
+ }
107
+ }
108
+ updateWindowProgress(windowId, progress) {
109
+ if (this.dockComponent) {
110
+ const item = this.dockComponent.instance.dockItems.find(i => i.windowId === windowId);
111
+ if (item) {
112
+ item.progress = progress;
113
+ }
114
+ }
115
+ }
116
+ static { this.ɵfac = function WindowDockService_Factory(t) { return new (t || WindowDockService)(i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.Injector)); }; }
117
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: WindowDockService, factory: WindowDockService.ɵfac, providedIn: 'root' }); }
118
+ }
119
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WindowDockService, [{
120
+ type: Injectable,
121
+ args: [{
122
+ providedIn: 'root'
123
+ }]
124
+ }], () => [{ type: i0.ApplicationRef }, { type: i0.Injector }], null); })();
125
+ //# sourceMappingURL=window-dock.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-dock.service.js","sourceRoot":"","sources":["../../src/lib/window-dock.service.ts"],"names":[],"mappings":"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"}
package/dist/module.d.ts CHANGED
@@ -1,25 +1,27 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import * as i1 from "./lib/ai-test-harness.component";
3
3
  import * as i2 from "./lib/ai-test-harness-dialog.component";
4
- import * as i3 from "./lib/json-viewer-window.component";
5
- import * as i4 from "@angular/common";
6
- import * as i5 from "@angular/forms";
7
- import * as i6 from "@progress/kendo-angular-buttons";
8
- import * as i7 from "@progress/kendo-angular-dialog";
9
- import * as i8 from "@progress/kendo-angular-dropdowns";
10
- import * as i9 from "@progress/kendo-angular-inputs";
11
- import * as i10 from "@progress/kendo-angular-layout";
12
- import * as i11 from "@progress/kendo-angular-notification";
13
- import * as i12 from "@progress/kendo-angular-indicators";
14
- import * as i13 from "@progress/kendo-angular-tooltip";
15
- import * as i14 from "@progress/kendo-angular-icons";
16
- import * as i15 from "@memberjunction/ng-container-directives";
17
- import * as i16 from "@memberjunction/ng-code-editor";
18
- import * as i17 from "./lib/agent-execution-monitor.component";
19
- import * as i18 from "./lib/agent-execution-node.component";
4
+ import * as i3 from "./lib/ai-test-harness-window.component";
5
+ import * as i4 from "./lib/test-harness-custom-window.component";
6
+ import * as i5 from "./lib/json-viewer-window.component";
7
+ import * as i6 from "@angular/common";
8
+ import * as i7 from "@angular/forms";
9
+ import * as i8 from "@progress/kendo-angular-buttons";
10
+ import * as i9 from "@progress/kendo-angular-dialog";
11
+ import * as i10 from "@progress/kendo-angular-dropdowns";
12
+ import * as i11 from "@progress/kendo-angular-inputs";
13
+ import * as i12 from "@progress/kendo-angular-layout";
14
+ import * as i13 from "@progress/kendo-angular-notification";
15
+ import * as i14 from "@progress/kendo-angular-indicators";
16
+ import * as i15 from "@progress/kendo-angular-tooltip";
17
+ import * as i16 from "@progress/kendo-angular-icons";
18
+ import * as i17 from "@memberjunction/ng-container-directives";
19
+ import * as i18 from "@memberjunction/ng-code-editor";
20
+ import * as i19 from "./lib/agent-execution-monitor.component";
21
+ import * as i20 from "./lib/agent-execution-node.component";
20
22
  export declare class AITestHarnessModule {
21
23
  static ɵfac: i0.ɵɵFactoryDeclaration<AITestHarnessModule, never>;
22
- static ɵmod: i0.ɵɵNgModuleDeclaration<AITestHarnessModule, [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.JsonViewerWindowComponent], [typeof i4.CommonModule, typeof i5.FormsModule, typeof i5.ReactiveFormsModule, typeof i6.ButtonsModule, typeof i7.DialogsModule, typeof i8.DropDownsModule, typeof i9.InputsModule, typeof i10.LayoutModule, typeof i11.NotificationModule, typeof i12.IndicatorsModule, typeof i13.TooltipsModule, typeof i14.IconsModule, typeof i15.ContainerDirectivesModule, typeof i16.CodeEditorModule, typeof i17.AgentExecutionMonitorComponent, typeof i18.ExecutionNodeComponent], [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i17.AgentExecutionMonitorComponent, typeof i18.ExecutionNodeComponent, typeof i3.JsonViewerWindowComponent]>;
24
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AITestHarnessModule, [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i5.JsonViewerWindowComponent], [typeof i6.CommonModule, typeof i7.FormsModule, typeof i7.ReactiveFormsModule, typeof i8.ButtonsModule, typeof i9.DialogsModule, typeof i9.WindowModule, typeof i10.DropDownsModule, typeof i11.InputsModule, typeof i12.LayoutModule, typeof i13.NotificationModule, typeof i14.IndicatorsModule, typeof i15.TooltipsModule, typeof i16.IconsModule, typeof i17.ContainerDirectivesModule, typeof i18.CodeEditorModule, typeof i19.AgentExecutionMonitorComponent, typeof i20.ExecutionNodeComponent], [typeof i1.AITestHarnessComponent, typeof i2.AITestHarnessDialogComponent, typeof i3.AITestHarnessWindowComponent, typeof i4.TestHarnessCustomWindowComponent, typeof i19.AgentExecutionMonitorComponent, typeof i20.ExecutionNodeComponent, typeof i5.JsonViewerWindowComponent]>;
23
25
  static ɵinj: i0.ɵɵInjectorDeclaration<AITestHarnessModule>;
24
26
  }
25
27
  //# sourceMappingURL=module.d.ts.map