@root-signals/scorable-cli 0.5.0 → 0.7.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 CHANGED
@@ -289,8 +289,8 @@ inputs:
289
289
  # dataset_id: "<uuid>"
290
290
 
291
291
  models:
292
- - gpt-4o-mini
293
- - gemini-2.5-flash-lite
292
+ - gpt-5.4
293
+ - gemini-3-flash
294
294
 
295
295
  evaluators:
296
296
  - name: Precision
@@ -1 +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;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkF9D"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA+E9D"}
@@ -9,7 +9,6 @@ export function registerCreateCommand(evaluator) {
9
9
  .requiredOption("--scoring-criteria <text>", "The scoring criteria prompt. Must contain {{ request }} and/or {{ response }} as placeholders.")
10
10
  .option("--intent <intent>", "The intent for the evaluator (mutually exclusive with --objective-id)")
11
11
  .option("--objective-id <id>", "Objective ID (mutually exclusive with --intent)")
12
- .option("--system-message <text>", "System message for the evaluator")
13
12
  .option("--models <json>", "JSON array of model names, in priority order. E.g., '[\"gpt-5-mini\"]'")
14
13
  .option("--overwrite", "Overwrite if evaluator with same name exists")
15
14
  .option("--objective-version-id <id>", "Objective version ID")
@@ -32,8 +31,6 @@ export function registerCreateCommand(evaluator) {
32
31
  payload.intent = opts.intent;
33
32
  if (opts.objectiveId)
34
33
  payload.objective_id = opts.objectiveId;
35
- if (opts.systemMessage)
36
- payload.system_message = opts.systemMessage;
37
34
  if (opts.overwrite !== undefined)
38
35
  payload.overwrite = opts.overwrite;
39
36
  if (opts.objectiveVersionId)
@@ -11,6 +11,7 @@ export declare function executeEvaluator(evaluatorId: string, opts: {
11
11
  sessionId?: string;
12
12
  systemPrompt?: string;
13
13
  variables?: string;
14
+ fileIds?: string;
14
15
  }, readStdin?: typeof readStdinDefault): Promise<void>;
15
16
  export declare function registerExecuteCommand(evaluator: Command): void;
16
17
  export {};
@@ -1 +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;AAOpC,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,CA2Ef;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAgF/D"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,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;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAwFf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2F/D"}
@@ -75,6 +75,19 @@ export async function executeEvaluator(evaluatorId, opts, readStdin = readStdinD
75
75
  return;
76
76
  }
77
77
  }
78
+ if (opts.fileIds) {
79
+ let parsed;
80
+ try {
81
+ parsed = JSON.parse(opts.fileIds);
82
+ }
83
+ catch {
84
+ throw new Error("Invalid JSON for --file-ids.");
85
+ }
86
+ if (!isStringArray(parsed)) {
87
+ throw new Error("Invalid JSON for --file-ids. Expected array of UUID strings.");
88
+ }
89
+ payload.file_ids = parsed;
90
+ }
78
91
  const spinner = ora("Running evaluator...").start();
