llm-testrunner-components 1.0.6 → 1.0.9

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 (266) hide show
  1. package/README.md +101 -100
  2. package/dist/cjs/app-chips_5.cjs.entry.js +158 -0
  3. package/dist/cjs/app-chips_5.cjs.entry.js.map +1 -0
  4. package/dist/cjs/app-globals-Chb-oJtg.js +34 -0
  5. package/dist/cjs/app-globals-Chb-oJtg.js.map +1 -0
  6. package/dist/cjs/index-By1scwl6.js +25542 -0
  7. package/dist/cjs/index-By1scwl6.js.map +1 -0
  8. package/dist/cjs/index-CgmLNwZO.js +21460 -0
  9. package/dist/cjs/index-CgmLNwZO.js.map +1 -0
  10. package/dist/cjs/index.cjs.js +5 -483
  11. package/dist/cjs/index.cjs.js.map +1 -1
  12. package/dist/cjs/llm-testrunner.cjs.js +6 -4
  13. package/dist/cjs/llm-testrunner.cjs.js.map +1 -1
  14. package/dist/cjs/loader.cjs.js +5 -3
  15. package/dist/collection/collection-manifest.json +8 -3
  16. package/dist/collection/components/error-message/error-message.css +34 -0
  17. package/dist/collection/components/error-message/error-message.js +2 -2
  18. package/dist/collection/components/error-message/error-message.js.map +1 -1
  19. package/dist/collection/components/llm-test-runner/header/llm-test-runner-header.css +60 -0
  20. package/dist/collection/components/llm-test-runner/header/llm-test-runner-header.js +18 -0
  21. package/dist/collection/components/llm-test-runner/header/llm-test-runner-header.js.map +1 -0
  22. package/dist/collection/components/llm-test-runner/llm-test-runner.css +17 -657
  23. package/dist/collection/components/llm-test-runner/llm-test-runner.import-export.test.js +253 -0
  24. package/dist/collection/components/llm-test-runner/llm-test-runner.import-export.test.js.map +1 -0
  25. package/dist/collection/components/llm-test-runner/llm-test-runner.js +191 -200
  26. package/dist/collection/components/llm-test-runner/llm-test-runner.js.map +1 -1
  27. package/dist/collection/components/llm-test-runner/test-cases/actions/row-actions.css +28 -0
  28. package/dist/collection/components/llm-test-runner/test-cases/actions/row-actions.js +6 -0
  29. package/dist/collection/components/llm-test-runner/test-cases/actions/row-actions.js.map +1 -0
  30. package/dist/collection/components/llm-test-runner/test-cases/evaluation/evaluation-summary.css +67 -0
  31. package/dist/collection/components/llm-test-runner/test-cases/evaluation/evaluation-summary.js +5 -0
  32. package/dist/collection/components/llm-test-runner/test-cases/evaluation/evaluation-summary.js.map +1 -0
  33. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.css +42 -0
  34. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js +39 -0
  35. package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js.map +1 -0
  36. package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.css +39 -0
  37. package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js +7 -0
  38. package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js.map +1 -0
  39. package/dist/collection/components/llm-test-runner/test-cases/output/response-output.css +51 -0
  40. package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js +5 -0
  41. package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js.map +1 -0
  42. package/dist/collection/global/env.js +3 -1
  43. package/dist/collection/global/env.js.map +1 -1
  44. package/dist/collection/index.js.map +1 -1
  45. package/dist/collection/lib/evaluation/constants.js +14 -0
  46. package/dist/collection/lib/evaluation/constants.js.map +1 -0
  47. package/dist/collection/lib/evaluation/evaluation-engine.js +45 -45
  48. package/dist/collection/lib/evaluation/evaluation-engine.js.map +1 -1
  49. package/dist/collection/lib/evaluation/evaluation-service.js +33 -0
  50. package/dist/collection/lib/evaluation/evaluation-service.js.map +1 -0
  51. package/dist/collection/lib/evaluation/evaluators/bleu/bleu-evaluator.js +116 -0
  52. package/dist/collection/lib/evaluation/evaluators/bleu/bleu-evaluator.js.map +1 -0
  53. package/dist/collection/lib/evaluation/evaluators/bleu/tests/bleu.test.js +352 -0
  54. package/dist/collection/lib/evaluation/evaluators/bleu/tests/bleu.test.js.map +1 -0
  55. package/dist/collection/lib/evaluation/evaluators/exact/exact.js +44 -0
  56. package/dist/collection/lib/evaluation/evaluators/exact/exact.js.map +1 -0
  57. package/dist/collection/lib/evaluation/evaluators/rouge1-evaluator.js +88 -0
  58. package/dist/collection/lib/evaluation/evaluators/rouge1-evaluator.js.map +1 -0
  59. package/dist/collection/lib/evaluation/evaluators/rougeL-evaluator.js +82 -0
  60. package/dist/collection/lib/evaluation/evaluators/rougeL-evaluator.js.map +1 -0
  61. package/dist/collection/lib/evaluation/evaluators/rougeL-evaluator.test.js +326 -0
  62. package/dist/collection/lib/evaluation/evaluators/rougeL-evaluator.test.js.map +1 -0
  63. package/dist/collection/lib/evaluation/evaluators/semantic/SemanticEvaluator.js +69 -0
  64. package/dist/collection/lib/evaluation/evaluators/semantic/SemanticEvaluator.js.map +1 -0
  65. package/dist/collection/lib/evaluation/evaluators/semantic/evaluate-keywords.js +56 -0
  66. package/dist/collection/lib/evaluation/evaluators/semantic/evaluate-keywords.js.map +1 -0
  67. package/dist/collection/lib/evaluation/evaluators/semantic/index.js +7 -0
  68. package/dist/collection/lib/evaluation/evaluators/semantic/index.js.map +1 -0
  69. package/dist/collection/lib/evaluation/evaluators/semantic/model-loader.js +19 -0
  70. package/dist/collection/lib/evaluation/evaluators/semantic/model-loader.js.map +1 -0
  71. package/dist/collection/lib/evaluation/evaluators/semantic/similarity-utils.js +16 -0
  72. package/dist/collection/lib/evaluation/evaluators/semantic/similarity-utils.js.map +1 -0
  73. package/dist/collection/lib/evaluation/evaluators/semantic/tests/evaluate-keywords.test.js +65 -0
  74. package/dist/collection/lib/evaluation/evaluators/semantic/tests/evaluate-keywords.test.js.map +1 -0
  75. package/dist/collection/lib/evaluation/evaluators/semantic/text-utils.js +5 -0
  76. package/dist/collection/lib/evaluation/evaluators/semantic/text-utils.js.map +1 -0
  77. package/dist/collection/lib/evaluation/index.js.map +1 -1
  78. package/dist/collection/lib/evaluation/rouge1-evaluator.test.js +117 -0
  79. package/dist/collection/lib/evaluation/rouge1-evaluator.test.js.map +1 -0
  80. package/dist/collection/lib/evaluation/types.js.map +1 -1
  81. package/dist/collection/lib/file/file-download.js +18 -0
  82. package/dist/collection/lib/file/file-download.js.map +1 -0
  83. package/dist/collection/lib/file/file-reader.js +14 -0
  84. package/dist/collection/lib/file/file-reader.js.map +1 -0
  85. package/dist/collection/lib/form/components/app-chips.css +97 -0
  86. package/dist/collection/lib/form/components/app-chips.js +155 -0
  87. package/dist/collection/lib/form/components/app-chips.js.map +1 -0
  88. package/dist/collection/lib/form/components/app-select.css +28 -0
  89. package/dist/collection/lib/form/components/app-select.js +101 -0
  90. package/dist/collection/lib/form/components/app-select.js.map +1 -0
  91. package/dist/collection/lib/form/components/app-textarea.css +38 -0
  92. package/dist/collection/lib/form/components/app-textarea.js +126 -0
  93. package/dist/collection/lib/form/components/app-textarea.js.map +1 -0
  94. package/dist/collection/lib/form/form-builder.js +171 -0
  95. package/dist/collection/lib/form/form-builder.js.map +1 -0
  96. package/dist/collection/lib/form/schema/base-input-field-config.js +2 -0
  97. package/dist/collection/lib/form/schema/base-input-field-config.js.map +1 -0
  98. package/dist/collection/lib/form/schema/form-control-config.js +2 -0
  99. package/dist/collection/lib/form/schema/form-control-config.js.map +1 -0
  100. package/dist/collection/lib/form/schema/index.js +8 -0
  101. package/dist/collection/lib/form/schema/index.js.map +1 -0
  102. package/dist/collection/lib/import-export/test-results-csv.js +65 -0
  103. package/dist/collection/lib/import-export/test-results-csv.js.map +1 -0
  104. package/dist/collection/lib/import-export/test-suite-exporter.js +15 -0
  105. package/dist/collection/lib/import-export/test-suite-exporter.js.map +1 -0
  106. package/dist/collection/lib/import-export/test-suite-importer.js +44 -0
  107. package/dist/collection/lib/import-export/test-suite-importer.js.map +1 -0
  108. package/dist/collection/lib/rate-limited-fetcher/rate-limited-fetcher.js +6 -6
  109. package/dist/collection/lib/rate-limited-fetcher/rate-limited-fetcher.js.map +1 -1
  110. package/dist/collection/lib/test-cases/test-case-factory.js +56 -0
  111. package/dist/collection/lib/test-cases/test-case-factory.js.map +1 -0
  112. package/dist/collection/lib/test-cases/test-case-mutations.js +16 -0
  113. package/dist/collection/lib/test-cases/test-case-mutations.js.map +1 -0
  114. package/dist/collection/lib/ui/button/button.css +113 -0
  115. package/dist/collection/lib/ui/button/button.js +21 -0
  116. package/dist/collection/lib/ui/button/button.js.map +1 -0
  117. package/dist/collection/lib/ui/button/index.js +2 -0
  118. package/dist/collection/lib/ui/button/index.js.map +1 -0
  119. package/dist/collection/lib/ui/icon-button/icon-button.css +77 -0
  120. package/dist/collection/lib/ui/icon-button/icon-button.js +19 -0
  121. package/dist/collection/lib/ui/icon-button/icon-button.js.map +1 -0
  122. package/dist/collection/lib/ui/icon-button/index.js +2 -0
  123. package/dist/collection/lib/ui/icon-button/index.js.map +1 -0
  124. package/dist/collection/services/adapters.js +2 -0
  125. package/dist/collection/services/adapters.js.map +1 -0
  126. package/dist/collection/services/models/gemini.js +17 -0
  127. package/dist/collection/services/models/gemini.js.map +1 -0
  128. package/dist/collection/styles/tokens.css +180 -0
  129. package/dist/collection/types/evaluation.js +2 -0
  130. package/dist/collection/types/evaluation.js.map +1 -0
  131. package/dist/collection/types/llm-test-runner.js +2 -0
  132. package/dist/collection/types/llm-test-runner.js.map +1 -0
  133. package/dist/components/app-chips.d.ts +11 -0
  134. package/dist/components/app-chips.js +2 -0
  135. package/dist/components/app-chips.js.map +1 -0
  136. package/dist/components/app-select.d.ts +11 -0
  137. package/dist/components/app-select.js +2 -0
  138. package/dist/components/app-select.js.map +1 -0
  139. package/dist/components/app-textarea.d.ts +11 -0
  140. package/dist/components/app-textarea.js +2 -0
  141. package/dist/components/app-textarea.js.map +1 -0
  142. package/dist/components/form-builder.d.ts +11 -0
  143. package/dist/components/form-builder.js +2 -0
  144. package/dist/components/form-builder.js.map +1 -0
  145. package/dist/components/index.d.ts +2 -0
  146. package/dist/components/index.js +1 -13
  147. package/dist/components/index.js.map +1 -1
  148. package/dist/components/llm-test-runner.js +1 -8
  149. package/dist/components/llm-test-runner.js.map +1 -1
  150. package/dist/components/p--2rdv_J9.js +2 -0
  151. package/dist/components/p--2rdv_J9.js.map +1 -0
  152. package/dist/components/p-B7J48VNq.js +2 -0
  153. package/dist/components/p-B7J48VNq.js.map +1 -0
  154. package/dist/components/p-BCB1rjPS.js +7 -0
  155. package/dist/components/p-BCB1rjPS.js.map +1 -0
  156. package/dist/components/p-BQhb2H_a.js +2 -0
  157. package/dist/components/p-BQhb2H_a.js.map +1 -0
  158. package/dist/components/p-D9BrlHdP.js +297 -0
  159. package/dist/components/p-D9BrlHdP.js.map +1 -0
  160. package/dist/components/p-DtCkZ1g2.js +2 -0
  161. package/dist/components/p-DtCkZ1g2.js.map +1 -0
  162. package/dist/esm/app-chips_5.entry.js +153 -0
  163. package/dist/esm/app-chips_5.entry.js.map +1 -0
  164. package/dist/esm/app-globals-DbR5vV7d.js +32 -0
  165. package/dist/esm/app-globals-DbR5vV7d.js.map +1 -0
  166. package/dist/esm/index-Bvg6mh1M.js +25539 -0
  167. package/dist/esm/index-Bvg6mh1M.js.map +1 -0
  168. package/dist/esm/index-DxzhGhec.js +21450 -0
  169. package/dist/esm/index-DxzhGhec.js.map +1 -0
  170. package/dist/esm/index.js +4 -486
  171. package/dist/esm/index.js.map +1 -1
  172. package/dist/esm/llm-testrunner.js +7 -5
  173. package/dist/esm/llm-testrunner.js.map +1 -1
  174. package/dist/esm/loader.js +6 -4
  175. package/dist/llm-testrunner/index.esm.js +1 -1
  176. package/dist/llm-testrunner/index.esm.js.map +1 -1
  177. package/dist/llm-testrunner/llm-testrunner.esm.js +1 -1
  178. package/dist/llm-testrunner/llm-testrunner.esm.js.map +1 -1
  179. package/dist/llm-testrunner/p-3f04b0fb.entry.js +2 -0
  180. package/dist/llm-testrunner/p-3f04b0fb.entry.js.map +1 -0
  181. package/dist/llm-testrunner/p-DFds8y01.js +7 -0
  182. package/dist/llm-testrunner/p-DFds8y01.js.map +1 -0
  183. package/dist/llm-testrunner/p-DxzhGhec.js +298 -0
  184. package/dist/llm-testrunner/p-DxzhGhec.js.map +1 -0
  185. package/dist/llm-testrunner/p-GQwFOmwJ.js +2 -0
  186. package/dist/llm-testrunner/p-GQwFOmwJ.js.map +1 -0
  187. package/dist/react/components.d.ts +32 -2
  188. package/dist/react/components.d.ts.map +1 -1
  189. package/dist/react/components.js +44 -2
  190. package/dist/types/components/llm-test-runner/header/llm-test-runner-header.d.ts +14 -0
  191. package/dist/types/components/llm-test-runner/llm-test-runner.d.ts +13 -29
  192. package/dist/types/components/llm-test-runner/llm-test-runner.import-export.test.d.ts +1 -0
  193. package/dist/types/components/llm-test-runner/test-cases/actions/row-actions.d.ts +8 -0
  194. package/dist/types/components/llm-test-runner/test-cases/evaluation/evaluation-summary.d.ts +7 -0
  195. package/dist/types/components/llm-test-runner/test-cases/llm-test-case-row.d.ts +25 -0
  196. package/dist/types/components/llm-test-runner/test-cases/llm-test-cases.d.ts +26 -0
  197. package/dist/types/components/llm-test-runner/test-cases/output/response-output.d.ts +6 -0
  198. package/dist/types/components.d.ts +199 -4
  199. package/dist/types/global/env.d.ts +2 -0
  200. package/dist/types/index.d.ts +1 -1
  201. package/dist/types/lib/evaluation/constants.d.ts +11 -0
  202. package/dist/types/lib/evaluation/evaluation-engine.d.ts +0 -4
  203. package/dist/types/lib/evaluation/evaluation-service.d.ts +15 -0
  204. package/dist/types/lib/evaluation/evaluators/bleu/bleu-evaluator.d.ts +18 -0
  205. package/dist/types/lib/evaluation/evaluators/bleu/tests/bleu.test.d.ts +1 -0
  206. package/dist/types/lib/evaluation/evaluators/exact/exact.d.ts +2 -0
  207. package/dist/types/lib/evaluation/evaluators/rouge1-evaluator.d.ts +17 -0
  208. package/dist/types/lib/evaluation/evaluators/rougeL-evaluator.d.ts +2 -0
  209. package/dist/types/lib/evaluation/evaluators/rougeL-evaluator.test.d.ts +1 -0
  210. package/dist/types/lib/evaluation/evaluators/semantic/SemanticEvaluator.d.ts +6 -0
  211. package/dist/types/lib/evaluation/evaluators/semantic/evaluate-keywords.d.ts +7 -0
  212. package/dist/types/lib/evaluation/evaluators/semantic/index.d.ts +2 -0
  213. package/dist/types/lib/evaluation/evaluators/semantic/model-loader.d.ts +1 -0
  214. package/dist/types/lib/evaluation/evaluators/semantic/similarity-utils.d.ts +1 -0
  215. package/dist/types/lib/evaluation/evaluators/semantic/tests/evaluate-keywords.test.d.ts +1 -0
  216. package/dist/types/lib/evaluation/evaluators/semantic/text-utils.d.ts +1 -0
  217. package/dist/types/lib/evaluation/index.d.ts +2 -2
  218. package/dist/types/lib/evaluation/rouge1-evaluator.test.d.ts +1 -0
  219. package/dist/types/lib/evaluation/types.d.ts +19 -7
  220. package/dist/types/lib/file/file-download.d.ts +7 -0
  221. package/dist/types/lib/file/file-reader.d.ts +6 -0
  222. package/dist/types/lib/form/components/app-chips.d.ts +20 -0
  223. package/dist/types/lib/form/components/app-select.d.ts +7 -0
  224. package/dist/types/lib/form/components/app-textarea.d.ts +14 -0
  225. package/dist/types/lib/form/form-builder.d.ts +24 -0
  226. package/dist/types/lib/form/schema/base-input-field-config.d.ts +37 -0
  227. package/dist/types/lib/form/schema/form-control-config.d.ts +13 -0
  228. package/dist/types/lib/form/schema/index.d.ts +9 -0
  229. package/dist/types/lib/import-export/test-results-csv.d.ts +13 -0
  230. package/dist/types/lib/import-export/test-suite-exporter.d.ts +16 -0
  231. package/dist/types/lib/import-export/test-suite-importer.d.ts +12 -0
  232. package/dist/types/lib/rate-limited-fetcher/rate-limited-fetcher.d.ts +1 -1
  233. package/dist/types/lib/test-cases/test-case-factory.d.ts +12 -0
  234. package/dist/types/lib/test-cases/test-case-mutations.d.ts +9 -0
  235. package/dist/types/lib/ui/button/button.d.ts +13 -0
  236. package/dist/types/lib/ui/button/index.d.ts +2 -0
  237. package/dist/types/lib/ui/icon-button/icon-button.d.ts +11 -0
  238. package/dist/types/lib/ui/icon-button/index.d.ts +2 -0
  239. package/dist/types/services/adapters.d.ts +3 -0
  240. package/dist/types/services/models/gemini.d.ts +11 -0
  241. package/dist/types/stencil-public-runtime.d.ts +110 -6
  242. package/dist/types/types/evaluation.d.ts +9 -0
  243. package/dist/types/types/llm-test-runner.d.ts +22 -0
  244. package/package.json +30 -6
  245. package/dist/cjs/app-globals-CbbEbofA.js +0 -14
  246. package/dist/cjs/app-globals-CbbEbofA.js.map +0 -1
  247. package/dist/cjs/index-D-FySkoV.js +0 -1470
  248. package/dist/cjs/index-D-FySkoV.js.map +0 -1
  249. package/dist/cjs/llm-test-runner.cjs.entry.js +0 -9
  250. package/dist/cjs/llm-test-runner.entry.cjs.js.map +0 -1
  251. package/dist/components/p-CYUbsbxt.js +0 -1770
  252. package/dist/components/p-CYUbsbxt.js.map +0 -1
  253. package/dist/esm/app-globals-BOQOUavG.js +0 -12
  254. package/dist/esm/app-globals-BOQOUavG.js.map +0 -1
  255. package/dist/esm/index-cncubhtM.js +0 -1463
  256. package/dist/esm/index-cncubhtM.js.map +0 -1
  257. package/dist/esm/llm-test-runner.entry.js +0 -3
  258. package/dist/esm/llm-test-runner.entry.js.map +0 -1
  259. package/dist/llm-testrunner/llm-test-runner.entry.esm.js.map +0 -1
  260. package/dist/llm-testrunner/loader.esm.js.map +0 -1
  261. package/dist/llm-testrunner/p-BOQOUavG.js +0 -2
  262. package/dist/llm-testrunner/p-BOQOUavG.js.map +0 -1
  263. package/dist/llm-testrunner/p-cncubhtM.js +0 -3
  264. package/dist/llm-testrunner/p-cncubhtM.js.map +0 -1
  265. package/dist/llm-testrunner/p-f68fd660.entry.js +0 -2
  266. package/dist/llm-testrunner/p-f68fd660.entry.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["src/lib/evaluation/evaluation-engine.ts","../../node_modules/uuid/dist/esm-browser/stringify.js","../../node_modules/uuid/dist/esm-browser/rng.js","../../node_modules/uuid/dist/esm-browser/native.js","../../node_modules/uuid/dist/esm-browser/v4.js","src/components/error-message/error-message.tsx","src/lib/rate-limited-fetcher/rate-limited-fetcher.ts","src/components/llm-test-runner/llm-test-runner.css?tag=llm-test-runner&encapsulation=shadow","src/components/llm-test-runner/llm-test-runner.tsx"],"sourcesContent":["import {\n EvaluationRequest,\n EvaluationResult,\n KeywordMatch,\n SourceLinkMatch,\n EvaluationCallback\n} from './types';\n\nexport class LLMEvaluationEngine {\n constructor() { }\n\n async evaluateResponse(\n request: EvaluationRequest,\n callback: EvaluationCallback\n ): Promise<void> {\n try {\n console.log('🔍 Starting evaluation for test case:', request.testCaseId);\n\n const result = await this.performEvaluation(request);\n\n console.log('Evaluation completed for test case:', request.testCaseId);\n console.log('Result:', result);\n\n callback(result);\n\n } catch (error) {\n console.error('Evaluation failed:', error);\n\n const errorResult: EvaluationResult = {\n testCaseId: request.testCaseId,\n passed: false,\n keywordMatches: [],\n sourceLinkMatches: [],\n timestamp: new Date().toISOString()\n };\n\n callback(errorResult);\n }\n }\n\n private async performEvaluation(request: EvaluationRequest): Promise<EvaluationResult> {\n const { testCaseId, expectedKeywords, expectedSourceLinks, actualResponse } = request;\n\n const keywordMatches = this.evaluateKeywords(expectedKeywords, actualResponse);\n const sourceLinkMatches = this.evaluateSourceLinks(expectedSourceLinks, actualResponse);\n\n // Test passes only if ALL expected keywords and source links are found\n const totalItems = keywordMatches.length + sourceLinkMatches.length;\n const foundItems = keywordMatches.filter(m => m.found).length + sourceLinkMatches.filter(m => m.found).length;\n const passed = foundItems === totalItems;\n\n return {\n testCaseId,\n passed,\n keywordMatches,\n sourceLinkMatches,\n timestamp: new Date().toISOString()\n };\n }\n\n private evaluateKeywords(expectedKeywords: string[], actualResponse: string): KeywordMatch[] {\n // Case-insensitive keyword matching\n const response = actualResponse.toLowerCase();\n\n return expectedKeywords.map(keyword => {\n const keywordToMatch = keyword.toLowerCase();\n const found = response.includes(keywordToMatch);\n\n return {\n keyword,\n found\n };\n });\n }\n\n private evaluateSourceLinks(expectedSourceLinks: string[], actualResponse: string): SourceLinkMatch[] {\n return expectedSourceLinks.map(link => {\n const found = actualResponse.includes(link);\n\n return {\n link,\n found\n };\n });\n }\n\n\n\n}\n\n","import validate from './validate.js';\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n //\n // Note to future-self: No, you can't remove the `toLowerCase()` call.\n // REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351\n return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n var uuid = unsafeStringify(arr, offset);\n // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;","// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\n\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n return getRandomValues(rnds8);\n}","var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default {\n randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n offset = offset || 0;\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;","import { FunctionalComponent, h } from '@stencil/core';\n\ninterface ErrorMessageProps {\n message: string;\n onClear?: () => void;\n}\n\nexport const ErrorMessage: FunctionalComponent<ErrorMessageProps> = ({ message, onClear }) => {\n if (!message) {\n return null;\n }\n\n return (\n <div class=\"error-message\">\n <span>{message}</span>\n {onClear && (\n <button\n class=\"error-close\"\n title=\"Close\"\n onClick={onClear}\n >\n &times;\n </button>\n )}\n </div>\n );\n};\n","export class RateLimitedFetcher {\n private queue: (() => void)[] = [];\n private delay: number; // delay in milliseconds\n private intervalId?: any;\n\n constructor(delayMs: number) {\n this.delay = delayMs;\n }\n\n private startQueue() {\n if (this.intervalId) return;\n this.intervalId = setInterval(() => {\n const task = this.queue.shift();\n if (task) task();\n if (this.queue.length === 0) {\n this.stop();\n }\n }, this.delay);\n }\n\n public schedule<T>(task: () => Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n this.queue.push(() => {\n task().then(resolve).catch(reject);\n });\n this.startQueue(); \n });\n }\n\n public stop() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = undefined;\n }\n }\n\n public async runAll<T>(tasks: Array<() => Promise<T>>): Promise<T[]> {\n const promises = tasks.map(task => this.schedule(task));\n return Promise.all(promises);\n }\n}\n",":host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background-color: #f8fafc;\n min-height: 100vh;\n}\n\n.test-runner-container {\n padding: 20px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n margin: 20px 0;\n}\n\n.simple-test {\n margin: 20px 0;\n padding: 20px;\n border: 1px solid #ddd;\n border-radius: 4px;\n}\n\n.test-cases {\n margin: 20px 0;\n}\n\n.test-case {\n margin: 20px 0;\n padding: 20px;\n border: 1px solid #eee;\n border-radius: 4px;\n background: #f9f9f9;\n}\n\n.test-case h3 {\n margin-top: 0;\n color: #333;\n}\n\n.test-case textarea {\n width: 100%;\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-family: inherit;\n margin: 10px 0;\n}\n\n.test-case button {\n background: #007bff;\n color: white;\n border: none;\n padding: 10px 20px;\n border-radius: 4px;\n cursor: pointer;\n margin: 10px 5px 10px 0;\n}\n\n.test-case button:disabled {\n background: #ccc;\n cursor: not-allowed;\n}\n\n.output, .error {\n margin: 10px 0;\n padding: 10px;\n border-radius: 4px;\n}\n\n.output {\n background: #d4edda;\n border: 1px solid #c3e6cb;\n color: #155724;\n}\n\n.error {\n background: #f8d7da;\n border: 1px solid #f5c6cb;\n color: #721c24;\n}\n\n.test-runner-container {\n max-width: 1400px;\n margin: 0 auto;\n background: white;\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);\n}\n\n/* Header Styles */\n.test-runner-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px 24px;\n background: /*linear-gradient(135deg, #667eea 0%, #764ba2 100%);*/ white;\n color: white;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.header-left, .header-right {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.header-center {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.api-status {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.api-status-text {\n color: #28a745;\n font-weight: 500;\n font-size: 0.9rem;\n}\n\n/* Button Styles */\n.btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n text-decoration: none;\n position: relative;\n}\n\n.btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none !important;\n}\n\n.btn-primary {\n color: black;\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);\n}\n\n.btn-primary:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 8px rgba(59, 130, 246, 0.4);\n}\n\n.btn-secondary {\n background: rgba(255, 255, 255, 0.2);\n color: blue;\n border: 1px solid rgba(255, 255, 255, 0.3);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: rgba(255, 255, 255, 0.3);\n transform: translateY(-1px);\n}\n\n.btn-outline {\n background: transparent;\n color: #6b7280;\n border: 2px solid #e5e7eb;\n}\n\n.btn-outline:hover {\n background: #f9fafb;\n border-color: #d1d5db;\n transform: translateY(-1px);\n}\n\n.btn-icon {\n padding: 8px;\n min-width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n}\n\n.btn-run {\n color: white;\n}\n\n.btn-run:hover:not(:disabled) {\n transform: translateY(-1px);\n}\n\n.btn-delete {\n color: white;\n}\n\n.btn-delete:hover:not(:disabled) {\n transform: translateY(-1px);\n}\n\n.icon {\n font-size: 16px;\n}\n\n/* Main Content */\n.test-runner-content {\n padding: 0;\n}\n\n/* Column Headers */\n.column-headers {\n display: grid;\n grid-template-columns: 1fr 1.5fr 0.5fr 120px;\n gap: 1px;\n background: #e5e7eb;\n border-bottom: 2px solid #d1d5db;\n}\n\n.column-header {\n background: #f8fafc;\n padding: 16px 20px;\n font-weight: 600;\n color: #374151;\n font-size: 14px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n/* Test Cases */\n.test-cases {\n background: white;\n}\n\n.test-case-row {\n display: grid;\n grid-template-columns: 1fr 1.5fr 0.5fr 120px;\n gap: 1px;\n border-bottom: 1px solid #e5e7eb;\n min-height: 200px;\n}\n\n.test-case-row:hover {\n background: #f9fafb;\n}\n\n/* Input Column */\n.input-column {\n padding: 20px;\n background: white;\n border-right: 1px solid #e5e7eb;\n}\n\n.input-group {\n margin-bottom: 16px;\n}\n\n.input-group label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #374151;\n font-size: 14px;\n}\n\n.input-group textarea {\n width: 95%;\n padding: 12px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n font-size: 14px;\n resize: vertical;\n outline: none;\n transition: border-color 0.2s ease;\n font-family: inherit;\n}\n\n.input-group textarea:focus {\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n/* Keywords and Links */\n.keywords-group, .links-group {\n margin-bottom: 16px;\n}\n\n.keywords-group label, .links-group label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #374151;\n font-size: 14px;\n}\n\n.tags-container, .links-container {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-items: center;\n}\n\n.tag {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: #dbeafe;\n color: #1e40af;\n padding: 4px 8px;\n border-radius: 16px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove {\n background: none;\n border: none;\n color: #1e40af;\n cursor: pointer;\n font-size: 14px;\n padding: 0;\n width: 16px;\n height: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n}\n\n.tag-remove:hover {\n background: rgba(30, 64, 175, 0.1);\n}\n\n.link-item {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #f0f9ff;\n padding: 4px 8px;\n border-radius: 6px;\n font-size: 12px;\n}\n\n.link-item a {\n color: #0369a1;\n text-decoration: none;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.link-item a:hover {\n text-decoration: underline;\n}\n\n.link-remove {\n background: none;\n border: none;\n color: #0369a1;\n cursor: pointer;\n font-size: 12px;\n padding: 0;\n width: 16px;\n height: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n}\n\n.link-remove:hover {\n background: rgba(3, 105, 161, 0.1);\n}\n\n.tags-container input, .links-container input {\n border: 1px solid #d1d5db;\n border-radius: 6px;\n padding: 6px 8px;\n font-size: 12px;\n outline: none;\n min-width: 120px;\n}\n\n.tags-container input:focus, .links-container input:focus {\n border-color: #3b82f6;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n\n/* Output Column */\n.output-column {\n padding: 20px;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n}\n\n.output-content {\n background: #f8fafc;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 16px;\n font-size: 14px;\n line-height: 1.6;\n color: #374151;\n white-space: pre-wrap;\n word-wrap: break-word;\n flex: 1;\n overflow-y: auto;\n max-height: 250px;\n overflow-x: scroll;\n}\n\n.output-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n color: #9ca3af;\n font-style: italic;\n flex: 1;\n background: #f9fafb;\n border: 2px dashed #d1d5db;\n border-radius: 8px;\n}\n\n/* Evaluation Column */\n.evaluation-column {\n padding: 20px;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n}\n\n.evaluation-content {\n display: flex;\n flex-direction: column;\n gap: 12px;\n flex: 1;\n}\n\n.score-display {\n text-align: center;\n}\n\n.score-number {\n font-size: 24px;\n font-weight: 700;\n color: #111827;\n display: block;\n margin-bottom: 8px;\n}\n\n.score-bar {\n width: 100%;\n height: 8px;\n background: #e5e7eb;\n border-radius: 4px;\n overflow: hidden;\n}\n\n.score-fill {\n height: 100%;\n background: linear-gradient(90deg, #ef4444 0%, #f59e0b 50%, #10b981 100%);\n transition: width 0.3s ease;\n}\n\n.evaluation-details {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.detail-item {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n}\n\n.status {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: bold;\n}\n\n.status.pass {\n background: #dcfce7;\n color: #166534;\n}\n\n.status.fail {\n background: #fef2f2;\n color: #dc2626;\n}\n\n.evaluation-text {\n font-size: 12px;\n color: #6b7280;\n line-height: 1.4;\n background: #f9fafb;\n padding: 8px;\n border-radius: 6px;\n border: 1px solid #e5e7eb;\n}\n\n.evaluation-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n color: #9ca3af;\n font-style: italic;\n flex: 1;\n background: #f9fafb;\n border: 2px dashed #d1d5db;\n border-radius: 8px;\n}\n\n/* New evaluation result styles */\n.evaluation-result {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.evaluation-status {\n font-weight: 600;\n font-size: 14px;\n padding: 8px 12px;\n border-radius: 4px;\n text-align: center;\n}\n\n.evaluation-status.passed {\n background: #d4edda;\n color: #155724;\n border: 1px solid #c3e6cb;\n}\n\n.evaluation-status.failed {\n background: #f8d7da;\n color: #721c24;\n border: 1px solid #f5c6cb;\n}\n\n.evaluation-score {\n font-size: 12px;\n color: #495057;\n text-align: center;\n font-weight: 500;\n}\n\n.evaluation-feedback {\n font-size: 12px;\n color: #6c757d;\n background: #f8f9fa;\n padding: 8px;\n border-radius: 4px;\n border: 1px solid #dee2e6;\n}\n\n/* Actions Column */\n.actions-column {\n padding: 20px;\n background: white;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: center;\n justify-content: flex-start;\n align-self: flex-start;\n}\n\n/* Add Test Case */\n.add-test-case {\n padding: 24px;\n text-align: center;\n background: #f9fafb;\n border-top: 1px solid #e5e7eb;\n}\n\n.hidden {\n display: none;\n}\n\n.error-message {\n background: #ffeaea;\n color: #b71c1c;\n border: 1px solid #f44336;\n padding: 0.75em 2.5em 0.75em 1em;\n border-radius: 4px;\n margin: 1em 0;\n position: relative;\n font-size: 1em;\n display: flex;\n align-items: center;\n gap: 1em;\n}\n\n.error-close {\n background: none;\n border: none;\n color: #b71c1c;\n font-size: 1.25em;\n font-weight: bold;\n cursor: pointer;\n position: absolute;\n right: 0.75em;\n top: 50%;\n transform: translateY(-50%);\n line-height: 1;\n padding: 0;\n}\n\n/* Responsive Design */\n@media (max-width: 1200px) {\n .test-case-row {\n grid-template-columns: 1fr;\n gap: 0;\n }\n \n .column-headers {\n display: none;\n }\n \n .input-column, .output-column, .evaluation-column, .actions-column {\n border-right: none;\n border-bottom: 1px solid #e5e7eb;\n }\n \n .actions-column {\n flex-direction: row;\n justify-content: center;\n }\n}\n\n@media (max-width: 768px) {\n .test-runner-header {\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n }\n \n .header-left, .header-right {\n flex-wrap: wrap;\n justify-content: center;\n }\n \n .btn {\n font-size: 12px;\n padding: 8px 12px;\n }\n \n .input-column, .output-column, .evaluation-column, .actions-column {\n padding: 16px;\n }\n \n .test-case-row {\n min-height: auto;\n }\n}","import { Component, State, Prop, h, EventEmitter, Event } from '@stencil/core';\nimport { LLMEvaluationEngine } from '../../lib/evaluation/evaluation-engine';\nimport { EvaluationRequest, EvaluationResult } from '../../lib/evaluation/types';\nimport { v4 as uuidv4 } from 'uuid';\nimport { ErrorMessage } from '../error-message/error-message';\nimport { RateLimitedFetcher } from '../../lib/rate-limited-fetcher/rate-limited-fetcher';\n\nexport interface TestCase {\n id: string;\n question: string;\n expectedKeywords: string[];\n expectedSourceLinks: string[];\n output?: string;\n isRunning?: boolean;\n error?: string;\n evaluationResult?: EvaluationResult;\n responseTime?: number; // Time taken by the callback to execute in milliseconds\n}\n\nexport interface LLMRequestPayload {\n prompt: string;\n resolve: (result: string) => void;\n reject: (err: any) => void;\n}\n\n@Component({\n tag: 'llm-test-runner',\n styleUrl: 'llm-test-runner.css',\n shadow: true,\n})\nexport class LLMTestRunner {\n @Event() llmRequest: EventEmitter<LLMRequestPayload>;\n @Prop() delayMs?: number = 500; \n @State() testCases: TestCase[] = [\n {\n id: '1',\n question: '',\n expectedKeywords: [],\n expectedSourceLinks: [],\n isRunning: false\n }\n ];\n @State() isRunningAll: boolean = false;\n @State() error: string = '';\n\n private fileInput!: HTMLInputElement;\n @State() isExportingTestSuite: boolean = false;\n @State() isExportingTestResults: boolean = false;\n\n private evaluationEngine: LLMEvaluationEngine;\n\n componentWillLoad() {\n this.evaluationEngine = new LLMEvaluationEngine();\n }\n\n componentDidLoad() {\n }\n\n disconnectedCallback() {\n }\n\n private addNewTestCase() {\n const newTestCase: TestCase = {\n id: this.generateId(),\n question: '',\n expectedKeywords: [],\n expectedSourceLinks: [],\n isRunning: false\n };\n this.testCases = [...this.testCases, newTestCase];\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 async runSingleTest(testCase: TestCase): Promise<void> {\n console.log('🚀 Starting test for question:', testCase.question);\n const startTime = Date.now();\n this.updateTestCase(testCase.id, { isRunning: true });\n return new Promise<void>((resolve, reject) => {\n this.llmRequest.emit({\n prompt: testCase.question,\n resolve: async (aiResponse: string) => {\n console.log('✅ AI call completed for test case:', testCase.id);\n const endTime = Date.now();\n const responseTime = endTime - startTime;\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: aiResponse,\n error: null,\n responseTime: responseTime\n });\n\n await this.evaluateResponse({\n ...testCase,\n output: aiResponse,\n responseTime: responseTime\n });\n resolve()\n },\n reject: (error: any) => {\n console.error('❌ Error in runSingleTest:', error);\n this.updateTestCase(testCase.id, {\n isRunning: false,\n output: null,\n error: error instanceof Error ? error.message : 'Unknown error'\n });\n reject(error);\n }\n });\n })\n }\n\n private deleteTestCase(id: string) {\n this.testCases = this.testCases.filter(tc => tc.id !== id);\n }\n\n private addKeyword(testCaseId: string, keyword: string) {\n if (keyword.trim()) {\n const testCase = this.testCases.find(tc => tc.id === testCaseId);\n if (testCase) {\n this.updateTestCase(testCaseId, {\n expectedKeywords: [...testCase.expectedKeywords, keyword.trim()]\n });\n }\n }\n }\n\n private removeKeyword(testCaseId: string, index: number) {\n const testCase = this.testCases.find(tc => tc.id === testCaseId);\n if (testCase) {\n const newKeywords = testCase.expectedKeywords.filter((_, i) => i !== index);\n this.updateTestCase(testCaseId, { expectedKeywords: newKeywords });\n }\n }\n\n private addSourceLink(testCaseId: string, link: string) {\n if (link.trim()) {\n const testCase = this.testCases.find(tc => tc.id === testCaseId);\n if (testCase) {\n this.updateTestCase(testCaseId, {\n expectedSourceLinks: [...testCase.expectedSourceLinks, link.trim()]\n });\n }\n }\n }\n\n private removeSourceLink(testCaseId: string, index: number) {\n const testCase = this.testCases.find(tc => tc.id === testCaseId);\n if (testCase) {\n const newLinks = testCase.expectedSourceLinks.filter((_, i) => i !== index);\n this.updateTestCase(testCaseId, { expectedSourceLinks: newLinks });\n }\n }\n\n private async evaluateResponse(testCase: TestCase): Promise<void> {\n if (!testCase.output) {\n console.warn('⚠️ No output to evaluate for test case:', testCase.id);\n return;\n }\n\n const evaluationRequest: EvaluationRequest = {\n testCaseId: testCase.id,\n question: testCase.question,\n expectedKeywords: testCase.expectedKeywords,\n expectedSourceLinks: testCase.expectedSourceLinks,\n actualResponse: testCase.output\n };\n\n await this.evaluationEngine.evaluateResponse(evaluationRequest, (result: EvaluationResult) => {\n console.log('📊 Evaluation result received:', result);\n \n this.updateTestCase(testCase.id, {\n evaluationResult: result\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(() => this.runSingleTest(testCase).catch(err => {\n console.error(`⚠️ Test case ${testCase.id} failed`, err);\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 generateId(): string {\n return uuidv4();\n }\n\n private handleFileSelect(): void {\n this.fileInput.click();\n }\n\n private async handleFileChange(event: Event): Promise<void> {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n\n // Immediately clear the input value to allow for a new upload.\n target.value = '';\n\n if (!file) {\n this.error = 'No file selected.';\n return;\n }\n\n const isJsonType = file.type === 'application/json';\n const isJsonExtension = file.name.toLowerCase().endsWith('.json');\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 this.readFileAsync(file);\n const fileContent = JSON.parse(content);\n\n if (!Array.isArray(fileContent)) {\n throw new Error(\"Invalid JSON structure. Expected a JSON array.\");\n } \n const importedTestCases: TestCase[] = fileContent.map((item) => ({\n id: this.generateId(),\n question: item.question || '',\n expectedKeywords: Array.isArray(item.expectedKeywords) ? item.expectedKeywords : [],\n expectedSourceLinks: Array.isArray(item.expectedSourceLinks) ? item.expectedSourceLinks : [],\n isRunning: false\n }));\n this.testCases = importedTestCases; \n } catch (err) {\n this.error = err?.message || 'Error processing file. Please ensure it is a valid JSON array.';\n console.error('File Processing Error:', err);\n }\n }\n\n private readFileAsync(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsText(file);\n });\n }\n\n private downloadFile(content: string, filename: string, mimeType: string) {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n private async handleExportTestSuite() {\n this.isExportingTestSuite = true;\n try {\n // Exporting only input data (question, expected keywords, expected source links)\n const exportData = this.testCases.map(testCase => ({\n id: testCase.id,\n question: testCase.question,\n expectedKeywords: testCase.expectedKeywords,\n expectedSourceLinks: testCase.expectedSourceLinks\n }));\n\n const jsonContent = JSON.stringify(exportData, null, 2);\n\n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n\n this.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 // Create CSV content with the required fields\n const csvRows = [];\n \n // Add header row\n const headers = [\n 'Question',\n 'Expected Keywords',\n 'Generated Keywords',\n 'Keywords Match',\n 'Expected Source Links',\n 'Generated Source Links',\n 'Source Links Match',\n 'Response Time (s)'\n ];\n csvRows.push(headers.join(','));\n \n // Add data rows\n this.testCases.forEach(testCase => {\n const expectedKeywords = testCase.expectedKeywords.join('; ');\n const expectedSourceLinks = testCase.expectedSourceLinks.join('; ');\n \n let generatedKeywords = '';\n let generatedSourceLinks = '';\n let keywordsMatch = '';\n let sourceLinksMatch = '';\n \n if (testCase.evaluationResult) {\n const foundKeywords = testCase.evaluationResult.keywordMatches\n .filter(match => match.found)\n .map(match => match.keyword);\n const foundSourceLinks = testCase.evaluationResult.sourceLinkMatches\n .filter(match => match.found)\n .map(match => match.link);\n \n generatedKeywords = foundKeywords.join('; ');\n generatedSourceLinks = foundSourceLinks.join('; ');\n \n // Calculate match percentages\n const keywordMatchCount = testCase.evaluationResult.keywordMatches.filter(m => m.found).length;\n const totalKeywords = testCase.evaluationResult.keywordMatches.length;\n const sourceLinkMatchCount = testCase.evaluationResult.sourceLinkMatches.filter(m => m.found).length;\n const totalSourceLinks = testCase.evaluationResult.sourceLinkMatches.length;\n \n keywordsMatch = totalKeywords > 0 ? `${keywordMatchCount}/${totalKeywords}` : 'N/A';\n sourceLinksMatch = totalSourceLinks > 0 ? `${sourceLinkMatchCount}/${totalSourceLinks}` : 'N/A';\n }\n \n const responseTime = testCase.responseTime ? (testCase.responseTime / 1000).toFixed(3) : 'N/A';\n \n const row = [\n this.escapeCsvField(testCase.question),\n this.escapeCsvField(expectedKeywords),\n this.escapeCsvField(generatedKeywords),\n keywordsMatch,\n this.escapeCsvField(expectedSourceLinks),\n this.escapeCsvField(generatedSourceLinks), \n sourceLinksMatch,\n responseTime\n ];\n \n csvRows.push(row.join(','));\n });\n \n const csvContent = csvRows.join('\\n');\n \n // Added a small delay to show the loading state\n await new Promise(resolve => setTimeout(resolve, 500));\n \n this.downloadFile(csvContent, 'test-results.csv', 'text/csv');\n } finally {\n this.isExportingTestResults = false;\n }\n }\n\n private escapeCsvField(field: string): string {\n if (field.includes(',') || field.includes('\"') || field.includes('\\n')) {\n return `\"${field.replace(/\"/g, '\"\"')}\"`;\n }\n return field;\n }\n\n render() {\n return (\n <div class=\"test-runner-container\">\n <header class=\"test-runner-header\">\n <div class=\"header-left\">\n <input\n class=\"hidden\"\n type=\"file\"\n ref={(el) => (this.fileInput = el as HTMLInputElement)}\n onChange={(e) => this.handleFileChange(e)}\n accept=\".json,application/json\"\n />\n <button class=\"btn btn-secondary\" onClick={() => this.handleFileSelect()}>\n <span class=\"icon\">↑</span>\n Import Test Suite\n </button>\n <button\n class=\"btn btn-secondary\"\n onClick={() => this.handleExportTestSuite()}\n disabled={this.isExportingTestSuite}\n >\n <span class=\"icon\">\n {this.isExportingTestSuite ? '⏳' : '↓'}\n </span>\n {this.isExportingTestSuite ? 'Exporting...' : 'Export Test Suite'}\n </button>\n </div>\n \n <div class=\"header-right\">\n <button class=\"btn btn-secondary\">\n <span class=\"icon\">⚙️</span>\n Prompt Editor\n </button>\n <button \n class=\"btn btn-secondary\"\n onClick={() => this.handleExportTestResults()}\n disabled={this.isExportingTestResults}\n >\n <span class=\"icon\">\n {this.isExportingTestResults ? '⏳' : '↓'}\n </span>\n {this.isExportingTestResults ? 'Exporting...' : 'Export Test Results'}\n </button>\n <button \n class=\"btn btn-primary\" \n onClick={() => this.runAllTests()}\n disabled={this.isRunningAll}\n >\n {this.isRunningAll ? 'Running...' : 'Run All'}\n </button>\n </div>\n </header>\n <ErrorMessage\n message={this.error}\n onClear={() => (this.error = '')}\n />\n <div class=\"test-runner-content\">\n <div class=\"column-headers\">\n <div class=\"column-header\">Input</div>\n <div class=\"column-header\">Output</div>\n <div class=\"column-header\">Evaluation</div>\n <div class=\"column-header\">Actions</div>\n </div>\n\n <div class=\"test-cases\">\n {this.testCases.map((testCase) => (\n <div class=\"test-case-row\" key={testCase.id}>\n <div class=\"input-column\">\n <div class=\"input-group\">\n <label>Question</label>\n <textarea\n value={testCase.question}\n onInput={(e) => this.updateTestCase(testCase.id, { \n question: (e.target as HTMLTextAreaElement).value \n })}\n placeholder=\"Enter your question here...\"\n rows={3}\n ></textarea>\n </div>\n \n <div class=\"keywords-group\">\n <label>Expected keywords</label>\n <div class=\"tags-container\">\n {testCase.expectedKeywords.map((keyword, index) => (\n <span class=\"tag\" key={index}>\n {keyword}\n <button \n class=\"tag-remove\" \n onClick={() => this.removeKeyword(testCase.id, index)}\n >×</button>\n </span>\n ))}\n <input\n type=\"text\"\n placeholder=\"New item...\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n this.addKeyword(testCase.id, (e.target as HTMLInputElement).value);\n (e.target as HTMLInputElement).value = '';\n }\n }}\n />\n </div>\n </div>\n \n <div class=\"links-group\">\n <label>Expected source links</label>\n <div class=\"links-container\">\n {testCase.expectedSourceLinks.map((link, index) => (\n <div class=\"link-item\" key={index}>\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">{link}</a>\n <button \n class=\"link-remove\" \n onClick={() => this.removeSourceLink(testCase.id, index)}\n >×</button>\n </div>\n ))}\n <input\n type=\"url\"\n placeholder=\"New item...\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n this.addSourceLink(testCase.id, (e.target as HTMLInputElement).value);\n (e.target as HTMLInputElement).value = '';\n }\n }}\n />\n </div>\n </div>\n </div>\n\n <div class=\"output-column\">\n {testCase.output ? (\n <div class=\"output-content\">\n {testCase.output}\n </div>\n ) : (\n <div class=\"output-placeholder\">\n {testCase.isRunning ? 'Running...' : ''}\n </div>\n )}\n </div>\n\n <div class=\"evaluation-column\">\n {testCase.evaluationResult ? (\n <div class=\"evaluation-result\">\n <div class={`evaluation-status ${testCase.evaluationResult.passed ? 'passed' : 'failed'}`}>\n {testCase.evaluationResult.passed ? '✅ PASSED' : '❌ FAILED'}\n </div>\n <div class=\"evaluation-details\">\n Keywords: {testCase.evaluationResult.keywordMatches.filter(m => m.found).length}/{testCase.evaluationResult.keywordMatches.length} found\n </div>\n </div>\n ) : (\n <div class=\"evaluation-placeholder\">\n {testCase.isRunning ? 'Evaluating...' : ''}\n </div>\n )}\n </div>\n\n <div class=\"actions-column\">\n <button \n class=\"btn btn-icon btn-run\"\n onClick={() => this.runSingleTest(testCase)}\n disabled={testCase.isRunning || !testCase.question.trim()}\n title={!testCase.question.trim() ? \"Enter a question first\" : \"Run this test\"}\n >\n {testCase.isRunning ? '⏳' : '▶️'}\n </button>\n <button \n class=\"btn btn-icon btn-delete\"\n onClick={() => this.deleteTestCase(testCase.id)}\n title=\"Delete this test\"\n >\n 🗑️\n </button>\n </div>\n </div>\n ))}\n </div>\n\n <div class=\"add-test-case\">\n <button class=\"btn btn-outline\" onClick={() => this.addNewTestCase()}>\n + Add Question\n </button>\n </div>\n </div>\n </div>\n );\n }\n}"],"names":["h","uuidv4","index"],"mappings":"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","x_google_ignoreList":[1,2,3,4]}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-D-FySkoV.js');
