@memberjunction/ng-ai-test-harness 2.73.0 → 2.75.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/ai-test-harness-dialog.component.d.ts +12 -1
- package/dist/lib/ai-test-harness-dialog.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness-dialog.component.js +154 -31
- package/dist/lib/ai-test-harness-dialog.component.js.map +1 -1
- package/dist/lib/ai-test-harness-window.component.d.ts +1 -0
- package/dist/lib/ai-test-harness-window.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness-window.component.js +7 -4
- package/dist/lib/ai-test-harness-window.component.js.map +1 -1
- package/dist/lib/ai-test-harness.component.d.ts +25 -2
- package/dist/lib/ai-test-harness.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness.component.js +573 -369
- package/dist/lib/ai-test-harness.component.js.map +1 -1
- package/dist/lib/test-harness-window.service.d.ts +1 -0
- package/dist/lib/test-harness-window.service.d.ts.map +1 -1
- package/dist/lib/test-harness-window.service.js +4 -0
- package/dist/lib/test-harness-window.service.js.map +1 -1
- package/package.json +8 -8
|
@@ -104,7 +104,7 @@ function AITestHarnessComponent_div_0_Conditional_2_Template(rf, ctx) { if (rf &
|
|
|
104
104
|
} }
|
|
105
105
|
function AITestHarnessComponent_div_0_Conditional_4_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
106
106
|
i0.ɵɵelementStart(0, "div", 30);
|
|
107
|
-
i0.ɵɵelement(1, "i",
|
|
107
|
+
i0.ɵɵelement(1, "i", 45);
|
|
108
108
|
i0.ɵɵelementStart(2, "h4");
|
|
109
109
|
i0.ɵɵtext(3, "Start a conversation");
|
|
110
110
|
i0.ɵɵelementEnd();
|
|
@@ -113,11 +113,11 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_5_Template(rf, c
|
|
|
113
113
|
i0.ɵɵelementEnd()();
|
|
114
114
|
} }
|
|
115
115
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
116
|
-
i0.ɵɵelement(0, "i",
|
|
116
|
+
i0.ɵɵelement(0, "i", 59);
|
|
117
117
|
i0.ɵɵtext(1, " You ");
|
|
118
118
|
} }
|
|
119
119
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
120
|
-
i0.ɵɵelement(0, "img",
|
|
120
|
+
i0.ɵɵelement(0, "img", 60);
|
|
121
121
|
} if (rf & 2) {
|
|
122
122
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
123
123
|
i0.ɵɵproperty("src", ctx_r1.getEntityLogoURL(), i0.ɵɵsanitizeUrl)("alt", ctx_r1.getEntityName() + " logo");
|
|
@@ -129,7 +129,7 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Conditio
|
|
|
129
129
|
i0.ɵɵclassMap(ctx_r1.getEntityIconClass());
|
|
130
130
|
} }
|
|
131
131
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
132
|
-
i0.ɵɵtemplate(0, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template, 1, 2, "img",
|
|
132
|
+
i0.ɵɵtemplate(0, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Conditional_0_Template, 1, 2, "img", 60)(1, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Conditional_1_Template, 1, 2, "i", 15);
|
|
133
133
|
i0.ɵɵtext(2);
|
|
134
134
|
} if (rf & 2) {
|
|
135
135
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -138,8 +138,8 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Template
|
|
|
138
138
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.getEntityName() || "Assistant", " ");
|
|
139
139
|
} }
|
|
140
140
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
-
i0.ɵɵelementStart(0, "span",
|
|
142
|
-
i0.ɵɵelement(1, "i",
|
|
141
|
+
i0.ɵɵelementStart(0, "span", 49);
|
|
142
|
+
i0.ɵɵelement(1, "i", 61);
|
|
143
143
|
i0.ɵɵtext(2);
|
|
144
144
|
i0.ɵɵelementEnd();
|
|
145
145
|
} if (rf & 2) {
|
|
@@ -149,7 +149,7 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_7_Template
|
|
|
149
149
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatElapsedTime(message_r5.elapsedTime), " ");
|
|
150
150
|
} }
|
|
151
151
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
152
|
-
i0.ɵɵelementStart(0, "span",
|
|
152
|
+
i0.ɵɵelementStart(0, "span", 50);
|
|
153
153
|
i0.ɵɵtext(1);
|
|
154
154
|
i0.ɵɵelementEnd();
|
|
155
155
|
} if (rf & 2) {
|
|
@@ -161,15 +161,15 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_8_Template
|
|
|
161
161
|
} }
|
|
162
162
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
163
163
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
164
|
-
i0.ɵɵelementStart(0, "button",
|
|
164
|
+
i0.ɵɵelementStart(0, "button", 62);
|
|
165
165
|
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
166
|
-
i0.ɵɵelement(1, "i",
|
|
166
|
+
i0.ɵɵelement(1, "i", 63);
|
|
167
167
|
i0.ɵɵelementEnd();
|
|
168
168
|
} }
|
|
169
169
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
170
|
-
i0.ɵɵelementStart(0, "div",
|
|
171
|
-
i0.ɵɵelement(1, "span",
|
|
172
|
-
i0.ɵɵelementStart(2, "span",
|
|
170
|
+
i0.ɵɵelementStart(0, "div", 55);
|
|
171
|
+
i0.ɵɵelement(1, "span", 64);
|
|
172
|
+
i0.ɵɵelementStart(2, "span", 65);
|
|
173
173
|
i0.ɵɵtext(3, "|");
|
|
174
174
|
i0.ɵɵelementEnd()();
|
|
175
175
|
} if (rf & 2) {
|
|
@@ -179,15 +179,15 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_13_Templat
|
|
|
179
179
|
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedStreamingContent(message_r5), i0.ɵɵsanitizeHtml);
|
|
180
180
|
} }
|
|
181
181
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
182
|
-
i0.ɵɵelement(0, "div",
|
|
182
|
+
i0.ɵɵelement(0, "div", 56);
|
|
183
183
|
} if (rf & 2) {
|
|
184
184
|
const message_r5 = i0.ɵɵnextContext().$implicit;
|
|
185
185
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
186
186
|
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedContent(message_r5), i0.ɵɵsanitizeHtml);
|
|
187
187
|
} }
|
|
188
188
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
189
|
-
i0.ɵɵelementStart(0, "div",
|
|
190
|
-
i0.ɵɵelement(1, "i",
|
|
189
|
+
i0.ɵɵelementStart(0, "div", 57);
|
|
190
|
+
i0.ɵɵelement(1, "i", 66);
|
|
191
191
|
i0.ɵɵtext(2);
|
|
192
192
|
i0.ɵɵelementEnd();
|
|
193
193
|
} if (rf & 2) {
|
|
@@ -196,8 +196,8 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_15_Templat
|
|
|
196
196
|
i0.ɵɵtextInterpolate1(" ", message_r5.error, " ");
|
|
197
197
|
} }
|
|
198
198
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
199
|
-
i0.ɵɵelementStart(0, "div",
|
|
200
|
-
i0.ɵɵelement(1, "mj-code-editor",
|
|
199
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
200
|
+
i0.ɵɵelement(1, "mj-code-editor", 72);
|
|
201
201
|
i0.ɵɵelementEnd();
|
|
202
202
|
} if (rf & 2) {
|
|
203
203
|
const message_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
@@ -207,16 +207,16 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Conditi
|
|
|
207
207
|
} }
|
|
208
208
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
209
209
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
210
|
-
i0.ɵɵelementStart(0, "div",
|
|
210
|
+
i0.ɵɵelementStart(0, "div", 67)(1, "div", 68);
|
|
211
211
|
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
212
|
-
i0.ɵɵelementStart(2, "span",
|
|
213
|
-
i0.ɵɵelement(3, "i",
|
|
212
|
+
i0.ɵɵelementStart(2, "span", 69);
|
|
213
|
+
i0.ɵɵelement(3, "i", 63);
|
|
214
214
|
i0.ɵɵtext(4, " Payload ");
|
|
215
215
|
i0.ɵɵelementEnd();
|
|
216
|
-
i0.ɵɵelementStart(5, "button",
|
|
216
|
+
i0.ɵɵelementStart(5, "button", 70);
|
|
217
217
|
i0.ɵɵelement(6, "i", 27);
|
|
218
218
|
i0.ɵɵelementEnd()();
|
|
219
|
-
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template, 2, 3, "div",
|
|
219
|
+
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Conditional_7_Template, 2, 3, "div", 71);
|
|
220
220
|
i0.ɵɵelementEnd();
|
|
221
221
|
} if (rf & 2) {
|
|
222
222
|
const message_r5 = i0.ɵɵnextContext().$implicit;
|
|
@@ -228,19 +228,19 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Templat
|
|
|
228
228
|
} }
|
|
229
229
|
function AITestHarnessComponent_div_0_Conditional_4_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
230
230
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
231
|
-
i0.ɵɵelementStart(0, "div", 31)(1, "div",
|
|
231
|
+
i0.ɵɵelementStart(0, "div", 31)(1, "div", 46)(2, "span", 47);
|
|
232
232
|
i0.ɵɵtemplate(3, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_3_Template, 2, 0)(4, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_4_Template, 3, 2);
|
|
233
233
|
i0.ɵɵelementEnd();
|
|
234
|
-
i0.ɵɵelementStart(5, "span",
|
|
234
|
+
i0.ɵɵelementStart(5, "span", 48);
|
|
235
235
|
i0.ɵɵtext(6);
|
|
236
236
|
i0.ɵɵelementEnd();
|
|
237
|
-
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_7_Template, 3, 1, "span",
|
|
237
|
+
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_7_Template, 3, 1, "span", 49)(8, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_8_Template, 2, 2, "span", 50)(9, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_9_Template, 2, 0, "button", 51);
|
|
238
238
|
i0.ɵɵelementEnd();
|
|
239
|
-
i0.ɵɵelementStart(10, "div",
|
|
239
|
+
i0.ɵɵelementStart(10, "div", 52)(11, "button", 53);
|
|
240
240
|
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
241
|
-
i0.ɵɵelement(12, "i",
|
|
241
|
+
i0.ɵɵelement(12, "i", 54);
|
|
242
242
|
i0.ɵɵelementEnd();
|
|
243
|
-
i0.ɵɵtemplate(13, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_13_Template, 4, 1, "div",
|
|
243
|
+
i0.ɵɵtemplate(13, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_13_Template, 4, 1, "div", 55)(14, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_14_Template, 1, 1, "div", 56)(15, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_15_Template, 3, 1, "div", 57)(16, AITestHarnessComponent_div_0_Conditional_4_For_7_Conditional_16_Template, 8, 7, "div", 58);
|
|
244
244
|
i0.ɵɵelementEnd()();
|
|
245
245
|
} if (rf & 2) {
|
|
246
246
|
const message_r5 = ctx.$implicit;
|
|
@@ -261,27 +261,103 @@ function AITestHarnessComponent_div_0_Conditional_4_For_7_Template(rf, ctx) { if
|
|
|
261
261
|
i0.ɵɵadvance();
|
|
262
262
|
i0.ɵɵconditional(ctx_r1.hasPayload(message_r5.payload) && ctx_r1.mode === "agent" && message_r5.role === "assistant" ? 16 : -1);
|
|
263
263
|
} }
|
|
264
|
-
function
|
|
265
|
-
i0.ɵɵelement(0, "i",
|
|
264
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
265
|
+
i0.ɵɵelement(0, "i", 61);
|
|
266
|
+
i0.ɵɵelementStart(1, "span");
|
|
267
|
+
i0.ɵɵtext(2, "Running...");
|
|
268
|
+
i0.ɵɵelementEnd();
|
|
266
269
|
} }
|
|
267
|
-
function
|
|
268
|
-
i0.ɵɵelement(0, "i",
|
|
270
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
271
|
+
i0.ɵɵelement(0, "i", 79);
|
|
272
|
+
i0.ɵɵelementStart(1, "span");
|
|
273
|
+
i0.ɵɵtext(2, "Re-Run");
|
|
274
|
+
i0.ɵɵelementEnd();
|
|
269
275
|
} }
|
|
270
|
-
function
|
|
276
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
271
277
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
272
|
-
i0.ɵɵelementStart(0, "button",
|
|
273
|
-
i0.ɵɵlistener("click", function
|
|
274
|
-
i0.ɵɵ
|
|
278
|
+
i0.ɵɵelementStart(0, "button", 78);
|
|
279
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
280
|
+
i0.ɵɵtemplate(1, AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Conditional_1_Template, 3, 0)(2, AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Conditional_2_Template, 3, 0);
|
|
281
|
+
i0.ɵɵelementEnd();
|
|
282
|
+
} if (rf & 2) {
|
|
283
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
284
|
+
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
285
|
+
i0.ɵɵadvance();
|
|
286
|
+
i0.ɵɵconditional(ctx_r1.isExecuting ? 1 : 2);
|
|
287
|
+
} }
|
|
288
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
289
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
290
|
+
i0.ɵɵelementStart(0, "button", 80);
|
|
291
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
292
|
+
i0.ɵɵelement(1, "i", 81);
|
|
293
|
+
i0.ɵɵelementStart(2, "span");
|
|
294
|
+
i0.ɵɵtext(3, "Reset Messages");
|
|
295
|
+
i0.ɵɵelementEnd()();
|
|
296
|
+
} if (rf & 2) {
|
|
297
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
298
|
+
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
299
|
+
} }
|
|
300
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
301
|
+
i0.ɵɵelementStart(0, "div", 33)(1, "div", 73);
|
|
302
|
+
i0.ɵɵelement(2, "i", 74);
|
|
303
|
+
i0.ɵɵelementStart(3, "span");
|
|
304
|
+
i0.ɵɵtext(4, "Messages from Prompt Run ");
|
|
305
|
+
i0.ɵɵelementStart(5, "strong");
|
|
306
|
+
i0.ɵɵtext(6);
|
|
307
|
+
i0.ɵɵelementEnd();
|
|
308
|
+
i0.ɵɵtext(7, " loaded above");
|
|
309
|
+
i0.ɵɵelementEnd()();
|
|
310
|
+
i0.ɵɵelementStart(8, "div", 75);
|
|
311
|
+
i0.ɵɵtemplate(9, AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_9_Template, 3, 2, "button", 76)(10, AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Conditional_10_Template, 4, 1, "button", 77);
|
|
312
|
+
i0.ɵɵelementEnd()();
|
|
313
|
+
} if (rf & 2) {
|
|
314
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
315
|
+
i0.ɵɵadvance(6);
|
|
316
|
+
i0.ɵɵtextInterpolate(ctx_r1.originalPromptRunId.substring(0, 8));
|
|
317
|
+
i0.ɵɵadvance(3);
|
|
318
|
+
i0.ɵɵconditional(!ctx_r1.hasExecutedRerun ? 9 : 10);
|
|
319
|
+
} }
|
|
320
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
321
|
+
i0.ɵɵelement(0, "i", 61);
|
|
322
|
+
} }
|
|
323
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
324
|
+
i0.ɵɵelement(0, "i", 84);
|
|
325
|
+
} }
|
|
326
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
327
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
328
|
+
i0.ɵɵelementStart(0, "div", 34)(1, "kendo-textarea", 82, 2);
|
|
329
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Template_kendo_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); });
|
|
330
|
+
i0.ɵɵlistener("keypress", function AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Template_kendo_textarea_keypress_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.handleKeyPress($event)); });
|
|
331
|
+
i0.ɵɵelementEnd();
|
|
332
|
+
i0.ɵɵelementStart(3, "button", 83);
|
|
333
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
334
|
+
i0.ɵɵtemplate(4, AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Conditional_4_Template, 1, 0, "i", 61)(5, AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Conditional_5_Template, 1, 0, "i", 84);
|
|
335
|
+
i0.ɵɵelementEnd()();
|
|
336
|
+
} if (rf & 2) {
|
|
337
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
338
|
+
i0.ɵɵadvance();
|
|
339
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.currentUserMessage);
|
|
340
|
+
i0.ɵɵproperty("rows", 3)("disabled", ctx_r1.isExecuting);
|
|
341
|
+
i0.ɵɵadvance(2);
|
|
342
|
+
i0.ɵɵproperty("disabled", ctx_r1.isExecuting || !ctx_r1.currentUserMessage.trim());
|
|
343
|
+
i0.ɵɵadvance();
|
|
344
|
+
i0.ɵɵconditional(ctx_r1.isExecuting ? 4 : 5);
|
|
345
|
+
} }
|
|
346
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
347
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
348
|
+
i0.ɵɵelementStart(0, "button", 38);
|
|
349
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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")); });
|
|
350
|
+
i0.ɵɵelement(1, "i", 63);
|
|
275
351
|
i0.ɵɵtext(2, " Agent Variables ");
|
|
276
352
|
i0.ɵɵelementEnd();
|
|
277
|
-
i0.ɵɵelementStart(3, "button",
|
|
278
|
-
i0.ɵɵlistener("click", function
|
|
279
|
-
i0.ɵɵelement(4, "i",
|
|
353
|
+
i0.ɵɵelementStart(3, "button", 85);
|
|
354
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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")); });
|
|
355
|
+
i0.ɵɵelement(4, "i", 86);
|
|
280
356
|
i0.ɵɵtext(5, " Execution Monitor ");
|
|
281
357
|
i0.ɵɵelementEnd();
|
|
282
|
-
i0.ɵɵelementStart(6, "button",
|
|
283
|
-
i0.ɵɵlistener("click", function
|
|
284
|
-
i0.ɵɵelement(7, "i",
|
|
358
|
+
i0.ɵɵelementStart(6, "button", 38);
|
|
359
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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")); });
|
|
360
|
+
i0.ɵɵelement(7, "i", 87);
|
|
285
361
|
i0.ɵɵtext(8, " Settings ");
|
|
286
362
|
i0.ɵɵelementEnd();
|
|
287
363
|
} if (rf & 2) {
|
|
@@ -294,16 +370,16 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_18_Template(rf,
|
|
|
294
370
|
i0.ɵɵclassProp("active", ctx_r1.activeTab === "agentSettings");
|
|
295
371
|
i0.ɵɵproperty("disabled", ctx_r1.executionMonitorMode === "live" && ctx_r1.activeTab !== "agentSettings");
|
|
296
372
|
} }
|
|
297
|
-
function
|
|
298
|
-
const
|
|
299
|
-
i0.ɵɵelementStart(0, "button",
|
|
300
|
-
i0.ɵɵlistener("click", function
|
|
301
|
-
i0.ɵɵelement(1, "i",
|
|
373
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
374
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
375
|
+
i0.ɵɵelementStart(0, "button", 85);
|
|
376
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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")); });
|
|
377
|
+
i0.ɵɵelement(1, "i", 63);
|
|
302
378
|
i0.ɵɵtext(2, " Template Variables ");
|
|
303
379
|
i0.ɵɵelementEnd();
|
|
304
|
-
i0.ɵɵelementStart(3, "button",
|
|
305
|
-
i0.ɵɵlistener("click", function
|
|
306
|
-
i0.ɵɵelement(4, "i",
|
|
380
|
+
i0.ɵɵelementStart(3, "button", 85);
|
|
381
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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")); });
|
|
382
|
+
i0.ɵɵelement(4, "i", 87);
|
|
307
383
|
i0.ɵɵtext(5, " Model Settings ");
|
|
308
384
|
i0.ɵɵelementEnd();
|
|
309
385
|
} if (rf & 2) {
|
|
@@ -312,8 +388,8 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_19_Template(rf,
|
|
|
312
388
|
i0.ɵɵadvance(3);
|
|
313
389
|
i0.ɵɵclassProp("active", ctx_r1.activeTab === "modelSettings");
|
|
314
390
|
} }
|
|
315
|
-
function
|
|
316
|
-
i0.ɵɵelementStart(0, "span",
|
|
391
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
392
|
+
i0.ɵɵelementStart(0, "span", 40);
|
|
317
393
|
i0.ɵɵtext(1);
|
|
318
394
|
i0.ɵɵelementEnd();
|
|
319
395
|
} if (rf & 2) {
|
|
@@ -321,56 +397,56 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Template(rf,
|
|
|
321
397
|
i0.ɵɵadvance();
|
|
322
398
|
i0.ɵɵtextInterpolate(ctx_r1.savedConversations.length);
|
|
323
399
|
} }
|
|
324
|
-
function
|
|
325
|
-
i0.ɵɵelementStart(0, "div",
|
|
400
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
401
|
+
i0.ɵɵelementStart(0, "div", 90)(1, "p");
|
|
326
402
|
i0.ɵɵtext(2, "No variables defined. Click \"Add Variable\" to get started.");
|
|
327
403
|
i0.ɵɵelementEnd()();
|
|
328
404
|
} }
|
|
329
|
-
function
|
|
330
|
-
const
|
|
331
|
-
i0.ɵɵelementStart(0, "div",
|
|
332
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
405
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
406
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
407
|
+
i0.ɵɵelementStart(0, "div", 91)(1, "kendo-textbox", 94);
|
|
408
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_For_9_Template_kendo_textbox_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); });
|
|
333
409
|
i0.ɵɵelementEnd();
|
|
334
|
-
i0.ɵɵelementStart(2, "kendo-dropdownlist",
|
|
335
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
410
|
+
i0.ɵɵelementStart(2, "kendo-dropdownlist", 95);
|
|
411
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_For_9_Template_kendo_dropdownlist_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); });
|
|
336
412
|
i0.ɵɵelementEnd();
|
|
337
|
-
i0.ɵɵelementStart(3, "kendo-textbox",
|
|
338
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
413
|
+
i0.ɵɵelementStart(3, "kendo-textbox", 96);
|
|
414
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_For_9_Template_kendo_textbox_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); });
|
|
339
415
|
i0.ɵɵelementEnd();
|
|
340
|
-
i0.ɵɵelementStart(4, "button",
|
|
341
|
-
i0.ɵɵlistener("click", function
|
|
342
|
-
i0.ɵɵelement(5, "i",
|
|
416
|
+
i0.ɵɵelementStart(4, "button", 97);
|
|
417
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
418
|
+
i0.ɵɵelement(5, "i", 98);
|
|
343
419
|
i0.ɵɵelementEnd()();
|
|
344
420
|
} if (rf & 2) {
|
|
345
|
-
const
|
|
421
|
+
const variable_r15 = ctx.$implicit;
|
|
346
422
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
347
423
|
i0.ɵɵadvance();
|
|
348
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
424
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r15.name);
|
|
349
425
|
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
350
426
|
i0.ɵɵadvance();
|
|
351
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
427
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r15.type);
|
|
352
428
|
i0.ɵɵproperty("data", i0.ɵɵpureFunction4(14, _c8, i0.ɵɵpureFunction0(10, _c4), i0.ɵɵpureFunction0(11, _c5), i0.ɵɵpureFunction0(12, _c6), i0.ɵɵpureFunction0(13, _c7)))("valuePrimitive", true)("disabled", ctx_r1.isExecuting);
|
|
353
429
|
i0.ɵɵadvance();
|
|
354
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
355
|
-
i0.ɵɵproperty("placeholder",
|
|
430
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r15.value);
|
|
431
|
+
i0.ɵɵproperty("placeholder", variable_r15.type === "object" ? "JSON value" : "Value")("disabled", ctx_r1.isExecuting);
|
|
356
432
|
i0.ɵɵadvance();
|
|
357
433
|
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
358
434
|
} }
|
|
359
|
-
function
|
|
360
|
-
const
|
|
361
|
-
i0.ɵɵelementStart(0, "div",
|
|
435
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
436
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
437
|
+
i0.ɵɵelementStart(0, "div", 42)(1, "div", 88)(2, "h4");
|
|
362
438
|
i0.ɵɵtext(3, "Agent Variables");
|
|
363
439
|
i0.ɵɵelementEnd();
|
|
364
440
|
i0.ɵɵelementStart(4, "p");
|
|
365
441
|
i0.ɵɵtext(5, "Variables available during agent execution and template rendering");
|
|
366
442
|
i0.ɵɵelementEnd()();
|
|
367
|
-
i0.ɵɵelementStart(6, "div",
|
|
368
|
-
i0.ɵɵtemplate(7,
|
|
369
|
-
i0.ɵɵrepeaterCreate(8,
|
|
443
|
+
i0.ɵɵelementStart(6, "div", 89);
|
|
444
|
+
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_4_Conditional_21_Conditional_7_Template, 3, 0, "div", 90);
|
|
445
|
+
i0.ɵɵrepeaterCreate(8, AITestHarnessComponent_div_0_Conditional_4_Conditional_21_For_9_Template, 6, 19, "div", 91, i0.ɵɵrepeaterTrackByIndex);
|
|
370
446
|
i0.ɵɵelementEnd();
|
|
371
|
-
i0.ɵɵelementStart(10, "button",
|
|
372
|
-
i0.ɵɵlistener("click", function
|
|
373
|
-
i0.ɵɵelement(11, "i",
|
|
447
|
+
i0.ɵɵelementStart(10, "button", 92);
|
|
448
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
449
|
+
i0.ɵɵelement(11, "i", 93);
|
|
374
450
|
i0.ɵɵtext(12, " Add Variable ");
|
|
375
451
|
i0.ɵɵelementEnd()();
|
|
376
452
|
} if (rf & 2) {
|
|
@@ -382,54 +458,54 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template(rf,
|
|
|
382
458
|
i0.ɵɵadvance(2);
|
|
383
459
|
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
384
460
|
} }
|
|
385
|
-
function
|
|
386
|
-
const
|
|
387
|
-
i0.ɵɵelementStart(0, "div",
|
|
388
|
-
i0.ɵɵlistener("viewRunClick", function
|
|
461
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
462
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
463
|
+
i0.ɵɵelementStart(0, "div", 43)(1, "mj-agent-execution-monitor", 99);
|
|
464
|
+
i0.ɵɵlistener("viewRunClick", function AITestHarnessComponent_div_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)); });
|
|
389
465
|
i0.ɵɵelementEnd()();
|
|
390
466
|
} if (rf & 2) {
|
|
391
467
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
392
468
|
i0.ɵɵadvance();
|
|
393
469
|
i0.ɵɵproperty("mode", ctx_r1.executionMonitorMode)("agentRun", ctx_r1.currentAgentRun)("liveSteps", ctx_r1.liveAgentSteps)("autoExpand", true)("runId", ctx_r1.getLastRunId())("runType", ctx_r1.mode);
|
|
394
470
|
} }
|
|
395
|
-
function
|
|
471
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_For_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
396
472
|
i0.ɵɵtext(0);
|
|
397
473
|
} if (rf & 2) {
|
|
398
|
-
const
|
|
399
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
474
|
+
const config_r19 = i0.ɵɵnextContext().$implicit;
|
|
475
|
+
i0.ɵɵtextInterpolate1(" ", config_r19.Description, " ");
|
|
400
476
|
} }
|
|
401
|
-
function
|
|
402
|
-
i0.ɵɵtemplate(0,
|
|
477
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
478
|
+
i0.ɵɵtemplate(0, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_For_1_Conditional_0_Template, 1, 1);
|
|
403
479
|
} if (rf & 2) {
|
|
404
|
-
const
|
|
480
|
+
const config_r19 = ctx.$implicit;
|
|
405
481
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
406
|
-
i0.ɵɵconditional(
|
|
482
|
+
i0.ɵɵconditional(config_r19.ID === ctx_r1.agentConfigurationId && config_r19.Description ? 0 : -1);
|
|
407
483
|
} }
|
|
408
|
-
function
|
|
409
|
-
i0.ɵɵrepeaterCreate(0,
|
|
484
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
485
|
+
i0.ɵɵrepeaterCreate(0, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_For_1_Template, 1, 1, null, null, _forTrack1);
|
|
410
486
|
} if (rf & 2) {
|
|
411
487
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
412
488
|
i0.ɵɵrepeater(ctx_r1.availableConfigurations);
|
|
413
489
|
} }
|
|
414
|
-
function
|
|
490
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
415
491
|
i0.ɵɵtext(0, " Using default configuration ");
|
|
416
492
|
} }
|
|
417
|
-
function
|
|
418
|
-
const
|
|
419
|
-
i0.ɵɵelementStart(0, "div",
|
|
493
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
494
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
495
|
+
i0.ɵɵelementStart(0, "div", 42)(1, "div", 88)(2, "h4");
|
|
420
496
|
i0.ɵɵtext(3, "Agent Settings");
|
|
421
497
|
i0.ɵɵelementEnd();
|
|
422
498
|
i0.ɵɵelementStart(4, "p");
|
|
423
499
|
i0.ɵɵtext(5, "Configure agent execution parameters");
|
|
424
500
|
i0.ɵɵelementEnd()();
|
|
425
|
-
i0.ɵɵelementStart(6, "div",
|
|
501
|
+
i0.ɵɵelementStart(6, "div", 100)(7, "div", 101)(8, "label");
|
|
426
502
|
i0.ɵɵtext(9, "AI Configuration");
|
|
427
503
|
i0.ɵɵelementEnd();
|
|
428
|
-
i0.ɵɵelementStart(10, "kendo-dropdownlist",
|
|
429
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
504
|
+
i0.ɵɵelementStart(10, "kendo-dropdownlist", 102);
|
|
505
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Template_kendo_dropdownlist_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); });
|
|
430
506
|
i0.ɵɵelementEnd();
|
|
431
|
-
i0.ɵɵelementStart(11, "div",
|
|
432
|
-
i0.ɵɵtemplate(12,
|
|
507
|
+
i0.ɵɵelementStart(11, "div", 103);
|
|
508
|
+
i0.ɵɵtemplate(12, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_12_Template, 2, 0)(13, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Conditional_13_Template, 1, 0);
|
|
433
509
|
i0.ɵɵelementEnd()()()();
|
|
434
510
|
} if (rf & 2) {
|
|
435
511
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -439,48 +515,48 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_27_Template(rf,
|
|
|
439
515
|
i0.ɵɵadvance(2);
|
|
440
516
|
i0.ɵɵconditional(ctx_r1.agentConfigurationId ? 12 : 13);
|
|
441
517
|
} }
|
|
442
|
-
function
|
|
443
|
-
const
|
|
444
|
-
i0.ɵɵelementStart(0, "div",
|
|
445
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
518
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_24_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
519
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
520
|
+
i0.ɵɵelementStart(0, "div", 91)(1, "kendo-textbox", 94);
|
|
521
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_24_For_8_Template_kendo_textbox_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); });
|
|
446
522
|
i0.ɵɵelementEnd();
|
|
447
|
-
i0.ɵɵelementStart(2, "kendo-dropdownlist",
|
|
448
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
523
|
+
i0.ɵɵelementStart(2, "kendo-dropdownlist", 95);
|
|
524
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_24_For_8_Template_kendo_dropdownlist_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); });
|
|
449
525
|
i0.ɵɵelementEnd();
|
|
450
|
-
i0.ɵɵelementStart(3, "kendo-textbox",
|
|
451
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
526
|
+
i0.ɵɵelementStart(3, "kendo-textbox", 96);
|
|
527
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_24_For_8_Template_kendo_textbox_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); });
|
|
452
528
|
i0.ɵɵelementEnd();
|
|
453
|
-
i0.ɵɵelementStart(4, "button",
|
|
454
|
-
i0.ɵɵlistener("click", function
|
|
455
|
-
i0.ɵɵelement(5, "i",
|
|
529
|
+
i0.ɵɵelementStart(4, "button", 105);
|
|
530
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
531
|
+
i0.ɵɵelement(5, "i", 98);
|
|
456
532
|
i0.ɵɵelementEnd()();
|
|
457
533
|
} if (rf & 2) {
|
|
458
|
-
const
|
|
534
|
+
const variable_r22 = ctx.$implicit;
|
|
459
535
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
460
536
|
i0.ɵɵadvance();
|
|
461
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
537
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r22.name);
|
|
462
538
|
i0.ɵɵproperty("disabled", ctx_r1.isExecuting);
|
|
463
539
|
i0.ɵɵadvance();
|
|
464
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
540
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r22.type);
|
|
465
541
|
i0.ɵɵproperty("data", i0.ɵɵpureFunction4(13, _c8, i0.ɵɵpureFunction0(9, _c4), i0.ɵɵpureFunction0(10, _c5), i0.ɵɵpureFunction0(11, _c6), i0.ɵɵpureFunction0(12, _c7)))("valuePrimitive", true)("disabled", ctx_r1.isExecuting);
|
|
466
542
|
i0.ɵɵadvance();
|
|
467
|
-
i0.ɵɵtwoWayProperty("ngModel",
|
|
468
|
-
i0.ɵɵproperty("placeholder",
|
|
543
|
+
i0.ɵɵtwoWayProperty("ngModel", variable_r22.value);
|
|
544
|
+
i0.ɵɵproperty("placeholder", variable_r22.type === "object" ? "JSON value" : "Value")("disabled", ctx_r1.isExecuting);
|
|
469
545
|
} }
|
|
470
|
-
function
|
|
471
|
-
const
|
|
472
|
-
i0.ɵɵelementStart(0, "div",
|
|
546
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
547
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
548
|
+
i0.ɵɵelementStart(0, "div", 42)(1, "div", 88)(2, "h4");
|
|
473
549
|
i0.ɵɵtext(3, "Template Variables");
|
|
474
550
|
i0.ɵɵelementEnd();
|
|
475
551
|
i0.ɵɵelementStart(4, "p");
|
|
476
552
|
i0.ɵɵtext(5, "Variables for prompt template rendering");
|
|
477
553
|
i0.ɵɵelementEnd()();
|
|
478
|
-
i0.ɵɵelementStart(6, "div",
|
|
479
|
-
i0.ɵɵrepeaterCreate(7,
|
|
554
|
+
i0.ɵɵelementStart(6, "div", 89);
|
|
555
|
+
i0.ɵɵrepeaterCreate(7, AITestHarnessComponent_div_0_Conditional_4_Conditional_24_For_8_Template, 6, 18, "div", 91, i0.ɵɵrepeaterTrackByIndex);
|
|
480
556
|
i0.ɵɵelementEnd();
|
|
481
|
-
i0.ɵɵelementStart(9, "button",
|
|
482
|
-
i0.ɵɵlistener("click", function
|
|
483
|
-
i0.ɵɵelement(10, "i",
|
|
557
|
+
i0.ɵɵelementStart(9, "button", 104);
|
|
558
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
559
|
+
i0.ɵɵelement(10, "i", 93);
|
|
484
560
|
i0.ɵɵtext(11, " Add Variable ");
|
|
485
561
|
i0.ɵɵelementEnd()();
|
|
486
562
|
} if (rf & 2) {
|
|
@@ -488,44 +564,44 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_28_Template(rf,
|
|
|
488
564
|
i0.ɵɵadvance(7);
|
|
489
565
|
i0.ɵɵrepeater(ctx_r1.templateVariables);
|
|
490
566
|
} }
|
|
491
|
-
function
|
|
567
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
492
568
|
i0.ɵɵtext(0, " Using default vendor for the default model ");
|
|
493
569
|
} }
|
|
494
|
-
function
|
|
570
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
495
571
|
i0.ɵɵtext(0, " Only one vendor available for this model ");
|
|
496
572
|
} }
|
|
497
|
-
function
|
|
573
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
498
574
|
i0.ɵɵtext(0, " Select the inference provider for this model ");
|
|
499
575
|
} }
|
|
500
|
-
function
|
|
576
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_For_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
501
577
|
i0.ɵɵtext(0);
|
|
502
578
|
} if (rf & 2) {
|
|
503
|
-
const
|
|
504
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
579
|
+
const config_r25 = i0.ɵɵnextContext().$implicit;
|
|
580
|
+
i0.ɵɵtextInterpolate1(" ", config_r25.Description, " ");
|
|
505
581
|
} }
|
|
506
|
-
function
|
|
507
|
-
i0.ɵɵtemplate(0,
|
|
582
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
583
|
+
i0.ɵɵtemplate(0, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_For_1_Conditional_0_Template, 1, 1);
|
|
508
584
|
} if (rf & 2) {
|
|
509
|
-
const
|
|
585
|
+
const config_r25 = ctx.$implicit;
|
|
510
586
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
511
|
-
i0.ɵɵconditional(
|
|
587
|
+
i0.ɵɵconditional(config_r25.ID === ctx_r1.selectedConfigurationId && config_r25.Description ? 0 : -1);
|
|
512
588
|
} }
|
|
513
|
-
function
|
|
514
|
-
i0.ɵɵrepeaterCreate(0,
|
|
589
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
590
|
+
i0.ɵɵrepeaterCreate(0, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_For_1_Template, 1, 1, null, null, _forTrack1);
|
|
515
591
|
} if (rf & 2) {
|
|
516
592
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
517
593
|
i0.ɵɵrepeater(ctx_r1.availableConfigurations);
|
|
518
594
|
} }
|
|
519
|
-
function
|
|
595
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_27_Template(rf, ctx) { if (rf & 1) {
|
|
520
596
|
i0.ɵɵtext(0, " Using default configuration ");
|
|
521
597
|
} }
|
|
522
|
-
function
|
|
523
|
-
const
|
|
524
|
-
i0.ɵɵelementStart(0, "div",
|
|
598
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_86_Template(rf, ctx) { if (rf & 1) {
|
|
599
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
600
|
+
i0.ɵɵelementStart(0, "div", 101)(1, "label", 129);
|
|
525
601
|
i0.ɵɵtext(2, " Top Log Probs ");
|
|
526
602
|
i0.ɵɵelementEnd();
|
|
527
|
-
i0.ɵɵelementStart(3, "kendo-numerictextbox",
|
|
528
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
603
|
+
i0.ɵɵelementStart(3, "kendo-numerictextbox", 130);
|
|
604
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_86_Template_kendo_numerictextbox_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); });
|
|
529
605
|
i0.ɵɵelementEnd()();
|
|
530
606
|
} if (rf & 2) {
|
|
531
607
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -533,130 +609,130 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_29_Conditional_8
|
|
|
533
609
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.advancedParams.topLogProbs);
|
|
534
610
|
i0.ɵɵproperty("min", 2)("max", 20)("step", 1)("format", "n0");
|
|
535
611
|
} }
|
|
536
|
-
function
|
|
537
|
-
const
|
|
538
|
-
i0.ɵɵelementStart(0, "div",
|
|
612
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
613
|
+
const _r24 = i0.ɵɵgetCurrentView();
|
|
614
|
+
i0.ɵɵelementStart(0, "div", 44)(1, "div", 88)(2, "h4");
|
|
539
615
|
i0.ɵɵtext(3, "Model Settings");
|
|
540
616
|
i0.ɵɵelementEnd();
|
|
541
617
|
i0.ɵɵelementStart(4, "p");
|
|
542
618
|
i0.ɵɵtext(5, "Configure AI model parameters");
|
|
543
619
|
i0.ɵɵelementEnd();
|
|
544
|
-
i0.ɵɵelementStart(6, "button",
|
|
545
|
-
i0.ɵɵlistener("click", function
|
|
546
|
-
i0.ɵɵelement(7, "i",
|
|
620
|
+
i0.ɵɵelementStart(6, "button", 106);
|
|
621
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
622
|
+
i0.ɵɵelement(7, "i", 107);
|
|
547
623
|
i0.ɵɵelementEnd()();
|
|
548
|
-
i0.ɵɵelementStart(8, "div",
|
|
624
|
+
i0.ɵɵelementStart(8, "div", 100)(9, "div", 101)(10, "label");
|
|
549
625
|
i0.ɵɵtext(11, "AI Model");
|
|
550
626
|
i0.ɵɵelementEnd();
|
|
551
|
-
i0.ɵɵelementStart(12, "kendo-dropdownlist",
|
|
552
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
553
|
-
i0.ɵɵlistener("ngModelChange", function
|
|
627
|
+
i0.ɵɵelementStart(12, "kendo-dropdownlist", 108);
|
|
628
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_dropdownlist_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); });
|
|
629
|
+
i0.ɵɵlistener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_dropdownlist_ngModelChange_12_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onModelSelectionChange()); });
|
|
554
630
|
i0.ɵɵelementEnd()();
|
|
555
|
-
i0.ɵɵelementStart(13, "div",
|
|
631
|
+
i0.ɵɵelementStart(13, "div", 101)(14, "label");
|
|
556
632
|
i0.ɵɵtext(15, "AI Vendor");
|
|
557
633
|
i0.ɵɵelementEnd();
|
|
558
|
-
i0.ɵɵelementStart(16, "kendo-dropdownlist",
|
|
559
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
634
|
+
i0.ɵɵelementStart(16, "kendo-dropdownlist", 109);
|
|
635
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_dropdownlist_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); });
|
|
560
636
|
i0.ɵɵelementEnd();
|
|
561
|
-
i0.ɵɵelementStart(17, "div",
|
|
562
|
-
i0.ɵɵtemplate(18,
|
|
637
|
+
i0.ɵɵelementStart(17, "div", 103);
|
|
638
|
+
i0.ɵɵtemplate(18, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_18_Template, 1, 0)(19, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_19_Template, 1, 0)(20, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_20_Template, 1, 0);
|
|
563
639
|
i0.ɵɵelementEnd()();
|
|
564
|
-
i0.ɵɵelementStart(21, "div",
|
|
640
|
+
i0.ɵɵelementStart(21, "div", 101)(22, "label");
|
|
565
641
|
i0.ɵɵtext(23, "AI Configuration");
|
|
566
642
|
i0.ɵɵelementEnd();
|
|
567
|
-
i0.ɵɵelementStart(24, "kendo-dropdownlist",
|
|
568
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
643
|
+
i0.ɵɵelementStart(24, "kendo-dropdownlist", 102);
|
|
644
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_dropdownlist_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); });
|
|
569
645
|
i0.ɵɵelementEnd();
|
|
570
|
-
i0.ɵɵelementStart(25, "div",
|
|
571
|
-
i0.ɵɵtemplate(26,
|
|
646
|
+
i0.ɵɵelementStart(25, "div", 103);
|
|
647
|
+
i0.ɵɵtemplate(26, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_26_Template, 2, 0)(27, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_27_Template, 1, 0);
|
|
572
648
|
i0.ɵɵelementEnd()();
|
|
573
|
-
i0.ɵɵelementStart(28, "div",
|
|
649
|
+
i0.ɵɵelementStart(28, "div", 101)(29, "label");
|
|
574
650
|
i0.ɵɵtext(30, "Response Format");
|
|
575
651
|
i0.ɵɵelementEnd();
|
|
576
|
-
i0.ɵɵelementStart(31, "kendo-dropdownlist",
|
|
577
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
652
|
+
i0.ɵɵelementStart(31, "kendo-dropdownlist", 110);
|
|
653
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_dropdownlist_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); });
|
|
578
654
|
i0.ɵɵelementEnd();
|
|
579
|
-
i0.ɵɵelementStart(32, "div",
|
|
655
|
+
i0.ɵɵelementStart(32, "div", 103);
|
|
580
656
|
i0.ɵɵtext(33, " Expected format for AI response (defaults to prompt setting) ");
|
|
581
657
|
i0.ɵɵelementEnd()();
|
|
582
|
-
i0.ɵɵelementStart(34, "div",
|
|
658
|
+
i0.ɵɵelementStart(34, "div", 101)(35, "label");
|
|
583
659
|
i0.ɵɵtext(36, "Max Tokens");
|
|
584
660
|
i0.ɵɵelementEnd();
|
|
585
|
-
i0.ɵɵelementStart(37, "kendo-numerictextbox",
|
|
586
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
661
|
+
i0.ɵɵelementStart(37, "kendo-numerictextbox", 111);
|
|
662
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
587
663
|
i0.ɵɵelementEnd();
|
|
588
|
-
i0.ɵɵelementStart(38, "div",
|
|
664
|
+
i0.ɵɵelementStart(38, "div", 103);
|
|
589
665
|
i0.ɵɵtext(39, " Maximum length of generated response ");
|
|
590
666
|
i0.ɵɵelementEnd()();
|
|
591
|
-
i0.ɵɵelementStart(40, "div",
|
|
592
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
667
|
+
i0.ɵɵelementStart(40, "div", 101)(41, "label", 112)(42, "input", 113);
|
|
668
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_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); });
|
|
593
669
|
i0.ɵɵelementEnd();
|
|
594
670
|
i0.ɵɵtext(43, " Skip Validation ");
|
|
595
671
|
i0.ɵɵelementEnd();
|
|
596
|
-
i0.ɵɵelementStart(44, "div",
|
|
672
|
+
i0.ɵɵelementStart(44, "div", 103);
|
|
597
673
|
i0.ɵɵtext(45, " Skip output validation during testing ");
|
|
598
674
|
i0.ɵɵelementEnd()();
|
|
599
|
-
i0.ɵɵelementStart(46, "kendo-expansionpanel",
|
|
600
|
-
i0.ɵɵlistener("action", function
|
|
601
|
-
i0.ɵɵelementStart(47, "div",
|
|
675
|
+
i0.ɵɵelementStart(46, "kendo-expansionpanel", 114);
|
|
676
|
+
i0.ɵɵlistener("action", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_expansionpanel_action_46_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleAdvancedParams()); });
|
|
677
|
+
i0.ɵɵelementStart(47, "div", 115)(48, "div", 101)(49, "label", 116);
|
|
602
678
|
i0.ɵɵtext(50, " Temperature ");
|
|
603
679
|
i0.ɵɵelementEnd();
|
|
604
|
-
i0.ɵɵelementStart(51, "kendo-numerictextbox",
|
|
605
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
680
|
+
i0.ɵɵelementStart(51, "kendo-numerictextbox", 117);
|
|
681
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
606
682
|
i0.ɵɵelementEnd()();
|
|
607
|
-
i0.ɵɵelementStart(52, "div",
|
|
683
|
+
i0.ɵɵelementStart(52, "div", 101)(53, "label", 118);
|
|
608
684
|
i0.ɵɵtext(54, " Top P ");
|
|
609
685
|
i0.ɵɵelementEnd();
|
|
610
|
-
i0.ɵɵelementStart(55, "kendo-numerictextbox",
|
|
611
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
686
|
+
i0.ɵɵelementStart(55, "kendo-numerictextbox", 117);
|
|
687
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
612
688
|
i0.ɵɵelementEnd()();
|
|
613
|
-
i0.ɵɵelementStart(56, "div",
|
|
689
|
+
i0.ɵɵelementStart(56, "div", 101)(57, "label", 119);
|
|
614
690
|
i0.ɵɵtext(58, " Top K ");
|
|
615
691
|
i0.ɵɵelementEnd();
|
|
616
|
-
i0.ɵɵelementStart(59, "kendo-numerictextbox",
|
|
617
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
692
|
+
i0.ɵɵelementStart(59, "kendo-numerictextbox", 117);
|
|
693
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
618
694
|
i0.ɵɵelementEnd()();
|
|
619
|
-
i0.ɵɵelementStart(60, "div",
|
|
695
|
+
i0.ɵɵelementStart(60, "div", 101)(61, "label", 120);
|
|
620
696
|
i0.ɵɵtext(62, " Min P ");
|
|
621
697
|
i0.ɵɵelementEnd();
|
|
622
|
-
i0.ɵɵelementStart(63, "kendo-numerictextbox",
|
|
623
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
698
|
+
i0.ɵɵelementStart(63, "kendo-numerictextbox", 117);
|
|
699
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
624
700
|
i0.ɵɵelementEnd()();
|
|
625
|
-
i0.ɵɵelementStart(64, "div",
|
|
701
|
+
i0.ɵɵelementStart(64, "div", 101)(65, "label", 121);
|
|
626
702
|
i0.ɵɵtext(66, " Frequency Penalty ");
|
|
627
703
|
i0.ɵɵelementEnd();
|
|
628
|
-
i0.ɵɵelementStart(67, "kendo-numerictextbox",
|
|
629
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
704
|
+
i0.ɵɵelementStart(67, "kendo-numerictextbox", 117);
|
|
705
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
630
706
|
i0.ɵɵelementEnd()();
|
|
631
|
-
i0.ɵɵelementStart(68, "div",
|
|
707
|
+
i0.ɵɵelementStart(68, "div", 101)(69, "label", 122);
|
|
632
708
|
i0.ɵɵtext(70, " Presence Penalty ");
|
|
633
709
|
i0.ɵɵelementEnd();
|
|
634
|
-
i0.ɵɵelementStart(71, "kendo-numerictextbox",
|
|
635
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
710
|
+
i0.ɵɵelementStart(71, "kendo-numerictextbox", 117);
|
|
711
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
636
712
|
i0.ɵɵelementEnd()();
|
|
637
|
-
i0.ɵɵelementStart(72, "div",
|
|
713
|
+
i0.ɵɵelementStart(72, "div", 101)(73, "label", 123);
|
|
638
714
|
i0.ɵɵtext(74, " Seed ");
|
|
639
715
|
i0.ɵɵelementEnd();
|
|
640
|
-
i0.ɵɵelementStart(75, "kendo-numerictextbox",
|
|
641
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
716
|
+
i0.ɵɵelementStart(75, "kendo-numerictextbox", 124);
|
|
717
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_numerictextbox_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); });
|
|
642
718
|
i0.ɵɵelementEnd()();
|
|
643
|
-
i0.ɵɵelementStart(76, "div",
|
|
719
|
+
i0.ɵɵelementStart(76, "div", 101)(77, "label", 125);
|
|
644
720
|
i0.ɵɵtext(78, " Stop Sequences ");
|
|
645
721
|
i0.ɵɵelementEnd();
|
|
646
|
-
i0.ɵɵelementStart(79, "kendo-textarea",
|
|
647
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
648
|
-
i0.ɵɵlistener("ngModelChange", function
|
|
722
|
+
i0.ɵɵelementStart(79, "kendo-textarea", 126);
|
|
723
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_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); });
|
|
724
|
+
i0.ɵɵlistener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_textarea_ngModelChange_79_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.updateStopSequences()); });
|
|
649
725
|
i0.ɵɵelementEnd();
|
|
650
|
-
i0.ɵɵelementStart(80, "div",
|
|
726
|
+
i0.ɵɵelementStart(80, "div", 103);
|
|
651
727
|
i0.ɵɵtext(81, " Separate multiple sequences with commas ");
|
|
652
728
|
i0.ɵɵelementEnd()();
|
|
653
|
-
i0.ɵɵelementStart(82, "div",
|
|
729
|
+
i0.ɵɵelementStart(82, "div", 101)(83, "label", 127);
|
|
654
730
|
i0.ɵɵtext(84, " Include Log Probs ");
|
|
655
731
|
i0.ɵɵelementEnd();
|
|
656
|
-
i0.ɵɵelementStart(85, "kendo-switch",
|
|
657
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
732
|
+
i0.ɵɵelementStart(85, "kendo-switch", 128);
|
|
733
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template_kendo_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); });
|
|
658
734
|
i0.ɵɵelementEnd()();
|
|
659
|
-
i0.ɵɵtemplate(86,
|
|
735
|
+
i0.ɵɵtemplate(86, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Conditional_86_Template, 4, 5, "div", 101);
|
|
660
736
|
i0.ɵɵelementEnd()()()();
|
|
661
737
|
} if (rf & 2) {
|
|
662
738
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -712,62 +788,62 @@ function AITestHarnessComponent_div_0_Conditional_4_Conditional_29_Template(rf,
|
|
|
712
788
|
i0.ɵɵadvance();
|
|
713
789
|
i0.ɵɵconditional(ctx_r1.advancedParams.includeLogProbs ? 86 : -1);
|
|
714
790
|
} }
|
|
715
|
-
function
|
|
716
|
-
const
|
|
717
|
-
i0.ɵɵelementStart(0, "button",
|
|
718
|
-
i0.ɵɵlistener("click", function
|
|
719
|
-
i0.ɵɵelement(1, "i",
|
|
791
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
792
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
793
|
+
i0.ɵɵelementStart(0, "button", 135);
|
|
794
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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()); });
|
|
795
|
+
i0.ɵɵelement(1, "i", 93);
|
|
720
796
|
i0.ɵɵtext(2, " New ");
|
|
721
797
|
i0.ɵɵelementEnd();
|
|
722
798
|
} }
|
|
723
|
-
function
|
|
724
|
-
i0.ɵɵelementStart(0, "div",
|
|
725
|
-
i0.ɵɵelement(1, "i",
|
|
799
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
800
|
+
i0.ɵɵelementStart(0, "div", 133);
|
|
801
|
+
i0.ɵɵelement(1, "i", 136);
|
|
726
802
|
i0.ɵɵelementStart(2, "p");
|
|
727
803
|
i0.ɵɵtext(3, "No saved conversations");
|
|
728
804
|
i0.ɵɵelementEnd()();
|
|
729
805
|
} }
|
|
730
|
-
function
|
|
731
|
-
const
|
|
732
|
-
i0.ɵɵelementStart(0, "div",
|
|
733
|
-
i0.ɵɵlistener("click", function
|
|
734
|
-
i0.ɵɵelementStart(1, "div",
|
|
806
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_26_For_10_Template(rf, ctx) { if (rf & 1) {
|
|
807
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
808
|
+
i0.ɵɵelementStart(0, "div", 137);
|
|
809
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
810
|
+
i0.ɵɵelementStart(1, "div", 138)(2, "h5");
|
|
735
811
|
i0.ɵɵtext(3);
|
|
736
812
|
i0.ɵɵelementEnd();
|
|
737
813
|
i0.ɵɵelementStart(4, "p");
|
|
738
814
|
i0.ɵɵtext(5);
|
|
739
815
|
i0.ɵɵelementEnd();
|
|
740
|
-
i0.ɵɵelementStart(6, "span",
|
|
816
|
+
i0.ɵɵelementStart(6, "span", 139);
|
|
741
817
|
i0.ɵɵtext(7);
|
|
742
818
|
i0.ɵɵpipe(8, "date");
|
|
743
819
|
i0.ɵɵelementEnd()();
|
|
744
|
-
i0.ɵɵelementStart(9, "button",
|
|
745
|
-
i0.ɵɵlistener("click", function
|
|
746
|
-
i0.ɵɵelement(10, "i",
|
|
820
|
+
i0.ɵɵelementStart(9, "button", 140);
|
|
821
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
822
|
+
i0.ɵɵelement(10, "i", 141);
|
|
747
823
|
i0.ɵɵelementEnd()();
|
|
748
824
|
} if (rf & 2) {
|
|
749
|
-
const
|
|
825
|
+
const conv_r29 = ctx.$implicit;
|
|
750
826
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
751
|
-
i0.ɵɵclassProp("current",
|
|
827
|
+
i0.ɵɵclassProp("current", conv_r29.id === ctx_r1.currentConversationId);
|
|
752
828
|
i0.ɵɵadvance(3);
|
|
753
|
-
i0.ɵɵtextInterpolate(
|
|
829
|
+
i0.ɵɵtextInterpolate(conv_r29.name);
|
|
754
830
|
i0.ɵɵadvance(2);
|
|
755
|
-
i0.ɵɵtextInterpolate1("",
|
|
831
|
+
i0.ɵɵtextInterpolate1("", conv_r29.messages.length, " messages");
|
|
756
832
|
i0.ɵɵadvance(2);
|
|
757
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(8, 5,
|
|
833
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(8, 5, conv_r29.updatedAt, "short"));
|
|
758
834
|
} }
|
|
759
|
-
function
|
|
760
|
-
i0.ɵɵelementStart(0, "div",
|
|
835
|
+
function AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
836
|
+
i0.ɵɵelementStart(0, "div", 42)(1, "div", 88)(2, "h4");
|
|
761
837
|
i0.ɵɵtext(3, "Saved Conversations");
|
|
762
838
|
i0.ɵɵelementEnd();
|
|
763
839
|
i0.ɵɵelementStart(4, "p");
|
|
764
840
|
i0.ɵɵtext(5, "Previously saved test sessions");
|
|
765
841
|
i0.ɵɵelementEnd();
|
|
766
|
-
i0.ɵɵtemplate(6,
|
|
842
|
+
i0.ɵɵtemplate(6, AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Conditional_6_Template, 3, 0, "button", 131);
|
|
767
843
|
i0.ɵɵelementEnd();
|
|
768
|
-
i0.ɵɵelementStart(7, "div",
|
|
769
|
-
i0.ɵɵtemplate(8,
|
|
770
|
-
i0.ɵɵrepeaterCreate(9,
|
|
844
|
+
i0.ɵɵelementStart(7, "div", 132);
|
|
845
|
+
i0.ɵɵtemplate(8, AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Conditional_8_Template, 4, 0, "div", 133);
|
|
846
|
+
i0.ɵɵrepeaterCreate(9, AITestHarnessComponent_div_0_Conditional_4_Conditional_26_For_10_Template, 11, 8, "div", 134, _forTrack0);
|
|
771
847
|
i0.ɵɵelementEnd()();
|
|
772
848
|
} if (rf & 2) {
|
|
773
849
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -784,24 +860,19 @@ function AITestHarnessComponent_div_0_Conditional_4_Template(rf, ctx) { if (rf &
|
|
|
784
860
|
i0.ɵɵtemplate(5, AITestHarnessComponent_div_0_Conditional_4_Conditional_5_Template, 6, 0, "div", 30);
|
|
785
861
|
i0.ɵɵrepeaterCreate(6, AITestHarnessComponent_div_0_Conditional_4_For_7_Template, 17, 8, "div", 31, _forTrack0);
|
|
786
862
|
i0.ɵɵelementEnd();
|
|
787
|
-
i0.ɵɵelementStart(8, "div", 32)
|
|
788
|
-
i0.ɵɵ
|
|
789
|
-
i0.ɵɵ
|
|
790
|
-
i0.ɵɵ
|
|
791
|
-
i0.ɵɵ
|
|
792
|
-
i0.ɵɵ
|
|
793
|
-
i0.ɵɵ
|
|
794
|
-
i0.ɵɵ
|
|
795
|
-
i0.ɵɵ
|
|
796
|
-
i0.ɵɵtemplate(
|
|
797
|
-
i0.ɵɵelementStart(20, "button", 41);
|
|
798
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_4_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectTab("savedConversations")); });
|
|
799
|
-
i0.ɵɵelement(21, "i", 42);
|
|
800
|
-
i0.ɵɵtext(22, " Saved ");
|
|
801
|
-
i0.ɵɵtemplate(23, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Template, 2, 1, "span", 43);
|
|
863
|
+
i0.ɵɵelementStart(8, "div", 32);
|
|
864
|
+
i0.ɵɵtemplate(9, AITestHarnessComponent_div_0_Conditional_4_Conditional_9_Template, 11, 2, "div", 33)(10, AITestHarnessComponent_div_0_Conditional_4_Conditional_10_Template, 6, 5, "div", 34);
|
|
865
|
+
i0.ɵɵelementEnd()()();
|
|
866
|
+
i0.ɵɵelementStart(11, "kendo-splitter-pane", 35)(12, "div", 36)(13, "div", 37);
|
|
867
|
+
i0.ɵɵtemplate(14, AITestHarnessComponent_div_0_Conditional_4_Conditional_14_Template, 9, 8)(15, AITestHarnessComponent_div_0_Conditional_4_Conditional_15_Template, 6, 4);
|
|
868
|
+
i0.ɵɵelementStart(16, "button", 38);
|
|
869
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_4_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectTab("savedConversations")); });
|
|
870
|
+
i0.ɵɵelement(17, "i", 39);
|
|
871
|
+
i0.ɵɵtext(18, " Saved ");
|
|
872
|
+
i0.ɵɵtemplate(19, AITestHarnessComponent_div_0_Conditional_4_Conditional_19_Template, 2, 1, "span", 40);
|
|
802
873
|
i0.ɵɵelementEnd()();
|
|
803
|
-
i0.ɵɵelementStart(
|
|
804
|
-
i0.ɵɵtemplate(
|
|
874
|
+
i0.ɵɵelementStart(20, "div", 41);
|
|
875
|
+
i0.ɵɵtemplate(21, AITestHarnessComponent_div_0_Conditional_4_Conditional_21_Template, 13, 2, "div", 42)(22, AITestHarnessComponent_div_0_Conditional_4_Conditional_22_Template, 2, 6, "div", 43)(23, AITestHarnessComponent_div_0_Conditional_4_Conditional_23_Template, 14, 4, "div", 42)(24, AITestHarnessComponent_div_0_Conditional_4_Conditional_24_Template, 12, 0, "div", 42)(25, AITestHarnessComponent_div_0_Conditional_4_Conditional_25_Template, 87, 56, "div", 44)(26, AITestHarnessComponent_div_0_Conditional_4_Conditional_26_Template, 11, 2, "div", 42);
|
|
805
876
|
i0.ɵɵelementEnd()()()();
|
|
806
877
|
} if (rf & 2) {
|
|
807
878
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -811,38 +882,33 @@ function AITestHarnessComponent_div_0_Conditional_4_Template(rf, ctx) { if (rf &
|
|
|
811
882
|
i0.ɵɵconditional(ctx_r1.conversationMessages.length === 0 ? 5 : -1);
|
|
812
883
|
i0.ɵɵadvance();
|
|
813
884
|
i0.ɵɵrepeater(ctx_r1.conversationMessages);
|
|
814
|
-
i0.ɵɵadvance(
|
|
815
|
-
i0.ɵɵ
|
|
816
|
-
i0.ɵɵproperty("rows", 3)("disabled", ctx_r1.isExecuting);
|
|
817
|
-
i0.ɵɵadvance(2);
|
|
818
|
-
i0.ɵɵproperty("disabled", ctx_r1.isExecuting || !ctx_r1.currentUserMessage.trim());
|
|
819
|
-
i0.ɵɵadvance();
|
|
820
|
-
i0.ɵɵconditional(ctx_r1.isExecuting ? 13 : 14);
|
|
885
|
+
i0.ɵɵadvance(3);
|
|
886
|
+
i0.ɵɵconditional(ctx_r1.originalPromptRunId && ctx_r1.conversationMessages.length > 0 ? 9 : 10);
|
|
821
887
|
i0.ɵɵadvance(2);
|
|
822
888
|
i0.ɵɵproperty("collapsible", false)("resizable", true)("size", "30%")("min", "300px");
|
|
823
889
|
i0.ɵɵadvance(3);
|
|
824
|
-
i0.ɵɵconditional(ctx_r1.mode === "agent" ?
|
|
890
|
+
i0.ɵɵconditional(ctx_r1.mode === "agent" ? 14 : 15);
|
|
825
891
|
i0.ɵɵadvance(2);
|
|
826
892
|
i0.ɵɵclassProp("active", ctx_r1.activeTab === "savedConversations");
|
|
827
893
|
i0.ɵɵproperty("disabled", ctx_r1.executionMonitorMode === "live" && ctx_r1.activeTab !== "savedConversations");
|
|
828
894
|
i0.ɵɵadvance(3);
|
|
829
|
-
i0.ɵɵconditional(ctx_r1.savedConversations.length > 0 ?
|
|
895
|
+
i0.ɵɵconditional(ctx_r1.savedConversations.length > 0 ? 19 : -1);
|
|
830
896
|
i0.ɵɵadvance(2);
|
|
831
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "agentVariables" ?
|
|
897
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "agentVariables" ? 21 : -1);
|
|
832
898
|
i0.ɵɵadvance();
|
|
833
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "executionMonitor" ?
|
|
899
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "executionMonitor" ? 22 : -1);
|
|
834
900
|
i0.ɵɵadvance();
|
|
835
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "agentSettings" ?
|
|
901
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "agentSettings" ? 23 : -1);
|
|
836
902
|
i0.ɵɵadvance();
|
|
837
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "templateVariables" ?
|
|
903
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "templateVariables" ? 24 : -1);
|
|
838
904
|
i0.ɵɵadvance();
|
|
839
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "modelSettings" ?
|
|
905
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "modelSettings" ? 25 : -1);
|
|
840
906
|
i0.ɵɵadvance();
|
|
841
|
-
i0.ɵɵconditional(ctx_r1.activeTab === "savedConversations" ?
|
|
907
|
+
i0.ɵɵconditional(ctx_r1.activeTab === "savedConversations" ? 26 : -1);
|
|
842
908
|
} }
|
|
843
909
|
function AITestHarnessComponent_div_0_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
844
910
|
i0.ɵɵelementStart(0, "div", 30);
|
|
845
|
-
i0.ɵɵelement(1, "i",
|
|
911
|
+
i0.ɵɵelement(1, "i", 45);
|
|
846
912
|
i0.ɵɵelementStart(2, "h4");
|
|
847
913
|
i0.ɵɵtext(3, "Start a conversation");
|
|
848
914
|
i0.ɵɵelementEnd();
|
|
@@ -851,11 +917,11 @@ function AITestHarnessComponent_div_0_Conditional_5_Conditional_3_Template(rf, c
|
|
|
851
917
|
i0.ɵɵelementEnd()();
|
|
852
918
|
} }
|
|
853
919
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
854
|
-
i0.ɵɵelement(0, "i",
|
|
920
|
+
i0.ɵɵelement(0, "i", 59);
|
|
855
921
|
i0.ɵɵtext(1, " You ");
|
|
856
922
|
} }
|
|
857
923
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
858
|
-
i0.ɵɵelement(0, "i",
|
|
924
|
+
i0.ɵɵelement(0, "i", 144);
|
|
859
925
|
i0.ɵɵtext(1);
|
|
860
926
|
} if (rf & 2) {
|
|
861
927
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -863,165 +929,165 @@ function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_4_Template
|
|
|
863
929
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.getEntityName() || "Assistant", " ");
|
|
864
930
|
} }
|
|
865
931
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
866
|
-
i0.ɵɵelementStart(0, "span",
|
|
867
|
-
i0.ɵɵelement(1, "i",
|
|
932
|
+
i0.ɵɵelementStart(0, "span", 49);
|
|
933
|
+
i0.ɵɵelement(1, "i", 61);
|
|
868
934
|
i0.ɵɵtext(2);
|
|
869
935
|
i0.ɵɵelementEnd();
|
|
870
936
|
} if (rf & 2) {
|
|
871
|
-
const
|
|
937
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
872
938
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
873
939
|
i0.ɵɵadvance(2);
|
|
874
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatElapsedTime(
|
|
940
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.formatElapsedTime(message_r32.elapsedTime), " ");
|
|
875
941
|
} }
|
|
876
942
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
877
|
-
i0.ɵɵelementStart(0, "span",
|
|
943
|
+
i0.ɵɵelementStart(0, "span", 50);
|
|
878
944
|
i0.ɵɵtext(1);
|
|
879
945
|
i0.ɵɵelementEnd();
|
|
880
946
|
} if (rf & 2) {
|
|
881
|
-
const
|
|
947
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
882
948
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
883
|
-
i0.ɵɵproperty("title", ctx_r1.getExecutionSummary(
|
|
949
|
+
i0.ɵɵproperty("title", ctx_r1.getExecutionSummary(message_r32));
|
|
884
950
|
i0.ɵɵadvance();
|
|
885
|
-
i0.ɵɵtextInterpolate(ctx_r1.formatExecutionTime(
|
|
951
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatExecutionTime(message_r32.executionTime));
|
|
886
952
|
} }
|
|
887
953
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
888
|
-
const
|
|
889
|
-
i0.ɵɵelementStart(0, "button",
|
|
890
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
891
|
-
i0.ɵɵelement(1, "i",
|
|
954
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
955
|
+
i0.ɵɵelementStart(0, "button", 62);
|
|
956
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
957
|
+
i0.ɵɵelement(1, "i", 63);
|
|
892
958
|
i0.ɵɵelementEnd();
|
|
893
959
|
} }
|
|
894
960
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
895
|
-
const
|
|
896
|
-
i0.ɵɵelementStart(0, "button",
|
|
897
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
898
|
-
i0.ɵɵelement(1, "i",
|
|
961
|
+
const _r34 = i0.ɵɵgetCurrentView();
|
|
962
|
+
i0.ɵɵelementStart(0, "button", 145);
|
|
963
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
964
|
+
i0.ɵɵelement(1, "i", 86);
|
|
899
965
|
i0.ɵɵelementEnd();
|
|
900
966
|
} }
|
|
901
967
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
902
|
-
const
|
|
903
|
-
i0.ɵɵelementStart(0, "button",
|
|
904
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_11_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
905
|
-
i0.ɵɵelement(1, "i",
|
|
968
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
969
|
+
i0.ɵɵelementStart(0, "button", 146);
|
|
970
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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" })); });
|
|
971
|
+
i0.ɵɵelement(1, "i", 147);
|
|
906
972
|
i0.ɵɵelementEnd();
|
|
907
973
|
} }
|
|
908
974
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
909
|
-
i0.ɵɵelementStart(0, "div",
|
|
975
|
+
i0.ɵɵelementStart(0, "div", 55)(1, "span", 148);
|
|
910
976
|
i0.ɵɵtext(2);
|
|
911
|
-
i0.ɵɵelementStart(3, "span",
|
|
977
|
+
i0.ɵɵelementStart(3, "span", 65);
|
|
912
978
|
i0.ɵɵtext(4, "|");
|
|
913
979
|
i0.ɵɵelementEnd()()();
|
|
914
980
|
} if (rf & 2) {
|
|
915
|
-
const
|
|
981
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
916
982
|
i0.ɵɵadvance(2);
|
|
917
|
-
i0.ɵɵtextInterpolate(
|
|
983
|
+
i0.ɵɵtextInterpolate(message_r32.streamingContent);
|
|
918
984
|
} }
|
|
919
985
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
920
|
-
i0.ɵɵelement(0, "div",
|
|
986
|
+
i0.ɵɵelement(0, "div", 56);
|
|
921
987
|
} if (rf & 2) {
|
|
922
|
-
const
|
|
988
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
923
989
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
924
|
-
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedContent(
|
|
990
|
+
i0.ɵɵproperty("innerHTML", ctx_r1.getFormattedContent(message_r32), i0.ɵɵsanitizeHtml);
|
|
925
991
|
} }
|
|
926
992
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
927
|
-
i0.ɵɵelementStart(0, "div",
|
|
928
|
-
i0.ɵɵelement(1, "i",
|
|
993
|
+
i0.ɵɵelementStart(0, "div", 57);
|
|
994
|
+
i0.ɵɵelement(1, "i", 66);
|
|
929
995
|
i0.ɵɵtext(2);
|
|
930
996
|
i0.ɵɵelementEnd();
|
|
931
997
|
} if (rf & 2) {
|
|
932
|
-
const
|
|
998
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
933
999
|
i0.ɵɵadvance(2);
|
|
934
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
1000
|
+
i0.ɵɵtextInterpolate1(" ", message_r32.error, " ");
|
|
935
1001
|
} }
|
|
936
1002
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
937
|
-
i0.ɵɵelementStart(0, "div",
|
|
1003
|
+
i0.ɵɵelementStart(0, "div", 71)(1, "pre");
|
|
938
1004
|
i0.ɵɵtext(2);
|
|
939
1005
|
i0.ɵɵelementEnd()();
|
|
940
1006
|
} if (rf & 2) {
|
|
941
|
-
const
|
|
1007
|
+
const message_r32 = i0.ɵɵnextContext(2).$implicit;
|
|
942
1008
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
943
1009
|
i0.ɵɵadvance(2);
|
|
944
|
-
i0.ɵɵtextInterpolate(ctx_r1.formatJson(
|
|
1010
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatJson(message_r32.payload));
|
|
945
1011
|
} }
|
|
946
1012
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
947
|
-
const
|
|
948
|
-
i0.ɵɵelementStart(0, "div",
|
|
949
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Template_div_click_1_listener() { i0.ɵɵrestoreView(
|
|
950
|
-
i0.ɵɵelementStart(2, "span",
|
|
951
|
-
i0.ɵɵelement(3, "i",
|
|
1013
|
+
const _r36 = i0.ɵɵgetCurrentView();
|
|
1014
|
+
i0.ɵɵelementStart(0, "div", 67)(1, "div", 68);
|
|
1015
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
1016
|
+
i0.ɵɵelementStart(2, "span", 69);
|
|
1017
|
+
i0.ɵɵelement(3, "i", 63);
|
|
952
1018
|
i0.ɵɵtext(4, " Payload ");
|
|
953
1019
|
i0.ɵɵelementEnd();
|
|
954
|
-
i0.ɵɵelementStart(5, "button",
|
|
1020
|
+
i0.ɵɵelementStart(5, "button", 70);
|
|
955
1021
|
i0.ɵɵelement(6, "i", 27);
|
|
956
1022
|
i0.ɵɵelementEnd()();
|
|
957
|
-
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template, 3, 1, "div",
|
|
1023
|
+
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Conditional_7_Template, 3, 1, "div", 71);
|
|
958
1024
|
i0.ɵɵelementEnd();
|
|
959
1025
|
} if (rf & 2) {
|
|
960
|
-
const
|
|
961
|
-
i0.ɵɵclassProp("collapsed",
|
|
1026
|
+
const message_r32 = i0.ɵɵnextContext().$implicit;
|
|
1027
|
+
i0.ɵɵclassProp("collapsed", message_r32.payloadCollapsed);
|
|
962
1028
|
i0.ɵɵadvance(6);
|
|
963
|
-
i0.ɵɵclassProp("fa-chevron-down", !
|
|
1029
|
+
i0.ɵɵclassProp("fa-chevron-down", !message_r32.payloadCollapsed)("fa-chevron-right", message_r32.payloadCollapsed);
|
|
964
1030
|
i0.ɵɵadvance();
|
|
965
|
-
i0.ɵɵconditional(!
|
|
1031
|
+
i0.ɵɵconditional(!message_r32.payloadCollapsed ? 7 : -1);
|
|
966
1032
|
} }
|
|
967
1033
|
function AITestHarnessComponent_div_0_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
968
|
-
const
|
|
969
|
-
i0.ɵɵelementStart(0, "div", 31)(1, "div",
|
|
1034
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
1035
|
+
i0.ɵɵelementStart(0, "div", 31)(1, "div", 46)(2, "span", 47);
|
|
970
1036
|
i0.ɵɵtemplate(3, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_3_Template, 2, 0)(4, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_4_Template, 2, 1);
|
|
971
1037
|
i0.ɵɵelementEnd();
|
|
972
|
-
i0.ɵɵelementStart(5, "span",
|
|
1038
|
+
i0.ɵɵelementStart(5, "span", 48);
|
|
973
1039
|
i0.ɵɵtext(6);
|
|
974
1040
|
i0.ɵɵelementEnd();
|
|
975
|
-
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_7_Template, 3, 1, "span",
|
|
1041
|
+
i0.ɵɵtemplate(7, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_7_Template, 3, 1, "span", 49)(8, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_8_Template, 2, 2, "span", 50)(9, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_9_Template, 2, 0, "button", 51)(10, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_10_Template, 2, 0, "button", 142)(11, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_11_Template, 2, 0, "button", 143);
|
|
976
1042
|
i0.ɵɵelementEnd();
|
|
977
|
-
i0.ɵɵelementStart(12, "div",
|
|
978
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_For_5_Template_button_click_13_listener() { const
|
|
979
|
-
i0.ɵɵelement(14, "i",
|
|
1043
|
+
i0.ɵɵelementStart(12, "div", 52)(13, "button", 53);
|
|
1044
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_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)); });
|
|
1045
|
+
i0.ɵɵelement(14, "i", 54);
|
|
980
1046
|
i0.ɵɵelementEnd();
|
|
981
|
-
i0.ɵɵtemplate(15, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_15_Template, 5, 1, "div",
|
|
1047
|
+
i0.ɵɵtemplate(15, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_15_Template, 5, 1, "div", 55)(16, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_16_Template, 1, 1, "div", 56)(17, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_17_Template, 3, 1, "div", 57)(18, AITestHarnessComponent_div_0_Conditional_5_For_5_Conditional_18_Template, 8, 7, "div", 58);
|
|
982
1048
|
i0.ɵɵelementEnd()();
|
|
983
1049
|
} if (rf & 2) {
|
|
984
|
-
const
|
|
1050
|
+
const message_r32 = ctx.$implicit;
|
|
985
1051
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
986
|
-
i0.ɵɵproperty("ngClass", ctx_r1.getMessageClass(
|
|
1052
|
+
i0.ɵɵproperty("ngClass", ctx_r1.getMessageClass(message_r32));
|
|
987
1053
|
i0.ɵɵadvance(3);
|
|
988
|
-
i0.ɵɵconditional(
|
|
1054
|
+
i0.ɵɵconditional(message_r32.role === "user" ? 3 : 4);
|
|
989
1055
|
i0.ɵɵadvance(3);
|
|
990
|
-
i0.ɵɵtextInterpolate(ctx_r1.formatTimestamp(
|
|
1056
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatTimestamp(message_r32.timestamp));
|
|
991
1057
|
i0.ɵɵadvance();
|
|
992
|
-
i0.ɵɵconditional(
|
|
1058
|
+
i0.ɵɵconditional(message_r32.isStreaming && message_r32.elapsedTime !== undefined ? 7 : message_r32.executionTime ? 8 : -1);
|
|
993
1059
|
i0.ɵɵadvance(2);
|
|
994
|
-
i0.ɵɵconditional(ctx_r1.showRawToggle(
|
|
1060
|
+
i0.ɵɵconditional(ctx_r1.showRawToggle(message_r32) ? 9 : -1);
|
|
995
1061
|
i0.ɵɵadvance();
|
|
996
|
-
i0.ɵɵconditional(
|
|
1062
|
+
i0.ɵɵconditional(message_r32.executionData && ctx_r1.mode === "agent" && message_r32.role === "assistant" ? 10 : -1);
|
|
997
1063
|
i0.ɵɵadvance();
|
|
998
|
-
i0.ɵɵconditional(
|
|
1064
|
+
i0.ɵɵconditional(message_r32.agentRunId && ctx_r1.mode === "agent" && message_r32.role === "assistant" ? 11 : -1);
|
|
999
1065
|
i0.ɵɵadvance(4);
|
|
1000
|
-
i0.ɵɵconditional(
|
|
1066
|
+
i0.ɵɵconditional(message_r32.isStreaming ? 15 : 16);
|
|
1001
1067
|
i0.ɵɵadvance(2);
|
|
1002
|
-
i0.ɵɵconditional(
|
|
1068
|
+
i0.ɵɵconditional(message_r32.error ? 17 : -1);
|
|
1003
1069
|
i0.ɵɵadvance();
|
|
1004
|
-
i0.ɵɵconditional(ctx_r1.hasPayload(
|
|
1070
|
+
i0.ɵɵconditional(ctx_r1.hasPayload(message_r32.payload) && ctx_r1.mode === "agent" && message_r32.role === "assistant" ? 18 : -1);
|
|
1005
1071
|
} }
|
|
1006
1072
|
function AITestHarnessComponent_div_0_Conditional_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
1007
|
-
i0.ɵɵelement(0, "i",
|
|
1073
|
+
i0.ɵɵelement(0, "i", 61);
|
|
1008
1074
|
} }
|
|
1009
1075
|
function AITestHarnessComponent_div_0_Conditional_5_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
1010
|
-
i0.ɵɵelement(0, "i",
|
|
1076
|
+
i0.ɵɵelement(0, "i", 84);
|
|
1011
1077
|
} }
|
|
1012
1078
|
function AITestHarnessComponent_div_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
1013
|
-
const
|
|
1079
|
+
const _r30 = i0.ɵɵgetCurrentView();
|
|
1014
1080
|
i0.ɵɵelementStart(0, "div", 12)(1, "div", 29, 1);
|
|
1015
1081
|
i0.ɵɵtemplate(3, AITestHarnessComponent_div_0_Conditional_5_Conditional_3_Template, 6, 0, "div", 30);
|
|
1016
1082
|
i0.ɵɵrepeaterCreate(4, AITestHarnessComponent_div_0_Conditional_5_For_5_Template, 19, 10, "div", 31, _forTrack0);
|
|
1017
1083
|
i0.ɵɵelementEnd();
|
|
1018
|
-
i0.ɵɵelementStart(6, "div", 32)(7, "div",
|
|
1019
|
-
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_5_Template_kendo_textarea_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(
|
|
1020
|
-
i0.ɵɵlistener("keypress", function AITestHarnessComponent_div_0_Conditional_5_Template_kendo_textarea_keypress_8_listener($event) { i0.ɵɵrestoreView(
|
|
1084
|
+
i0.ɵɵelementStart(6, "div", 32)(7, "div", 34)(8, "kendo-textarea", 82, 2);
|
|
1085
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AITestHarnessComponent_div_0_Conditional_5_Template_kendo_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); });
|
|
1086
|
+
i0.ɵɵlistener("keypress", function AITestHarnessComponent_div_0_Conditional_5_Template_kendo_textarea_keypress_8_listener($event) { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.handleKeyPress($event)); });
|
|
1021
1087
|
i0.ɵɵelementEnd();
|
|
1022
|
-
i0.ɵɵelementStart(10, "button",
|
|
1023
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_Template_button_click_10_listener() { i0.ɵɵrestoreView(
|
|
1024
|
-
i0.ɵɵtemplate(11, AITestHarnessComponent_div_0_Conditional_5_Conditional_11_Template, 1, 0, "i",
|
|
1088
|
+
i0.ɵɵelementStart(10, "button", 83);
|
|
1089
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_div_0_Conditional_5_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r30); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.sendMessage()); });
|
|
1090
|
+
i0.ɵɵtemplate(11, AITestHarnessComponent_div_0_Conditional_5_Conditional_11_Template, 1, 0, "i", 61)(12, AITestHarnessComponent_div_0_Conditional_5_Conditional_12_Template, 1, 0, "i", 84);
|
|
1025
1091
|
i0.ɵɵelementEnd()()()();
|
|
1026
1092
|
} if (rf & 2) {
|
|
1027
1093
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -1042,7 +1108,7 @@ function AITestHarnessComponent_div_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
1042
1108
|
i0.ɵɵtemplate(2, AITestHarnessComponent_div_0_Conditional_2_Template, 25, 10, "div", 9);
|
|
1043
1109
|
i0.ɵɵelementEnd();
|
|
1044
1110
|
i0.ɵɵelementStart(3, "div", 10);
|
|
1045
|
-
i0.ɵɵtemplate(4, AITestHarnessComponent_div_0_Conditional_4_Template,
|
|
1111
|
+
i0.ɵɵtemplate(4, AITestHarnessComponent_div_0_Conditional_4_Template, 27, 20, "kendo-splitter", 11)(5, AITestHarnessComponent_div_0_Conditional_5_Template, 13, 6, "div", 12);
|
|
1046
1112
|
i0.ɵɵelementEnd()();
|
|
1047
1113
|
} if (rf & 2) {
|
|
1048
1114
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -1052,21 +1118,21 @@ function AITestHarnessComponent_div_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
1052
1118
|
i0.ɵɵconditional(ctx_r1.showSidebar ? 4 : 5);
|
|
1053
1119
|
} }
|
|
1054
1120
|
function AITestHarnessComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1055
|
-
const
|
|
1056
|
-
i0.ɵɵelementStart(0, "kendo-dialog",
|
|
1057
|
-
i0.ɵɵlistener("close", function AITestHarnessComponent_Conditional_1_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(
|
|
1058
|
-
i0.ɵɵelementStart(1, "div",
|
|
1121
|
+
const _r37 = i0.ɵɵgetCurrentView();
|
|
1122
|
+
i0.ɵɵelementStart(0, "kendo-dialog", 149);
|
|
1123
|
+
i0.ɵɵlistener("close", function AITestHarnessComponent_Conditional_1_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelSaveDialog()); });
|
|
1124
|
+
i0.ɵɵelementStart(1, "div", 150)(2, "p");
|
|
1059
1125
|
i0.ɵɵtext(3, "Enter a name for this conversation:");
|
|
1060
1126
|
i0.ɵɵelementEnd();
|
|
1061
|
-
i0.ɵɵelementStart(4, "input",
|
|
1062
|
-
i0.ɵɵlistener("keyup", function AITestHarnessComponent_Conditional_1_Template_input_keyup_4_listener() { i0.ɵɵrestoreView(
|
|
1127
|
+
i0.ɵɵelementStart(4, "input", 151, 3);
|
|
1128
|
+
i0.ɵɵlistener("keyup", function AITestHarnessComponent_Conditional_1_Template_input_keyup_4_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateTempConversation()); });
|
|
1063
1129
|
i0.ɵɵelementEnd()();
|
|
1064
|
-
i0.ɵɵelementStart(6, "kendo-dialog-actions")(7, "button",
|
|
1065
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(
|
|
1130
|
+
i0.ɵɵelementStart(6, "kendo-dialog-actions")(7, "button", 152);
|
|
1131
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r37); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelSaveDialog()); });
|
|
1066
1132
|
i0.ɵɵtext(8, "Cancel");
|
|
1067
1133
|
i0.ɵɵelementEnd();
|
|
1068
|
-
i0.ɵɵelementStart(9, "button",
|
|
1069
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_1_Template_button_click_9_listener() { i0.ɵɵrestoreView(
|
|
1134
|
+
i0.ɵɵelementStart(9, "button", 153);
|
|
1135
|
+
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.confirmSaveConversation()); });
|
|
1070
1136
|
i0.ɵɵtext(10, " Save ");
|
|
1071
1137
|
i0.ɵɵelementEnd()()();
|
|
1072
1138
|
} if (rf & 2) {
|
|
@@ -1076,21 +1142,21 @@ function AITestHarnessComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
1076
1142
|
i0.ɵɵproperty("primary", true)("disabled", ctx_r1.tempConversationName === "");
|
|
1077
1143
|
} }
|
|
1078
1144
|
function AITestHarnessComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1079
|
-
const
|
|
1080
|
-
i0.ɵɵelementStart(0, "kendo-dialog",
|
|
1081
|
-
i0.ɵɵlistener("close", function AITestHarnessComponent_Conditional_2_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(
|
|
1082
|
-
i0.ɵɵelementStart(1, "div",
|
|
1145
|
+
const _r38 = i0.ɵɵgetCurrentView();
|
|
1146
|
+
i0.ɵɵelementStart(0, "kendo-dialog", 154);
|
|
1147
|
+
i0.ɵɵlistener("close", function AITestHarnessComponent_Conditional_2_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r38); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelLoadConversation()); });
|
|
1148
|
+
i0.ɵɵelementStart(1, "div", 150)(2, "p");
|
|
1083
1149
|
i0.ɵɵtext(3, "Loading this conversation will replace the current one. Any unsaved changes will be lost.");
|
|
1084
1150
|
i0.ɵɵelementEnd();
|
|
1085
1151
|
i0.ɵɵelementStart(4, "p");
|
|
1086
1152
|
i0.ɵɵtext(5, "Do you want to continue?");
|
|
1087
1153
|
i0.ɵɵelementEnd()();
|
|
1088
|
-
i0.ɵɵelementStart(6, "kendo-dialog-actions")(7, "button",
|
|
1089
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(
|
|
1154
|
+
i0.ɵɵelementStart(6, "kendo-dialog-actions")(7, "button", 152);
|
|
1155
|
+
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r38); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelLoadConversation()); });
|
|
1090
1156
|
i0.ɵɵtext(8, "Cancel");
|
|
1091
1157
|
i0.ɵɵelementEnd();
|
|
1092
|
-
i0.ɵɵelementStart(9, "button",
|
|
1093
|
-
i0.ɵɵlistener("click", function AITestHarnessComponent_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(
|
|
1158
|
+
i0.ɵɵelementStart(9, "button", 155);
|
|
1159
|
+
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.confirmLoadConversation()); });
|
|
1094
1160
|
i0.ɵɵtext(10, " Load Conversation ");
|
|
1095
1161
|
i0.ɵɵelementEnd()()();
|
|
1096
1162
|
} if (rf & 2) {
|
|
@@ -1150,6 +1216,14 @@ export class AITestHarnessComponent {
|
|
|
1150
1216
|
this.mode = 'agent';
|
|
1151
1217
|
/** The entity to test - either an AI Agent or AI Prompt */
|
|
1152
1218
|
this.entity = null;
|
|
1219
|
+
/** The original prompt run ID when re-running a previous prompt execution */
|
|
1220
|
+
this.originalPromptRunId = null;
|
|
1221
|
+
/** The system prompt override to use instead of rendering from template */
|
|
1222
|
+
this.systemPromptOverride = null;
|
|
1223
|
+
/** Whether a re-run has been executed (shows Reset button instead of Re-Run) */
|
|
1224
|
+
this.hasExecutedRerun = false;
|
|
1225
|
+
/** Original messages from the prompt run for reset functionality */
|
|
1226
|
+
this.originalPromptRunMessages = [];
|
|
1153
1227
|
this._isVisible = false;
|
|
1154
1228
|
/** Event emitted when the visibility state changes, allowing parent components to react */
|
|
1155
1229
|
this.visibilityChange = new EventEmitter();
|
|
@@ -1305,7 +1379,11 @@ export class AITestHarnessComponent {
|
|
|
1305
1379
|
* Component initialization. Loads saved conversations, sets up event subscriptions,
|
|
1306
1380
|
* and initializes the harness to a clean state.
|
|
1307
1381
|
*/
|
|
1308
|
-
ngOnInit() {
|
|
1382
|
+
async ngOnInit() {
|
|
1383
|
+
console.log('🚀 AITestHarnessComponent.ngOnInit');
|
|
1384
|
+
console.log('📌 originalPromptRunId:', this.originalPromptRunId);
|
|
1385
|
+
console.log('🎯 entity:', this.entity);
|
|
1386
|
+
console.log('📊 mode:', this.mode);
|
|
1309
1387
|
// Ensure we have an entity
|
|
1310
1388
|
if (!this.entity && this.aiAgent) {
|
|
1311
1389
|
// Handle backward compatibility
|
|
@@ -1317,6 +1395,11 @@ export class AITestHarnessComponent {
|
|
|
1317
1395
|
this.resetHarness();
|
|
1318
1396
|
// Load configurations for both modes
|
|
1319
1397
|
this.loadAvailableConfigurations();
|
|
1398
|
+
// If we have a prompt run ID, load the conversation history
|
|
1399
|
+
if (this.originalPromptRunId && this.mode === 'prompt') {
|
|
1400
|
+
console.log('🔄 Loading from prompt run in ngOnInit');
|
|
1401
|
+
await this.loadFromPromptRun(this.originalPromptRunId);
|
|
1402
|
+
}
|
|
1320
1403
|
// Load models if in prompt mode
|
|
1321
1404
|
if (this.mode === 'prompt') {
|
|
1322
1405
|
this.loadAvailableModels();
|
|
@@ -1858,7 +1941,7 @@ export class AITestHarnessComponent {
|
|
|
1858
1941
|
this.lastAgentPayload = null;
|
|
1859
1942
|
this.subAgentHistory = [];
|
|
1860
1943
|
// Set default tab based on mode
|
|
1861
|
-
this.activeTab = this.mode === 'agent' ? 'agentVariables' : '
|
|
1944
|
+
this.activeTab = this.mode === 'agent' ? 'agentVariables' : 'modelSettings';
|
|
1862
1945
|
// Reset advanced parameters
|
|
1863
1946
|
this.advancedParams = {
|
|
1864
1947
|
temperature: null,
|
|
@@ -2032,6 +2115,33 @@ export class AITestHarnessComponent {
|
|
|
2032
2115
|
* await this.sendMessage();
|
|
2033
2116
|
* ```
|
|
2034
2117
|
*/
|
|
2118
|
+
/**
|
|
2119
|
+
* Executes a re-run of a previously loaded prompt run.
|
|
2120
|
+
* This bypasses the need for a new user message since we're re-running with existing messages.
|
|
2121
|
+
*/
|
|
2122
|
+
async executeRerun() {
|
|
2123
|
+
if (this.mode === 'prompt' && this.conversationMessages.length > 0) {
|
|
2124
|
+
// Mark that we've executed a re-run
|
|
2125
|
+
this.hasExecutedRerun = true;
|
|
2126
|
+
// For prompt re-runs, we need to execute the prompt with the loaded messages
|
|
2127
|
+
await this.executePrompt(''); // Empty message since we're using loaded conversation
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
/**
|
|
2131
|
+
* Resets the conversation back to the original messages from the prompt run.
|
|
2132
|
+
* This is available after a re-run has been executed.
|
|
2133
|
+
*/
|
|
2134
|
+
resetToOriginalMessages() {
|
|
2135
|
+
if (this.originalPromptRunMessages.length > 0) {
|
|
2136
|
+
// Reset messages to the original state
|
|
2137
|
+
this.conversationMessages = [...this.originalPromptRunMessages];
|
|
2138
|
+
// Reset the execution flag so Re-Run button shows again
|
|
2139
|
+
this.hasExecutedRerun = false;
|
|
2140
|
+
// Trigger change detection
|
|
2141
|
+
this.cdr.detectChanges();
|
|
2142
|
+
console.log('🔄 Reset to original messages from prompt run');
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2035
2145
|
async sendMessage() {
|
|
2036
2146
|
if (!this.currentUserMessage.trim() || !this.entity) {
|
|
2037
2147
|
return;
|
|
@@ -2335,8 +2445,8 @@ export class AITestHarnessComponent {
|
|
|
2335
2445
|
}));
|
|
2336
2446
|
// Execute the prompt using RunAIPrompt
|
|
2337
2447
|
const query = `
|
|
2338
|
-
mutation RunAIPrompt($promptId: String!, $data: String, $overrideModelId: String, $overrideVendorId: String, $configurationId: String, $skipValidation: Boolean, $templateData: String, $responseFormat: String, $temperature: Float, $topP: Float, $topK: Int, $minP: Float, $frequencyPenalty: Float, $presencePenalty: Float, $seed: Int, $stopSequences: [String!], $includeLogProbs: Boolean, $topLogProbs: Int, $messages: String) {
|
|
2339
|
-
RunAIPrompt(promptId: $promptId, data: $data, overrideModelId: $overrideModelId, overrideVendorId: $overrideVendorId, configurationId: $configurationId, skipValidation: $skipValidation, templateData: $templateData, responseFormat: $responseFormat, temperature: $temperature, topP: $topP, topK: $topK, minP: $minP, frequencyPenalty: $frequencyPenalty, presencePenalty: $presencePenalty, seed: $seed, stopSequences: $stopSequences, includeLogProbs: $includeLogProbs, topLogProbs: $topLogProbs, messages: $messages) {
|
|
2448
|
+
mutation RunAIPrompt($promptId: String!, $data: String, $overrideModelId: String, $overrideVendorId: String, $configurationId: String, $skipValidation: Boolean, $templateData: String, $responseFormat: String, $temperature: Float, $topP: Float, $topK: Int, $minP: Float, $frequencyPenalty: Float, $presencePenalty: Float, $seed: Int, $stopSequences: [String!], $includeLogProbs: Boolean, $topLogProbs: Int, $messages: String, $rerunFromPromptRunID: String, $systemPromptOverride: String) {
|
|
2449
|
+
RunAIPrompt(promptId: $promptId, data: $data, overrideModelId: $overrideModelId, overrideVendorId: $overrideVendorId, configurationId: $configurationId, skipValidation: $skipValidation, templateData: $templateData, responseFormat: $responseFormat, temperature: $temperature, topP: $topP, topK: $topK, minP: $minP, frequencyPenalty: $frequencyPenalty, presencePenalty: $presencePenalty, seed: $seed, stopSequences: $stopSequences, includeLogProbs: $includeLogProbs, topLogProbs: $topLogProbs, messages: $messages, rerunFromPromptRunID: $rerunFromPromptRunID, systemPromptOverride: $systemPromptOverride) {
|
|
2340
2450
|
success
|
|
2341
2451
|
output
|
|
2342
2452
|
parsedResult
|
|
@@ -2369,7 +2479,9 @@ export class AITestHarnessComponent {
|
|
|
2369
2479
|
stopSequences: this.advancedParams.stopSequences.length > 0 ? this.advancedParams.stopSequences : undefined,
|
|
2370
2480
|
includeLogProbs: this.advancedParams.includeLogProbs,
|
|
2371
2481
|
topLogProbs: this.advancedParams.includeLogProbs ? this.advancedParams.topLogProbs : undefined,
|
|
2372
|
-
messages: messages.length > 0 ? JSON.stringify(messages) : undefined
|
|
2482
|
+
messages: messages.length > 0 ? JSON.stringify(messages) : undefined,
|
|
2483
|
+
rerunFromPromptRunID: this.originalPromptRunId || undefined,
|
|
2484
|
+
systemPromptOverride: this.systemPromptOverride || undefined
|
|
2373
2485
|
};
|
|
2374
2486
|
const result = await dataProvider.ExecuteGQL(query, variables);
|
|
2375
2487
|
const executionResult = result?.RunAIPrompt;
|
|
@@ -3707,6 +3819,94 @@ export class AITestHarnessComponent {
|
|
|
3707
3819
|
this.minimizeRequested.emit();
|
|
3708
3820
|
}
|
|
3709
3821
|
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Loads data from an existing prompt run to pre-populate the test harness
|
|
3824
|
+
* @param promptRunId - The ID of the prompt run to load
|
|
3825
|
+
*/
|
|
3826
|
+
async loadFromPromptRun(promptRunId) {
|
|
3827
|
+
console.log('🔄 Loading from prompt run:', promptRunId);
|
|
3828
|
+
const md = new Metadata();
|
|
3829
|
+
const promptRun = await md.GetEntityObject('MJ: AI Prompt Runs');
|
|
3830
|
+
if (await promptRun.Load(promptRunId)) {
|
|
3831
|
+
console.log('✅ Prompt run loaded successfully');
|
|
3832
|
+
console.log('📝 Raw Messages field:', promptRun.Messages);
|
|
3833
|
+
// Set the model/vendor/configuration
|
|
3834
|
+
if (promptRun.ModelID) {
|
|
3835
|
+
this.selectedModelId = promptRun.ModelID;
|
|
3836
|
+
}
|
|
3837
|
+
if (promptRun.VendorID) {
|
|
3838
|
+
this.selectedVendorId = promptRun.VendorID;
|
|
3839
|
+
}
|
|
3840
|
+
if (promptRun.ConfigurationID) {
|
|
3841
|
+
this.selectedConfigurationId = promptRun.ConfigurationID;
|
|
3842
|
+
}
|
|
3843
|
+
// Set advanced parameters
|
|
3844
|
+
if (promptRun.Temperature != null) {
|
|
3845
|
+
this.advancedParams.temperature = promptRun.Temperature;
|
|
3846
|
+
}
|
|
3847
|
+
if (promptRun.TopP != null) {
|
|
3848
|
+
this.advancedParams.topP = promptRun.TopP;
|
|
3849
|
+
}
|
|
3850
|
+
if (promptRun.TopK != null) {
|
|
3851
|
+
this.advancedParams.topK = promptRun.TopK;
|
|
3852
|
+
}
|
|
3853
|
+
if (promptRun.MinP != null) {
|
|
3854
|
+
this.advancedParams.minP = promptRun.MinP;
|
|
3855
|
+
}
|
|
3856
|
+
if (promptRun.FrequencyPenalty != null) {
|
|
3857
|
+
this.advancedParams.frequencyPenalty = promptRun.FrequencyPenalty;
|
|
3858
|
+
}
|
|
3859
|
+
if (promptRun.PresencePenalty != null) {
|
|
3860
|
+
this.advancedParams.presencePenalty = promptRun.PresencePenalty;
|
|
3861
|
+
}
|
|
3862
|
+
if (promptRun.Seed != null) {
|
|
3863
|
+
this.advancedParams.seed = promptRun.Seed;
|
|
3864
|
+
}
|
|
3865
|
+
// Use the extended entity methods to get conversation messages
|
|
3866
|
+
const parsedData = promptRun.ParseMessagesData();
|
|
3867
|
+
console.log('🔍 Parsed messages data:', parsedData);
|
|
3868
|
+
const chatMessages = promptRun.GetChatMessages();
|
|
3869
|
+
console.log('💬 Extracted chat messages:', chatMessages);
|
|
3870
|
+
if (chatMessages.length > 0) {
|
|
3871
|
+
// Convert messages to the format expected by the test harness
|
|
3872
|
+
const convertedMessages = chatMessages.map((msg, index) => ({
|
|
3873
|
+
id: `msg-${Date.now()}-${index}`,
|
|
3874
|
+
role: msg.role,
|
|
3875
|
+
content: typeof msg.content === 'string' ? msg.content :
|
|
3876
|
+
Array.isArray(msg.content) ?
|
|
3877
|
+
msg.content.filter(block => block.type === 'text').map(block => block.content).join('\n') :
|
|
3878
|
+
'',
|
|
3879
|
+
timestamp: new Date(),
|
|
3880
|
+
isStreaming: false
|
|
3881
|
+
}));
|
|
3882
|
+
console.log('🎯 Converted messages for test harness:', convertedMessages);
|
|
3883
|
+
this.conversationMessages = convertedMessages;
|
|
3884
|
+
// Store original messages for reset functionality
|
|
3885
|
+
this.originalPromptRunMessages = [...convertedMessages];
|
|
3886
|
+
// Reset re-run execution state
|
|
3887
|
+
this.hasExecutedRerun = false;
|
|
3888
|
+
console.log('✅ conversationMessages set:', this.conversationMessages);
|
|
3889
|
+
// Trigger change detection
|
|
3890
|
+
this.cdr.detectChanges();
|
|
3891
|
+
}
|
|
3892
|
+
else {
|
|
3893
|
+
console.log('⚠️ No chat messages found in prompt run');
|
|
3894
|
+
}
|
|
3895
|
+
// Extract and store the system prompt for re-run
|
|
3896
|
+
const systemPrompt = promptRun.GetSystemPrompt();
|
|
3897
|
+
if (systemPrompt) {
|
|
3898
|
+
this.systemPromptOverride = systemPrompt;
|
|
3899
|
+
console.log('📋 System prompt override set');
|
|
3900
|
+
}
|
|
3901
|
+
// Switch to model settings tab for prompt re-runs
|
|
3902
|
+
if (this.activeTab !== 'modelSettings') {
|
|
3903
|
+
this.selectTab('modelSettings');
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
else {
|
|
3907
|
+
console.error('❌ Failed to load prompt run:', promptRunId);
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3710
3910
|
static { this.ɵfac = function AITestHarnessComponent_Factory(t) { return new (t || AITestHarnessComponent)(i0.ɵɵdirectiveInject(i1.DomSanitizer), i0.ɵɵdirectiveInject(i2.WindowService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.Router)); }; }
|
|
3711
3911
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AITestHarnessComponent, selectors: [["mj-ai-test-harness"]], viewQuery: function AITestHarnessComponent_Query(rf, ctx) { if (rf & 1) {
|
|
3712
3912
|
i0.ɵɵviewQuery(_c0, 5);
|
|
@@ -3719,7 +3919,7 @@ export class AITestHarnessComponent {
|
|
|
3719
3919
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fileInput = _t.first);
|
|
3720
3920
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInput = _t.first);
|
|
3721
3921
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.saveDialogInput = _t.first);
|
|
3722
|
-
} }, inputs: { mode: "mode", entity: "entity", aiAgent: "aiAgent", isVisible: "isVisible" }, outputs: { visibilityChange: "visibilityChange", runOpened: "runOpened", minimizeRequested: "minimizeRequested" }, features: [i0.ɵɵNgOnChangesFeature], decls: 3, vars: 3, consts: [["fileInput", ""], ["messagesContainer", ""], ["messageInput", ""], ["saveDialogInput", ""], ["class", "harness-container", "kendoWindowContainer", "", 4, "ngIf"], [1, "save-dialog", 3, "title", "width"], [1, "confirm-dialog", 3, "title", "width"], ["kendoWindowContainer", "", 1, "harness-container"], [1, "harness-header"], [1, "agent-info"], [1, "harness-body"], ["orientation", "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, "collapsible", "resizable", "min"], [1, "messages-container"], [1, "empty-state"], [3, "ngClass"], [1, "input-area"], [1, "
|
|
3922
|
+
} }, inputs: { mode: "mode", entity: "entity", originalPromptRunId: "originalPromptRunId", systemPromptOverride: "systemPromptOverride", aiAgent: "aiAgent", isVisible: "isVisible" }, outputs: { visibilityChange: "visibilityChange", runOpened: "runOpened", minimizeRequested: "minimizeRequested" }, features: [i0.ɵɵNgOnChangesFeature], decls: 3, vars: 3, consts: [["fileInput", ""], ["messagesContainer", ""], ["messageInput", ""], ["saveDialogInput", ""], ["class", "harness-container", "kendoWindowContainer", "", 4, "ngIf"], [1, "save-dialog", 3, "title", "width"], [1, "confirm-dialog", 3, "title", "width"], ["kendoWindowContainer", "", 1, "harness-container"], [1, "harness-header"], [1, "agent-info"], [1, "harness-body"], ["orientation", "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, "collapsible", "resizable", "min"], [1, "messages-container"], [1, "empty-state"], [3, "ngClass"], [1, "input-area"], [1, "rerun-mode-container"], [1, "input-container"], [3, "collapsible", "resizable", "size", "min"], [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, "fa-solid", "fa-comments"], [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, "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"], [1, "empty-variables"], [1, "variable-item"], [1, "add-button", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], ["placeholder", "Variable name", 1, "variable-name", 3, "ngModelChange", "ngModel", "disabled"], ["textField", "text", "valueField", "value", 1, "variable-type", 3, "ngModelChange", "ngModel", "data", "valuePrimitive", "disabled"], [1, "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"], ["title", "Advanced Parameters", 1, "advanced-params-panel", 3, "action", "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, "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"], [1, "empty-saved"], [1, "saved-item", 3, "current"], ["title", "Start a new conversation", 1, "custom-button", "small", "primary", 3, "click"], [1, "fa-solid", "fa-folder-open"], [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", "title", "width"], [1, "dialog-content"], ["type", "text", "placeholder", "Conversation name", 1, "k-textbox", "k-input", "k-input-md", "k-rounded-md", "k-input-solid", "full-width", 3, "keyup"], ["kendoButton", "", 3, "click"], ["kendoButton", "", 3, "click", "primary", "disabled"], [1, "confirm-dialog", 3, "close", "title", "width"], ["kendoButton", "", 3, "click", "primary"]], template: function AITestHarnessComponent_Template(rf, ctx) { if (rf & 1) {
|
|
3723
3923
|
i0.ɵɵtemplate(0, AITestHarnessComponent_div_0_Template, 6, 2, "div", 4)(1, AITestHarnessComponent_Conditional_1_Template, 11, 4, "kendo-dialog", 5)(2, AITestHarnessComponent_Conditional_2_Template, 11, 3, "kendo-dialog", 6);
|
|
3724
3924
|
} if (rf & 2) {
|
|
3725
3925
|
i0.ɵɵproperty("ngIf", ctx.isVisible);
|
|
@@ -3727,15 +3927,19 @@ export class AITestHarnessComponent {
|
|
|
3727
3927
|
i0.ɵɵconditional(ctx.showSaveDialog ? 1 : -1);
|
|
3728
3928
|
i0.ɵɵadvance();
|
|
3729
3929
|
i0.ɵɵconditional(ctx.showLoadConfirmDialog ? 2 : -1);
|
|
3730
|
-
} }, dependencies: [i4.NgClass, i4.NgIf, i5.CheckboxControlValueAccessor, i5.NgControlStatus, i5.NgModel, i6.ButtonComponent, i2.DialogComponent, i2.DialogActionsComponent, i2.WindowContainerDirective, i7.DropDownListComponent, i8.TextAreaComponent, i8.TextBoxComponent, i8.SwitchComponent, i8.NumericTextBoxComponent, i9.ExpansionPanelComponent, i9.SplitterComponent, i9.SplitterPaneComponent, i10.CodeEditorComponent, i11.AgentExecutionMonitorComponent, i4.DatePipe], styles: ["\n\n.harness-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n\n\n.custom-button[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\n}\n\n.custom-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #e9ecef;\n border-color: #adb5bd;\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: #0d6efd;\n border: 1px solid #0d6efd;\n color: white;\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: #0b5ed7;\n border-color: #0a58ca;\n}\n\n.send-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #0a58ca;\n border-color: #0a58ca;\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: white;\n border: 1px solid #0d6efd;\n color: #0d6efd;\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: #0d6efd;\n color: white;\n}\n\n\n\n.remove-button[_ngcontent-%COMP%], \n.delete-button[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n color: #dc3545;\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: rgba(220, 53, 69, 0.1);\n color: #bd2130;\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: #adb5bd;\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: #6c757d;\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: #495057;\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: #6c757d;\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: #495057;\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: white;\n border-bottom: 1px solid #dee2e6;\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: #17a2b8;\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: #212529;\n}\n\n.agent-details[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: #6c757d;\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: white;\n border-right: 1px solid #dee2e6;\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: #6c757d;\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: #495057;\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: #6f42c1;\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: #17a2b8;\n}\n\n.message-time[_ngcontent-%COMP%] {\n color: #6c757d;\n font-size: 12px;\n}\n\n.execution-time[_ngcontent-%COMP%] {\n background: #e9ecef;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: #495057;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming[_ngcontent-%COMP%] {\n background: #fff3cd;\n color: #856404;\n border: 1px solid #ffeaa7;\n}\n\n.raw-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: #6c757d;\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: #495057;\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: #e7f3ff;\n border: 1px solid #b8daff;\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n}\n\n.message.streaming[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: #fff3cd;\n border: 1px solid #ffeaa7;\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: #495057;\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: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 6px;\n color: #721c24;\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: #dc3545;\n}\n\n\n\n.payload-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n overflow: hidden;\n background: #ffffff;\n}\n\n.payload-header[_ngcontent-%COMP%] {\n background: #f8f9fa;\n padding: 8px 12px;\n border-bottom: 1px solid #e9ecef;\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: #e9ecef;\n}\n\n.payload-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6c757d;\n font-size: 12px;\n}\n\n.payload-content[_ngcontent-%COMP%] {\n max-height: 250px;\n overflow: auto;\n background: #f8f9fa;\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: #212529;\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: #6c757d;\n transition: color 0.2s;\n}\n\n.payload-toggle[_ngcontent-%COMP%]:hover {\n color: #495057;\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: #333;\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 #dee2e6;\n border-radius: 4px;\n \n &:focus {\n outline: none;\n border-color: #ff6358;\n box-shadow: 0 0 0 0.25rem rgba(255, 99, 88, 0.25);\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: #f8f9fa;\n border: 1px solid #e0e0e0;\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: #333;\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: #212529;\n border-bottom: 2px solid #e9ecef;\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: #212529;\n border-bottom: 1px solid #e9ecef;\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: #212529;\n}\n\n.code-block[_ngcontent-%COMP%] {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\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: #212529;\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: #d73e48;\n}\n\n.inline-code[_ngcontent-%COMP%] {\n background: #f1f3f4;\n border: 1px solid #dadce0;\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: #d73e48;\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: #0d6efd;\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link[_ngcontent-%COMP%]:hover {\n color: #0a58ca;\n text-decoration: none;\n}\n\n\n\n.message-content[_ngcontent-%COMP%] {\n background: #f8f9fa;\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: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\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: white;\n border-top: 1px solid #dee2e6;\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.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: white;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n.harness-body[_ngcontent-%COMP%] kendo-splitter[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n.harness-body[_ngcontent-%COMP%] kendo-splitter-pane[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n\n\n.sidebar-tabs[_ngcontent-%COMP%] {\n display: flex;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\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: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n color: #0d6efd;\n border-bottom-color: #0d6efd;\n background: white;\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: #6c757d;\n color: white;\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: #0d6efd;\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: #212529;\n}\n\n.tab-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #6c757d;\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: #6c757d;\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: #6c757d;\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 #dee2e6;\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: #f8f9fa;\n border-color: #adb5bd;\n}\n\n.saved-item.current[_ngcontent-%COMP%] {\n background: #e7f3ff;\n border-color: #0d6efd;\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: #212529;\n}\n\n.saved-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: #6c757d;\n}\n\n.saved-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\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: #f1f1f1;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #c1c1c1;\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: #a1a1a1;\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: #343a40;\n color: white;\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: white;\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 #dee2e6;\n border-radius: 4px;\n}\n\n.advanced-params-panel[_ngcontent-%COMP%] .k-expander-title {\n font-weight: 600;\n color: #495057;\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}"] }); }
|
|
3930
|
+
} }, dependencies: [i4.NgClass, i4.NgIf, i5.CheckboxControlValueAccessor, i5.NgControlStatus, i5.NgModel, i6.ButtonComponent, i2.DialogComponent, i2.DialogActionsComponent, i2.WindowContainerDirective, i7.DropDownListComponent, i8.TextAreaComponent, i8.TextBoxComponent, i8.SwitchComponent, i8.NumericTextBoxComponent, i9.ExpansionPanelComponent, i9.SplitterComponent, i9.SplitterPaneComponent, i10.CodeEditorComponent, i11.AgentExecutionMonitorComponent, i4.DatePipe], styles: ["\n\n.harness-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n\n\n.custom-button[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\n}\n\n.custom-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #e9ecef;\n border-color: #adb5bd;\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: #0d6efd;\n border: 1px solid #0d6efd;\n color: white;\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: #0b5ed7;\n border-color: #0a58ca;\n}\n\n.send-button[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #0a58ca;\n border-color: #0a58ca;\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: white;\n border: 1px solid #0d6efd;\n color: #0d6efd;\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: #0d6efd;\n color: white;\n}\n\n\n\n.remove-button[_ngcontent-%COMP%], \n.delete-button[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n color: #dc3545;\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: rgba(220, 53, 69, 0.1);\n color: #bd2130;\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: #adb5bd;\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: #6c757d;\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: #495057;\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: #6c757d;\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: #495057;\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: white;\n border-bottom: 1px solid #dee2e6;\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: #17a2b8;\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: #212529;\n}\n\n.agent-details[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: #6c757d;\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: white;\n border-right: 1px solid #dee2e6;\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: #6c757d;\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: #495057;\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: #6f42c1;\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-role[_ngcontent-%COMP%] {\n color: #17a2b8;\n}\n\n.message-time[_ngcontent-%COMP%] {\n color: #6c757d;\n font-size: 12px;\n}\n\n.execution-time[_ngcontent-%COMP%] {\n background: #e9ecef;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: #495057;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming[_ngcontent-%COMP%] {\n background: #fff3cd;\n color: #856404;\n border: 1px solid #ffeaa7;\n}\n\n.raw-toggle[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: #6c757d;\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: #495057;\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: #e7f3ff;\n border: 1px solid #b8daff;\n}\n\n.message-assistant[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n}\n\n.message.streaming[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n background: #fff3cd;\n border: 1px solid #ffeaa7;\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: #495057;\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: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 6px;\n color: #721c24;\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: #dc3545;\n}\n\n\n\n.payload-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n overflow: hidden;\n background: #ffffff;\n}\n\n.payload-header[_ngcontent-%COMP%] {\n background: #f8f9fa;\n padding: 8px 12px;\n border-bottom: 1px solid #e9ecef;\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: #e9ecef;\n}\n\n.payload-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6c757d;\n font-size: 12px;\n}\n\n.payload-content[_ngcontent-%COMP%] {\n max-height: 250px;\n overflow: auto;\n background: #f8f9fa;\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: #212529;\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: #6c757d;\n transition: color 0.2s;\n}\n\n.payload-toggle[_ngcontent-%COMP%]:hover {\n color: #495057;\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: #333;\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 #dee2e6;\n border-radius: 4px;\n \n &:focus {\n outline: none;\n border-color: #ff6358;\n box-shadow: 0 0 0 0.25rem rgba(255, 99, 88, 0.25);\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: #f8f9fa;\n border: 1px solid #e0e0e0;\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: #333;\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: #212529;\n border-bottom: 2px solid #e9ecef;\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: #212529;\n border-bottom: 1px solid #e9ecef;\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: #212529;\n}\n\n.code-block[_ngcontent-%COMP%] {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\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: #212529;\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: #d73e48;\n}\n\n.inline-code[_ngcontent-%COMP%] {\n background: #f1f3f4;\n border: 1px solid #dadce0;\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: #d73e48;\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: #0d6efd;\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link[_ngcontent-%COMP%]:hover {\n color: #0a58ca;\n text-decoration: none;\n}\n\n\n\n.message-content[_ngcontent-%COMP%] {\n background: #f8f9fa;\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: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\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: white;\n border-top: 1px solid #dee2e6;\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: #f0f9ff;\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: #0369a1;\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: #6b7280;\n}\n\n.reset-button[_ngcontent-%COMP%]:hover:not(:disabled) {\n background-color: #4b5563;\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: white;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n.harness-body[_ngcontent-%COMP%] kendo-splitter[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n.harness-body[_ngcontent-%COMP%] kendo-splitter-pane[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n\n\n.sidebar-tabs[_ngcontent-%COMP%] {\n display: flex;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\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: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.tab-button.active[_ngcontent-%COMP%] {\n color: #0d6efd;\n border-bottom-color: #0d6efd;\n background: white;\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: #6c757d;\n color: white;\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: #0d6efd;\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: #212529;\n}\n\n.tab-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #6c757d;\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: #6c757d;\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: #6c757d;\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 #dee2e6;\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: #f8f9fa;\n border-color: #adb5bd;\n}\n\n.saved-item.current[_ngcontent-%COMP%] {\n background: #e7f3ff;\n border-color: #0d6efd;\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: #212529;\n}\n\n.saved-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: #6c757d;\n}\n\n.saved-date[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6c757d;\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: #f1f1f1;\n}\n\n.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.sidebar-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #c1c1c1;\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: #a1a1a1;\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: #343a40;\n color: white;\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: white;\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 #dee2e6;\n border-radius: 4px;\n}\n\n.advanced-params-panel[_ngcontent-%COMP%] .k-expander-title {\n font-weight: 600;\n color: #495057;\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}"] }); }
|
|
3731
3931
|
}
|
|
3732
3932
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AITestHarnessComponent, [{
|
|
3733
3933
|
type: Component,
|
|
3734
|
-
args: [{ selector: 'mj-ai-test-harness', template: "<div class=\"harness-container\" *ngIf=\"isVisible\" kendoWindowContainer>\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\n <!-- Main Content Area with Splitter -->\n <div class=\"harness-body\">\n @if (showSidebar) {\n <kendo-splitter \n orientation=\"horizontal\"\n style=\"height: 100%; width: 100%;\">\n \n <!-- Chat Area (Left Pane) -->\n <kendo-splitter-pane \n [collapsible]=\"false\"\n [resizable]=\"true\"\n [min]=\"'400px'\">\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\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\n <!-- Input Area -->\n <div class=\"input-area\">\n <div class=\"input-container\">\n <kendo-textarea\n #messageInput\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\"\n class=\"message-input\">\n </kendo-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 </kendo-splitter-pane>\n \n <!-- Sidebar (Right Pane) -->\n <kendo-splitter-pane \n [collapsible]=\"false\"\n [resizable]=\"true\"\n [size]=\"'30%'\"\n [min]=\"'300px'\">\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\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 \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 \n @for (variable of agentVariables; track $index) {\n <div class=\"variable-item\">\n <kendo-textbox \n [(ngModel)]=\"variable.name\" \n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\"\n class=\"variable-name\">\n </kendo-textbox>\n \n <kendo-dropdownlist \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 </kendo-dropdownlist>\n \n <kendo-textbox \n [(ngModel)]=\"variable.value\" \n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\"\n class=\"variable-value\">\n </kendo-textbox>\n \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 \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\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\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 \n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n <div class=\"setting-help\">\n @if (agentConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (config.ID === 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\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 \n <div class=\"variables-list\">\n @for (variable of templateVariables; track $index) {\n <div class=\"variable-item\">\n <kendo-textbox \n [(ngModel)]=\"variable.name\" \n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\"\n class=\"variable-name\">\n </kendo-textbox>\n \n <kendo-dropdownlist \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 </kendo-dropdownlist>\n \n <kendo-textbox \n [(ngModel)]=\"variable.value\" \n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\"\n class=\"variable-value\">\n </kendo-textbox>\n \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 \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\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 \n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Model</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n </div>\n \n <div class=\"setting-group\">\n <label>AI Vendor</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\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 \n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n <div class=\"setting-help\">\n @if (selectedConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (config.ID === selectedConfigurationId && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n \n <div class=\"setting-group\">\n <label>Response Format</label>\n <kendo-dropdownlist \n [(ngModel)]=\"selectedResponseFormat\"\n [data]=\"responseFormatOptions\"\n textField=\"text\"\n valueField=\"value\"\n placeholder=\"Select format...\"\n class=\"format-selector\">\n </kendo-dropdownlist>\n <div class=\"setting-help\">\n Expected format for AI response (defaults to prompt setting)\n </div>\n </div>\n \n <div class=\"setting-group\">\n <label>Max Tokens</label>\n <kendo-numerictextbox \n [(ngModel)]=\"maxTokens\"\n [min]=\"100\"\n [max]=\"8000\"\n [step]=\"100\"\n placeholder=\"Max tokens...\"\n class=\"max-tokens-input\">\n </kendo-numerictextbox>\n <div class=\"setting-help\">\n Maximum length of generated response\n </div>\n </div>\n \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 \n <!-- Advanced Parameters Expansion Panel -->\n <kendo-expansionpanel \n [expanded]=\"advancedParamsExpanded\"\n (action)=\"toggleAdvancedParams()\"\n title=\"Advanced Parameters\"\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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \n <div class=\"setting-group\">\n <label title=\"Minimum probability for token selection. Filters out low-probability tokens\">\n Min P\n </label>\n <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \n <div class=\"setting-group\">\n <label title=\"Random seed for deterministic generation. Same seed produces same output\">\n Seed\n </label>\n <kendo-numerictextbox \n [(ngModel)]=\"advancedParams.seed\"\n [format]=\"'n0'\"\n placeholder=\"None\"\n class=\"advanced-param-input\">\n </kendo-numerictextbox>\n </div>\n \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 <kendo-textarea \n [(ngModel)]=\"stopSequencesText\"\n (ngModelChange)=\"updateStopSequences()\"\n [rows]=\"2\"\n placeholder=\"Enter comma-separated sequences\"\n class=\"advanced-param-input\">\n </kendo-textarea>\n <div class=\"setting-help\">\n Separate multiple sequences with commas\n </div>\n </div>\n \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 <kendo-switch \n [(ngModel)]=\"advancedParams.includeLogProbs\"\n class=\"advanced-param-switch\">\n </kendo-switch>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n </div>\n </div>\n }\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 \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 \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 </kendo-splitter-pane>\n </kendo-splitter>\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\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\n <!-- Input Area -->\n <div class=\"input-area\">\n <div class=\"input-container\">\n <kendo-textarea\n #messageInput\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\"\n class=\"message-input\">\n </kendo-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 <!-- Save Conversation Dialog -->\n @if (showSaveDialog) {\n <kendo-dialog \n [title]=\"'Save Conversation'\" \n [width]=\"400\"\n (close)=\"cancelSaveDialog()\"\n class=\"save-dialog\">\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=\"k-textbox k-input k-input-md k-rounded-md k-input-solid full-width\" />\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"cancelSaveDialog()\">Cancel</button>\n <button kendoButton \n [primary]=\"true\" \n (click)=\"confirmSaveConversation()\"\n [disabled]=\"tempConversationName === ''\">\n Save\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n \n <!-- Load Confirmation Dialog -->\n @if (showLoadConfirmDialog) {\n <kendo-dialog \n [title]=\"'Replace Current Conversation?'\" \n [width]=\"400\"\n (close)=\"cancelLoadConversation()\"\n class=\"confirm-dialog\">\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 <kendo-dialog-actions>\n <button kendoButton (click)=\"cancelLoadConversation()\">Cancel</button>\n <button kendoButton \n [primary]=\"true\" \n (click)=\"confirmLoadConversation()\">\n Load Conversation\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n\n", styles: ["/* Container Styles */\n.harness-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n/* Custom Button Styles */\n.custom-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\n}\n\n.custom-button:active:not(:disabled) {\n background: #e9ecef;\n border-color: #adb5bd;\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: #0d6efd;\n border: 1px solid #0d6efd;\n color: white;\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: #0b5ed7;\n border-color: #0a58ca;\n}\n\n.send-button:active:not(:disabled) {\n background: #0a58ca;\n border-color: #0a58ca;\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: white;\n border: 1px solid #0d6efd;\n color: #0d6efd;\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: #0d6efd;\n color: white;\n}\n\n/* Remove/Delete Buttons */\n.remove-button,\n.delete-button {\n background: transparent;\n border: none;\n color: #dc3545;\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: rgba(220, 53, 69, 0.1);\n color: #bd2130;\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: #adb5bd;\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: #6c757d;\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: #495057;\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: #6c757d;\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: #495057;\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: white;\n border-bottom: 1px solid #dee2e6;\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: #17a2b8;\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: #212529;\n}\n\n.agent-details p {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: #6c757d;\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: white;\n border-right: 1px solid #dee2e6;\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: #6c757d;\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: #495057;\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: #6f42c1;\n}\n\n.message-assistant .message-role {\n color: #17a2b8;\n}\n\n.message-time {\n color: #6c757d;\n font-size: 12px;\n}\n\n.execution-time {\n background: #e9ecef;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: #495057;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming {\n background: #fff3cd;\n color: #856404;\n border: 1px solid #ffeaa7;\n}\n\n.raw-toggle {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: #6c757d;\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: #495057;\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: #e7f3ff;\n border: 1px solid #b8daff;\n}\n\n.message-assistant .message-content {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n}\n\n.message.streaming .message-content {\n background: #fff3cd;\n border: 1px solid #ffeaa7;\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: #495057;\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: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 6px;\n color: #721c24;\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details i {\n color: #dc3545;\n}\n\n/* Payload Section Styles */\n.payload-section {\n margin-top: 12px;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n overflow: hidden;\n background: #ffffff;\n}\n\n.payload-header {\n background: #f8f9fa;\n padding: 8px 12px;\n border-bottom: 1px solid #e9ecef;\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: #e9ecef;\n}\n\n.payload-label {\n font-size: 13px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label i {\n color: #6c757d;\n font-size: 12px;\n}\n\n.payload-content {\n max-height: 250px;\n overflow: auto;\n background: #f8f9fa;\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: #212529;\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: #6c757d;\n transition: color 0.2s;\n}\n\n.payload-toggle:hover {\n color: #495057;\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: #333;\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 #dee2e6;\n border-radius: 4px;\n \n &:focus {\n outline: none;\n border-color: #ff6358;\n box-shadow: 0 0 0 0.25rem rgba(255, 99, 88, 0.25);\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: #f8f9fa;\n border: 1px solid #e0e0e0;\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: #333;\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: #212529;\n border-bottom: 2px solid #e9ecef;\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: #212529;\n border-bottom: 1px solid #e9ecef;\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: #212529;\n}\n\n.code-block {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\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: #212529;\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: #d73e48;\n}\n\n.inline-code {\n background: #f1f3f4;\n border: 1px solid #dadce0;\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: #d73e48;\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: #0d6efd;\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link:hover {\n color: #0a58ca;\n text-decoration: none;\n}\n\n/* Ensure proper text wrapping in message content */\n.message-content {\n background: #f8f9fa;\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: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\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: white;\n border-top: 1px solid #dee2e6;\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.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: white;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* Kendo Splitter Specific Styles */\n.harness-body kendo-splitter {\n height: 100%;\n}\n\n.harness-body kendo-splitter-pane {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Sidebar Tabs */\n.sidebar-tabs {\n display: flex;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\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: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.tab-button.active {\n color: #0d6efd;\n border-bottom-color: #0d6efd;\n background: white;\n}\n\n.tab-button i {\n font-size: 14px;\n}\n\n.tab-button .badge {\n background: #6c757d;\n color: white;\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: #0d6efd;\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: #212529;\n}\n\n.tab-header p {\n margin: 0;\n font-size: 13px;\n color: #6c757d;\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: #6c757d;\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: #6c757d;\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 #dee2e6;\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: #f8f9fa;\n border-color: #adb5bd;\n}\n\n.saved-item.current {\n background: #e7f3ff;\n border-color: #0d6efd;\n}\n\n.saved-info h5 {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: #212529;\n}\n\n.saved-info p {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: #6c757d;\n}\n\n.saved-date {\n font-size: 11px;\n color: #6c757d;\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: #f1f1f1;\n}\n\n.messages-container::-webkit-scrollbar-thumb,\n.sidebar-content::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 4px;\n}\n\n.messages-container::-webkit-scrollbar-thumb:hover,\n.sidebar-content::-webkit-scrollbar-thumb:hover {\n background: #a1a1a1;\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: #343a40;\n color: white;\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: white;\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 #dee2e6;\n border-radius: 4px;\n}\n\n.advanced-params-panel ::ng-deep .k-expander-title {\n font-weight: 600;\n color: #495057;\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}"] }]
|
|
3934
|
+
args: [{ selector: 'mj-ai-test-harness', template: "<div class=\"harness-container\" *ngIf=\"isVisible\" kendoWindowContainer>\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\n <!-- Main Content Area with Splitter -->\n <div class=\"harness-body\">\n @if (showSidebar) {\n <kendo-splitter \n orientation=\"horizontal\"\n style=\"height: 100%; width: 100%;\">\n \n <!-- Chat Area (Left Pane) -->\n <kendo-splitter-pane \n [collapsible]=\"false\"\n [resizable]=\"true\"\n [min]=\"'400px'\">\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\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\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 <kendo-textarea\n #messageInput\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\"\n class=\"message-input\">\n </kendo-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 </kendo-splitter-pane>\n \n <!-- Sidebar (Right Pane) -->\n <kendo-splitter-pane \n [collapsible]=\"false\"\n [resizable]=\"true\"\n [size]=\"'30%'\"\n [min]=\"'300px'\">\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\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 \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 \n @for (variable of agentVariables; track $index) {\n <div class=\"variable-item\">\n <kendo-textbox \n [(ngModel)]=\"variable.name\" \n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\"\n class=\"variable-name\">\n </kendo-textbox>\n \n <kendo-dropdownlist \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 </kendo-dropdownlist>\n \n <kendo-textbox \n [(ngModel)]=\"variable.value\" \n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\"\n class=\"variable-value\">\n </kendo-textbox>\n \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 \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\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\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 \n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n <div class=\"setting-help\">\n @if (agentConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (config.ID === 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\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 \n <div class=\"variables-list\">\n @for (variable of templateVariables; track $index) {\n <div class=\"variable-item\">\n <kendo-textbox \n [(ngModel)]=\"variable.name\" \n placeholder=\"Variable name\"\n [disabled]=\"isExecuting\"\n class=\"variable-name\">\n </kendo-textbox>\n \n <kendo-dropdownlist \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 </kendo-dropdownlist>\n \n <kendo-textbox \n [(ngModel)]=\"variable.value\" \n [placeholder]=\"variable.type === 'object' ? 'JSON value' : 'Value'\"\n [disabled]=\"isExecuting\"\n class=\"variable-value\">\n </kendo-textbox>\n \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 \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\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 \n <div class=\"model-settings\">\n <div class=\"setting-group\">\n <label>AI Model</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n </div>\n \n <div class=\"setting-group\">\n <label>AI Vendor</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\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 \n <div class=\"setting-group\">\n <label>AI Configuration</label>\n <kendo-dropdownlist \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 </kendo-dropdownlist>\n <div class=\"setting-help\">\n @if (selectedConfigurationId) {\n @for (config of availableConfigurations; track config.ID) {\n @if (config.ID === selectedConfigurationId && config.Description) {\n {{ config.Description }}\n }\n }\n } @else {\n Using default configuration\n }\n </div>\n </div>\n \n <div class=\"setting-group\">\n <label>Response Format</label>\n <kendo-dropdownlist \n [(ngModel)]=\"selectedResponseFormat\"\n [data]=\"responseFormatOptions\"\n textField=\"text\"\n valueField=\"value\"\n placeholder=\"Select format...\"\n class=\"format-selector\">\n </kendo-dropdownlist>\n <div class=\"setting-help\">\n Expected format for AI response (defaults to prompt setting)\n </div>\n </div>\n \n <div class=\"setting-group\">\n <label>Max Tokens</label>\n <kendo-numerictextbox \n [(ngModel)]=\"maxTokens\"\n [min]=\"100\"\n [max]=\"8000\"\n [step]=\"100\"\n placeholder=\"Max tokens...\"\n class=\"max-tokens-input\">\n </kendo-numerictextbox>\n <div class=\"setting-help\">\n Maximum length of generated response\n </div>\n </div>\n \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 \n <!-- Advanced Parameters Expansion Panel -->\n <kendo-expansionpanel \n [expanded]=\"advancedParamsExpanded\"\n (action)=\"toggleAdvancedParams()\"\n title=\"Advanced Parameters\"\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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \n <div class=\"setting-group\">\n <label title=\"Minimum probability for token selection. Filters out low-probability tokens\">\n Min P\n </label>\n <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n \n <div class=\"setting-group\">\n <label title=\"Random seed for deterministic generation. Same seed produces same output\">\n Seed\n </label>\n <kendo-numerictextbox \n [(ngModel)]=\"advancedParams.seed\"\n [format]=\"'n0'\"\n placeholder=\"None\"\n class=\"advanced-param-input\">\n </kendo-numerictextbox>\n </div>\n \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 <kendo-textarea \n [(ngModel)]=\"stopSequencesText\"\n (ngModelChange)=\"updateStopSequences()\"\n [rows]=\"2\"\n placeholder=\"Enter comma-separated sequences\"\n class=\"advanced-param-input\">\n </kendo-textarea>\n <div class=\"setting-help\">\n Separate multiple sequences with commas\n </div>\n </div>\n \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 <kendo-switch \n [(ngModel)]=\"advancedParams.includeLogProbs\"\n class=\"advanced-param-switch\">\n </kendo-switch>\n </div>\n \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 <kendo-numerictextbox \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 </kendo-numerictextbox>\n </div>\n }\n </div>\n </kendo-expansionpanel>\n </div>\n </div>\n }\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 \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 \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 </kendo-splitter-pane>\n </kendo-splitter>\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\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\n <!-- Input Area -->\n <div class=\"input-area\">\n <div class=\"input-container\">\n <kendo-textarea\n #messageInput\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\"\n class=\"message-input\">\n </kendo-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 <!-- Save Conversation Dialog -->\n @if (showSaveDialog) {\n <kendo-dialog \n [title]=\"'Save Conversation'\" \n [width]=\"400\"\n (close)=\"cancelSaveDialog()\"\n class=\"save-dialog\">\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=\"k-textbox k-input k-input-md k-rounded-md k-input-solid full-width\" />\n </div>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"cancelSaveDialog()\">Cancel</button>\n <button kendoButton \n [primary]=\"true\" \n (click)=\"confirmSaveConversation()\"\n [disabled]=\"tempConversationName === ''\">\n Save\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n \n <!-- Load Confirmation Dialog -->\n @if (showLoadConfirmDialog) {\n <kendo-dialog \n [title]=\"'Replace Current Conversation?'\" \n [width]=\"400\"\n (close)=\"cancelLoadConversation()\"\n class=\"confirm-dialog\">\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 <kendo-dialog-actions>\n <button kendoButton (click)=\"cancelLoadConversation()\">Cancel</button>\n <button kendoButton \n [primary]=\"true\" \n (click)=\"confirmLoadConversation()\">\n Load Conversation\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n\n", styles: ["/* Container Styles */\n.harness-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n/* Custom Button Styles */\n.custom-button {\n background: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 13px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\n}\n\n.custom-button:active:not(:disabled) {\n background: #e9ecef;\n border-color: #adb5bd;\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: #0d6efd;\n border: 1px solid #0d6efd;\n color: white;\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: #0b5ed7;\n border-color: #0a58ca;\n}\n\n.send-button:active:not(:disabled) {\n background: #0a58ca;\n border-color: #0a58ca;\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: white;\n border: 1px solid #0d6efd;\n color: #0d6efd;\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: #0d6efd;\n color: white;\n}\n\n/* Remove/Delete Buttons */\n.remove-button,\n.delete-button {\n background: transparent;\n border: none;\n color: #dc3545;\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: rgba(220, 53, 69, 0.1);\n color: #bd2130;\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: #adb5bd;\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: #6c757d;\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: #495057;\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: #6c757d;\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: #495057;\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: white;\n border-bottom: 1px solid #dee2e6;\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: #17a2b8;\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: #212529;\n}\n\n.agent-details p {\n margin: 4px 0 0 0;\n font-size: 14px;\n color: #6c757d;\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: white;\n border-right: 1px solid #dee2e6;\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: #6c757d;\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: #495057;\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: #6f42c1;\n}\n\n.message-assistant .message-role {\n color: #17a2b8;\n}\n\n.message-time {\n color: #6c757d;\n font-size: 12px;\n}\n\n.execution-time {\n background: #e9ecef;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n color: #495057;\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.execution-time.streaming {\n background: #fff3cd;\n color: #856404;\n border: 1px solid #ffeaa7;\n}\n\n.raw-toggle {\n background: transparent;\n border: none;\n padding: 4px 8px;\n font-size: 12px;\n color: #6c757d;\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: #495057;\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: #e7f3ff;\n border: 1px solid #b8daff;\n}\n\n.message-assistant .message-content {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n}\n\n.message.streaming .message-content {\n background: #fff3cd;\n border: 1px solid #ffeaa7;\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: #495057;\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: #f8d7da;\n border: 1px solid #f5c6cb;\n border-radius: 6px;\n color: #721c24;\n font-size: 13px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.error-details i {\n color: #dc3545;\n}\n\n/* Payload Section Styles */\n.payload-section {\n margin-top: 12px;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n overflow: hidden;\n background: #ffffff;\n}\n\n.payload-header {\n background: #f8f9fa;\n padding: 8px 12px;\n border-bottom: 1px solid #e9ecef;\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: #e9ecef;\n}\n\n.payload-label {\n font-size: 13px;\n font-weight: 600;\n color: #495057;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.payload-label i {\n color: #6c757d;\n font-size: 12px;\n}\n\n.payload-content {\n max-height: 250px;\n overflow: auto;\n background: #f8f9fa;\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: #212529;\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: #6c757d;\n transition: color 0.2s;\n}\n\n.payload-toggle:hover {\n color: #495057;\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: #333;\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 #dee2e6;\n border-radius: 4px;\n \n &:focus {\n outline: none;\n border-color: #ff6358;\n box-shadow: 0 0 0 0.25rem rgba(255, 99, 88, 0.25);\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: #f8f9fa;\n border: 1px solid #e0e0e0;\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: #333;\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: #212529;\n border-bottom: 2px solid #e9ecef;\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: #212529;\n border-bottom: 1px solid #e9ecef;\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: #212529;\n}\n\n.code-block {\n background: #f8f9fa;\n border: 1px solid #e9ecef;\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: #212529;\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: #d73e48;\n}\n\n.inline-code {\n background: #f1f3f4;\n border: 1px solid #dadce0;\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: #d73e48;\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: #0d6efd;\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.markdown-link:hover {\n color: #0a58ca;\n text-decoration: none;\n}\n\n/* Ensure proper text wrapping in message content */\n.message-content {\n background: #f8f9fa;\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: white;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n padding: 6px 12px;\n font-size: 12px;\n color: #495057;\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: #f8f9fa;\n border-color: #adb5bd;\n color: #212529;\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: white;\n border-top: 1px solid #dee2e6;\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: #f0f9ff;\n border-radius: 8px;\n gap: 16px;\n}\n\n.rerun-message {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #0369a1;\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: #6b7280;\n}\n\n.reset-button:hover:not(:disabled) {\n background-color: #4b5563;\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: white;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* Kendo Splitter Specific Styles */\n.harness-body kendo-splitter {\n height: 100%;\n}\n\n.harness-body kendo-splitter-pane {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Sidebar Tabs */\n.sidebar-tabs {\n display: flex;\n background: #f8f9fa;\n border-bottom: 1px solid #dee2e6;\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: #6c757d;\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: #e9ecef;\n color: #495057;\n}\n\n.tab-button.active {\n color: #0d6efd;\n border-bottom-color: #0d6efd;\n background: white;\n}\n\n.tab-button i {\n font-size: 14px;\n}\n\n.tab-button .badge {\n background: #6c757d;\n color: white;\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: #0d6efd;\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: #212529;\n}\n\n.tab-header p {\n margin: 0;\n font-size: 13px;\n color: #6c757d;\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: #6c757d;\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: #6c757d;\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 #dee2e6;\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: #f8f9fa;\n border-color: #adb5bd;\n}\n\n.saved-item.current {\n background: #e7f3ff;\n border-color: #0d6efd;\n}\n\n.saved-info h5 {\n margin: 0 0 4px 0;\n font-size: 14px;\n font-weight: 600;\n color: #212529;\n}\n\n.saved-info p {\n margin: 0 0 4px 0;\n font-size: 12px;\n color: #6c757d;\n}\n\n.saved-date {\n font-size: 11px;\n color: #6c757d;\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: #f1f1f1;\n}\n\n.messages-container::-webkit-scrollbar-thumb,\n.sidebar-content::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 4px;\n}\n\n.messages-container::-webkit-scrollbar-thumb:hover,\n.sidebar-content::-webkit-scrollbar-thumb:hover {\n background: #a1a1a1;\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: #343a40;\n color: white;\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: white;\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 #dee2e6;\n border-radius: 4px;\n}\n\n.advanced-params-panel ::ng-deep .k-expander-title {\n font-weight: 600;\n color: #495057;\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}"] }]
|
|
3735
3935
|
}], () => [{ type: i1.DomSanitizer }, { type: i2.WindowService }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i3.Router }], { mode: [{
|
|
3736
3936
|
type: Input
|
|
3737
3937
|
}], entity: [{
|
|
3738
3938
|
type: Input
|
|
3939
|
+
}], originalPromptRunId: [{
|
|
3940
|
+
type: Input
|
|
3941
|
+
}], systemPromptOverride: [{
|
|
3942
|
+
type: Input
|
|
3739
3943
|
}], aiAgent: [{
|
|
3740
3944
|
type: Input
|
|
3741
3945
|
}], isVisible: [{
|