orizu 0.3.4 → 0.3.5
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 +15 -0
- package/dist/index.js +192 -7
- package/dist/preview-runtime.js +857 -0
- package/package.json +10 -1
- package/src/index.ts +217 -8
- package/src/preview-runtime.ts +976 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/cli.py +2 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/optimizer.py +22 -56
- package/vendor/orizu-gepa-python/src/orizu_gepa/reflection.py +31 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orizu",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,5 +18,14 @@
|
|
|
18
18
|
"build": "tsc -p tsconfig.json",
|
|
19
19
|
"prepack": "node scripts/vendor-gepa-python.mjs",
|
|
20
20
|
"postpack": "node scripts/vendor-gepa-python.mjs --clean"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@playwright/test": "^1.60.0",
|
|
24
|
+
"@tailwindcss/postcss": "^4.1.7",
|
|
25
|
+
"esbuild": "^0.25.8",
|
|
26
|
+
"postcss": "^8.5.6",
|
|
27
|
+
"react": "19.2.6",
|
|
28
|
+
"react-dom": "19.2.6",
|
|
29
|
+
"tailwindcss": "^4.1.10"
|
|
21
30
|
}
|
|
22
31
|
}
|
package/src/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { parseDatasetFile } from './file-parser.js'
|
|
|
24
24
|
import { streamJsonlRowChunks } from './jsonl-stream.js'
|
|
25
25
|
import { parseDatasetReference } from './dataset-download.js'
|
|
26
26
|
import { parseGlobalFlags } from './global-flags.js'
|
|
27
|
+
import { runLocalAppPreview } from './preview-runtime.js'
|
|
27
28
|
import {
|
|
28
29
|
assertSecureTokenTransport,
|
|
29
30
|
authedFetch,
|
|
@@ -163,6 +164,12 @@ interface ScorerSummary {
|
|
|
163
164
|
implementationKind: string
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
interface ScoreSubmitInput {
|
|
168
|
+
resultsJsonl?: string
|
|
169
|
+
aggregate?: Record<string, unknown>
|
|
170
|
+
aggregateWarning?: string
|
|
171
|
+
}
|
|
172
|
+
|
|
166
173
|
interface RunnerExecContext {
|
|
167
174
|
prompt: {
|
|
168
175
|
body: string | null
|
|
@@ -263,7 +270,12 @@ function printVersion() {
|
|
|
263
270
|
}
|
|
264
271
|
|
|
265
272
|
function printUsage() {
|
|
266
|
-
printLine(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n --version, -v Print the orizu CLI version\n\norizu commands:\n\n orizu login [--no-prompt-if-logged-in]\n orizu logout\n orizu whoami\n orizu env [--project <team/project>] [--project-id <projectId>]\n orizu log <event_type> --run-id <id> --sequence <n> --payload @event.json\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu prompts list --project <team/project>\n orizu prompts comments <prompt-id-or-name> --project <team/project> [--label <label> | --version <id>] [--json]\n orizu prompts pull <prompt-id-or-name> --project <team/project> --out <dir> [--label <label> | --version <id>] [--json]\n orizu prompts push <dir> [--runner-version <id>] [--project <team/project>] [--parent <version-id>] [--json]\n orizu prompts labels set <prompt-name> <label> --version <version-id> [--project <team/project>] [--json]\n orizu prompts scorers set-headline <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu prompts scorers add <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu scorers list --project <team/project>\n orizu scorers register --project <team/project> --name <name> --manifest <manifest.json> [--prompt-version <id>] [--runner-version <id>] [--label <label>] [--json]\n orizu scorers detail <scorer-id-or-name> --project <team/project> [--json]\n orizu scorers labels set <scorer-name> <label> --version <scorer-version-id> [--project <team/project>] [--json]\n orizu scores submit <results.jsonl|results.json> --scorer-version <id> --subject-version <prompt-version-id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu judges list --project <team/project>\n orizu judges pull <judge-id-or-name> --project <team/project> --out <dir> [--label <label> | --version <id>] [--json]\n orizu judges push <dir> [--runner-version <id>] [--project <team/project>] [--parent <version-id>] [--json]\n orizu runners push <dir> [--project <team/project>] [--name <name>] [--label <label>] [--json]\n orizu runners exec (--prompt <prompt-version-id> | --prompt-version <id> --runner-version <id> | --scorer-version <id>) --dataset-version <id> --split-set <id-or-name> --split <name> [--runner-dir <dir>] --out <results.jsonl|results.jsonl.gz>\n orizu optimizers push <dir> [--project <team/project>] [--name <name>] [--label <label>] [--json]\n orizu runs submit <results.jsonl|results.jsonl.gz> --prompt-version <id> --runner-version <id> --dataset-version <id> --split-set <id> --split <name> [--project <team/project>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu apps detail --app <appId> [--project <team/project>] [--json]\n orizu apps export [--app <appId>] [--project <team/project>] [--version <n>] [--out <path>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userIdOrEmail1,userIdOrEmail2> [--version <n>] [--instructions <text>] [--labels-per-item <n>] [--json]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu tasks pause --task <taskId>\n orizu tasks unpause --task <taskId>\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>] [--readme-file <README.md> | --readme-text <markdown>]\n orizu datasets push <path> [--project <team/project>] [--name <name>] [--readme-file <README.md> | --readme-text <markdown>] [--json]\n orizu datasets readme set <datasetId|dataset-name> [--project <team/project>] (--readme-file <README.md> | --readme-text <markdown>) [--json]\n orizu datasets versions create <datasetId|dataset-name> [--project <team/project>] [--label <label>] [--readme-file <README.md> | --readme-text <markdown>] [--json]\n orizu datasets splits create <datasetVersionId> [--from-file <split.json>] [--json]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets edit-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] --row-ids <id1,id2>\n orizu datasets delete [--dataset <datasetId|datasetUrl>] [--project <team/project>]\n orizu datasets lock [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--reason <text>]\n orizu datasets clone [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--name <name>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`)
|
|
273
|
+
printLine(`orizu global options:\n\n --local Use http://localhost:3000\n --server <url> Use a specific server origin (for example: https://preview.example.com)\n --version, -v Print the orizu CLI version\n\norizu commands:\n\n orizu login [--no-prompt-if-logged-in]\n orizu logout\n orizu whoami\n orizu env [--project <team/project>] [--project-id <projectId>]\n orizu log <event_type> --run-id <id> --sequence <n> --payload @event.json\n orizu teams list\n orizu teams create [--name <name>]\n orizu teams members list [--team <teamSlug>]\n orizu teams members add --email <email> [--team <teamSlug>]\n orizu teams members remove --email <email> [--team <teamSlug>]\n orizu teams members role --team <teamSlug> --email <email> --role <admin|member>\n orizu projects list [--team <teamSlug>]\n orizu projects create --name <name> [--team <teamSlug>]\n orizu prompts list --project <team/project>\n orizu prompts comments <prompt-id-or-name> --project <team/project> [--label <label> | --version <id>] [--json]\n orizu prompts pull <prompt-id-or-name> --project <team/project> --out <dir> [--label <label> | --version <id>] [--json]\n orizu prompts push <dir> [--runner-version <id>] [--project <team/project>] [--parent <version-id>] [--json]\n orizu prompts labels set <prompt-name> <label> --version <version-id> [--project <team/project>] [--json]\n orizu prompts scorers set-headline <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu prompts scorers add <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu scorers list --project <team/project>\n orizu scorers register --project <team/project> --name <name> --manifest <manifest.json> [--prompt-version <id>] [--runner-version <id>] [--label <label>] [--json]\n orizu scorers detail <scorer-id-or-name> --project <team/project> [--json]\n orizu scorers labels set <scorer-name> <label> --version <scorer-version-id> [--project <team/project>] [--json]\n orizu scorers exec --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) --dataset-version <id> --split-set <id> --split <name> [--subject-results <jsonl>] [--dependency-score-run <alias=id>] [--dependency-results <alias=path>] [--no-submit] [--out <score.json>] [--project <team/project>] [--json]\n orizu scores submit <results.jsonl|results.json> --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) [--aggregate] [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]\n orizu judges list --project <team/project>\n orizu judges pull <judge-id-or-name> --project <team/project> --out <dir> [--label <label> | --version <id>] [--json]\n orizu judges push <dir> [--runner-version <id>] [--project <team/project>] [--parent <version-id>] [--json]\n orizu runners push <dir> [--project <team/project>] [--name <name>] [--label <label>] [--json]\n orizu runners exec (--prompt <prompt-version-id> | --prompt-version <id> --runner-version <id> | --scorer-version <id>) --dataset-version <id> --split-set <id-or-name> --split <name> [--runner-dir <dir>] --out <results.jsonl|results.jsonl.gz>\n orizu optimizers push <dir> [--project <team/project>] [--name <name>] [--label <label>] [--json]\n orizu runs submit <results.jsonl|results.jsonl.gz> --prompt-version <id> --runner-version <id> --dataset-version <id> --split-set <id> --split <name> [--project <team/project>]\n orizu apps list [--project <team/project>]\n orizu apps create --project <team/project> --name <name> --dataset <datasetId> --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps update [--app <appId>] [--project <team/project>] --file <path> --input-schema <json-path> --output-schema <json-path> [--component <name>]\n orizu apps link-dataset --dataset <datasetId> [--app <appId>] [--project <team/project>] [--version <n>]\n orizu apps detail --app <appId> [--project <team/project>] [--json]\n orizu apps export [--app <appId>] [--project <team/project>] [--version <n>] [--out <path>]\n orizu tasks list [--project <team/project>]\n orizu tasks create --project <team/project> --dataset <datasetId> --app <appId> --title <title> --assignees <userIdOrEmail1,userIdOrEmail2> [--version <n>] [--instructions <text>] [--labels-per-item <n>] [--json]\n orizu tasks assign --task <taskId> --assignees <userId1,userId2>\n orizu tasks status --task <taskId> [--json]\n orizu tasks pause --task <taskId>\n orizu tasks unpause --task <taskId>\n orizu datasets upload --file <path> [--project <team/project>] [--name <name>] [--readme-file <README.md> | --readme-text <markdown>]\n orizu datasets push <path> [--project <team/project>] [--name <name>] [--readme-file <README.md> | --readme-text <markdown>] [--json]\n orizu datasets readme set <datasetId|dataset-name> [--project <team/project>] (--readme-file <README.md> | --readme-text <markdown>) [--json]\n orizu datasets versions create <datasetId|dataset-name> [--project <team/project>] [--label <label>] [--readme-file <README.md> | --readme-text <markdown>] [--json]\n orizu datasets splits create <datasetVersionId> [--from-file <split.json>] [--json]\n orizu datasets download [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--format <csv|json|jsonl>] [--out <path>]\n orizu datasets append [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets edit-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] --file <path>\n orizu datasets delete-rows [--dataset <datasetId|datasetUrl>] [--project <team/project>] --row-ids <id1,id2>\n orizu datasets delete [--dataset <datasetId|datasetUrl>] [--project <team/project>]\n orizu datasets lock [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--reason <text>]\n orizu datasets clone [--dataset <datasetId|datasetUrl>] [--project <team/project>] [--name <name>]\n orizu tasks export [--task <taskId>] [--format <csv|json|jsonl>] [--out <path>]`)
|
|
274
|
+
printPreviewUsage()
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function printPreviewUsage() {
|
|
278
|
+
printLine(`\nLocal app preview:\n\n orizu apps preview --file <path> --input-schema <json-path> --output-schema <json-path> --sample-row <json-path> [--screenshot <png-path>] [--headed] [--keep-open] [--component <name>]`)
|
|
267
279
|
}
|
|
268
280
|
|
|
269
281
|
function printOptimizationUsage() {
|
|
@@ -2001,18 +2013,23 @@ async function submitScoreResults() {
|
|
|
2001
2013
|
const candidateId = getArg('--candidate')
|
|
2002
2014
|
|
|
2003
2015
|
if (!resultsPath || !scorerVersionId || (!subjectPromptVersionId && (!optimizationRunId || !candidateId))) {
|
|
2004
|
-
throw new Error('Usage: orizu scores submit <results.jsonl|results.json> --project <team/project> --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) [--dataset-version <id> --split-set <id> --split <name>] [--json]')
|
|
2016
|
+
throw new Error('Usage: orizu scores submit <results.jsonl|results.json> --project <team/project> --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) [--aggregate] [--dataset-version <id> --split-set <id> --split <name>] [--json]')
|
|
2005
2017
|
}
|
|
2006
2018
|
|
|
2007
2019
|
const resultBytes = readSourceBytes(resultsPath)
|
|
2008
2020
|
const raw = resultsPath.endsWith('.gz')
|
|
2009
2021
|
? gunzipSync(resultBytes).toString('utf8')
|
|
2010
2022
|
: resultBytes.toString('utf8')
|
|
2011
|
-
const
|
|
2023
|
+
const scoreInput = normalizeScoreResultsInput(resultsPath, raw, hasArg('--aggregate'))
|
|
2024
|
+
if (scoreInput.aggregateWarning) {
|
|
2025
|
+
console.warn(scoreInput.aggregateWarning)
|
|
2026
|
+
}
|
|
2027
|
+
const aggregatePayload = scoreInput.aggregate || {}
|
|
2012
2028
|
const response = await authedFetch(`/api/cli/scores/submit?project=${encodeURIComponent(project)}`, {
|
|
2013
2029
|
method: 'POST',
|
|
2014
2030
|
headers: { 'Content-Type': 'application/json' },
|
|
2015
2031
|
body: JSON.stringify({
|
|
2032
|
+
...aggregatePayload,
|
|
2016
2033
|
scorerVersionId,
|
|
2017
2034
|
subjectPromptVersionId: subjectPromptVersionId || undefined,
|
|
2018
2035
|
datasetVersionId: getArg('--dataset-version') || undefined,
|
|
@@ -2020,7 +2037,7 @@ async function submitScoreResults() {
|
|
|
2020
2037
|
splitName: getArg('--split') || undefined,
|
|
2021
2038
|
optimizationRunId: optimizationRunId || undefined,
|
|
2022
2039
|
candidateId: candidateId || undefined,
|
|
2023
|
-
resultsJsonl,
|
|
2040
|
+
resultsJsonl: scoreInput.resultsJsonl,
|
|
2024
2041
|
}),
|
|
2025
2042
|
})
|
|
2026
2043
|
|
|
@@ -2046,23 +2063,159 @@ async function submitScoreResults() {
|
|
|
2046
2063
|
)
|
|
2047
2064
|
}
|
|
2048
2065
|
|
|
2049
|
-
function
|
|
2066
|
+
function looksLikeAggregateScoreObject(value: Record<string, unknown>): boolean {
|
|
2067
|
+
return (
|
|
2068
|
+
value.scoreValue !== undefined ||
|
|
2069
|
+
value.score_value !== undefined ||
|
|
2070
|
+
value.diagnostics !== undefined ||
|
|
2071
|
+
value.feedbackSummary !== undefined ||
|
|
2072
|
+
value.feedback_summary !== undefined ||
|
|
2073
|
+
value.rowEvidence !== undefined ||
|
|
2074
|
+
value.row_evidence !== undefined ||
|
|
2075
|
+
value.dependencyScoreRunIds !== undefined ||
|
|
2076
|
+
value.dependency_score_run_ids !== undefined
|
|
2077
|
+
)
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
function numberFromUnknown(value: unknown): number | null {
|
|
2081
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value
|
|
2082
|
+
if (typeof value === 'string' && value.trim()) {
|
|
2083
|
+
const parsed = Number(value)
|
|
2084
|
+
return Number.isFinite(parsed) ? parsed : null
|
|
2085
|
+
}
|
|
2086
|
+
if (typeof value === 'boolean') return value ? 1 : 0
|
|
2087
|
+
return null
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
function normalizeScoreResultsInput(sourcePath: string, raw: string, aggregateMode = false): ScoreSubmitInput {
|
|
2050
2091
|
const logicalPath = sourcePath.endsWith('.gz') ? sourcePath.slice(0, -3) : sourcePath
|
|
2051
|
-
if (!logicalPath.endsWith('.json')) return raw
|
|
2092
|
+
if (!logicalPath.endsWith('.json')) return { resultsJsonl: raw }
|
|
2052
2093
|
|
|
2053
2094
|
try {
|
|
2054
2095
|
const parsed = JSON.parse(raw) as unknown
|
|
2096
|
+
if (aggregateMode) {
|
|
2097
|
+
if (!isRecord(parsed)) {
|
|
2098
|
+
throw new Error('Aggregate score results JSON must be an object')
|
|
2099
|
+
}
|
|
2100
|
+
return { aggregate: parsed }
|
|
2101
|
+
}
|
|
2102
|
+
if (isRecord(parsed) && looksLikeAggregateScoreObject(parsed)) {
|
|
2103
|
+
return {
|
|
2104
|
+
aggregate: parsed,
|
|
2105
|
+
aggregateWarning: 'Warning: aggregate score JSON detected. Pass --aggregate to make this explicit.',
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2055
2108
|
const rows = Array.isArray(parsed) ? parsed : [parsed]
|
|
2056
2109
|
if (rows.some(row => !isRecord(row))) {
|
|
2057
2110
|
throw new Error('JSON score results must be an object or an array of objects')
|
|
2058
2111
|
}
|
|
2059
|
-
return rows.map(row => JSON.stringify(row)).join('\n')
|
|
2112
|
+
return { resultsJsonl: rows.map(row => JSON.stringify(row)).join('\n') }
|
|
2060
2113
|
} catch (error) {
|
|
2061
2114
|
const message = error instanceof Error ? error.message : String(error)
|
|
2062
2115
|
throw new Error(`Invalid score results JSON '${sourcePath}': ${message}`)
|
|
2063
2116
|
}
|
|
2064
2117
|
}
|
|
2065
2118
|
|
|
2119
|
+
function readOptionalJsonlFile(pathArg: string | null): string | undefined {
|
|
2120
|
+
if (!pathArg) return undefined
|
|
2121
|
+
const bytes = readSourceBytes(pathArg)
|
|
2122
|
+
return pathArg.endsWith('.gz')
|
|
2123
|
+
? gunzipSync(bytes).toString('utf8')
|
|
2124
|
+
: bytes.toString('utf8')
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
function parseAliasAssignments(value: string | null): Record<string, string> {
|
|
2128
|
+
const result: Record<string, string> = {}
|
|
2129
|
+
if (!value) return result
|
|
2130
|
+
for (const item of parseCommaSeparated(value)) {
|
|
2131
|
+
const equalsIndex = item.indexOf('=')
|
|
2132
|
+
if (equalsIndex <= 0 || equalsIndex === item.length - 1) {
|
|
2133
|
+
throw new Error(`Expected alias assignment in form alias=value, got '${item}'`)
|
|
2134
|
+
}
|
|
2135
|
+
result[item.slice(0, equalsIndex)] = item.slice(equalsIndex + 1)
|
|
2136
|
+
}
|
|
2137
|
+
return result
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
function readDependencyResultAssignments(value: string | null): Record<string, string> | undefined {
|
|
2141
|
+
const assignments = parseAliasAssignments(value)
|
|
2142
|
+
const result: Record<string, string> = {}
|
|
2143
|
+
for (const [alias, path] of Object.entries(assignments)) {
|
|
2144
|
+
result[alias] = readOptionalJsonlFile(path) || ''
|
|
2145
|
+
}
|
|
2146
|
+
return Object.keys(result).length > 0 ? result : undefined
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
async function execScorer() {
|
|
2150
|
+
const project = getArg('--project') || await resolveProjectSlug(null)
|
|
2151
|
+
const scorerVersionId = getArg('--scorer-version')
|
|
2152
|
+
const subjectPromptVersionId = getArg('--subject-version') || getArg('--prompt-version')
|
|
2153
|
+
const optimizationRunId = getArg('--optimization-run')
|
|
2154
|
+
const candidateId = getArg('--candidate')
|
|
2155
|
+
const datasetVersionId = getArg('--dataset-version')
|
|
2156
|
+
const splitSetId = getArg('--split-set')
|
|
2157
|
+
const splitName = getArg('--split')
|
|
2158
|
+
const outPath = getArg('--out')
|
|
2159
|
+
|
|
2160
|
+
if (
|
|
2161
|
+
!scorerVersionId ||
|
|
2162
|
+
(!subjectPromptVersionId && (!optimizationRunId || !candidateId)) ||
|
|
2163
|
+
!datasetVersionId ||
|
|
2164
|
+
!splitSetId ||
|
|
2165
|
+
!splitName
|
|
2166
|
+
) {
|
|
2167
|
+
throw new Error('Usage: orizu scorers exec --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) --dataset-version <id> --split-set <id> --split <name> [--subject-results <jsonl>] [--dependency-score-run <alias=id>] [--dependency-results <alias=path>] [--no-submit] [--out <score.json>] [--project <team/project>] [--json]')
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
const response = await authedFetch(`/api/cli/scorers/exec?project=${encodeURIComponent(project)}`, {
|
|
2171
|
+
method: 'POST',
|
|
2172
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2173
|
+
body: JSON.stringify({
|
|
2174
|
+
scorerVersionId,
|
|
2175
|
+
subjectPromptVersionId: subjectPromptVersionId || undefined,
|
|
2176
|
+
optimizationRunId: optimizationRunId || undefined,
|
|
2177
|
+
candidateId: candidateId || undefined,
|
|
2178
|
+
datasetVersionId,
|
|
2179
|
+
splitSetId,
|
|
2180
|
+
splitName,
|
|
2181
|
+
submit: !hasArg('--no-submit'),
|
|
2182
|
+
reuseExisting: !hasArg('--no-reuse-existing'),
|
|
2183
|
+
subjectResultsJsonl: readOptionalJsonlFile(getArg('--subject-results') || getArg('--outputs')),
|
|
2184
|
+
dependencyScoreRunIds: parseAliasAssignments(getArg('--dependency-score-run') || getArg('--dependency-score-runs')),
|
|
2185
|
+
dependencyResultsJsonl: readDependencyResultAssignments(getArg('--dependency-results')),
|
|
2186
|
+
}),
|
|
2187
|
+
})
|
|
2188
|
+
|
|
2189
|
+
if (!response.ok) {
|
|
2190
|
+
throw new Error(`Failed to execute scorer: ${await response.text()}`)
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
const data = await parseJsonResponse<Record<string, unknown>>(response, 'Scorer exec')
|
|
2194
|
+
if (outPath) {
|
|
2195
|
+
writeFileSync(expandHomePath(outPath), `${JSON.stringify(data.scoreResult || data, null, 2)}\n`)
|
|
2196
|
+
}
|
|
2197
|
+
if (hasJsonFlag()) {
|
|
2198
|
+
printJson(data)
|
|
2199
|
+
return
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
const scoreRun = isRecord(data.scoreRun) ? data.scoreRun : null
|
|
2203
|
+
const scoreResult = isRecord(data.scoreResult) ? data.scoreResult : null
|
|
2204
|
+
const scoreValue = scoreRun
|
|
2205
|
+
? scoreRun.scoreValue
|
|
2206
|
+
: scoreResult
|
|
2207
|
+
? scoreResult.scoreValue
|
|
2208
|
+
: null
|
|
2209
|
+
if (scoreRun && typeof scoreRun.id === 'string') {
|
|
2210
|
+
printLine(`Executed scorer ${sanitizeTerminalText(scorerVersionId)} -> score ${sanitizeTerminalText(scoreRun.id)} (${formatPercent(numberFromUnknown(scoreValue))})`)
|
|
2211
|
+
} else {
|
|
2212
|
+
printLine(`Executed scorer ${sanitizeTerminalText(scorerVersionId)} (${formatPercent(numberFromUnknown(scoreValue))})`)
|
|
2213
|
+
}
|
|
2214
|
+
if (outPath) {
|
|
2215
|
+
printLine(`Wrote scorer result to ${sanitizeTerminalText(outPath)}`)
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2066
2219
|
type OptimizationLifecycleAction = 'pause' | 'resume' | 'finish' | 'fail' | 'cancel'
|
|
2067
2220
|
const OPTIMIZATION_REPORT_MAX_BYTES = 2 * 1024 * 1024
|
|
2068
2221
|
|
|
@@ -2789,15 +2942,61 @@ async function createAppFromFile() {
|
|
|
2789
2942
|
}
|
|
2790
2943
|
|
|
2791
2944
|
const data = await parseJsonResponse<{
|
|
2792
|
-
app: { id: string; name: string; versionNum: number; componentName?: string }
|
|
2945
|
+
app: { id: string; name: string; versionNum: number; componentName?: string; url?: string }
|
|
2793
2946
|
warnings?: string[]
|
|
2794
2947
|
}>(response, 'App create')
|
|
2795
2948
|
printLine(`Created app ${sanitizeTerminalText(data.app.name)} (${sanitizeTerminalText(data.app.id)}) v${data.app.versionNum}`)
|
|
2949
|
+
if (data.app.url) {
|
|
2950
|
+
printLine(`View app: ${formatTerminalLink(data.app.url)}`)
|
|
2951
|
+
}
|
|
2796
2952
|
if (data.warnings?.length) {
|
|
2797
2953
|
printLine(`Warnings: ${sanitizeTerminalText(data.warnings.join('; '))}`)
|
|
2798
2954
|
}
|
|
2799
2955
|
}
|
|
2800
2956
|
|
|
2957
|
+
async function previewAppFromFile() {
|
|
2958
|
+
const filePath = getArg('--file')
|
|
2959
|
+
const inputSchemaPath = getArg('--input-schema')
|
|
2960
|
+
const outputSchemaPath = getArg('--output-schema')
|
|
2961
|
+
const sampleRowPath = getArg('--sample-row')
|
|
2962
|
+
const screenshotPath = getArg('--screenshot')
|
|
2963
|
+
const component = getArg('--component') || undefined
|
|
2964
|
+
const headed = hasArg('--headed')
|
|
2965
|
+
const keepOpen = hasArg('--keep-open')
|
|
2966
|
+
|
|
2967
|
+
if (!filePath || !inputSchemaPath || !outputSchemaPath || !sampleRowPath) {
|
|
2968
|
+
throw new Error('Usage: orizu apps preview --file <path> --input-schema <json-path> --output-schema <json-path> --sample-row <json-path> [--screenshot <png-path>] [--headed] [--keep-open] [--component <name>]')
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
const expandedFilePath = realpathSync(expandHomePath(filePath))
|
|
2972
|
+
const inputJsonSchema = readJsonFile(inputSchemaPath)
|
|
2973
|
+
const outputJsonSchema = readJsonFile(outputSchemaPath)
|
|
2974
|
+
const sampleRow = readJsonFile(sampleRowPath)
|
|
2975
|
+
const expandedScreenshotPath = screenshotPath ? expandHomePath(screenshotPath) : undefined
|
|
2976
|
+
|
|
2977
|
+
const result = await runLocalAppPreview({
|
|
2978
|
+
filePath: expandedFilePath,
|
|
2979
|
+
inputSchema: inputJsonSchema,
|
|
2980
|
+
outputSchema: outputJsonSchema,
|
|
2981
|
+
sampleRow,
|
|
2982
|
+
screenshotPath: expandedScreenshotPath,
|
|
2983
|
+
componentName: component,
|
|
2984
|
+
headed,
|
|
2985
|
+
keepOpen,
|
|
2986
|
+
})
|
|
2987
|
+
|
|
2988
|
+
printLine(`Preview rendered: ${formatTerminalLink(result.url)}`)
|
|
2989
|
+
if (result.screenshotPath) {
|
|
2990
|
+
printLine(`Screenshot: ${sanitizeTerminalText(result.screenshotPath)}`)
|
|
2991
|
+
}
|
|
2992
|
+
if (headed || keepOpen) {
|
|
2993
|
+
printLine('Headed preview is running. Close Chromium or stop the command when you are done.')
|
|
2994
|
+
}
|
|
2995
|
+
if (result.warnings.length > 0) {
|
|
2996
|
+
printLine(`Warnings: ${sanitizeTerminalText(result.warnings.join('; '))}`)
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
|
|
2801
3000
|
async function updateAppFromFile() {
|
|
2802
3001
|
const filePath = getArg('--file')
|
|
2803
3002
|
const inputSchemaPath = getArg('--input-schema')
|
|
@@ -4388,6 +4587,11 @@ export async function main(rawArgs = process.argv.slice(2)) {
|
|
|
4388
4587
|
return
|
|
4389
4588
|
}
|
|
4390
4589
|
|
|
4590
|
+
if (command === 'scorers' && subcommand === 'exec') {
|
|
4591
|
+
await execScorer()
|
|
4592
|
+
return
|
|
4593
|
+
}
|
|
4594
|
+
|
|
4391
4595
|
if (command === 'runners' && subcommand === 'push') {
|
|
4392
4596
|
await pushRunnerArtifact('runner')
|
|
4393
4597
|
return
|
|
@@ -4452,6 +4656,11 @@ export async function main(rawArgs = process.argv.slice(2)) {
|
|
|
4452
4656
|
return
|
|
4453
4657
|
}
|
|
4454
4658
|
|
|
4659
|
+
if (command === 'apps' && subcommand === 'preview') {
|
|
4660
|
+
await previewAppFromFile()
|
|
4661
|
+
return
|
|
4662
|
+
}
|
|
4663
|
+
|
|
4455
4664
|
if (command === 'apps' && subcommand === 'update') {
|
|
4456
4665
|
await updateAppFromFile()
|
|
4457
4666
|
return
|