llm-testrunner-components 1.2.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +9 -5
  2. package/dist/cjs/{app-chips_5.cjs.entry.js → app-chips_4.cjs.entry.js} +20 -22
  3. package/dist/cjs/app-chips_4.cjs.entry.js.map +1 -0
  4. package/dist/cjs/index.cjs.js +464 -66
  5. package/dist/cjs/index.cjs.js.map +1 -1
  6. package/dist/cjs/llm-test-runner.cjs.entry.js +11 -0
  7. package/dist/cjs/llm-test-runner.cjs.entry.js.map +1 -0
  8. package/dist/cjs/llm-testrunner.cjs.js +1 -1
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/collection/components/llm-test-runner/llm-test-runner.js +46 -13
  11. package/dist/collection/components/llm-test-runner/llm-test-runner.js.map +1 -1
  12. package/dist/collection/components/llm-test-runner/test-cases/chat-history.css +5 -5
  13. package/dist/collection/components/llm-test-runner/test-cases/expected-outcome-renderer.js +45 -5
  14. package/dist/collection/components/llm-test-runner/test-cases/expected-outcome-renderer.js.map +1 -1
  15. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.css +21 -0
  16. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js +2 -2
  17. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js.map +1 -1
  18. package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js +2 -2
  19. package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js.map +1 -1
  20. package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js +1 -1
  21. package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js.map +1 -1
  22. package/dist/collection/demo/demo-modes.js +130 -0
  23. package/dist/collection/demo/vanilla-demo.js +56 -0
  24. package/dist/collection/lib/evaluation/actual-value-resolver.js +52 -0
  25. package/dist/collection/lib/evaluation/actual-value-resolver.js.map +1 -0
  26. package/dist/collection/lib/evaluation/evaluation-engine.js +1 -1
  27. package/dist/collection/lib/evaluation/evaluation-engine.js.map +1 -1
  28. package/dist/collection/lib/evaluation/evaluation-service.js +55 -17
  29. package/dist/collection/lib/evaluation/evaluation-service.js.map +1 -1
  30. package/dist/collection/lib/evaluation/types.js.map +1 -1
  31. package/dist/collection/lib/form/components/app-textarea.css +2 -2
  32. package/dist/collection/lib/import-export/test-suite-importer.js +7 -1
  33. package/dist/collection/lib/import-export/test-suite-importer.js.map +1 -1
  34. package/dist/collection/lib/test-cases/test-case-factory.js +5 -0
  35. package/dist/collection/lib/test-cases/test-case-factory.js.map +1 -1
  36. package/dist/collection/lib/test-cases/test-case-mutations.js +58 -23
  37. package/dist/collection/lib/test-cases/test-case-mutations.js.map +1 -1
  38. package/dist/collection/schemas/expected-outcome.js +39 -0
  39. package/dist/collection/schemas/expected-outcome.js.map +1 -1
  40. package/dist/collection/schemas/model-response.js +7 -0
  41. package/dist/collection/schemas/model-response.js.map +1 -0
  42. package/dist/collection/schemas/test-case.js +2 -1
  43. package/dist/collection/schemas/test-case.js.map +1 -1
  44. package/dist/collection/types/expected-outcome.js.map +1 -1
  45. package/dist/collection/types/llm-test-runner.js.map +1 -1
  46. package/dist/components/app-textarea.js +1 -1
  47. package/dist/components/chat-history.js +1 -1
  48. package/dist/components/index.js +1 -1
  49. package/dist/components/llm-test-runner.js +1 -1
  50. package/dist/components/{p-B87Lt3z4.js → p-D3eincg_.js} +3 -3
  51. package/dist/components/p-D3eincg_.js.map +1 -0
  52. package/dist/components/{p-D2qDAxFN.js → p-D6BL2E3J.js} +2 -2
  53. package/dist/components/{p-D2qDAxFN.js.map → p-D6BL2E3J.js.map} +1 -1
  54. package/dist/components/p-kmtfMXcQ.js +2 -0
  55. package/dist/components/p-kmtfMXcQ.js.map +1 -0
  56. package/dist/esm/{app-chips_5.entry.js → app-chips_4.entry.js} +4 -5
  57. package/dist/esm/app-chips_4.entry.js.map +1 -0
  58. package/dist/esm/index.js +464 -66
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/llm-test-runner.entry.js +5 -0
  61. package/dist/esm/llm-test-runner.entry.js.map +1 -0
  62. package/dist/esm/llm-testrunner.js +1 -1
  63. package/dist/esm/loader.js +1 -1
  64. package/dist/llm-testrunner/index.esm.js +2 -2
  65. package/dist/llm-testrunner/index.esm.js.map +1 -1
  66. package/dist/llm-testrunner/llm-testrunner.esm.js +1 -1
  67. package/dist/llm-testrunner/p-c3fec0bb.entry.js +2 -0
  68. package/dist/llm-testrunner/{p-21202f12.entry.js.map → p-c3fec0bb.entry.js.map} +1 -1
  69. package/dist/llm-testrunner/p-caccdb4b.entry.js +2 -0
  70. package/dist/llm-testrunner/p-caccdb4b.entry.js.map +1 -0
  71. package/dist/types/components/llm-test-runner/llm-test-runner.d.ts +3 -4
  72. package/dist/types/components/llm-test-runner/test-cases/expected-outcome-renderer.d.ts +1 -0
  73. package/dist/types/components/llm-test-runner/test-cases/llm-test-case-row.d.ts +1 -0
  74. package/dist/types/components/llm-test-runner/test-cases/llm-test-cases.d.ts +1 -0
  75. package/dist/types/components/llm-test-runner/test-cases/output/response-output.d.ts +2 -1
  76. package/dist/types/components.d.ts +4 -2
  77. package/dist/types/lib/evaluation/actual-value-resolver.d.ts +9 -0
  78. package/dist/types/lib/evaluation/evaluation-service.d.ts +2 -2
  79. package/dist/types/lib/evaluation/types.d.ts +1 -1
  80. package/dist/types/lib/import-export/test-suite-importer.d.ts +1 -1
  81. package/dist/types/lib/test-cases/test-case-mutations.d.ts +10 -1
  82. package/dist/types/schemas/expected-outcome.d.ts +116 -0
  83. package/dist/types/schemas/model-response.d.ts +7 -0
  84. package/dist/types/schemas/test-case.d.ts +76 -1
  85. package/dist/types/types/expected-outcome.d.ts +1 -1
  86. package/dist/types/types/llm-test-runner.d.ts +4 -2
  87. package/package.json +1 -1
  88. package/dist/cjs/app-chips_5.cjs.entry.js.map +0 -1
  89. package/dist/components/p-B87Lt3z4.js.map +0 -1
  90. package/dist/components/p-Bx2jqguC.js +0 -2
  91. package/dist/components/p-Bx2jqguC.js.map +0 -1
  92. package/dist/esm/app-chips_5.entry.js.map +0 -1
  93. package/dist/llm-testrunner/p-21202f12.entry.js +0 -2
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index.cjs.js');
4
+ require('./index-CgmLNwZO.js');
5
+
6
+
7
+
8
+ exports.llm_test_runner = index.LLMTestRunner;
9
+ //# sourceMappingURL=llm-test-runner.entry.cjs.js.map
10
+
11
+ //# sourceMappingURL=llm-test-runner.cjs.entry.js.map
@@ -0,0 +1 @@
1
+ {"file":"llm-test-runner.cjs.entry.js","mappings":";;;;;;;","names":[],"sources":[],"sourcesContent":[],"version":3}
@@ -19,7 +19,7 @@ var patchBrowser = () => {
19
19
 
20
20
  patchBrowser().then(async (options) => {
21
21
  await appGlobals.globalScripts();
22
- return index.bootstrapLazy([["app-chips_5.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"usePromptEditor":[4,"use-prompt-editor"],"resolveExpectedOutcome":[16],"initialTestCases":[16],"defaultExpectedOutcomeSchema":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64],"getTestCases":[64]}],[513,"app-chips",{"value":[16],"config":[16]}],[513,"app-select",{"value":[1],"config":[16]}],[513,"app-textarea",{"value":[1],"config":[16]}],[513,"chat-history",{"chatHistoryEnabled":[4,"chat-history-enabled"],"chatHistoryValue":[1,"chat-history-value"]}]]]], options);
22
+ return index.bootstrapLazy([["app-chips_4.cjs",[[513,"app-chips",{"value":[16],"config":[16]}],[513,"app-select",{"value":[1],"config":[16]}],[513,"app-textarea",{"value":[1],"config":[16]}],[513,"chat-history",{"chatHistoryEnabled":[4,"chat-history-enabled"],"chatHistoryValue":[1,"chat-history-value"]}]]],["llm-test-runner.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"usePromptEditor":[4,"use-prompt-editor"],"resolveExpectedOutcome":[16],"evaluationSourceExtractors":[16],"initialTestCases":[16],"defaultExpectedOutcomeSchema":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64],"getTestCases":[64]}]]]], options);
23
23
  });
24
24
 
25
25
  exports.setNonce = index.setNonce;
@@ -6,7 +6,7 @@ var appGlobals = require('./app-globals-Chb-oJtg.js');
6
6
  const defineCustomElements = async (win, options) => {
7
7
  if (typeof window === 'undefined') return undefined;
8
8
  await appGlobals.globalScripts();
9
- return index.bootstrapLazy([["app-chips_5.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"usePromptEditor":[4,"use-prompt-editor"],"resolveExpectedOutcome":[16],"initialTestCases":[16],"defaultExpectedOutcomeSchema":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64],"getTestCases":[64]}],[513,"app-chips",{"value":[16],"config":[16]}],[513,"app-select",{"value":[1],"config":[16]}],[513,"app-textarea",{"value":[1],"config":[16]}],[513,"chat-history",{"chatHistoryEnabled":[4,"chat-history-enabled"],"chatHistoryValue":[1,"chat-history-value"]}]]]], options);
9
+ return index.bootstrapLazy([["app-chips_4.cjs",[[513,"app-chips",{"value":[16],"config":[16]}],[513,"app-select",{"value":[1],"config":[16]}],[513,"app-textarea",{"value":[1],"config":[16]}],[513,"chat-history",{"chatHistoryEnabled":[4,"chat-history-enabled"],"chatHistoryValue":[1,"chat-history-value"]}]]],["llm-test-runner.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"usePromptEditor":[4,"use-prompt-editor"],"resolveExpectedOutcome":[16],"evaluationSourceExtractors":[16],"initialTestCases":[16],"defaultExpectedOutcomeSchema":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64],"getTestCases":[64]}]]]], options);
10
10
  };
11
11
 
12
12
  exports.setNonce = index.setNonce;
@@ -11,7 +11,7 @@ import { resolveDynamicExpectedOutcomes, } from "../../lib/test-cases/dynamic-ex
11
11
  import * as TestCaseMutations from "../../lib/test-cases/test-case-mutations";
12
12
  import { EvaluationService } from "../../lib/evaluation/evaluation-service";
13
13
  import { validateTestCaseInputArray } from "../../schemas/test-case";
14
- import { validateExpectedOutcomeSchema } from "../../schemas/expected-outcome";
14
+ import { getExtractorIds, validateExpectedOutcomeArrayWithExtractors, validateExpectedOutcomeSchema, } from "../../schemas/expected-outcome";
15
15
  import { LLMTestRunnerHeader } from "./header/llm-test-runner-header";
16
16
  import { LLMTestCases } from "./test-cases/llm-test-cases";
17
17
  export class LLMTestRunner {
@@ -21,6 +21,7 @@ export class LLMTestRunner {
21
21
  useSave = false;
22
22
  usePromptEditor = false;
23
23
  resolveExpectedOutcome;
24
+ evaluationSourceExtractors;
24
25
  initialTestCases;
25
26
  defaultExpectedOutcomeSchema;
26
27
  testCases = [
@@ -57,6 +58,12 @@ export class LLMTestRunner {
57
58
  // Initialize testCases from prop if provided
58
59
  if (this.initialTestCases !== undefined) {
59
60
  validateTestCaseInputArray(this.initialTestCases);
61
+ const extractorIds = getExtractorIds(this.evaluationSourceExtractors);
62
+ if (extractorIds.length > 0) {
63
+ this.initialTestCases.forEach(testCase => {
64
+ validateExpectedOutcomeArrayWithExtractors(testCase.expectedOutcome, extractorIds);
65
+ });
66
+ }
60
67
  this.testCases = this.initialTestCases.map((rawTestCase, index) => {
61
68
  try {
62
69
  return createTestCaseFromInput(rawTestCase);
@@ -80,8 +87,6 @@ export class LLMTestRunner {
80
87
  this.testCases = [];
81
88
  }
82
89
  }
83
- componentDidLoad() { }
84
- disconnectedCallback() { }
85
90
  async resetSavingState() {
86
91
  this.isSaving = false;
87
92
  }
@@ -114,7 +119,7 @@ export class LLMTestRunner {
114
119
  updateTestCase(id, updates) {
115
120
  this.testCases = this.testCases.map(tc => tc.id === id ? { ...tc, ...updates } : tc);
116
121
  }
117
- requestLlmText(testCase) {
122
+ requestLlmResponse(testCase) {
118
123
  return new Promise((resolve, reject) => {
119
124
  const payload = {
120
125
  prompt: testCase.question,
@@ -137,14 +142,14 @@ export class LLMTestRunner {
137
142
  const startTime = Date.now();
138
143
  this.updateTestCase(testCase.id, { isRunning: true });
139
144
  const [llmSettled, resolutionSettled] = await Promise.allSettled([
140
- this.requestLlmText(testCase),
145
+ this.requestLlmResponse(testCase),
141
146
  resolveDynamicExpectedOutcomes(testCase, this.resolveExpectedOutcome),
142
147
  ]);
143
148
  const responseTime = Date.now() - startTime;
144
149
  if (llmSettled.status === 'rejected') {
145
150
  this.updateTestCase(testCase.id, {
146
151
  isRunning: false,
147
- output: null,
152
+ output: undefined,
148
153
  error: this.addErrorMessage(llmSettled.reason, 'Unknown error'),
149
154
  responseTime,
150
155
  });
@@ -192,7 +197,7 @@ export class LLMTestRunner {
192
197
  this.updateTestCase(testCase.id, {
193
198
  evaluationResult: result,
194
199
  });
195
- });
200
+ }, this.evaluationSourceExtractors);
196
201
  }
197
202
  async runAllTests() {
198
203
  this.isRunningAll = true;
@@ -223,7 +228,7 @@ export class LLMTestRunner {
223
228
  this.error = '';
224
229
  try {
225
230
  const content = await readFileAsync(file);
226
- const result = importTestSuite(content);
231
+ const result = importTestSuite(content, getExtractorIds(this.evaluationSourceExtractors));
227
232
  if (!result.success) {
228
233
  this.error = result.error || 'Unknown error occurred during import.';
229
234
  return;
@@ -284,7 +289,7 @@ export class LLMTestRunner {
284
289
  }
285
290
  }
286
291
  render() {
287
- return (h("div", { key: 'cc808096f929b2e1c570c53144aab195d177c187', class: "test-runner-container" }, h(LLMTestRunnerHeader, { key: 'b91cf3df7df0e95bfd4908a2f91c7310b5b7a09a', isExportingTestSuite: this.isExportingTestSuite, isExportingTestResults: this.isExportingTestResults, isRunningAll: this.isRunningAll, useSave: this.useSave, isSaving: this.isSaving, usePromptEditor: this.usePromptEditor, onImport: file => this.handleImport(file), onExportSuite: () => this.handleExportTestSuite(), onExportResults: () => this.handleExportTestResults(), onRunAll: () => this.runAllTests(), onSave: () => this.handleSave() }), h(ErrorMessage, { key: 'c7991497173fa9843e7aa42f5283d0897ddff2e2', message: this.error, onClear: () => (this.error = '') }), h("div", { key: '2b57132564442b8047d8672c6adcba62cdc9ae87', class: "test-runner-container__content" }, h(LLMTestCases, { key: '146e9d8c76a34980a2a274dd856887c22e1ed0e9', testCases: this.testCases, dynamicResolutionSupported: !!this.resolveExpectedOutcome, onRun: testCase => this.runSingleTest(testCase).catch(() => { }), onDelete: id => this.deleteTestCase(id), onAddTestCase: () => this.addNewTestCase(), handleTestCaseChange: this.handleTestCaseChange, onExpectedOutcomeChange: this.handleExpectedOutcomeChange, onChatHistoryChange: this.handleChatHistoryChange }))));
292
+ return (h("div", { key: '7433beaa1d60d48f65600c43e11b302b892a7bca', class: "test-runner-container" }, h(LLMTestRunnerHeader, { key: '8083cc39376e7a710bd3f52efb184b959e885a87', isExportingTestSuite: this.isExportingTestSuite, isExportingTestResults: this.isExportingTestResults, isRunningAll: this.isRunningAll, useSave: this.useSave, isSaving: this.isSaving, usePromptEditor: this.usePromptEditor, onImport: file => this.handleImport(file), onExportSuite: () => this.handleExportTestSuite(), onExportResults: () => this.handleExportTestResults(), onRunAll: () => this.runAllTests(), onSave: () => this.handleSave() }), h(ErrorMessage, { key: 'ddced98c13cd595c4cfb6eef11b27cb173769518', message: this.error, onClear: () => (this.error = '') }), h("div", { key: '8d6f65c4d68d34869b644709eacb97fec93683c6', class: "test-runner-container__content" }, h(LLMTestCases, { key: '5ccb186132b23af6209209b0a14086e03cf790af', testCases: this.testCases, dynamicResolutionSupported: !!this.resolveExpectedOutcome, extractorIds: getExtractorIds(this.evaluationSourceExtractors), onRun: testCase => this.runSingleTest(testCase).catch(() => { }), onDelete: id => this.deleteTestCase(id), onAddTestCase: () => this.addNewTestCase(), handleTestCaseChange: this.handleTestCaseChange, onExpectedOutcomeChange: this.handleExpectedOutcomeChange, onChatHistoryChange: this.handleChatHistoryChange }))));
288
293
  }
289
294
  static get is() { return "llm-test-runner"; }
290
295
  static get encapsulation() { return "shadow"; }
@@ -365,7 +370,7 @@ export class LLMTestRunner {
365
370
  "mutable": false,
366
371
  "complexType": {
367
372
  "original": "ExpectedOutcomeResolver",
368
- "resolved": "(resolutionQuery: string, context: { testCase: { id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: string; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }; fieldIndex: number; }) => Promise<string>",
373
+ "resolved": "(resolutionQuery: string, context: { testCase: { id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: { text?: string; metadata?: Record<string, unknown>; }; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }; fieldIndex: number; }) => Promise<string>",
369
374
  "references": {
370
375
  "ExpectedOutcomeResolver": {
371
376
  "location": "import",
@@ -384,12 +389,36 @@ export class LLMTestRunner {
384
389
  "getter": false,
385
390
  "setter": false
386
391
  },
392
+ "evaluationSourceExtractors": {
393
+ "type": "unknown",
394
+ "mutable": false,
395
+ "complexType": {
396
+ "original": "EvaluationSourceExtractors",
397
+ "resolved": "((payload: { text?: string; metadata?: Record<string, unknown>; }) => string | Promise<string>) | string",
398
+ "references": {
399
+ "EvaluationSourceExtractors": {
400
+ "location": "import",
401
+ "path": "../../types/llm-test-runner",
402
+ "id": "src/types/llm-test-runner.ts::EvaluationSourceExtractors",
403
+ "referenceLocation": "EvaluationSourceExtractors"
404
+ }
405
+ }
406
+ },
407
+ "required": false,
408
+ "optional": true,
409
+ "docs": {
410
+ "tags": [],
411
+ "text": ""
412
+ },
413
+ "getter": false,
414
+ "setter": false
415
+ },
387
416
  "initialTestCases": {
388
417
  "type": "unknown",
389
418
  "mutable": false,
390
419
  "complexType": {
391
420
  "original": "TestCase[]",
392
- "resolved": "{ id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: string; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }[]",
421
+ "resolved": "{ id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: { text?: string; metadata?: Record<string, unknown>; }; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }[]",
393
422
  "references": {
394
423
  "TestCase": {
395
424
  "location": "import",
@@ -413,7 +442,7 @@ export class LLMTestRunner {
413
442
  "mutable": false,
414
443
  "complexType": {
415
444
  "original": "ExpectedOutcomeSchema",
416
- "resolved": "({ label: string; type: \"text\"; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; placeholder?: string; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"chips-input\"; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]",
445
+ "resolved": "({ label: string; type: \"text\"; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"chips-input\"; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]",
417
446
  "references": {
418
447
  "ExpectedOutcomeSchema": {
419
448
  "location": "import",
@@ -519,6 +548,10 @@ export class LLMTestRunner {
519
548
  "location": "global",
520
549
  "id": "global::Promise"
521
550
  },
551
+ "Record": {
552
+ "location": "global",
553
+ "id": "global::Record"
554
+ },
522
555
  "EvaluationResult": {
523
556
  "location": "import",
524
557
  "path": "../../lib/evaluation/types",
@@ -532,7 +565,7 @@ export class LLMTestRunner {
532
565
  "referenceLocation": "TestCase"
533
566
  }
534
567
  },
535
- "return": "Promise<{ id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: string; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }[]>"
568
+ "return": "Promise<{ id: string; question: string; expectedOutcome: ({ label: string; type: \"text\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"textarea\"; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; rows?: number; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; outcomeMode?: \"static\" | \"dynamic\"; resolutionQuery?: string; } | { label: string; type: \"chips-input\"; value: string[]; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; } | { label: string; type: \"select\"; options: string[]; value: string; placeholder?: string; evaluationSource?: { type: \"text\"; } | { type: \"custom\"; extractorId: string; }; evaluationParameters?: { approach: EvaluationApproach; threshold?: number; }; })[]; chatHistory: { enabled: boolean; value: string; }; output?: { text?: string; metadata?: Record<string, unknown>; }; isRunning?: boolean; error?: string; evaluationResult?: EvaluationResult; responseTime?: number; }[]>"
536
569
  },
537
570
  "docs": {
538
571
  "text": "",
@@ -1 +1 @@
1
- {"version":3,"file":"llm-test-runner.js","sourceRoot":"","sources":["../../../src/components/llm-test-runner/llm-test-runner.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n State,\n Prop,\n h,\n EventEmitter,\n Event,\n Method,\n} from '@stencil/core';\nimport { EvaluationResult } from '../../lib/evaluation/types';\nimport { ErrorMessage } from '../error-message/error-message';\nimport { RateLimitedFetcher } from '../../lib/rate-limited-fetcher/rate-limited-fetcher';\nimport {\n ExpectedOutcomeSchema,\n TestCase,\n LLMRequestPayload,\n SavePayload,\n} from '../../types/llm-test-runner';\nimport { readFileAsync } from '../../lib/file/file-reader';\nimport { downloadFile } from '../../lib/file/file-download';\nimport { formatTestSuiteAsJson } from '../../lib/import-export/test-suite-exporter';\nimport { exportTestResultsToCsv } from '../../lib/import-export/test-results-csv';\nimport { importTestSuite } from '../../lib/import-export/test-suite-importer';\nimport {\n createTestCase,\n createTestCaseFromInput,\n DEFAULT_EXPECTED_OUTCOME_SCHEMA,\n} from '../../lib/test-cases/test-case-factory';\nimport {\n type ExpectedOutcomeResolver,\n resolveDynamicExpectedOutcomes,\n} from '../../lib/test-cases/dynamic-expected-outcome-resolver';\nimport * as TestCaseMutations from '../../lib/test-cases/test-case-mutations';\nimport { EvaluationService } from '../../lib/evaluation/evaluation-service';\nimport { validateTestCaseInputArray } from '../../schemas/test-case';\nimport { validateExpectedOutcomeSchema } from '../../schemas/expected-outcome';\nimport { LLMTestRunnerHeader } from './header/llm-test-runner-header';\nimport { LLMTestCases } from './test-cases/llm-test-cases';\nimport { ExpectedOutcomeChangeDetail } from './test-cases/expected-outcome-renderer';\nimport type { ChatHistoryRowChangeDetail } from './test-cases/llm-test-case-row';\n\n@Component({\n tag: 'llm-test-runner',\n styleUrls: [\n '../../styles/tokens.css',\n 'llm-test-runner.css',\n 'header/llm-test-runner-header.css',\n 'test-cases/llm-test-cases.css',\n 'test-cases/llm-test-case-row.css',\n 'test-cases/actions/row-actions.css',\n 'test-cases/evaluation/evaluation-summary.css',\n 'test-cases/output/response-output.css',\n '../error-message/error-message.css',\n '../../lib/ui/button/button.css',\n '../../lib/ui/icon-button/icon-button.css',\n ],\n shadow: true,\n})\nexport class LLMTestRunner {\n @Event() llmRequest: EventEmitter<LLMRequestPayload>;\n @Event() save: EventEmitter<SavePayload>;\n @Prop() delayMs?: number = 500;\n @Prop() useSave?: boolean = false;\n @Prop() usePromptEditor?: boolean = false;\n @Prop() resolveExpectedOutcome?: ExpectedOutcomeResolver;\n @Prop() initialTestCases?: TestCase[];\n @Prop() defaultExpectedOutcomeSchema?: ExpectedOutcomeSchema;\n @State() testCases: TestCase[] = [\n {\n id: '1',\n question: '',\n expectedOutcome: [\n {\n type: 'textarea',\n label: 'Expected Outcome',\n value: '',\n },\n ],\n chatHistory: { enabled: false, value: '' },\n isRunning: false,\n },\n ];\n @State() isRunningAll: boolean = false;\n @State() error: string = '';\n @State() isExportingTestSuite: boolean = false;\n @State() isExportingTestResults: boolean = false;\n @State() isSaving: boolean = false;\n\n private evaluationService: EvaluationService;\n\n private getResolvedExpectedOutcomeSchema(): ExpectedOutcomeSchema {\n if (this.defaultExpectedOutcomeSchema === undefined) {\n return DEFAULT_EXPECTED_OUTCOME_SCHEMA;\n }\n\n validateExpectedOutcomeSchema(this.defaultExpectedOutcomeSchema);\n return this.defaultExpectedOutcomeSchema;\n }\n\n componentWillLoad() {\n this.evaluationService = new EvaluationService();\n try {\n // Initialize testCases from prop if provided\n if (this.initialTestCases !== undefined) {\n validateTestCaseInputArray(this.initialTestCases);\n this.testCases = this.initialTestCases.map((rawTestCase, index) => {\n try {\n return createTestCaseFromInput(rawTestCase);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n throw new Error(`Invalid initial test case at index ${index}: ${message}`);\n }\n });\n } else {\n const schema = this.getResolvedExpectedOutcomeSchema();\n this.testCases = [createTestCase(schema)];\n }\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Invalid defaultExpectedOutcomeSchema provided.';\n this.testCases = [];\n }\n }\n\n componentDidLoad() {}\n\n disconnectedCallback() {}\n\n @Method()\n async resetSavingState(): Promise<void> {\n this.isSaving = false;\n }\n\n @Method()\n async getTestCases(): Promise<TestCase[]> {\n return this.testCases;\n }\n\n private handleTestCaseChange = (\n event: CustomEvent<{ testCaseId: string; key: string; value: string }>,\n ) => {\n const { testCaseId, key, value } = event.detail;\n this.testCases = this.testCases.map(tc =>\n tc.id === testCaseId ? { ...tc, [key]: value } : tc,\n );\n };\n\n private handleChatHistoryChange = (\n event: CustomEvent<ChatHistoryRowChangeDetail>,\n ) => {\n const { testCaseId, enabled, value } = event.detail;\n this.updateTestCase(testCaseId, {\n chatHistory: { enabled, value },\n });\n };\n\n private addNewTestCase() {\n try {\n const schema = this.getResolvedExpectedOutcomeSchema();\n const newTestCase = createTestCase(schema);\n this.testCases = [...this.testCases, newTestCase];\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Invalid defaultExpectedOutcomeSchema provided.';\n }\n }\n\n private updateTestCase(id: string, updates: Partial<TestCase>) {\n this.testCases = this.testCases.map(tc =>\n tc.id === id ? { ...tc, ...updates } : tc,\n );\n }\n\n private requestLlmText(testCase: TestCase): Promise<string> {\n return new Promise((resolve, reject) => {\n const payload: LLMRequestPayload = {\n prompt: testCase.question,\n resolve,\n reject,\n };\n if (testCase.chatHistory?.enabled) {\n payload.chatHistory = testCase.chatHistory.value;\n }\n this.llmRequest.emit(payload);\n });\n }\n\n private throwError(reason: unknown): never {\n throw reason instanceof Error ? reason : new Error(String(reason));\n }\n\n private addErrorMessage(reason: unknown, fallback: string): string {\n return reason instanceof Error ? reason.message : fallback;\n }\n\n private async runSingleTest(testCase: TestCase): Promise<void> {\n const startTime = Date.now();\n this.updateTestCase(testCase.id, { isRunning: true });\n const [llmSettled, resolutionSettled] = await Promise.allSettled([\n this.requestLlmText(testCase),\n resolveDynamicExpectedOutcomes(testCase, this.resolveExpectedOutcome),\n ]);\n\n const responseTime = Date.now() - startTime;\n\n if (llmSettled.status === 'rejected') {\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: null,\n error: this.addErrorMessage(llmSettled.reason, 'Unknown error'),\n responseTime,\n });\n this.throwError(llmSettled.reason);\n }\n const aiResponse = llmSettled.value;\n\n if (resolutionSettled.status === 'rejected') {\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: aiResponse,\n error: this.addErrorMessage(\n resolutionSettled.reason,\n 'Failed to resolve dynamic expected outcome.',\n ),\n responseTime,\n });\n this.throwError(resolutionSettled.reason);\n }\n const resolvedTestCase = resolutionSettled.value;\n\n const forEvaluationTestCase: TestCase = {\n ...resolvedTestCase,\n output: aiResponse,\n responseTime,\n };\n\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: aiResponse,\n error: null,\n responseTime,\n expectedOutcome: forEvaluationTestCase.expectedOutcome,\n });\n\n await this.evaluateResponse(forEvaluationTestCase);\n }\n\n private deleteTestCase(id: string) {\n this.testCases = this.testCases.filter(tc => tc.id !== id);\n }\n\n private handleExpectedOutcomeChange = (\n event: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => {\n const { testCaseId, ...change } = event.detail;\n\n this.testCases = this.testCases.map(tc => {\n if (tc.id !== testCaseId) {\n return tc;\n }\n\n return TestCaseMutations.applyExpectedOutcomeChange(tc, change);\n });\n };\n\n private async evaluateResponse(testCase: TestCase): Promise<void> {\n await this.evaluationService.evaluateTestCase(\n testCase,\n (result: EvaluationResult) => {\n this.updateTestCase(testCase.id, {\n evaluationResult: result,\n });\n },\n );\n }\n\n private async runAllTests() {\n this.isRunningAll = true;\n const tasks = [];\n for (const testCase of this.testCases) {\n if (!testCase.isRunning && testCase.question.trim()) {\n tasks.push(() =>\n this.runSingleTest(testCase).catch(err => {\n console.error(`⚠️ Test case ${testCase.id} failed`, err);\n }),\n );\n }\n }\n try {\n const fetcher = new RateLimitedFetcher(this.delayMs);\n await fetcher.runAll(tasks);\n } catch (err) {\n console.error('⚠️ Error running all tests:', err);\n }\n this.isRunningAll = false;\n }\n\n private async handleImport(file: File): Promise<void> {\n const isJsonType = file.type === 'application/json';\n const isJsonExtension = file.name.toLowerCase().endsWith('.json');\n\n if (!isJsonType && !isJsonExtension) {\n this.error = 'Invalid file type. Please select a JSON file.';\n return;\n }\n\n this.error = '';\n\n try {\n const content = await readFileAsync(file);\n const result = importTestSuite(content);\n\n if (!result.success) {\n this.error = result.error || 'Unknown error occurred during import.';\n return;\n }\n\n this.testCases = result.testCases || [];\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Error processing file. Please ensure it is a valid JSON array.';\n console.error('File Processing Error:', err);\n }\n }\n\n private async handleExportTestSuite() {\n this.isExportingTestSuite = true;\n try {\n const jsonContent = formatTestSuiteAsJson(this.testCases);\n\n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n\n downloadFile(jsonContent, 'test-suite.json', 'application/json');\n } finally {\n this.isExportingTestSuite = false;\n }\n }\n\n private async handleExportTestResults() {\n this.isExportingTestResults = true;\n try {\n const csvContent = exportTestResultsToCsv(this.testCases);\n\n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n\n downloadFile(csvContent, 'test-results.csv', 'text/csv');\n } finally {\n this.isExportingTestResults = false;\n }\n }\n\n private async handleSave() {\n this.isSaving = true;\n try {\n const testRun = {\n timestamp: new Date().toISOString(),\n testCases: this.testCases,\n };\n this.save.emit(testRun);\n\n // Failsafe: Auto-reset saving state after 10 seconds to prevent stuck UI\n setTimeout(() => {\n if (this.isSaving) {\n console.warn('Save operation timed out, resetting state');\n this.isSaving = false;\n }\n }, 10000);\n } finally {\n // Parent will call resetSavingState() when actual save completes\n // If not called within 10 seconds, failsafe above will reset state\n }\n }\n\n render() {\n return (\n <div class=\"test-runner-container\">\n <LLMTestRunnerHeader\n isExportingTestSuite={this.isExportingTestSuite}\n isExportingTestResults={this.isExportingTestResults}\n isRunningAll={this.isRunningAll}\n useSave={this.useSave}\n isSaving={this.isSaving}\n usePromptEditor={this.usePromptEditor}\n onImport={file => this.handleImport(file)}\n onExportSuite={() => this.handleExportTestSuite()}\n onExportResults={() => this.handleExportTestResults()}\n onRunAll={() => this.runAllTests()}\n onSave={() => this.handleSave()}\n />\n <ErrorMessage message={this.error} onClear={() => (this.error = '')} />\n <div class=\"test-runner-container__content\">\n <LLMTestCases\n testCases={this.testCases}\n dynamicResolutionSupported={!!this.resolveExpectedOutcome}\n onRun={testCase => this.runSingleTest(testCase).catch(() => {})}\n onDelete={id => this.deleteTestCase(id)}\n onAddTestCase={() => this.addNewTestCase()}\n handleTestCaseChange={this.handleTestCaseChange}\n onExpectedOutcomeChange={this.handleExpectedOutcomeChange}\n onChatHistoryChange={this.handleChatHistoryChange}\n />\n </div>\n </div>\n );\n }\n}\n"]}
1
+ {"version":3,"file":"llm-test-runner.js","sourceRoot":"","sources":["../../../src/components/llm-test-runner/llm-test-runner.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n State,\n Prop,\n h,\n EventEmitter,\n Event,\n Method,\n} from '@stencil/core';\nimport { EvaluationResult } from '../../lib/evaluation/types';\nimport { ErrorMessage } from '../error-message/error-message';\nimport { RateLimitedFetcher } from '../../lib/rate-limited-fetcher/rate-limited-fetcher';\nimport {\n ExpectedOutcomeSchema,\n TestCase,\n LLMRequestPayload,\n SavePayload,\n ModelResponsePayload,\n EvaluationSourceExtractors,\n} from '../../types/llm-test-runner';\nimport { readFileAsync } from '../../lib/file/file-reader';\nimport { downloadFile } from '../../lib/file/file-download';\nimport { formatTestSuiteAsJson } from '../../lib/import-export/test-suite-exporter';\nimport { exportTestResultsToCsv } from '../../lib/import-export/test-results-csv';\nimport { importTestSuite } from '../../lib/import-export/test-suite-importer';\nimport {\n createTestCase,\n createTestCaseFromInput,\n DEFAULT_EXPECTED_OUTCOME_SCHEMA,\n} from '../../lib/test-cases/test-case-factory';\nimport {\n type ExpectedOutcomeResolver,\n resolveDynamicExpectedOutcomes,\n} from '../../lib/test-cases/dynamic-expected-outcome-resolver';\nimport * as TestCaseMutations from '../../lib/test-cases/test-case-mutations';\nimport { EvaluationService } from '../../lib/evaluation/evaluation-service';\nimport { validateTestCaseInputArray } from '../../schemas/test-case';\nimport {\n getExtractorIds,\n validateExpectedOutcomeArrayWithExtractors,\n validateExpectedOutcomeSchema,\n} from '../../schemas/expected-outcome';\nimport { LLMTestRunnerHeader } from './header/llm-test-runner-header';\nimport { LLMTestCases } from './test-cases/llm-test-cases';\nimport { ExpectedOutcomeChangeDetail } from './test-cases/expected-outcome-renderer';\nimport type { ChatHistoryRowChangeDetail } from './test-cases/llm-test-case-row';\n\n@Component({\n tag: 'llm-test-runner',\n styleUrls: [\n '../../styles/tokens.css',\n 'llm-test-runner.css',\n 'header/llm-test-runner-header.css',\n 'test-cases/llm-test-cases.css',\n 'test-cases/llm-test-case-row.css',\n 'test-cases/actions/row-actions.css',\n 'test-cases/evaluation/evaluation-summary.css',\n 'test-cases/output/response-output.css',\n '../error-message/error-message.css',\n '../../lib/ui/button/button.css',\n '../../lib/ui/icon-button/icon-button.css',\n ],\n shadow: true,\n})\nexport class LLMTestRunner {\n @Event() llmRequest: EventEmitter<LLMRequestPayload>;\n @Event() save: EventEmitter<SavePayload>;\n @Prop() delayMs?: number = 500;\n @Prop() useSave?: boolean = false;\n @Prop() usePromptEditor?: boolean = false;\n @Prop() resolveExpectedOutcome?: ExpectedOutcomeResolver;\n @Prop() evaluationSourceExtractors?: EvaluationSourceExtractors;\n @Prop() initialTestCases?: TestCase[];\n @Prop() defaultExpectedOutcomeSchema?: ExpectedOutcomeSchema;\n @State() testCases: TestCase[] = [\n {\n id: '1',\n question: '',\n expectedOutcome: [\n {\n type: 'textarea',\n label: 'Expected Outcome',\n value: '',\n },\n ],\n chatHistory: { enabled: false, value: '' },\n isRunning: false,\n },\n ];\n @State() isRunningAll: boolean = false;\n @State() error: string = '';\n @State() isExportingTestSuite: boolean = false;\n @State() isExportingTestResults: boolean = false;\n @State() isSaving: boolean = false;\n\n private evaluationService: EvaluationService;\n\n private getResolvedExpectedOutcomeSchema(): ExpectedOutcomeSchema {\n if (this.defaultExpectedOutcomeSchema === undefined) {\n return DEFAULT_EXPECTED_OUTCOME_SCHEMA;\n }\n\n validateExpectedOutcomeSchema(this.defaultExpectedOutcomeSchema);\n return this.defaultExpectedOutcomeSchema;\n }\n\n componentWillLoad() {\n this.evaluationService = new EvaluationService();\n try {\n // Initialize testCases from prop if provided\n if (this.initialTestCases !== undefined) {\n validateTestCaseInputArray(this.initialTestCases);\n const extractorIds = getExtractorIds(this.evaluationSourceExtractors);\n if (extractorIds.length > 0) {\n this.initialTestCases.forEach(testCase => {\n validateExpectedOutcomeArrayWithExtractors(\n testCase.expectedOutcome,\n extractorIds,\n );\n });\n }\n this.testCases = this.initialTestCases.map((rawTestCase, index) => {\n try {\n return createTestCaseFromInput(rawTestCase);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n throw new Error(`Invalid initial test case at index ${index}: ${message}`);\n }\n });\n } else {\n const schema = this.getResolvedExpectedOutcomeSchema();\n this.testCases = [createTestCase(schema)];\n }\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Invalid defaultExpectedOutcomeSchema provided.';\n this.testCases = [];\n }\n }\n\n @Method()\n async resetSavingState(): Promise<void> {\n this.isSaving = false;\n }\n\n @Method()\n async getTestCases(): Promise<TestCase[]> {\n return this.testCases;\n }\n\n private handleTestCaseChange = (\n event: CustomEvent<{ testCaseId: string; key: string; value: string }>,\n ) => {\n const { testCaseId, key, value } = event.detail;\n this.testCases = this.testCases.map(tc =>\n tc.id === testCaseId ? { ...tc, [key]: value } : tc,\n );\n };\n\n private handleChatHistoryChange = (\n event: CustomEvent<ChatHistoryRowChangeDetail>,\n ) => {\n const { testCaseId, enabled, value } = event.detail;\n this.updateTestCase(testCaseId, {\n chatHistory: { enabled, value },\n });\n };\n\n private addNewTestCase() {\n try {\n const schema = this.getResolvedExpectedOutcomeSchema();\n const newTestCase = createTestCase(schema);\n this.testCases = [...this.testCases, newTestCase];\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Invalid defaultExpectedOutcomeSchema provided.';\n }\n }\n\n private updateTestCase(id: string, updates: Partial<TestCase>) {\n this.testCases = this.testCases.map(tc =>\n tc.id === id ? { ...tc, ...updates } : tc,\n );\n }\n\n private requestLlmResponse(testCase: TestCase): Promise<ModelResponsePayload> {\n return new Promise((resolve, reject) => {\n const payload: LLMRequestPayload = {\n prompt: testCase.question,\n resolve,\n reject,\n };\n if (testCase.chatHistory?.enabled) {\n payload.chatHistory = testCase.chatHistory.value;\n }\n this.llmRequest.emit(payload);\n });\n }\n\n private throwError(reason: unknown): never {\n throw reason instanceof Error ? reason : new Error(String(reason));\n }\n\n private addErrorMessage(reason: unknown, fallback: string): string {\n return reason instanceof Error ? reason.message : fallback;\n }\n\n private async runSingleTest(testCase: TestCase): Promise<void> {\n const startTime = Date.now();\n this.updateTestCase(testCase.id, { isRunning: true });\n const [llmSettled, resolutionSettled] = await Promise.allSettled([\n this.requestLlmResponse(testCase),\n resolveDynamicExpectedOutcomes(testCase, this.resolveExpectedOutcome),\n ]);\n\n const responseTime = Date.now() - startTime;\n\n if (llmSettled.status === 'rejected') {\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: undefined,\n error: this.addErrorMessage(llmSettled.reason, 'Unknown error'),\n responseTime,\n });\n this.throwError(llmSettled.reason);\n }\n const aiResponse = llmSettled.value;\n\n if (resolutionSettled.status === 'rejected') {\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: aiResponse,\n error: this.addErrorMessage(\n resolutionSettled.reason,\n 'Failed to resolve dynamic expected outcome.',\n ),\n responseTime,\n });\n this.throwError(resolutionSettled.reason);\n }\n const resolvedTestCase = resolutionSettled.value;\n\n const forEvaluationTestCase: TestCase = {\n ...resolvedTestCase,\n output: aiResponse,\n responseTime,\n };\n\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: aiResponse,\n error: null,\n responseTime,\n expectedOutcome: forEvaluationTestCase.expectedOutcome,\n });\n\n await this.evaluateResponse(forEvaluationTestCase);\n }\n\n private deleteTestCase(id: string) {\n this.testCases = this.testCases.filter(tc => tc.id !== id);\n }\n\n private handleExpectedOutcomeChange = (\n event: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => {\n const { testCaseId, ...change } = event.detail;\n\n this.testCases = this.testCases.map(tc => {\n if (tc.id !== testCaseId) {\n return tc;\n }\n\n return TestCaseMutations.applyExpectedOutcomeChange(tc, change);\n });\n };\n\n private async evaluateResponse(testCase: TestCase): Promise<void> {\n await this.evaluationService.evaluateTestCase(\n testCase,\n (result: EvaluationResult) => {\n this.updateTestCase(testCase.id, {\n evaluationResult: result,\n });\n },\n this.evaluationSourceExtractors,\n );\n }\n\n private async runAllTests() {\n this.isRunningAll = true;\n const tasks = [];\n for (const testCase of this.testCases) {\n if (!testCase.isRunning && testCase.question.trim()) {\n tasks.push(() =>\n this.runSingleTest(testCase).catch(err => {\n console.error(`⚠️ Test case ${testCase.id} failed`, err);\n }),\n );\n }\n }\n try {\n const fetcher = new RateLimitedFetcher(this.delayMs);\n await fetcher.runAll(tasks);\n } catch (err) {\n console.error('⚠️ Error running all tests:', err);\n }\n this.isRunningAll = false;\n }\n\n private async handleImport(file: File): Promise<void> {\n const isJsonType = file.type === 'application/json';\n const isJsonExtension = file.name.toLowerCase().endsWith('.json');\n\n if (!isJsonType && !isJsonExtension) {\n this.error = 'Invalid file type. Please select a JSON file.';\n return;\n }\n\n this.error = '';\n\n try {\n const content = await readFileAsync(file);\n const result = importTestSuite(\n content,\n getExtractorIds(this.evaluationSourceExtractors),\n );\n\n if (!result.success) {\n this.error = result.error || 'Unknown error occurred during import.';\n return;\n }\n\n this.testCases = result.testCases || [];\n } catch (err) {\n this.error =\n err instanceof Error\n ? err.message\n : 'Error processing file. Please ensure it is a valid JSON array.';\n console.error('File Processing Error:', err);\n }\n }\n\n private async handleExportTestSuite() {\n this.isExportingTestSuite = true;\n try {\n const jsonContent = formatTestSuiteAsJson(this.testCases);\n\n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n\n downloadFile(jsonContent, 'test-suite.json', 'application/json');\n } finally {\n this.isExportingTestSuite = false;\n }\n }\n\n private async handleExportTestResults() {\n this.isExportingTestResults = true;\n try {\n const csvContent = exportTestResultsToCsv(this.testCases);\n\n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n\n downloadFile(csvContent, 'test-results.csv', 'text/csv');\n } finally {\n this.isExportingTestResults = false;\n }\n }\n\n private async handleSave() {\n this.isSaving = true;\n try {\n const testRun = {\n timestamp: new Date().toISOString(),\n testCases: this.testCases,\n };\n this.save.emit(testRun);\n\n // Failsafe: Auto-reset saving state after 10 seconds to prevent stuck UI\n setTimeout(() => {\n if (this.isSaving) {\n console.warn('Save operation timed out, resetting state');\n this.isSaving = false;\n }\n }, 10000);\n } finally {\n // Parent will call resetSavingState() when actual save completes\n // If not called within 10 seconds, failsafe above will reset state\n }\n }\n\n render() {\n return (\n <div class=\"test-runner-container\">\n <LLMTestRunnerHeader\n isExportingTestSuite={this.isExportingTestSuite}\n isExportingTestResults={this.isExportingTestResults}\n isRunningAll={this.isRunningAll}\n useSave={this.useSave}\n isSaving={this.isSaving}\n usePromptEditor={this.usePromptEditor}\n onImport={file => this.handleImport(file)}\n onExportSuite={() => this.handleExportTestSuite()}\n onExportResults={() => this.handleExportTestResults()}\n onRunAll={() => this.runAllTests()}\n onSave={() => this.handleSave()}\n />\n <ErrorMessage message={this.error} onClear={() => (this.error = '')} />\n <div class=\"test-runner-container__content\">\n <LLMTestCases\n testCases={this.testCases}\n dynamicResolutionSupported={!!this.resolveExpectedOutcome}\n extractorIds={getExtractorIds(this.evaluationSourceExtractors)}\n onRun={testCase => this.runSingleTest(testCase).catch(() => {})}\n onDelete={id => this.deleteTestCase(id)}\n onAddTestCase={() => this.addNewTestCase()}\n handleTestCaseChange={this.handleTestCaseChange}\n onExpectedOutcomeChange={this.handleExpectedOutcomeChange}\n onChatHistoryChange={this.handleChatHistoryChange}\n />\n </div>\n </div>\n );\n }\n}\n"]}
@@ -34,6 +34,9 @@
34
34
  .chat-history__switch-ui {
35
35
  position: relative;
36
36
  flex-shrink: 0;
37
+ display: flex;
38
+ align-items: center;
39
+ padding: 0px 4px;
37
40
  width: 2.75rem;
38
41
  height: 1.5rem;
39
42
  border-radius: var(--radius-full);
@@ -52,9 +55,7 @@
52
55
  }
53
56
 
54
57
  .chat-history__switch-thumb {
55
- position: absolute;
56
- top: 2px;
57
- left: 2px;
58
+ display: inline-block;
58
59
  width: calc(1.5rem - 6px);
59
60
  height: calc(1.5rem - 6px);
60
61
  border-radius: var(--radius-full);
@@ -69,8 +70,7 @@
69
70
  }
70
71
 
71
72
  .chat-history__switch-input:checked + .chat-history__switch-ui .chat-history__switch-thumb {
72
- /* track width − end padding (2px × 2) − thumb width */
73
- transform: translateX(calc(2.75rem - (1.5rem - 6px) - 4px));
73
+ transform: translateX(calc(2.75rem - (1.5rem - 6px)));
74
74
  }
75
75
 
76
76
  .chat-history__switch-input:focus-visible + .chat-history__switch-ui {
@@ -2,7 +2,9 @@ import { h } from "@stencil/core";
2
2
  import { FormFieldType } from "../../../lib/form/schema";
3
3
  import { EvaluationApproach, } from "../../../lib/evaluation/constants";
4
4
  import { getAllowedApproachesForFieldType } from "../../../lib/evaluation/field-evaluation-approach";
5
- export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionSupported = false, onExpectedOutcomeChange, }) => {
5
+ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionSupported = false, extractorIds = [], onExpectedOutcomeChange, }) => {
6
+ const hasExtractorOptions = extractorIds.length > 0;
7
+ const firstExtractorId = extractorIds[0];
6
8
  const emit = (detail) => onExpectedOutcomeChange({
7
9
  detail,
8
10
  });
@@ -32,6 +34,23 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
32
34
  required: false,
33
35
  rows: 2,
34
36
  });
37
+ const buildEvaluationSourceConfig = (index) => ({
38
+ name: `expectedOutcomeEvaluationSource-${index}`,
39
+ fieldType: FormFieldType.SELECT,
40
+ label: 'Evaluation Source',
41
+ placeholder: 'Select evaluation source',
42
+ required: true,
43
+ optionList: ['text', 'custom'],
44
+ defaultValue: 'text',
45
+ });
46
+ const buildExtractorConfig = (index) => ({
47
+ name: `expectedOutcomeEvaluationSourceExtractor-${index}`,
48
+ fieldType: FormFieldType.SELECT,
49
+ label: 'Extractor',
50
+ placeholder: 'Select extractor',
51
+ required: true,
52
+ optionList: extractorIds,
53
+ });
35
54
  const renderEvaluationSelector = (field, index) => {
36
55
  const optionList = getAllowedApproachesForFieldType(field.type);
37
56
  return (h("app-select", { config: buildEvaluationConfig(index, optionList), value: field.evaluationParameters?.approach, onValueChange: (e) => emit({
@@ -41,6 +60,27 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
41
60
  value: e.detail.value,
42
61
  }) }));
43
62
  };
63
+ const renderEvaluationSourceSelector = (field, index) => {
64
+ if (!hasExtractorOptions) {
65
+ return null;
66
+ }
67
+ const sourceType = field.evaluationSource?.type || 'text';
68
+ return (h("div", null, h("app-select", { config: buildEvaluationSourceConfig(index), value: sourceType, onValueChange: (e) => emit({
69
+ testCaseId,
70
+ index,
71
+ operation: 'set-evaluation-source-type',
72
+ value: e.detail.value,
73
+ fallbackExtractorId: firstExtractorId,
74
+ }) }), sourceType === 'custom' && (h("app-select", { config: buildExtractorConfig(index), value: field.evaluationSource?.type === 'custom'
75
+ ? field.evaluationSource.extractorId
76
+ : '', onValueChange: (e) => emit({
77
+ testCaseId,
78
+ index,
79
+ operation: 'set-evaluation-source-extractor',
80
+ value: e.detail.value,
81
+ }) }))));
82
+ };
83
+ const renderEvaluationOptions = (field, index) => (h("details", { class: "expected-outcome-renderer__options" }, h("summary", { class: "expected-outcome-renderer__options-summary" }, "More options"), h("div", { class: "expected-outcome-renderer__options-content" }, renderEvaluationSelector(field, index), renderEvaluationSourceSelector(field, index))));
44
84
  return (h("div", { class: "expected-outcome-renderer" }, (fields || []).map((field, index) => {
45
85
  if (field.type === 'textarea') {
46
86
  const isDynamic = dynamicResolutionSupported && field.outcomeMode === 'dynamic';
@@ -72,7 +112,7 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
72
112
  index,
73
113
  operation: 'set-resolution-query',
74
114
  value: e.detail.value,
75
- }) })), !isDynamic && renderEvaluationSelector(field, index)));
115
+ }) })), !isDynamic && renderEvaluationOptions(field, index)));
76
116
  }
77
117
  if (field.type === 'chips-input') {
78
118
  const config = {
@@ -92,7 +132,7 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
92
132
  index,
93
133
  operation: 'remove-chip',
94
134
  value: e.detail.value,
95
- }) }), renderEvaluationSelector(field, index)));
135
+ }) }), renderEvaluationOptions(field, index)));
96
136
  }
97
137
  if (field.type === 'select') {
98
138
  const config = {
@@ -108,14 +148,14 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
108
148
  index,
109
149
  operation: 'set-value',
110
150
  value: e.detail.value,
111
- }) }), renderEvaluationSelector(field, index)));
151
+ }) }), renderEvaluationOptions(field, index)));
112
152
  }
113
153
  return (h("div", { class: "expected-outcome-renderer__group" }, h("div", { class: "expected-outcome-renderer__text" }, h("label", null, field.label), h("input", { type: "text", value: field.value, placeholder: field.placeholder, onInput: (e) => emit({
114
154
  testCaseId,
115
155
  index,
116
156
  operation: 'set-value',
117
157
  value: e.target.value,
118
- }) })), renderEvaluationSelector(field, index)));
158
+ }) })), renderEvaluationOptions(field, index)));
119
159
  })));
