@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.
Files changed (73) hide show
  1. package/README.md +94 -13
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/commands/evaluator/create.d.ts +3 -0
  4. package/dist/commands/evaluator/create.d.ts.map +1 -0
  5. package/dist/commands/evaluator/create.js +62 -0
  6. package/dist/commands/evaluator/delete.d.ts +3 -0
  7. package/dist/commands/evaluator/delete.d.ts.map +1 -0
  8. package/dist/commands/evaluator/delete.js +34 -0
  9. package/dist/commands/evaluator/duplicate.d.ts +3 -0
  10. package/dist/commands/evaluator/duplicate.d.ts.map +1 -0
  11. package/dist/commands/evaluator/duplicate.js +20 -0
  12. package/dist/commands/evaluator/execute-by-name.d.ts +17 -0
  13. package/dist/commands/evaluator/execute-by-name.d.ts.map +1 -0
  14. package/dist/commands/evaluator/execute-by-name.js +131 -0
  15. package/dist/commands/evaluator/execute.d.ts +17 -0
  16. package/dist/commands/evaluator/execute.d.ts.map +1 -0
  17. package/dist/commands/evaluator/execute.js +135 -0
  18. package/dist/commands/evaluator/get.d.ts +3 -0
  19. package/dist/commands/evaluator/get.d.ts.map +1 -0
  20. package/dist/commands/evaluator/get.js +20 -0
  21. package/dist/commands/evaluator/index.d.ts +3 -0
  22. package/dist/commands/evaluator/index.d.ts.map +1 -0
  23. package/dist/commands/evaluator/index.js +21 -0
  24. package/dist/commands/evaluator/list.d.ts +3 -0
  25. package/dist/commands/evaluator/list.d.ts.map +1 -0
  26. package/dist/commands/evaluator/list.js +39 -0
  27. package/dist/commands/evaluator/update.d.ts +3 -0
  28. package/dist/commands/evaluator/update.d.ts.map +1 -0
  29. package/dist/commands/evaluator/update.js +51 -0
  30. package/dist/commands/execution-log/get.d.ts +3 -0
  31. package/dist/commands/execution-log/get.d.ts.map +1 -0
  32. package/dist/commands/execution-log/get.js +19 -0
  33. package/dist/commands/execution-log/index.d.ts +3 -0
  34. package/dist/commands/execution-log/index.d.ts.map +1 -0
  35. package/dist/commands/execution-log/index.js +9 -0
  36. package/dist/commands/execution-log/list.d.ts +3 -0
  37. package/dist/commands/execution-log/list.d.ts.map +1 -0
  38. package/dist/commands/execution-log/list.js +60 -0
  39. package/dist/commands/judge/create.d.ts.map +1 -1
  40. package/dist/commands/judge/create.js +2 -5
  41. package/dist/commands/judge/delete.d.ts.map +1 -1
  42. package/dist/commands/judge/delete.js +5 -4
  43. package/dist/commands/judge/duplicate.d.ts.map +1 -1
  44. package/dist/commands/judge/duplicate.js +2 -5
  45. package/dist/commands/judge/exec-openai-generic.d.ts.map +1 -1
  46. package/dist/commands/judge/exec-openai-generic.js +2 -5
  47. package/dist/commands/judge/exec-openai.d.ts.map +1 -1
  48. package/dist/commands/judge/exec-openai.js +2 -5
  49. package/dist/commands/judge/execute-by-name.d.ts +1 -0
  50. package/dist/commands/judge/execute-by-name.d.ts.map +1 -1
  51. package/dist/commands/judge/execute-by-name.js +54 -16
  52. package/dist/commands/judge/execute.d.ts +1 -0
  53. package/dist/commands/judge/execute.d.ts.map +1 -1
  54. package/dist/commands/judge/execute.js +61 -16
  55. package/dist/commands/judge/get.d.ts.map +1 -1
  56. package/dist/commands/judge/get.js +2 -5
  57. package/dist/commands/judge/list.d.ts.map +1 -1
  58. package/dist/commands/judge/list.js +15 -34
  59. package/dist/commands/judge/update.d.ts.map +1 -1
  60. package/dist/commands/judge/update.js +2 -5
  61. package/dist/commands/prompt-test/run.d.ts.map +1 -1
  62. package/dist/commands/prompt-test/run.js +5 -6
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +4 -0
  65. package/dist/output.d.ts +4 -1
  66. package/dist/output.d.ts.map +1 -1
  67. package/dist/output.js +47 -4
  68. package/dist/types.d.ts +0 -15
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/utils.d.ts +5 -0
  71. package/dist/utils.d.ts.map +1 -0
  72. package/dist/utils.js +18 -0
  73. package/package.json +2 -4
