@memberjunction/ng-ai-test-harness 5.30.1 → 5.32.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,4 +1,5 @@
1
1
  import { EventEmitter, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
2
3
  import { MJWindowComponent } from '@memberjunction/ng-ui-components';
3
4
  import { MJAIAgentEntityExtended, MJAIPromptEntityExtended } from '@memberjunction/ai-core-plus';
4
5
  import { AITestHarnessComponent } from './ai-test-harness.component';
@@ -17,7 +18,7 @@ export interface CustomWindowData {
17
18
  selectedModelId?: string;
18
19
  mode?: 'agent' | 'prompt';
19
20
  }
20
- export declare class TestHarnessCustomWindowComponent implements OnInit, OnDestroy, AfterViewInit {
21
+ export declare class TestHarnessCustomWindowComponent extends BaseAngularComponent implements OnInit, OnDestroy, AfterViewInit {
21
22
  MjWindow: MJWindowComponent;
22
23
  TestHarness?: AITestHarnessComponent;
23
24
  Data: CustomWindowData;
@@ -1 +1 @@
1
- {"version":3,"file":"test-harness-custom-window.component.d.ts","sourceRoot":"","sources":["../../src/lib/test-harness-custom-window.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAa,SAAS,EAAE,aAAa,EAA6B,MAAM,eAAe,CAAC;AAC/I,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAEjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;;AAErE,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,qBAyKa,gCAAiC,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;IAC3C,QAAQ,EAAG,iBAAiB,CAAC;IACjB,WAAW,CAAC,EAAE,sBAAsB,CAAC;IAClF,IAAI,EAAE,gBAAgB,CAAM;IAC3B,WAAW,qBAA4B;IACvC,cAAc,qBAA4B;IAC1C,aAAa,qBAA4B;IACzC,oBAAoB;mBAAiC,MAAM;qBAAe,OAAO;OAAM;IAEjG,WAAW,SAAqB;IAChC,aAAa,UAAS;IACtB,KAAK,EAAE,MAAM,CAAQ;IACrB,MAAM,EAAE,MAAM,CAAO;IACrB,SAAS,EAAE,MAAM,CAAO;IACxB,UAAU,EAAE,MAAM,CAAO;IACzB,OAAO,UAAQ;IACf,KAAK,SAAM;IACX,WAAW,EAAE,SAAS,GAAG,WAAW,CAAa;IACjD,WAAW,UAAS;IACpB,WAAW,UAAS;IAGpB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAe;IACrC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,YAAY,CAAe;IAEnC,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAW;IAEnC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,sBAAsB,CAA+C;IAC7E,OAAO,CAAC,GAAG,CAA6B;IAExC,QAAQ;IAsCF,UAAU;YAgBF,SAAS;YAkBT,UAAU;IAkBxB,OAAO;IAIP,gBAAgB;IAIhB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW;IAK5C,cAAc;IAId,WAAW,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE;IAKlE,QAAQ;IAgBR,oBAAoB;IAgBpB,cAAc;IAed,OAAO,CAAC,eAAe;IAwBvB,eAAe;IAKf,OAAO,CAAC,sBAAsB;IAc9B,WAAW;yCA7OF,gCAAgC;2CAAhC,gCAAgC;CAkP5C"}
1
+ {"version":3,"file":"test-harness-custom-window.component.d.ts","sourceRoot":"","sources":["../../src/lib/test-harness-custom-window.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAa,SAAS,EAAE,aAAa,EAA6B,MAAM,eAAe,CAAC;AAC/I,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAEjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;;AAErE,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,qBAyKa,gCAAiC,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;IACxE,QAAQ,EAAG,iBAAiB,CAAC;IACjB,WAAW,CAAC,EAAE,sBAAsB,CAAC;IAClF,IAAI,EAAE,gBAAgB,CAAM;IAC3B,WAAW,qBAA4B;IACvC,cAAc,qBAA4B;IAC1C,aAAa,qBAA4B;IACzC,oBAAoB;mBAAiC,MAAM;qBAAe,OAAO;OAAM;IAEjG,WAAW,SAAqB;IAChC,aAAa,UAAS;IACtB,KAAK,EAAE,MAAM,CAAQ;IACrB,MAAM,EAAE,MAAM,CAAO;IACrB,SAAS,EAAE,MAAM,CAAO;IACxB,UAAU,EAAE,MAAM,CAAO;IACzB,OAAO,UAAQ;IACf,KAAK,SAAM;IACX,WAAW,EAAE,SAAS,GAAG,WAAW,CAAa;IACjD,WAAW,UAAS;IACpB,WAAW,UAAS;IAGpB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAe;IACrC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,YAAY,CAAe;IAEnC,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAW;IAEnC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,sBAAsB,CAA+C;IAC7E,OAAO,CAAC,GAAG,CAA6B;IAExC,QAAQ;IAsCF,UAAU;YAgBF,SAAS;YAkBT,UAAU;IAkBxB,OAAO;IAIP,gBAAgB;IAIhB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW;IAK5C,cAAc;IAId,WAAW,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE;IAKlE,QAAQ;IAgBR,oBAAoB;IAgBpB,cAAc;IAed,OAAO,CAAC,eAAe;IAwBvB,eAAe;IAKf,OAAO,CAAC,sBAAsB;IAc9B,WAAW;yCA7OF,gCAAgC;2CAAhC,gCAAgC;CAkP5C"}
@@ -1,5 +1,5 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef, inject } from '@angular/core';
2
- import { Metadata } from '@memberjunction/core';
2
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
3
  import { AITestHarnessComponent } from './ai-test-harness.component';
4
4
  import * as i0 from "@angular/core";
5
5
  import * as i1 from "@memberjunction/ng-ui-components";
@@ -47,8 +47,9 @@ function TestHarnessCustomWindowComponent_Conditional_19_Template(rf, ctx) { if
47
47
  const ctx_r1 = i0.ɵɵnextContext();
48
48
  i0.ɵɵproperty("entity", ctx_r1.Agent || ctx_r1.Prompt || null)("mode", ctx_r1.Mode)("isVisible", true);
49
49
  } }
50
- export class TestHarnessCustomWindowComponent {
50
+ export class TestHarnessCustomWindowComponent extends BaseAngularComponent {
51
51
  constructor() {
52
+ super(...arguments);
52
53
  this.Data = {};
53
54
  this.CloseWindow = new EventEmitter();
54
55
  this.MinimizeWindow = new EventEmitter();
@@ -71,7 +72,7 @@ export class TestHarnessCustomWindowComponent {
71
72
  this.originalTop = 100;
72
73
  this.originalLeft = 100;
73
74
  this.Mode = 'agent';
74
- this.metadata = new Metadata();
75
+ this.metadata = this.ProviderToUse;
75
76
  this.executionCheckInterval = null;
76
77
  this.cdr = inject(ChangeDetectorRef);
77
78
  }
@@ -267,14 +268,14 @@ export class TestHarnessCustomWindowComponent {
267
268
  clearInterval(this.executionCheckInterval);
268
269
  }
269
270
  }
270
- static { this.ɵfac = function TestHarnessCustomWindowComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestHarnessCustomWindowComponent)(); }; }
271
+ static { this.ɵfac = /*@__PURE__*/ (() => { let ɵTestHarnessCustomWindowComponent_BaseFactory; return function TestHarnessCustomWindowComponent_Factory(__ngFactoryType__) { return (ɵTestHarnessCustomWindowComponent_BaseFactory || (ɵTestHarnessCustomWindowComponent_BaseFactory = i0.ɵɵgetInheritedFactory(TestHarnessCustomWindowComponent)))(__ngFactoryType__ || TestHarnessCustomWindowComponent); }; })(); }
271
272
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestHarnessCustomWindowComponent, selectors: [["mj-test-harness-custom-window"]], viewQuery: function TestHarnessCustomWindowComponent_Query(rf, ctx) { if (rf & 1) {
272
273
  i0.ɵɵviewQuery(_c0, 5)(AITestHarnessComponent, 5);
273
274
  } if (rf & 2) {
274
275
  let _t;
275
276
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.MjWindow = _t.first);
276
277
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.TestHarness = _t.first);
277
- } }, inputs: { Data: "Data" }, outputs: { CloseWindow: "CloseWindow", MinimizeWindow: "MinimizeWindow", RestoreWindow: "RestoreWindow", ExecutionStateChange: "ExecutionStateChange" }, standalone: false, decls: 20, vars: 19, consts: [["mjWindow", ""], [3, "Close", "StateChange", "Resize", "Visible", "Title", "Width", "Height", "Top", "Left", "MinWidth", "MinHeight", "Draggable", "Resizable", "State"], [1, "window-title"], ["alt", "Agent logo", 1, "title-logo", 3, "src"], [1, "fa-solid", "fa-robot", "title-icon"], [1, "fa-solid", "fa-comment-dots", "title-icon"], [1, "window-actions"], ["title", "Minimize", 1, "window-action-btn", 3, "click"], [1, "fa-solid", "fa-window-minimize"], [1, "window-action-btn", 3, "click", "title"], [1, "fa-solid"], ["title", "Close", 1, "window-action-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "window-content"], [1, "loading-container"], [1, "error-container"], [3, "entity", "mode", "isVisible"], ["size", "large", 3, "text"], [1, "fa-solid", "fa-exclamation-triangle"], [3, "runOpened", "entity", "mode", "isVisible"]], template: function TestHarnessCustomWindowComponent_Template(rf, ctx) { if (rf & 1) {
278
+ } }, inputs: { Data: "Data" }, outputs: { CloseWindow: "CloseWindow", MinimizeWindow: "MinimizeWindow", RestoreWindow: "RestoreWindow", ExecutionStateChange: "ExecutionStateChange" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 20, vars: 19, consts: [["mjWindow", ""], [3, "Close", "StateChange", "Resize", "Visible", "Title", "Width", "Height", "Top", "Left", "MinWidth", "MinHeight", "Draggable", "Resizable", "State"], [1, "window-title"], ["alt", "Agent logo", 1, "title-logo", 3, "src"], [1, "fa-solid", "fa-robot", "title-icon"], [1, "fa-solid", "fa-comment-dots", "title-icon"], [1, "window-actions"], ["title", "Minimize", 1, "window-action-btn", 3, "click"], [1, "fa-solid", "fa-window-minimize"], [1, "window-action-btn", 3, "click", "title"], [1, "fa-solid"], ["title", "Close", 1, "window-action-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "window-content"], [1, "loading-container"], [1, "error-container"], [3, "entity", "mode", "isVisible"], ["size", "large", 3, "text"], [1, "fa-solid", "fa-exclamation-triangle"], [3, "runOpened", "entity", "mode", "isVisible"]], template: function TestHarnessCustomWindowComponent_Template(rf, ctx) { if (rf & 1) {
278
279
  const _r1 = i0.ɵɵgetCurrentView();
279
280
  i0.ɵɵelementStart(0, "mj-window", 1, 0);
280
281
  i0.ɵɵlistener("Close", function TestHarnessCustomWindowComponent_Template_mj_window_Close_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnClose()); })("StateChange", function TestHarnessCustomWindowComponent_Template_mj_window_StateChange_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnStateChange($event)); })("Resize", function TestHarnessCustomWindowComponent_Template_mj_window_Resize_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnWindowResize()); });
