@memberjunction/ng-ai-test-harness 5.43.0 → 5.45.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.
- package/dist/lib/agent-execution-monitor.component.d.ts.map +1 -1
- package/dist/lib/agent-execution-monitor.component.dom.test.d.ts +2 -0
- package/dist/lib/agent-execution-monitor.component.dom.test.d.ts.map +1 -0
- package/dist/lib/agent-execution-monitor.component.dom.test.js +101 -0
- package/dist/lib/agent-execution-monitor.component.dom.test.js.map +1 -0
- package/dist/lib/agent-execution-monitor.component.js +13 -16
- package/dist/lib/agent-execution-monitor.component.js.map +1 -1
- package/dist/lib/agent-execution-node.component.dom.test.d.ts +2 -0
- package/dist/lib/agent-execution-node.component.dom.test.d.ts.map +1 -0
- package/dist/lib/agent-execution-node.component.dom.test.js +122 -0
- package/dist/lib/agent-execution-node.component.dom.test.js.map +1 -0
- package/dist/lib/ai-test-harness.component.d.ts +5 -3
- package/dist/lib/ai-test-harness.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness.component.js +208 -236
- package/dist/lib/ai-test-harness.component.js.map +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +7 -4
- package/dist/module.js.map +1 -1
- package/package.json +16 -15
|
@@ -5,12 +5,12 @@ import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
|
5
5
|
import { SharedService } from '@memberjunction/ng-shared';
|
|
6
6
|
import { Subject } from 'rxjs';
|
|
7
7
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
8
|
-
import { ParseJSONRecursive, UUIDsEqual } from '@memberjunction/global';
|
|
8
|
+
import { ParseJSONRecursive, UUIDsEqual, EscapeHTML } from '@memberjunction/global';
|
|
9
9
|
import * as i0 from "@angular/core";
|
|
10
10
|
import * as i1 from "@angular/platform-browser";
|
|
11
|
-
import * as i2 from "@
|
|
12
|
-
import * as i3 from "@angular/
|
|
13
|
-
import * as i4 from "@
|
|
11
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
12
|
+
import * as i3 from "@angular/common";
|
|
13
|
+
import * as i4 from "@angular/forms";
|
|
14
14
|
import * as i5 from "angular-split";
|
|
15
15
|
import * as i6 from "@memberjunction/ng-code-editor";
|
|
16
16
|
import * as i7 from "./json-viewer-window.component";
|
|
@@ -101,21 +101,14 @@ function AITestHarnessComponent_Conditional_0_Conditional_2_Template(rf, ctx) {
|
|
|
101
101
|
i0.ɵɵclassProp("fa-chevron-right", !ctx_r1.showSidebar)("fa-chevron-left", ctx_r1.showSidebar);
|
|
102
102
|
} }
|
|
103
103
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
104
|
-
i0.ɵɵ
|
|
105
|
-
i0.ɵɵelement(1, "i", 44);
|
|
106
|
-
i0.ɵɵelementStart(2, "h4");
|
|
107
|
-
i0.ɵɵtext(3, "Start a conversation");
|
|
108
|
-
i0.ɵɵelementEnd();
|
|
109
|
-
i0.ɵɵelementStart(4, "p");
|
|
110
|
-
i0.ɵɵtext(5, "Send a message to begin testing the AI agent");
|
|
111
|
-
i0.ɵɵelementEnd()();
|
|
104
|
+
i0.ɵɵelement(0, "mj-empty-state", 30);
|
|
112
105
|
} }
|
|
113
106
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
114
|
-
i0.ɵɵelement(0, "i",
|
|
107
|
+
i0.ɵɵelement(0, "i", 57);
|
|
115
108
|
i0.ɵɵtext(1, " You ");
|
|
116
109
|
} }
|
|
117
110
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
-
i0.ɵɵelement(0, "img",
|
|
111
|
+
i0.ɵɵelement(0, "img", 58);
|
|
119
112
|
} if (rf & 2) {
|
|
120
113
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
121
114
|
i0.ɵɵproperty("src", ctx_r1.getEntityLogoURL(), i0.ɵɵsanitizeUrl)("alt", ctx_r1.getEntityName() + " logo");
|
|
@@ -127,7 +120,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_
|
|
|
127
120
|
i0.ɵɵclassMap(ctx_r1.getEntityIconClass());
|
|
128
121
|
} }
|
|
129
122
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
-
i0.ɵɵconditionalCreate(0, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template, 1, 2, "img",
|
|
123
|
+
i0.ɵɵconditionalCreate(0, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template, 1, 2, "img", 58)(1, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Conditional_1_Template, 1, 2, "i", 15);
|
|
131
124
|
i0.ɵɵtext(2);
|
|
132
125
|
} if (rf & 2) {
|
|
133
126
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -136,8 +129,8 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_
|
|
|
136
129
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.getEntityName() || "Assistant", " ");
|
|
137
130
|
} }
|
|
138
131
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
139
|
-
i0.ɵɵelementStart(0, "span",
|
|
140
|
-
i0.ɵɵelement(1, "i",
|
|
132
|
+
i0.ɵɵelementStart(0, "span", 47);
|
|
133
|
+
i0.ɵɵelement(1, "i", 59);
|
|
141
134
|
i0.ɵɵtext(2);
|
|
142
135
|
i0.ɵɵelementEnd();
|
|
143
136
|
} if (rf & 2) {
|
|
@@ -147,7 +140,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_7_
|
|
|
147
140
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatElapsedTime(message_r5.elapsedTime), " ");
|
|
148
141
|
} }
|
|
149
142
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
150
|
-
i0.ɵɵelementStart(0, "span",
|
|
143
|
+
i0.ɵɵelementStart(0, "span", 48);
|
|
151
144
|
i0.ɵɵtext(1);
|
|
152
145
|
i0.ɵɵelementEnd();
|
|
153
146
|
} if (rf & 2) {
|
|
@@ -159,15 +152,15 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_8_
|
|
|
159
152
|
} }
|
|
160
153
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
161
154
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
162
|
-
i0.ɵɵelementStart(0, "button",
|
|
155
|
+
i0.ɵɵelementStart(0, "button", 60);
|
|
163
156
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const message_r5 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showRawJsonDialog(message_r5)); });
|
|
164
|
-
i0.ɵɵelement(1, "i",
|
|
157
|
+
i0.ɵɵelement(1, "i", 61);
|
|
165
158
|
i0.ɵɵelementEnd();
|
|
166
159
|
} }
|
|
167
160
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
168
|
-
i0.ɵɵelementStart(0, "div",
|
|
169
|
-
i0.ɵɵelement(1, "span",
|
|
170
|
-
i0.ɵɵelementStart(2, "span",
|
|
161
|
+
i0.ɵɵelementStart(0, "div", 53);
|
|
162
|
+
i0.ɵɵelement(1, "span", 62);
|
|
163
|
+
i0.ɵɵelementStart(2, "span", 63);
|
|
171
164
|
i0.ɵɵtext(3, "|");
|
|
172
165
|
i0.ɵɵelementEnd()();
|
|
173
166
|
} if (rf & 2) {
|
|
@@ -177,15 +170,15 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_13
|
|
|
177
170
|
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedStreamingContent(message_r5), i0.ɵɵsanitizeHtml);
|
|
178
171
|
} }
|
|
179
172
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
180
|
-
i0.ɵɵelement(0, "div",
|
|
173
|
+
i0.ɵɵelement(0, "div", 54);
|
|
181
174
|
} if (rf & 2) {
|
|
182
175
|
const message_r5 = i0.ɵɵnextContext().$implicit;
|
|
183
176
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
184
177
|
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedContent(message_r5), i0.ɵɵsanitizeHtml);
|
|
185
178
|
} }
|
|
186
179
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
187
|
-
i0.ɵɵelementStart(0, "div",
|
|
188
|
-
i0.ɵɵelement(1, "i",
|
|
180
|
+
i0.ɵɵelementStart(0, "div", 55);
|
|
181
|
+
i0.ɵɵelement(1, "i", 64);
|
|
189
182
|
i0.ɵɵtext(2);
|
|
190
183
|
i0.ɵɵelementEnd();
|
|
191
184
|
} if (rf & 2) {
|
|
@@ -194,8 +187,8 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_15
|
|
|
194
187
|
i0.ɵɵtextInterpolate1(" ", message_r5.error, " ");
|
|
195
188
|
} }
|
|
196
189
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
197
|
-
i0.ɵɵelementStart(0, "div",
|
|
198
|
-
i0.ɵɵelement(1, "mj-code-editor",
|
|
190
|
+
i0.ɵɵelementStart(0, "div", 69);
|
|
191
|
+
i0.ɵɵelement(1, "mj-code-editor", 70);
|
|
199
192
|
i0.ɵɵelementEnd();
|
|
200
193
|
} if (rf & 2) {
|
|
201
194
|
const message_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
@@ -205,16 +198,16 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16
|
|
|
205
198
|
} }
|
|
206
199
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
207
200
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
208
|
-
i0.ɵɵelementStart(0, "div",
|
|
201
|
+
i0.ɵɵelementStart(0, "div", 65)(1, "div", 66);
|
|
209
202
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r7); const message_r5 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.togglePayloadCollapse(message_r5)); });
|
|
210
|
-
i0.ɵɵelementStart(2, "span",
|
|
211
|
-
i0.ɵɵelement(3, "i",
|
|
203
|
+
i0.ɵɵelementStart(2, "span", 67);
|
|
204
|
+
i0.ɵɵelement(3, "i", 61);
|
|
212
205
|
i0.ɵɵtext(4, " Payload ");
|
|
213
206
|
i0.ɵɵelementEnd();
|
|
214
|
-
i0.ɵɵelementStart(5, "button",
|
|
207
|
+
i0.ɵɵelementStart(5, "button", 68);
|
|
215
208
|
i0.ɵɵelement(6, "i", 27);
|
|
216
209
|
i0.ɵɵelementEnd()();
|
|
217
|
-
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template, 2, 3, "div",
|
|
210
|
+
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template, 2, 3, "div", 69);
|
|
218
211
|
i0.ɵɵelementEnd();
|
|
219
212
|
} if (rf & 2) {
|
|
220
213
|
const message_r5 = i0.ɵɵnextContext().$implicit;
|
|
@@ -226,22 +219,22 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16
|
|
|
226
219
|
} }
|
|
227
220
|
function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
228
221
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
229
|
-
i0.ɵɵelementStart(0, "div", 31)(1, "div",
|
|
222
|
+
i0.ɵɵelementStart(0, "div", 31)(1, "div", 44)(2, "span", 45);
|
|
230
223
|
i0.ɵɵconditionalCreate(3, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_3_Template, 2, 0)(4, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_4_Template, 3, 2);
|
|
231
224
|
i0.ɵɵelementEnd();
|
|
232
|
-
i0.ɵɵelementStart(5, "span",
|
|
225
|
+
i0.ɵɵelementStart(5, "span", 46);
|
|
233
226
|
i0.ɵɵtext(6);
|
|
234
227
|
i0.ɵɵelementEnd();
|
|
235
|
-
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_7_Template, 3, 1, "span",
|
|
236
|
-
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_9_Template, 2, 0, "button",
|
|
228
|
+
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_7_Template, 3, 1, "span", 47)(8, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_8_Template, 2, 2, "span", 48);
|
|
229
|
+
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_9_Template, 2, 0, "button", 49);
|
|
237
230
|
i0.ɵɵelementEnd();
|
|
238
|
-
i0.ɵɵelementStart(10, "div",
|
|
231
|
+
i0.ɵɵelementStart(10, "div", 50)(11, "button", 51);
|
|
239
232
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Template_button_click_11_listener() { const message_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.copyMessage(message_r5)); });
|
|
240
|
-
i0.ɵɵelement(12, "i",
|
|
233
|
+
i0.ɵɵelement(12, "i", 52);
|
|
241
234
|
i0.ɵɵelementEnd();
|
|
242
|
-
i0.ɵɵconditionalCreate(13, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_13_Template, 4, 1, "div",
|
|
243
|
-
i0.ɵɵconditionalCreate(15, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_15_Template, 3, 1, "div",
|
|
244
|
-
i0.ɵɵconditionalCreate(16, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Template, 8, 7, "div",
|
|
235
|
+
i0.ɵɵconditionalCreate(13, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_13_Template, 4, 1, "div", 53)(14, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_14_Template, 1, 1, "div", 54);
|
|
236
|
+
i0.ɵɵconditionalCreate(15, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_15_Template, 3, 1, "div", 55);
|
|
237
|
+
i0.ɵɵconditionalCreate(16, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Conditional_16_Template, 8, 7, "div", 56);
|
|
245
238
|
i0.ɵɵelementEnd()();
|
|
246
239
|
} if (rf & 2) {
|
|
247
240
|
const message_r5 = ctx.$implicit;
|
|
@@ -263,20 +256,20 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Template(rf, c
|
|
|
263
256
|
i0.ɵɵconditional(ctx_r1.hasPayload(message_r5.payload) && ctx_r1.mode === "agent" && message_r5.role === "assistant" ? 16 : -1);
|
|
264
257
|
} }
|
|
265
258
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
266
|
-
i0.ɵɵelement(0, "i",
|
|
259
|
+
i0.ɵɵelement(0, "i", 59);
|
|
267
260
|
i0.ɵɵelementStart(1, "span");
|
|
268
261
|
i0.ɵɵtext(2, "Running...");
|
|
269
262
|
i0.ɵɵelementEnd();
|
|
270
263
|
} }
|
|
271
264
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
272
|
-
i0.ɵɵelement(0, "i",
|
|
265
|
+
i0.ɵɵelement(0, "i", 77);
|
|
273
266
|
i0.ɵɵelementStart(1, "span");
|
|
274
267
|
i0.ɵɵtext(2, "Re-Run");
|
|
275
268
|
i0.ɵɵelementEnd();
|
|
276
269
|
} }
|
|
277
270
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
278
271
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
279
|
-
i0.ɵɵelementStart(0, "button",
|
|
272
|
+
i0.ɵɵelementStart(0, "button", 76);
|
|
280
273
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.executeRerun()); });
|
|
281
274
|
i0.ɵɵconditionalCreate(1, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Conditional_1_Template, 3, 0)(2, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Conditional_2_Template, 3, 0);
|
|
282
275
|
i0.ɵɵelementEnd();
|
|
@@ -288,9 +281,9 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Condit
|
|
|
288
281
|
} }
|
|
289
282
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
290
283
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
291
|
-
i0.ɵɵelementStart(0, "button",
|
|
284
|
+
i0.ɵɵelementStart(0, "button", 78);
|
|
292
285
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.resetToOriginalMessages()); });
|
|
293
|
-
i0.ɵɵelement(1, "i",
|
|
286
|
+
i0.ɵɵelement(1, "i", 79);
|
|
294
287
|
i0.ɵɵelementStart(2, "span");
|
|
295
288
|
i0.ɵɵtext(3, "Reset Messages");
|
|
296
289
|
i0.ɵɵelementEnd()();
|
|
@@ -299,8 +292,8 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Condit
|
|
|
299
292
|
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
300
293
|
} }
|
|
301
294
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
302
|
-
i0.ɵɵelementStart(0, "div", 33)(1, "div",
|
|
303
|
-
i0.ɵɵelement(2, "i",
|
|
295
|
+
i0.ɵɵelementStart(0, "div", 33)(1, "div", 71);
|
|
296
|
+
i0.ɵɵelement(2, "i", 72);
|
|
304
297
|
i0.ɵɵelementStart(3, "span");
|
|
305
298
|
i0.ɵɵtext(4, "Messages from Prompt Run ");
|
|
306
299
|
i0.ɵɵelementStart(5, "strong");
|
|
@@ -308,8 +301,8 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Templa
|
|
|
308
301
|
i0.ɵɵelementEnd();
|
|
309
302
|
i0.ɵɵtext(7, " loaded above");
|
|
310
303
|
i0.ɵɵelementEnd()();
|
|
311
|
-
i0.ɵɵelementStart(8, "div",
|
|
312
|
-
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Template, 3, 2, "button",
|
|
304
|
+
i0.ɵɵelementStart(8, "div", 73);
|
|
305
|
+
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_9_Template, 3, 2, "button", 74)(10, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Conditional_10_Template, 4, 1, "button", 75);
|
|
313
306
|
i0.ɵɵelementEnd()();
|
|
314
307
|
} if (rf & 2) {
|
|
315
308
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -319,20 +312,20 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_9_Templa
|
|
|
319
312
|
i0.ɵɵconditional(!ctx_r1.hasExecutedRerun ? 9 : 10);
|
|
320
313
|
} }
|
|
321
314
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
322
|
-
i0.ɵɵelement(0, "i",
|
|
315
|
+
i0.ɵɵelement(0, "i", 59);
|
|
323
316
|
} }
|
|
324
317
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
325
|
-
i0.ɵɵelement(0, "i",
|
|
318
|
+
i0.ɵɵelement(0, "i", 82);
|
|
326
319
|
} }
|
|
327
320
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
328
321
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
329
|
-
i0.ɵɵelementStart(0, "div", 34)(1, "textarea",
|
|
322
|
+
i0.ɵɵelementStart(0, "div", 34)(1, "textarea", 80, 2);
|
|
330
323
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Template_textarea_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.currentUserMessage, $event) || (ctx_r1.currentUserMessage = $event); return i0.ɵɵresetView($event); });
|
|
331
324
|
i0.ɵɵlistener("keypress", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Template_textarea_keypress_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.handleKeyPress($event)); });
|
|
332
325
|
i0.ɵɵelementEnd();
|
|
333
|
-
i0.ɵɵelementStart(3, "button",
|
|
326
|
+
i0.ɵɵelementStart(3, "button", 81);
|
|
334
327
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.sendMessage()); });
|
|
335
|
-
i0.ɵɵconditionalCreate(4, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Conditional_4_Template, 1, 0, "i",
|
|
328
|
+
i0.ɵɵconditionalCreate(4, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Conditional_4_Template, 1, 0, "i", 59)(5, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_10_Conditional_5_Template, 1, 0, "i", 82);
|
|
336
329
|
i0.ɵɵelementEnd()();
|
|
337
330
|
} if (rf & 2) {
|
|
338
331
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -348,17 +341,17 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_14_Templ
|
|
|
348
341
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
349
342
|
i0.ɵɵelementStart(0, "button", 37);
|
|
350
343
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectTab("agentVariables")); });
|
|
351
|
-
i0.ɵɵelement(1, "i",
|
|
344
|
+
i0.ɵɵelement(1, "i", 61);
|
|
352
345
|
i0.ɵɵtext(2, " Agent Variables ");
|
|
353
346
|
i0.ɵɵelementEnd();
|
|
354
|
-
i0.ɵɵelementStart(3, "button",
|
|
347
|
+
i0.ɵɵelementStart(3, "button", 83);
|
|
355
348
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_14_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectTab("executionMonitor")); });
|
|
356
|
-
i0.ɵɵelement(4, "i",
|
|
349
|
+
i0.ɵɵelement(4, "i", 84);
|
|
357
350
|
i0.ɵɵtext(5, " Execution Monitor ");
|
|
358
351
|
i0.ɵɵelementEnd();
|
|
359
352
|
i0.ɵɵelementStart(6, "button", 37);
|
|
360
353
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_14_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectTab("agentSettings")); });
|
|
361
|
-
i0.ɵɵelement(7, "i",
|
|
354
|
+
i0.ɵɵelement(7, "i", 85);
|
|
362
355
|
i0.ɵɵtext(8, " Settings ");
|
|
363
356
|
i0.ɵɵelementEnd();
|
|
364
357
|
} if (rf & 2) {
|
|
@@ -373,14 +366,14 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_14_Templ
|
|
|
373
366
|
} }
|
|
374
367
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
375
368
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
376
|
-
i0.ɵɵelementStart(0, "button",
|
|
369
|
+
i0.ɵɵelementStart(0, "button", 83);
|
|
377
370
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectTab("templateVariables")); });
|
|
378
|
-
i0.ɵɵelement(1, "i",
|
|
371
|
+
i0.ɵɵelement(1, "i", 61);
|
|
379
372
|
i0.ɵɵtext(2, " Template Variables ");
|
|
380
373
|
i0.ɵɵelementEnd();
|
|
381
|
-
i0.ɵɵelementStart(3, "button",
|
|
374
|
+
i0.ɵɵelementStart(3, "button", 83);
|
|
382
375
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_15_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.selectTab("modelSettings")); });
|
|
383
|
-
i0.ɵɵelement(4, "i",
|
|
376
|
+
i0.ɵɵelement(4, "i", 85);
|
|
384
377
|
i0.ɵɵtext(5, " Model Settings ");
|
|
385
378
|
i0.ɵɵelementEnd();
|
|
386
379
|
} if (rf & 2) {
|
|
@@ -399,24 +392,22 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_19_Templ
|
|
|
399
392
|
i0.ɵɵtextInterpolate(ctx_r1.savedConversations.length);
|
|
400
393
|
} }
|
|
401
394
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
402
|
-
i0.ɵɵ
|
|
403
|
-
i0.ɵɵtext(2, "No variables defined. Click \"Add Variable\" to get started.");
|
|
404
|
-
i0.ɵɵelementEnd()();
|
|
395
|
+
i0.ɵɵelement(0, "mj-empty-state", 88);
|
|
405
396
|
} }
|
|
406
397
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
407
398
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
408
|
-
i0.ɵɵelementStart(0, "div",
|
|
399
|
+
i0.ɵɵelementStart(0, "div", 89)(1, "input", 92);
|
|
409
400
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template_input_ngModelChange_1_listener($event) { const variable_r15 = i0.ɵɵrestoreView(_r14).$implicit; i0.ɵɵtwoWayBindingSet(variable_r15.name, $event) || (variable_r15.name = $event); return i0.ɵɵresetView($event); });
|
|
410
401
|
i0.ɵɵelementEnd();
|
|
411
|
-
i0.ɵɵelementStart(2, "mj-dropdown",
|
|
402
|
+
i0.ɵɵelementStart(2, "mj-dropdown", 93);
|
|
412
403
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template_mj_dropdown_ngModelChange_2_listener($event) { const variable_r15 = i0.ɵɵrestoreView(_r14).$implicit; i0.ɵɵtwoWayBindingSet(variable_r15.type, $event) || (variable_r15.type = $event); return i0.ɵɵresetView($event); });
|
|
413
404
|
i0.ɵɵelementEnd();
|
|
414
|
-
i0.ɵɵelementStart(3, "input",
|
|
405
|
+
i0.ɵɵelementStart(3, "input", 94);
|
|
415
406
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template_input_ngModelChange_3_listener($event) { const variable_r15 = i0.ɵɵrestoreView(_r14).$implicit; i0.ɵɵtwoWayBindingSet(variable_r15.value, $event) || (variable_r15.value = $event); return i0.ɵɵresetView($event); });
|
|
416
407
|
i0.ɵɵelementEnd();
|
|
417
|
-
i0.ɵɵelementStart(4, "button",
|
|
408
|
+
i0.ɵɵelementStart(4, "button", 95);
|
|
418
409
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template_button_click_4_listener() { const $index_r16 = i0.ɵɵrestoreView(_r14).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.removeAgentVariable($index_r16)); });
|
|
419
|
-
i0.ɵɵelement(5, "i",
|
|
410
|
+
i0.ɵɵelement(5, "i", 96);
|
|
420
411
|
i0.ɵɵelementEnd()();
|
|
421
412
|
} if (rf & 2) {
|
|
422
413
|
const variable_r15 = ctx.$implicit;
|
|
@@ -435,19 +426,19 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9
|
|
|
435
426
|
} }
|
|
436
427
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
437
428
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
438
|
-
i0.ɵɵelementStart(0, "div", 41)(1, "div",
|
|
429
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 86)(2, "h4");
|
|
439
430
|
i0.ɵɵtext(3, "Agent Variables");
|
|
440
431
|
i0.ɵɵelementEnd();
|
|
441
432
|
i0.ɵɵelementStart(4, "p");
|
|
442
433
|
i0.ɵɵtext(5, "Variables available during agent execution and template rendering");
|
|
443
434
|
i0.ɵɵelementEnd()();
|
|
444
|
-
i0.ɵɵelementStart(6, "div",
|
|
445
|
-
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Conditional_7_Template,
|
|
446
|
-
i0.ɵɵrepeaterCreate(8, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template, 6, 19, "div",
|
|
435
|
+
i0.ɵɵelementStart(6, "div", 87);
|
|
436
|
+
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Conditional_7_Template, 1, 0, "mj-empty-state", 88);
|
|
437
|
+
i0.ɵɵrepeaterCreate(8, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_For_9_Template, 6, 19, "div", 89, i0.ɵɵrepeaterTrackByIndex);
|
|
447
438
|
i0.ɵɵelementEnd();
|
|
448
|
-
i0.ɵɵelementStart(10, "button",
|
|
439
|
+
i0.ɵɵelementStart(10, "button", 90);
|
|
449
440
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.addAgentVariable()); });
|
|
450
|
-
i0.ɵɵelement(11, "i",
|
|
441
|
+
i0.ɵɵelement(11, "i", 91);
|
|
451
442
|
i0.ɵɵtext(12, " Add Variable ");
|
|
452
443
|
i0.ɵɵelementEnd()();
|
|
453
444
|
} if (rf & 2) {
|
|
@@ -461,7 +452,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_21_Templ
|
|
|
461
452
|
} }
|
|
462
453
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
463
454
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
464
|
-
i0.ɵɵelementStart(0, "div", 42)(1, "mj-agent-execution-monitor",
|
|
455
|
+
i0.ɵɵelementStart(0, "div", 42)(1, "mj-agent-execution-monitor", 97);
|
|
465
456
|
i0.ɵɵlistener("viewRunClick", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_22_Template_mj_agent_execution_monitor_viewRunClick_1_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.navigateToAgentRun($event)); });
|
|
466
457
|
i0.ɵɵelementEnd()();
|
|
467
458
|
} if (rf & 2) {
|
|
@@ -493,19 +484,19 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Condi
|
|
|
493
484
|
} }
|
|
494
485
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
495
486
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
496
|
-
i0.ɵɵelementStart(0, "div", 41)(1, "div",
|
|
487
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 86)(2, "h4");
|
|
497
488
|
i0.ɵɵtext(3, "Agent Settings");
|
|
498
489
|
i0.ɵɵelementEnd();
|
|
499
490
|
i0.ɵɵelementStart(4, "p");
|
|
500
491
|
i0.ɵɵtext(5, "Configure agent execution parameters");
|
|
501
492
|
i0.ɵɵelementEnd()();
|
|
502
|
-
i0.ɵɵelementStart(6, "div",
|
|
493
|
+
i0.ɵɵelementStart(6, "div", 98)(7, "div", 99)(8, "label");
|
|
503
494
|
i0.ɵɵtext(9, "AI Configuration");
|
|
504
495
|
i0.ɵɵelementEnd();
|
|
505
|
-
i0.ɵɵelementStart(10, "mj-dropdown",
|
|
496
|
+
i0.ɵɵelementStart(10, "mj-dropdown", 100);
|
|
506
497
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Template_mj_dropdown_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.agentConfigurationId, $event) || (ctx_r1.agentConfigurationId = $event); return i0.ɵɵresetView($event); });
|
|
507
498
|
i0.ɵɵelementEnd();
|
|
508
|
-
i0.ɵɵelementStart(11, "div",
|
|
499
|
+
i0.ɵɵelementStart(11, "div", 101);
|
|
509
500
|
i0.ɵɵconditionalCreate(12, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Conditional_12_Template, 2, 0)(13, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Conditional_13_Template, 1, 0);
|
|
510
501
|
i0.ɵɵelementEnd()()()();
|
|
511
502
|
} if (rf & 2) {
|
|
@@ -518,18 +509,18 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_23_Templ
|
|
|
518
509
|
} }
|
|
519
510
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
520
511
|
const _r21 = i0.ɵɵgetCurrentView();
|
|
521
|
-
i0.ɵɵelementStart(0, "div",
|
|
512
|
+
i0.ɵɵelementStart(0, "div", 89)(1, "input", 92);
|
|
522
513
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template_input_ngModelChange_1_listener($event) { const variable_r22 = i0.ɵɵrestoreView(_r21).$implicit; i0.ɵɵtwoWayBindingSet(variable_r22.name, $event) || (variable_r22.name = $event); return i0.ɵɵresetView($event); });
|
|
523
514
|
i0.ɵɵelementEnd();
|
|
524
|
-
i0.ɵɵelementStart(2, "mj-dropdown",
|
|
515
|
+
i0.ɵɵelementStart(2, "mj-dropdown", 93);
|
|
525
516
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template_mj_dropdown_ngModelChange_2_listener($event) { const variable_r22 = i0.ɵɵrestoreView(_r21).$implicit; i0.ɵɵtwoWayBindingSet(variable_r22.type, $event) || (variable_r22.type = $event); return i0.ɵɵresetView($event); });
|
|
526
517
|
i0.ɵɵelementEnd();
|
|
527
|
-
i0.ɵɵelementStart(3, "input",
|
|
518
|
+
i0.ɵɵelementStart(3, "input", 94);
|
|
528
519
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template_input_ngModelChange_3_listener($event) { const variable_r22 = i0.ɵɵrestoreView(_r21).$implicit; i0.ɵɵtwoWayBindingSet(variable_r22.value, $event) || (variable_r22.value = $event); return i0.ɵɵresetView($event); });
|
|
529
520
|
i0.ɵɵelementEnd();
|
|
530
|
-
i0.ɵɵelementStart(4, "button",
|
|
521
|
+
i0.ɵɵelementStart(4, "button", 103);
|
|
531
522
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template_button_click_4_listener() { const $index_r23 = i0.ɵɵrestoreView(_r21).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.removeTemplateVariable($index_r23)); });
|
|
532
|
-
i0.ɵɵelement(5, "i",
|
|
523
|
+
i0.ɵɵelement(5, "i", 96);
|
|
533
524
|
i0.ɵɵelementEnd()();
|
|
534
525
|
} if (rf & 2) {
|
|
535
526
|
const variable_r22 = ctx.$implicit;
|
|
@@ -546,18 +537,18 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8
|
|
|
546
537
|
} }
|
|
547
538
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
548
539
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
549
|
-
i0.ɵɵelementStart(0, "div", 41)(1, "div",
|
|
540
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 86)(2, "h4");
|
|
550
541
|
i0.ɵɵtext(3, "Template Variables");
|
|
551
542
|
i0.ɵɵelementEnd();
|
|
552
543
|
i0.ɵɵelementStart(4, "p");
|
|
553
544
|
i0.ɵɵtext(5, "Variables for prompt template rendering");
|
|
554
545
|
i0.ɵɵelementEnd()();
|
|
555
|
-
i0.ɵɵelementStart(6, "div",
|
|
556
|
-
i0.ɵɵrepeaterCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template, 6, 18, "div",
|
|
546
|
+
i0.ɵɵelementStart(6, "div", 87);
|
|
547
|
+
i0.ɵɵrepeaterCreate(7, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_For_8_Template, 6, 18, "div", 89, i0.ɵɵrepeaterTrackByIndex);
|
|
557
548
|
i0.ɵɵelementEnd();
|
|
558
|
-
i0.ɵɵelementStart(9, "button",
|
|
549
|
+
i0.ɵɵelementStart(9, "button", 102);
|
|
559
550
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_24_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.addTemplateVariable()); });
|
|
560
|
-
i0.ɵɵelement(10, "i",
|
|
551
|
+
i0.ɵɵelement(10, "i", 91);
|
|
561
552
|
i0.ɵɵtext(11, " Add Variable ");
|
|
562
553
|
i0.ɵɵelementEnd()();
|
|
563
554
|
} if (rf & 2) {
|
|
@@ -598,10 +589,10 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Condi
|
|
|
598
589
|
} }
|
|
599
590
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_86_Template(rf, ctx) { if (rf & 1) {
|
|
600
591
|
const _r26 = i0.ɵɵgetCurrentView();
|
|
601
|
-
i0.ɵɵelementStart(0, "div",
|
|
592
|
+
i0.ɵɵelementStart(0, "div", 99)(1, "label", 127);
|
|
602
593
|
i0.ɵɵtext(2, " Top Log Probs ");
|
|
603
594
|
i0.ɵɵelementEnd();
|
|
604
|
-
i0.ɵɵelementStart(3, "mj-numeric-input",
|
|
595
|
+
i0.ɵɵelementStart(3, "mj-numeric-input", 128);
|
|
605
596
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_86_Template_mj_numeric_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.topLogProbs, $event) || (ctx_r1.advancedParams.topLogProbs = $event); return i0.ɵɵresetView($event); });
|
|
606
597
|
i0.ɵɵelementEnd()();
|
|
607
598
|
} if (rf & 2) {
|
|
@@ -612,126 +603,126 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Condi
|
|
|
612
603
|
} }
|
|
613
604
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
614
605
|
const _r24 = i0.ɵɵgetCurrentView();
|
|
615
|
-
i0.ɵɵelementStart(0, "div", 43)(1, "div",
|
|
606
|
+
i0.ɵɵelementStart(0, "div", 43)(1, "div", 86)(2, "h4");
|
|
616
607
|
i0.ɵɵtext(3, "Model Settings");
|
|
617
608
|
i0.ɵɵelementEnd();
|
|
618
609
|
i0.ɵɵelementStart(4, "p");
|
|
619
610
|
i0.ɵɵtext(5, "Configure AI model parameters");
|
|
620
611
|
i0.ɵɵelementEnd();
|
|
621
|
-
i0.ɵɵelementStart(6, "button",
|
|
612
|
+
i0.ɵɵelementStart(6, "button", 104);
|
|
622
613
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.resetToPromptDefaults()); });
|
|
623
|
-
i0.ɵɵelement(7, "i",
|
|
614
|
+
i0.ɵɵelement(7, "i", 105);
|
|
624
615
|
i0.ɵɵelementEnd()();
|
|
625
|
-
i0.ɵɵelementStart(8, "div",
|
|
616
|
+
i0.ɵɵelementStart(8, "div", 98)(9, "div", 99)(10, "label");
|
|
626
617
|
i0.ɵɵtext(11, "AI Model");
|
|
627
618
|
i0.ɵɵelementEnd();
|
|
628
|
-
i0.ɵɵelementStart(12, "mj-dropdown",
|
|
619
|
+
i0.ɵɵelementStart(12, "mj-dropdown", 106);
|
|
629
620
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_dropdown_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedModelId, $event) || (ctx_r1.selectedModelId = $event); return i0.ɵɵresetView($event); });
|
|
630
621
|
i0.ɵɵlistener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_dropdown_ngModelChange_12_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onModelSelectionChange()); });
|
|
631
622
|
i0.ɵɵelementEnd()();
|
|
632
|
-
i0.ɵɵelementStart(13, "div",
|
|
623
|
+
i0.ɵɵelementStart(13, "div", 99)(14, "label");
|
|
633
624
|
i0.ɵɵtext(15, "AI Vendor");
|
|
634
625
|
i0.ɵɵelementEnd();
|
|
635
|
-
i0.ɵɵelementStart(16, "mj-dropdown",
|
|
626
|
+
i0.ɵɵelementStart(16, "mj-dropdown", 107);
|
|
636
627
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_dropdown_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedVendorId, $event) || (ctx_r1.selectedVendorId = $event); return i0.ɵɵresetView($event); });
|
|
637
628
|
i0.ɵɵelementEnd();
|
|
638
|
-
i0.ɵɵelementStart(17, "div",
|
|
629
|
+
i0.ɵɵelementStart(17, "div", 101);
|
|
639
630
|
i0.ɵɵconditionalCreate(18, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_18_Template, 1, 0)(19, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_19_Template, 1, 0)(20, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_20_Template, 1, 0);
|
|
640
631
|
i0.ɵɵelementEnd()();
|
|
641
|
-
i0.ɵɵelementStart(21, "div",
|
|
632
|
+
i0.ɵɵelementStart(21, "div", 99)(22, "label");
|
|
642
633
|
i0.ɵɵtext(23, "AI Configuration");
|
|
643
634
|
i0.ɵɵelementEnd();
|
|
644
|
-
i0.ɵɵelementStart(24, "mj-dropdown",
|
|
635
|
+
i0.ɵɵelementStart(24, "mj-dropdown", 100);
|
|
645
636
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_dropdown_ngModelChange_24_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedConfigurationId, $event) || (ctx_r1.selectedConfigurationId = $event); return i0.ɵɵresetView($event); });
|
|
646
637
|
i0.ɵɵelementEnd();
|
|
647
|
-
i0.ɵɵelementStart(25, "div",
|
|
638
|
+
i0.ɵɵelementStart(25, "div", 101);
|
|
648
639
|
i0.ɵɵconditionalCreate(26, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_26_Template, 2, 0)(27, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_27_Template, 1, 0);
|
|
649
640
|
i0.ɵɵelementEnd()();
|
|
650
|
-
i0.ɵɵelementStart(28, "div",
|
|
641
|
+
i0.ɵɵelementStart(28, "div", 99)(29, "label");
|
|
651
642
|
i0.ɵɵtext(30, "Response Format");
|
|
652
643
|
i0.ɵɵelementEnd();
|
|
653
|
-
i0.ɵɵelementStart(31, "mj-dropdown",
|
|
644
|
+
i0.ɵɵelementStart(31, "mj-dropdown", 108);
|
|
654
645
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_dropdown_ngModelChange_31_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedResponseFormat, $event) || (ctx_r1.selectedResponseFormat = $event); return i0.ɵɵresetView($event); });
|
|
655
646
|
i0.ɵɵelementEnd();
|
|
656
|
-
i0.ɵɵelementStart(32, "div",
|
|
647
|
+
i0.ɵɵelementStart(32, "div", 101);
|
|
657
648
|
i0.ɵɵtext(33, " Expected format for AI response (defaults to prompt setting) ");
|
|
658
649
|
i0.ɵɵelementEnd()();
|
|
659
|
-
i0.ɵɵelementStart(34, "div",
|
|
650
|
+
i0.ɵɵelementStart(34, "div", 99)(35, "label");
|
|
660
651
|
i0.ɵɵtext(36, "Max Tokens");
|
|
661
652
|
i0.ɵɵelementEnd();
|
|
662
|
-
i0.ɵɵelementStart(37, "mj-numeric-input",
|
|
653
|
+
i0.ɵɵelementStart(37, "mj-numeric-input", 109);
|
|
663
654
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.maxTokens, $event) || (ctx_r1.maxTokens = $event); return i0.ɵɵresetView($event); });
|
|
664
655
|
i0.ɵɵelementEnd();
|
|
665
|
-
i0.ɵɵelementStart(38, "div",
|
|
656
|
+
i0.ɵɵelementStart(38, "div", 101);
|
|
666
657
|
i0.ɵɵtext(39, " Maximum length of generated response ");
|
|
667
658
|
i0.ɵɵelementEnd()();
|
|
668
|
-
i0.ɵɵelementStart(40, "div",
|
|
659
|
+
i0.ɵɵelementStart(40, "div", 99)(41, "label", 110)(42, "input", 111);
|
|
669
660
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_input_ngModelChange_42_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.skipValidation, $event) || (ctx_r1.skipValidation = $event); return i0.ɵɵresetView($event); });
|
|
670
661
|
i0.ɵɵelementEnd();
|
|
671
662
|
i0.ɵɵtext(43, " Skip Validation ");
|
|
672
663
|
i0.ɵɵelementEnd();
|
|
673
|
-
i0.ɵɵelementStart(44, "div",
|
|
664
|
+
i0.ɵɵelementStart(44, "div", 101);
|
|
674
665
|
i0.ɵɵtext(45, " Skip output validation during testing ");
|
|
675
666
|
i0.ɵɵelementEnd()();
|
|
676
|
-
i0.ɵɵelementStart(46, "mj-accordion-panel",
|
|
667
|
+
i0.ɵɵelementStart(46, "mj-accordion-panel", 112)(47, "div", 113)(48, "div", 99)(49, "label", 114);
|
|
677
668
|
i0.ɵɵtext(50, " Temperature ");
|
|
678
669
|
i0.ɵɵelementEnd();
|
|
679
|
-
i0.ɵɵelementStart(51, "mj-numeric-input",
|
|
670
|
+
i0.ɵɵelementStart(51, "mj-numeric-input", 115);
|
|
680
671
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_51_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.temperature, $event) || (ctx_r1.advancedParams.temperature = $event); return i0.ɵɵresetView($event); });
|
|
681
672
|
i0.ɵɵelementEnd()();
|
|
682
|
-
i0.ɵɵelementStart(52, "div",
|
|
673
|
+
i0.ɵɵelementStart(52, "div", 99)(53, "label", 116);
|
|
683
674
|
i0.ɵɵtext(54, " Top P ");
|
|
684
675
|
i0.ɵɵelementEnd();
|
|
685
|
-
i0.ɵɵelementStart(55, "mj-numeric-input",
|
|
676
|
+
i0.ɵɵelementStart(55, "mj-numeric-input", 115);
|
|
686
677
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_55_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.topP, $event) || (ctx_r1.advancedParams.topP = $event); return i0.ɵɵresetView($event); });
|
|
687
678
|
i0.ɵɵelementEnd()();
|
|
688
|
-
i0.ɵɵelementStart(56, "div",
|
|
679
|
+
i0.ɵɵelementStart(56, "div", 99)(57, "label", 117);
|
|
689
680
|
i0.ɵɵtext(58, " Top K ");
|
|
690
681
|
i0.ɵɵelementEnd();
|
|
691
|
-
i0.ɵɵelementStart(59, "mj-numeric-input",
|
|
682
|
+
i0.ɵɵelementStart(59, "mj-numeric-input", 115);
|
|
692
683
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_59_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.topK, $event) || (ctx_r1.advancedParams.topK = $event); return i0.ɵɵresetView($event); });
|
|
693
684
|
i0.ɵɵelementEnd()();
|
|
694
|
-
i0.ɵɵelementStart(60, "div",
|
|
685
|
+
i0.ɵɵelementStart(60, "div", 99)(61, "label", 118);
|
|
695
686
|
i0.ɵɵtext(62, " Min P ");
|
|
696
687
|
i0.ɵɵelementEnd();
|
|
697
|
-
i0.ɵɵelementStart(63, "mj-numeric-input",
|
|
688
|
+
i0.ɵɵelementStart(63, "mj-numeric-input", 115);
|
|
698
689
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_63_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.minP, $event) || (ctx_r1.advancedParams.minP = $event); return i0.ɵɵresetView($event); });
|
|
699
690
|
i0.ɵɵelementEnd()();
|
|
700
|
-
i0.ɵɵelementStart(64, "div",
|
|
691
|
+
i0.ɵɵelementStart(64, "div", 99)(65, "label", 119);
|
|
701
692
|
i0.ɵɵtext(66, " Frequency Penalty ");
|
|
702
693
|
i0.ɵɵelementEnd();
|
|
703
|
-
i0.ɵɵelementStart(67, "mj-numeric-input",
|
|
694
|
+
i0.ɵɵelementStart(67, "mj-numeric-input", 115);
|
|
704
695
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_67_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.frequencyPenalty, $event) || (ctx_r1.advancedParams.frequencyPenalty = $event); return i0.ɵɵresetView($event); });
|
|
705
696
|
i0.ɵɵelementEnd()();
|
|
706
|
-
i0.ɵɵelementStart(68, "div",
|
|
697
|
+
i0.ɵɵelementStart(68, "div", 99)(69, "label", 120);
|
|
707
698
|
i0.ɵɵtext(70, " Presence Penalty ");
|
|
708
699
|
i0.ɵɵelementEnd();
|
|
709
|
-
i0.ɵɵelementStart(71, "mj-numeric-input",
|
|
700
|
+
i0.ɵɵelementStart(71, "mj-numeric-input", 115);
|
|
710
701
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_71_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.presencePenalty, $event) || (ctx_r1.advancedParams.presencePenalty = $event); return i0.ɵɵresetView($event); });
|
|
711
702
|
i0.ɵɵelementEnd()();
|
|
712
|
-
i0.ɵɵelementStart(72, "div",
|
|
703
|
+
i0.ɵɵelementStart(72, "div", 99)(73, "label", 121);
|
|
713
704
|
i0.ɵɵtext(74, " Seed ");
|
|
714
705
|
i0.ɵɵelementEnd();
|
|
715
|
-
i0.ɵɵelementStart(75, "mj-numeric-input",
|
|
706
|
+
i0.ɵɵelementStart(75, "mj-numeric-input", 122);
|
|
716
707
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_numeric_input_ngModelChange_75_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.seed, $event) || (ctx_r1.advancedParams.seed = $event); return i0.ɵɵresetView($event); });
|
|
717
708
|
i0.ɵɵelementEnd()();
|
|
718
|
-
i0.ɵɵelementStart(76, "div",
|
|
709
|
+
i0.ɵɵelementStart(76, "div", 99)(77, "label", 123);
|
|
719
710
|
i0.ɵɵtext(78, " Stop Sequences ");
|
|
720
711
|
i0.ɵɵelementEnd();
|
|
721
|
-
i0.ɵɵelementStart(79, "textarea",
|
|
712
|
+
i0.ɵɵelementStart(79, "textarea", 124);
|
|
722
713
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_textarea_ngModelChange_79_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.stopSequencesText, $event) || (ctx_r1.stopSequencesText = $event); return i0.ɵɵresetView($event); });
|
|
723
714
|
i0.ɵɵlistener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_textarea_ngModelChange_79_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.updateStopSequences()); });
|
|
724
715
|
i0.ɵɵelementEnd();
|
|
725
|
-
i0.ɵɵelementStart(80, "div",
|
|
716
|
+
i0.ɵɵelementStart(80, "div", 101);
|
|
726
717
|
i0.ɵɵtext(81, " Separate multiple sequences with commas ");
|
|
727
718
|
i0.ɵɵelementEnd()();
|
|
728
|
-
i0.ɵɵelementStart(82, "div",
|
|
719
|
+
i0.ɵɵelementStart(82, "div", 99)(83, "label", 125);
|
|
729
720
|
i0.ɵɵtext(84, " Include Log Probs ");
|
|
730
721
|
i0.ɵɵelementEnd();
|
|
731
|
-
i0.ɵɵelementStart(85, "mj-switch",
|
|
722
|
+
i0.ɵɵelementStart(85, "mj-switch", 126);
|
|
732
723
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Template_mj_switch_ngModelChange_85_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.advancedParams.includeLogProbs, $event) || (ctx_r1.advancedParams.includeLogProbs = $event); return i0.ɵɵresetView($event); });
|
|
733
724
|
i0.ɵɵelementEnd()();
|
|
734
|
-
i0.ɵɵconditionalCreate(86, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_86_Template, 4, 5, "div",
|
|
725
|
+
i0.ɵɵconditionalCreate(86, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Conditional_86_Template, 4, 5, "div", 99);
|
|
735
726
|
i0.ɵɵelementEnd()()()();
|
|
736
727
|
} if (rf & 2) {
|
|
737
728
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -789,36 +780,32 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_25_Templ
|
|
|
789
780
|
} }
|
|
790
781
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
791
782
|
const _r27 = i0.ɵɵgetCurrentView();
|
|
792
|
-
i0.ɵɵelementStart(0, "button",
|
|
783
|
+
i0.ɵɵelementStart(0, "button", 133);
|
|
793
784
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.newConversation()); });
|
|
794
|
-
i0.ɵɵelement(1, "i",
|
|
785
|
+
i0.ɵɵelement(1, "i", 91);
|
|
795
786
|
i0.ɵɵtext(2, " New ");
|
|
796
787
|
i0.ɵɵelementEnd();
|
|
797
788
|
} }
|
|
798
789
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
799
|
-
i0.ɵɵ
|
|
800
|
-
i0.ɵɵelement(1, "i", 135);
|
|
801
|
-
i0.ɵɵelementStart(2, "p");
|
|
802
|
-
i0.ɵɵtext(3, "No saved conversations");
|
|
803
|
-
i0.ɵɵelementEnd()();
|
|
790
|
+
i0.ɵɵelement(0, "mj-empty-state", 131);
|
|
804
791
|
} }
|
|
805
792
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
806
793
|
const _r28 = i0.ɵɵgetCurrentView();
|
|
807
|
-
i0.ɵɵelementStart(0, "div",
|
|
794
|
+
i0.ɵɵelementStart(0, "div", 134);
|
|
808
795
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_10_Template_div_click_0_listener() { const conv_r29 = i0.ɵɵrestoreView(_r28).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.loadConversation(conv_r29)); });
|
|
809
|
-
i0.ɵɵelementStart(1, "div",
|
|
796
|
+
i0.ɵɵelementStart(1, "div", 135)(2, "h5");
|
|
810
797
|
i0.ɵɵtext(3);
|
|
811
798
|
i0.ɵɵelementEnd();
|
|
812
799
|
i0.ɵɵelementStart(4, "p");
|
|
813
800
|
i0.ɵɵtext(5);
|
|
814
801
|
i0.ɵɵelementEnd();
|
|
815
|
-
i0.ɵɵelementStart(6, "span",
|
|
802
|
+
i0.ɵɵelementStart(6, "span", 136);
|
|
816
803
|
i0.ɵɵtext(7);
|
|
817
804
|
i0.ɵɵpipe(8, "date");
|
|
818
805
|
i0.ɵɵelementEnd()();
|
|
819
|
-
i0.ɵɵelementStart(9, "button",
|
|
806
|
+
i0.ɵɵelementStart(9, "button", 137);
|
|
820
807
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_10_Template_button_click_9_listener($event) { const conv_r29 = i0.ɵɵrestoreView(_r28).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.deleteConversation(conv_r29, $event)); });
|
|
821
|
-
i0.ɵɵelement(10, "i",
|
|
808
|
+
i0.ɵɵelement(10, "i", 138);
|
|
822
809
|
i0.ɵɵelementEnd()();
|
|
823
810
|
} if (rf & 2) {
|
|
824
811
|
const conv_r29 = ctx.$implicit;
|
|
@@ -832,17 +819,17 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_1
|
|
|
832
819
|
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(8, 5, conv_r29.updatedAt, "short"));
|
|
833
820
|
} }
|
|
834
821
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
835
|
-
i0.ɵɵelementStart(0, "div", 41)(1, "div",
|
|
822
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 86)(2, "h4");
|
|
836
823
|
i0.ɵɵtext(3, "Saved Conversations");
|
|
837
824
|
i0.ɵɵelementEnd();
|
|
838
825
|
i0.ɵɵelementStart(4, "p");
|
|
839
826
|
i0.ɵɵtext(5, "Previously saved test sessions");
|
|
840
827
|
i0.ɵɵelementEnd();
|
|
841
|
-
i0.ɵɵconditionalCreate(6, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_6_Template, 3, 0, "button",
|
|
828
|
+
i0.ɵɵconditionalCreate(6, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_6_Template, 3, 0, "button", 129);
|
|
842
829
|
i0.ɵɵelementEnd();
|
|
843
|
-
i0.ɵɵelementStart(7, "div",
|
|
844
|
-
i0.ɵɵconditionalCreate(8, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_8_Template,
|
|
845
|
-
i0.ɵɵrepeaterCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_10_Template, 11, 8, "div",
|
|
830
|
+
i0.ɵɵelementStart(7, "div", 130);
|
|
831
|
+
i0.ɵɵconditionalCreate(8, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Conditional_8_Template, 1, 0, "mj-empty-state", 131);
|
|
832
|
+
i0.ɵɵrepeaterCreate(9, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_For_10_Template, 11, 8, "div", 132, _forTrack0);
|
|
846
833
|
i0.ɵɵelementEnd()();
|
|
847
834
|
} if (rf & 2) {
|
|
848
835
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -856,7 +843,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_26_Templ
|
|
|
856
843
|
function AITestHarnessComponent_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
857
844
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
858
845
|
i0.ɵɵelementStart(0, "as-split", 11)(1, "as-split-area", 28)(2, "div", 12)(3, "div", 29, 1);
|
|
859
|
-
i0.ɵɵconditionalCreate(5, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_5_Template,
|
|
846
|
+
i0.ɵɵconditionalCreate(5, AITestHarnessComponent_Conditional_0_Conditional_4_Conditional_5_Template, 1, 0, "mj-empty-state", 30);
|
|
860
847
|
i0.ɵɵrepeaterCreate(6, AITestHarnessComponent_Conditional_0_Conditional_4_For_7_Template, 17, 8, "div", 31, _forTrack0);
|
|
861
848
|
i0.ɵɵelementEnd();
|
|
862
849
|
i0.ɵɵelementStart(8, "div", 32);
|
|
@@ -911,21 +898,14 @@ function AITestHarnessComponent_Conditional_0_Conditional_4_Template(rf, ctx) {
|
|
|
911
898
|
i0.ɵɵconditional(ctx_r1.activeTab === "savedConversations" ? 26 : -1);
|
|
912
899
|
} }
|
|
913
900
|
function AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
914
|
-
i0.ɵɵ
|
|
915
|
-
i0.ɵɵelement(1, "i", 44);
|
|
916
|
-
i0.ɵɵelementStart(2, "h4");
|
|
917
|
-
i0.ɵɵtext(3, "Start a conversation");
|
|
918
|
-
i0.ɵɵelementEnd();
|
|
919
|
-
i0.ɵɵelementStart(4, "p");
|
|
920
|
-
i0.ɵɵtext(5, "Send a message to begin testing the AI agent");
|
|
921
|
-
i0.ɵɵelementEnd()();
|
|
901
|
+
i0.ɵɵelement(0, "mj-empty-state", 30);
|
|
922
902
|
} }
|
|
923
903
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
924
|
-
i0.ɵɵelement(0, "i",
|
|
904
|
+
i0.ɵɵelement(0, "i", 57);
|
|
925
905
|
i0.ɵɵtext(1, " You ");
|
|
926
906
|
} }
|
|
927
907
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
928
|
-
i0.ɵɵelement(0, "i",
|
|
908
|
+
i0.ɵɵelement(0, "i", 141);
|
|
929
909
|
i0.ɵɵtext(1);
|
|
930
910
|
} if (rf & 2) {
|
|
931
911
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -933,8 +913,8 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_4_
|
|
|
933
913
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.getEntityName() || "Assistant", " ");
|
|
934
914
|
} }
|
|
935
915
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
936
|
-
i0.ɵɵelementStart(0, "span",
|
|
937
|
-
i0.ɵɵelement(1, "i",
|
|
916
|
+
i0.ɵɵelementStart(0, "span", 47);
|
|
917
|
+
i0.ɵɵelement(1, "i", 59);
|
|
938
918
|
i0.ɵɵtext(2);
|
|
939
919
|
i0.ɵɵelementEnd();
|
|
940
920
|
} if (rf & 2) {
|
|
@@ -944,7 +924,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_7_
|
|
|
944
924
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatElapsedTime(message_r32.elapsedTime), " ");
|
|
945
925
|
} }
|
|
946
926
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
947
|
-
i0.ɵɵelementStart(0, "span",
|
|
927
|
+
i0.ɵɵelementStart(0, "span", 48);
|
|
948
928
|
i0.ɵɵtext(1);
|
|
949
929
|
i0.ɵɵelementEnd();
|
|
950
930
|
} if (rf & 2) {
|
|
@@ -956,29 +936,29 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_8_
|
|
|
956
936
|
} }
|
|
957
937
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
958
938
|
const _r33 = i0.ɵɵgetCurrentView();
|
|
959
|
-
i0.ɵɵelementStart(0, "button",
|
|
939
|
+
i0.ɵɵelementStart(0, "button", 60);
|
|
960
940
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r33); const message_r32 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showRawJsonDialog(message_r32)); });
|
|
961
|
-
i0.ɵɵelement(1, "i",
|
|
941
|
+
i0.ɵɵelement(1, "i", 61);
|
|
962
942
|
i0.ɵɵelementEnd();
|
|
963
943
|
} }
|
|
964
944
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
965
945
|
const _r34 = i0.ɵɵgetCurrentView();
|
|
966
|
-
i0.ɵɵelementStart(0, "button",
|
|
946
|
+
i0.ɵɵelementStart(0, "button", 142);
|
|
967
947
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r34); const message_r32 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.showMessageExecutionHistory(message_r32)); });
|
|
968
|
-
i0.ɵɵelement(1, "i",
|
|
948
|
+
i0.ɵɵelement(1, "i", 84);
|
|
969
949
|
i0.ɵɵelementEnd();
|
|
970
950
|
} }
|
|
971
951
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
972
952
|
const _r35 = i0.ɵɵgetCurrentView();
|
|
973
|
-
i0.ɵɵelementStart(0, "button",
|
|
953
|
+
i0.ɵɵelementStart(0, "button", 143);
|
|
974
954
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r35); const message_r32 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.navigateToAgentRun({ runId: message_r32.agentRunId, runType: "agent" })); });
|
|
975
|
-
i0.ɵɵelement(1, "i",
|
|
955
|
+
i0.ɵɵelement(1, "i", 144);
|
|
976
956
|
i0.ɵɵelementEnd();
|
|
977
957
|
} }
|
|
978
958
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
979
|
-
i0.ɵɵelementStart(0, "div",
|
|
959
|
+
i0.ɵɵelementStart(0, "div", 53)(1, "span", 145);
|
|
980
960
|
i0.ɵɵtext(2);
|
|
981
|
-
i0.ɵɵelementStart(3, "span",
|
|
961
|
+
i0.ɵɵelementStart(3, "span", 63);
|
|
982
962
|
i0.ɵɵtext(4, "|");
|
|
983
963
|
i0.ɵɵelementEnd()()();
|
|
984
964
|
} if (rf & 2) {
|
|
@@ -987,15 +967,15 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_15
|
|
|
987
967
|
i0.ɵɵtextInterpolate(message_r32.streamingContent);
|
|
988
968
|
} }
|
|
989
969
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
990
|
-
i0.ɵɵelement(0, "div",
|
|
970
|
+
i0.ɵɵelement(0, "div", 54);
|
|
991
971
|
} if (rf & 2) {
|
|
992
972
|
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
993
973
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
994
974
|
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedContent(message_r32), i0.ɵɵsanitizeHtml);
|
|
995
975
|
} }
|
|
996
976
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
997
|
-
i0.ɵɵelementStart(0, "div",
|
|
998
|
-
i0.ɵɵelement(1, "i",
|
|
977
|
+
i0.ɵɵelementStart(0, "div", 55);
|
|
978
|
+
i0.ɵɵelement(1, "i", 64);
|
|
999
979
|
i0.ɵɵtext(2);
|
|
1000
980
|
i0.ɵɵelementEnd();
|
|
1001
981
|
} if (rf & 2) {
|
|
@@ -1004,7 +984,7 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_17
|
|
|
1004
984
|
i0.ɵɵtextInterpolate1(" ", message_r32.error, " ");
|
|
1005
985
|
} }
|
|
1006
986
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
1007
|
-
i0.ɵɵelementStart(0, "div",
|
|
987
|
+
i0.ɵɵelementStart(0, "div", 69)(1, "pre");
|
|
1008
988
|
i0.ɵɵtext(2);
|
|
1009
989
|
i0.ɵɵelementEnd()();
|
|
1010
990
|
} if (rf & 2) {
|
|
@@ -1015,16 +995,16 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18
|
|
|
1015
995
|
} }
|
|
1016
996
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
1017
997
|
const _r36 = i0.ɵɵgetCurrentView();
|
|
1018
|
-
i0.ɵɵelementStart(0, "div",
|
|
998
|
+
i0.ɵɵelementStart(0, "div", 65)(1, "div", 66);
|
|
1019
999
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r36); const message_r32 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.togglePayloadCollapse(message_r32)); });
|
|
1020
|
-
i0.ɵɵelementStart(2, "span",
|
|
1021
|
-
i0.ɵɵelement(3, "i",
|
|
1000
|
+
i0.ɵɵelementStart(2, "span", 67);
|
|
1001
|
+
i0.ɵɵelement(3, "i", 61);
|
|
1022
1002
|
i0.ɵɵtext(4, " Payload ");
|
|
1023
1003
|
i0.ɵɵelementEnd();
|
|
1024
|
-
i0.ɵɵelementStart(5, "button",
|
|
1004
|
+
i0.ɵɵelementStart(5, "button", 68);
|
|
1025
1005
|
i0.ɵɵelement(6, "i", 27);
|
|
1026
1006
|
i0.ɵɵelementEnd()();
|
|
1027
|
-
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template, 3, 1, "div",
|
|
1007
|
+
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template, 3, 1, "div", 69);
|
|
1028
1008
|
i0.ɵɵelementEnd();
|
|
1029
1009
|
} if (rf & 2) {
|
|
1030
1010
|
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
@@ -1036,24 +1016,24 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18
|
|
|
1036
1016
|
} }
|
|
1037
1017
|
function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
1038
1018
|
const _r31 = i0.ɵɵgetCurrentView();
|
|
1039
|
-
i0.ɵɵelementStart(0, "div", 31)(1, "div",
|
|
1019
|
+
i0.ɵɵelementStart(0, "div", 31)(1, "div", 44)(2, "span", 45);
|
|
1040
1020
|
i0.ɵɵconditionalCreate(3, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_3_Template, 2, 0)(4, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_4_Template, 2, 1);
|
|
1041
1021
|
i0.ɵɵelementEnd();
|
|
1042
|
-
i0.ɵɵelementStart(5, "span",
|
|
1022
|
+
i0.ɵɵelementStart(5, "span", 46);
|
|
1043
1023
|
i0.ɵɵtext(6);
|
|
1044
1024
|
i0.ɵɵelementEnd();
|
|
1045
|
-
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_7_Template, 3, 1, "span",
|
|
1046
|
-
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_9_Template, 2, 0, "button",
|
|
1047
|
-
i0.ɵɵconditionalCreate(10, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_10_Template, 2, 0, "button",
|
|
1048
|
-
i0.ɵɵconditionalCreate(11, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_11_Template, 2, 0, "button",
|
|
1025
|
+
i0.ɵɵconditionalCreate(7, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_7_Template, 3, 1, "span", 47)(8, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_8_Template, 2, 2, "span", 48);
|
|
1026
|
+
i0.ɵɵconditionalCreate(9, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_9_Template, 2, 0, "button", 49);
|
|
1027
|
+
i0.ɵɵconditionalCreate(10, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_10_Template, 2, 0, "button", 139);
|
|
1028
|
+
i0.ɵɵconditionalCreate(11, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_11_Template, 2, 0, "button", 140);
|
|
1049
1029
|
i0.ɵɵelementEnd();
|
|
1050
|
-
i0.ɵɵelementStart(12, "div",
|
|
1030
|
+
i0.ɵɵelementStart(12, "div", 50)(13, "button", 51);
|
|
1051
1031
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Template_button_click_13_listener() { const message_r32 = i0.ɵɵrestoreView(_r31).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.copyMessage(message_r32)); });
|
|
1052
|
-
i0.ɵɵelement(14, "i",
|
|
1032
|
+
i0.ɵɵelement(14, "i", 52);
|
|
1053
1033
|
i0.ɵɵelementEnd();
|
|
1054
|
-
i0.ɵɵconditionalCreate(15, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_15_Template, 5, 1, "div",
|
|
1055
|
-
i0.ɵɵconditionalCreate(17, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_17_Template, 3, 1, "div",
|
|
1056
|
-
i0.ɵɵconditionalCreate(18, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Template, 8, 7, "div",
|
|
1034
|
+
i0.ɵɵconditionalCreate(15, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_15_Template, 5, 1, "div", 53)(16, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_16_Template, 1, 1, "div", 54);
|
|
1035
|
+
i0.ɵɵconditionalCreate(17, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_17_Template, 3, 1, "div", 55);
|
|
1036
|
+
i0.ɵɵconditionalCreate(18, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Conditional_18_Template, 8, 7, "div", 56);
|
|
1057
1037
|
i0.ɵɵelementEnd()();
|
|
1058
1038
|
} if (rf & 2) {
|
|
1059
1039
|
const message_r32 = ctx.$implicit;
|
|
@@ -1079,24 +1059,24 @@ function AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Template(rf, c
|
|
|
1079
1059
|
i0.ɵɵconditional(ctx_r1.hasPayload(message_r32.payload) && ctx_r1.mode === "agent" && message_r32.role === "assistant" ? 18 : -1);
|
|
1080
1060
|
} }
|
|
1081
1061
|
function AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
1082
|
-
i0.ɵɵelement(0, "i",
|
|
1062
|
+
i0.ɵɵelement(0, "i", 59);
|
|
1083
1063
|
} }
|
|
1084
1064
|
function AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
1085
|
-
i0.ɵɵelement(0, "i",
|
|
1065
|
+
i0.ɵɵelement(0, "i", 82);
|
|
1086
1066
|
} }
|
|
1087
1067
|
function AITestHarnessComponent_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
1088
1068
|
const _r30 = i0.ɵɵgetCurrentView();
|
|
1089
1069
|
i0.ɵɵelementStart(0, "div", 12)(1, "div", 29, 1);
|
|
1090
|
-
i0.ɵɵconditionalCreate(3, AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_3_Template,
|
|
1070
|
+
i0.ɵɵconditionalCreate(3, AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_3_Template, 1, 0, "mj-empty-state", 30);
|
|
1091
1071
|
i0.ɵɵrepeaterCreate(4, AITestHarnessComponent_Conditional_0_Conditional_5_For_5_Template, 19, 10, "div", 31, _forTrack0);
|
|
1092
1072
|
i0.ɵɵelementEnd();
|
|
1093
|
-
i0.ɵɵelementStart(6, "div", 32)(7, "div", 34)(8, "textarea",
|
|
1073
|
+
i0.ɵɵelementStart(6, "div", 32)(7, "div", 34)(8, "textarea", 80, 2);
|
|
1094
1074
|
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_Conditional_0_Conditional_5_Template_textarea_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.currentUserMessage, $event) || (ctx_r1.currentUserMessage = $event); return i0.ɵɵresetView($event); });
|
|
1095
1075
|
i0.ɵɵlistener("keypress", function AITestHarnessComponent_Conditional_0_Conditional_5_Template_textarea_keypress_8_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.handleKeyPress($event)); });
|
|
1096
1076
|
i0.ɵɵelementEnd();
|
|
1097
|
-
i0.ɵɵelementStart(10, "button",
|
|
1077
|
+
i0.ɵɵelementStart(10, "button", 81);
|
|
1098
1078
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_0_Conditional_5_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.sendMessage()); });
|
|
1099
|
-
i0.ɵɵconditionalCreate(11, AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_11_Template, 1, 0, "i",
|
|
1079
|
+
i0.ɵɵconditionalCreate(11, AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_11_Template, 1, 0, "i", 59)(12, AITestHarnessComponent_Conditional_0_Conditional_5_Conditional_12_Template, 1, 0, "i", 82);
|
|
1100
1080
|
i0.ɵɵelementEnd()()()();
|
|
1101
1081
|
} if (rf & 2) {
|
|
1102
1082
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -1128,22 +1108,22 @@ function AITestHarnessComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
1128
1108
|
} }
|
|
1129
1109
|
function AITestHarnessComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1130
1110
|
const _r37 = i0.ɵɵgetCurrentView();
|
|
1131
|
-
i0.ɵɵelementStart(0, "mj-dialog",
|
|
1111
|
+
i0.ɵɵelementStart(0, "mj-dialog", 146);
|
|
1132
1112
|
i0.ɵɵlistener("Close", function AITestHarnessComponent_Conditional_1_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelSaveDialog()); });
|
|
1133
1113
|
i0.ɵɵelementStart(1, "mj-dialog-titlebar");
|
|
1134
1114
|
i0.ɵɵtext(2, "Save Conversation");
|
|
1135
1115
|
i0.ɵɵelementEnd();
|
|
1136
|
-
i0.ɵɵelementStart(3, "div",
|
|
1116
|
+
i0.ɵɵelementStart(3, "div", 147)(4, "p");
|
|
1137
1117
|
i0.ɵɵtext(5, "Enter a name for this conversation:");
|
|
1138
1118
|
i0.ɵɵelementEnd();
|
|
1139
|
-
i0.ɵɵelementStart(6, "input",
|
|
1119
|
+
i0.ɵɵelementStart(6, "input", 148, 3);
|
|
1140
1120
|
i0.ɵɵlistener("keyup", function AITestHarnessComponent_Conditional_1_Template_input_keyup_6_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateTempConversation()); });
|
|
1141
1121
|
i0.ɵɵelementEnd()();
|
|
1142
|
-
i0.ɵɵelementStart(8, "mj-dialog-actions")(9, "button",
|
|
1122
|
+
i0.ɵɵelementStart(8, "mj-dialog-actions")(9, "button", 149);
|
|
1143
1123
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_1_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelSaveDialog()); });
|
|
1144
1124
|
i0.ɵɵtext(10, "Cancel");
|
|
1145
1125
|
i0.ɵɵelementEnd();
|
|
1146
|
-
i0.ɵɵelementStart(11, "button",
|
|
1126
|
+
i0.ɵɵelementStart(11, "button", 150);
|
|
1147
1127
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_1_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmSaveConversation()); });
|
|
1148
1128
|
i0.ɵɵtext(12, " Save ");
|
|
1149
1129
|
i0.ɵɵelementEnd()()();
|
|
@@ -1155,22 +1135,22 @@ function AITestHarnessComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
1155
1135
|
} }
|
|
1156
1136
|
function AITestHarnessComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1157
1137
|
const _r38 = i0.ɵɵgetCurrentView();
|
|
1158
|
-
i0.ɵɵelementStart(0, "mj-dialog",
|
|
1138
|
+
i0.ɵɵelementStart(0, "mj-dialog", 151);
|
|
1159
1139
|
i0.ɵɵlistener("Close", function AITestHarnessComponent_Conditional_2_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r38); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelLoadConversation()); });
|
|
1160
1140
|
i0.ɵɵelementStart(1, "mj-dialog-titlebar");
|
|
1161
1141
|
i0.ɵɵtext(2, "Replace Current Conversation?");
|
|
1162
1142
|
i0.ɵɵelementEnd();
|
|
1163
|
-
i0.ɵɵelementStart(3, "div",
|
|
1143
|
+
i0.ɵɵelementStart(3, "div", 147)(4, "p");
|
|
1164
1144
|
i0.ɵɵtext(5, "Loading this conversation will replace the current one. Any unsaved changes will be lost.");
|
|
1165
1145
|
i0.ɵɵelementEnd();
|
|
1166
1146
|
i0.ɵɵelementStart(6, "p");
|
|
1167
1147
|
i0.ɵɵtext(7, "Do you want to continue?");
|
|
1168
1148
|
i0.ɵɵelementEnd()();
|
|
1169
|
-
i0.ɵɵelementStart(8, "mj-dialog-actions")(9, "button",
|
|
1149
|
+
i0.ɵɵelementStart(8, "mj-dialog-actions")(9, "button", 149);
|
|
1170
1150
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r38); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelLoadConversation()); });
|
|
1171
1151
|
i0.ɵɵtext(10, "Cancel");
|
|
1172
1152
|
i0.ɵɵelementEnd();
|
|
1173
|
-
i0.ɵɵelementStart(11, "button",
|
|
1153
|
+
i0.ɵɵelementStart(11, "button", 152);
|
|
1174
1154
|
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r38); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmLoadConversation()); });
|
|
1175
1155
|
i0.ɵɵtext(12, " Load Conversation ");
|
|
1176
1156
|
i0.ɵɵelementEnd()()();
|
|
@@ -1179,9 +1159,9 @@ function AITestHarnessComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
1179
1159
|
} }
|
|
1180
1160
|
function AITestHarnessComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
1181
1161
|
const _r39 = i0.ɵɵgetCurrentView();
|
|
1182
|
-
i0.ɵɵelementStart(0, "mj-window",
|
|
1162
|
+
i0.ɵɵelementStart(0, "mj-window", 153);
|
|
1183
1163
|
i0.ɵɵlistener("Close", function AITestHarnessComponent_Conditional_3_Template_mj_window_Close_0_listener() { i0.ɵɵrestoreView(_r39); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.closeJsonWindow()); });
|
|
1184
|
-
i0.ɵɵelement(1, "mj-json-viewer-window",
|
|
1164
|
+
i0.ɵɵelement(1, "mj-json-viewer-window", 154);
|
|
1185
1165
|
i0.ɵɵelementEnd();
|
|
1186
1166
|
} if (rf & 2) {
|
|
1187
1167
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -1229,10 +1209,11 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
1229
1209
|
* @param sanitizer - Angular DomSanitizer for safe HTML rendering of formatted content
|
|
1230
1210
|
* @param cdr - Angular ChangeDetectorRef for managing change detection
|
|
1231
1211
|
*/
|
|
1232
|
-
constructor(sanitizer, cdr) {
|
|
1212
|
+
constructor(sanitizer, cdr, confirmService) {
|
|
1233
1213
|
super();
|
|
1234
1214
|
this.sanitizer = sanitizer;
|
|
1235
1215
|
this.cdr = cdr;
|
|
1216
|
+
this.confirmService = confirmService;
|
|
1236
1217
|
/** The mode of operation - either 'agent' or 'prompt' */
|
|
1237
1218
|
this.mode = 'agent';
|
|
1238
1219
|
/** The entity to test - either an AI Agent or AI Prompt */
|
|
@@ -1988,10 +1969,10 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
1988
1969
|
/**
|
|
1989
1970
|
* Starts a new conversation
|
|
1990
1971
|
*/
|
|
1991
|
-
newConversation() {
|
|
1972
|
+
async newConversation() {
|
|
1992
1973
|
if (this.conversationMessages.length > 0 && !this.currentConversationId) {
|
|
1993
1974
|
// Unsaved conversation exists - use our custom dialog
|
|
1994
|
-
if (
|
|
1975
|
+
if (await this.confirmService.Confirm({ title: 'Unsaved conversation', message: 'You have an unsaved conversation. Would you like to save it first?', confirmText: 'Save' })) {
|
|
1995
1976
|
this.saveConversation();
|
|
1996
1977
|
return;
|
|
1997
1978
|
}
|
|
@@ -2645,9 +2626,9 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
2645
2626
|
* Clears the current conversation after user confirmation.
|
|
2646
2627
|
* Resets both the message history and the current conversation ID.
|
|
2647
2628
|
*/
|
|
2648
|
-
clearConversation() {
|
|
2629
|
+
async clearConversation() {
|
|
2649
2630
|
if (this.conversationMessages.length > 0) {
|
|
2650
|
-
if (
|
|
2631
|
+
if (await this.confirmService.Confirm({ title: 'Clear conversation', message: 'Are you sure you want to clear the conversation?' })) {
|
|
2651
2632
|
this.conversationMessages = [];
|
|
2652
2633
|
this.currentConversationId = null;
|
|
2653
2634
|
}
|
|
@@ -2964,7 +2945,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
2964
2945
|
}
|
|
2965
2946
|
async deleteConversation(conversation, event) {
|
|
2966
2947
|
event.stopPropagation();
|
|
2967
|
-
if (
|
|
2948
|
+
if (await this.confirmService.ConfirmDelete({ title: 'Delete Conversation', message: `Delete conversation "${conversation.name}"?` })) {
|
|
2968
2949
|
const index = this.savedConversations.findIndex(c => c.id === conversation.id);
|
|
2969
2950
|
if (index >= 0) {
|
|
2970
2951
|
this.savedConversations.splice(index, 1);
|
|
@@ -3027,13 +3008,13 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3027
3008
|
if (input.files && input.files[0]) {
|
|
3028
3009
|
const file = input.files[0];
|
|
3029
3010
|
const reader = new FileReader();
|
|
3030
|
-
reader.onload = (e) => {
|
|
3011
|
+
reader.onload = async (e) => {
|
|
3031
3012
|
try {
|
|
3032
3013
|
const data = JSON.parse(e.target?.result);
|
|
3033
3014
|
// Validate and import
|
|
3034
3015
|
if (data.messages && Array.isArray(data.messages)) {
|
|
3035
3016
|
if (this.conversationMessages.length > 0) {
|
|
3036
|
-
if (!
|
|
3017
|
+
if (!(await this.confirmService.Confirm({ title: 'Import conversation', message: 'Importing will replace the current conversation. Continue?' }))) {
|
|
3037
3018
|
return;
|
|
3038
3019
|
}
|
|
3039
3020
|
}
|
|
@@ -3389,9 +3370,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3389
3370
|
// Basic markdown to HTML conversion with improved formatting
|
|
3390
3371
|
let html = content;
|
|
3391
3372
|
// Escape HTML first
|
|
3392
|
-
html = html
|
|
3393
|
-
.replace(/</g, '<')
|
|
3394
|
-
.replace(/>/g, '>');
|
|
3373
|
+
html = EscapeHTML(html);
|
|
3395
3374
|
// Code blocks with language support
|
|
3396
3375
|
html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
|
|
3397
3376
|
const language = lang || '';
|
|
@@ -3481,12 +3460,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3481
3460
|
* Escapes HTML content for use in attributes
|
|
3482
3461
|
*/
|
|
3483
3462
|
escapeHtmlAttribute(text) {
|
|
3484
|
-
return text
|
|
3485
|
-
.replace(/&/g, '&')
|
|
3486
|
-
.replace(/"/g, '"')
|
|
3487
|
-
.replace(/'/g, ''')
|
|
3488
|
-
.replace(/</g, '<')
|
|
3489
|
-
.replace(/>/g, '>');
|
|
3463
|
+
return EscapeHTML(text);
|
|
3490
3464
|
}
|
|
3491
3465
|
/**
|
|
3492
3466
|
* Renders JSON content with human-readable content prominently displayed
|
|
@@ -3610,9 +3584,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3610
3584
|
return (message.rawContent && !message.isStreaming) || this.hasExtractableContent(message);
|
|
3611
3585
|
}
|
|
3612
3586
|
escapeHtml(text) {
|
|
3613
|
-
|
|
3614
|
-
div.textContent = text;
|
|
3615
|
-
return div.innerHTML;
|
|
3587
|
+
return EscapeHTML(text);
|
|
3616
3588
|
}
|
|
3617
3589
|
/**
|
|
3618
3590
|
* Formats JSON for proper display with text wrapping instead of wide code blocks.
|
|
@@ -3842,7 +3814,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3842
3814
|
IsConfigMatchById(config, id) {
|
|
3843
3815
|
return UUIDsEqual(config.ID, id);
|
|
3844
3816
|
}
|
|
3845
|
-
static { this.ɵfac = function AITestHarnessComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AITestHarnessComponent)(i0.ɵɵdirectiveInject(i1.DomSanitizer), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
|
|
3817
|
+
static { this.ɵfac = function AITestHarnessComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AITestHarnessComponent)(i0.ɵɵdirectiveInject(i1.DomSanitizer), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i2.MJConfirmService)); }; }
|
|
3846
3818
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AITestHarnessComponent, selectors: [["mj-ai-test-harness"]], viewQuery: function AITestHarnessComponent_Query(rf, ctx) { if (rf & 1) {
|
|
3847
3819
|
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5)(_c3, 5);
|
|
3848
3820
|
} if (rf & 2) {
|
|
@@ -3851,7 +3823,7 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3851
3823
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fileInput = _t.first);
|
|
3852
3824
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInput = _t.first);
|
|
3853
3825
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.saveDialogInput = _t.first);
|
|
3854
|
-
} }, inputs: { mode: "mode", entity: "entity", originalPromptRunId: "originalPromptRunId", systemPromptOverride: "systemPromptOverride", aiAgent: "aiAgent", isVisible: "isVisible" }, outputs: { visibilityChange: "visibilityChange", runOpened: "runOpened", minimizeRequested: "minimizeRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 4, vars: 4, consts: [["fileInput", ""], ["messagesContainer", ""], ["messageInput", ""], ["saveDialogInput", ""], [1, "harness-container"], [1, "save-dialog", 3, "Visible", "Width"], [1, "confirm-dialog", 3, "Visible", "Width"], ["Title", "Raw JSON Response", 3, "Visible", "Width", "Height", "MinWidth", "MinHeight", "Draggable", "Resizable"], [1, "harness-header"], [1, "agent-info"], [1, "harness-body"], ["direction", "horizontal", 2, "height", "100%", "width", "100%"], [1, "chat-area"], [1, "agent-details"], [1, "entity-logo", 3, "src", "alt"], [3, "class"], [1, "header-actions"], ["title", "Clear conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-broom"], ["title", "Save conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-save"], ["title", "Export conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-download"], ["title", "Import conversation", 1, "custom-button", 3, "click"], [1, "fa-solid", "fa-upload"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], ["title", "Toggle sidebar", 1, "custom-button", "icon-only", 3, "click"], [1, "fa-solid"], [3, "size"], [1, "messages-container"], [
|
|
3826
|
+
} }, inputs: { mode: "mode", entity: "entity", originalPromptRunId: "originalPromptRunId", systemPromptOverride: "systemPromptOverride", aiAgent: "aiAgent", isVisible: "isVisible" }, outputs: { visibilityChange: "visibilityChange", runOpened: "runOpened", minimizeRequested: "minimizeRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 4, vars: 4, consts: [["fileInput", ""], ["messagesContainer", ""], ["messageInput", ""], ["saveDialogInput", ""], [1, "harness-container"], [1, "save-dialog", 3, "Visible", "Width"], [1, "confirm-dialog", 3, "Visible", "Width"], ["Title", "Raw JSON Response", 3, "Visible", "Width", "Height", "MinWidth", "MinHeight", "Draggable", "Resizable"], [1, "harness-header"], [1, "agent-info"], [1, "harness-body"], ["direction", "horizontal", 2, "height", "100%", "width", "100%"], [1, "chat-area"], [1, "agent-details"], [1, "entity-logo", 3, "src", "alt"], [3, "class"], [1, "header-actions"], ["title", "Clear conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-broom"], ["title", "Save conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-save"], ["title", "Export conversation", 1, "custom-button", 3, "click", "disabled"], [1, "fa-solid", "fa-download"], ["title", "Import conversation", 1, "custom-button", 3, "click"], [1, "fa-solid", "fa-upload"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], ["title", "Toggle sidebar", 1, "custom-button", "icon-only", 3, "click"], [1, "fa-solid"], [3, "size"], [1, "messages-container"], ["Icon", "fa-solid fa-comments", "Title", "Start a conversation", "Message", "Send a message to begin testing the AI agent"], [3, "ngClass"], [1, "input-area"], [1, "rerun-mode-container"], [1, "input-container"], [1, "sidebar"], [1, "sidebar-tabs"], [1, "tab-button", 3, "click", "disabled"], [1, "fa-solid", "fa-history"], [1, "badge"], [1, "sidebar-content"], [1, "tab-content"], [1, "tab-content", 2, "padding", "0", "height", "100%"], [1, "tab-content", 2, "overflow-y", "auto"], [1, "message-header"], [1, "message-role"], [1, "message-time"], [1, "execution-time", "streaming"], [1, "execution-time", 3, "title"], ["title", "View raw JSON response", 1, "raw-toggle"], [1, "message-content"], ["title", "Copy message", 1, "copy-button-in-bubble", 3, "click"], [1, "fa-solid", "fa-copy"], [1, "streaming-wrapper"], [3, "innerHTML"], [1, "error-details"], [1, "payload-section", 3, "collapsed"], [1, "fa-solid", "fa-user"], [1, "message-role-logo", 3, "src", "alt"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["title", "View raw JSON response", 1, "raw-toggle", 3, "click"], [1, "fa-solid", "fa-code"], [1, "streaming-content", 3, "innerHTML"], [1, "cursor"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "payload-section"], [1, "payload-header", 3, "click"], [1, "payload-label"], ["type", "button", 1, "payload-toggle"], [1, "payload-content"], [2, "height", "300px", "width", "100%", 3, "ngModel", "language", "readonly"], [1, "rerun-message"], [1, "fa-solid", "fa-rotate-right"], [1, "rerun-buttons"], ["title", "Re-run with loaded messages", 1, "send-button", "rerun-button", 3, "disabled"], ["title", "Reset conversation messages to the original state from the prompt run. Model settings and parameters will be preserved.", 1, "send-button", "reset-button", 3, "disabled"], ["title", "Re-run with loaded messages", 1, "send-button", "rerun-button", 3, "click", "disabled"], [1, "fa-solid", "fa-play"], ["title", "Reset conversation messages to the original state from the prompt run. Model settings and parameters will be preserved.", 1, "send-button", "reset-button", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], ["placeholder", "Type your message here... (Press Enter to send, Shift+Enter for new line)", 1, "mj-textarea", "message-input", 3, "ngModelChange", "keypress", "ngModel", "rows", "disabled"], ["title", "Send message", 1, "send-button", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], [1, "tab-button", 3, "click"], [1, "fa-solid", "fa-diagram-project"], [1, "fa-solid", "fa-sliders"], [1, "tab-header"], [1, "variables-list"], ["Icon", "fa-solid fa-code", "Title", "No variables defined", "Message", "Click \"Add Variable\" to get started.", "Size", "compact"], [1, "variable-item"], [1, "add-button", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], ["type", "text", "placeholder", "Variable name", 1, "mj-input", "variable-name", 3, "ngModelChange", "ngModel", "disabled"], ["TextField", "text", "ValueField", "value", 1, "variable-type", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive", "Disabled"], ["type", "text", 1, "mj-input", "variable-value", 3, "ngModelChange", "ngModel", "placeholder", "disabled"], ["title", "Remove variable", 1, "remove-button", 3, "click", "disabled"], [1, "fa-solid", "fa-times"], [3, "viewRunClick", "mode", "agentRun", "liveSteps", "autoExpand", "runId", "runType"], [1, "model-settings"], [1, "setting-group"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a configuration...", 1, "configuration-selector", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive"], [1, "setting-help"], [1, "add-button", 3, "click"], ["title", "Remove variable", 1, "remove-button", 3, "click"], ["title", "Reset to Prompt Settings", 1, "custom-button", "icon-only", 3, "click"], [1, "fa-solid", "fa-undo"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a model...", 1, "model-selector", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a vendor...", 1, "vendor-selector", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive", "Disabled"], ["TextField", "text", "ValueField", "value", "Placeholder", "Select format...", 1, "format-selector", 3, "ngModelChange", "ngModel", "Data"], ["Placeholder", "Max tokens...", 1, "max-tokens-input", 3, "ngModelChange", "ngModel", "Min", "Max", "Step"], [1, "checkbox-label"], ["type", "checkbox", 1, "skip-validation-checkbox", 3, "ngModelChange", "ngModel"], [1, "advanced-params-panel", 3, "Title", "Expanded"], [1, "advanced-settings"], ["title", "Controls randomness: 0 = more focused and deterministic, 2 = more random and creative"], ["Placeholder", "None", 1, "advanced-param-input", 3, "ngModelChange", "ngModel", "Min", "Max", "Step", "Format"], ["title", "Nucleus sampling: only consider tokens with cumulative probability up to this value. 1 = consider all tokens"], ["title", "Only sample from the top K tokens. Lower values reduce randomness"], ["title", "Minimum probability for token selection. Filters out low-probability tokens"], ["title", "Penalizes tokens based on their frequency in the text. Positive values reduce repetition"], ["title", "Penalizes tokens that have appeared in the text. Positive values increase topic diversity"], ["title", "Random seed for deterministic generation. Same seed produces same output"], ["Placeholder", "None", 1, "advanced-param-input", 3, "ngModelChange", "ngModel", "Format"], ["title", "Sequences that will stop generation when encountered. Enter comma-separated values"], ["placeholder", "Enter comma-separated sequences", 1, "mj-textarea", "advanced-param-input", 3, "ngModelChange", "ngModel", "rows"], ["title", "Include log probabilities of the output tokens in the response"], [1, "advanced-param-switch", 3, "ngModelChange", "ngModel"], ["title", "Number of top log probabilities to include for each token"], ["Placeholder", "2", 1, "advanced-param-input", 3, "ngModelChange", "ngModel", "Min", "Max", "Step", "Format"], ["title", "Start a new conversation", 1, "custom-button", "small", "primary"], [1, "saved-list"], ["Icon", "fa-solid fa-folder-open", "Title", "No saved conversations", "Size", "compact"], [1, "saved-item", 3, "current"], ["title", "Start a new conversation", 1, "custom-button", "small", "primary", 3, "click"], [1, "saved-item", 3, "click"], [1, "saved-info"], [1, "saved-date"], ["title", "Delete conversation", 1, "delete-button", 3, "click"], [1, "fa-solid", "fa-trash"], ["title", "View execution details", 1, "execution-history-toggle"], ["title", "View full run details", 1, "execution-history-toggle"], [1, "fa-solid", "fa-robot"], ["title", "View execution details", 1, "execution-history-toggle", 3, "click"], ["title", "View full run details", 1, "execution-history-toggle", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "streaming-content"], [1, "save-dialog", 3, "Close", "Visible", "Width"], [1, "dialog-content"], ["type", "text", "placeholder", "Conversation name", 1, "mj-input", "full-width", 3, "keyup"], ["mjButton", "", 3, "click"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "confirm-dialog", 3, "Close", "Visible", "Width"], ["mjButton", "", "variant", "primary", 3, "click"], ["Title", "Raw JSON Response", 3, "Close", "Visible", "Width", "Height", "MinWidth", "MinHeight", "Draggable", "Resizable"], [3, "jsonContent"]], template: function AITestHarnessComponent_Template(rf, ctx) { if (rf & 1) {
|
|
3855
3827
|
i0.ɵɵconditionalCreate(0, AITestHarnessComponent_Conditional_0_Template, 6, 2, "div", 4);
|
|
3856
3828
|
i0.ɵɵconditionalCreate(1, AITestHarnessComponent_Conditional_1_Template, 13, 3, "mj-dialog", 5);
|
|
3857
3829
|
i0.ɵɵconditionalCreate(2, AITestHarnessComponent_Conditional_2_Template, 13, 2, "mj-dialog", 6);
|
|
@@ -3864,12 +3836,12 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3864
3836
|
i0.ɵɵconditional(ctx.showLoadConfirmDialog ? 2 : -1);
|
|
3865
3837
|
i0.ɵɵadvance();
|
|
3866
3838
|
i0.ɵɵconditional(ctx.showJsonWindow ? 3 : -1);
|
|
3867
|
-
} }, dependencies: [i2.NgClass, i3.DefaultValueAccessor, i3.CheckboxControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJWindowComponent, i4.MJButtonDirective, i4.MJDropdownComponent, i4.MJNumericInputComponent, i4.MJSwitchComponent, i4.MJAccordionPanelComponent, i4.MJDialogComponent, i4.MJDialogTitlebarComponent, i4.MJDialogActionsComponent, i5.SplitComponent, i5.SplitAreaComponent, i6.CodeEditorComponent, i7.JsonViewerWindowComponent, i8.AgentExecutionMonitorComponent, i2.DatePipe], styles: ["\n\n.harness-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n\n\n.custom-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.custom-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.custom-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.custom-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.custom-button.icon-only[_ngcontent-%COMP%] {\n padding: 6px 8px;\n}\n\n.custom-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.send-button[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 44px;\n font-family: inherit;\n}\n\n.send-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.send-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n\n\n.add-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.add-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n\n\n.remove-button[_ngcontent-%COMP%], \n.delete-button[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n color: var(--mj-status-error);\n padding: 4px 8px;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n border-radius: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.remove-button[_ngcontent-%COMP%]:hover, \n.delete-button[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-color-error-600);\n}\n\n\n\n.copy-button-in-bubble[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n padding: 6px;\n font-size: 14px;\n color: var(--mj-border-strong);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n opacity: 0;\n z-index: 10; \n\n}\n\n.message-content[_ngcontent-%COMP%]:hover .copy-button-in-bubble[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.copy-button-in-bubble[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.08);\n color: var(--mj-text-muted);\n}\n\n.copy-button-in-bubble[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.model-settings[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.setting-group[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.setting-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.model-selector[_ngcontent-%COMP%], \n.vendor-selector[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.temperature-slider[_ngcontent-%COMP%] {\n width: 100%;\n margin-top: 8px;\n}\n\n.max-tokens-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.setting-help[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n}\n\n.skip-validation-checkbox[_ngcontent-%COMP%] {\n margin-right: 8px;\n cursor: pointer;\n width: 16px;\n height: 16px;\n}\n\n\n\n.harness-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 16px 20px;\n}\n\n.agent-info[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.agent-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.agent-details[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.agent-details[_ngcontent-%COMP%] .entity-logo[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-details[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.agent-details[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n.harness-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n\n\n.chat-area[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n height: 100%;\n min-height: 0; \n\n}\n\n\n\n.messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-user[_ngcontent-%COMP%] {\n margin-left: auto;\n max-width: 70%;\n}\n\n.message-assistant[_ngcontent-%COMP%] {\n margin-right: auto;\n max-width: 70%;\n}\n\n.message-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 13px;\n}\n\n.message-role[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.message-role[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.message-role[_ngcontent-%COMP%] .message-role-logo[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.message-user[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.message-time[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.execution-time[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.raw-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n}\n\n.raw-toggle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-secondary);\n}\n\n.raw-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n\n.message-user[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.message.streaming[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.streaming-content[_ngcontent-%COMP%] {\n display: inline;\n}\n\n.streaming-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.streaming-wrapper[_ngcontent-%COMP%] .cursor[_ngcontent-%COMP%] {\n display: inline;\n margin-left: 2px;\n}\n\n.cursor[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_blink 1s infinite;\n font-weight: 100;\n color: var(--mj-text-secondary);\n}\n\n@keyframes _ngcontent-%COMP%_blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n}\n\n.error-details[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 6px;\n color: var(--mj-color-error-600);\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.payload-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.payload-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.payload-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.payload-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.payload-content[_ngcontent-%COMP%] {\n max-height: 250px;\n overflow: auto;\n background: var(--mj-bg-surface-card);\n}\n\n.payload-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 12px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n background: transparent;\n}\n\n.payload-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.payload-toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.payload-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.payload-section.collapsed[_ngcontent-%COMP%] .payload-header[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n\n\n.save-dialog[_ngcontent-%COMP%], \n.confirm-dialog[_ngcontent-%COMP%] {\n .dialog-content {\n padding: 20px;\n\n p {\n margin: 0 0 16px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .full-width {\n width: 100%;\n }\n\n input.k-textbox {\n padding: 8px 12px;\n font-size: 14px;\n line-height: 1.5;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n\n &:focus {\n outline: none;\n border-color: var(--mj-status-error);\n box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--mj-status-error) 25%, transparent);\n }\n }\n }\n}\n\n\n\n.markdown-content[_ngcontent-%COMP%] {\n line-height: 1.6;\n word-wrap: break-word;\n overflow-wrap: break-word;\n max-width: 100%;\n}\n\n\n\n.inline-json-editor[_ngcontent-%COMP%] {\n margin: 8px 0;\n\n .json-editor-container {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n max-height: 400px;\n\n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;\n font-size: 13px;\n line-height: 1.5;\n overflow: auto;\n height: 100%;\n background: transparent;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n }\n}\n\n.markdown-paragraph[_ngcontent-%COMP%] {\n margin: 8px 0;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.markdown-h1[_ngcontent-%COMP%] {\n font-size: 1.5em;\n font-weight: 600;\n margin: 16px 0 8px 0;\n color: var(--mj-text-primary);\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n padding-bottom: 4px;\n}\n\n.markdown-h2[_ngcontent-%COMP%] {\n font-size: 1.3em;\n font-weight: 600;\n margin: 14px 0 6px 0;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n padding-bottom: 2px;\n}\n\n.markdown-h3[_ngcontent-%COMP%] {\n font-size: 1.1em;\n font-weight: 600;\n margin: 12px 0 4px 0;\n color: var(--mj-text-primary);\n}\n\n.code-block[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 16px;\n margin: 12px 0;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre;\n word-wrap: normal;\n max-width: 100%;\n}\n\n.code-block[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre;\n word-wrap: normal;\n}\n\n.language-json[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.inline-code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 0.9em;\n color: var(--mj-status-error);\n white-space: nowrap;\n}\n\n.markdown-list[_ngcontent-%COMP%] {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.markdown-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 4px 0;\n line-height: 1.5;\n}\n\n.markdown-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: none;\n}\n\n\n\n.message-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n padding: 12px 40px 12px 16px; \n\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n position: relative;\n overflow-wrap: break-word;\n hyphens: auto;\n max-width: 100%;\n overflow-x: hidden;\n}\n\n\n\n.json-content-wrapper[_ngcontent-%COMP%] {\n margin: 8px 0;\n}\n\n.json-main-content[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.json-raw-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n}\n\n.json-toggle-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.json-toggle-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.json-toggle-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.json-raw-section[_ngcontent-%COMP%] .code-block[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n font-size: 12px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n\n\n@media (max-width: 768px) {\n .json-raw-section[_ngcontent-%COMP%] .code-block[_ngcontent-%COMP%] {\n font-size: 11px;\n max-height: 200px;\n }\n}\n\n\n\n.json-raw-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n}\n\n\n\n.input-area[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0; \n\n margin-top: auto; \n\n}\n\n.input-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.rerun-mode-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 8px;\n gap: 16px;\n}\n\n.rerun-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.rerun-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.rerun-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-family: 'Fira Code', 'Consolas', monospace;\n}\n\n.rerun-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 100px;\n justify-content: center;\n}\n\n.rerun-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.rerun-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.reset-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 120px;\n justify-content: center;\n background-color: var(--mj-text-muted);\n}\n\n.reset-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-text-secondary);\n}\n\n.reset-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.message-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.message-input[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: none;\n font-size: 14px;\n}\n\n.send-button[_ngcontent-%COMP%] {\n margin-bottom: 1px;\n}\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n width: 100%; \n\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n.sidebar-tabs[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tab-button[_ngcontent-%COMP%] {\n flex: 1;\n padding: 12px 8px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.2s;\n position: relative;\n}\n\n.tab-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.tab-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-button[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n margin-left: 4px;\n}\n\n.tab-button.active[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.tab-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n width: 100%; \n\n}\n\n.tab-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%; \n\n box-sizing: border-box; \n\n}\n\n.tab-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.icon-only[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.tab-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.tab-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.small[_ngcontent-%COMP%] {\n align-self: flex-start;\n padding: 6px 12px;\n font-size: 13px;\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.variables-list[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.variable-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n align-items: center;\n width: 100%;\n}\n\n.variable-name[_ngcontent-%COMP%] {\n width: 30%; \n\n min-width: 100px;\n}\n\n.variable-type[_ngcontent-%COMP%] {\n width: 25%; \n\n min-width: 80px;\n}\n\n.variable-value[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0; \n\n}\n\n.remove-button[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.add-variable-button[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.empty-variables[_ngcontent-%COMP%] {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n\n\n.saved-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.empty-saved[_ngcontent-%COMP%] {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.empty-saved[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.saved-item[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.saved-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.saved-item.current[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.saved-info[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.saved-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.saved-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n@media (max-width: 1200px) {\n .sidebar[_ngcontent-%COMP%] {\n width: 320px;\n }\n}\n\n@media (max-width: 992px) {\n .message-user[_ngcontent-%COMP%], \n .message-assistant[_ngcontent-%COMP%] {\n max-width: 85%;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n}\n\n\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n .ai-agent-test-harness .k-dialog-wrapper {\n border-radius: 8px;\n overflow: hidden;\n}\n\n .ai-agent-test-harness .k-dialog-titlebar {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-inverse);\n}\n\n .ai-agent-test-harness .k-dialog-title {\n font-weight: 600;\n}\n\n .ai-agent-test-harness .k-dialog-titlebar-actions .k-button {\n color: var(--mj-text-inverse);\n}\n\n .ai-agent-test-harness .k-dialog-content {\n padding: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n\n\n\n\n\n.advanced-params-panel[_ngcontent-%COMP%] {\n margin-top: 24px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n}\n\n.advanced-params-panel[_ngcontent-%COMP%] .k-expander-title {\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.advanced-settings[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.advanced-param-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.advanced-param-switch[_ngcontent-%COMP%] {\n margin-top: 8px;\n}\n\n\n\n.format-selector[_ngcontent-%COMP%] {\n width: 100%;\n}"] }); }
|
|
3839
|
+
} }, dependencies: [i3.NgClass, i4.DefaultValueAccessor, i4.CheckboxControlValueAccessor, i4.NgControlStatus, i4.NgModel, i2.MJWindowComponent, i2.MJButtonDirective, i2.MJDropdownComponent, i2.MJNumericInputComponent, i2.MJSwitchComponent, i2.MJAccordionPanelComponent, i2.MJDialogComponent, i2.MJDialogTitlebarComponent, i2.MJDialogActionsComponent, i2.MJEmptyStateComponent, i5.SplitComponent, i5.SplitAreaComponent, i6.CodeEditorComponent, i7.JsonViewerWindowComponent, i8.AgentExecutionMonitorComponent, i3.DatePipe], styles: ["\n\n.harness-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n\n\n.custom-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.custom-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.custom-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.custom-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.custom-button.icon-only[_ngcontent-%COMP%] {\n padding: 6px 8px;\n}\n\n.custom-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.send-button[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 44px;\n font-family: inherit;\n}\n\n.send-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.send-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n\n\n.add-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.add-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n\n\n.remove-button[_ngcontent-%COMP%], \n.delete-button[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n color: var(--mj-status-error);\n padding: 4px 8px;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n border-radius: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.remove-button[_ngcontent-%COMP%]:hover, \n.delete-button[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-color-error-600);\n}\n\n\n\n.copy-button-in-bubble[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n padding: 6px;\n font-size: 14px;\n color: var(--mj-border-strong);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n opacity: 0;\n z-index: 10; \n\n}\n\n.message-content[_ngcontent-%COMP%]:hover .copy-button-in-bubble[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.copy-button-in-bubble[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.08);\n color: var(--mj-text-muted);\n}\n\n.copy-button-in-bubble[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.model-settings[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.setting-group[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.setting-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.model-selector[_ngcontent-%COMP%], \n.vendor-selector[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.temperature-slider[_ngcontent-%COMP%] {\n width: 100%;\n margin-top: 8px;\n}\n\n.max-tokens-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.setting-help[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n}\n\n.skip-validation-checkbox[_ngcontent-%COMP%] {\n margin-right: 8px;\n cursor: pointer;\n width: 16px;\n height: 16px;\n}\n\n\n\n.harness-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 16px 20px;\n}\n\n.agent-info[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.agent-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.agent-details[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.agent-details[_ngcontent-%COMP%] .entity-logo[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-details[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.agent-details[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n.harness-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n\n\n.chat-area[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n height: 100%;\n min-height: 0; \n\n}\n\n\n\n.messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n.messages-container[_ngcontent-%COMP%] mj-empty-state[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-in;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-user[_ngcontent-%COMP%] {\n margin-left: auto;\n max-width: 70%;\n}\n\n.message-assistant[_ngcontent-%COMP%] {\n margin-right: auto;\n max-width: 70%;\n}\n\n.message-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 13px;\n}\n\n.message-role[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.message-role[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.message-role[_ngcontent-%COMP%] .message-role-logo[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.message-user[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.message-time[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.execution-time[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.raw-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n}\n\n.raw-toggle[_ngcontent-%COMP%]:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-secondary);\n}\n\n.raw-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n\n.message-user[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.message.streaming[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.streaming-content[_ngcontent-%COMP%] {\n display: inline;\n}\n\n.streaming-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.streaming-wrapper[_ngcontent-%COMP%] .cursor[_ngcontent-%COMP%] {\n display: inline;\n margin-left: 2px;\n}\n\n.cursor[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_blink 1s infinite;\n font-weight: 100;\n color: var(--mj-text-secondary);\n}\n\n@keyframes _ngcontent-%COMP%_blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n}\n\n.error-details[_ngcontent-%COMP%] {\n margin-top: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 6px;\n color: var(--mj-color-error-600);\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n\n\n.payload-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.payload-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.payload-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.payload-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.payload-content[_ngcontent-%COMP%] {\n max-height: 250px;\n overflow: auto;\n background: var(--mj-bg-surface-card);\n}\n\n.payload-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n padding: 12px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n background: transparent;\n}\n\n.payload-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.payload-toggle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.payload-toggle[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.payload-section.collapsed[_ngcontent-%COMP%] .payload-header[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n\n\n.save-dialog[_ngcontent-%COMP%], \n.confirm-dialog[_ngcontent-%COMP%] {\n .dialog-content {\n padding: 20px;\n\n p {\n margin: 0 0 16px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .full-width {\n width: 100%;\n }\n\n input.k-textbox {\n padding: 8px 12px;\n font-size: 14px;\n line-height: 1.5;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n\n &:focus {\n outline: none;\n border-color: var(--mj-status-error);\n box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--mj-status-error) 25%, transparent);\n }\n }\n }\n}\n\n\n\n.markdown-content[_ngcontent-%COMP%] {\n line-height: 1.6;\n word-wrap: break-word;\n overflow-wrap: break-word;\n max-width: 100%;\n}\n\n\n\n.inline-json-editor[_ngcontent-%COMP%] {\n margin: 8px 0;\n\n .json-editor-container {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n max-height: 400px;\n\n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;\n font-size: 13px;\n line-height: 1.5;\n overflow: auto;\n height: 100%;\n background: transparent;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n }\n}\n\n.markdown-paragraph[_ngcontent-%COMP%] {\n margin: 8px 0;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.markdown-h1[_ngcontent-%COMP%] {\n font-size: 1.5em;\n font-weight: 600;\n margin: 16px 0 8px 0;\n color: var(--mj-text-primary);\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n padding-bottom: 4px;\n}\n\n.markdown-h2[_ngcontent-%COMP%] {\n font-size: 1.3em;\n font-weight: 600;\n margin: 14px 0 6px 0;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n padding-bottom: 2px;\n}\n\n.markdown-h3[_ngcontent-%COMP%] {\n font-size: 1.1em;\n font-weight: 600;\n margin: 12px 0 4px 0;\n color: var(--mj-text-primary);\n}\n\n.code-block[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 16px;\n margin: 12px 0;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre;\n word-wrap: normal;\n max-width: 100%;\n}\n\n.code-block[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre;\n word-wrap: normal;\n}\n\n.language-json[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.inline-code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 0.9em;\n color: var(--mj-status-error);\n white-space: nowrap;\n}\n\n.markdown-list[_ngcontent-%COMP%] {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.markdown-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 4px 0;\n line-height: 1.5;\n}\n\n.markdown-link[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: none;\n}\n\n\n\n.message-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n padding: 12px 40px 12px 16px; \n\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n position: relative;\n overflow-wrap: break-word;\n hyphens: auto;\n max-width: 100%;\n overflow-x: hidden;\n}\n\n\n\n.json-content-wrapper[_ngcontent-%COMP%] {\n margin: 8px 0;\n}\n\n.json-main-content[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.json-raw-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n}\n\n.json-toggle-button[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.json-toggle-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.json-toggle-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.json-raw-section[_ngcontent-%COMP%] .code-block[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n font-size: 12px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n\n\n@media (max-width: 768px) {\n .json-raw-section[_ngcontent-%COMP%] .code-block[_ngcontent-%COMP%] {\n font-size: 11px;\n max-height: 200px;\n }\n}\n\n\n\n.json-raw-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n}\n\n\n\n.input-area[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0; \n\n margin-top: auto; \n\n}\n\n.input-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.rerun-mode-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 8px;\n gap: 16px;\n}\n\n.rerun-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.rerun-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.rerun-message[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-family: 'Fira Code', 'Consolas', monospace;\n}\n\n.rerun-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 100px;\n justify-content: center;\n}\n\n.rerun-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.rerun-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.reset-button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 120px;\n justify-content: center;\n background-color: var(--mj-text-muted);\n}\n\n.reset-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: var(--mj-text-secondary);\n}\n\n.reset-button[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.message-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.message-input[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: none;\n font-size: 14px;\n}\n\n.send-button[_ngcontent-%COMP%] {\n margin-bottom: 1px;\n}\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n width: 100%; \n\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n.sidebar-tabs[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tab-button[_ngcontent-%COMP%] {\n flex: 1;\n padding: 12px 8px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.2s;\n position: relative;\n}\n\n.tab-button[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.tab-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-button[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n margin-left: 4px;\n}\n\n.tab-button.active[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.tab-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n width: 100%; \n\n}\n\n.tab-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%; \n\n box-sizing: border-box; \n\n}\n\n.tab-header[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.icon-only[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.tab-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.tab-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.small[_ngcontent-%COMP%] {\n align-self: flex-start;\n padding: 6px 12px;\n font-size: 13px;\n}\n\n.tab-header[_ngcontent-%COMP%] .custom-button.small[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n}\n\n\n\n.variables-list[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.variable-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n align-items: center;\n width: 100%;\n}\n\n.variable-name[_ngcontent-%COMP%] {\n width: 30%; \n\n min-width: 100px;\n}\n\n.variable-type[_ngcontent-%COMP%] {\n width: 25%; \n\n min-width: 80px;\n}\n\n.variable-value[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0; \n\n}\n\n.remove-button[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.add-variable-button[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n\n\n.saved-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.saved-item[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.saved-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.saved-item.current[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.saved-info[_ngcontent-%COMP%] h5[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.saved-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.saved-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n\n\n@media (max-width: 1200px) {\n .sidebar[_ngcontent-%COMP%] {\n width: 320px;\n }\n}\n\n@media (max-width: 992px) {\n .message-user[_ngcontent-%COMP%], \n .message-assistant[_ngcontent-%COMP%] {\n max-width: 85%;\n }\n\n .sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n}\n\n\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n .ai-agent-test-harness .k-dialog-wrapper {\n border-radius: 8px;\n overflow: hidden;\n}\n\n .ai-agent-test-harness .k-dialog-titlebar {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-inverse);\n}\n\n .ai-agent-test-harness .k-dialog-title {\n font-weight: 600;\n}\n\n .ai-agent-test-harness .k-dialog-titlebar-actions .k-button {\n color: var(--mj-text-inverse);\n}\n\n .ai-agent-test-harness .k-dialog-content {\n padding: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n\n\n\n\n\n.advanced-params-panel[_ngcontent-%COMP%] {\n margin-top: 24px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n}\n\n.advanced-params-panel[_ngcontent-%COMP%] .k-expander-title {\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.advanced-settings[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.advanced-param-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.advanced-param-switch[_ngcontent-%COMP%] {\n margin-top: 8px;\n}\n\n\n\n.format-selector[_ngcontent-%COMP%] {\n width: 100%;\n}"] }); }
|
|
3868
3840
|
}
|
|
3869
3841
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AITestHarnessComponent, [{
|
|
3870
3842
|
type: Component,
|
|
3871
|
-
args: [{ standalone: false, selector: 'mj-ai-test-harness', template: "@if (isVisible) {\n <div class=\"harness-container\">\n <!-- Header -->\n <div class=\"harness-header\">\n @if (entity) {\n <div class=\"agent-info\">\n <div class=\"agent-details\">\n @if (hasEntityLogo()) {\n <img [src]=\"getEntityLogoURL()\" [alt]=\"getEntityName() + ' logo'\" class=\"entity-logo\">\n } @else {\n <i [class]=\"getEntityIconClass()\"></i>\n }\n <div>\n <h3>{{ getEntityName() }}</h3>\n @if (entity.Description) {\n <p>{{ entity.Description }}</p>\n }\n </div>\n </div>\n <div class=\"header-actions\">\n <button\n class=\"custom-button\"\n (click)=\"clearConversation()\"\n [disabled]=\"isExecuting || conversationMessages.length === 0\"\n title=\"Clear conversation\">\n <i class=\"fa-solid fa-broom\"></i>\n Clear\n </button>\n <button\n class=\"custom-button\"\n (click)=\"saveConversation()\"\n [disabled]=\"conversationMessages.length === 0\"\n title=\"Save conversation\">\n <i class=\"fa-solid fa-save\"></i>\n Save\n </button>\n <button\n class=\"custom-button\"\n (click)=\"exportConversation()\"\n [disabled]=\"conversationMessages.length === 0\"\n title=\"Export conversation\">\n <i class=\"fa-solid fa-download\"></i>\n Export\n </button>\n <button\n class=\"custom-button\"\n (click)=\"importConversation()\"\n title=\"Import conversation\">\n <i class=\"fa-solid fa-upload\"></i>\n Import\n </button>\n <input\n #fileInput\n type=\"file\"\n accept=\".json\"\n style=\"display: none\"\n (change)=\"onFileSelected($event)\">\n <button\n class=\"custom-button icon-only\"\n (click)=\"toggleSidebar()\"\n title=\"Toggle sidebar\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!showSidebar\" [class.fa-chevron-left]=\"showSidebar\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n <!-- Main Content Area with Splitter -->\n <div class=\"harness-body\">\n @if (showSidebar) {\n <as-split\n direction=\"horizontal\"\n style=\"height: 100%; width: 100%;\">\n <!-- Chat Area (Left Pane) -->\n <as-split-area\n [size]=\"70\">\n <div class=\"chat-area\">\n <!-- Messages Container -->\n <div class=\"messages-container\" #messagesContainer>\n @if (conversationMessages.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comments\"></i>\n <h4>Start a conversation</h4>\n <p>Send a message to begin testing the AI agent</p>\n </div>\n }\n @for (message of conversationMessages; track message.id) {\n <div [ngClass]=\"getMessageClass(message)\">\n <div class=\"message-header\">\n <span class=\"message-role\">\n @if (message.role === 'user') {\n <i class=\"fa-solid fa-user\"></i> You\n } @else {\n @if (hasEntityLogo()) {\n <img [src]=\"getEntityLogoURL()\" [alt]=\"getEntityName() + ' logo'\" class=\"message-role-logo\">\n } @else {\n <i [class]=\"getEntityIconClass()\"></i>\n }\n {{ getEntityName() || 'Assistant' }}\n }\n </span>\n <span class=\"message-time\">{{ formatTimestamp(message.timestamp) }}</span>\n @if (message.isStreaming && message.elapsedTime !== undefined) {\n <span class=\"execution-time streaming\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> {{ formatElapsedTime(message.elapsedTime) }}\n </span>\n } @else if (message.executionTime) {\n <span class=\"execution-time\" [title]=\"getExecutionSummary(message)\">{{ formatExecutionTime(message.executionTime) }}</span>\n }\n @if (showRawToggle(message)) {\n <button class=\"raw-toggle\" (click)=\"showRawJsonDialog(message)\" title=\"View raw JSON response\">\n <i class=\"fa-solid fa-code\"></i>\n </button>\n }\n </div>\n <div class=\"message-content\">\n <button class=\"copy-button-in-bubble\" (click)=\"copyMessage(message)\" title=\"Copy message\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n @if (message.isStreaming) {\n <div class=\"streaming-wrapper\">\n <span class=\"streaming-content\" [innerHTML]=\"getFormattedStreamingContent(message)\"></span>\n <span class=\"cursor\">|</span>\n </div>\n } @else {\n <div [innerHTML]=\"getFormattedContent(message)\"></div>\n }\n @if (message.error) {\n <div class=\"error-details\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ message.error }}\n </div>\n }\n @if (hasPayload(message.payload) && mode === 'agent' && message.role === 'assistant') {\n <div class=\"payload-section\" [class.collapsed]=\"message.payloadCollapsed\">\n <div class=\"payload-header\" (click)=\"togglePayloadCollapse(message)\">\n <span class=\"payload-label\">\n <i class=\"fa-solid fa-code\"></i> Payload\n </span>\n <button class=\"payload-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!message.payloadCollapsed\" [class.fa-chevron-right]=\"message.payloadCollapsed\"></i>\n </button>\n </div>\n @if (!message.payloadCollapsed) {\n <div class=\"payload-content\">\n <mj-code-editor\n [ngModel]=\"formatJson(message.payload)\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n style=\"height: 300px; width: 100%;\">\n </mj-code-editor>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <!-- Input Area -->\n <div class=\"input-area\">\n @if (originalPromptRunId && conversationMessages.length > 0) {\n <!-- Re-run mode - show loaded message -->\n <div class=\"rerun-mode-container\">\n <div class=\"rerun-message\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n <span>Messages from Prompt Run <strong>{{ originalPromptRunId.substring(0, 8) }}</strong> loaded above</span>\n </div>\n <div class=\"rerun-buttons\">\n @if (!hasExecutedRerun) {\n <!-- Show Re-Run button if we haven't executed yet -->\n <button\n class=\"send-button rerun-button\"\n (click)=\"executeRerun()\"\n [disabled]=\"isExecuting\"\n title=\"Re-run with loaded messages\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Running...</span>\n } @else {\n <i class=\"fa-solid fa-play\"></i>\n <span>Re-Run</span>\n }\n </button>\n } @else {\n <!-- Show only Reset button after execution -->\n <button\n class=\"send-button reset-button\"\n (click)=\"resetToOriginalMessages()\"\n [disabled]=\"isExecuting\"\n title=\"Reset conversation messages to the original state from the prompt run. Model settings and parameters will be preserved.\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n <span>Reset Messages</span>\n </button>\n }\n </div>\n </div>\n } @else {\n <!-- Normal mode - show text input -->\n <div class=\"input-container\">\n <textarea\n #messageInput\n class=\"mj-textarea message-input\"\n [(ngModel)]=\"currentUserMessage\"\n [rows]=\"3\"\n placeholder=\"Type your message here... (Press Enter to send, Shift+Enter for new line)\"\n (keypress)=\"handleKeyPress($event)\"\n [disabled]=\"isExecuting\"></textarea>\n <button\n class=\"send-button\"\n (click)=\"sendMessage()\"\n [disabled]=\"isExecuting || !currentUserMessage.trim()\"\n title=\"Send message\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n </button>\n </div>\n }\n </div>\n </div>\n </as-split-area>\n <!-- Sidebar (Right Pane) -->\n <as-split-area\n [size]=\"30\">\n <div class=\"sidebar\">\n <!-- Tab Navigation -->\n <div class=\"sidebar-tabs\">\n @if (mode === 'agent') {\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'agentVariables'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'agentVariables'\"\n (click)=\"selectTab('agentVariables')\">\n <i class=\"fa-solid fa-code\"></i>\n Agent Variables\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'executionMonitor'\"\n (click)=\"selectTab('executionMonitor')\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n Execution Monitor\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'agentSettings'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'agentSettings'\"\n (click)=\"selectTab('agentSettings')\">\n <i class=\"fa-solid fa-sliders\"></i>\n Settings\n </button>\n } @else {\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'templateVariables'\"\n (click)=\"selectTab('templateVariables')\">\n <i class=\"fa-solid fa-code\"></i>\n Template Variables\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'modelSettings'\"\n (click)=\"selectTab('modelSettings')\">\n <i class=\"fa-solid fa-sliders\"></i>\n Model Settings\n </button>\n }\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'savedConversations'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'savedConversations'\"\n (click)=\"selectTab('savedConversations')\">\n <i class=\"fa-solid fa-history\"></i>\n Saved\n @if (savedConversations.length > 0) {\n <span class=\"badge\">{{ savedConversations.length }}</span>\n }\n </button>\n </div>\n <!-- Tab Content -->\n <div class=\"sidebar-content\">\n <!-- Agent Variables Tab (Unified) -->\n @if (activeTab === 'agentVariables') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Agent Variables</h4>\n <p>Variables available during agent execution and template rendering</p>\n </div>\n <div class=\"variables-list\">\n @if (agentVariables.length === 0) {\n <div class=\"empty-variables\">\n <p>No variables defined. Click \"Add Variable\" to get started.</p>\n </div>\n }\n @for (variable of agentVariables; track $index) {\n <div class=\"variable-item\">\n <input type=\"text\"\n class=\"mj-input variable-name\"\n [(ngModel)]=\"variable.name\"\n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\" />\n <mj-dropdown\n [(ngModel)]=\"variable.type\"\n [Data]=\"[\n {text: 'String', value: 'string'},\n {text: 'Number', value: 'number'},\n {text: 'Boolean', value: 'boolean'},\n {text: 'Object', value: 'object'}\n ]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"isExecuting\"\n class=\"variable-type\">\n </mj-dropdown>\n <input type=\"text\"\n class=\"mj-input variable-value\"\n [(ngModel)]=\"variable.value\"\n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\" />\n <button\n class=\"remove-button\"\n (click)=\"removeAgentVariable($index)\"\n [disabled]=\"isExecuting\"\n title=\"Remove variable\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n <button\n class=\"add-button\"\n (click)=\"addAgentVariable()\"\n [disabled]=\"isExecuting\">\n <i class=\"fa-solid fa-plus\"></i> Add Variable\n </button>\n </div>\n }\n <!-- Execution Monitor Tab -->\n @if (activeTab === 'executionMonitor') {\n <div class=\"tab-content\" style=\"padding: 0; height: 100%;\">\n <mj-agent-execution-monitor\n [mode]=\"executionMonitorMode\"\n [agentRun]=\"currentAgentRun\"\n [liveSteps]=\"liveAgentSteps\"\n [autoExpand]=\"true\"\n (viewRunClick)=\"navigateToAgentRun($event)\"\n [runId]=\"getLastRunId()\"\n [runType]=\"mode\">\n </mj-agent-execution-monitor>\n </div>\n }\n <!-- Agent Settings Tab -->\n @if (activeTab === 'agentSettings') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Agent Settings</h4>\n <p>Configure agent execution parameters</p>\n </div>\n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <mj-dropdown\n [(ngModel)]=\"agentConfigurationId\"\n [Data]=\"availableConfigurations\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a configuration...\"\n class=\"configuration-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (agentConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (IsConfigMatchById(config, agentConfigurationId) && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Template Variables Tab (Prompt Mode) -->\n @if (activeTab === 'templateVariables') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Template Variables</h4>\n <p>Variables for prompt template rendering</p>\n </div>\n <div class=\"variables-list\">\n @for (variable of templateVariables; track $index) {\n <div class=\"variable-item\">\n <input type=\"text\"\n class=\"mj-input variable-name\"\n [(ngModel)]=\"variable.name\"\n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\" />\n <mj-dropdown\n [(ngModel)]=\"variable.type\"\n [Data]=\"[\n {text: 'String', value: 'string'},\n {text: 'Number', value: 'number'},\n {text: 'Boolean', value: 'boolean'},\n {text: 'Object', value: 'object'}\n ]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"isExecuting\"\n class=\"variable-type\">\n </mj-dropdown>\n <input type=\"text\"\n class=\"mj-input variable-value\"\n [(ngModel)]=\"variable.value\"\n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\" />\n <button\n class=\"remove-button\"\n (click)=\"removeTemplateVariable($index)\"\n title=\"Remove variable\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n <button\n class=\"add-button\"\n (click)=\"addTemplateVariable()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Variable\n </button>\n </div>\n }\n <!-- Model Settings Tab (Prompt Mode) -->\n @if (activeTab === 'modelSettings') {\n <div class=\"tab-content\" style=\"overflow-y: auto;\">\n <div class=\"tab-header\">\n <h4>Model Settings</h4>\n <p>Configure AI model parameters</p>\n <button class=\"custom-button icon-only\" (click)=\"resetToPromptDefaults()\" title=\"Reset to Prompt Settings\">\n <i class=\"fa-solid fa-undo\"></i>\n </button>\n </div>\n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Model</label>\n <mj-dropdown\n [(ngModel)]=\"selectedModelId\"\n (ngModelChange)=\"onModelSelectionChange()\"\n [Data]=\"availableModels\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a model...\"\n class=\"model-selector\">\n </mj-dropdown>\n </div>\n <div class=\"setting-group\">\n <label>AI Vendor</label>\n <mj-dropdown\n [(ngModel)]=\"selectedVendorId\"\n [Data]=\"availableVendors\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"availableVendors.length <= 1 || !selectedModelId\"\n Placeholder=\"Select a vendor...\"\n class=\"vendor-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (!selectedModelId) {\n Using default vendor for the default model\n } @else if (availableVendors.length <= 1) {\n Only one vendor available for this model\n } @else {\n Select the inference provider for this model\n }\n </div>\n </div>\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <mj-dropdown\n [(ngModel)]=\"selectedConfigurationId\"\n [Data]=\"availableConfigurations\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a configuration...\"\n class=\"configuration-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (selectedConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (IsConfigMatchById(config, selectedConfigurationId) && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n <div class=\"setting-group\">\n <label>Response Format</label>\n <mj-dropdown\n [(ngModel)]=\"selectedResponseFormat\"\n [Data]=\"responseFormatOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n Placeholder=\"Select format...\"\n class=\"format-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n Expected format for AI response (defaults to prompt setting)\n </div>\n </div>\n <div class=\"setting-group\">\n <label>Max Tokens</label>\n <mj-numeric-input\n [(ngModel)]=\"maxTokens\"\n [Min]=\"100\"\n [Max]=\"8000\"\n [Step]=\"100\"\n Placeholder=\"Max tokens...\"\n class=\"max-tokens-input\">\n </mj-numeric-input>\n <div class=\"setting-help\">\n Maximum length of generated response\n </div>\n </div>\n <div class=\"setting-group\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\"\n [(ngModel)]=\"skipValidation\"\n class=\"skip-validation-checkbox\">\n Skip Validation\n </label>\n <div class=\"setting-help\">\n Skip output validation during testing\n </div>\n </div>\n <!-- Advanced Parameters Expansion Panel -->\n <mj-accordion-panel\n [Title]=\"'Advanced Parameters'\"\n [Expanded]=\"advancedParamsExpanded\"\n class=\"advanced-params-panel\">\n <div class=\"advanced-settings\">\n <div class=\"setting-group\">\n <label title=\"Controls randomness: 0 = more focused and deterministic, 2 = more random and creative\">\n Temperature\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.temperature\"\n [Min]=\"0\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Nucleus sampling: only consider tokens with cumulative probability up to this value. 1 = consider all tokens\">\n Top P\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topP\"\n [Min]=\"0\"\n [Max]=\"1\"\n [Step]=\"0.01\"\n [Format]=\"'n2'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Only sample from the top K tokens. Lower values reduce randomness\">\n Top K\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topK\"\n [Min]=\"1\"\n [Max]=\"100\"\n [Step]=\"1\"\n [Format]=\"'n0'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Minimum probability for token selection. Filters out low-probability tokens\">\n Min P\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.minP\"\n [Min]=\"0\"\n [Max]=\"1\"\n [Step]=\"0.01\"\n [Format]=\"'n2'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Penalizes tokens based on their frequency in the text. Positive values reduce repetition\">\n Frequency Penalty\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.frequencyPenalty\"\n [Min]=\"-2\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Penalizes tokens that have appeared in the text. Positive values increase topic diversity\">\n Presence Penalty\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.presencePenalty\"\n [Min]=\"-2\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Random seed for deterministic generation. Same seed produces same output\">\n Seed\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.seed\"\n [Format]=\"'n0'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Sequences that will stop generation when encountered. Enter comma-separated values\">\n Stop Sequences\n </label>\n <textarea\n class=\"mj-textarea advanced-param-input\"\n [(ngModel)]=\"stopSequencesText\"\n (ngModelChange)=\"updateStopSequences()\"\n [rows]=\"2\"\n placeholder=\"Enter comma-separated sequences\"></textarea>\n <div class=\"setting-help\">\n Separate multiple sequences with commas\n </div>\n </div>\n <div class=\"setting-group\">\n <label title=\"Include log probabilities of the output tokens in the response\">\n Include Log Probs\n </label>\n <mj-switch\n [(ngModel)]=\"advancedParams.includeLogProbs\"\n class=\"advanced-param-switch\">\n </mj-switch>\n </div>\n @if (advancedParams.includeLogProbs) {\n <div class=\"setting-group\">\n <label title=\"Number of top log probabilities to include for each token\">\n Top Log Probs\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topLogProbs\"\n [Min]=\"2\"\n [Max]=\"20\"\n [Step]=\"1\"\n [Format]=\"'n0'\"\n Placeholder=\"2\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n }\n </div>\n </mj-accordion-panel>\n </div>\n </div>\n }\n <!-- Saved Conversations Tab -->\n @if (activeTab === 'savedConversations') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Saved Conversations</h4>\n <p>Previously saved test sessions</p>\n @if (currentConversationId) {\n <button class=\"custom-button small primary\" (click)=\"newConversation()\" title=\"Start a new conversation\">\n <i class=\"fa-solid fa-plus\"></i>\n New\n </button>\n }\n </div>\n <div class=\"saved-list\">\n @if (savedConversations.length === 0) {\n <div class=\"empty-saved\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <p>No saved conversations</p>\n </div>\n }\n @for (conv of savedConversations; track conv.id) {\n <div class=\"saved-item\"\n [class.current]=\"conv.id === currentConversationId\"\n (click)=\"loadConversation(conv)\">\n <div class=\"saved-info\">\n <h5>{{ conv.name }}</h5>\n <p>{{ conv.messages.length }} messages</p>\n <span class=\"saved-date\">{{ conv.updatedAt | date:'short' }}</span>\n </div>\n <button\n class=\"delete-button\"\n (click)=\"deleteConversation(conv, $event)\"\n title=\"Delete conversation\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </as-split-area>\n </as-split>\n } @else {\n <!-- No sidebar - full width chat -->\n <div class=\"chat-area\">\n <!-- Messages Container -->\n <div class=\"messages-container\" #messagesContainer>\n @if (conversationMessages.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comments\"></i>\n <h4>Start a conversation</h4>\n <p>Send a message to begin testing the AI agent</p>\n </div>\n }\n @for (message of conversationMessages; track message.id) {\n <div [ngClass]=\"getMessageClass(message)\">\n <div class=\"message-header\">\n <span class=\"message-role\">\n @if (message.role === 'user') {\n <i class=\"fa-solid fa-user\"></i> You\n } @else {\n <i class=\"fa-solid fa-robot\"></i> {{ getEntityName() || 'Assistant' }}\n }\n </span>\n <span class=\"message-time\">{{ formatTimestamp(message.timestamp) }}</span>\n @if (message.isStreaming && message.elapsedTime !== undefined) {\n <span class=\"execution-time streaming\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> {{ formatElapsedTime(message.elapsedTime) }}\n </span>\n } @else if (message.executionTime) {\n <span class=\"execution-time\" [title]=\"getExecutionSummary(message)\">{{ formatExecutionTime(message.executionTime) }}</span>\n }\n @if (showRawToggle(message)) {\n <button class=\"raw-toggle\" (click)=\"showRawJsonDialog(message)\" title=\"View raw JSON response\">\n <i class=\"fa-solid fa-code\"></i>\n </button>\n }\n @if (message.executionData && mode === 'agent' && message.role === 'assistant') {\n <button class=\"execution-history-toggle\" (click)=\"showMessageExecutionHistory(message)\" title=\"View execution details\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n </button>\n }\n @if (message.agentRunId && mode === 'agent' && message.role === 'assistant') {\n <button class=\"execution-history-toggle\" (click)=\"navigateToAgentRun({runId: message.agentRunId, runType: 'agent'})\" title=\"View full run details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n }\n </div>\n <div class=\"message-content\">\n <button class=\"copy-button-in-bubble\" (click)=\"copyMessage(message)\" title=\"Copy message\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n @if (message.isStreaming) {\n <div class=\"streaming-wrapper\">\n <span class=\"streaming-content\">{{ message.streamingContent }}<span class=\"cursor\">|</span></span>\n </div>\n } @else {\n <div [innerHTML]=\"getFormattedContent(message)\"></div>\n }\n @if (message.error) {\n <div class=\"error-details\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ message.error }}\n </div>\n }\n @if (hasPayload(message.payload) && mode === 'agent' && message.role === 'assistant') {\n <div class=\"payload-section\" [class.collapsed]=\"message.payloadCollapsed\">\n <div class=\"payload-header\" (click)=\"togglePayloadCollapse(message)\">\n <span class=\"payload-label\">\n <i class=\"fa-solid fa-code\"></i> Payload\n </span>\n <button class=\"payload-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!message.payloadCollapsed\" [class.fa-chevron-right]=\"message.payloadCollapsed\"></i>\n </button>\n </div>\n @if (!message.payloadCollapsed) {\n <div class=\"payload-content\">\n <pre>{{ formatJson(message.payload) }}</pre>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <!-- Input Area -->\n <div class=\"input-area\">\n <div class=\"input-container\">\n <textarea\n #messageInput\n class=\"mj-textarea message-input\"\n [(ngModel)]=\"currentUserMessage\"\n [rows]=\"3\"\n placeholder=\"Type your message here... (Press Enter to send, Shift+Enter for new line)\"\n (keypress)=\"handleKeyPress($event)\"\n [disabled]=\"isExecuting\"></textarea>\n <button\n class=\"send-button\"\n (click)=\"sendMessage()\"\n [disabled]=\"isExecuting || !currentUserMessage.trim()\"\n title=\"Send message\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n<!-- Save Conversation Dialog -->\n@if (showSaveDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"400\"\n (Close)=\"cancelSaveDialog()\"\n class=\"save-dialog\">\n <mj-dialog-titlebar>Save Conversation</mj-dialog-titlebar>\n <div class=\"dialog-content\">\n <p>Enter a name for this conversation:</p>\n <input\n #saveDialogInput\n type=\"text\"\n (keyup)=\"updateTempConversation()\"\n placeholder=\"Conversation name\"\n class=\"mj-input full-width\" />\n </div>\n <mj-dialog-actions>\n <button mjButton (click)=\"cancelSaveDialog()\">Cancel</button>\n <button mjButton\n variant=\"primary\"\n (click)=\"confirmSaveConversation()\"\n [disabled]=\"tempConversationName === ''\">\n Save\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Load Confirmation Dialog -->\n@if (showLoadConfirmDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"400\"\n (Close)=\"cancelLoadConversation()\"\n class=\"confirm-dialog\">\n <mj-dialog-titlebar>Replace Current Conversation?</mj-dialog-titlebar>\n <div class=\"dialog-content\">\n <p>Loading this conversation will replace the current one. Any unsaved changes will be lost.</p>\n <p>Do you want to continue?</p>\n </div>\n <mj-dialog-actions>\n <button mjButton (click)=\"cancelLoadConversation()\">Cancel</button>\n <button mjButton\n variant=\"primary\"\n (click)=\"confirmLoadConversation()\">\n Load Conversation\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- JSON Viewer Window -->\n@if (showJsonWindow) {\n <mj-window\n [Visible]=\"true\"\n Title=\"Raw JSON Response\"\n [Width]=\"900\"\n [Height]=\"700\"\n [MinWidth]=\"600\"\n [MinHeight]=\"400\"\n [Draggable]=\"true\"\n [Resizable]=\"true\"\n (Close)=\"closeJsonWindow()\">\n <mj-json-viewer-window [jsonContent]=\"currentJsonContent\"></mj-json-viewer-window>\n </mj-window>\n}\n\n", styles: ["/* Container Styles */\n.harness-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n/* Custom Button Styles */\n.custom-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.custom-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.custom-button:active:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.custom-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.custom-button.icon-only {\n padding: 6px 8px;\n}\n\n.custom-button i {\n font-size: 14px;\n}\n\n/* Send Button - Primary Style */\n.send-button {\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 44px;\n font-family: inherit;\n}\n\n.send-button:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button:active:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.send-button i {\n font-size: 16px;\n}\n\n/* Add Button */\n.add-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.add-button:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Remove/Delete Buttons */\n.remove-button,\n.delete-button {\n background: transparent;\n border: none;\n color: var(--mj-status-error);\n padding: 4px 8px;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n border-radius: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.remove-button:hover,\n.delete-button:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-color-error-600);\n}\n\n/* Copy Button in Message Bubble */\n.copy-button-in-bubble {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n padding: 6px;\n font-size: 14px;\n color: var(--mj-border-strong);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n opacity: 0;\n z-index: 10; /* Ensure it's above content */\n}\n\n.message-content:hover .copy-button-in-bubble {\n opacity: 1;\n}\n\n.copy-button-in-bubble:hover {\n background: rgba(0, 0, 0, 0.08);\n color: var(--mj-text-muted);\n}\n\n.copy-button-in-bubble i {\n font-size: 14px;\n}\n\n/* Model Settings Styles (Prompt Mode) */\n.model-settings {\n padding: 16px;\n}\n\n.setting-group {\n margin-bottom: 24px;\n}\n\n.setting-group label {\n display: block;\n margin-bottom: 8px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.model-selector,\n.vendor-selector {\n width: 100%;\n}\n\n.temperature-slider {\n width: 100%;\n margin-top: 8px;\n}\n\n.max-tokens-input {\n width: 100%;\n}\n\n.setting-help {\n margin-top: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Checkbox Styles */\n.checkbox-label {\n display: flex;\n align-items: center;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n}\n\n.skip-validation-checkbox {\n margin-right: 8px;\n cursor: pointer;\n width: 16px;\n height: 16px;\n}\n\n/* Header Styles */\n.harness-header {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 16px 20px;\n}\n\n.agent-info {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.agent-details {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.agent-details i {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.agent-details .entity-logo {\n width: 40px;\n height: 40px;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-details h3 {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.agent-details p {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n}\n\n/* Body Layout */\n.harness-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n/* Chat Area */\n.chat-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n height: 100%;\n min-height: 0; /* Important for flexbox children */\n}\n\n/* Messages Container */\n.messages-container {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: var(--mj-text-muted);\n}\n\n.empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 500;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n/* Message Styles */\n.message {\n margin-bottom: 20px;\n animation: fadeIn 0.3s ease-in;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-user {\n margin-left: auto;\n max-width: 70%;\n}\n\n.message-assistant {\n margin-right: auto;\n max-width: 70%;\n}\n\n.message-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 13px;\n}\n\n.message-role {\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.message-role i {\n font-size: 14px;\n}\n\n.message-role .message-role-logo {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.message-user .message-role {\n color: var(--mj-brand-primary);\n}\n\n.message-assistant .message-role {\n color: var(--mj-brand-primary);\n}\n\n.message-time {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.execution-time {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.raw-toggle {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n}\n\n.raw-toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-secondary);\n}\n\n.raw-toggle i {\n font-size: 12px;\n}\n\n/* Message content styles are now defined above in enhanced content formatting section */\n\n.message-user .message-content {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.message-assistant .message-content {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.message.streaming .message-content {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.streaming-content {\n display: inline;\n}\n\n.streaming-wrapper {\n position: relative;\n}\n\n.streaming-wrapper .cursor {\n display: inline;\n margin-left: 2px;\n}\n\n.cursor {\n animation: blink 1s infinite;\n font-weight: 100;\n color: var(--mj-text-secondary);\n}\n\n@keyframes blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n}\n\n.error-details {\n margin-top: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 6px;\n color: var(--mj-color-error-600);\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details i {\n color: var(--mj-status-error);\n}\n\n/* Payload Section Styles */\n.payload-section {\n margin-top: 12px;\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.payload-header {\n background: var(--mj-bg-surface-card);\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.payload-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.payload-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.payload-content {\n max-height: 250px;\n overflow: auto;\n background: var(--mj-bg-surface-card);\n}\n\n.payload-content pre {\n margin: 0;\n padding: 12px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n background: transparent;\n}\n\n.payload-toggle {\n background: transparent;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.payload-toggle:hover {\n color: var(--mj-text-secondary);\n}\n\n.payload-toggle i {\n font-size: 12px;\n}\n\n.payload-section.collapsed .payload-header {\n border-bottom: none;\n}\n\n/* Dialog styles */\n.save-dialog,\n.confirm-dialog {\n .dialog-content {\n padding: 20px;\n\n p {\n margin: 0 0 16px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .full-width {\n width: 100%;\n }\n\n input.k-textbox {\n padding: 8px 12px;\n font-size: 14px;\n line-height: 1.5;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n\n &:focus {\n outline: none;\n border-color: var(--mj-status-error);\n box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--mj-status-error) 25%, transparent);\n }\n }\n }\n}\n\n/* Enhanced content formatting styles */\n.markdown-content {\n line-height: 1.6;\n word-wrap: break-word;\n overflow-wrap: break-word;\n max-width: 100%;\n}\n\n/* Inline JSON editor styles */\n.inline-json-editor {\n margin: 8px 0;\n\n .json-editor-container {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n max-height: 400px;\n\n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;\n font-size: 13px;\n line-height: 1.5;\n overflow: auto;\n height: 100%;\n background: transparent;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n }\n}\n\n.markdown-paragraph {\n margin: 8px 0;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.markdown-h1 {\n font-size: 1.5em;\n font-weight: 600;\n margin: 16px 0 8px 0;\n color: var(--mj-text-primary);\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n padding-bottom: 4px;\n}\n\n.markdown-h2 {\n font-size: 1.3em;\n font-weight: 600;\n margin: 14px 0 6px 0;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n padding-bottom: 2px;\n}\n\n.markdown-h3 {\n font-size: 1.1em;\n font-weight: 600;\n margin: 12px 0 4px 0;\n color: var(--mj-text-primary);\n}\n\n.code-block {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 16px;\n margin: 12px 0;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre;\n word-wrap: normal;\n max-width: 100%;\n}\n\n.code-block code {\n background: none;\n border: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre;\n word-wrap: normal;\n}\n\n.language-json {\n color: var(--mj-status-error);\n}\n\n.inline-code {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 0.9em;\n color: var(--mj-status-error);\n white-space: nowrap;\n}\n\n.markdown-list {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.markdown-list li {\n margin: 4px 0;\n line-height: 1.5;\n}\n\n.markdown-link {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: none;\n}\n\n/* Ensure proper text wrapping in message content */\n.message-content {\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n padding: 12px 40px 12px 16px; /* Extra right padding for copy button */\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n position: relative;\n overflow-wrap: break-word;\n hyphens: auto;\n max-width: 100%;\n overflow-x: hidden;\n}\n\n/* Enhanced JSON content display */\n.json-content-wrapper {\n margin: 8px 0;\n}\n\n.json-main-content {\n margin-bottom: 12px;\n}\n\n.json-raw-section {\n margin-top: 12px;\n}\n\n.json-toggle-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.json-toggle-button:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.json-toggle-button i {\n font-size: 12px;\n}\n\n/* Compact code block for JSON in collapsible sections */\n.json-raw-section .code-block {\n margin: 8px 0 0 0;\n font-size: 12px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n/* Better mobile responsiveness for JSON content */\n@media (max-width: 768px) {\n .json-raw-section .code-block {\n font-size: 11px;\n max-height: 200px;\n }\n}\n\n/* JSON raw section styling - simplified since we use code editor in dialog */\n.json-raw-section {\n margin-top: 12px;\n}\n\n/* Input Area */\n.input-area {\n padding: 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0; /* Prevent input area from shrinking */\n margin-top: auto; /* Push to bottom */\n}\n\n.input-container {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.rerun-mode-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 8px;\n gap: 16px;\n}\n\n.rerun-message {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.rerun-message i {\n font-size: 16px;\n}\n\n.rerun-message strong {\n font-family: 'Fira Code', 'Consolas', monospace;\n}\n\n.rerun-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 100px;\n justify-content: center;\n}\n\n.rerun-button span {\n font-weight: 500;\n}\n\n.rerun-buttons {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.reset-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 120px;\n justify-content: center;\n background-color: var(--mj-text-muted);\n}\n\n.reset-button:hover:not(:disabled) {\n background-color: var(--mj-text-secondary);\n}\n\n.reset-button span {\n font-weight: 500;\n}\n\n.message-input {\n flex: 1;\n}\n\n.message-input textarea {\n resize: none;\n font-size: 14px;\n}\n\n.send-button {\n margin-bottom: 1px;\n}\n\n/* Sidebar */\n.sidebar {\n width: 100%; /* Changed from fixed 360px to 100% */\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* Sidebar Tabs */\n.sidebar-tabs {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tab-button {\n flex: 1;\n padding: 12px 8px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.2s;\n position: relative;\n}\n\n.tab-button:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.tab-button.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.tab-button i {\n font-size: 14px;\n}\n\n.tab-button .badge {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n margin-left: 4px;\n}\n\n.tab-button.active .badge {\n background: var(--mj-brand-primary);\n}\n\n.tab-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* Sidebar Content */\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n width: 100%; /* Ensure content takes full width */\n}\n\n.tab-content {\n padding: 20px;\n width: 100%; /* Ensure content takes full width */\n box-sizing: border-box; /* Include padding in width calculation */\n}\n\n.tab-header {\n margin-bottom: 20px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.tab-header .custom-button.icon-only {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.tab-header h4 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.tab-header p {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.tab-header .custom-button.small {\n align-self: flex-start;\n padding: 6px 12px;\n font-size: 13px;\n}\n\n.tab-header .custom-button.small i {\n margin-right: 4px;\n}\n\n/* Variables */\n.variables-list {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.variable-item {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n align-items: center;\n width: 100%;\n}\n\n.variable-name {\n width: 30%; /* Changed from fixed width to percentage */\n min-width: 100px;\n}\n\n.variable-type {\n width: 25%; /* Changed from fixed width to percentage */\n min-width: 80px;\n}\n\n.variable-value {\n flex: 1;\n min-width: 0; /* Allow flex item to shrink below content size */\n}\n\n.remove-button {\n width: 32px;\n height: 32px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.add-variable-button {\n width: 100%;\n}\n\n.empty-variables {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n/* Saved Conversations */\n.saved-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.empty-saved {\n text-align: center;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.empty-saved i {\n font-size: 36px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n.saved-item {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.saved-item:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.saved-item.current {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.saved-info h5 {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.saved-info p {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.saved-date {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* Responsive adjustments */\n@media (max-width: 1200px) {\n .sidebar {\n width: 320px;\n }\n}\n\n@media (max-width: 992px) {\n .message-user,\n .message-assistant {\n max-width: 85%;\n }\n\n .sidebar {\n width: 280px;\n }\n}\n\n/* Custom scrollbar */\n.messages-container::-webkit-scrollbar,\n.sidebar-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.messages-container::-webkit-scrollbar-track,\n.sidebar-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.messages-container::-webkit-scrollbar-thumb,\n.sidebar-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.messages-container::-webkit-scrollbar-thumb:hover,\n.sidebar-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Dialog customization */\n::ng-deep .ai-agent-test-harness .k-dialog-wrapper {\n border-radius: 8px;\n overflow: hidden;\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-titlebar {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-inverse);\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-title {\n font-weight: 600;\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-titlebar-actions .k-button {\n color: var(--mj-text-inverse);\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-content {\n padding: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* JSON Dialog Styles - removed since we're using WindowService */\n\n/* Advanced Parameters Styles */\n.advanced-params-panel {\n margin-top: 24px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n}\n\n.advanced-params-panel ::ng-deep .k-expander-title {\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.advanced-settings {\n padding: 16px;\n}\n\n.advanced-param-input {\n width: 100%;\n}\n\n.advanced-param-switch {\n margin-top: 8px;\n}\n\n/* Format selector dropdown */\n.format-selector {\n width: 100%;\n}\n"] }]
|
|
3872
|
-
}], () => [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }], { mode: [{
|
|
3843
|
+
args: [{ standalone: false, selector: 'mj-ai-test-harness', template: "@if (isVisible) {\n <div class=\"harness-container\">\n <!-- Header -->\n <div class=\"harness-header\">\n @if (entity) {\n <div class=\"agent-info\">\n <div class=\"agent-details\">\n @if (hasEntityLogo()) {\n <img [src]=\"getEntityLogoURL()\" [alt]=\"getEntityName() + ' logo'\" class=\"entity-logo\">\n } @else {\n <i [class]=\"getEntityIconClass()\"></i>\n }\n <div>\n <h3>{{ getEntityName() }}</h3>\n @if (entity.Description) {\n <p>{{ entity.Description }}</p>\n }\n </div>\n </div>\n <div class=\"header-actions\">\n <button\n class=\"custom-button\"\n (click)=\"clearConversation()\"\n [disabled]=\"isExecuting || conversationMessages.length === 0\"\n title=\"Clear conversation\">\n <i class=\"fa-solid fa-broom\"></i>\n Clear\n </button>\n <button\n class=\"custom-button\"\n (click)=\"saveConversation()\"\n [disabled]=\"conversationMessages.length === 0\"\n title=\"Save conversation\">\n <i class=\"fa-solid fa-save\"></i>\n Save\n </button>\n <button\n class=\"custom-button\"\n (click)=\"exportConversation()\"\n [disabled]=\"conversationMessages.length === 0\"\n title=\"Export conversation\">\n <i class=\"fa-solid fa-download\"></i>\n Export\n </button>\n <button\n class=\"custom-button\"\n (click)=\"importConversation()\"\n title=\"Import conversation\">\n <i class=\"fa-solid fa-upload\"></i>\n Import\n </button>\n <input\n #fileInput\n type=\"file\"\n accept=\".json\"\n style=\"display: none\"\n (change)=\"onFileSelected($event)\">\n <button\n class=\"custom-button icon-only\"\n (click)=\"toggleSidebar()\"\n title=\"Toggle sidebar\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!showSidebar\" [class.fa-chevron-left]=\"showSidebar\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n <!-- Main Content Area with Splitter -->\n <div class=\"harness-body\">\n @if (showSidebar) {\n <as-split\n direction=\"horizontal\"\n style=\"height: 100%; width: 100%;\">\n <!-- Chat Area (Left Pane) -->\n <as-split-area\n [size]=\"70\">\n <div class=\"chat-area\">\n <!-- Messages Container -->\n <div class=\"messages-container\" #messagesContainer>\n @if (conversationMessages.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-comments\"\n Title=\"Start a conversation\"\n Message=\"Send a message to begin testing the AI agent\" />\n }\n @for (message of conversationMessages; track message.id) {\n <div [ngClass]=\"getMessageClass(message)\">\n <div class=\"message-header\">\n <span class=\"message-role\">\n @if (message.role === 'user') {\n <i class=\"fa-solid fa-user\"></i> You\n } @else {\n @if (hasEntityLogo()) {\n <img [src]=\"getEntityLogoURL()\" [alt]=\"getEntityName() + ' logo'\" class=\"message-role-logo\">\n } @else {\n <i [class]=\"getEntityIconClass()\"></i>\n }\n {{ getEntityName() || 'Assistant' }}\n }\n </span>\n <span class=\"message-time\">{{ formatTimestamp(message.timestamp) }}</span>\n @if (message.isStreaming && message.elapsedTime !== undefined) {\n <span class=\"execution-time streaming\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> {{ formatElapsedTime(message.elapsedTime) }}\n </span>\n } @else if (message.executionTime) {\n <span class=\"execution-time\" [title]=\"getExecutionSummary(message)\">{{ formatExecutionTime(message.executionTime) }}</span>\n }\n @if (showRawToggle(message)) {\n <button class=\"raw-toggle\" (click)=\"showRawJsonDialog(message)\" title=\"View raw JSON response\">\n <i class=\"fa-solid fa-code\"></i>\n </button>\n }\n </div>\n <div class=\"message-content\">\n <button class=\"copy-button-in-bubble\" (click)=\"copyMessage(message)\" title=\"Copy message\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n @if (message.isStreaming) {\n <div class=\"streaming-wrapper\">\n <span class=\"streaming-content\" [innerHTML]=\"getFormattedStreamingContent(message)\"></span>\n <span class=\"cursor\">|</span>\n </div>\n } @else {\n <div [innerHTML]=\"getFormattedContent(message)\"></div>\n }\n @if (message.error) {\n <div class=\"error-details\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ message.error }}\n </div>\n }\n @if (hasPayload(message.payload) && mode === 'agent' && message.role === 'assistant') {\n <div class=\"payload-section\" [class.collapsed]=\"message.payloadCollapsed\">\n <div class=\"payload-header\" (click)=\"togglePayloadCollapse(message)\">\n <span class=\"payload-label\">\n <i class=\"fa-solid fa-code\"></i> Payload\n </span>\n <button class=\"payload-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!message.payloadCollapsed\" [class.fa-chevron-right]=\"message.payloadCollapsed\"></i>\n </button>\n </div>\n @if (!message.payloadCollapsed) {\n <div class=\"payload-content\">\n <mj-code-editor\n [ngModel]=\"formatJson(message.payload)\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n style=\"height: 300px; width: 100%;\">\n </mj-code-editor>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <!-- Input Area -->\n <div class=\"input-area\">\n @if (originalPromptRunId && conversationMessages.length > 0) {\n <!-- Re-run mode - show loaded message -->\n <div class=\"rerun-mode-container\">\n <div class=\"rerun-message\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n <span>Messages from Prompt Run <strong>{{ originalPromptRunId.substring(0, 8) }}</strong> loaded above</span>\n </div>\n <div class=\"rerun-buttons\">\n @if (!hasExecutedRerun) {\n <!-- Show Re-Run button if we haven't executed yet -->\n <button\n class=\"send-button rerun-button\"\n (click)=\"executeRerun()\"\n [disabled]=\"isExecuting\"\n title=\"Re-run with loaded messages\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Running...</span>\n } @else {\n <i class=\"fa-solid fa-play\"></i>\n <span>Re-Run</span>\n }\n </button>\n } @else {\n <!-- Show only Reset button after execution -->\n <button\n class=\"send-button reset-button\"\n (click)=\"resetToOriginalMessages()\"\n [disabled]=\"isExecuting\"\n title=\"Reset conversation messages to the original state from the prompt run. Model settings and parameters will be preserved.\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n <span>Reset Messages</span>\n </button>\n }\n </div>\n </div>\n } @else {\n <!-- Normal mode - show text input -->\n <div class=\"input-container\">\n <textarea\n #messageInput\n class=\"mj-textarea message-input\"\n [(ngModel)]=\"currentUserMessage\"\n [rows]=\"3\"\n placeholder=\"Type your message here... (Press Enter to send, Shift+Enter for new line)\"\n (keypress)=\"handleKeyPress($event)\"\n [disabled]=\"isExecuting\"></textarea>\n <button\n class=\"send-button\"\n (click)=\"sendMessage()\"\n [disabled]=\"isExecuting || !currentUserMessage.trim()\"\n title=\"Send message\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n </button>\n </div>\n }\n </div>\n </div>\n </as-split-area>\n <!-- Sidebar (Right Pane) -->\n <as-split-area\n [size]=\"30\">\n <div class=\"sidebar\">\n <!-- Tab Navigation -->\n <div class=\"sidebar-tabs\">\n @if (mode === 'agent') {\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'agentVariables'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'agentVariables'\"\n (click)=\"selectTab('agentVariables')\">\n <i class=\"fa-solid fa-code\"></i>\n Agent Variables\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'executionMonitor'\"\n (click)=\"selectTab('executionMonitor')\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n Execution Monitor\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'agentSettings'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'agentSettings'\"\n (click)=\"selectTab('agentSettings')\">\n <i class=\"fa-solid fa-sliders\"></i>\n Settings\n </button>\n } @else {\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'templateVariables'\"\n (click)=\"selectTab('templateVariables')\">\n <i class=\"fa-solid fa-code\"></i>\n Template Variables\n </button>\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'modelSettings'\"\n (click)=\"selectTab('modelSettings')\">\n <i class=\"fa-solid fa-sliders\"></i>\n Model Settings\n </button>\n }\n <button\n class=\"tab-button\"\n [class.active]=\"activeTab === 'savedConversations'\"\n [disabled]=\"executionMonitorMode === 'live' && activeTab !== 'savedConversations'\"\n (click)=\"selectTab('savedConversations')\">\n <i class=\"fa-solid fa-history\"></i>\n Saved\n @if (savedConversations.length > 0) {\n <span class=\"badge\">{{ savedConversations.length }}</span>\n }\n </button>\n </div>\n <!-- Tab Content -->\n <div class=\"sidebar-content\">\n <!-- Agent Variables Tab (Unified) -->\n @if (activeTab === 'agentVariables') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Agent Variables</h4>\n <p>Variables available during agent execution and template rendering</p>\n </div>\n <div class=\"variables-list\">\n @if (agentVariables.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-code\"\n Title=\"No variables defined\"\n Message=\"Click "Add Variable" to get started.\"\n Size=\"compact\" />\n }\n @for (variable of agentVariables; track $index) {\n <div class=\"variable-item\">\n <input type=\"text\"\n class=\"mj-input variable-name\"\n [(ngModel)]=\"variable.name\"\n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\" />\n <mj-dropdown\n [(ngModel)]=\"variable.type\"\n [Data]=\"[\n {text: 'String', value: 'string'},\n {text: 'Number', value: 'number'},\n {text: 'Boolean', value: 'boolean'},\n {text: 'Object', value: 'object'}\n ]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"isExecuting\"\n class=\"variable-type\">\n </mj-dropdown>\n <input type=\"text\"\n class=\"mj-input variable-value\"\n [(ngModel)]=\"variable.value\"\n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\" />\n <button\n class=\"remove-button\"\n (click)=\"removeAgentVariable($index)\"\n [disabled]=\"isExecuting\"\n title=\"Remove variable\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n <button\n class=\"add-button\"\n (click)=\"addAgentVariable()\"\n [disabled]=\"isExecuting\">\n <i class=\"fa-solid fa-plus\"></i> Add Variable\n </button>\n </div>\n }\n <!-- Execution Monitor Tab -->\n @if (activeTab === 'executionMonitor') {\n <div class=\"tab-content\" style=\"padding: 0; height: 100%;\">\n <mj-agent-execution-monitor\n [mode]=\"executionMonitorMode\"\n [agentRun]=\"currentAgentRun\"\n [liveSteps]=\"liveAgentSteps\"\n [autoExpand]=\"true\"\n (viewRunClick)=\"navigateToAgentRun($event)\"\n [runId]=\"getLastRunId()\"\n [runType]=\"mode\">\n </mj-agent-execution-monitor>\n </div>\n }\n <!-- Agent Settings Tab -->\n @if (activeTab === 'agentSettings') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Agent Settings</h4>\n <p>Configure agent execution parameters</p>\n </div>\n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <mj-dropdown\n [(ngModel)]=\"agentConfigurationId\"\n [Data]=\"availableConfigurations\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a configuration...\"\n class=\"configuration-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (agentConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (IsConfigMatchById(config, agentConfigurationId) && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Template Variables Tab (Prompt Mode) -->\n @if (activeTab === 'templateVariables') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Template Variables</h4>\n <p>Variables for prompt template rendering</p>\n </div>\n <div class=\"variables-list\">\n @for (variable of templateVariables; track $index) {\n <div class=\"variable-item\">\n <input type=\"text\"\n class=\"mj-input variable-name\"\n [(ngModel)]=\"variable.name\"\n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\" />\n <mj-dropdown\n [(ngModel)]=\"variable.type\"\n [Data]=\"[\n {text: 'String', value: 'string'},\n {text: 'Number', value: 'number'},\n {text: 'Boolean', value: 'boolean'},\n {text: 'Object', value: 'object'}\n ]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"isExecuting\"\n class=\"variable-type\">\n </mj-dropdown>\n <input type=\"text\"\n class=\"mj-input variable-value\"\n [(ngModel)]=\"variable.value\"\n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\" />\n <button\n class=\"remove-button\"\n (click)=\"removeTemplateVariable($index)\"\n title=\"Remove variable\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n <button\n class=\"add-button\"\n (click)=\"addTemplateVariable()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Variable\n </button>\n </div>\n }\n <!-- Model Settings Tab (Prompt Mode) -->\n @if (activeTab === 'modelSettings') {\n <div class=\"tab-content\" style=\"overflow-y: auto;\">\n <div class=\"tab-header\">\n <h4>Model Settings</h4>\n <p>Configure AI model parameters</p>\n <button class=\"custom-button icon-only\" (click)=\"resetToPromptDefaults()\" title=\"Reset to Prompt Settings\">\n <i class=\"fa-solid fa-undo\"></i>\n </button>\n </div>\n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Model</label>\n <mj-dropdown\n [(ngModel)]=\"selectedModelId\"\n (ngModelChange)=\"onModelSelectionChange()\"\n [Data]=\"availableModels\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a model...\"\n class=\"model-selector\">\n </mj-dropdown>\n </div>\n <div class=\"setting-group\">\n <label>AI Vendor</label>\n <mj-dropdown\n [(ngModel)]=\"selectedVendorId\"\n [Data]=\"availableVendors\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Disabled]=\"availableVendors.length <= 1 || !selectedModelId\"\n Placeholder=\"Select a vendor...\"\n class=\"vendor-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (!selectedModelId) {\n Using default vendor for the default model\n } @else if (availableVendors.length <= 1) {\n Only one vendor available for this model\n } @else {\n Select the inference provider for this model\n }\n </div>\n </div>\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <mj-dropdown\n [(ngModel)]=\"selectedConfigurationId\"\n [Data]=\"availableConfigurations\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select a configuration...\"\n class=\"configuration-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n @if (selectedConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (IsConfigMatchById(config, selectedConfigurationId) && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n <div class=\"setting-group\">\n <label>Response Format</label>\n <mj-dropdown\n [(ngModel)]=\"selectedResponseFormat\"\n [Data]=\"responseFormatOptions\"\n TextField=\"text\"\n ValueField=\"value\"\n Placeholder=\"Select format...\"\n class=\"format-selector\">\n </mj-dropdown>\n <div class=\"setting-help\">\n Expected format for AI response (defaults to prompt setting)\n </div>\n </div>\n <div class=\"setting-group\">\n <label>Max Tokens</label>\n <mj-numeric-input\n [(ngModel)]=\"maxTokens\"\n [Min]=\"100\"\n [Max]=\"8000\"\n [Step]=\"100\"\n Placeholder=\"Max tokens...\"\n class=\"max-tokens-input\">\n </mj-numeric-input>\n <div class=\"setting-help\">\n Maximum length of generated response\n </div>\n </div>\n <div class=\"setting-group\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\"\n [(ngModel)]=\"skipValidation\"\n class=\"skip-validation-checkbox\">\n Skip Validation\n </label>\n <div class=\"setting-help\">\n Skip output validation during testing\n </div>\n </div>\n <!-- Advanced Parameters Expansion Panel -->\n <mj-accordion-panel\n [Title]=\"'Advanced Parameters'\"\n [Expanded]=\"advancedParamsExpanded\"\n class=\"advanced-params-panel\">\n <div class=\"advanced-settings\">\n <div class=\"setting-group\">\n <label title=\"Controls randomness: 0 = more focused and deterministic, 2 = more random and creative\">\n Temperature\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.temperature\"\n [Min]=\"0\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Nucleus sampling: only consider tokens with cumulative probability up to this value. 1 = consider all tokens\">\n Top P\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topP\"\n [Min]=\"0\"\n [Max]=\"1\"\n [Step]=\"0.01\"\n [Format]=\"'n2'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Only sample from the top K tokens. Lower values reduce randomness\">\n Top K\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topK\"\n [Min]=\"1\"\n [Max]=\"100\"\n [Step]=\"1\"\n [Format]=\"'n0'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Minimum probability for token selection. Filters out low-probability tokens\">\n Min P\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.minP\"\n [Min]=\"0\"\n [Max]=\"1\"\n [Step]=\"0.01\"\n [Format]=\"'n2'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Penalizes tokens based on their frequency in the text. Positive values reduce repetition\">\n Frequency Penalty\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.frequencyPenalty\"\n [Min]=\"-2\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Penalizes tokens that have appeared in the text. Positive values increase topic diversity\">\n Presence Penalty\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.presencePenalty\"\n [Min]=\"-2\"\n [Max]=\"2\"\n [Step]=\"0.1\"\n [Format]=\"'n1'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Random seed for deterministic generation. Same seed produces same output\">\n Seed\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.seed\"\n [Format]=\"'n0'\"\n Placeholder=\"None\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n <div class=\"setting-group\">\n <label title=\"Sequences that will stop generation when encountered. Enter comma-separated values\">\n Stop Sequences\n </label>\n <textarea\n class=\"mj-textarea advanced-param-input\"\n [(ngModel)]=\"stopSequencesText\"\n (ngModelChange)=\"updateStopSequences()\"\n [rows]=\"2\"\n placeholder=\"Enter comma-separated sequences\"></textarea>\n <div class=\"setting-help\">\n Separate multiple sequences with commas\n </div>\n </div>\n <div class=\"setting-group\">\n <label title=\"Include log probabilities of the output tokens in the response\">\n Include Log Probs\n </label>\n <mj-switch\n [(ngModel)]=\"advancedParams.includeLogProbs\"\n class=\"advanced-param-switch\">\n </mj-switch>\n </div>\n @if (advancedParams.includeLogProbs) {\n <div class=\"setting-group\">\n <label title=\"Number of top log probabilities to include for each token\">\n Top Log Probs\n </label>\n <mj-numeric-input\n [(ngModel)]=\"advancedParams.topLogProbs\"\n [Min]=\"2\"\n [Max]=\"20\"\n [Step]=\"1\"\n [Format]=\"'n0'\"\n Placeholder=\"2\"\n class=\"advanced-param-input\">\n </mj-numeric-input>\n </div>\n }\n </div>\n </mj-accordion-panel>\n </div>\n </div>\n }\n <!-- Saved Conversations Tab -->\n @if (activeTab === 'savedConversations') {\n <div class=\"tab-content\">\n <div class=\"tab-header\">\n <h4>Saved Conversations</h4>\n <p>Previously saved test sessions</p>\n @if (currentConversationId) {\n <button class=\"custom-button small primary\" (click)=\"newConversation()\" title=\"Start a new conversation\">\n <i class=\"fa-solid fa-plus\"></i>\n New\n </button>\n }\n </div>\n <div class=\"saved-list\">\n @if (savedConversations.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-folder-open\"\n Title=\"No saved conversations\"\n Size=\"compact\" />\n }\n @for (conv of savedConversations; track conv.id) {\n <div class=\"saved-item\"\n [class.current]=\"conv.id === currentConversationId\"\n (click)=\"loadConversation(conv)\">\n <div class=\"saved-info\">\n <h5>{{ conv.name }}</h5>\n <p>{{ conv.messages.length }} messages</p>\n <span class=\"saved-date\">{{ conv.updatedAt | date:'short' }}</span>\n </div>\n <button\n class=\"delete-button\"\n (click)=\"deleteConversation(conv, $event)\"\n title=\"Delete conversation\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </as-split-area>\n </as-split>\n } @else {\n <!-- No sidebar - full width chat -->\n <div class=\"chat-area\">\n <!-- Messages Container -->\n <div class=\"messages-container\" #messagesContainer>\n @if (conversationMessages.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-comments\"\n Title=\"Start a conversation\"\n Message=\"Send a message to begin testing the AI agent\" />\n }\n @for (message of conversationMessages; track message.id) {\n <div [ngClass]=\"getMessageClass(message)\">\n <div class=\"message-header\">\n <span class=\"message-role\">\n @if (message.role === 'user') {\n <i class=\"fa-solid fa-user\"></i> You\n } @else {\n <i class=\"fa-solid fa-robot\"></i> {{ getEntityName() || 'Assistant' }}\n }\n </span>\n <span class=\"message-time\">{{ formatTimestamp(message.timestamp) }}</span>\n @if (message.isStreaming && message.elapsedTime !== undefined) {\n <span class=\"execution-time streaming\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> {{ formatElapsedTime(message.elapsedTime) }}\n </span>\n } @else if (message.executionTime) {\n <span class=\"execution-time\" [title]=\"getExecutionSummary(message)\">{{ formatExecutionTime(message.executionTime) }}</span>\n }\n @if (showRawToggle(message)) {\n <button class=\"raw-toggle\" (click)=\"showRawJsonDialog(message)\" title=\"View raw JSON response\">\n <i class=\"fa-solid fa-code\"></i>\n </button>\n }\n @if (message.executionData && mode === 'agent' && message.role === 'assistant') {\n <button class=\"execution-history-toggle\" (click)=\"showMessageExecutionHistory(message)\" title=\"View execution details\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n </button>\n }\n @if (message.agentRunId && mode === 'agent' && message.role === 'assistant') {\n <button class=\"execution-history-toggle\" (click)=\"navigateToAgentRun({runId: message.agentRunId, runType: 'agent'})\" title=\"View full run details\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n </button>\n }\n </div>\n <div class=\"message-content\">\n <button class=\"copy-button-in-bubble\" (click)=\"copyMessage(message)\" title=\"Copy message\">\n <i class=\"fa-solid fa-copy\"></i>\n </button>\n @if (message.isStreaming) {\n <div class=\"streaming-wrapper\">\n <span class=\"streaming-content\">{{ message.streamingContent }}<span class=\"cursor\">|</span></span>\n </div>\n } @else {\n <div [innerHTML]=\"getFormattedContent(message)\"></div>\n }\n @if (message.error) {\n <div class=\"error-details\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ message.error }}\n </div>\n }\n @if (hasPayload(message.payload) && mode === 'agent' && message.role === 'assistant') {\n <div class=\"payload-section\" [class.collapsed]=\"message.payloadCollapsed\">\n <div class=\"payload-header\" (click)=\"togglePayloadCollapse(message)\">\n <span class=\"payload-label\">\n <i class=\"fa-solid fa-code\"></i> Payload\n </span>\n <button class=\"payload-toggle\" type=\"button\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!message.payloadCollapsed\" [class.fa-chevron-right]=\"message.payloadCollapsed\"></i>\n </button>\n </div>\n @if (!message.payloadCollapsed) {\n <div class=\"payload-content\">\n <pre>{{ formatJson(message.payload) }}</pre>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n <!-- Input Area -->\n <div class=\"input-area\">\n <div class=\"input-container\">\n <textarea\n #messageInput\n class=\"mj-textarea message-input\"\n [(ngModel)]=\"currentUserMessage\"\n [rows]=\"3\"\n placeholder=\"Type your message here... (Press Enter to send, Shift+Enter for new line)\"\n (keypress)=\"handleKeyPress($event)\"\n [disabled]=\"isExecuting\"></textarea>\n <button\n class=\"send-button\"\n (click)=\"sendMessage()\"\n [disabled]=\"isExecuting || !currentUserMessage.trim()\"\n title=\"Send message\">\n @if (isExecuting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-paper-plane\"></i>\n }\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n}\n\n<!-- Save Conversation Dialog -->\n@if (showSaveDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"400\"\n (Close)=\"cancelSaveDialog()\"\n class=\"save-dialog\">\n <mj-dialog-titlebar>Save Conversation</mj-dialog-titlebar>\n <div class=\"dialog-content\">\n <p>Enter a name for this conversation:</p>\n <input\n #saveDialogInput\n type=\"text\"\n (keyup)=\"updateTempConversation()\"\n placeholder=\"Conversation name\"\n class=\"mj-input full-width\" />\n </div>\n <mj-dialog-actions>\n <button mjButton (click)=\"cancelSaveDialog()\">Cancel</button>\n <button mjButton\n variant=\"primary\"\n (click)=\"confirmSaveConversation()\"\n [disabled]=\"tempConversationName === ''\">\n Save\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- Load Confirmation Dialog -->\n@if (showLoadConfirmDialog) {\n <mj-dialog\n [Visible]=\"true\"\n [Width]=\"400\"\n (Close)=\"cancelLoadConversation()\"\n class=\"confirm-dialog\">\n <mj-dialog-titlebar>Replace Current Conversation?</mj-dialog-titlebar>\n <div class=\"dialog-content\">\n <p>Loading this conversation will replace the current one. Any unsaved changes will be lost.</p>\n <p>Do you want to continue?</p>\n </div>\n <mj-dialog-actions>\n <button mjButton (click)=\"cancelLoadConversation()\">Cancel</button>\n <button mjButton\n variant=\"primary\"\n (click)=\"confirmLoadConversation()\">\n Load Conversation\n </button>\n </mj-dialog-actions>\n </mj-dialog>\n}\n\n<!-- JSON Viewer Window -->\n@if (showJsonWindow) {\n <mj-window\n [Visible]=\"true\"\n Title=\"Raw JSON Response\"\n [Width]=\"900\"\n [Height]=\"700\"\n [MinWidth]=\"600\"\n [MinHeight]=\"400\"\n [Draggable]=\"true\"\n [Resizable]=\"true\"\n (Close)=\"closeJsonWindow()\">\n <mj-json-viewer-window [jsonContent]=\"currentJsonContent\"></mj-json-viewer-window>\n </mj-window>\n}\n\n", styles: ["/* Container Styles */\n.harness-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n/* Custom Button Styles */\n.custom-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.custom-button:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.custom-button:active:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.custom-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.custom-button.icon-only {\n padding: 6px 8px;\n}\n\n.custom-button i {\n font-size: 14px;\n}\n\n/* Send Button - Primary Style */\n.send-button {\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n padding: 8px 16px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 44px;\n font-family: inherit;\n}\n\n.send-button:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button:active:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.send-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.send-button i {\n font-size: 16px;\n}\n\n/* Add Button */\n.add-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.add-button:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n/* Remove/Delete Buttons */\n.remove-button,\n.delete-button {\n background: transparent;\n border: none;\n color: var(--mj-status-error);\n padding: 4px 8px;\n font-size: 12px;\n cursor: pointer;\n transition: all 0.2s;\n border-radius: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.remove-button:hover,\n.delete-button:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-color-error-600);\n}\n\n/* Copy Button in Message Bubble */\n.copy-button-in-bubble {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n padding: 6px;\n font-size: 14px;\n color: var(--mj-border-strong);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n opacity: 0;\n z-index: 10; /* Ensure it's above content */\n}\n\n.message-content:hover .copy-button-in-bubble {\n opacity: 1;\n}\n\n.copy-button-in-bubble:hover {\n background: rgba(0, 0, 0, 0.08);\n color: var(--mj-text-muted);\n}\n\n.copy-button-in-bubble i {\n font-size: 14px;\n}\n\n/* Model Settings Styles (Prompt Mode) */\n.model-settings {\n padding: 16px;\n}\n\n.setting-group {\n margin-bottom: 24px;\n}\n\n.setting-group label {\n display: block;\n margin-bottom: 8px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.model-selector,\n.vendor-selector {\n width: 100%;\n}\n\n.temperature-slider {\n width: 100%;\n margin-top: 8px;\n}\n\n.max-tokens-input {\n width: 100%;\n}\n\n.setting-help {\n margin-top: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Checkbox Styles */\n.checkbox-label {\n display: flex;\n align-items: center;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n cursor: pointer;\n}\n\n.skip-validation-checkbox {\n margin-right: 8px;\n cursor: pointer;\n width: 16px;\n height: 16px;\n}\n\n/* Header Styles */\n.harness-header {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 16px 20px;\n}\n\n.agent-info {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.agent-details {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.agent-details i {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.agent-details .entity-logo {\n width: 40px;\n height: 40px;\n object-fit: cover;\n border-radius: 8px;\n}\n\n.agent-details h3 {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.agent-details p {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: var(--mj-text-muted);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n}\n\n/* Body Layout */\n.harness-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n/* Chat Area */\n.chat-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n height: 100%;\n min-height: 0; /* Important for flexbox children */\n}\n\n/* Messages Container */\n.messages-container {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n.messages-container mj-empty-state {\n height: 100%;\n}\n\n/* Message Styles */\n.message {\n margin-bottom: 20px;\n animation: fadeIn 0.3s ease-in;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-user {\n margin-left: auto;\n max-width: 70%;\n}\n\n.message-assistant {\n margin-right: auto;\n max-width: 70%;\n}\n\n.message-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 13px;\n}\n\n.message-role {\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.message-role i {\n font-size: 14px;\n}\n\n.message-role .message-role-logo {\n width: 16px;\n height: 16px;\n object-fit: cover;\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.message-user .message-role {\n color: var(--mj-brand-primary);\n}\n\n.message-assistant .message-role {\n color: var(--mj-brand-primary);\n}\n\n.message-time {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.execution-time {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.raw-toggle {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n}\n\n.raw-toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n color: var(--mj-text-secondary);\n}\n\n.raw-toggle i {\n font-size: 12px;\n}\n\n/* Message content styles are now defined above in enhanced content formatting section */\n\n.message-user .message-content {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.message-assistant .message-content {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.message.streaming .message-content {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--mj-bg-surface));\n}\n\n.streaming-content {\n display: inline;\n}\n\n.streaming-wrapper {\n position: relative;\n}\n\n.streaming-wrapper .cursor {\n display: inline;\n margin-left: 2px;\n}\n\n.cursor {\n animation: blink 1s infinite;\n font-weight: 100;\n color: var(--mj-text-secondary);\n}\n\n@keyframes blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n}\n\n.error-details {\n margin-top: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n border-radius: 6px;\n color: var(--mj-color-error-600);\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details i {\n color: var(--mj-status-error);\n}\n\n/* Payload Section Styles */\n.payload-section {\n margin-top: 12px;\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.payload-header {\n background: var(--mj-bg-surface-card);\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.payload-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.payload-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label i {\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.payload-content {\n max-height: 250px;\n overflow: auto;\n background: var(--mj-bg-surface-card);\n}\n\n.payload-content pre {\n margin: 0;\n padding: 12px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n background: transparent;\n}\n\n.payload-toggle {\n background: transparent;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.payload-toggle:hover {\n color: var(--mj-text-secondary);\n}\n\n.payload-toggle i {\n font-size: 12px;\n}\n\n.payload-section.collapsed .payload-header {\n border-bottom: none;\n}\n\n/* Dialog styles */\n.save-dialog,\n.confirm-dialog {\n .dialog-content {\n padding: 20px;\n\n p {\n margin: 0 0 16px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .full-width {\n width: 100%;\n }\n\n input.k-textbox {\n padding: 8px 12px;\n font-size: 14px;\n line-height: 1.5;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n\n &:focus {\n outline: none;\n border-color: var(--mj-status-error);\n box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--mj-status-error) 25%, transparent);\n }\n }\n }\n}\n\n/* Enhanced content formatting styles */\n.markdown-content {\n line-height: 1.6;\n word-wrap: break-word;\n overflow-wrap: break-word;\n max-width: 100%;\n}\n\n/* Inline JSON editor styles */\n.inline-json-editor {\n margin: 8px 0;\n\n .json-editor-container {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n max-height: 400px;\n\n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;\n font-size: 13px;\n line-height: 1.5;\n overflow: auto;\n height: 100%;\n background: transparent;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n }\n}\n\n.markdown-paragraph {\n margin: 8px 0;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.markdown-h1 {\n font-size: 1.5em;\n font-weight: 600;\n margin: 16px 0 8px 0;\n color: var(--mj-text-primary);\n border-bottom: 2px solid var(--mj-bg-surface-sunken);\n padding-bottom: 4px;\n}\n\n.markdown-h2 {\n font-size: 1.3em;\n font-weight: 600;\n margin: 14px 0 6px 0;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n padding-bottom: 2px;\n}\n\n.markdown-h3 {\n font-size: 1.1em;\n font-weight: 600;\n margin: 12px 0 4px 0;\n color: var(--mj-text-primary);\n}\n\n.code-block {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 16px;\n margin: 12px 0;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-primary);\n white-space: pre;\n word-wrap: normal;\n max-width: 100%;\n}\n\n.code-block code {\n background: none;\n border: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre;\n word-wrap: normal;\n}\n\n.language-json {\n color: var(--mj-status-error);\n}\n\n.inline-code {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;\n font-size: 0.9em;\n color: var(--mj-status-error);\n white-space: nowrap;\n}\n\n.markdown-list {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.markdown-list li {\n margin: 4px 0;\n line-height: 1.5;\n}\n\n.markdown-link {\n color: var(--mj-brand-primary);\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: none;\n}\n\n/* Ensure proper text wrapping in message content */\n.message-content {\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n padding: 12px 40px 12px 16px; /* Extra right padding for copy button */\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n position: relative;\n overflow-wrap: break-word;\n hyphens: auto;\n max-width: 100%;\n overflow-x: hidden;\n}\n\n/* Enhanced JSON content display */\n.json-content-wrapper {\n margin: 8px 0;\n}\n\n.json-main-content {\n margin-bottom: 12px;\n}\n\n.json-raw-section {\n margin-top: 12px;\n}\n\n.json-toggle-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-family: inherit;\n}\n\n.json-toggle-button:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.json-toggle-button i {\n font-size: 12px;\n}\n\n/* Compact code block for JSON in collapsible sections */\n.json-raw-section .code-block {\n margin: 8px 0 0 0;\n font-size: 12px;\n max-height: 300px;\n overflow-y: auto;\n}\n\n/* Better mobile responsiveness for JSON content */\n@media (max-width: 768px) {\n .json-raw-section .code-block {\n font-size: 11px;\n max-height: 200px;\n }\n}\n\n/* JSON raw section styling - simplified since we use code editor in dialog */\n.json-raw-section {\n margin-top: 12px;\n}\n\n/* Input Area */\n.input-area {\n padding: 16px;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n flex-shrink: 0; /* Prevent input area from shrinking */\n margin-top: auto; /* Push to bottom */\n}\n\n.input-container {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.rerun-mode-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background-color: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-radius: 8px;\n gap: 16px;\n}\n\n.rerun-message {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.rerun-message i {\n font-size: 16px;\n}\n\n.rerun-message strong {\n font-family: 'Fira Code', 'Consolas', monospace;\n}\n\n.rerun-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 100px;\n justify-content: center;\n}\n\n.rerun-button span {\n font-weight: 500;\n}\n\n.rerun-buttons {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.reset-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n min-width: 120px;\n justify-content: center;\n background-color: var(--mj-text-muted);\n}\n\n.reset-button:hover:not(:disabled) {\n background-color: var(--mj-text-secondary);\n}\n\n.reset-button span {\n font-weight: 500;\n}\n\n.message-input {\n flex: 1;\n}\n\n.message-input textarea {\n resize: none;\n font-size: 14px;\n}\n\n.send-button {\n margin-bottom: 1px;\n}\n\n/* Sidebar */\n.sidebar {\n width: 100%; /* Changed from fixed 360px to 100% */\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* Sidebar Tabs */\n.sidebar-tabs {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.tab-button {\n flex: 1;\n padding: 12px 8px;\n background: none;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: all 0.2s;\n position: relative;\n}\n\n.tab-button:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.tab-button.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.tab-button i {\n font-size: 14px;\n}\n\n.tab-button .badge {\n background: var(--mj-text-muted);\n color: var(--mj-text-inverse);\n padding: 2px 6px;\n border-radius: 10px;\n font-size: 10px;\n margin-left: 4px;\n}\n\n.tab-button.active .badge {\n background: var(--mj-brand-primary);\n}\n\n.tab-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* Sidebar Content */\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n width: 100%; /* Ensure content takes full width */\n}\n\n.tab-content {\n padding: 20px;\n width: 100%; /* Ensure content takes full width */\n box-sizing: border-box; /* Include padding in width calculation */\n}\n\n.tab-header {\n margin-bottom: 20px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n position: relative;\n}\n\n.tab-header .custom-button.icon-only {\n position: absolute;\n top: 0;\n right: 0;\n}\n\n.tab-header h4 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.tab-header p {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n.tab-header .custom-button.small {\n align-self: flex-start;\n padding: 6px 12px;\n font-size: 13px;\n}\n\n.tab-header .custom-button.small i {\n margin-right: 4px;\n}\n\n/* Variables */\n.variables-list {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.variable-item {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n align-items: center;\n width: 100%;\n}\n\n.variable-name {\n width: 30%; /* Changed from fixed width to percentage */\n min-width: 100px;\n}\n\n.variable-type {\n width: 25%; /* Changed from fixed width to percentage */\n min-width: 80px;\n}\n\n.variable-value {\n flex: 1;\n min-width: 0; /* Allow flex item to shrink below content size */\n}\n\n.remove-button {\n width: 32px;\n height: 32px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.add-variable-button {\n width: 100%;\n}\n\n/* Saved Conversations */\n.saved-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.saved-item {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 12px;\n cursor: pointer;\n transition: all 0.2s;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.saved-item:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n}\n\n.saved-item.current {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.saved-info h5 {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.saved-info p {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.saved-date {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n/* Responsive adjustments */\n@media (max-width: 1200px) {\n .sidebar {\n width: 320px;\n }\n}\n\n@media (max-width: 992px) {\n .message-user,\n .message-assistant {\n max-width: 85%;\n }\n\n .sidebar {\n width: 280px;\n }\n}\n\n/* Custom scrollbar */\n.messages-container::-webkit-scrollbar,\n.sidebar-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.messages-container::-webkit-scrollbar-track,\n.sidebar-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.messages-container::-webkit-scrollbar-thumb,\n.sidebar-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n.messages-container::-webkit-scrollbar-thumb:hover,\n.sidebar-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Dialog customization */\n::ng-deep .ai-agent-test-harness .k-dialog-wrapper {\n border-radius: 8px;\n overflow: hidden;\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-titlebar {\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-inverse);\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-title {\n font-weight: 600;\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-titlebar-actions .k-button {\n color: var(--mj-text-inverse);\n}\n\n::ng-deep .ai-agent-test-harness .k-dialog-content {\n padding: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* JSON Dialog Styles - removed since we're using WindowService */\n\n/* Advanced Parameters Styles */\n.advanced-params-panel {\n margin-top: 24px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n}\n\n.advanced-params-panel ::ng-deep .k-expander-title {\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.advanced-settings {\n padding: 16px;\n}\n\n.advanced-param-input {\n width: 100%;\n}\n\n.advanced-param-switch {\n margin-top: 8px;\n}\n\n/* Format selector dropdown */\n.format-selector {\n width: 100%;\n}\n"] }]
|
|
3844
|
+
}], () => [{ type: i1.DomSanitizer }, { type: i0.ChangeDetectorRef }, { type: i2.MJConfirmService }], { mode: [{
|
|
3873
3845
|
type: Input
|
|
3874
3846
|
}], entity: [{
|
|
3875
3847
|
type: Input
|
|
@@ -3900,5 +3872,5 @@ export class AITestHarnessComponent extends BaseAngularComponent {
|
|
|
3900
3872
|
type: ViewChild,
|
|
3901
3873
|
args: ['saveDialogInput']
|
|
3902
3874
|
}] }); })();
|
|
3903
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AITestHarnessComponent, { className: "AITestHarnessComponent", filePath: "lib/ai-test-harness.component.ts", lineNumber:
|
|
3875
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AITestHarnessComponent, { className: "AITestHarnessComponent", filePath: "lib/ai-test-harness.component.ts", lineNumber: 155 }); })();
|
|
3904
3876
|
//# sourceMappingURL=ai-test-harness.component.js.map
|