79
92
  try {
80
93
  const client = getSdkClient(apiKey);
@@ -102,6 +115,7 @@ export function registerExecuteCommand(evaluator) {
102
115
  .option("--system-prompt <text>", "System prompt that was used for the LLM call")
103
116
  .option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
104
117
  .option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
118
+ .option("--file-ids <json>", "JSON array of file UUIDs from 'scorable file upload'. E.g., '[\"uuid1\"]'")
105
119
  .addHelpText("after", `
106
120
  Examples:
107
121
  # Check helpfulness of a support response
@@ -130,7 +144,13 @@ Examples:
130
144
  --request "How do I cancel my subscription?" \\
131
145
  --response "You can cancel anytime from account settings under billing." \\
132
146
  --variables '{"topic":"subscription"}' \\
133
- --user-id user_123 --session-id session_abc --tag production`)
147
+ --user-id user_123 --session-id session_abc --tag production
148
+
149
+ # Evaluate a response with an uploaded image
150
+ $ scorable evaluator execute <evaluatorId> \\
151
+ --request "Does the chart match the data?" \\
152
+ --response "Yes, the Q1 figures align." \\
153
+ --file-ids '["550e8400-e29b-41d4-a716-446655440000"]'`)
134
154
  .action(async (evaluatorId, opts) => {
135
155
  try {
136
156
  await executeEvaluator(evaluatorId, opts);
@@ -1 +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;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2D9D"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwD9D"}
@@ -7,7 +7,6 @@ export function registerUpdateCommand(evaluator) {
7
7
  .description("Update an existing evaluator (PATCH)")
8
8
  .option("--name <name>", "The new name for the evaluator")
9
9
  .option("--scoring-criteria <text>", "The new scoring criteria (prompt text)")
10
- .option("--system-message <text>", "The new system message")
11
10
  .option("--models <json>", "JSON array of model names. E.g., '[\"gpt-4\"]'")
12
11
  .option("--objective-id <id>", "The new objective ID")
13
12
  .option("--objective-version-id <id>", "The new objective version ID")
@@ -18,8 +17,6 @@ export function registerUpdateCommand(evaluator) {
18
17
  payload.name = opts.name;
19
18
  if (opts.scoringCriteria !== undefined)
20
19
  payload.prompt = opts.scoringCriteria;
21
- if (opts.systemMessage !== undefined)
22
- payload.system_message = opts.systemMessage;
23
20
  if (opts.objectiveId !== undefined)
24
21
  payload.objective_id = opts.objectiveId;
25
22
  if (opts.objectiveVersionId !== undefined)
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerFileCommands(program: Command): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/file/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAI3D"}
@@ -0,0 +1,5 @@
1
+ import { registerUploadCommand } from "./upload.js";
2
+ export function registerFileCommands(program) {
3
+ const file = program.command("file").description("Manage uploaded files");
4
+ registerUploadCommand(file);
5
+ }
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ export declare function uploadFile(filePath: string): Promise<void>;
3
+ export declare function registerUploadCommand(file: Command): void;
4
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/commands/file/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CA2BzD"}
@@ -0,0 +1,54 @@
1
+ import ora from "ora";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { requireApiKey } from "../../auth.js";
5
+ import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
6
+ import { getSdkClient } from "../../auth.js";
7
+ export async function uploadFile(filePath) {
8
+ const apiKey = await requireApiKey();
9
+ if (!fs.existsSync(filePath)) {
10
+ printError(`File not found: ${filePath}`);
11
+ process.exit(1);
12
+ }
13
+ const client = getSdkClient(apiKey);
14
+ const fileName = path.basename(filePath);
15
+ const fileBuffer = fs.readFileSync(filePath);
16
+ const blob = new Blob([fileBuffer]);
17
+ const spinner = ora(`Uploading ${fileName}...`).start();
18
+ try {
19
+ const result = await client.files.upload(blob, fileName);
20
+ spinner.stop();
21
+ printSuccess("File uploaded successfully!");
22
+ printJson(result);
23
+ }
24
+ catch (e) {
25
+ spinner.stop();
26
+ throw e;
27
+ }
28
+ }
29
+ export function registerUploadCommand(file) {
30
+ file
31
+ .command("upload <filePath>")
32
+ .description("Upload a file (PDF, PNG, JPG, JPEG, WEBP, SVG) for use in evaluator execution")
33
+ .addHelpText("after", `
34
+ Examples:
35
+ # Upload a PDF document
36
+ $ scorable file upload ./report.pdf
37
+
38
+ # Upload an image
39
+ $ scorable file upload ./chart.png
40
+
41
+ # Use the returned ID in evaluator execution
42
+ $ scorable evaluator execute <evaluatorId> \\
43
+ --request "Does the chart match?" \\
44
+ --response "Yes." \\
45
+ --file-ids '["<id from upload>"]'`)
46
+ .action(async (filePath) => {
47
+ try {
48
+ await uploadFile(filePath);
49
+ }
50
+ catch (e) {
51
+ handleSdkError(e);
52
+ }
53
+ });
54
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA4H5D"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA2H5D"}
@@ -30,7 +30,6 @@ offer to connect the guest with a human agent when uncertain."`)
30
30
  printError(`Invalid --visibility value: "${visibility}". Accepted values: private, public.`);
31
31
  throw new CliError(1, "invalid_visibility");
32
32
  }