4
- var appGlobals = require('./app-globals-CbbEbofA.js');
3
+ var index = require('./index-CgmLNwZO.js');
4
+ var appGlobals = require('./app-globals-Chb-oJtg.js');
5
5
 
6
6
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
7
  /*
8
- Stencil Client Patch Browser v4.38.2 | MIT Licensed | https://stenciljs.com
8
+ Stencil Client Patch Browser v4.43.2 | MIT Licensed | https://stenciljs.com
9
9
  */
10
10
 
11
11
  var patchBrowser = () => {
@@ -19,8 +19,10 @@ var patchBrowser = () => {
19
19
 
20
20
  patchBrowser().then(async (options) => {
21
21
  await appGlobals.globalScripts();
22
- return index.bootstrapLazy([["llm-test-runner.cjs",[[257,"llm-test-runner",{"delayMs":[2,"delay-ms"],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32]}]]]], options);
22
+ return index.bootstrapLazy([["app-chips_5.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"initialTestCases":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64]}],[513,"form-builder",{"fields":[16],"onUpdateApproach":[16],"testCase":[16],"handleTestCaseChange":[16],"addChip":[16],"removeChip":[16]}],[513,"app-chips",{"value":[16],"config":[16],"testCaseId":[1,"test-case-id"]}],[513,"app-select",{"value":[8],"onChange":[16],"config":[16]}],[513,"app-textarea",{"testCaseId":[1,"test-case-id"],"value":[1],"config":[16]}]]]], options);
23
23
  });
24
24
 
25
25
  exports.setNonce = index.setNonce;
26
26
  //# sourceMappingURL=llm-testrunner.cjs.js.map
27
+
28
+ //# sourceMappingURL=llm-testrunner.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-testrunner.cjs.js","sources":["../../node_modules/@stencil/core/internal/client/patch-browser.js","@lazy-browser-entrypoint?app-data=conditional"],"sourcesContent":["/*\n Stencil Client Patch Browser v4.38.2 | MIT Licensed | https://stenciljs.com\n */\n\n// src/client/client-patch-browser.ts\nimport { BUILD, NAMESPACE } from \"@stencil/core/internal/app-data\";\nimport { consoleDevInfo, H, promiseResolve, win } from \"@stencil/core\";\nvar patchBrowser = () => {\n if (BUILD.isDev && !BUILD.isTesting) {\n consoleDevInfo(\"Running in development mode.\");\n }\n if (BUILD.cloneNodeFix) {\n patchCloneNodeFix(H.prototype);\n }\n const scriptElm = BUILD.scriptDataOpts ? win.document && Array.from(win.document.querySelectorAll(\"script\")).find(\n (s) => new RegExp(`/${NAMESPACE}(\\\\.esm)?\\\\.js($|\\\\?|#)`).test(s.src) || s.getAttribute(\"data-stencil-namespace\") === NAMESPACE\n ) : null;\n const importMeta = import.meta.url;\n const opts = BUILD.scriptDataOpts ? (scriptElm || {})[\"data-opts\"] || {} : {};\n if (importMeta !== \"\") {\n opts.resourcesUrl = new URL(\".\", importMeta).href;\n }\n return promiseResolve(opts);\n};\nvar patchCloneNodeFix = (HTMLElementPrototype) => {\n const nativeCloneNodeFn = HTMLElementPrototype.cloneNode;\n HTMLElementPrototype.cloneNode = function(deep) {\n if (this.nodeName === \"TEMPLATE\") {\n return nativeCloneNodeFn.call(this, deep);\n }\n const clonedNode = nativeCloneNodeFn.call(this, false);\n const srcChildNodes = this.childNodes;\n if (deep) {\n for (let i = 0; i < srcChildNodes.length; i++) {\n if (srcChildNodes[i].nodeType !== 2) {\n clonedNode.appendChild(srcChildNodes[i].cloneNode(true));\n }\n }\n }\n return clonedNode;\n };\n};\nexport {\n patchBrowser\n};\n","export { setNonce } from '@stencil/core';\nimport { bootstrapLazy } from '@stencil/core';\nimport { patchBrowser } from '@stencil/core/internal/client/patch-browser';\nimport { globalScripts } from '@stencil/core/internal/app-globals';\npatchBrowser().then(async (options) => {\n await globalScripts();\n return bootstrapLazy([/*!__STENCIL_LAZY_DATA__*/], options);\n});\n"],"names":["promiseResolve","globalScripts","bootstrapLazy"],"mappings":";;;;;;AAAA;AACA;AACA;;AAKA,IAAI,YAAY,GAAG,MAAM;AAUzB,EAAE,MAAM,UAAU,GAAG,uQAAe;AACpC,EAAE,MAAM,IAAI,GAAiE,EAAE;AAC/E,EAAE,IAAI,UAAU,KAAK,EAAE,EAAE;AACzB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,IAAI;AACrD;AACA,EAAE,OAAOA,oBAAc,CAAC,IAAI,CAAC;AAC7B,CAAC;;ACnBD,YAAY,EAAE,CAAC,IAAI,CAAC,OAAO,OAAO,KAAK;AACvC,EAAE,MAAMC,wBAAa,EAAE;AACvB,EAAE,OAAOC,mBAAa,CAAC,4BAA4B,EAAE,OAAO,CAAC;AAC7D,CAAC,CAAC;;;;","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"llm-testrunner.cjs.js","sources":["node_modules/@stencil/core/internal/client/patch-browser.js","@lazy-browser-entrypoint?app-data=conditional"],"sourcesContent":["/*\n Stencil Client Patch Browser v4.43.2 | MIT Licensed | https://stenciljs.com\n */\n\n// src/client/client-patch-browser.ts\nimport { BUILD, NAMESPACE } from \"@stencil/core/internal/app-data\";\nimport { consoleDevInfo, H, promiseResolve, win } from \"@stencil/core\";\nvar patchBrowser = () => {\n if (BUILD.isDev && !BUILD.isTesting) {\n consoleDevInfo(\"Running in development mode.\");\n }\n if (BUILD.cloneNodeFix) {\n patchCloneNodeFix(H.prototype);\n }\n const scriptElm = BUILD.scriptDataOpts ? win.document && Array.from(win.document.querySelectorAll(\"script\")).find(\n (s) => new RegExp(`/${NAMESPACE}(\\\\.esm)?\\\\.js($|\\\\?|#)`).test(s.src) || s.getAttribute(\"data-stencil-namespace\") === NAMESPACE\n ) : null;\n const importMeta = import.meta.url;\n const opts = BUILD.scriptDataOpts ? (scriptElm || {})[\"data-opts\"] || {} : {};\n if (importMeta !== \"\") {\n opts.resourcesUrl = new URL(\".\", importMeta).href;\n }\n return promiseResolve(opts);\n};\nvar patchCloneNodeFix = (HTMLElementPrototype) => {\n const nativeCloneNodeFn = HTMLElementPrototype.cloneNode;\n HTMLElementPrototype.cloneNode = function(deep) {\n if (this.nodeName === \"TEMPLATE\") {\n return nativeCloneNodeFn.call(this, deep);\n }\n const clonedNode = nativeCloneNodeFn.call(this, false);\n const srcChildNodes = this.childNodes;\n if (deep) {\n for (let i = 0; i < srcChildNodes.length; i++) {\n if (srcChildNodes[i].nodeType !== 2) {\n clonedNode.appendChild(srcChildNodes[i].cloneNode(true));\n }\n }\n }\n return clonedNode;\n };\n};\nexport {\n patchBrowser\n};\n","export { setNonce } from '@stencil/core';\nimport { bootstrapLazy } from '@stencil/core';\nimport { patchBrowser } from '@stencil/core/internal/client/patch-browser';\nimport { globalScripts } from '@stencil/core/internal/app-globals';\npatchBrowser().then(async (options) => {\n await globalScripts();\n return bootstrapLazy([/*!__STENCIL_LAZY_DATA__*/], options);\n});\n"],"names":["promiseResolve","globalScripts","bootstrapLazy"],"mappings":";;;;;;AAAA;AACA;AACA;;AAKA,IAAI,YAAY,GAAG,MAAM;AAUzB,EAAE,MAAM,UAAU,GAAG,uQAAe;AACpC,EAAE,MAAM,IAAI,GAAiE,EAAE;AAC/E,EAAE,IAAI,UAAU,KAAK,EAAE,EAAE;AACzB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,IAAI;AACrD;AACA,EAAE,OAAOA,oBAAc,CAAC,IAAI,CAAC;AAC7B,CAAC;;ACnBD,YAAY,EAAE,CAAC,IAAI,CAAC,OAAO,OAAO,KAAK;AACvC,EAAE,MAAMC,wBAAa,EAAE;AACvB,EAAE,OAAOC,mBAAa,CAAC,4BAA4B,EAAE,OAAO,CAAC;AAC7D,CAAC,CAAC;;;;","x_google_ignoreList":[0]}
@@ -1,14 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-D-FySkoV.js');
4
- var appGlobals = require('./app-globals-CbbEbofA.js');
3
+ var index = require('./index-CgmLNwZO.js');
4
+ var appGlobals = require('./app-globals-Chb-oJtg.js');
5
5
 
6
6
  const defineCustomElements = async (win, options) => {
7
7
  if (typeof window === 'undefined') return undefined;
8
8
  await appGlobals.globalScripts();
9
- return index.bootstrapLazy([["llm-test-runner.cjs",[[257,"llm-test-runner",{"delayMs":[2,"delay-ms"],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32]}]]]], options);
9
+ return index.bootstrapLazy([["app-chips_5.cjs",[[513,"llm-test-runner",{"delayMs":[2,"delay-ms"],"useSave":[4,"use-save"],"initialTestCases":[16],"testCases":[32],"isRunningAll":[32],"error":[32],"isExportingTestSuite":[32],"isExportingTestResults":[32],"isSaving":[32],"resetSavingState":[64]}],[513,"form-builder",{"fields":[16],"onUpdateApproach":[16],"testCase":[16],"handleTestCaseChange":[16],"addChip":[16],"removeChip":[16]}],[513,"app-chips",{"value":[16],"config":[16],"testCaseId":[1,"test-case-id"]}],[513,"app-select",{"value":[8],"onChange":[16],"config":[16]}],[513,"app-textarea",{"testCaseId":[1,"test-case-id"],"value":[1],"config":[16]}]]]], options);
10
10
  };
11
11
 
12
12
  exports.setNonce = index.setNonce;
13
13
  exports.defineCustomElements = defineCustomElements;
14
14
  //# sourceMappingURL=loader.cjs.js.map
15
+
16
+ //# sourceMappingURL=loader.cjs.js.map
@@ -1,11 +1,16 @@
1
1
  {
2
2
  "entries": [
3
- "components/llm-test-runner/llm-test-runner.js"
3
+ "components/llm-test-runner/llm-test-runner.js",
4
+ "lib/form/form-builder.js",
5
+ "lib/form/components/app-chips.js",
6
+ "lib/form/components/app-select.js",
7
+ "lib/form/components/app-textarea.js"
4
8
  ],
9
+ "mixins": [],
5
10
  "compiler": {
6
11
  "name": "@stencil/core",
7
- "version": "4.38.2",
8
- "typescriptVersion": "5.9.3"
12
+ "version": "4.43.2",
13
+ "typescriptVersion": "5.8.3"
9
14
  },
10
15
  "collections": [],
11
16
  "bundles": [],
@@ -0,0 +1,34 @@
1
+ /* Error Message Block */
2
+ .error-message {
3
+ background: var(--destructive);
4
+ color: var(--destructive-foreground);
5
+ border: var(--border-width) solid var(--destructive);
6
+ padding: var(--spacing-3) var(--spacing-10) var(--spacing-3) var(--spacing-4);
7
+ border-radius: var(--radius-md);
8
+ margin: var(--spacing-4) 0;
9
+ position: relative;
10
+ font-size: var(--font-size-sm);
11
+ display: flex;
12
+ align-items: center;
13
+ gap: var(--spacing-4);
14
+ }
15
+
16
+ .error-message__close {
17
+ background: none;
18
+ border: none;
19
+ color: var(--destructive-foreground);
20
+ font-size: var(--font-size-xl);
21
+ font-weight: var(--font-weight-bold);
22
+ cursor: pointer;
23
+ position: absolute;
24
+ right: var(--spacing-3);
25
+ top: 50%;
26
+ transform: translateY(-50%);
27
+ line-height: var(--line-height-none);
28
+ padding: 0;
29
+ opacity: var(--opacity-hover);
30
+ }
31
+
32
+ .error-message__close:hover {
33
+ opacity: 1;
34
+ }
@@ -1,8 +1,8 @@
1
1
  import { h } from "@stencil/core";
2
- export const ErrorMessage = ({ message, onClear }) => {
2
+ export const ErrorMessage = ({ message, onClear, }) => {
3
3
  if (!message) {
4
4
  return null;
5
5
  }
6
- return (h("div", { class: "error-message" }, h("span", null, message), onClear && (h("button", { class: "error-close", title: "Close", onClick: onClear }, "\u00D7"))));
6
+ return (h("div", { class: "error-message" }, h("span", null, message), onClear && (h("button", { type: "button", class: "error-message__close", title: "Close", onClick: onClear }, "\u00D7"))));
7
7
  };
8
8
  //# sourceMappingURL=error-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-message.js","sourceRoot":"","sources":["../../../src/components/error-message/error-message.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,CAAC,EAAE,MAAM,eAAe,CAAC;AAOvD,MAAM,CAAC,MAAM,YAAY,GAA2C,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;IAC3F,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,WAAK,KAAK,EAAC,eAAe;QACxB,gBAAO,OAAO,CAAQ;QACrB,OAAO,IAAI,CACV,cACE,KAAK,EAAC,aAAa,EACnB,KAAK,EAAC,OAAO,EACb,OAAO,EAAE,OAAO,aAGT,CACV,CACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FunctionalComponent, h } from '@stencil/core';\n\ninterface ErrorMessageProps {\n message: string;\n onClear?: () => void;\n}\n\nexport const ErrorMessage: FunctionalComponent<ErrorMessageProps> = ({ message, onClear }) => {\n if (!message) {\n return null;\n }\n\n return (\n <div class=\"error-message\">\n <span>{message}</span>\n {onClear && (\n <button\n class=\"error-close\"\n title=\"Close\"\n onClick={onClear}\n >\n &times;\n </button>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"error-message.js","sourceRoot":"","sources":["../../../src/components/error-message/error-message.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,CAAC,EAAE,MAAM,eAAe,CAAC;AAOvD,MAAM,CAAC,MAAM,YAAY,GAA2C,CAAC,EACnE,OAAO,EACP,OAAO,GACR,EAAE,EAAE;IACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,WAAK,KAAK,EAAC,eAAe;QACxB,gBAAO,OAAO,CAAQ;QACrB,OAAO,IAAI,CACV,cACE,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,sBAAsB,EAC5B,KAAK,EAAC,OAAO,EACb,OAAO,EAAE,OAAO,aAGT,CACV,CACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FunctionalComponent, h } from '@stencil/core';\n\ninterface ErrorMessageProps {\n message: string;\n onClear?: () => void;\n}\n\nexport const ErrorMessage: FunctionalComponent<ErrorMessageProps> = ({\n message,\n onClear,\n}) => {\n if (!message) {\n return null;\n }\n\n return (\n <div class=\"error-message\">\n <span>{message}</span>\n {onClear && (\n <button\n type=\"button\"\n class=\"error-message__close\"\n title=\"Close\"\n onClick={onClear}\n >\n &times;\n </button>\n )}\n </div>\n );\n};\n"]}
@@ -0,0 +1,60 @@
1
+ /* Test Runner Header Block */
2
+ .test-runner-header {
3
+ display: flex;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+ padding: var(--spacing-5) var(--spacing-6);
7
+ background: var(--background);
8
+ color: var(--foreground);
9
+ box-shadow: var(--shadow-md);
10
+ border-bottom: var(--border-width) solid var(--border);
11
+ }
12
+
13
+ /* Header Elements */
14
+ .test-runner-header__left,
15
+ .test-runner-header__right {
16
+ display: flex;
17
+ gap: var(--spacing-3);
18
+ align-items: center;
19
+ }
20
+
21
+ .test-runner-header__center {
22
+ flex: 1;
23
+ display: flex;
24
+ justify-content: center;
25
+ align-items: center;
26
+ }
27
+
28
+ /* API Status Element */
29
+ .test-runner-header__api-status {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: var(--spacing-2);
33
+ }
34
+
35
+ .test-runner-header__api-status-text {
36
+ color: var(--success);
37
+ font-weight: var(--font-weight-medium);
38
+ font-size: var(--font-size-sm);
39
+ line-height: var(--line-height-normal);
40
+ }
41
+
42
+ /* Modifier: Hidden */
43
+ .test-runner-header--hidden {
44
+ display: none;
45
+ }
46
+
47
+ /* Responsive Design */
48
+ @media (max-width: 768px) /* var(--breakpoint-md) */ {
49
+ .test-runner-header {
50
+ flex-direction: column;
51
+ gap: var(--spacing-4);
52
+ padding: var(--spacing-4);
53
+ }
54
+
55
+ .test-runner-header__left,
56
+ .test-runner-header__right {
57
+ flex-wrap: wrap;
58
+ justify-content: center;
59
+ }
60
+ }
@@ -0,0 +1,18 @@
1
+ import { h } from "@stencil/core";
2
+ import { Button } from "../../../lib/ui/button/index";
3
+ export const LLMTestRunnerHeader = ({ isExportingTestSuite, isExportingTestResults, isRunningAll, useSave = false, isSaving = false, onImport, onExportSuite, onExportResults, onRunAll, onSave, }) => {
4
+ let fileInputRef;
5
+ const handleFileSelect = () => {
6
+ fileInputRef?.click();
7
+ };
8
+ const handleFileChange = (event) => {
9
+ const target = event.target;
10
+ const file = target.files?.[0];
11
+ target.value = ''; // Clear for re-upload
12
+ if (file) {
13
+ onImport(file);
14
+ }
15
+ };
16
+ return (h("header", { class: "test-runner-header" }, h("div", { class: "test-runner-header__left" }, h("input", { class: "test-runner-header--hidden", type: "file", ref: el => (fileInputRef = el), onChange: handleFileChange, accept: ".json,application/json" }), h(Button, { variant: "secondary", size: "md", onClick: handleFileSelect, icon: "\u2191" }, "Import Test Suite"), h(Button, { variant: "secondary", size: "md", onClick: onExportSuite, disabled: isExportingTestSuite, loading: isExportingTestSuite, icon: isExportingTestSuite ? '⏳' : '↓' }, isExportingTestSuite ? 'Exporting...' : 'Export Test Suite')), h("div", { class: "test-runner-header__right" }, h(Button, { variant: "secondary", size: "md", icon: "\u2699\uFE0F" }, "Prompt Editor"), h(Button, { variant: "secondary", size: "md", onClick: onExportResults, disabled: isExportingTestResults, loading: isExportingTestResults, icon: isExportingTestResults ? '⏳' : '↓' }, isExportingTestResults ? 'Exporting...' : 'Export Test Results'), useSave && (h(Button, { variant: "secondary", size: "md", onClick: onSave, disabled: isSaving, loading: isSaving, icon: isSaving ? '⏳' : '💾' }, isSaving ? 'Saving...' : 'Save')), h(Button, { "aria-label": "Run All", variant: "primary", size: "md", onClick: onRunAll, disabled: isRunningAll, loading: isRunningAll }, isRunningAll ? 'Running...' : 'Run All'))));
17
+ };
18
+ //# sourceMappingURL=llm-test-runner-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-test-runner-header.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/header/llm-test-runner-header.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport { Button } from '../../../lib/ui/button/index';\n\nexport interface LLMTestRunnerHeaderProps {\n isExportingTestSuite: boolean;\n isExportingTestResults: boolean;\n isRunningAll: boolean;\n useSave?: boolean;\n isSaving?: boolean;\n onImport: (file: File) => void;\n onExportSuite: () => void;\n onExportResults: () => void;\n onRunAll: () => void;\n onSave?: () => void;\n}\n\nexport const LLMTestRunnerHeader: FunctionalComponent<\n LLMTestRunnerHeaderProps\n> = ({\n isExportingTestSuite,\n isExportingTestResults,\n isRunningAll,\n useSave = false,\n isSaving = false,\n onImport,\n onExportSuite,\n onExportResults,\n onRunAll,\n onSave,\n}) => {\n let fileInputRef: HTMLInputElement;\n\n const handleFileSelect = () => {\n fileInputRef?.click();\n };\n\n const handleFileChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n target.value = ''; // Clear for re-upload\n if (file) {\n onImport(file);\n }\n };\n\n return (\n <header class=\"test-runner-header\">\n <div class=\"test-runner-header__left\">\n <input\n class=\"test-runner-header--hidden\"\n type=\"file\"\n ref={el => (fileInputRef = el as HTMLInputElement)}\n onChange={handleFileChange}\n accept=\".json,application/json\"\n />\n <Button\n variant=\"secondary\"\n size=\"md\"\n onClick={handleFileSelect}\n icon=\"↑\"\n >\n Import Test Suite\n </Button>\n <Button\n variant=\"secondary\"\n size=\"md\"\n onClick={onExportSuite}\n disabled={isExportingTestSuite}\n loading={isExportingTestSuite}\n icon={isExportingTestSuite ? '⏳' : '↓'}\n >\n {isExportingTestSuite ? 'Exporting...' : 'Export Test Suite'}\n </Button>\n </div>\n\n <div class=\"test-runner-header__right\">\n <Button variant=\"secondary\" size=\"md\" icon=\"⚙️\">\n Prompt Editor\n </Button>\n <Button\n variant=\"secondary\"\n size=\"md\"\n onClick={onExportResults}\n disabled={isExportingTestResults}\n loading={isExportingTestResults}\n icon={isExportingTestResults ? '⏳' : '↓'}\n >\n {isExportingTestResults ? 'Exporting...' : 'Export Test Results'}\n </Button>\n {useSave && (\n <Button\n variant=\"secondary\"\n size=\"md\"\n onClick={onSave}\n disabled={isSaving}\n loading={isSaving}\n icon={isSaving ? '⏳' : '💾'}\n >\n {isSaving ? 'Saving...' : 'Save'}\n </Button>\n )}\n <Button\n aria-label=\"Run All\"\n variant=\"primary\"\n size=\"md\"\n onClick={onRunAll}\n disabled={isRunningAll}\n loading={isRunningAll}\n >\n {isRunningAll ? 'Running...' : 'Run All'}\n </Button>\n </div>\n </header>\n );\n};\n"]}