@@ -0,0 +1,21 @@
1
+ import { Command } from "commander";
2
+ import { registerListCommand } from "./list.js";
3
+ import { registerGetCommand } from "./get.js";
4
+ import { registerCreateCommand } from "./create.js";
5
+ import { registerUpdateCommand } from "./update.js";
6
+ import { registerDeleteCommand } from "./delete.js";
7
+ import { registerExecuteCommand } from "./execute.js";
8
+ import { registerExecuteByNameCommand } from "./execute-by-name.js";
9
+ import { registerDuplicateCommand } from "./duplicate.js";
10
+ export function registerEvaluatorCommands(program) {
11
+ const evaluator = new Command("evaluator").description("Evaluator management commands");
12
+ registerListCommand(evaluator);
13
+ registerGetCommand(evaluator);
14
+ registerCreateCommand(evaluator);
15
+ registerUpdateCommand(evaluator);
16
+ registerDeleteCommand(evaluator);
17
+ registerExecuteCommand(evaluator);
18
+ registerExecuteByNameCommand(evaluator);
19
+ registerDuplicateCommand(evaluator);
20
+ program.addCommand(evaluator);
21
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerListCommand(evaluator: Command): void;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2C5D"}
@@ -0,0 +1,39 @@
1
+ import { requireApiKey, getSdkClient } from "../../auth.js";
2
+ import { printInfo, printMessage, printEvaluatorTable, handleSdkError } from "../../output.js";
3
+ export function registerListCommand(evaluator) {
4
+ evaluator
5
+ .command("list")
6
+ .description("List evaluators with optional filters")
7
+ .option("--page-size <number>", "Number of results to return per page", parseInt)
8
+ .option("--cursor <cursor>", "The pagination cursor value")
9
+ .option("--search <term>", "A search term to filter by")
10
+ .option("--name <name>", "Filter by exact evaluator name")
11
+ .option("--ordering <field>", "Which field to use for ordering the results")
12
+ .action(async (opts) => {
13
+ const apiKey = await requireApiKey();
14
+ const params = {};
15
+ if (opts.pageSize !== undefined)
16
+ params.page_size = opts.pageSize;
17
+ if (opts.cursor !== undefined)
18
+ params.cursor = opts.cursor;
19
+ if (opts.search !== undefined)
20
+ params.search = opts.search;
21
+ if (opts.name !== undefined)
22
+ params.name = opts.name;
23
+ if (opts.ordering !== undefined)
24
+ params.ordering = opts.ordering;
25
+ printInfo(`Fetching evaluators with params: ${JSON.stringify(params)}...`);
26
+ try {
27
+ const client = getSdkClient(apiKey);
28
+ const response = await client.evaluators.list(params);
29
+ if (!response.results.length) {
30
+ printMessage("No evaluators found.");
31
+ return;
32
+ }
33
+ printEvaluatorTable(response.results, response.next);
34
+ }
35
+ catch (e) {
36
+ handleSdkError(e);
37
+ }
38
+ });
39
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerUpdateCommand(evaluator: Command): void;
3
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2D9D"}
@@ -0,0 +1,51 @@
1
+ import { requireApiKey, getSdkClient } from "../../auth.js";
2
+ import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
3
+ export function registerUpdateCommand(evaluator) {
4
+ evaluator
5
+ .command("update <evaluatorId>")
6
+ .description("Update an existing evaluator (PATCH)")
7
+ .option("--name <name>", "The new name for the evaluator")
8
+ .option("--scoring-criteria <text>", "The new scoring criteria (prompt text)")
9
+ .option("--system-message <text>", "The new system message")
10
+ .option("--models <json>", "JSON array of model names. E.g., '[\"gpt-4\"]'")
11
+ .option("--objective-id <id>", "The new objective ID")
12
+ .option("--objective-version-id <id>", "The new objective version ID")
13
+ .action(async (evaluatorId, opts) => {
14
+ const apiKey = await requireApiKey();
15
+ const payload = {};
16
+ if (opts.name !== undefined)
17
+ payload.name = opts.name;
18
+ if (opts.scoringCriteria !== undefined)
19
+ payload.prompt = opts.scoringCriteria;
20
+ if (opts.systemMessage !== undefined)
21
+ payload.system_message = opts.systemMessage;
22
+ if (opts.objectiveId !== undefined)
23
+ payload.objective_id = opts.objectiveId;
24
+ if (opts.objectiveVersionId !== undefined)
25
+ payload.objective_version_id = opts.objectiveVersionId;
26
+ if (opts.models !== undefined) {
27
+ try {
28
+ payload.models = JSON.parse(opts.models);
29
+ }
30
+ catch {
31
+ printError("Invalid JSON format for --models.");
32
+ return;
33
+ }
34
+ }
35
+ if (Object.keys(payload).length === 0) {
36
+ printInfo("No update parameters provided. Aborting.");
37
+ return;
38
+ }
39
+ printInfo(`Attempting to update evaluator ${evaluatorId} with PATCH payload:`);
40
+ printJson(payload);
41
+ try {
42
+ const client = getSdkClient(apiKey);
43
+ const result = await client.evaluators.update(evaluatorId, payload);
44
+ printSuccess(`Evaluator ${evaluatorId} updated successfully!`);
45
+ printJson(result);
46
+ }
47
+ catch (e) {
48
+ handleSdkError(e);
49
+ }
50
+ });
51
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerGetCommand(executionLog: Command): void;
3
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/execution-log/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAgB9D"}
@@ -0,0 +1,19 @@
1
+ import { requireApiKey, getSdkClient } from "../../auth.js";
2
+ import { printInfo, printJson, handleSdkError } from "../../output.js";
3
+ export function registerGetCommand(executionLog) {
4
+ executionLog
5
+ .command("get <logId>")
6
+ .description("Get a specific execution log by its ID")
7
+ .action(async (logId) => {
8
+ const apiKey = await requireApiKey();
9
+ printInfo(`Fetching execution log with ID: ${logId}...`);
10
+ try {
11
+ const client = getSdkClient(apiKey);
12
+ const result = await client.executionLogs.get(logId);
13
+ printJson(result);
14
+ }
15
+ catch (e) {
16
+ handleSdkError(e);
17
+ }
18
+ });
19
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerExecutionLogCommands(program: Command): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/execution-log/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOnE"}
@@ -0,0 +1,9 @@
1
+ import { Command } from "commander";
2
+ import { registerListCommand } from "./list.js";
3
+ import { registerGetCommand } from "./get.js";
4
+ export function registerExecutionLogCommands(program) {
5
+ const executionLog = new Command("execution-log").description("Execution log commands");
6
+ registerListCommand(executionLog);
7
+ registerGetCommand(executionLog);
8
+ program.addCommand(executionLog);
9
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerListCommand(executionLog: Command): void;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/execution-log/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAgE/D"}
@@ -0,0 +1,60 @@
1
+ import { requireApiKey, getSdkClient } from "../../auth.js";
2
+ import { printInfo, printMessage, printExecutionLogTable, handleSdkError } from "../../output.js";
3
+ export function registerListCommand(executionLog) {
4
+ executionLog
5
+ .command("list")
6
+ .description("List execution logs with optional filters")
7
+ .option("--page-size <number>", "Number of results to return per page", parseInt)
8
+ .option("--cursor <cursor>", "The pagination cursor value")
9
+ .option("--search <term>", "Search term to filter by evaluator id or name")
10
+ .option("--evaluator-id <id>", "Filter by evaluator ID")
11
+ .option("--judge-id <id>", "Filter by judge ID")
12
+ .option("--model <model>", "Filter by model name")
13
+ .option("--tags <tags>", "Filter by tags (comma-separated)")
14
+ .option("--score-min <number>", "Minimum score filter", parseFloat)
15
+ .option("--score-max <number>", "Maximum score filter", parseFloat)
16
+ .option("--created-at-after <date>", "Filter logs created after this date (ISO 8601)")
17
+ .option("--created-at-before <date>", "Filter logs created before this date (ISO 8601)")
18
+ .option("--owner-email <email>", "Filter by owner email")
19
+ .action(async (opts) => {
20
+ const apiKey = await requireApiKey();
21
+ const params = {};
22
+ if (opts.pageSize !== undefined)
23
+ params.page_size = opts.pageSize;
24
+ if (opts.cursor !== undefined)
25
+ params.cursor = opts.cursor;
26
+ if (opts.search !== undefined)
27
+ params.search = opts.search;
28
+ if (opts.evaluatorId !== undefined)
29
+ params.evaluator_id = opts.evaluatorId;
30
+ if (opts.judgeId !== undefined)
31
+ params.judge_id = opts.judgeId;
32
+ if (opts.model !== undefined)
33
+ params.model = opts.model;
34
+ if (opts.tags !== undefined)
35
+ params.tags = opts.tags;
36
+ if (opts.scoreMin !== undefined)
37
+ params.score_min = opts.scoreMin;
38
+ if (opts.scoreMax !== undefined)
39
+ params.score_max = opts.scoreMax;
40
+ if (opts.createdAtAfter !== undefined)
41
+ params.created_at_after = opts.createdAtAfter;
42
+ if (opts.createdAtBefore !== undefined)
43
+ params.created_at_before = opts.createdAtBefore;
44
+ if (opts.ownerEmail !== undefined)
45
+ params.owner__email = opts.ownerEmail;
46
+ printInfo(`Fetching execution logs...`);
47
+ try {
48
+ const client = getSdkClient(apiKey);
49
+ const response = await client.executionLogs.list(params);
50
+ if (!response.results.length) {
51
+ printMessage("No execution logs found.");
52
+ return;
53
+ }
54
+ printExecutionLogTable(response.results, response.next);
55
+ }
56
+ catch (e) {
57
+ handleSdkError(e);
58
+ }
59
+ });
60
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAgD1D"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA+C1D"}
@@ -1,6 +1,5 @@
1
1
  import { requireApiKey, getSdkClient } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
4
3
  export function registerCreateCommand(judge) {
5
4
  judge
6
5
  .command("create")
@@ -32,9 +31,7 @@ export function registerCreateCommand(judge) {
32
31
  printJson(result);
33
32
  }
34
33
  catch (e) {
35
- if (e instanceof CliError)
36
- throw e;
37
- printError(e instanceof Error ? e.message : String(e));
34
+ handleSdkError(e);
38
35
  }
39
36
  });
40
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA8B1D"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAmC1D"}
@@ -1,5 +1,5 @@
1
1
  import { requireApiKey, getSdkClient } from "../../auth.js";
2
- import { printInfo, printSuccess } from "../../output.js";
2
+ import { printInfo, printSuccess, handleSdkError } from "../../output.js";
3
3
  import { CliError } from "../../types.js";
4
4
  export function registerDeleteCommand(judge) {
5
5
  judge
@@ -9,6 +9,9 @@ export function registerDeleteCommand(judge) {
9
9
  .action(async (judgeId, opts) => {
10
10
  const apiKey = await requireApiKey();
11
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
+ }
12
15
  const { confirm } = await import("@inquirer/prompts");
13
16
  const ok = await confirm({
14
17
  message: "Are you sure you want to delete this judge?",
@@ -25,9 +28,7 @@ export function registerDeleteCommand(judge) {
25
28
  printSuccess(`Judge ${judgeId} deleted successfully.`);
26
29
  }
27
30
  catch (e) {
28
- if (e instanceof CliError)
29
- throw e;
30
- throw new CliError(1, e instanceof Error ? e.message : String(e));
31
+ handleSdkError(e);
31
32
  }
32
33
  });
33
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAkB7D"}
1
+ {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAiB7D"}
@@ -1,6 +1,5 @@
1
1
  import { requireApiKey, getSdkClient } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printJson, handleSdkError } from "../../output.js";
4
3
  export function registerDuplicateCommand(judge) {
5
4
  judge
6
5
  .command("duplicate <judgeId>")
@@ -15,9 +14,7 @@ export function registerDuplicateCommand(judge) {
15
14
  printJson(result);
16
15
  }
17
16
  catch (e) {
18
- if (e instanceof CliError)
19
- throw e;
20
- printError(e instanceof Error ? e.message : String(e));
17
+ handleSdkError(e);
21
18
  }
22
19
  });
23
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"exec-openai-generic.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai-generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA8CrE"}
1
+ {"version":3,"file":"exec-openai-generic.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai-generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA6CrE"}
@@ -1,6 +1,5 @@
1
1
  import { requireApiKey } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printWarning, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printError, printWarning, printJson, handleSdkError, } from "../../output.js";
4
3
  import { apiRequest } from "../../client.js";
5
4
  export function registerExecOpenaiGenericCommand(judge) {
6
5
  judge
@@ -42,9 +41,7 @@ export function registerExecOpenaiGenericCommand(judge) {
42
41
  }
43
42
  }
44
43
  catch (e) {
45
- if (e instanceof CliError)
46
- throw e;
47
- printError(e instanceof Error ? e.message : String(e));
44
+ handleSdkError(e);
48
45
  }
49
46
  });
50
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"exec-openai.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyD9D"}
1
+ {"version":3,"file":"exec-openai.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAwD9D"}
@@ -1,6 +1,5 @@
1
1
  import { requireApiKey } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printWarning, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printError, printWarning, printJson, handleSdkError, } from "../../output.js";