33
- const apiVisibility = visibility === "private" ? "unlisted" : "public";
34
33
  const apiKey = await requireApiKey();
35
34
  let extra_contexts;
36
35
  if (opts.extraContexts) {
@@ -45,9 +44,9 @@ offer to connect the guest with a human agent when uncertain."`)
45
44
  const spinner = ora("Generating judge (this may take a moment)...").start();
46
45
  try {
47
46
  const client = getSdkClient(apiKey);
48
- const result = await client.judges.generate({
47
+ const result = (await client.judges.generate({
49
48
  intent: opts.intent,
50
- visibility: apiVisibility,
49
+ visibility: visibility,
51
50
  overwrite: opts.overwrite,
52
51
  name: opts.name,
53
52
  stage: opts.stage,
@@ -59,7 +58,7 @@ offer to connect the guest with a human agent when uncertain."`)
59
58
  reasoning_effort: opts.reasoningEffort,
60
59
  },
61
60
  }),
62
- });
61
+ }));
63
62
  spinner.stop();
64
63
  if (result.error_code === "multiple_stages") {
65
64
  printWarning("Multiple evaluation stages detected. Each judge covers one stage.");
@@ -12,7 +12,7 @@ export function registerListCommand(judge) {
12
12
  .option("--ordering <field>", "Which field to use for ordering the results")
13
13
  .action(async (opts) => {
14
14
  const apiKey = await requireApiKey();
15
- const params = { is_public: false };
15
+ const params = {};
16
16
  if (opts.pageSize !== undefined)
17
17
  params.page_size = opts.pageSize;
18
18
  if (opts.cursor !== undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgDpC,wBAAgB,SAAS,IAAI,OAAO,CAoBnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiDpC,wBAAgB,SAAS,IAAI,OAAO,CAqBnC"}
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { registerEvaluatorCommands } from "./commands/evaluator/index.js";
10
10
  import { registerExecutionLogCommands } from "./commands/execution-log/index.js";
11
11
  import { registerAuthCommands } from "./commands/auth/index.js";
12
12
  import { registerSkillsAddCommand } from "./commands/skills-add.js";
13
+ import { registerFileCommands } from "./commands/file/index.js";
13
14
  const { version } = createRequire(import.meta.url)("../package.json");
14
15
  function buildBanner(ver) {
15
16
  const logo = chalk.hex("#4D9FFF");
@@ -61,6 +62,7 @@ export function createCli() {
61
62
  registerExecutionLogCommands(program);
62
63
  registerAuthCommands(program);
63
64
  registerSkillsAddCommand(program);
65
+ registerFileCommands(program);
64
66
  return program;
65
67
  }
66
68
  if (realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@root-signals/scorable-cli",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "CLI for Scorable",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Scorable",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@inquirer/prompts": "^8.3.2",
34
- "@root-signals/scorable": "^0.4.0",
34
+ "@root-signals/scorable": "^0.6.0",
35
35
  "chalk": "^5.6.2",
36
36
  "cli-table3": "^0.6.5",
37
37
  "commander": "^14.0.3",
@@ -44,7 +44,7 @@
44
44
  "oxfmt": "^0.41.0",
45
45
  "oxlint": "^1.56.0",
46
46
  "typescript": "^5.9.3",
47
- "vitest": "^4.1.0"
47
+ "vitest": "^4.1.5"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=20"