@root-signals/scorable-cli 0.1.3 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/commands/evaluator/create.d.ts +3 -0
- package/dist/commands/evaluator/create.d.ts.map +1 -0
- package/dist/commands/evaluator/create.js +62 -0
- package/dist/commands/evaluator/delete.d.ts +3 -0
- package/dist/commands/evaluator/delete.d.ts.map +1 -0
- package/dist/commands/evaluator/delete.js +34 -0
- package/dist/commands/evaluator/duplicate.d.ts +3 -0
- package/dist/commands/evaluator/duplicate.d.ts.map +1 -0
- package/dist/commands/evaluator/duplicate.js +20 -0
- package/dist/commands/evaluator/execute-by-name.d.ts +17 -0
- package/dist/commands/evaluator/execute-by-name.d.ts.map +1 -0
- package/dist/commands/evaluator/execute-by-name.js +131 -0
- package/dist/commands/evaluator/execute.d.ts +17 -0
- package/dist/commands/evaluator/execute.d.ts.map +1 -0
- package/dist/commands/evaluator/execute.js +135 -0
- package/dist/commands/evaluator/get.d.ts +3 -0
- package/dist/commands/evaluator/get.d.ts.map +1 -0
- package/dist/commands/evaluator/get.js +20 -0
- package/dist/commands/evaluator/index.d.ts +3 -0
- package/dist/commands/evaluator/index.d.ts.map +1 -0
- package/dist/commands/evaluator/index.js +21 -0
- package/dist/commands/evaluator/list.d.ts +3 -0
- package/dist/commands/evaluator/list.d.ts.map +1 -0
- package/dist/commands/evaluator/list.js +39 -0
- package/dist/commands/evaluator/update.d.ts +3 -0
- package/dist/commands/evaluator/update.d.ts.map +1 -0
- package/dist/commands/evaluator/update.js +51 -0
- package/dist/commands/execution-log/get.d.ts +3 -0
- package/dist/commands/execution-log/get.d.ts.map +1 -0
- package/dist/commands/execution-log/get.js +19 -0
- package/dist/commands/execution-log/index.d.ts +3 -0
- package/dist/commands/execution-log/index.d.ts.map +1 -0
- package/dist/commands/execution-log/index.js +9 -0
- package/dist/commands/execution-log/list.d.ts +3 -0
- package/dist/commands/execution-log/list.d.ts.map +1 -0
- package/dist/commands/execution-log/list.js +60 -0
- package/dist/commands/judge/create.d.ts.map +1 -1
- package/dist/commands/judge/create.js +2 -5
- package/dist/commands/judge/delete.d.ts.map +1 -1
- package/dist/commands/judge/delete.js +5 -4
- package/dist/commands/judge/duplicate.d.ts.map +1 -1
- package/dist/commands/judge/duplicate.js +2 -5
- package/dist/commands/judge/exec-openai-generic.d.ts.map +1 -1
- package/dist/commands/judge/exec-openai-generic.js +2 -5
- package/dist/commands/judge/exec-openai.d.ts.map +1 -1
- package/dist/commands/judge/exec-openai.js +2 -5
- package/dist/commands/judge/execute-by-name.d.ts +1 -0
- package/dist/commands/judge/execute-by-name.d.ts.map +1 -1
- package/dist/commands/judge/execute-by-name.js +54 -16
- package/dist/commands/judge/execute.d.ts +1 -0
- package/dist/commands/judge/execute.d.ts.map +1 -1
- package/dist/commands/judge/execute.js +61 -16
- package/dist/commands/judge/get.d.ts.map +1 -1
- package/dist/commands/judge/get.js +2 -5
- package/dist/commands/judge/list.d.ts.map +1 -1
- package/dist/commands/judge/list.js +15 -34
- package/dist/commands/judge/update.d.ts.map +1 -1
- package/dist/commands/judge/update.js +2 -5
- package/dist/commands/prompt-test/run.d.ts.map +1 -1
- package/dist/commands/prompt-test/run.js +5 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/output.d.ts +4 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +47 -4
- package/dist/types.d.ts +0 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +18 -0
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
</a>
|
|
25
25
|
</p>
|
|
26
26
|
|
|
27
|
-
The `scorable` CLI is a command-line tool for interacting with the Scorable API. It lets you manage and execute Judges and run prompt testing experiments directly from the terminal.
|
|
27
|
+
The `scorable` CLI is a command-line tool for interacting with the Scorable API. It lets you manage and execute Judges and Evaluators, view execution logs, and run prompt testing experiments directly from the terminal.
|
|
28
28
|
|
|
29
29
|
Requires **Node.js 20 or higher**.
|
|
30
30
|
|
|
@@ -68,7 +68,7 @@ If no API key is set, the CLI will offer to create a temporary key interactively
|
|
|
68
68
|
scorable judge list
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Options: `--page-size`, `--cursor`, `--search`, `--name`, `--ordering
|
|
71
|
+
Options: `--page-size`, `--cursor`, `--search`, `--name`, `--ordering`
|
|
72
72
|
|
|
73
73
|
### Get a judge
|
|
74
74
|
|
|
@@ -114,37 +114,118 @@ scorable judge duplicate <judge_id>
|
|
|
114
114
|
scorable judge execute <judge_id> --request "What is the capital of France?" --response "Paris"
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
Options: `--request`, `--response`, `--contexts` (JSON list), `--expected-output`, `--tag` (repeatable), `--user-id`, `--session-id`, `--system-prompt`
|
|
117
|
+
Options: `--request`, `--response`, `--turns` (JSON array of conversation turns), `--contexts` (JSON list), `--expected-output`, `--tag` (repeatable), `--user-id`, `--session-id`, `--system-prompt`
|
|
118
118
|
|
|
119
|
-
Pipe
|
|
119
|
+
Pipe a response via stdin:
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
122
|
echo "Paris" | scorable judge execute <judge_id> --request "What is the capital of France?"
|
|
123
123
|
cat response.txt | scorable judge execute <judge_id>
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
For multi-turn conversations, pass the full history as a JSON array:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
scorable judge execute <judge_id> --turns '[{"role":"user","content":"Hi"},{"role":"assistant","content":"Hello!"}]'
|
|
130
|
+
```
|
|
131
|
+
|
|
126
132
|
### Execute by name
|
|
127
133
|
|
|
128
134
|
```bash
|
|
129
135
|
scorable judge execute-by-name "My Judge" --request "What is the capital of France?" --response "Paris"
|
|
130
136
|
```
|
|
131
137
|
|
|
132
|
-
Accepts the same options as `execute`. Stdin piping
|
|
138
|
+
Accepts the same options as `execute`. Stdin piping and `--turns` work the same way.
|
|
139
|
+
|
|
140
|
+
## Evaluator Management
|
|
141
|
+
|
|
142
|
+
### List evaluators
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
scorable evaluator list
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Options: `--page-size`, `--cursor`, `--search`, `--name`, `--ordering`
|
|
149
|
+
|
|
150
|
+
### Get an evaluator
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
scorable evaluator get <evaluator_id>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Create an evaluator
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
scorable evaluator create \
|
|
160
|
+
--name "My Evaluator" \
|
|
161
|
+
--scoring-criteria "Does the {{ response }} directly answer the user's question?" \
|
|
162
|
+
--intent "Evaluate response relevance"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Options: `--name` (required), `--scoring-criteria` (required — must contain `{{ request }}` and/or `{{ response }}`), `--intent` or `--objective-id` (one required), `--system-message`, `--models` (JSON array), `--overwrite`, `--objective-version-id`
|
|
166
|
+
|
|
167
|
+
### Update an evaluator
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
scorable evaluator update <evaluator_id> --name "Updated Name"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Options: `--name`, `--scoring-criteria`, `--system-message`, `--models` (JSON array), `--objective-id`, `--objective-version-id`
|
|
174
|
+
|
|
175
|
+
### Delete an evaluator
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
scorable evaluator delete <evaluator_id>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Prompts for confirmation. Use `--yes` to skip.
|
|
182
|
+
|
|
183
|
+
### Duplicate an evaluator
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
scorable evaluator duplicate <evaluator_id>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Evaluator Execution
|
|
133
190
|
|
|
134
|
-
### Execute
|
|
191
|
+
### Execute by ID
|
|
135
192
|
|
|
136
193
|
```bash
|
|
137
|
-
scorable
|
|
138
|
-
--model gpt-4o \
|
|
139
|
-
--messages '[{"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there"}]'
|
|
194
|
+
scorable evaluator execute <evaluator_id> --request "What is 2+2?" --response "4"
|
|
140
195
|
```
|
|
141
196
|
|
|
142
|
-
|
|
197
|
+
Options: `--request`, `--response`, `--turns` (JSON array of conversation turns), `--contexts` (JSON list), `--expected-output`, `--tag` (repeatable), `--user-id`, `--session-id`, `--system-prompt`, `--variables` (JSON object of extra template variables)
|
|
198
|
+
|
|
199
|
+
Stdin piping and `--turns` work the same way as for judge execution.
|
|
200
|
+
|
|
201
|
+
For evaluators with custom template placeholders beyond `{{request}}`/`{{response}}`:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
scorable evaluator execute <evaluator_id> --request "Hello" --variables '{"lang":"EN","topic":"science"}'
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Execute by name
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
scorable evaluator execute-by-name "My Evaluator" --request "What is 2+2?" --response "4"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Accepts the same options as `execute`, including `--variables`.
|
|
214
|
+
|
|
215
|
+
## Execution Logs
|
|
216
|
+
|
|
217
|
+
### List execution logs
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
scorable execution-log list
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Options: `--page-size`, `--cursor`, `--search`, `--evaluator-id`, `--judge-id`, `--model`, `--tags`, `--score-min`, `--score-max`, `--created-at-after`, `--created-at-before`, `--owner-email`
|
|
224
|
+
|
|
225
|
+
### Get an execution log
|
|
143
226
|
|
|
144
227
|
```bash
|
|
145
|
-
scorable
|
|
146
|
-
--model <judge_id_or_name> \
|
|
147
|
-
--messages '[{"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there"}]'
|
|
228
|
+
scorable execution-log get <log_id>
|
|
148
229
|
```
|
|
149
230
|
|
|
150
231
|
## Prompt Testing
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,OAAO,CAAC,CAoDlB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkF9D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
|
|
3
|
+
export function registerCreateCommand(evaluator) {
|
|
4
|
+
evaluator
|
|
5
|
+
.command("create")
|
|
6
|
+
.description("Create a new evaluator")
|
|
7
|
+
.requiredOption("--name <name>", "The name for the new evaluator")
|
|
8
|
+
.requiredOption("--scoring-criteria <text>", "The scoring criteria prompt. Must contain {{ request }} and/or {{ response }} as placeholders.")
|
|
9
|
+
.option("--intent <intent>", "The intent for the evaluator (mutually exclusive with --objective-id)")
|
|
10
|
+
.option("--objective-id <id>", "Objective ID (mutually exclusive with --intent)")
|
|
11
|
+
.option("--system-message <text>", "System message for the evaluator")
|
|
12
|
+
.option("--models <json>", "JSON array of model names, in priority order. E.g., '[\"gpt-5-mini\"]'")
|
|
13
|
+
.option("--overwrite", "Overwrite if evaluator with same name exists")
|
|
14
|
+
.option("--objective-version-id <id>", "Objective version ID")
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
if (!opts.intent && !opts.objectiveId) {
|
|
17
|
+
printError("Either --intent or --objective-id is required.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!/\{\{\s*request\s*\}\}/.test(opts.scoringCriteria) &&
|
|
21
|
+
!/\{\{\s*response\s*\}\}/.test(opts.scoringCriteria)) {
|
|
22
|
+
printError("The --scoring-criteria must contain at least one of {{ request }} or {{ response }} as a placeholder.\n" +
|
|
23
|
+
'Example: "Does the {{ response }} directly answer the user\'s question?"');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const payload = {
|
|
27
|
+
name: opts.name,
|
|
28
|
+
predicate: opts.scoringCriteria,
|
|
29
|
+
};
|
|
30
|
+
if (opts.intent)
|
|
31
|
+
payload.intent = opts.intent;
|
|
32
|
+
if (opts.objectiveId)
|
|
33
|
+
payload.objective_id = opts.objectiveId;
|
|
34
|
+
if (opts.systemMessage)
|
|
35
|
+
payload.system_message = opts.systemMessage;
|
|
36
|
+
if (opts.overwrite !== undefined)
|
|
37
|
+
payload.overwrite = opts.overwrite;
|
|
38
|
+
if (opts.objectiveVersionId)
|
|
39
|
+
payload.objective_version_id = opts.objectiveVersionId;
|
|
40
|
+
if (opts.models) {
|
|
41
|
+
try {
|
|
42
|
+
payload.models = JSON.parse(opts.models);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
printError("Invalid JSON format for --models.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
printInfo("Attempting to create evaluator with payload:");
|
|
50
|
+
printJson(payload);
|
|
51
|
+
try {
|
|
52
|
+
const apiKey = await requireApiKey();
|
|
53
|
+
const client = getSdkClient(apiKey);
|
|
54
|
+
const result = await client.evaluators.create(payload);
|
|
55
|
+
printSuccess("Evaluator created successfully!");
|
|
56
|
+
printJson(result);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
handleSdkError(e);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAmC9D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, handleSdkError } from "../../output.js";
|
|
3
|
+
import { CliError } from "../../types.js";
|
|
4
|
+
export function registerDeleteCommand(evaluator) {
|
|
5
|
+
evaluator
|
|
6
|
+
.command("delete <evaluatorId>")
|
|
7
|
+
.description("Delete an evaluator by its ID")
|
|
8
|
+
.option("--yes", "Skip confirmation prompt")
|
|
9
|
+
.action(async (evaluatorId, opts) => {
|
|
10
|
+
const apiKey = await requireApiKey();
|
|
11
|
+
if (!opts.yes) {
|
|
12
|
+
if (!process.stdin.isTTY && !process.stdout.isTTY) {
|
|
13
|
+
throw new CliError(1, "Refusing to prompt for confirmation in a non-interactive environment. Pass --yes to skip the prompt.");
|
|
14
|
+
}
|
|
15
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
16
|
+
const ok = await confirm({
|
|
17
|
+
message: "Are you sure you want to delete this evaluator?",
|
|
18
|
+
default: false,
|
|
19
|
+
});
|
|
20
|
+
if (!ok) {
|
|
21
|
+
throw new CliError(1, "Aborted");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
printInfo(`Deleting evaluator ${evaluatorId}...`);
|
|
25
|
+
try {
|
|
26
|
+
const client = getSdkClient(apiKey);
|
|
27
|
+
await client.evaluators.delete(evaluatorId);
|
|
28
|
+
printSuccess(`Evaluator ${evaluatorId} deleted successfully.`);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
handleSdkError(e);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAiBjE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, printJson, handleSdkError } from "../../output.js";
|
|
3
|
+
export function registerDuplicateCommand(evaluator) {
|
|
4
|
+
evaluator
|
|
5
|
+
.command("duplicate <evaluatorId>")
|
|
6
|
+
.description("Duplicate an existing evaluator")
|
|
7
|
+
.action(async (evaluatorId) => {
|
|
8
|
+
const apiKey = await requireApiKey();
|
|
9
|
+
printInfo(`Duplicating evaluator ID: ${evaluatorId}...`);
|
|
10
|
+
try {
|
|
11
|
+
const client = getSdkClient(apiKey);
|
|
12
|
+
const result = await client.evaluators.duplicate(evaluatorId);
|
|
13
|
+
printSuccess(`Evaluator ${evaluatorId} duplicated successfully!`);
|
|
14
|
+
printJson(result);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
handleSdkError(e);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
declare function readStdinDefault(): Promise<string>;
|
|
3
|
+
export declare function executeEvaluatorByName(evaluatorName: string, opts: {
|
|
4
|
+
request?: string;
|
|
5
|
+
response?: string;
|
|
6
|
+
turns?: string;
|
|
7
|
+
contexts?: string;
|
|
8
|
+
expectedOutput?: string;
|
|
9
|
+
tag?: string[];
|
|
10
|
+
userId?: string;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
systemPrompt?: string;
|
|
13
|
+
variables?: string;
|
|
14
|
+
}, readStdin?: typeof readStdinDefault): Promise<void>;
|
|
15
|
+
export declare function registerExecuteByNameCommand(evaluator: Command): void;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=execute-by-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute-by-name.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute-by-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA4ErE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
|
|
3
|
+
import { isTurnArray, isStringArray, isStringRecord } from "../../utils.js";
|
|
4
|
+
async function readStdinDefault() {
|
|
5
|
+
const chunks = [];
|
|
6
|
+
for await (const chunk of process.stdin)
|
|
7
|
+
chunks.push(chunk);
|
|
8
|
+
return Buffer.concat(chunks).toString().trim();
|
|
9
|
+
}
|
|
10
|
+
export async function executeEvaluatorByName(evaluatorName, opts, readStdin = readStdinDefault) {
|
|
11
|
+
const apiKey = await requireApiKey();
|
|
12
|
+
let response = opts.response;
|
|
13
|
+
if (!opts.request && !response && !opts.turns && !process.stdin.isTTY) {
|
|
14
|
+
response = await readStdin();
|
|
15
|
+
}
|
|
16
|
+
if (!opts.request && !response && !opts.turns) {
|
|
17
|
+
printError("Either --request, --response, or --turns must be provided.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const payload = {};
|
|
21
|
+
if (opts.request)
|
|
22
|
+
payload.request = opts.request;
|
|
23
|
+
if (response)
|
|
24
|
+
payload.response = response;
|
|
25
|
+
if (opts.expectedOutput)
|
|
26
|
+
payload.expected_output = opts.expectedOutput;
|
|
27
|
+
if (opts.tag?.length)
|
|
28
|
+
payload.tags = opts.tag;
|
|
29
|
+
if (opts.userId)
|
|
30
|
+
payload.user_id = opts.userId;
|
|
31
|
+
if (opts.sessionId)
|
|
32
|
+
payload.session_id = opts.sessionId;
|
|
33
|
+
if (opts.systemPrompt)
|
|
34
|
+
payload.system_prompt = opts.systemPrompt;
|
|
35
|
+
if (opts.turns) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(opts.turns);
|
|
38
|
+
if (!isTurnArray(parsed)) {
|
|
39
|
+
printError("Invalid JSON for --turns.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
payload.turns = parsed;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
printError("Invalid JSON for --turns.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (opts.contexts) {
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(opts.contexts);
|
|
52
|
+
if (!isStringArray(parsed)) {
|
|
53
|
+
printError("Invalid JSON for --contexts. Skipping.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
payload.contexts = parsed;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
printError("Invalid JSON for --contexts. Skipping.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (opts.variables) {
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(opts.variables);
|
|
66
|
+
if (!isStringRecord(parsed)) {
|
|
67
|
+
printError("Invalid JSON for --variables.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
payload.variables = parsed;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
printError("Invalid JSON for --variables.");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
printInfo(`Attempting to execute evaluator '${evaluatorName}' with payload:`);
|
|
78
|
+
printJson(payload);
|
|
79
|
+
const client = getSdkClient(apiKey);
|
|
80
|
+
const result = await client.evaluators.executeByName(evaluatorName, payload);
|
|
81
|
+
printSuccess("Evaluator execution by name successful!");
|
|
82
|
+
printJson(result);
|
|
83
|
+
}
|
|
84
|
+
export function registerExecuteByNameCommand(evaluator) {
|
|
85
|
+
evaluator
|
|
86
|
+
.command("execute-by-name <evaluatorName>")
|
|
87
|
+
.description("Execute an evaluator by name with interaction details")
|
|
88
|
+
.option("--request <text>", "Request text")
|
|
89
|
+
.option("--response <text>", "Response text to evaluate")
|
|
90
|
+
.option("--contexts <json>", "JSON list of context strings. E.g., '[\"ctx1\"]'")
|
|
91
|
+
.option("--expected-output <text>", "Expected output text")
|
|
92
|
+
.option("--tag <tag>", "Add one or more tags", (v, a) => [...a, v], [])
|
|
93
|
+
.option("--user-id <id>", "User identifier for tracking purposes")
|
|
94
|
+
.option("--session-id <id>", "Session identifier for tracking purposes")
|
|
95
|
+
.option("--system-prompt <text>", "System prompt that was used for the LLM call")
|
|
96
|
+
.option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
|
|
97
|
+
.option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
|
|
98
|
+
.addHelpText("after", `
|
|
99
|
+
Examples:
|
|
100
|
+
# Check helpfulness of a support response
|
|
101
|
+
$ scorable evaluator execute-by-name "Helpfulness" \\
|
|
102
|
+
--request "Where can I find the application instructions?" \\
|
|
103
|
+
--response "You can find the instructions from our Careers page."
|
|
104
|
+
|
|
105
|
+
# Network troubleshooting accuracy check
|
|
106
|
+
$ scorable evaluator execute-by-name "Network Troubleshooting" \\
|
|
107
|
+
--request "My internet is not working." \\
|
|
108
|
+
--response "Let's check the basics. Ensure the Ethernet cable is securely connected, then run \`ping 8.8.8.8\` and share the results."
|
|
109
|
+
|
|
110
|
+
# Faithfulness against retrieved context
|
|
111
|
+
$ scorable evaluator execute-by-name "Faithfulness" \\
|
|
112
|
+
--request "What is your return policy for electronics?" \\
|
|
113
|
+
--response "You can return electronics within 30 days, unused and in original packaging." \\
|
|
114
|
+
--contexts '["Returns for electronics: 30 days, unused, original packaging, valid receipt required."]'
|
|
115
|
+
|
|
116
|
+
# Multi-turn conversation
|
|
117
|
+
$ scorable evaluator execute-by-name "Helpfulness" \\
|
|
118
|
+
--turns '[{"role":"user","content":"Hello, I need help with my order"},{"role":"assistant","content":"I\\'d be happy to help! What\\'s your order number?"},{"role":"user","content":"It\\'s ORDER-12345"}]'
|
|
119
|
+
|
|
120
|
+
# Pipe a response from your app via stdin
|
|
121
|
+
$ ./my-app respond "Do you offer refunds?" | \\
|
|
122
|
+
scorable evaluator execute-by-name "Helpfulness" --request "Do you offer refunds?"`)
|
|
123
|
+
.action(async (evaluatorName, opts) => {
|
|
124
|
+
try {
|
|
125
|
+
await executeEvaluatorByName(evaluatorName, opts);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
handleSdkError(e);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
declare function readStdinDefault(): Promise<string>;
|
|
3
|
+
export declare function executeEvaluator(evaluatorId: string, opts: {
|
|
4
|
+
request?: string;
|
|
5
|
+
response?: string;
|
|
6
|
+
turns?: string;
|
|
7
|
+
contexts?: string;
|
|
8
|
+
expectedOutput?: string;
|
|
9
|
+
tag?: string[];
|
|
10
|
+
userId?: string;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
systemPrompt?: string;
|
|
13
|
+
variables?: string;
|
|
14
|
+
}, readStdin?: typeof readStdinDefault): Promise<void>;
|
|
15
|
+
export declare function registerExecuteCommand(evaluator: Command): void;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAgF/D"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
|
|
3
|
+
import { isTurnArray, isStringArray, isStringRecord } from "../../utils.js";
|
|
4
|
+
async function readStdinDefault() {
|
|
5
|
+
const chunks = [];
|
|
6
|
+
for await (const chunk of process.stdin)
|
|
7
|
+
chunks.push(chunk);
|
|
8
|
+
return Buffer.concat(chunks).toString().trim();
|
|
9
|
+
}
|
|
10
|
+
export async function executeEvaluator(evaluatorId, opts, readStdin = readStdinDefault) {
|
|
11
|
+
const apiKey = await requireApiKey();
|
|
12
|
+
let response = opts.response;
|
|
13
|
+
if (!opts.request && !response && !opts.turns && !process.stdin.isTTY) {
|
|
14
|
+
response = await readStdin();
|
|
15
|
+
}
|
|
16
|
+
if (!opts.request && !response && !opts.turns) {
|
|
17
|
+
printError("Either --request, --response, or --turns must be provided.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const payload = {};
|
|
21
|
+
if (opts.request)
|
|
22
|
+
payload.request = opts.request;
|
|
23
|
+
if (response)
|
|
24
|
+
payload.response = response;
|
|
25
|
+
if (opts.expectedOutput)
|
|
26
|
+
payload.expected_output = opts.expectedOutput;
|
|
27
|
+
if (opts.tag?.length)
|
|
28
|
+
payload.tags = opts.tag;
|
|
29
|
+
if (opts.userId)
|
|
30
|
+
payload.user_id = opts.userId;
|
|
31
|
+
if (opts.sessionId)
|
|
32
|
+
payload.session_id = opts.sessionId;
|
|
33
|
+
if (opts.systemPrompt)
|
|
34
|
+
payload.system_prompt = opts.systemPrompt;
|
|
35
|
+
if (opts.turns) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(opts.turns);
|
|
38
|
+
if (!isTurnArray(parsed)) {
|
|
39
|
+
printError("Invalid JSON for --turns.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
payload.turns = parsed;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
printError("Invalid JSON for --turns.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (opts.contexts) {
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(opts.contexts);
|
|
52
|
+
if (!isStringArray(parsed)) {
|
|
53
|
+
printError("Invalid JSON for --contexts. Skipping.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
payload.contexts = parsed;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
printError("Invalid JSON for --contexts. Skipping.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (opts.variables) {
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(opts.variables);
|
|
66
|
+
if (!isStringRecord(parsed)) {
|
|
67
|
+
printError("Invalid JSON for --variables.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
payload.variables = parsed;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
printError("Invalid JSON for --variables.");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
printInfo(`Attempting to execute evaluator ${evaluatorId} with payload:`);
|
|
78
|
+
printJson(payload);
|
|
79
|
+
const client = getSdkClient(apiKey);
|
|
80
|
+
const result = await client.evaluators.execute(evaluatorId, payload);
|
|
81
|
+
printSuccess("Evaluator execution successful!");
|
|
82
|
+
printJson(result);
|
|
83
|
+
}
|
|
84
|
+
export function registerExecuteCommand(evaluator) {
|
|
85
|
+
evaluator
|
|
86
|
+
.command("execute <evaluatorId>")
|
|
87
|
+
.description("Execute an evaluator with interaction details")
|
|
88
|
+
.option("--request <text>", "Request text")
|
|
89
|
+
.option("--response <text>", "Response text to evaluate")
|
|
90
|
+
.option("--contexts <json>", "JSON list of context strings. E.g., '[\"ctx1\"]'")
|
|
91
|
+
.option("--expected-output <text>", "Expected output text")
|
|
92
|
+
.option("--tag <tag>", "Add one or more tags", (v, a) => [...a, v], [])
|
|
93
|
+
.option("--user-id <id>", "User identifier for tracking purposes")
|
|
94
|
+
.option("--session-id <id>", "Session identifier for tracking purposes")
|
|
95
|
+
.option("--system-prompt <text>", "System prompt that was used for the LLM call")
|
|
96
|
+
.option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
|
|
97
|
+
.option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
|
|
98
|
+
.addHelpText("after", `
|
|
99
|
+
Examples:
|
|
100
|
+
# Check helpfulness of a support response
|
|
101
|
+
$ scorable evaluator execute <evaluatorId> \\
|
|
102
|
+
--request "Where can I find the application instructions?" \\
|
|
103
|
+
--response "You can find the instructions from our Careers page."
|
|
104
|
+
|
|
105
|
+
# Evaluate network troubleshooting response
|
|
106
|
+
$ scorable evaluator execute <evaluatorId> \\
|
|
107
|
+
--request "My internet is not working." \\
|
|
108
|
+
--response "Let's check the basics. Ensure the Ethernet cable is securely connected, then run \`ping 8.8.8.8\` in a terminal and share the results."
|
|
109
|
+
|
|
110
|
+
# RAG faithfulness check with context documents
|
|
111
|
+
$ scorable evaluator execute <evaluatorId> \\
|
|
112
|
+
--request "Was the number of pensioners working above 100k in 2023?" \\
|
|
113
|
+
--response "Yes, 150,000 pensioners were working in 2023." \\
|
|
114
|
+
--expected-output "In 2023, 150k pensioners were still working." \\
|
|
115
|
+
--contexts '["More than 150,000 pensioners were employed in 2023, the centre\\'s statistics reveal."]'
|
|
116
|
+
|
|
117
|
+
# Multi-turn conversation evaluation
|
|
118
|
+
$ scorable evaluator execute <evaluatorId> \\
|
|
119
|
+
--turns '[{"role":"user","content":"Hello, I need help with my order"},{"role":"assistant","content":"I\\'d be happy to help! What\\'s your order number?"},{"role":"user","content":"It\\'s ORDER-12345"},{"role":"assistant","content":"I found your order. It\\'s currently in transit."}]'
|
|
120
|
+
|
|
121
|
+
# With custom template variables and tracking
|
|
122
|
+
$ scorable evaluator execute <evaluatorId> \\
|
|
123
|
+
--request "How do I cancel my subscription?" \\
|
|
124
|
+
--response "You can cancel anytime from account settings under billing." \\
|
|
125
|
+
--variables '{"topic":"subscription"}' \\
|
|
126
|
+
--user-id user_123 --session-id session_abc --tag production`)
|
|
127
|
+
.action(async (evaluatorId, opts) => {
|
|
128
|
+
try {
|
|
129
|
+
await executeEvaluator(evaluatorId, opts);
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
handleSdkError(e);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAiB3D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { requireApiKey, getSdkClient } from "../../auth.js";
|
|
2
|
+
import { printInfo, printSuccess, printJson, handleSdkError } from "../../output.js";
|
|
3
|
+
export function registerGetCommand(evaluator) {
|
|
4
|
+
evaluator
|
|
5
|
+
.command("get <evaluatorId>")
|
|
6
|
+
.description("Get a specific evaluator by its ID")
|
|
7
|
+
.action(async (evaluatorId) => {
|
|
8
|
+
const apiKey = await requireApiKey();
|
|
9
|
+
printInfo(`Fetching evaluator with ID: ${evaluatorId}...`);
|
|
10
|
+
try {
|
|
11
|
+
const client = getSdkClient(apiKey);
|
|
12
|
+
const result = await client.evaluators.get(evaluatorId);
|
|
13
|
+
printSuccess(`Evaluator '${result.name}' details:`);
|
|
14
|
+
printJson(result);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
handleSdkError(e);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAahE"}
|