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
@@ -1 +1 @@
1
- {"version":3,"file":"test-case-factory.js","sourceRoot":"","sources":["../../../src/lib/test-cases/test-case-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AASpC,OAAO,EAAE,qCAAqC,EAAE,MAAM,yCAAyC,CAAC;AAEhG,MAAM,CAAC,MAAM,+BAA+B,GAA0B;IACpE;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,2BAA2B;QACxC,IAAI,EAAE,CAAC;KACR;CACF,CAAC;AAEF,SAAS,6BAA6B,CACpC,KAA2B;IAE3B,OAAO;QACL,GAAG,KAAK;QACR,oBAAoB,EAAE,qCAAqC,CACzD,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,oBAAoB,CAC3B;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,wBAA+C,+BAA+B;IAE9E,OAAO;QACL,EAAE,EAAE,MAAM,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,+BAA+B,CAAC,qBAAqB,CAAC;QACvE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QAC1C,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,SAAS,oCAAoC,CAC3C,WAAuC;IAEvC,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM;YACT,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,WAAW,EAAE,WAAW,CAAC,WAAW;gBACpC,KAAK,EAAE,EAAE;gBACT,oBAAoB,EAAE,qCAAqC,CACzD,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,oBAAoB,CACjC;aACF,CAAC;QAEJ,KAAK,UAAU;YACb,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,WAAW,EAAE,WAAW,CAAC,WAAW;gBACpC,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,KAAK,EAAE,EAAE;gBACT,oBAAoB,EAAE,qCAAqC,CACzD,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,oBAAoB,CACjC;aACF,CAAC;QAEJ,KAAK,aAAa;YAChB,OAAO;gBACL,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,WAAW,EAAE,WAAW,CAAC,WAAW;gBACpC,KAAK,EAAE,EAAE;gBACT,oBAAoB,EAAE,qCAAqC,CACzD,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,oBAAoB,CACjC;aACF,CAAC;QAEJ,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,WAAW,EAAE,WAAW,CAAC,WAAW;gBACpC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC7B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,oBAAoB,EAAE,qCAAqC,CACzD,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,oBAAoB,CAC6B;aAChE,CAAC;QAEJ,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,gBAAgB,GAAU,WAAW,CAAC;YAC5C,OAAO,gBAAgB,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,qBAA4C;IAE5C,OAAO,qBAAqB,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAmB;IACzD,OAAO;QACL,GAAG,IAAI;QACP,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9D,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,6BAA6B,CAAC;KACzE,CAAC;AACJ,CAAC","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\nimport {\n ExpectedOutcomeField,\n ExpectedOutcomeSchema,\n ExpectedOutcomeSchemaField,\n TestCase,\n TestCaseInput,\n} from '../../types/llm-test-runner';\nimport { EvaluationApproach } from '../evaluation/constants';\nimport { normalizeEvaluationParametersForField } from '../evaluation/field-evaluation-approach';\n\nexport const DEFAULT_EXPECTED_OUTCOME_SCHEMA: ExpectedOutcomeSchema = [\n {\n type: 'textarea',\n label: 'Expected Outcome',\n placeholder: 'Enter expected outcome...',\n rows: 2,\n },\n];\n\nfunction normalizeExpectedOutcomeField(\n field: ExpectedOutcomeField,\n): ExpectedOutcomeField {\n return {\n ...field,\n evaluationParameters: normalizeEvaluationParametersForField(\n field.type,\n field.evaluationParameters,\n ),\n };\n}\n\n/**\n * Creates a new test case with default values\n * @returns A new TestCase object with a unique ID\n */\nexport function createTestCase(\n expectedOutcomeSchema: ExpectedOutcomeSchema = DEFAULT_EXPECTED_OUTCOME_SCHEMA,\n): TestCase {\n return {\n id: uuidv4(),\n question: '',\n expectedOutcome: createExpectedOutcomeFromSchema(expectedOutcomeSchema),\n chatHistory: { enabled: false, value: '' },\n isRunning: false,\n };\n}\n\nfunction createExpectedOutcomeFieldFromSchema(\n schemaField: ExpectedOutcomeSchemaField,\n): ExpectedOutcomeField {\n switch (schemaField.type) {\n case 'text':\n return {\n type: 'text',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n value: '',\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'textarea':\n return {\n type: 'textarea',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n rows: schemaField.rows,\n value: '',\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'chips-input':\n return {\n type: 'chips-input',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n value: [],\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'select':\n return {\n type: 'select',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n value: schemaField.options[0],\n options: schemaField.options,\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ) as { approach: EvaluationApproach.EXACT; threshold?: number },\n };\n\n default: {\n const _exhaustiveCheck: never = schemaField;\n return _exhaustiveCheck;\n }\n }\n}\n\nexport function createExpectedOutcomeFromSchema(\n expectedOutcomeSchema: ExpectedOutcomeSchema,\n): ExpectedOutcomeField[] {\n return expectedOutcomeSchema.map(createExpectedOutcomeFieldFromSchema);\n}\n\n/**\n * Creates a runtime test case from validated input data.\n * The input is expected to already satisfy `TestCaseInput`,\n * and this function only performs normalization/defaulting.\n *\n * @param data - Validated test case input\n * @returns A normalized TestCase object with runtime defaults applied\n */\nexport function createTestCaseFromInput(data: TestCaseInput): TestCase {\n return {\n ...data,\n chatHistory: data.chatHistory ?? { enabled: false, value: '' },\n expectedOutcome: data.expectedOutcome.map(normalizeExpectedOutcomeField),\n };\n}\n"]}
1
+ {"version":3,"file":"test-case-factory.js","sourceRoot":"","sources":["../../../src/lib/test-cases/test-case-factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\nimport {\n ExpectedOutcomeField,\n ExpectedOutcomeSchema,\n ExpectedOutcomeSchemaField,\n TestCase,\n TestCaseInput,\n} from '../../types/llm-test-runner';\nimport { EvaluationApproach } from '../evaluation/constants';\nimport { normalizeEvaluationParametersForField } from '../evaluation/field-evaluation-approach';\n\nexport const DEFAULT_EXPECTED_OUTCOME_SCHEMA: ExpectedOutcomeSchema = [\n {\n type: 'textarea',\n label: 'Expected Outcome',\n placeholder: 'Enter expected outcome...',\n rows: 2,\n },\n];\n\nfunction normalizeExpectedOutcomeField(\n field: ExpectedOutcomeField,\n): ExpectedOutcomeField {\n return {\n ...field,\n evaluationSource: field.evaluationSource || { type: 'text' },\n evaluationParameters: normalizeEvaluationParametersForField(\n field.type,\n field.evaluationParameters,\n ),\n };\n}\n\n/**\n * Creates a new test case with default values\n * @returns A new TestCase object with a unique ID\n */\nexport function createTestCase(\n expectedOutcomeSchema: ExpectedOutcomeSchema = DEFAULT_EXPECTED_OUTCOME_SCHEMA,\n): TestCase {\n return {\n id: uuidv4(),\n question: '',\n expectedOutcome: createExpectedOutcomeFromSchema(expectedOutcomeSchema),\n chatHistory: { enabled: false, value: '' },\n isRunning: false,\n };\n}\n\nfunction createExpectedOutcomeFieldFromSchema(\n schemaField: ExpectedOutcomeSchemaField,\n): ExpectedOutcomeField {\n switch (schemaField.type) {\n case 'text':\n return {\n type: 'text',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n evaluationSource: schemaField.evaluationSource || { type: 'text' },\n value: '',\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'textarea':\n return {\n type: 'textarea',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n evaluationSource: schemaField.evaluationSource || { type: 'text' },\n rows: schemaField.rows,\n value: '',\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'chips-input':\n return {\n type: 'chips-input',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n evaluationSource: schemaField.evaluationSource || { type: 'text' },\n value: [],\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ),\n };\n\n case 'select':\n return {\n type: 'select',\n label: schemaField.label,\n placeholder: schemaField.placeholder,\n evaluationSource: schemaField.evaluationSource || { type: 'text' },\n value: schemaField.options[0],\n options: schemaField.options,\n evaluationParameters: normalizeEvaluationParametersForField(\n schemaField.type,\n schemaField.evaluationParameters,\n ) as { approach: EvaluationApproach.EXACT; threshold?: number },\n };\n\n default: {\n const _exhaustiveCheck: never = schemaField;\n return _exhaustiveCheck;\n }\n }\n}\n\nexport function createExpectedOutcomeFromSchema(\n expectedOutcomeSchema: ExpectedOutcomeSchema,\n): ExpectedOutcomeField[] {\n return expectedOutcomeSchema.map(createExpectedOutcomeFieldFromSchema);\n}\n\n/**\n * Creates a runtime test case from validated input data.\n * The input is expected to already satisfy `TestCaseInput`,\n * and this function only performs normalization/defaulting.\n *\n * @param data - Validated test case input\n * @returns A normalized TestCase object with runtime defaults applied\n */\nexport function createTestCaseFromInput(data: TestCaseInput): TestCase {\n return {\n ...data,\n chatHistory: data.chatHistory ?? { enabled: false, value: '' },\n expectedOutcome: data.expectedOutcome.map(normalizeExpectedOutcomeField),\n };\n}\n"]}
@@ -1,4 +1,13 @@
1
1
  import { normalizeEvaluationParametersForField } from "../evaluation/field-evaluation-approach";