@@ -405,5 +406,5 @@ export class TestHarnessCustomWindowComponent {
405
406
  }], ExecutionStateChange: [{
406
407
  type: Output
407
408
  }] }); })();
408
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestHarnessCustomWindowComponent, { className: "TestHarnessCustomWindowComponent", filePath: "lib/test-harness-custom-window.component.ts", lineNumber: 191 }); })();
409
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestHarnessCustomWindowComponent, { className: "TestHarnessCustomWindowComponent", filePath: "lib/test-harness-custom-window.component.ts", lineNumber: 192 }); })();
409
410
  //# sourceMappingURL=test-harness-custom-window.component.js.map
@@ -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, 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"]}
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 { BaseAngularComponent } from '@memberjunction/ng-base-types';\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 extends BaseAngularComponent 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 = this.ProviderToUse;\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-ai-test-harness",
3
- "version": "5.30.1",
3
+ "version": "5.32.0",
4
4
  "description": "MemberJunction AI Test Harness - A reusable component for testing AI agents and prompts with beautiful UX",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -35,26 +35,27 @@
35
35
  "dependencies": {
36
36
  "@angular/platform-browser": "21.1.3",
37
37
  "@angular/router": "21.1.3",
38
- "@memberjunction/ai": "5.30.1",
39
- "@memberjunction/ai-core-plus": "5.30.1",
40
- "@memberjunction/ai-engine-base": "5.30.1",
41
- "@memberjunction/core": "5.30.1",
42
- "@memberjunction/core-entities": "5.30.1",
43
- "@memberjunction/global": "5.30.1",
44
- "@memberjunction/graphql-dataprovider": "5.30.1",
45
- "@memberjunction/ng-code-editor": "5.30.1",
46
- "@memberjunction/ng-container-directives": "5.30.1",
47
- "@memberjunction/ng-notifications": "5.30.1",
48
- "@memberjunction/ng-shared": "5.30.1",
49
- "@memberjunction/ng-shared-generic": "5.30.1",
50
- "@memberjunction/ng-ui-components": "5.30.1",
38
+ "@memberjunction/ai": "5.32.0",
39
+ "@memberjunction/ai-core-plus": "5.32.0",
40
+ "@memberjunction/ai-engine-base": "5.32.0",
41
+ "@memberjunction/core": "5.32.0",
42
+ "@memberjunction/core-entities": "5.32.0",
43
+ "@memberjunction/global": "5.32.0",
44
+ "@memberjunction/graphql-dataprovider": "5.32.0",
45
+ "@memberjunction/ng-code-editor": "5.32.0",
46
+ "@memberjunction/ng-container-directives": "5.32.0",
47
+ "@memberjunction/ng-notifications": "5.32.0",
48
+ "@memberjunction/ng-shared": "5.32.0",
49
+ "@memberjunction/ng-shared-generic": "5.32.0",
50
+ "@memberjunction/ng-ui-components": "5.32.0",
51
51
  "angular-split": "^20.0.0",
52
52
  "rxjs": "^7.8.2",
53
- "tslib": "^2.8.1"
53
+ "tslib": "^2.8.1",
54
+ "@memberjunction/ng-base-types": "5.32.0"
54
55
  },
55
56
  "sideEffects": true,
56
57
  "repository": {
57
58
  "type": "git",
58
59
  "url": "https://github.com/MemberJunction/MJ"
59
60
  }
60
- }
61
+ }