120
160
  };
121
161
  //# sourceMappingURL=expected-outcome-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"expected-outcome-renderer.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/expected-outcome-renderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport {\n ExpectedOutcomeField,\n type ExpectedOutcomeMode,\n} from '../../../types/llm-test-runner';\nimport { ChipsConfig, FormFieldType, SelectConfig, TextAreaConfig } from '../../../lib/form/schema';\nimport {\n EvaluationApproach,\n} from '../../../lib/evaluation/constants';\nimport { getAllowedApproachesForFieldType } from '../../../lib/evaluation/field-evaluation-approach';\nimport { ExpectedOutcomeChange } from '../../../lib/test-cases/test-case-mutations';\n\nexport type ExpectedOutcomeChangeDetail = {\n testCaseId: string;\n} & ExpectedOutcomeChange;\n\ninterface ExpectedOutcomeRendererProps {\n testCaseId: string;\n fields: ExpectedOutcomeField[];\n dynamicResolutionSupported?: boolean;\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n}\n\nexport const ExpectedOutcomeRenderer: FunctionalComponent<ExpectedOutcomeRendererProps> = ({\n testCaseId,\n fields,\n dynamicResolutionSupported = false,\n onExpectedOutcomeChange,\n}) => {\n const emit = (detail: ExpectedOutcomeChangeDetail) =>\n onExpectedOutcomeChange({\n detail,\n } as CustomEvent<ExpectedOutcomeChangeDetail>);\n\n const buildEvaluationConfig = (\n index: number,\n optionList: string[],\n ): SelectConfig => ({\n name: `expectedOutcomeEvaluation-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Approach',\n placeholder: 'Select evaluation approach…',\n required: true,\n optionList,\n defaultValue: EvaluationApproach.EXACT,\n });\n\n const buildOutcomeModeConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeMode-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Outcome Mode',\n placeholder: 'Select outcome mode',\n required: true,\n optionList: ['static', 'dynamic'],\n defaultValue: 'static',\n });\n\n const buildResolutionQueryConfig = (index: number): TextAreaConfig => ({\n name: `expectedOutcomeResolutionQuery-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: 'Resolution Query',\n placeholder: 'Query used to resolve expected value',\n required: false,\n rows: 2,\n });\n\n const renderEvaluationSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n const optionList = getAllowedApproachesForFieldType(field.type);\n\n return (\n <app-select\n config={buildEvaluationConfig(index, optionList)}\n value={field.evaluationParameters?.approach}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-approach',\n value: e.detail.value as EvaluationApproach,\n })\n }\n />\n );\n };\n\n return (\n <div class=\"expected-outcome-renderer\">\n {(fields || []).map((field, index) => {\n if (field.type === 'textarea') {\n const isDynamic =\n dynamicResolutionSupported && field.outcomeMode === 'dynamic';\n const config: TextAreaConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: field.label,\n placeholder: isDynamic ? 'Resolved on run' : field.placeholder,\n required: !isDynamic,\n readOnly: isDynamic,\n helpText: isDynamic\n ? 'Filled automatically when the test is run'\n : undefined,\n rows: field.rows || 2,\n };\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-textarea\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {dynamicResolutionSupported && (\n <app-select\n config={buildOutcomeModeConfig(index)}\n value={field.outcomeMode || 'static'}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-outcome-mode',\n value: e.detail.value as ExpectedOutcomeMode,\n })\n }\n />\n )}\n {dynamicResolutionSupported &&\n field.outcomeMode === 'dynamic' && (\n <app-textarea\n config={buildResolutionQueryConfig(index)}\n value={field.resolutionQuery || ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-resolution-query',\n value: e.detail.value,\n })\n }\n />\n )}\n {!isDynamic && renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n if (field.type === 'chips-input') {\n const config: ChipsConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.CHIPS,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-chips\n config={config}\n value={field.value}\n onAddChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'add-chip',\n value: e.detail.value,\n })\n }\n onRemoveChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'remove-chip',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n if (field.type === 'select') {\n const config: SelectConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.SELECT,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n optionList: field.options,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-select\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <div class=\"expected-outcome-renderer__text\">\n <label>{field.label}</label>\n <input\n type=\"text\"\n value={field.value}\n placeholder={field.placeholder}\n onInput={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: (e.target as HTMLInputElement).value,\n })\n }\n />\n </div>\n {renderEvaluationSelector(field, index)}\n </div>\n );\n })}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"expected-outcome-renderer.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/expected-outcome-renderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport {\n ExpectedOutcomeField,\n type EvaluationSource,\n type ExpectedOutcomeMode,\n} from '../../../types/llm-test-runner';\nimport { ChipsConfig, FormFieldType, SelectConfig, TextAreaConfig } from '../../../lib/form/schema';\nimport {\n EvaluationApproach,\n} from '../../../lib/evaluation/constants';\nimport { getAllowedApproachesForFieldType } from '../../../lib/evaluation/field-evaluation-approach';\nimport { ExpectedOutcomeChange } from '../../../lib/test-cases/test-case-mutations';\n\nexport type ExpectedOutcomeChangeDetail = {\n testCaseId: string;\n} & ExpectedOutcomeChange;\n\ninterface ExpectedOutcomeRendererProps {\n testCaseId: string;\n fields: ExpectedOutcomeField[];\n dynamicResolutionSupported?: boolean;\n extractorIds?: string[];\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n}\n\nexport const ExpectedOutcomeRenderer: FunctionalComponent<ExpectedOutcomeRendererProps> = ({\n testCaseId,\n fields,\n dynamicResolutionSupported = false,\n extractorIds = [],\n onExpectedOutcomeChange,\n}) => {\n const hasExtractorOptions = extractorIds.length > 0;\n const firstExtractorId = extractorIds[0];\n\n const emit = (detail: ExpectedOutcomeChangeDetail) =>\n onExpectedOutcomeChange({\n detail,\n } as CustomEvent<ExpectedOutcomeChangeDetail>);\n\n const buildEvaluationConfig = (\n index: number,\n optionList: string[],\n ): SelectConfig => ({\n name: `expectedOutcomeEvaluation-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Approach',\n placeholder: 'Select evaluation approach…',\n required: true,\n optionList,\n defaultValue: EvaluationApproach.EXACT,\n });\n\n const buildOutcomeModeConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeMode-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Outcome Mode',\n placeholder: 'Select outcome mode',\n required: true,\n optionList: ['static', 'dynamic'],\n defaultValue: 'static',\n });\n\n const buildResolutionQueryConfig = (index: number): TextAreaConfig => ({\n name: `expectedOutcomeResolutionQuery-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: 'Resolution Query',\n placeholder: 'Query used to resolve expected value',\n required: false,\n rows: 2,\n });\n\n const buildEvaluationSourceConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeEvaluationSource-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Source',\n placeholder: 'Select evaluation source',\n required: true,\n optionList: ['text', 'custom'],\n defaultValue: 'text',\n });\n\n const buildExtractorConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeEvaluationSourceExtractor-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Extractor',\n placeholder: 'Select extractor',\n required: true,\n optionList: extractorIds,\n });\n\n const renderEvaluationSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n const optionList = getAllowedApproachesForFieldType(field.type);\n\n return (\n <app-select\n config={buildEvaluationConfig(index, optionList)}\n value={field.evaluationParameters?.approach}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-approach',\n value: e.detail.value as EvaluationApproach,\n })\n }\n />\n );\n };\n\n const renderEvaluationSourceSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n if (!hasExtractorOptions) {\n return null;\n }\n\n const sourceType = field.evaluationSource?.type || 'text';\n\n return (\n <div>\n <app-select\n config={buildEvaluationSourceConfig(index)}\n value={sourceType}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-source-type',\n value: e.detail.value as EvaluationSource['type'],\n fallbackExtractorId: firstExtractorId,\n })\n }\n />\n {sourceType === 'custom' && (\n <app-select\n config={buildExtractorConfig(index)}\n value={field.evaluationSource?.type === 'custom'\n ? field.evaluationSource.extractorId\n : ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-source-extractor',\n value: e.detail.value,\n })\n }\n />\n )}\n </div>\n );\n };\n\n const renderEvaluationOptions = (field: ExpectedOutcomeField, index: number) => (\n <details class=\"expected-outcome-renderer__options\">\n <summary class=\"expected-outcome-renderer__options-summary\">\n More options\n </summary>\n <div class=\"expected-outcome-renderer__options-content\">\n {renderEvaluationSelector(field, index)}\n {renderEvaluationSourceSelector(field, index)}\n </div>\n </details>\n );\n\n return (\n <div class=\"expected-outcome-renderer\">\n {(fields || []).map((field, index) => {\n if (field.type === 'textarea') {\n const isDynamic =\n dynamicResolutionSupported && field.outcomeMode === 'dynamic';\n const config: TextAreaConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: field.label,\n placeholder: isDynamic ? 'Resolved on run' : field.placeholder,\n required: !isDynamic,\n readOnly: isDynamic,\n helpText: isDynamic\n ? 'Filled automatically when the test is run'\n : undefined,\n rows: field.rows || 2,\n };\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-textarea\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {dynamicResolutionSupported && (\n <app-select\n config={buildOutcomeModeConfig(index)}\n value={field.outcomeMode || 'static'}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-outcome-mode',\n value: e.detail.value as ExpectedOutcomeMode,\n })\n }\n />\n )}\n {dynamicResolutionSupported &&\n field.outcomeMode === 'dynamic' && (\n <app-textarea\n config={buildResolutionQueryConfig(index)}\n value={field.resolutionQuery || ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-resolution-query',\n value: e.detail.value,\n })\n }\n />\n )}\n {!isDynamic && renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n if (field.type === 'chips-input') {\n const config: ChipsConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.CHIPS,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-chips\n config={config}\n value={field.value}\n onAddChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'add-chip',\n value: e.detail.value,\n })\n }\n onRemoveChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'remove-chip',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n if (field.type === 'select') {\n const config: SelectConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.SELECT,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n optionList: field.options,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-select\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <div class=\"expected-outcome-renderer__text\">\n <label>{field.label}</label>\n <input\n type=\"text\"\n value={field.value}\n placeholder={field.placeholder}\n onInput={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: (e.target as HTMLInputElement).value,\n })\n }\n />\n </div>\n {renderEvaluationOptions(field, index)}\n </div>\n );\n })}\n </div>\n );\n};\n"]}