2
+ function isChipsInputField(field) {
3
+ return field.type === 'chips-input';
4
+ }
5
+ function isTextareaField(field) {
6
+ return field.type === 'textarea';
7
+ }
8
+ function isDynamicTextareaField(field) {
9
+ return isTextareaField(field) && field.outcomeMode === 'dynamic';
10
+ }
2
11
  export function applyExpectedOutcomeChange(testCase, change) {
3
12
  const { index } = change;
4
13
  const expectedOutcome = [...(testCase.expectedOutcome || [])];
@@ -6,73 +15,99 @@ export function applyExpectedOutcomeChange(testCase, change) {
6
15
  if (!target) {
7
16
  return testCase;
8
17
  }
18
+ const commit = (updatedField) => {
19
+ expectedOutcome[index] = updatedField;
20
+ return { ...testCase, expectedOutcome };
21
+ };
9
22
  switch (change.operation) {
10
23
  case 'set-value': {
11
- if (target.type === 'chips-input') {
24
+ if (isChipsInputField(target)) {
12
25
  return testCase;
13
26
  }
14
- if (target.type === 'textarea' && target.outcomeMode === 'dynamic') {
27
+ if (isDynamicTextareaField(target)) {
15
28
  return testCase;
16
29
  }
17
- expectedOutcome[index] = {
30
+ return commit({
18
31
  ...target,
19
32
  value: change.value,
20
- };
21
- return { ...testCase, expectedOutcome };
33
+ });
22
34
  }
23
35
  case 'add-chip': {
24
- if (target.type !== 'chips-input') {
36
+ if (!isChipsInputField(target)) {
25
37
  return testCase;
26
38
  }
27
- expectedOutcome[index] = {
39
+ return commit({
28
40
  ...target,
29
41
  value: [...target.value, change.value],
30
- };
31
- return { ...testCase, expectedOutcome };
42
+ });
32
43
  }
33
44
  case 'remove-chip': {
34
- if (target.type !== 'chips-input') {
45
+ if (!isChipsInputField(target)) {
35
46
  return testCase;
36
47
  }
37
- expectedOutcome[index] = {
48
+ return commit({
38
49
  ...target,
39
50
  value: target.value.filter(chip => chip !== change.value),
40
- };
41
- return { ...testCase, expectedOutcome };
51
+ });
42
52
  }
43
53
  case 'set-evaluation-approach':
44
54
  return updateExpectedOutcomeFieldApproach(testCase, index, change.value);
45
55
  case 'set-outcome-mode': {
46
- if (target.type !== 'textarea') {
56
+ if (!isTextareaField(target)) {
47
57
  return testCase;
48
58
  }
49
59
  const mode = change.value;
50
60
  if (mode === 'static') {
51
61
  const { resolutionQuery: _, ...rest } = target;
52
- expectedOutcome[index] = {
62
+ return commit({
53
63
  ...rest,
54
64
  outcomeMode: 'static',
55
65
  value: '',
56
- };
66
+ });
57
67
  }
58
68
  else {
59
- expectedOutcome[index] = {
69
+ return commit({
60
70
  ...target,
61
71
  outcomeMode: 'dynamic',
62
72
  value: '',
63
- };
73
+ });
64
74
  }
65
- return { ...testCase, expectedOutcome };
66
75
  }
67
76
  case 'set-resolution-query': {
68
- if (target.type !== 'textarea' || target.outcomeMode !== 'dynamic') {
77
+ if (!isDynamicTextareaField(target)) {
69
78
  return testCase;
70
79
  }
71
- expectedOutcome[index] = {
80
+ return commit({
72
81
  ...target,
73
82
  resolutionQuery: change.value,
74
- };
75
- return { ...testCase, expectedOutcome };
83
+ });
84
+ }
85
+ case 'set-evaluation-source-type': {
86
+ if (change.value === 'text') {
87
+ return commit({
88
+ ...target,
89
+ evaluationSource: { type: 'text' },
90
+ });
91
+ }
92
+ const extractorId = target.evaluationSource?.type === 'custom'
93
+ ? target.evaluationSource.extractorId
94
+ : (change.fallbackExtractorId ?? '');
95
+ return commit({
96
+ ...target,
97
+ evaluationSource: {
98
+ type: 'custom',
99
+ extractorId,
100
+ },
101
+ });
102
+ }
103
+ case 'set-evaluation-source-extractor': {
104
+ return commit({
105
+ ...target,
106
+ evaluationSource: {
107
+ type: 'custom',
108
+ extractorId: change.value,
109
+ },
110
+ });
76
111
  }
77
112
  }
78
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"test-case-mutations.js","sourceRoot":"","sources":["../../../src/lib/test-cases/test-case-mutations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n TestCase,\n type ExpectedOutcomeMode,\n} from '../../types/llm-test-runner';\nimport { EvaluationApproach } from '../evaluation/constants';\nimport { normalizeEvaluationParametersForField } from '../evaluation/field-evaluation-approach';\n\nexport type ExpectedOutcomeChange =\n | {\n index: number;\n operation: 'set-value';\n value: string;\n }\n | {\n index: number;\n operation: 'add-chip';\n value: string;\n }\n | {\n index: number;\n operation: 'remove-chip';\n value: string;\n }\n | {\n index: number;\n operation: 'set-evaluation-approach';\n value: EvaluationApproach;\n }\n | {\n index: number;\n operation: 'set-outcome-mode';\n value: ExpectedOutcomeMode;\n }\n | {\n index: number;\n operation: 'set-resolution-query';\n value: string;\n };\n\nexport function applyExpectedOutcomeChange(\n testCase: TestCase,\n change: ExpectedOutcomeChange,\n): TestCase {\n const { index } = change;\n const expectedOutcome = [...(testCase.expectedOutcome || [])];\n const target = expectedOutcome[index];\n\n if (!target) {\n return testCase;\n }\n\n switch (change.operation) {\n case 'set-value': {\n if (target.type === 'chips-input') {\n return testCase;\n }\n if (target.type === 'textarea' && target.outcomeMode === 'dynamic') {\n return testCase;\n }\n expectedOutcome[index] = {\n ...target,\n value: change.value,\n };\n return { ...testCase, expectedOutcome };\n }\n case 'add-chip': {\n if (target.type !== 'chips-input') {\n return testCase;\n }\n expectedOutcome[index] = {\n ...target,\n value: [...target.value, change.value],\n };\n return { ...testCase, expectedOutcome };\n }\n case 'remove-chip': {\n if (target.type !== 'chips-input') {\n return testCase;\n }\n expectedOutcome[index] = {\n ...target,\n value: target.value.filter(chip => chip !== change.value),\n };\n return { ...testCase, expectedOutcome };\n }\n case 'set-evaluation-approach':\n return updateExpectedOutcomeFieldApproach(testCase, index, change.value);\n case 'set-outcome-mode': {\n if (target.type !== 'textarea') {\n return testCase;\n }\n const mode = change.value;\n if (mode === 'static') {\n const { resolutionQuery: _, ...rest } = target;\n expectedOutcome[index] = {\n ...rest,\n outcomeMode: 'static',\n value: '',\n };\n } else {\n expectedOutcome[index] = {\n ...target,\n outcomeMode: 'dynamic',\n value: '',\n };\n }\n return { ...testCase, expectedOutcome };\n }\n case 'set-resolution-query': {\n if (target.type !== 'textarea' || target.outcomeMode !== 'dynamic') {\n return testCase;\n }\n expectedOutcome[index] = {\n ...target,\n resolutionQuery: change.value,\n };\n return { ...testCase, expectedOutcome };\n }\n }\n}\n\n/**\n * Updates the evaluation approach for a specific expected outcome field.\n * Select fields always use exact matching.\n */\nexport function updateExpectedOutcomeFieldApproach(\n testCase: TestCase,\n fieldIndex: number,\n approach: EvaluationApproach,\n): TestCase {\n const expectedOutcome = [...(testCase.expectedOutcome || [])];\n const target = expectedOutcome[fieldIndex];\n\n if (!target) {\n return testCase;\n }\n\n const currentEvaluationParameters = target.evaluationParameters;\n expectedOutcome[fieldIndex] = {\n ...target,\n evaluationParameters: normalizeEvaluationParametersForField(target.type, {\n ...currentEvaluationParameters,\n approach,\n }),\n };\n\n return {\n ...testCase,\n expectedOutcome,\n };\n}\n"]}
1
+ {"version":3,"file":"test-case-mutations.js","sourceRoot":"","sources":["../../../src/lib/test-cases/test-case-mutations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n TestCase,\n type ExpectedOutcomeField,\n type EvaluationSource,\n type ExpectedOutcomeMode,\n} from '../../types/llm-test-runner';\nimport { EvaluationApproach } from '../evaluation/constants';\nimport { normalizeEvaluationParametersForField } from '../evaluation/field-evaluation-approach';\n\nfunction isChipsInputField(\n field: ExpectedOutcomeField,\n): field is Extract<ExpectedOutcomeField, { type: 'chips-input' }> {\n return field.type === 'chips-input';\n}\n\nfunction isTextareaField(\n field: ExpectedOutcomeField,\n): field is Extract<ExpectedOutcomeField, { type: 'textarea' }> {\n return field.type === 'textarea';\n}\n\nfunction isDynamicTextareaField(\n field: ExpectedOutcomeField,\n): field is Extract<ExpectedOutcomeField, { type: 'textarea' }> {\n return isTextareaField(field) && field.outcomeMode === 'dynamic';\n}\n\n\nexport type ExpectedOutcomeChange =\n | {\n index: number;\n operation: 'set-value';\n value: string;\n }\n | {\n index: number;\n operation: 'add-chip';\n value: string;\n }\n | {\n index: number;\n operation: 'remove-chip';\n value: string;\n }\n | {\n index: number;\n operation: 'set-evaluation-approach';\n value: EvaluationApproach;\n }\n | {\n index: number;\n operation: 'set-outcome-mode';\n value: ExpectedOutcomeMode;\n }\n | {\n index: number;\n operation: 'set-resolution-query';\n value: string;\n }\n | {\n index: number;\n operation: 'set-evaluation-source-type';\n value: EvaluationSource['type'];\n fallbackExtractorId?: string;\n }\n | {\n index: number;\n operation: 'set-evaluation-source-extractor';\n value: string;\n };\n\nexport function applyExpectedOutcomeChange(\n testCase: TestCase,\n change: ExpectedOutcomeChange,\n): TestCase {\n const { index } = change;\n const expectedOutcome = [...(testCase.expectedOutcome || [])];\n const target = expectedOutcome[index];\n\n if (!target) {\n return testCase;\n }\n\n const commit = (updatedField: ExpectedOutcomeField): TestCase => {\n expectedOutcome[index] = updatedField;\n return { ...testCase, expectedOutcome };\n };\n\n switch (change.operation) {\n case 'set-value': {\n if (isChipsInputField(target)) {\n return testCase;\n }\n if (isDynamicTextareaField(target)) {\n return testCase;\n }\n return commit({\n ...target,\n value: change.value,\n });\n }\n case 'add-chip': {\n if (!isChipsInputField(target)) {\n return testCase;\n }\n return commit({\n ...target,\n value: [...target.value, change.value],\n });\n }\n case 'remove-chip': {\n if (!isChipsInputField(target)) {\n return testCase;\n }\n return commit({\n ...target,\n value: target.value.filter(chip => chip !== change.value),\n });\n }\n case 'set-evaluation-approach':\n return updateExpectedOutcomeFieldApproach(testCase, index, change.value);\n case 'set-outcome-mode': {\n if (!isTextareaField(target)) {\n return testCase;\n }\n const mode = change.value;\n if (mode === 'static') {\n const { resolutionQuery: _, ...rest } = target;\n return commit({\n ...rest,\n outcomeMode: 'static',\n value: '',\n });\n } else {\n return commit({\n ...target,\n outcomeMode: 'dynamic',\n value: '',\n });\n }\n }\n case 'set-resolution-query': {\n if (!isDynamicTextareaField(target)) {\n return testCase;\n }\n return commit({\n ...target,\n resolutionQuery: change.value,\n });\n }\n case 'set-evaluation-source-type': {\n if (change.value === 'text') {\n return commit({\n ...target,\n evaluationSource: { type: 'text' },\n });\n }\n\n const extractorId =\n target.evaluationSource?.type === 'custom'\n ? target.evaluationSource.extractorId\n : (change.fallbackExtractorId ?? '');\n return commit({\n ...target,\n evaluationSource: {\n type: 'custom',\n extractorId,\n },\n });\n }\n case 'set-evaluation-source-extractor': {\n return commit({\n ...target,\n evaluationSource: {\n type: 'custom',\n extractorId: change.value,\n },\n });\n }\n }\n}\n\n/**\n * Updates the evaluation approach for a specific expected outcome field.\n * Select fields always use exact matching.\n */\nexport function updateExpectedOutcomeFieldApproach(\n testCase: TestCase,\n fieldIndex: number,\n approach: EvaluationApproach,\n): TestCase {\n const expectedOutcome = [...(testCase.expectedOutcome || [])];\n const target = expectedOutcome[fieldIndex];\n\n if (!target) {\n return testCase;\n }\n\n const currentEvaluationParameters = target.evaluationParameters;\n expectedOutcome[fieldIndex] = {\n ...target,\n evaluationParameters: normalizeEvaluationParametersForField(target.type, {\n ...currentEvaluationParameters,\n approach,\n }),\n };\n\n return {\n ...testCase,\n expectedOutcome,\n };\n}\n"]}
@@ -6,6 +6,19 @@ const optionalPositiveInt = z.number().int().positive().optional();
6
6
  const optionalString = z.string().optional();
7
7
  const selectOptionsSchema = z.array(nonEmptyString).min(1);
8
8
  const optionalNumber = z.number().optional();
9
+ const textEvaluationSourceSchema = z.object({
10
+ type: z.literal('text'),
11
+ });
12
+ const customEvaluationSourceSchema = z.object({
13
+ type: z.literal('custom'),
14
+ extractorId: nonEmptyString,
15
+ });
16
+ export const evaluationSourceExtractorSchema = z.custom(value => typeof value === 'function', 'Extractor must be a function.');
17
+ export const evaluationSourceExtractorsSchema = z.record(z.string().min(1), evaluationSourceExtractorSchema);
18
+ export const evaluationSourceSchema = z.discriminatedUnion('type', [
19
+ textEvaluationSourceSchema,
20
+ customEvaluationSourceSchema,
21
+ ]);
9
22
  export const expectedOutcomeModeSchema = z.enum(['static', 'dynamic']);
10
23
  const evaluationParametersSchema = z.object({
11
24
  approach: z.enum(EvaluationApproach),
@@ -23,6 +36,7 @@ const selectEvaluationParametersSchema = evaluationParametersSchema.superRefine(
23
36
  const defaultExpectedOutcomeBaseSchema = z.object({
24
37
  label: nonEmptyString,
25
38
  placeholder: optionalString,
39
+ evaluationSource: evaluationSourceSchema.optional(),
26
40
  });
27
41
  const createDefaultExpectedOutcomeFieldSchemas = (baseSchema) => ({
28
42
  text: baseSchema.extend({
@@ -122,4 +136,29 @@ export function validateExpectedOutcomeArray(expectedOutcome) {
122
136
  throw new Error(`Invalid expectedOutcome: ${parsed.error.issues[0].message}`);
123
137
  }
124
138
  }
139
+ export function validateExpectedOutcomeArrayWithExtractors(expectedOutcome, allowedExtractorIds) {
140
+ const allowed = new Set(allowedExtractorIds);
141
+ const schema = expectedOutcomeArraySchema.superRefine((fields, ctx) => {
142
+ fields.forEach((field, index) => {
143
+ if (field.evaluationSource?.type !== 'custom') {
144
+ return;
145
+ }
146
+ if (allowed.has(field.evaluationSource.extractorId)) {
147
+ return;
148
+ }
149
+ ctx.addIssue({
150
+ code: 'custom',
151
+ path: [index, 'evaluationSource', 'extractorId'],
152
+ message: `Invalid expectedOutcome: Extractor "${field.evaluationSource.extractorId}" is not registered.`,
153
+ });
154
+ });
155
+ });
156
+ const parsed = schema.safeParse(expectedOutcome);
157
+ if (!parsed.success) {
158
+ throw new Error(parsed.error.issues[0].message);
159
+ }
160
+ }
161
+ export function getExtractorIds(extractors) {
162
+ return Object.keys(extractors || {});
163
+ }
125
164
  //# sourceMappingURL=expected-outcome.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"expected-outcome.js","sourceRoot":"","sources":["../../src/schemas/expected-outcome.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { EvaluationApproach } from '../lib/evaluation/constants';\nimport { isApproachAllowedForFieldType } from '../lib/evaluation/field-evaluation-approach';\n\nconst nonEmptyString = z.string().trim().min(1);\nconst optionalPositiveInt = z.number().int().positive().optional();\nconst optionalString = z.string().optional();\nconst selectOptionsSchema = z.array(nonEmptyString).min(1);\nconst optionalNumber = z.number().optional();\n\nexport const expectedOutcomeModeSchema = z.enum(['static', 'dynamic']);\nexport type ExpectedOutcomeMode = z.infer<typeof expectedOutcomeModeSchema>;\n\nconst evaluationParametersSchema = z.object({\n approach: z.enum(EvaluationApproach),\n threshold: optionalNumber,\n});\n\nconst selectEvaluationParametersSchema = evaluationParametersSchema.superRefine(\n (parameters, ctx) => {\n if (!isApproachAllowedForFieldType('select', parameters.approach)) {\n ctx.addIssue({\n code: 'custom',\n path: ['approach'],\n message: `select fields only support \"${EvaluationApproach.EXACT}\" evaluation approach.`,\n });\n }\n },\n);\n\nconst defaultExpectedOutcomeBaseSchema = z.object({\n label: nonEmptyString,\n placeholder: optionalString,\n});\n\nconst createDefaultExpectedOutcomeFieldSchemas = (\n baseSchema: typeof defaultExpectedOutcomeBaseSchema,\n) => ({\n text: baseSchema.extend({\n type: z.literal('text'),\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n textarea: baseSchema.extend({\n type: z.literal('textarea'),\n rows: optionalPositiveInt,\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n chipsInput: baseSchema.extend({\n type: z.literal('chips-input'),\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n select: baseSchema.extend({\n type: z.literal('select'),\n options: selectOptionsSchema,\n evaluationParameters: selectEvaluationParametersSchema.optional(),\n }),\n});\n\nfunction hasDuplicateChips(values: string[]): boolean {\n const seen = new Set<string>();\n for (const value of values) {\n const normalized = value.trim().toLowerCase();\n if (seen.has(normalized)) {\n return true;\n }\n seen.add(normalized);\n }\n return false;\n}\n\nconst defaultFieldDefinitions =\n createDefaultExpectedOutcomeFieldSchemas(defaultExpectedOutcomeBaseSchema);\n\nexport const expectedOutcomeSchemaFieldSchema = z.discriminatedUnion('type', [\n defaultFieldDefinitions.text,\n defaultFieldDefinitions.textarea,\n defaultFieldDefinitions.chipsInput,\n defaultFieldDefinitions.select,\n]);\n\nexport const expectedOutcomeSchemaSchema = z\n .array(expectedOutcomeSchemaFieldSchema)\n .min(1);\n\nexport const expectedOutcomeFieldSchema = z.discriminatedUnion('type', [\n defaultFieldDefinitions.text.extend({\n value: z.string(),\n }),\n defaultFieldDefinitions.textarea\n .extend({\n value: z.string(),\n outcomeMode: expectedOutcomeModeSchema.default('static'),\n resolutionQuery: z.string().optional(),\n })\n .superRefine((field, ctx) => {\n if (\n field.outcomeMode === 'dynamic' &&\n (!field.resolutionQuery || field.resolutionQuery.trim().length === 0)\n ) {\n ctx.addIssue({\n code: 'custom',\n path: ['resolutionQuery'],\n message: 'resolutionQuery is required when outcomeMode is dynamic.',\n });\n }\n }),\n defaultFieldDefinitions.chipsInput.extend({\n value: z.array(z.string()).superRefine((values, ctx) => {\n if (hasDuplicateChips(values)) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'chips-input values must be unique (case-insensitive, trimmed).',\n });\n }\n }),\n }),\n defaultFieldDefinitions.select\n .extend({\n value: z.string(),\n })\n .superRefine((field, ctx) => {\n if (!field.options.includes(field.value)) {\n ctx.addIssue({\n code: 'custom',\n path: ['value'],\n message: 'select value must be one of the provided options.',\n });\n }\n }),\n]);\n\nexport const expectedOutcomeArraySchema = z.array(expectedOutcomeFieldSchema).min(1);\n\nexport type ExpectedOutcomeSchemaField = z.infer<\n typeof expectedOutcomeSchemaFieldSchema\n>;\nexport type ExpectedOutcomeSchema = z.infer<typeof expectedOutcomeSchemaSchema>;\nexport type ExpectedOutcomeField = z.input<typeof expectedOutcomeFieldSchema>;\nexport type ExpectedOutcomeFieldType = ExpectedOutcomeField['type'];\nexport type ExpectedOutcomeBase = z.infer<typeof defaultExpectedOutcomeBaseSchema>;\n\nexport type TextExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'text' }\n>;\nexport type TextareaExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'textarea' }\n>;\nexport type ChipsExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'chips-input' }\n>;\nexport type SelectExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'select' }\n>;\n\nexport type TextExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'text' }\n>;\nexport type TextareaExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'textarea' }\n>;\nexport type ChipsExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'chips-input' }\n>;\nexport type SelectExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'select' }\n>;\n\nexport function validateExpectedOutcomeSchema(\n schema: unknown,\n): asserts schema is ExpectedOutcomeSchema {\n const parsed = expectedOutcomeSchemaSchema.safeParse(schema);\n if (!parsed.success) {\n throw new Error(\n `Invalid expectedOutcomeSchema: ${parsed.error.issues[0].message}`,\n );\n }\n}\n\nexport function validateExpectedOutcomeArray(\n expectedOutcome: unknown,\n): asserts expectedOutcome is ExpectedOutcomeField[] {\n const parsed = expectedOutcomeArraySchema.safeParse(expectedOutcome);\n if (!parsed.success) {\n throw new Error(`Invalid expectedOutcome: ${parsed.error.issues[0].message}`);\n }\n}\n"]}
1
+ {"version":3,"file":"expected-outcome.js","sourceRoot":"","sources":["../../src/schemas/expected-outcome.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { EvaluationApproach } from '../lib/evaluation/constants';\nimport { isApproachAllowedForFieldType } from '../lib/evaluation/field-evaluation-approach';\nimport type { ModelResponsePayload } from './model-response';\n\nconst nonEmptyString = z.string().trim().min(1);\nconst optionalPositiveInt = z.number().int().positive().optional();\nconst optionalString = z.string().optional();\nconst selectOptionsSchema = z.array(nonEmptyString).min(1);\nconst optionalNumber = z.number().optional();\nconst textEvaluationSourceSchema = z.object({\n type: z.literal('text'),\n});\nconst customEvaluationSourceSchema = z.object({\n type: z.literal('custom'),\n extractorId: nonEmptyString,\n});\n\nexport const evaluationSourceExtractorSchema = z.custom<\n (payload: ModelResponsePayload) => string | Promise<string>\n>(\n value => typeof value === 'function',\n 'Extractor must be a function.',\n);\n\nexport const evaluationSourceExtractorsSchema = z.record(\n z.string().min(1),\n evaluationSourceExtractorSchema,\n);\n\nexport const evaluationSourceSchema = z.discriminatedUnion('type', [\n textEvaluationSourceSchema,\n customEvaluationSourceSchema,\n]);\n\nexport const expectedOutcomeModeSchema = z.enum(['static', 'dynamic']);\nexport type ExpectedOutcomeMode = z.infer<typeof expectedOutcomeModeSchema>;\nexport type EvaluationSource = z.infer<typeof evaluationSourceSchema>;\nexport type EvaluationSourceExtractor = z.infer<\n typeof evaluationSourceExtractorSchema\n>;\nexport type EvaluationSourceExtractors = z.infer<\n typeof evaluationSourceExtractorsSchema\n>;\n\nconst evaluationParametersSchema = z.object({\n approach: z.enum(EvaluationApproach),\n threshold: optionalNumber,\n});\n\nconst selectEvaluationParametersSchema = evaluationParametersSchema.superRefine(\n (parameters, ctx) => {\n if (!isApproachAllowedForFieldType('select', parameters.approach)) {\n ctx.addIssue({\n code: 'custom',\n path: ['approach'],\n message: `select fields only support \"${EvaluationApproach.EXACT}\" evaluation approach.`,\n });\n }\n },\n);\n\nconst defaultExpectedOutcomeBaseSchema = z.object({\n label: nonEmptyString,\n placeholder: optionalString,\n evaluationSource: evaluationSourceSchema.optional(),\n});\n\nconst createDefaultExpectedOutcomeFieldSchemas = (\n baseSchema: typeof defaultExpectedOutcomeBaseSchema,\n) => ({\n text: baseSchema.extend({\n type: z.literal('text'),\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n textarea: baseSchema.extend({\n type: z.literal('textarea'),\n rows: optionalPositiveInt,\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n chipsInput: baseSchema.extend({\n type: z.literal('chips-input'),\n evaluationParameters: evaluationParametersSchema.optional(),\n }),\n select: baseSchema.extend({\n type: z.literal('select'),\n options: selectOptionsSchema,\n evaluationParameters: selectEvaluationParametersSchema.optional(),\n }),\n});\n\nfunction hasDuplicateChips(values: string[]): boolean {\n const seen = new Set<string>();\n for (const value of values) {\n const normalized = value.trim().toLowerCase();\n if (seen.has(normalized)) {\n return true;\n }\n seen.add(normalized);\n }\n return false;\n}\n\nconst defaultFieldDefinitions =\n createDefaultExpectedOutcomeFieldSchemas(defaultExpectedOutcomeBaseSchema);\n\nexport const expectedOutcomeSchemaFieldSchema = z.discriminatedUnion('type', [\n defaultFieldDefinitions.text,\n defaultFieldDefinitions.textarea,\n defaultFieldDefinitions.chipsInput,\n defaultFieldDefinitions.select,\n]);\n\nexport const expectedOutcomeSchemaSchema = z\n .array(expectedOutcomeSchemaFieldSchema)\n .min(1);\n\nexport const expectedOutcomeFieldSchema = z.discriminatedUnion('type', [\n defaultFieldDefinitions.text.extend({\n value: z.string(),\n }),\n defaultFieldDefinitions.textarea\n .extend({\n value: z.string(),\n outcomeMode: expectedOutcomeModeSchema.default('static'),\n resolutionQuery: z.string().optional(),\n })\n .superRefine((field, ctx) => {\n if (\n field.outcomeMode === 'dynamic' &&\n (!field.resolutionQuery || field.resolutionQuery.trim().length === 0)\n ) {\n ctx.addIssue({\n code: 'custom',\n path: ['resolutionQuery'],\n message: 'resolutionQuery is required when outcomeMode is dynamic.',\n });\n }\n }),\n defaultFieldDefinitions.chipsInput.extend({\n value: z.array(z.string()).superRefine((values, ctx) => {\n if (hasDuplicateChips(values)) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'chips-input values must be unique (case-insensitive, trimmed).',\n });\n }\n }),\n }),\n defaultFieldDefinitions.select\n .extend({\n value: z.string(),\n })\n .superRefine((field, ctx) => {\n if (!field.options.includes(field.value)) {\n ctx.addIssue({\n code: 'custom',\n path: ['value'],\n message: 'select value must be one of the provided options.',\n });\n }\n }),\n]);\n\nexport const expectedOutcomeArraySchema = z.array(expectedOutcomeFieldSchema).min(1);\n\nexport type ExpectedOutcomeSchemaField = z.infer<\n typeof expectedOutcomeSchemaFieldSchema\n>;\nexport type ExpectedOutcomeSchema = z.infer<typeof expectedOutcomeSchemaSchema>;\nexport type ExpectedOutcomeField = z.input<typeof expectedOutcomeFieldSchema>;\nexport type ExpectedOutcomeFieldType = ExpectedOutcomeField['type'];\nexport type ExpectedOutcomeBase = z.infer<typeof defaultExpectedOutcomeBaseSchema>;\n\nexport type TextExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'text' }\n>;\nexport type TextareaExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'textarea' }\n>;\nexport type ChipsExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'chips-input' }\n>;\nexport type SelectExpectedOutcomeSchemaField = Extract<\n ExpectedOutcomeSchemaField,\n { type: 'select' }\n>;\n\nexport type TextExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'text' }\n>;\nexport type TextareaExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'textarea' }\n>;\nexport type ChipsExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'chips-input' }\n>;\nexport type SelectExpectedOutcomeField = Extract<\n ExpectedOutcomeField,\n { type: 'select' }\n>;\n\nexport function validateExpectedOutcomeSchema(\n schema: unknown,\n): asserts schema is ExpectedOutcomeSchema {\n const parsed = expectedOutcomeSchemaSchema.safeParse(schema);\n if (!parsed.success) {\n throw new Error(\n `Invalid expectedOutcomeSchema: ${parsed.error.issues[0].message}`,\n );\n }\n}\n\nexport function validateExpectedOutcomeArray(\n expectedOutcome: unknown,\n): asserts expectedOutcome is ExpectedOutcomeField[] {\n const parsed = expectedOutcomeArraySchema.safeParse(expectedOutcome);\n if (!parsed.success) {\n throw new Error(`Invalid expectedOutcome: ${parsed.error.issues[0].message}`);\n }\n}\n\nexport function validateExpectedOutcomeArrayWithExtractors(\n expectedOutcome: unknown,\n allowedExtractorIds: string[],\n): asserts expectedOutcome is ExpectedOutcomeField[] {\n const allowed = new Set(allowedExtractorIds);\n const schema = expectedOutcomeArraySchema.superRefine((fields, ctx) => {\n fields.forEach((field, index) => {\n if (field.evaluationSource?.type !== 'custom') {\n return;\n }\n\n if (allowed.has(field.evaluationSource.extractorId)) {\n return;\n }\n\n ctx.addIssue({\n code: 'custom',\n path: [index, 'evaluationSource', 'extractorId'],\n message: `Invalid expectedOutcome: Extractor \"${field.evaluationSource.extractorId}\" is not registered.`,\n });\n });\n });\n\n const parsed = schema.safeParse(expectedOutcome);\n if (!parsed.success) {\n throw new Error(parsed.error.issues[0].message);\n }\n}\n\nexport function getExtractorIds(\n extractors?: EvaluationSourceExtractors,\n): string[] {\n return Object.keys(extractors || {});\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ export const modelResponseMetadataSchema = z.record(z.string(), z.unknown());
3
+ export const modelResponsePayloadSchema = z.object({
4
+ text: z.string().optional(),
5
+ metadata: modelResponseMetadataSchema.optional(),
6
+ });
7
+ //# sourceMappingURL=model-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-response.js","sourceRoot":"","sources":["../../src/schemas/model-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\n\nexport const modelResponseMetadataSchema = z.record(z.string(), z.unknown());\n\nexport const modelResponsePayloadSchema = z.object({\n text: z.string().optional(),\n metadata: modelResponseMetadataSchema.optional(),\n});\n\nexport type ModelResponsePayload = z.infer<typeof modelResponsePayloadSchema>;\n"]}
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { expectedOutcomeArraySchema } from "./expected-outcome";
3
+ import { modelResponsePayloadSchema } from "./model-response";
3
4
  export const testCaseChatHistorySchema = z.object({
4
5
  enabled: z.boolean(),
5
6
  value: z.string(),
@@ -15,8 +16,8 @@ export const testCaseSchema = z.object({
15
16
  id: z.string(),
16
17
  question: z.string(),
17
18
  expectedOutcome: expectedOutcomeArraySchema,
19
+ output: modelResponsePayloadSchema.optional(),
18
20
  chatHistory: testCaseChatHistorySchema,
19
- output: z.string().optional(),
20
21
  isRunning: z.boolean().optional(),
21
22
  error: z.string().optional(),
22
23
  evaluationResult: z.custom().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"test-case.js","sourceRoot":"","sources":["../../src/schemas/test-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,eAAe,EAAE,0BAA0B;IAC3C,WAAW,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,eAAe,EAAE,0BAA0B;IAC3C,WAAW,EAAE,yBAAyB;IACtC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAoB,CAAC,QAAQ,EAAE;IACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAMH,MAAM,UAAU,qBAAqB,CACnC,IAAa;IAEb,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,IAAa;IAEb,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,OAAO,GACX,UAAU,CAAC,IAAI,KAAK,cAAc;YAChC,CAAC,CAAC,gDAAgD;YAClD,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC","sourcesContent":["import { z } from 'zod';\nimport type { EvaluationResult } from '../lib/evaluation/types';\nimport { expectedOutcomeArraySchema } from './expected-outcome';\n\nexport const testCaseChatHistorySchema = z.object({\n enabled: z.boolean(),\n value: z.string(),\n});\n\nexport const testCaseInputSchema = z.object({\n id: z.string(),\n question: z.string(),\n expectedOutcome: expectedOutcomeArraySchema,\n chatHistory: testCaseChatHistorySchema.optional(),\n});\n\nexport const testCaseInputArraySchema = z.array(testCaseInputSchema);\n\nexport const testCaseSchema = z.object({\n id: z.string(),\n question: z.string(),\n expectedOutcome: expectedOutcomeArraySchema,\n chatHistory: testCaseChatHistorySchema,\n output: z.string().optional(),\n isRunning: z.boolean().optional(),\n error: z.string().optional(),\n evaluationResult: z.custom<EvaluationResult>().optional(),\n responseTime: z.number().optional(),\n});\n\nexport type TestCaseChatHistory = z.infer<typeof testCaseChatHistorySchema>;\nexport type TestCaseInput = z.input<typeof testCaseInputSchema>;\nexport type TestCase = z.input<typeof testCaseSchema>;\n\nexport function validateTestCaseInput(\n data: unknown,\n): asserts data is TestCaseInput {\n const parsed = testCaseInputSchema.safeParse(data);\n if (!parsed.success) {\n throw new Error(`Invalid test case input: ${parsed.error.issues[0].message}`);\n }\n}\n\nexport function validateTestCaseInputArray(\n data: unknown,\n): asserts data is TestCaseInput[] {\n const parsed = testCaseInputArraySchema.safeParse(data);\n if (!parsed.success) {\n const firstIssue = parsed.error.issues[0];\n const message =\n firstIssue.code === 'invalid_type'\n ? 'Invalid JSON structure. Expected a JSON array.'\n : firstIssue.message;\n throw new Error(message);\n }\n}\n"]}
1
+ {"version":3,"file":"test-case.js","sourceRoot":"","sources":["../../src/schemas/test-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,eAAe,EAAE,0BAA0B;IAC3C,WAAW,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,eAAe,EAAE,0BAA0B;IAC3C,MAAM,EAAE,0BAA0B,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,yBAAyB;IACtC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAoB,CAAC,QAAQ,EAAE;IACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAMH,MAAM,UAAU,qBAAqB,CACnC,IAAa;IAEb,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,IAAa;IAEb,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,OAAO,GACX,UAAU,CAAC,IAAI,KAAK,cAAc;YAChC,CAAC,CAAC,gDAAgD;YAClD,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC","sourcesContent":["import { z } from 'zod';\nimport type { EvaluationResult } from '../lib/evaluation/types';\nimport { expectedOutcomeArraySchema } from './expected-outcome';\nimport { modelResponsePayloadSchema } from './model-response';\n\nexport const testCaseChatHistorySchema = z.object({\n enabled: z.boolean(),\n value: z.string(),\n});\n\nexport const testCaseInputSchema = z.object({\n id: z.string(),\n question: z.string(),\n expectedOutcome: expectedOutcomeArraySchema,\n chatHistory: testCaseChatHistorySchema.optional(),\n});\n\nexport const testCaseInputArraySchema = z.array(testCaseInputSchema);\n\nexport const testCaseSchema = z.object({\n id: z.string(),\n question: z.string(),\n expectedOutcome: expectedOutcomeArraySchema,\n output: modelResponsePayloadSchema.optional(),\n chatHistory: testCaseChatHistorySchema,\n isRunning: z.boolean().optional(),\n error: z.string().optional(),\n evaluationResult: z.custom<EvaluationResult>().optional(),\n responseTime: z.number().optional(),\n});\n\nexport type TestCaseChatHistory = z.infer<typeof testCaseChatHistorySchema>;\nexport type TestCaseInput = z.input<typeof testCaseInputSchema>;\nexport type TestCase = z.input<typeof testCaseSchema>;\n\nexport function validateTestCaseInput(\n data: unknown,\n): asserts data is TestCaseInput {\n const parsed = testCaseInputSchema.safeParse(data);\n if (!parsed.success) {\n throw new Error(`Invalid test case input: ${parsed.error.issues[0].message}`);\n }\n}\n\nexport function validateTestCaseInputArray(\n data: unknown,\n): asserts data is TestCaseInput[] {\n const parsed = testCaseInputArraySchema.safeParse(data);\n if (!parsed.success) {\n const firstIssue = parsed.error.issues[0];\n const message =\n firstIssue.code === 'invalid_type'\n ? 'Invalid JSON structure. Expected a JSON array.'\n : firstIssue.message;\n throw new Error(message);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"expected-outcome.js","sourceRoot":"","sources":["../../src/types/expected-outcome.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n ExpectedOutcomeMode,\n ExpectedOutcomeSchemaField,\n ExpectedOutcomeSchema,\n ExpectedOutcomeField,\n ExpectedOutcomeFieldType,\n ExpectedOutcomeBase,\n TextExpectedOutcomeSchemaField,\n TextareaExpectedOutcomeSchemaField,\n ChipsExpectedOutcomeSchemaField,\n SelectExpectedOutcomeSchemaField,\n TextExpectedOutcomeField,\n TextareaExpectedOutcomeField,\n ChipsExpectedOutcomeField,\n SelectExpectedOutcomeField,\n} from '../schemas/expected-outcome';\n"]}
1
+ {"version":3,"file":"expected-outcome.js","sourceRoot":"","sources":["../../src/types/expected-outcome.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n EvaluationSource,\n EvaluationSourceExtractor,\n EvaluationSourceExtractors,\n ExpectedOutcomeMode,\n ExpectedOutcomeSchemaField,\n ExpectedOutcomeSchema,\n ExpectedOutcomeField,\n ExpectedOutcomeFieldType,\n ExpectedOutcomeBase,\n TextExpectedOutcomeSchemaField,\n TextareaExpectedOutcomeSchemaField,\n ChipsExpectedOutcomeSchemaField,\n SelectExpectedOutcomeSchemaField,\n TextExpectedOutcomeField,\n TextareaExpectedOutcomeField,\n ChipsExpectedOutcomeField,\n SelectExpectedOutcomeField,\n} from '../schemas/expected-outcome';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"llm-test-runner.js","sourceRoot":"","sources":["../../src/types/llm-test-runner.ts"],"names":[],"mappings":"","sourcesContent":["import type { TestCase } from './test-case';\n\nexport type {\n ExpectedOutcomeMode,\n ExpectedOutcomeFieldType,\n ExpectedOutcomeBase,\n ExpectedOutcomeSchema,\n ExpectedOutcomeSchemaField,\n ExpectedOutcomeField,\n TextExpectedOutcomeSchemaField,\n TextareaExpectedOutcomeSchemaField,\n ChipsExpectedOutcomeSchemaField,\n SelectExpectedOutcomeSchemaField,\n TextExpectedOutcomeField,\n TextareaExpectedOutcomeField,\n ChipsExpectedOutcomeField,\n SelectExpectedOutcomeField,\n} from './expected-outcome';\nexport type {\n TestCaseChatHistory,\n TestCase,\n TestCaseInput,\n} from './test-case';\n\nexport interface LLMRequestPayload {\n prompt: string;\n chatHistory?: string;\n resolve: (result: string) => void;\n reject: (err: Error | unknown) => void;\n}\n\nexport interface SavePayload {\n timestamp: string;\n testCases: TestCase[];\n}\n"]}
1
+ {"version":3,"file":"llm-test-runner.js","sourceRoot":"","sources":["../../src/types/llm-test-runner.ts"],"names":[],"mappings":"","sourcesContent":["import type { TestCase } from './test-case';\nimport type { ModelResponsePayload } from '../schemas/model-response';\n\nexport type {\n EvaluationSource,\n EvaluationSourceExtractor,\n EvaluationSourceExtractors,\n ExpectedOutcomeMode,\n ExpectedOutcomeFieldType,\n ExpectedOutcomeBase,\n ExpectedOutcomeSchema,\n ExpectedOutcomeSchemaField,\n ExpectedOutcomeField,\n TextExpectedOutcomeSchemaField,\n TextareaExpectedOutcomeSchemaField,\n ChipsExpectedOutcomeSchemaField,\n SelectExpectedOutcomeSchemaField,\n TextExpectedOutcomeField,\n TextareaExpectedOutcomeField,\n ChipsExpectedOutcomeField,\n SelectExpectedOutcomeField,\n} from './expected-outcome';\nexport type {\n ModelResponsePayload,\n} from '../schemas/model-response';\nexport type {\n TestCaseChatHistory,\n TestCase,\n TestCaseInput,\n} from './test-case';\n\nexport interface LLMRequestPayload {\n prompt: string;\n resolve: (result: ModelResponsePayload) => void;\n chatHistory?: string;\n reject: (err: Error | unknown) => void;\n}\n\nexport interface SavePayload {\n timestamp: string;\n testCases: TestCase[];\n}\n"]}
@@ -1,2 +1,2 @@
1
- import{A as o,d as s}from"./p-D2qDAxFN.js";const t=o;const p=s;export{t as AppTextarea,p as defineCustomElement};
1
+ import{A as o,d as s}from"./p-D6BL2E3J.js";const t=o;const p=s;export{t as AppTextarea,p as defineCustomElement};
2
2
  //# sourceMappingURL=app-textarea.js.map
@@ -1,2 +1,2 @@
1
- import{C as o,d as s}from"./p-Bx2jqguC.js";const t=o;const p=s;export{t as ChatHistory,p as defineCustomElement};
1
+ import{C as o,d as s}from"./p-kmtfMXcQ.js";const t=o;const c=s;export{t as ChatHistory,c as defineCustomElement};
2
2
  //# sourceMappingURL=chat-history.js.map
@@ -1,2 +1,2 @@
1
- import{G as t}from"./p-D9BrlHdP.js";export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-D9BrlHdP.js";export{L as LLMTestRunner}from"./p-B87Lt3z4.js";class e{sdk;constructor(s){this.sdk=new t({apiKey:s})}async invoke(s){const t=await this.sdk.models.generateContent({model:"gemini-3-flash-preview",contents:s});return t.text}}function n(){window.env={API_KEY:""};window.GeminiAdapter=e}const o=n||(()=>{});const i=o;i();
1
+ import{G as t}from"./p-D9BrlHdP.js";export{g as getAssetPath,r as render,s as setAssetPath,a as setNonce,b as setPlatformOptions}from"./p-D9BrlHdP.js";export{L as LLMTestRunner}from"./p-D3eincg_.js";class e{sdk;constructor(s){this.sdk=new t({apiKey:s})}async invoke(s){const t=await this.sdk.models.generateContent({model:"gemini-3-flash-preview",contents:s});return t.text}}function n(){window.env={API_KEY:""};window.GeminiAdapter=e}const o=n||(()=>{});const i=o;i();
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import{L as o,d as s}from"./p-B87Lt3z4.js";const t=o;const p=s;export{t as LlmTestRunner,p as defineCustomElement};
1
+ import{L as o,d as s}from"./p-D3eincg_.js";const t=o;const c=s;export{t as LlmTestRunner,c as defineCustomElement};
2
2
  //# sourceMappingURL=llm-test-runner.js.map