4
3
  import { apiRequest } from "../../client.js";
5
4
  export function registerExecOpenaiCommand(judge) {
6
5
  judge
@@ -42,9 +41,7 @@ export function registerExecOpenaiCommand(judge) {
42
41
  }
43
42
  }
44
43
  catch (e) {
45
- if (e instanceof CliError)
46
- throw e;
47
- printError(e instanceof Error ? e.message : String(e));
44
+ handleSdkError(e);
48
45
  }
49
46
  });
50
47
  }
@@ -3,6 +3,7 @@ declare function readStdinDefault(): Promise<string>;
3
3
  export declare function executeJudgeByName(judgeName: string, opts: {
4
4
  request?: string;
5
5
  response?: string;
6
+ turns?: string;
6
7
  contexts?: string;
7
8
  expectedOutput?: string;
8
9
  tag?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"execute-by-name.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/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,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,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;CACvB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyBjE"}
1
+ {"version":3,"file":"execute-by-name.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/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,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,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;CACvB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyDf;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAkEjE"}
@@ -1,6 +1,6 @@
1
1
  import { requireApiKey, getSdkClient } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
3
+ import { isTurnArray, isStringArray } from "../../utils.js";
4
4
  async function readStdinDefault() {
5
5
  const chunks = [];
6
6
  for await (const chunk of process.stdin)
@@ -10,31 +10,50 @@ async function readStdinDefault() {
10
10
  export async function executeJudgeByName(judgeName, opts, readStdin = readStdinDefault) {
11
11
  const apiKey = await requireApiKey();
12
12
  let response = opts.response;
13
- if (!opts.request && !response && !process.stdin.isTTY) {
13
+ if (!opts.request && !response && !opts.turns && !process.stdin.isTTY) {
14
14
  response = await readStdin();
15
15
  }
16
- if (!opts.request && !response) {
17
- printError("Either --request or --response must be provided.");
16
+ if (!opts.request && !response && !opts.turns) {
17
+ printError("Either --request, --response, or --turns must be provided.");
18
18
  return;
19
19
  }
20
20
  const payload = {};
21
21
  if (opts.request)
22
- payload["request"] = opts.request;
22
+ payload.request = opts.request;
23
23
  if (response)
24
- payload["response"] = response;
24
+ payload.response = response;
25
25
  if (opts.expectedOutput)
26
- payload["expected_output"] = opts.expectedOutput;
26
+ payload.expected_output = opts.expectedOutput;
27
27
  if (opts.tag?.length)
28
- payload["tags"] = opts.tag;
28
+ payload.tags = opts.tag;
29
29
  if (opts.userId)
30
- payload["user_id"] = opts.userId;
30
+ payload.user_id = opts.userId;
31
31
  if (opts.sessionId)
32
- payload["session_id"] = opts.sessionId;
32
+ payload.session_id = opts.sessionId;
33
33
  if (opts.systemPrompt)
34
- payload["system_prompt"] = 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
+ }
35
49
  if (opts.contexts) {
36
50
  try {
37
- payload["contexts"] = JSON.parse(opts.contexts);
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;
38
57
  }
39
58
  catch {
40
59
  printError("Invalid JSON for --contexts. Skipping.");
@@ -60,14 +79,33 @@ export function registerExecuteByNameCommand(judge) {
60
79
  .option("--user-id <id>", "User identifier for tracking purposes")
61
80
  .option("--session-id <id>", "Session identifier for tracking purposes")
62
81
  .option("--system-prompt <text>", "System prompt that was used for the LLM call")
82
+ .option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
83
+ .addHelpText("after", `
84
+ Examples:
85
+ # Evaluate a customer service response
86
+ $ scorable judge execute-by-name "Customer Service Judge" \\
87
+ --request "My order hasn't arrived and it's been two weeks." \\
88
+ --response "I completely understand your frustration. Let me immediately look into your order status and arrange expedited shipping at no extra cost."
89
+
90
+ # With context documents
91
+ $ scorable judge execute-by-name "E-commerce Support Judge" \\
92
+ --request "What's your return policy for electronics?" \\
93
+ --response "You can return electronics within 30 days, unused and in original packaging." \\
94
+ --contexts '["Returns for electronics: 30 days, unused, original packaging, valid receipt required."]'
95
+
96
+ # Multi-turn conversation
97
+ $ scorable judge execute-by-name "Customer Service Judge" \\
98
+ --turns '[{"role":"user","content":"I haven\\'t received my refund and it\\'s been 10 days."},{"role":"assistant","content":"Thank you for contacting us. I will investigate this immediately and provide an update within 24 hours."}]'
99
+
100
+ # Pipe the LLM response from stdin
101
+ $ echo "We offer a 30-day money-back guarantee on all purchases." | \\
102
+ scorable judge execute-by-name "Custom Returns Policy Judge" --request "Do you offer refunds?"`)
63
103
  .action(async (judgeName, opts) => {
64
104
  try {
65
105
  await executeJudgeByName(judgeName, opts);
66
106
  }
67
107
  catch (e) {
68
- if (e instanceof CliError)
69
- throw e;
70
- printError(e instanceof Error ? e.message : String(e));
108
+ handleSdkError(e);
71
109
  }
72
110
  });
73
111
  }
@@ -3,6 +3,7 @@ declare function readStdinDefault(): Promise<string>;
3
3
  export declare function executeJudge(judgeId: string, opts: {
4
4
  request?: string;
5
5
  response?: string;
6
+ turns?: string;
6
7
  contexts?: string;
7
8
  expectedOutput?: string;
8
9
  tag?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,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;CACvB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyB3D"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,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;CACvB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyDf;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyE3D"}
@@ -1,6 +1,6 @@
1
1
  import { requireApiKey, getSdkClient } from "../../auth.js";
2
- import { printInfo, printSuccess, printError, printJson } from "../../output.js";
3
- import { CliError } from "../../types.js";
2
+ import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
3
+ import { isTurnArray, isStringArray } from "../../utils.js";
4
4
  async function readStdinDefault() {
5
5
  const chunks = [];
6
6
  for await (const chunk of process.stdin)
@@ -10,31 +10,50 @@ async function readStdinDefault() {
10
10
  export async function executeJudge(judgeId, opts, readStdin = readStdinDefault) {
11
11
  const apiKey = await requireApiKey();
12
12
  let response = opts.response;
13
- if (!opts.request && !response && !process.stdin.isTTY) {
13
+ if (!opts.request && !response && !opts.turns && !process.stdin.isTTY) {
14
14
  response = await readStdin();
15
15
  }
16
- if (!opts.request && !response) {
17
- printError("Either --request or --response must be provided.");
16
+ if (!opts.request && !response && !opts.turns) {
17
+ printError("Either --request, --response, or --turns must be provided.");
18
18
  return;
19
19
  }
20
20
  const payload = {};
21
21
  if (opts.request)
22
- payload["request"] = opts.request;
22
+ payload.request = opts.request;
23
23
  if (response)
24
- payload["response"] = response;
24
+ payload.response = response;
25
25
  if (opts.expectedOutput)
26
- payload["expected_output"] = opts.expectedOutput;
26
+ payload.expected_output = opts.expectedOutput;
27
27
  if (opts.tag?.length)
28
- payload["tags"] = opts.tag;
28
+ payload.tags = opts.tag;
29
29
  if (opts.userId)
30
- payload["user_id"] = opts.userId;
30
+ payload.user_id = opts.userId;
31
31
  if (opts.sessionId)
32
- payload["session_id"] = opts.sessionId;
32
+ payload.session_id = opts.sessionId;
33
33
  if (opts.systemPrompt)
34
- payload["system_prompt"] = 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
+ }
35
49
  if (opts.contexts) {
36
50
  try {
37
- payload["contexts"] = JSON.parse(opts.contexts);
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;
38
57
  }
39
58
  catch {
40
59
  printError("Invalid JSON for --contexts. Skipping.");
@@ -60,14 +79,40 @@ export function registerExecuteCommand(judge) {
60
79
  .option("--user-id <id>", "User identifier for tracking purposes")
61
80
  .option("--session-id <id>", "Session identifier for tracking purposes")
62
81
  .option("--system-prompt <text>", "System prompt that was used for the LLM call")
82
+ .option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
83
+ .addHelpText("after", `
84
+ Examples:
85
+ # Evaluate a customer service response about return policy
86
+ $ scorable judge execute <judgeId> \\
87
+ --request "What's your return policy?" \\
88
+ --response "We have a 30-day return policy. If you're not satisfied, you can return within 30 days for a full refund."
89
+
90
+ # RAG evaluation with context documents
91
+ $ scorable judge execute <judgeId> \\
92
+ --request "What's your return policy for electronics?" \\
93
+ --response "You can return electronics within 30 days, unused and in original packaging." \\
94
+ --contexts '["Returns for electronics are accepted within 30 days. Item must be unused, in original packaging, with valid receipt."]'
95
+
96
+ # Multi-turn conversation evaluation
97
+ $ scorable judge execute <judgeId> \\
98
+ --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."}]'
99
+
100
+ # With tracking metadata and tags
101
+ $ scorable judge execute <judgeId> \\
102
+ --request "How do I reset my password?" \\
103
+ --response "Click the Forgot Password link on the login page and follow the instructions." \\
104
+ --user-id user_123 --session-id session_abc \\
105
+ --tag production --tag v1.23
106
+
107
+ # Pipe the LLM response from stdin
108
+ $ echo "You can cancel your subscription from account settings under billing." | \\
109
+ scorable judge execute <judgeId> --request "How do I cancel my subscription?"`)
63
110
  .action(async (judgeId, opts) => {
64
111
  try {
65
112
  await executeJudge(judgeId, opts);
66
113
  }
67
114
  catch (e) {
68
- if (e instanceof CliError)
69
- throw e;
70
- printError(e instanceof Error ? e.message : String(e));
115
+ handleSdkError(e);
71
116
  }
72
117
  });
73
118
  }