@@ -35,6 +35,27 @@
35
35
  background: var(--background);
36
36
  }
37
37
 
38
+ .expected-outcome-renderer__options {
39
+ border: var(--border-width) solid var(--border);
40
+ border-radius: var(--radius-sm);
41
+ background: var(--muted);
42
+ }
43
+
44
+ .expected-outcome-renderer__options-summary {
45
+ cursor: pointer;
46
+ font-size: var(--font-size-sm);
47
+ color: var(--foreground);
48
+ padding: var(--spacing-2) var(--spacing-3);
49
+ user-select: none;
50
+ }
51
+
52
+ .expected-outcome-renderer__options-content {
53
+ display: flex;
54
+ flex-direction: column;
55
+ gap: var(--spacing-2);
56
+ padding: 0 var(--spacing-3) var(--spacing-3);
57
+ }
58
+
38
59
  /* Responsive Design */
39
60
  @media (max-width: 1200px) {
40
61
  .test-case-row {
@@ -4,7 +4,7 @@ import { EvaluationSummary } from "./evaluation/evaluation-summary";
4
4
  import { RowActions } from "./actions/row-actions";
5
5
  import { FormFieldType } from "../../../lib/form/schema";
6
6
  import { ExpectedOutcomeRenderer, } from "./expected-outcome-renderer";
7
- export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, onRun, onDelete, handleTestCaseChange, onExpectedOutcomeChange, onChatHistoryChange, }) => {
7
+ export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, extractorIds = [], onRun, onDelete, handleTestCaseChange, onExpectedOutcomeChange, onChatHistoryChange, }) => {
8
8
  const questionConfig = {
9
9
  name: 'question',
10
10
  fieldType: FormFieldType.TEXT_AREA,
@@ -30,6 +30,6 @@ export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, o
30
30
  value,
31
31
  },
32
32
  });
