llm-testrunner-components 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/cjs/{app-chips_4.cjs.entry.js → app-chips_5.cjs.entry.js} +38 -6
- package/dist/cjs/app-chips_5.cjs.entry.js.map +1 -0
- package/dist/cjs/index.cjs.js +499 -68
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/llm-testrunner.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/llm-test-runner/llm-test-runner.import-export.test.js +22 -12
- package/dist/collection/components/llm-test-runner/llm-test-runner.import-export.test.js.map +1 -1
- package/dist/collection/components/llm-test-runner/llm-test-runner.js +59 -15
- package/dist/collection/components/llm-test-runner/llm-test-runner.js.map +1 -1
- package/dist/collection/components/llm-test-runner/test-cases/chat-history.css +101 -0
- package/dist/collection/components/llm-test-runner/test-cases/chat-history.js +105 -0
- package/dist/collection/components/llm-test-runner/test-cases/chat-history.js.map +1 -0
- package/dist/collection/components/llm-test-runner/test-cases/expected-outcome-renderer.js +45 -5
- package/dist/collection/components/llm-test-runner/test-cases/expected-outcome-renderer.js.map +1 -1
- package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.css +21 -0
- package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js +12 -2
- package/dist/collection/components/llm-test-runner/test-cases/llm-test-case-row.js.map +1 -1
- package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js +2 -2
- package/dist/collection/components/llm-test-runner/test-cases/llm-test-cases.js.map +1 -1
- package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js +1 -1
- package/dist/collection/components/llm-test-runner/test-cases/output/response-output.js.map +1 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/lib/evaluation/actual-value-resolver.js +52 -0
- package/dist/collection/lib/evaluation/actual-value-resolver.js.map +1 -0
- package/dist/collection/lib/evaluation/evaluation-engine.js +1 -1
- package/dist/collection/lib/evaluation/evaluation-engine.js.map +1 -1
- package/dist/collection/lib/evaluation/evaluation-service.js +55 -17
- package/dist/collection/lib/evaluation/evaluation-service.js.map +1 -1
- package/dist/collection/lib/evaluation/types.js.map +1 -1
- package/dist/collection/lib/form/components/app-chips.js +1 -1
- package/dist/collection/lib/form/components/app-select.js +1 -1
- package/dist/collection/lib/form/components/app-textarea.js +2 -2
- package/dist/collection/lib/import-export/test-suite-exporter.js +4 -0
- package/dist/collection/lib/import-export/test-suite-exporter.js.map +1 -1
- package/dist/collection/lib/import-export/test-suite-importer.js +7 -1
- package/dist/collection/lib/import-export/test-suite-importer.js.map +1 -1
- package/dist/collection/lib/test-cases/test-case-factory.js +7 -0
- package/dist/collection/lib/test-cases/test-case-factory.js.map +1 -1
- package/dist/collection/lib/test-cases/test-case-mutations.js +58 -23
- package/dist/collection/lib/test-cases/test-case-mutations.js.map +1 -1
- package/dist/collection/schemas/expected-outcome.js +39 -0
- package/dist/collection/schemas/expected-outcome.js.map +1 -1
- package/dist/collection/schemas/model-response.js +7 -0
- package/dist/collection/schemas/model-response.js.map +1 -0
- package/dist/collection/schemas/test-case.js +8 -1
- package/dist/collection/schemas/test-case.js.map +1 -1
- package/dist/collection/types/expected-outcome.js.map +1 -1
- package/dist/collection/types/llm-test-runner.js.map +1 -1
- package/dist/collection/types/test-case.js.map +1 -1
- package/dist/components/app-chips.js +1 -1
- package/dist/components/app-select.js +1 -1
- package/dist/components/app-textarea.js +1 -1
- package/dist/components/chat-history.d.ts +11 -0
- package/dist/components/chat-history.js +2 -0
- package/dist/components/chat-history.js.map +1 -0
- package/dist/components/index.js +1 -1
- package/dist/components/llm-test-runner.js +1 -1
- package/dist/components/{p-CVtKFBJl.js → p-D2qDAxFN.js} +2 -2
- package/dist/components/{p-Dv7cB5FU.js → p-D4dHUFN9.js} +2 -2
- package/dist/components/{p-CE5-1jfZ.js → p-eN2dLrsr.js} +2 -2
- package/dist/components/p-kmtfMXcQ.js +2 -0
- package/dist/components/p-kmtfMXcQ.js.map +1 -0
- package/dist/components/{p-BcygfrMf.js → p-wzA48RFK.js} +3 -3
- package/dist/components/p-wzA48RFK.js.map +1 -0
- package/dist/esm/{app-chips_4.entry.js → app-chips_5.entry.js} +38 -7
- package/dist/esm/app-chips_5.entry.js.map +1 -0
- package/dist/esm/index.js +499 -68
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/llm-testrunner.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/llm-testrunner/index.esm.js +2 -2
- package/dist/llm-testrunner/index.esm.js.map +1 -1
- package/dist/llm-testrunner/llm-testrunner.esm.js +1 -1
- package/dist/llm-testrunner/p-5bf1fc78.entry.js +2 -0
- package/dist/llm-testrunner/p-5bf1fc78.entry.js.map +1 -0
- package/dist/react/components.d.ts +6 -1
- package/dist/react/components.d.ts.map +1 -1
- package/dist/react/components.js +9 -0
- package/dist/types/components/llm-test-runner/llm-test-runner.d.ts +4 -4
- package/dist/types/components/llm-test-runner/test-cases/chat-history.d.ts +14 -0
- package/dist/types/components/llm-test-runner/test-cases/expected-outcome-renderer.d.ts +1 -0
- package/dist/types/components/llm-test-runner/test-cases/llm-test-case-row.d.ts +6 -0
- package/dist/types/components/llm-test-runner/test-cases/llm-test-cases.d.ts +3 -0
- package/dist/types/components/llm-test-runner/test-cases/output/response-output.d.ts +2 -1
- package/dist/types/components.d.ts +55 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/lib/evaluation/actual-value-resolver.d.ts +9 -0
- package/dist/types/lib/evaluation/evaluation-service.d.ts +2 -2
- package/dist/types/lib/evaluation/types.d.ts +1 -1
- package/dist/types/lib/import-export/test-suite-exporter.d.ts +4 -0
- package/dist/types/lib/import-export/test-suite-importer.d.ts +1 -1
- package/dist/types/lib/test-cases/test-case-mutations.d.ts +10 -1
- package/dist/types/schemas/expected-outcome.d.ts +116 -0
- package/dist/types/schemas/model-response.d.ts +7 -0
- package/dist/types/schemas/test-case.d.ts +93 -1
- package/dist/types/types/expected-outcome.d.ts +1 -1
- package/dist/types/types/llm-test-runner.d.ts +6 -3
- package/dist/types/types/test-case.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cjs/app-chips_4.cjs.entry.js.map +0 -1
- package/dist/components/p-BcygfrMf.js.map +0 -1
- package/dist/esm/app-chips_4.entry.js.map +0 -1
- package/dist/llm-testrunner/p-5df053b4.entry.js +0 -2
- package/dist/llm-testrunner/p-5df053b4.entry.js.map +0 -1
- /package/dist/components/{p-CVtKFBJl.js.map → p-D2qDAxFN.js.map} +0 -0
- /package/dist/components/{p-Dv7cB5FU.js.map → p-D4dHUFN9.js.map} +0 -0
- /package/dist/components/{p-CE5-1jfZ.js.map → p-eN2dLrsr.js.map} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.chat-history {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--spacing-3);
|
|
5
|
+
margin-top: var(--spacing-4);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.chat-history__toggle-row {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.chat-history__switch {
|
|
14
|
+
position: relative;
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: var(--spacing-3);
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
user-select: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.chat-history__switch-input {
|
|
23
|
+
position: absolute;
|
|
24
|
+
width: 1px;
|
|
25
|
+
height: 1px;
|
|
26
|
+
padding: 0;
|
|
27
|
+
margin: -1px;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
clip: rect(0, 0, 0, 0);
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
border: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.chat-history__switch-ui {
|
|
35
|
+
position: relative;
|
|
36
|
+
flex-shrink: 0;
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
padding: 0px 4px;
|
|
40
|
+
width: 2.75rem;
|
|
41
|
+
height: 1.5rem;
|
|
42
|
+
border-radius: var(--radius-full);
|
|
43
|
+
background: var(--muted);
|
|
44
|
+
border: var(--border-width) solid var(--border);
|
|
45
|
+
transition:
|
|
46
|
+
background 0.15s ease,
|
|
47
|
+
border-color 0.15s ease;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@media (prefers-reduced-motion: reduce) {
|
|
51
|
+
.chat-history__switch-ui,
|
|
52
|
+
.chat-history__switch-thumb {
|
|
53
|
+
transition: none;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.chat-history__switch-thumb {
|
|
58
|
+
display: inline-block;
|
|
59
|
+
width: calc(1.5rem - 6px);
|
|
60
|
+
height: calc(1.5rem - 6px);
|
|
61
|
+
border-radius: var(--radius-full);
|
|
62
|
+
background: var(--background);
|
|
63
|
+
box-shadow: var(--shadow-sm);
|
|
64
|
+
transition: transform 0.15s ease;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.chat-history__switch-input:checked + .chat-history__switch-ui {
|
|
68
|
+
background: var(--primary);
|
|
69
|
+
border-color: var(--primary);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.chat-history__switch-input:checked + .chat-history__switch-ui .chat-history__switch-thumb {
|
|
73
|
+
transform: translateX(calc(2.75rem - (1.5rem - 6px)));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.chat-history__switch-input:focus-visible + .chat-history__switch-ui {
|
|
77
|
+
outline: 2px solid var(--ring);
|
|
78
|
+
outline-offset: 2px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.chat-history__switch-text {
|
|
82
|
+
font-size: var(--font-size-sm, 0.875rem);
|
|
83
|
+
color: var(--foreground);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.chat-history__textarea {
|
|
87
|
+
width: 100%;
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
padding: var(--spacing-2) var(--spacing-3);
|
|
90
|
+
border: var(--border-width) solid var(--border);
|
|
91
|
+
border-radius: var(--radius-md);
|
|
92
|
+
font: inherit;
|
|
93
|
+
resize: vertical;
|
|
94
|
+
min-height: 9rem;
|
|
95
|
+
background: var(--background);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.chat-history__textarea:focus-visible {
|
|
99
|
+
outline: 2px solid var(--ring);
|
|
100
|
+
outline-offset: 2px;
|
|
101
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
const CHAT_HISTORY_PLACEHOLDER = `[
|
|
3
|
+
{"role": "user", "content": "How do I import a saved suite?"},
|
|
4
|
+
{"role": "model", "content": "Use Import and pick the JSON from Export suite."}
|
|
5
|
+
]`;
|
|
6
|
+
export class ChatHistory {
|
|
7
|
+
chatHistoryEnabled = false;
|
|
8
|
+
chatHistoryValue = '';
|
|
9
|
+
chatHistoryChange;
|
|
10
|
+
emit(detail) {
|
|
11
|
+
this.chatHistoryChange.emit(detail);
|
|
12
|
+
}
|
|
13
|
+
onToggle = (e) => {
|
|
14
|
+
const checked = e.target.checked;
|
|
15
|
+
this.emit({ enabled: checked, value: this.chatHistoryValue });
|
|
16
|
+
};
|
|
17
|
+
onTextInput = (e) => {
|
|
18
|
+
const value = e.target.value;
|
|
19
|
+
this.emit({ enabled: this.chatHistoryEnabled, value });
|
|
20
|
+
};
|
|
21
|
+
render() {
|
|
22
|
+
return (h("div", { key: 'f444a4b5bd9b48df151cad67b54bef54116d11b3', class: "chat-history" }, h("div", { key: '7216d764fb905ac5e8e33209d9586525e59fa218', class: "chat-history__toggle-row" }, h("label", { key: 'd5d092c323b48543c96525d449bcb03dcaf5113b', class: "chat-history__switch" }, h("input", { key: '5104ce460686434156454fc1dfd3685ba0e0968c', type: "checkbox", class: "chat-history__switch-input", checked: this.chatHistoryEnabled, onInput: this.onToggle }), h("span", { key: 'fa2e51bce0d6ff2d3bf133383e1ce940521097b0', class: "chat-history__switch-ui", "aria-hidden": "true" }, h("span", { key: 'e0d897ca166623ece09834b44b5baa12605cb9f3', class: "chat-history__switch-thumb" })), h("span", { key: 'e769678fde5d670e634d7a8e905ef09ce936f440', class: "chat-history__switch-text" }, "Chat history"))), this.chatHistoryEnabled ? (h("textarea", { class: "chat-history__textarea", value: this.chatHistoryValue, rows: 8, placeholder: CHAT_HISTORY_PLACEHOLDER, "aria-label": "Chat history", onInput: this.onTextInput })) : null));
|
|
23
|
+
}
|
|
24
|
+
static get is() { return "chat-history"; }
|
|
25
|
+
static get encapsulation() { return "shadow"; }
|
|
26
|
+
static get originalStyleUrls() {
|
|
27
|
+
return {
|
|
28
|
+
"$": ["chat-history.css"]
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
static get styleUrls() {
|
|
32
|
+
return {
|
|
33
|
+
"$": ["chat-history.css"]
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
static get properties() {
|
|
37
|
+
return {
|
|
38
|
+
"chatHistoryEnabled": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"mutable": false,
|
|
41
|
+
"complexType": {
|
|
42
|
+
"original": "boolean",
|
|
43
|
+
"resolved": "boolean",
|
|
44
|
+
"references": {}
|
|
45
|
+
},
|
|
46
|
+
"required": false,
|
|
47
|
+
"optional": false,
|
|
48
|
+
"docs": {
|
|
49
|
+
"tags": [],
|
|
50
|
+
"text": ""
|
|
51
|
+
},
|
|
52
|
+
"getter": false,
|
|
53
|
+
"setter": false,
|
|
54
|
+
"reflect": false,
|
|
55
|
+
"attribute": "chat-history-enabled",
|
|
56
|
+
"defaultValue": "false"
|
|
57
|
+
},
|
|
58
|
+
"chatHistoryValue": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"mutable": false,
|
|
61
|
+
"complexType": {
|
|
62
|
+
"original": "string",
|
|
63
|
+
"resolved": "string",
|
|
64
|
+
"references": {}
|
|
65
|
+
},
|
|
66
|
+
"required": false,
|
|
67
|
+
"optional": false,
|
|
68
|
+
"docs": {
|
|
69
|
+
"tags": [],
|
|
70
|
+
"text": ""
|
|
71
|
+
},
|
|
72
|
+
"getter": false,
|
|
73
|
+
"setter": false,
|
|
74
|
+
"reflect": false,
|
|
75
|
+
"attribute": "chat-history-value",
|
|
76
|
+
"defaultValue": "''"
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
static get events() {
|
|
81
|
+
return [{
|
|
82
|
+
"method": "chatHistoryChange",
|
|
83
|
+
"name": "chatHistoryChange",
|
|
84
|
+
"bubbles": true,
|
|
85
|
+
"cancelable": true,
|
|
86
|
+
"composed": true,
|
|
87
|
+
"docs": {
|
|
88
|
+
"tags": [],
|
|
89
|
+
"text": ""
|
|
90
|
+
},
|
|
91
|
+
"complexType": {
|
|
92
|
+
"original": "ChatHistoryChangeDetail",
|
|
93
|
+
"resolved": "{ enabled: boolean; value: string; }",
|
|
94
|
+
"references": {
|
|
95
|
+
"ChatHistoryChangeDetail": {
|
|
96
|
+
"location": "local",
|
|
97
|
+
"path": "/home/runner/work/llm-testrunner-lib/llm-testrunner-lib/src/components/llm-test-runner/test-cases/chat-history.tsx",
|
|
98
|
+
"id": "src/components/llm-test-runner/test-cases/chat-history.tsx::ChatHistoryChangeDetail"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=chat-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-history.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/chat-history.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAgB,IAAI,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAExE,MAAM,wBAAwB,GAAG;;;EAG/B,CAAC;AAYH,MAAM,OAAO,WAAW;IACd,kBAAkB,GAAG,KAAK,CAAC;IAC3B,gBAAgB,GAAG,EAAE,CAAC;IAG9B,iBAAiB,CAAwC;IAEjD,IAAI,CAAC,MAA+B;QAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAEO,QAAQ,GAAG,CAAC,CAAQ,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAI,CAAC,CAAC,MAA2B,CAAC,OAAO,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC;IAEM,WAAW,GAAG,CAAC,CAAQ,EAAE,EAAE;QACjC,MAAM,KAAK,GAAI,CAAC,CAAC,MAA8B,CAAC,KAAK,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC;IAEF,MAAM;QACJ,OAAO,CACL,4DAAK,KAAK,EAAC,cAAc;YACvB,4DAAK,KAAK,EAAC,0BAA0B;gBACnC,8DAAO,KAAK,EAAC,sBAAsB;oBACjC,8DACE,IAAI,EAAC,UAAU,EACf,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAChC,OAAO,EAAE,IAAI,CAAC,QAAQ,GACtB;oBACF,6DAAM,KAAK,EAAC,yBAAyB,iBAAa,MAAM;wBACtD,6DAAM,KAAK,EAAC,4BAA4B,GAAG,CACtC;oBACP,6DAAM,KAAK,EAAC,2BAA2B,mBAAoB,CACrD,CACJ;YACL,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CACzB,gBACE,KAAK,EAAC,wBAAwB,EAC9B,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAC5B,IAAI,EAAE,CAAC,EACP,WAAW,EAAE,wBAAwB,gBAC1B,cAAc,EACzB,OAAO,EAAE,IAAI,CAAC,WAAW,GACzB,CACH,CAAC,CAAC,CAAC,IAAI,CACJ,CACP,CAAC;IACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACF","sourcesContent":["import { Component, Event, EventEmitter, Prop, h } from '@stencil/core';\n\nconst CHAT_HISTORY_PLACEHOLDER = `[\n {\"role\": \"user\", \"content\": \"How do I import a saved suite?\"},\n {\"role\": \"model\", \"content\": \"Use Import and pick the JSON from Export suite.\"}\n]`;\n\nexport type ChatHistoryChangeDetail = {\n enabled: boolean;\n value: string;\n};\n\n@Component({\n tag: 'chat-history',\n styleUrl: 'chat-history.css',\n shadow: true,\n})\nexport class ChatHistory {\n @Prop() chatHistoryEnabled = false;\n @Prop() chatHistoryValue = '';\n\n @Event({ bubbles: true, composed: true })\n chatHistoryChange: EventEmitter<ChatHistoryChangeDetail>;\n\n private emit(detail: ChatHistoryChangeDetail) {\n this.chatHistoryChange.emit(detail);\n }\n\n private onToggle = (e: Event) => {\n const checked = (e.target as HTMLInputElement).checked;\n this.emit({ enabled: checked, value: this.chatHistoryValue });\n };\n\n private onTextInput = (e: Event) => {\n const value = (e.target as HTMLTextAreaElement).value;\n this.emit({ enabled: this.chatHistoryEnabled, value });\n };\n\n render() {\n return (\n <div class=\"chat-history\">\n <div class=\"chat-history__toggle-row\">\n <label class=\"chat-history__switch\">\n <input\n type=\"checkbox\"\n class=\"chat-history__switch-input\"\n checked={this.chatHistoryEnabled}\n onInput={this.onToggle}\n />\n <span class=\"chat-history__switch-ui\" aria-hidden=\"true\">\n <span class=\"chat-history__switch-thumb\" />\n </span>\n <span class=\"chat-history__switch-text\">Chat history</span>\n </label>\n </div>\n {this.chatHistoryEnabled ? (\n <textarea\n class=\"chat-history__textarea\"\n value={this.chatHistoryValue}\n rows={8}\n placeholder={CHAT_HISTORY_PLACEHOLDER}\n aria-label=\"Chat history\"\n onInput={this.onTextInput}\n />\n ) : null}\n </div>\n );\n }\n}\n"]}
|
|
@@ -2,7 +2,9 @@ import { h } from "@stencil/core";
|
|
|
2
2
|
import { FormFieldType } from "../../../lib/form/schema";
|
|
3
3
|
import { EvaluationApproach, } from "../../../lib/evaluation/constants";
|
|
4
4
|
import { getAllowedApproachesForFieldType } from "../../../lib/evaluation/field-evaluation-approach";
|
|
5
|
-
export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionSupported = false, onExpectedOutcomeChange, }) => {
|
|
5
|
+
export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionSupported = false, extractorIds = [], onExpectedOutcomeChange, }) => {
|
|
6
|
+
const hasExtractorOptions = extractorIds.length > 0;
|
|
7
|
+
const firstExtractorId = extractorIds[0];
|
|
6
8
|
const emit = (detail) => onExpectedOutcomeChange({
|
|
7
9
|
detail,
|
|
8
10
|
});
|
|
@@ -32,6 +34,23 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
|
|
|
32
34
|
required: false,
|
|
33
35
|
rows: 2,
|
|
34
36
|
});
|
|
37
|
+
const buildEvaluationSourceConfig = (index) => ({
|
|
38
|
+
name: `expectedOutcomeEvaluationSource-${index}`,
|
|
39
|
+
fieldType: FormFieldType.SELECT,
|
|
40
|
+
label: 'Evaluation Source',
|
|
41
|
+
placeholder: 'Select evaluation source',
|
|
42
|
+
required: true,
|
|
43
|
+
optionList: ['text', 'custom'],
|
|
44
|
+
defaultValue: 'text',
|
|
45
|
+
});
|
|
46
|
+
const buildExtractorConfig = (index) => ({
|
|
47
|
+
name: `expectedOutcomeEvaluationSourceExtractor-${index}`,
|
|
48
|
+
fieldType: FormFieldType.SELECT,
|
|
49
|
+
label: 'Extractor',
|
|
50
|
+
placeholder: 'Select extractor',
|
|
51
|
+
required: true,
|
|
52
|
+
optionList: extractorIds,
|
|
53
|
+
});
|
|
35
54
|
const renderEvaluationSelector = (field, index) => {
|
|
36
55
|
const optionList = getAllowedApproachesForFieldType(field.type);
|
|
37
56
|
return (h("app-select", { config: buildEvaluationConfig(index, optionList), value: field.evaluationParameters?.approach, onValueChange: (e) => emit({
|
|
@@ -41,6 +60,27 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
|
|
|
41
60
|
value: e.detail.value,
|
|
42
61
|
}) }));
|
|
43
62
|
};
|
|
63
|
+
const renderEvaluationSourceSelector = (field, index) => {
|
|
64
|
+
if (!hasExtractorOptions) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const sourceType = field.evaluationSource?.type || 'text';
|
|
68
|
+
return (h("div", null, h("app-select", { config: buildEvaluationSourceConfig(index), value: sourceType, onValueChange: (e) => emit({
|
|
69
|
+
testCaseId,
|
|
70
|
+
index,
|
|
71
|
+
operation: 'set-evaluation-source-type',
|
|
72
|
+
value: e.detail.value,
|
|
73
|
+
fallbackExtractorId: firstExtractorId,
|
|
74
|
+
}) }), sourceType === 'custom' && (h("app-select", { config: buildExtractorConfig(index), value: field.evaluationSource?.type === 'custom'
|
|
75
|
+
? field.evaluationSource.extractorId
|
|
76
|
+
: '', onValueChange: (e) => emit({
|
|
77
|
+
testCaseId,
|
|
78
|
+
index,
|
|
79
|
+
operation: 'set-evaluation-source-extractor',
|
|
80
|
+
value: e.detail.value,
|
|
81
|
+
}) }))));
|
|
82
|
+
};
|
|
83
|
+
const renderEvaluationOptions = (field, index) => (h("details", { class: "expected-outcome-renderer__options" }, h("summary", { class: "expected-outcome-renderer__options-summary" }, "More options"), h("div", { class: "expected-outcome-renderer__options-content" }, renderEvaluationSelector(field, index), renderEvaluationSourceSelector(field, index))));
|
|
44
84
|
return (h("div", { class: "expected-outcome-renderer" }, (fields || []).map((field, index) => {
|
|
45
85
|
if (field.type === 'textarea') {
|
|
46
86
|
const isDynamic = dynamicResolutionSupported && field.outcomeMode === 'dynamic';
|
|
@@ -72,7 +112,7 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
|
|
|
72
112
|
index,
|
|
73
113
|
operation: 'set-resolution-query',
|
|
74
114
|
value: e.detail.value,
|
|
75
|
-
}) })), !isDynamic &&
|
|
115
|
+
}) })), !isDynamic && renderEvaluationOptions(field, index)));
|
|
76
116
|
}
|
|
77
117
|
if (field.type === 'chips-input') {
|
|
78
118
|
const config = {
|
|
@@ -92,7 +132,7 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
|
|
|
92
132
|
index,
|
|
93
133
|
operation: 'remove-chip',
|
|
94
134
|
value: e.detail.value,
|
|
95
|
-
}) }),
|
|
135
|
+
}) }), renderEvaluationOptions(field, index)));
|
|
96
136
|
}
|
|
97
137
|
if (field.type === 'select') {
|
|
98
138
|
const config = {
|
|
@@ -108,14 +148,14 @@ export const ExpectedOutcomeRenderer = ({ testCaseId, fields, dynamicResolutionS
|
|
|
108
148
|
index,
|
|
109
149
|
operation: 'set-value',
|
|
110
150
|
value: e.detail.value,
|
|
111
|
-
}) }),
|
|
151
|
+
}) }), renderEvaluationOptions(field, index)));
|
|
112
152
|
}
|
|
113
153
|
return (h("div", { class: "expected-outcome-renderer__group" }, h("div", { class: "expected-outcome-renderer__text" }, h("label", null, field.label), h("input", { type: "text", value: field.value, placeholder: field.placeholder, onInput: (e) => emit({
|
|
114
154
|
testCaseId,
|
|
115
155
|
index,
|
|
116
156
|
operation: 'set-value',
|
|
117
157
|
value: e.target.value,
|
|
118
|
-
}) })),
|
|
158
|
+
}) })), renderEvaluationOptions(field, index)));
|
|
119
159
|
})));
|
|
120
160
|
};
|
|
121
161
|
//# sourceMappingURL=expected-outcome-renderer.js.map
|
package/dist/collection/components/llm-test-runner/test-cases/expected-outcome-renderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expected-outcome-renderer.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/expected-outcome-renderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport {\n ExpectedOutcomeField,\n type ExpectedOutcomeMode,\n} from '../../../types/llm-test-runner';\nimport { ChipsConfig, FormFieldType, SelectConfig, TextAreaConfig } from '../../../lib/form/schema';\nimport {\n EvaluationApproach,\n} from '../../../lib/evaluation/constants';\nimport { getAllowedApproachesForFieldType } from '../../../lib/evaluation/field-evaluation-approach';\nimport { ExpectedOutcomeChange } from '../../../lib/test-cases/test-case-mutations';\n\nexport type ExpectedOutcomeChangeDetail = {\n testCaseId: string;\n} & ExpectedOutcomeChange;\n\ninterface ExpectedOutcomeRendererProps {\n testCaseId: string;\n fields: ExpectedOutcomeField[];\n dynamicResolutionSupported?: boolean;\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n}\n\nexport const ExpectedOutcomeRenderer: FunctionalComponent<ExpectedOutcomeRendererProps> = ({\n testCaseId,\n fields,\n dynamicResolutionSupported = false,\n onExpectedOutcomeChange,\n}) => {\n const emit = (detail: ExpectedOutcomeChangeDetail) =>\n onExpectedOutcomeChange({\n detail,\n } as CustomEvent<ExpectedOutcomeChangeDetail>);\n\n const buildEvaluationConfig = (\n index: number,\n optionList: string[],\n ): SelectConfig => ({\n name: `expectedOutcomeEvaluation-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Approach',\n placeholder: 'Select evaluation approach…',\n required: true,\n optionList,\n defaultValue: EvaluationApproach.EXACT,\n });\n\n const buildOutcomeModeConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeMode-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Outcome Mode',\n placeholder: 'Select outcome mode',\n required: true,\n optionList: ['static', 'dynamic'],\n defaultValue: 'static',\n });\n\n const buildResolutionQueryConfig = (index: number): TextAreaConfig => ({\n name: `expectedOutcomeResolutionQuery-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: 'Resolution Query',\n placeholder: 'Query used to resolve expected value',\n required: false,\n rows: 2,\n });\n\n const renderEvaluationSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n const optionList = getAllowedApproachesForFieldType(field.type);\n\n return (\n <app-select\n config={buildEvaluationConfig(index, optionList)}\n value={field.evaluationParameters?.approach}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-approach',\n value: e.detail.value as EvaluationApproach,\n })\n }\n />\n );\n };\n\n return (\n <div class=\"expected-outcome-renderer\">\n {(fields || []).map((field, index) => {\n if (field.type === 'textarea') {\n const isDynamic =\n dynamicResolutionSupported && field.outcomeMode === 'dynamic';\n const config: TextAreaConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: field.label,\n placeholder: isDynamic ? 'Resolved on run' : field.placeholder,\n required: !isDynamic,\n readOnly: isDynamic,\n helpText: isDynamic\n ? 'Filled automatically when the test is run'\n : undefined,\n rows: field.rows || 2,\n };\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-textarea\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {dynamicResolutionSupported && (\n <app-select\n config={buildOutcomeModeConfig(index)}\n value={field.outcomeMode || 'static'}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-outcome-mode',\n value: e.detail.value as ExpectedOutcomeMode,\n })\n }\n />\n )}\n {dynamicResolutionSupported &&\n field.outcomeMode === 'dynamic' && (\n <app-textarea\n config={buildResolutionQueryConfig(index)}\n value={field.resolutionQuery || ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-resolution-query',\n value: e.detail.value,\n })\n }\n />\n )}\n {!isDynamic && renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n if (field.type === 'chips-input') {\n const config: ChipsConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.CHIPS,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-chips\n config={config}\n value={field.value}\n onAddChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'add-chip',\n value: e.detail.value,\n })\n }\n onRemoveChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'remove-chip',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n if (field.type === 'select') {\n const config: SelectConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.SELECT,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n optionList: field.options,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-select\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationSelector(field, index)}\n </div>\n );\n }\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <div class=\"expected-outcome-renderer__text\">\n <label>{field.label}</label>\n <input\n type=\"text\"\n value={field.value}\n placeholder={field.placeholder}\n onInput={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: (e.target as HTMLInputElement).value,\n })\n }\n />\n </div>\n {renderEvaluationSelector(field, index)}\n </div>\n );\n })}\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"expected-outcome-renderer.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/expected-outcome-renderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport {\n ExpectedOutcomeField,\n type EvaluationSource,\n type ExpectedOutcomeMode,\n} from '../../../types/llm-test-runner';\nimport { ChipsConfig, FormFieldType, SelectConfig, TextAreaConfig } from '../../../lib/form/schema';\nimport {\n EvaluationApproach,\n} from '../../../lib/evaluation/constants';\nimport { getAllowedApproachesForFieldType } from '../../../lib/evaluation/field-evaluation-approach';\nimport { ExpectedOutcomeChange } from '../../../lib/test-cases/test-case-mutations';\n\nexport type ExpectedOutcomeChangeDetail = {\n testCaseId: string;\n} & ExpectedOutcomeChange;\n\ninterface ExpectedOutcomeRendererProps {\n testCaseId: string;\n fields: ExpectedOutcomeField[];\n dynamicResolutionSupported?: boolean;\n extractorIds?: string[];\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n}\n\nexport const ExpectedOutcomeRenderer: FunctionalComponent<ExpectedOutcomeRendererProps> = ({\n testCaseId,\n fields,\n dynamicResolutionSupported = false,\n extractorIds = [],\n onExpectedOutcomeChange,\n}) => {\n const hasExtractorOptions = extractorIds.length > 0;\n const firstExtractorId = extractorIds[0];\n\n const emit = (detail: ExpectedOutcomeChangeDetail) =>\n onExpectedOutcomeChange({\n detail,\n } as CustomEvent<ExpectedOutcomeChangeDetail>);\n\n const buildEvaluationConfig = (\n index: number,\n optionList: string[],\n ): SelectConfig => ({\n name: `expectedOutcomeEvaluation-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Approach',\n placeholder: 'Select evaluation approach…',\n required: true,\n optionList,\n defaultValue: EvaluationApproach.EXACT,\n });\n\n const buildOutcomeModeConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeMode-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Outcome Mode',\n placeholder: 'Select outcome mode',\n required: true,\n optionList: ['static', 'dynamic'],\n defaultValue: 'static',\n });\n\n const buildResolutionQueryConfig = (index: number): TextAreaConfig => ({\n name: `expectedOutcomeResolutionQuery-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: 'Resolution Query',\n placeholder: 'Query used to resolve expected value',\n required: false,\n rows: 2,\n });\n\n const buildEvaluationSourceConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeEvaluationSource-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Evaluation Source',\n placeholder: 'Select evaluation source',\n required: true,\n optionList: ['text', 'custom'],\n defaultValue: 'text',\n });\n\n const buildExtractorConfig = (index: number): SelectConfig => ({\n name: `expectedOutcomeEvaluationSourceExtractor-${index}`,\n fieldType: FormFieldType.SELECT,\n label: 'Extractor',\n placeholder: 'Select extractor',\n required: true,\n optionList: extractorIds,\n });\n\n const renderEvaluationSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n const optionList = getAllowedApproachesForFieldType(field.type);\n\n return (\n <app-select\n config={buildEvaluationConfig(index, optionList)}\n value={field.evaluationParameters?.approach}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-approach',\n value: e.detail.value as EvaluationApproach,\n })\n }\n />\n );\n };\n\n const renderEvaluationSourceSelector = (\n field: ExpectedOutcomeField,\n index: number,\n ) => {\n if (!hasExtractorOptions) {\n return null;\n }\n\n const sourceType = field.evaluationSource?.type || 'text';\n\n return (\n <div>\n <app-select\n config={buildEvaluationSourceConfig(index)}\n value={sourceType}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-source-type',\n value: e.detail.value as EvaluationSource['type'],\n fallbackExtractorId: firstExtractorId,\n })\n }\n />\n {sourceType === 'custom' && (\n <app-select\n config={buildExtractorConfig(index)}\n value={field.evaluationSource?.type === 'custom'\n ? field.evaluationSource.extractorId\n : ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-evaluation-source-extractor',\n value: e.detail.value,\n })\n }\n />\n )}\n </div>\n );\n };\n\n const renderEvaluationOptions = (field: ExpectedOutcomeField, index: number) => (\n <details class=\"expected-outcome-renderer__options\">\n <summary class=\"expected-outcome-renderer__options-summary\">\n More options\n </summary>\n <div class=\"expected-outcome-renderer__options-content\">\n {renderEvaluationSelector(field, index)}\n {renderEvaluationSourceSelector(field, index)}\n </div>\n </details>\n );\n\n return (\n <div class=\"expected-outcome-renderer\">\n {(fields || []).map((field, index) => {\n if (field.type === 'textarea') {\n const isDynamic =\n dynamicResolutionSupported && field.outcomeMode === 'dynamic';\n const config: TextAreaConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.TEXT_AREA,\n label: field.label,\n placeholder: isDynamic ? 'Resolved on run' : field.placeholder,\n required: !isDynamic,\n readOnly: isDynamic,\n helpText: isDynamic\n ? 'Filled automatically when the test is run'\n : undefined,\n rows: field.rows || 2,\n };\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-textarea\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {dynamicResolutionSupported && (\n <app-select\n config={buildOutcomeModeConfig(index)}\n value={field.outcomeMode || 'static'}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-outcome-mode',\n value: e.detail.value as ExpectedOutcomeMode,\n })\n }\n />\n )}\n {dynamicResolutionSupported &&\n field.outcomeMode === 'dynamic' && (\n <app-textarea\n config={buildResolutionQueryConfig(index)}\n value={field.resolutionQuery || ''}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-resolution-query',\n value: e.detail.value,\n })\n }\n />\n )}\n {!isDynamic && renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n if (field.type === 'chips-input') {\n const config: ChipsConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.CHIPS,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-chips\n config={config}\n value={field.value}\n onAddChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'add-chip',\n value: e.detail.value,\n })\n }\n onRemoveChip={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'remove-chip',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n if (field.type === 'select') {\n const config: SelectConfig = {\n name: `expectedOutcome-${index}`,\n fieldType: FormFieldType.SELECT,\n label: field.label,\n placeholder: field.placeholder,\n required: true,\n optionList: field.options,\n };\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <app-select\n config={config}\n value={field.value}\n onValueChange={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: e.detail.value,\n })\n }\n />\n {renderEvaluationOptions(field, index)}\n </div>\n );\n }\n\n return (\n <div class=\"expected-outcome-renderer__group\">\n <div class=\"expected-outcome-renderer__text\">\n <label>{field.label}</label>\n <input\n type=\"text\"\n value={field.value}\n placeholder={field.placeholder}\n onInput={(e) =>\n emit({\n testCaseId,\n index,\n operation: 'set-value',\n value: (e.target as HTMLInputElement).value,\n })\n }\n />\n </div>\n {renderEvaluationOptions(field, index)}\n </div>\n );\n })}\n </div>\n );\n};\n"]}
|
|
@@ -35,6 +35,27 @@
|
|
|
35
35
|
background: var(--background);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
.expected-outcome-renderer__options {
|
|
39
|
+
border: var(--border-width) solid var(--border);
|
|
40
|
+
border-radius: var(--radius-sm);
|
|
41
|
+
background: var(--muted);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.expected-outcome-renderer__options-summary {
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
font-size: var(--font-size-sm);
|
|
47
|
+
color: var(--foreground);
|
|
48
|
+
padding: var(--spacing-2) var(--spacing-3);
|
|
49
|
+
user-select: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.expected-outcome-renderer__options-content {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
gap: var(--spacing-2);
|
|
56
|
+
padding: 0 var(--spacing-3) var(--spacing-3);
|
|
57
|
+
}
|
|
58
|
+
|
|
38
59
|
/* Responsive Design */
|
|
39
60
|
@media (max-width: 1200px) {
|
|
40
61
|
.test-case-row {
|
|
@@ -4,7 +4,7 @@ import { EvaluationSummary } from "./evaluation/evaluation-summary";
|
|
|
4
4
|
import { RowActions } from "./actions/row-actions";
|
|
5
5
|
import { FormFieldType } from "../../../lib/form/schema";
|
|
6
6
|
import { ExpectedOutcomeRenderer, } from "./expected-outcome-renderer";
|
|
7
|
-
export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, onRun, onDelete, handleTestCaseChange, onExpectedOutcomeChange, }) => {
|
|
7
|
+
export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, extractorIds = [], onRun, onDelete, handleTestCaseChange, onExpectedOutcomeChange, onChatHistoryChange, }) => {
|
|
8
8
|
const questionConfig = {
|
|
9
9
|
name: 'question',
|
|
10
10
|
fieldType: FormFieldType.TEXT_AREA,
|
|
@@ -20,6 +20,16 @@ export const LLMTestCaseRow = ({ testCase, dynamicResolutionSupported = false, o
|
|
|
20
20
|
key: 'question',
|
|
21
21
|
value: e.detail.value,
|
|
22
22
|
},
|
|
23
|
-
}) }), h(
|
|
23
|
+
}) }), h("chat-history", { chatHistoryEnabled: testCase.chatHistory?.enabled ?? false, chatHistoryValue: testCase.chatHistory?.value ?? '', onChatHistoryChange: (e) => {
|
|
24
|
+
const { enabled, value } = e
|
|
25
|
+
.detail;
|
|
26
|
+
onChatHistoryChange({
|
|
27
|
+
detail: {
|
|
28
|
+
testCaseId: testCase.id,
|
|
29
|
+
enabled,
|
|
30
|
+
value,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
} }), h(ExpectedOutcomeRenderer, { testCaseId: testCase.id, fields: testCase.expectedOutcome || [], dynamicResolutionSupported: dynamicResolutionSupported, extractorIds: extractorIds, onExpectedOutcomeChange: onExpectedOutcomeChange })), h(ResponseOutput, { output: testCase.output, isRunning: testCase.isRunning }), h(EvaluationSummary, { result: testCase.evaluationResult, isRunning: testCase.isRunning }), h(RowActions, { isRunning: testCase.isRunning, canRun: !!testCase.question.trim(), onRun: () => onRun(testCase), onDelete: () => onDelete(testCase.id) })));
|
|
24
34
|
};
|
|
25
35
|
//# sourceMappingURL=llm-test-case-row.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-test-case-row.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/llm-test-case-row.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAkB,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAEL,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"llm-test-case-row.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/llm-test-case-row.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAkB,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAEL,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAsBrC,MAAM,CAAC,MAAM,cAAc,GAA6C,CAAC,EACvE,QAAQ,EACR,0BAA0B,GAAG,KAAK,EAClC,YAAY,GAAG,EAAE,EACjB,KAAK,EACL,QAAQ,EACR,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,GACpB,EAAE,EAAE;IACH,MAAM,cAAc,GAAmB;QACrC,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,aAAa,CAAC,SAAS;QAClC,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,6BAA6B;QAC1C,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,CAAC;KACR,CAAC;IACF,OAAO,CACL,WAAK,KAAK,EAAC,eAAe,EAAC,GAAG,EAAE,QAAQ,CAAC,EAAE;QACzC,WAAK,KAAK,EAAC,6BAA6B;YACtC,oBACE,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,QAAQ,CAAC,QAAQ,EACxB,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,oBAAoB,CAAC;oBACnB,MAAM,EAAE;wBACN,UAAU,EAAE,QAAQ,CAAC,EAAE;wBACvB,GAAG,EAAE,UAAU;wBACf,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK;qBACtB;iBACiE,CAAC,GAEvE;YACF,oBACE,kBAAkB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,IAAI,KAAK,EAC1D,gBAAgB,EAAE,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,EACnD,mBAAmB,EAAE,CAAC,CAAQ,EAAE,EAAE;oBAChC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAI,CAA0C;yBACnE,MAAM,CAAC;oBACV,mBAAmB,CAAC;wBAClB,MAAM,EAAE;4BACN,UAAU,EAAE,QAAQ,CAAC,EAAE;4BACvB,OAAO;4BACP,KAAK;yBACN;qBACyC,CAAC,CAAC;gBAChD,CAAC,GACD;YACF,EAAC,uBAAuB,IACtB,UAAU,EAAE,QAAQ,CAAC,EAAE,EACvB,MAAM,EAAE,QAAQ,CAAC,eAAe,IAAI,EAAE,EACtC,0BAA0B,EAAE,0BAA0B,EACtD,YAAY,EAAE,YAAY,EAC1B,uBAAuB,EAAE,uBAAuB,GAChD,CACE;QAEN,EAAC,cAAc,IAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,GAAI;QAE1E,EAAC,iBAAiB,IAChB,MAAM,EAAE,QAAQ,CAAC,gBAAgB,EACjC,SAAS,EAAE,QAAQ,CAAC,SAAS,GAC7B;QAEF,EAAC,UAAU,IACT,SAAS,EAAE,QAAQ,CAAC,SAAS,EAC7B,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAClC,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GACrC,CACE,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport { TestCase } from '../../../types/llm-test-runner';\nimport { ResponseOutput } from './output/response-output';\nimport { EvaluationSummary } from './evaluation/evaluation-summary';\nimport { RowActions } from './actions/row-actions';\nimport { FormFieldType, TextAreaConfig } from '../../../lib/form/schema';\nimport {\n ExpectedOutcomeChangeDetail,\n ExpectedOutcomeRenderer,\n} from './expected-outcome-renderer';\nimport type { ChatHistoryChangeDetail } from './chat-history';\n\nexport type ChatHistoryRowChangeDetail = {\n testCaseId: string;\n} & ChatHistoryChangeDetail;\n\nexport interface LLMTestCaseRowProps {\n testCase: TestCase;\n dynamicResolutionSupported?: boolean;\n extractorIds?: string[];\n onRun: (testCase: TestCase) => void;\n onDelete: (id: string) => void;\n handleTestCaseChange: (\n e: CustomEvent<{ testCaseId: string; key: string; value: string }>,\n ) => void;\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n onChatHistoryChange: (e: CustomEvent<ChatHistoryRowChangeDetail>) => void;\n}\n\nexport const LLMTestCaseRow: FunctionalComponent<LLMTestCaseRowProps> = ({\n testCase,\n dynamicResolutionSupported = false,\n extractorIds = [],\n onRun,\n onDelete,\n handleTestCaseChange,\n onExpectedOutcomeChange,\n onChatHistoryChange,\n}) => {\n const questionConfig: TextAreaConfig = {\n name: 'question',\n fieldType: FormFieldType.TEXT_AREA,\n type: 'text',\n label: 'Question',\n placeholder: 'Enter your question here...',\n required: true,\n rows: 3,\n };\n return (\n <div class=\"test-case-row\" key={testCase.id}>\n <div class=\"test-case-row__input-column\">\n <app-textarea\n config={questionConfig}\n value={testCase.question}\n onValueChange={(e) =>\n handleTestCaseChange({\n detail: {\n testCaseId: testCase.id,\n key: 'question',\n value: e.detail.value,\n },\n } as CustomEvent<{ testCaseId: string; key: string; value: string }>)\n }\n />\n <chat-history\n chatHistoryEnabled={testCase.chatHistory?.enabled ?? false}\n chatHistoryValue={testCase.chatHistory?.value ?? ''}\n onChatHistoryChange={(e: Event) => {\n const { enabled, value } = (e as CustomEvent<ChatHistoryChangeDetail>)\n .detail;\n onChatHistoryChange({\n detail: {\n testCaseId: testCase.id,\n enabled,\n value,\n },\n } as CustomEvent<ChatHistoryRowChangeDetail>);\n }}\n />\n <ExpectedOutcomeRenderer\n testCaseId={testCase.id}\n fields={testCase.expectedOutcome || []}\n dynamicResolutionSupported={dynamicResolutionSupported}\n extractorIds={extractorIds}\n onExpectedOutcomeChange={onExpectedOutcomeChange}\n />\n </div>\n\n <ResponseOutput output={testCase.output} isRunning={testCase.isRunning} />\n\n <EvaluationSummary\n result={testCase.evaluationResult}\n isRunning={testCase.isRunning}\n />\n\n <RowActions\n isRunning={testCase.isRunning}\n canRun={!!testCase.question.trim()}\n onRun={() => onRun(testCase)}\n onDelete={() => onDelete(testCase.id)}\n />\n </div>\n );\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
2
|
import { LLMTestCaseRow } from "./llm-test-case-row";
|
|
3
3
|
import { Button } from "../../../lib/ui/button/index";
|
|
4
|
-
export const LLMTestCases = ({ testCases, dynamicResolutionSupported = false, onRun, onDelete, onAddTestCase, handleTestCaseChange, onExpectedOutcomeChange, }) => {
|
|
5
|
-
return (h("div", { class: "test-cases" }, h("div", { class: "test-cases__column-headers" }, h("div", { class: "test-cases__column-header" }, "Input"), h("div", { class: "test-cases__column-header" }, "Output"), h("div", { class: "test-cases__column-header" }, "Evaluation"), h("div", { class: "test-cases__column-header" }, "Actions")), testCases.map(testCase => (h(LLMTestCaseRow, { testCase: testCase, dynamicResolutionSupported: dynamicResolutionSupported, onRun: onRun, onDelete: onDelete, handleTestCaseChange: handleTestCaseChange, onExpectedOutcomeChange: onExpectedOutcomeChange }))), h("div", { class: "test-cases__add-section" }, h(Button, { variant: "outline", size: "md", onClick: onAddTestCase }, "+ Add Question"))));
|
|
4
|
+
export const LLMTestCases = ({ testCases, dynamicResolutionSupported = false, extractorIds = [], onRun, onDelete, onAddTestCase, handleTestCaseChange, onExpectedOutcomeChange, onChatHistoryChange, }) => {
|
|
5
|
+
return (h("div", { class: "test-cases" }, h("div", { class: "test-cases__column-headers" }, h("div", { class: "test-cases__column-header" }, "Input"), h("div", { class: "test-cases__column-header" }, "Output"), h("div", { class: "test-cases__column-header" }, "Evaluation"), h("div", { class: "test-cases__column-header" }, "Actions")), testCases.map(testCase => (h(LLMTestCaseRow, { testCase: testCase, dynamicResolutionSupported: dynamicResolutionSupported, extractorIds: extractorIds, onRun: onRun, onDelete: onDelete, handleTestCaseChange: handleTestCaseChange, onExpectedOutcomeChange: onExpectedOutcomeChange, onChatHistoryChange: onChatHistoryChange }))), h("div", { class: "test-cases__add-section" }, h(Button, { variant: "outline", size: "md", onClick: onAddTestCase }, "+ Add Question"))));
|
|
6
6
|
};
|
|
7
7
|
//# sourceMappingURL=llm-test-cases.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-test-cases.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/llm-test-cases.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"llm-test-cases.js","sourceRoot":"","sources":["../../../../src/components/llm-test-runner/test-cases/llm-test-cases.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,cAAc,EAA8B,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAmBtD,MAAM,CAAC,MAAM,YAAY,GAA2C,CAAC,EACnE,SAAS,EACT,0BAA0B,GAAG,KAAK,EAClC,YAAY,GAAG,EAAE,EACjB,KAAK,EACL,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,GACpB,EAAE,EAAE;IACH,OAAO,CACL,WAAK,KAAK,EAAC,YAAY;QACrB,WAAK,KAAK,EAAC,4BAA4B;YACrC,WAAK,KAAK,EAAC,2BAA2B,YAAY;YAClD,WAAK,KAAK,EAAC,2BAA2B,aAAa;YACnD,WAAK,KAAK,EAAC,2BAA2B,iBAAiB;YACvD,WAAK,KAAK,EAAC,2BAA2B,cAAc,CAChD;QAEL,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CACzB,EAAC,cAAc,IACb,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,EAAE,0BAA0B,EACtD,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,oBAAoB,EAAE,oBAAoB,EAC1C,uBAAuB,EAAE,uBAAuB,EAChD,mBAAmB,EAAE,mBAAmB,GACxC,CACH,CAAC;QAEF,WAAK,KAAK,EAAC,yBAAyB;YAClC,EAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,aAAa,qBAEjD,CACL,CACF,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport { TestCase } from '../../../types/llm-test-runner';\nimport { LLMTestCaseRow, ChatHistoryRowChangeDetail } from './llm-test-case-row';\nimport { Button } from '../../../lib/ui/button/index';\nimport { ExpectedOutcomeChangeDetail } from './expected-outcome-renderer';\n\nexport interface LLMTestCasesProps {\n testCases: TestCase[];\n dynamicResolutionSupported?: boolean;\n extractorIds?: string[];\n onRun: (testCase: TestCase) => void;\n onDelete: (id: string) => void;\n onAddTestCase: () => void;\n handleTestCaseChange: (\n e: CustomEvent<{ testCaseId: string; key: string; value: string }>,\n ) => void;\n onExpectedOutcomeChange: (\n e: CustomEvent<ExpectedOutcomeChangeDetail>,\n ) => void;\n onChatHistoryChange: (e: CustomEvent<ChatHistoryRowChangeDetail>) => void;\n}\n\nexport const LLMTestCases: FunctionalComponent<LLMTestCasesProps> = ({\n testCases,\n dynamicResolutionSupported = false,\n extractorIds = [],\n onRun,\n onDelete,\n onAddTestCase,\n handleTestCaseChange,\n onExpectedOutcomeChange,\n onChatHistoryChange,\n}) => {\n return (\n <div class=\"test-cases\">\n <div class=\"test-cases__column-headers\">\n <div class=\"test-cases__column-header\">Input</div>\n <div class=\"test-cases__column-header\">Output</div>\n <div class=\"test-cases__column-header\">Evaluation</div>\n <div class=\"test-cases__column-header\">Actions</div>\n </div>\n\n {testCases.map(testCase => (\n <LLMTestCaseRow\n testCase={testCase}\n dynamicResolutionSupported={dynamicResolutionSupported}\n extractorIds={extractorIds}\n onRun={onRun}\n onDelete={onDelete}\n handleTestCaseChange={handleTestCaseChange}\n onExpectedOutcomeChange={onExpectedOutcomeChange}\n onChatHistoryChange={onChatHistoryChange}\n />\n ))}\n\n <div class=\"test-cases__add-section\">\n <Button variant=\"outline\" size=\"md\" onClick={onAddTestCase}>\n + Add Question\n </Button>\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
2
|
export const ResponseOutput = ({ output, isRunning, }) => {
|
|
3
|
-
return (h("div", { class: "response-output" }, output ? (h("div", { class: "response-output__content" }, output)) : (h("div", { class: "response-output__placeholder" }, isRunning ? 'Running...' : ''))));
|
|
3
|
+
return (h("div", { class: "response-output" }, output?.text ? (h("div", { class: "response-output__content" }, output.text)) : (h("div", { class: "response-output__placeholder" }, isRunning ? 'Running...' : ''))));
|
|
4
4
|
};
|
|
5
5
|
//# sourceMappingURL=response-output.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-output.js","sourceRoot":"","sources":["../../../../../src/components/llm-test-runner/test-cases/output/response-output.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"response-output.js","sourceRoot":"","sources":["../../../../../src/components/llm-test-runner/test-cases/output/response-output.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAuB,MAAM,eAAe,CAAC;AAQvD,MAAM,CAAC,MAAM,cAAc,GAA6C,CAAC,EACvE,MAAM,EACN,SAAS,GACV,EAAE,EAAE;IACH,OAAO,CACL,WAAK,KAAK,EAAC,iBAAiB,IACzB,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CACd,WAAK,KAAK,EAAC,0BAA0B,IAAE,MAAM,CAAC,IAAI,CAAO,CAC1D,CAAC,CAAC,CAAC,CACF,WAAK,KAAK,EAAC,8BAA8B,IAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAO,CAChF,CACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { h, FunctionalComponent } from '@stencil/core';\nimport type { ModelResponsePayload } from '../../../../types/llm-test-runner';\n\nexport interface ResponseOutputProps {\n output?: ModelResponsePayload;\n isRunning: boolean;\n}\n\nexport const ResponseOutput: FunctionalComponent<ResponseOutputProps> = ({\n output,\n isRunning,\n}) => {\n return (\n <div class=\"response-output\">\n {output?.text ? (\n <div class=\"response-output__content\">{output.text}</div>\n ) : (\n <div class=\"response-output__placeholder\">{isRunning ? 'Running...' : ''}</div>\n )}\n </div>\n );\n};\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC","sourcesContent":["export { LLMTestRunner } from './components/llm-test-runner/llm-test-runner';\nexport type {
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC","sourcesContent":["export { LLMTestRunner } from './components/llm-test-runner/llm-test-runner';\nexport type {\n TestCase,\n TestCaseChatHistory,\n LLMRequestPayload,\n} from './types/llm-test-runner';\nexport type * from './components.d.ts';\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function toTextSource() {
|
|
2
|
+
return { type: 'text' };
|
|
3
|
+
}
|
|
4
|
+
export async function resolveActualValue(field, output, extractors) {
|
|
5
|
+
const source = field.evaluationSource || toTextSource();
|
|
6
|
+
if (source.type === 'text') {
|
|
7
|
+
const text = output?.text?.trim();
|
|
8
|
+
if (!text) {
|
|
9
|
+
return {
|
|
10
|
+
success: false,
|
|
11
|
+
error: 'Model response text is empty.',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return { success: true, value: text };
|
|
15
|
+
}
|
|
16
|
+
const extractor = extractors?.[source.extractorId];
|
|
17
|
+
if (!extractor) {
|
|
18
|
+
return {
|
|
19
|
+
success: false,
|
|
20
|
+
error: `Extractor "${source.extractorId}" is not registered.`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const extractedRaw = await extractor(output || {});
|
|
25
|
+
if (typeof extractedRaw !== 'string') {
|
|
26
|
+
return {
|
|
27
|
+
success: false,
|
|
28
|
+
error: `Extractor "${source.extractorId}" must return a string.`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const extracted = extractedRaw.trim();
|
|
32
|
+
if (!extracted) {
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: `Extractor "${source.extractorId}" returned an empty value.`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
value: extracted,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: error instanceof Error
|
|
47
|
+
? error.message
|
|
48
|
+
: `Extractor "${source.extractorId}" failed.`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=actual-value-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actual-value-resolver.js","sourceRoot":"","sources":["../../../src/lib/evaluation/actual-value-resolver.ts"],"names":[],"mappings":"AAUA,SAAS,YAAY;IACnB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAW,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA2B,EAC3B,MAA6B,EAC7B,UAAuC;IAEvC,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,IAAI,YAAY,EAAE,CAAC;IAExD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,+BAA+B;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,cAAc,MAAM,CAAC,WAAW,sBAAsB;SAC9D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QACnD,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,cAAc,MAAM,CAAC,WAAW,yBAAyB;aACjE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,cAAc,MAAM,CAAC,WAAW,4BAA4B;aACpE,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,SAAS;SACjB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EACH,KAAK,YAAY,KAAK;gBACpB,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,cAAc,MAAM,CAAC,WAAW,WAAW;SAClD,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import type {\n EvaluationSourceExtractors,\n ExpectedOutcomeField,\n ModelResponsePayload,\n} from '../../types/llm-test-runner';\n\nexport type ResolvedActualValue =\n | { success: true; value: string }\n | { success: false; error: string };\n\nfunction toTextSource() {\n return { type: 'text' } as const;\n}\n\nexport async function resolveActualValue(\n field: ExpectedOutcomeField,\n output?: ModelResponsePayload,\n extractors?: EvaluationSourceExtractors,\n): Promise<ResolvedActualValue> {\n const source = field.evaluationSource || toTextSource();\n\n if (source.type === 'text') {\n const text = output?.text?.trim();\n if (!text) {\n return {\n success: false,\n error: 'Model response text is empty.',\n };\n }\n return { success: true, value: text };\n }\n\n const extractor = extractors?.[source.extractorId];\n if (!extractor) {\n return {\n success: false,\n error: `Extractor \"${source.extractorId}\" is not registered.`,\n };\n }\n\n try {\n const extractedRaw = await extractor(output || {});\n if (typeof extractedRaw !== 'string') {\n return {\n success: false,\n error: `Extractor \"${source.extractorId}\" must return a string.`,\n };\n }\n\n const extracted = extractedRaw.trim();\n if (!extracted) {\n return {\n success: false,\n error: `Extractor \"${source.extractorId}\" returned an empty value.`,\n };\n }\n\n return {\n success: true,\n value: extracted,\n };\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof Error\n ? error.message\n : `Extractor \"${source.extractorId}\" failed.`,\n };\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export class LLMEvaluationEngine {
|
|
|
10
10
|
const fieldRequest = {
|
|
11
11
|
testCaseId: request.testCaseId,
|
|
12
12
|
question: request.question,
|
|
13
|
-
actualResponse:
|
|
13
|
+
actualResponse: field.actualResponse,
|
|
14
14
|
expectedOutcome: field.expectedValue,
|
|
15
15
|
evaluationParameters: field.evaluationParameters,
|
|
16
16
|
};
|