33
- } }), h(ExpectedOutcomeRenderer, { testCaseId: testCase.id, fields: testCase.expectedOutcome || [], dynamicResolutionSupported: dynamicResolutionSupported, onExpectedOutcomeChange: onExpectedOutcomeChange })), h(ResponseOutput, { output: testCase.output, isRunning: testCase.isRunning }), h(EvaluationSummary, { result: testCase.evaluationResult, isRunning: testCase.isRunning }), h(RowActions, { isRunning: testCase.isRunning, canRun: !!testCase.question.trim(), onRun: () => onRun(testCase), onDelete: () => onDelete(testCase.id) })));
33
+ } }), h(ExpectedOutcomeRenderer, { testCaseId: testCase.id, fields: testCase.expectedOutcome || [], dynamicResolutionSupported: dynamicResolutionSupported, extractorIds: extractorIds, onExpectedOutcomeChange: onExpectedOutcomeChange })), h(ResponseOutput, { output: testCase.output, isRunning: testCase.isRunning }), h(EvaluationSummary, { result: testCase.evaluationResult, isRunning: testCase.isRunning }), h(RowActions, { isRunning: testCase.isRunning, canRun: !!testCase.question.trim(), onRun: () => onRun(testCase), onDelete: () => onDelete(testCase.id) })));
34
34
  };
35
35
  //# sourceMappingURL=llm-test-case-row.js.map