@prismatic-io/lux 0.0.2-preview.15 → 0.0.2-preview.16
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/lib/answerers/claude-code/index.d.ts +14 -2
- package/lib/answerers/claude-code/index.d.ts.map +1 -1
- package/lib/answerers/claude-code/index.js +3 -3
- package/lib/answerers/claude-code/index.js.map +1 -1
- package/lib/answerers/persona/index.d.ts +28 -2
- package/lib/answerers/persona/index.d.ts.map +1 -1
- package/lib/answerers/persona/index.js +3 -3
- package/lib/answerers/persona/index.js.map +1 -1
- package/lib/answerers/terminal/index.d.ts +8 -2
- package/lib/answerers/terminal/index.d.ts.map +1 -1
- package/lib/answerers/terminal/index.js +3 -2
- package/lib/answerers/terminal/index.js.map +1 -1
- package/lib/assertions/core/resource-checks.d.ts.map +1 -1
- package/lib/assertions/core/resource-checks.js +3 -5
- package/lib/assertions/core/resource-checks.js.map +1 -1
- package/lib/assertions/rubric/index.d.ts.map +1 -1
- package/lib/assertions/rubric/index.js +7 -1
- package/lib/assertions/rubric/index.js.map +1 -1
- package/lib/assertions/rubric/internal.d.ts +16 -5
- package/lib/assertions/rubric/internal.d.ts.map +1 -1
- package/lib/assertions/rubric/internal.js +10 -6
- package/lib/assertions/rubric/internal.js.map +1 -1
- package/lib/authoring.d.ts +32 -2
- package/lib/authoring.d.ts.map +1 -1
- package/lib/authoring.js +33 -1
- package/lib/authoring.js.map +1 -1
- package/lib/cli/bin.js +2 -13
- package/lib/cli/bin.js.map +1 -1
- package/lib/cli/command-runtime.d.ts +3 -3
- package/lib/cli/command-runtime.d.ts.map +1 -1
- package/lib/cli/command-runtime.js +17 -6
- package/lib/cli/command-runtime.js.map +1 -1
- package/lib/cli/init-templates.d.ts +11 -0
- package/lib/cli/init-templates.d.ts.map +1 -0
- package/lib/cli/init-templates.js +207 -0
- package/lib/cli/init-templates.js.map +1 -0
- package/lib/cli/init.d.ts +7 -0
- package/lib/cli/init.d.ts.map +1 -1
- package/lib/cli/init.js +23 -173
- package/lib/cli/init.js.map +1 -1
- package/lib/cli/output-schemas.d.ts +1399 -0
- package/lib/cli/output-schemas.d.ts.map +1 -0
- package/lib/cli/output-schemas.js +91 -0
- package/lib/cli/output-schemas.js.map +1 -0
- package/lib/cli/program.d.ts +135 -4
- package/lib/cli/program.d.ts.map +1 -1
- package/lib/cli/program.js +725 -520
- package/lib/cli/program.js.map +1 -1
- package/lib/cli/render/reporter.d.ts.map +1 -1
- package/lib/cli/render/reporter.js +24 -4
- package/lib/cli/render/reporter.js.map +1 -1
- package/lib/cli/run-options.d.ts +0 -4
- package/lib/cli/run-options.d.ts.map +1 -1
- package/lib/cli/run-options.js +8 -19
- package/lib/cli/run-options.js.map +1 -1
- package/lib/cli/view.d.ts +5 -3
- package/lib/cli/view.d.ts.map +1 -1
- package/lib/cli/view.js +120 -78
- package/lib/cli/view.js.map +1 -1
- package/lib/core/annotation.d.ts +6 -2
- package/lib/core/annotation.d.ts.map +1 -1
- package/lib/core/annotation.js +2 -1
- package/lib/core/annotation.js.map +1 -1
- package/lib/core/answerer.d.ts +12 -0
- package/lib/core/answerer.d.ts.map +1 -1
- package/lib/core/answerer.js +2 -0
- package/lib/core/answerer.js.map +1 -1
- package/lib/core/assertion.d.ts +3 -0
- package/lib/core/assertion.d.ts.map +1 -1
- package/lib/core/assertion.js +3 -0
- package/lib/core/assertion.js.map +1 -1
- package/lib/core/case.d.ts +24 -2
- package/lib/core/case.d.ts.map +1 -1
- package/lib/core/case.js +5 -1
- package/lib/core/case.js.map +1 -1
- package/lib/core/driver.d.ts +40 -0
- package/lib/core/driver.d.ts.map +1 -1
- package/lib/core/driver.js +12 -0
- package/lib/core/driver.js.map +1 -1
- package/lib/core/environment.d.ts +18 -0
- package/lib/core/environment.d.ts.map +1 -0
- package/lib/core/environment.js +21 -0
- package/lib/core/environment.js.map +1 -0
- package/lib/core/evaluation-clusters.d.ts +17 -0
- package/lib/core/evaluation-clusters.d.ts.map +1 -0
- package/lib/core/evaluation-clusters.js +23 -0
- package/lib/core/evaluation-clusters.js.map +1 -0
- package/lib/core/experiment.d.ts +11 -0
- package/lib/core/experiment.d.ts.map +1 -1
- package/lib/core/experiment.js +31 -17
- package/lib/core/experiment.js.map +1 -1
- package/lib/core/file-tree.d.ts +7 -0
- package/lib/core/file-tree.d.ts.map +1 -0
- package/lib/core/file-tree.js +35 -0
- package/lib/core/file-tree.js.map +1 -0
- package/lib/core/index.d.ts +1 -0
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -0
- package/lib/core/index.js.map +1 -1
- package/lib/core/lifecycle-fixtures.d.ts.map +1 -1
- package/lib/core/lifecycle-fixtures.js +4 -2
- package/lib/core/lifecycle-fixtures.js.map +1 -1
- package/lib/core/platform-process.d.ts +5 -1
- package/lib/core/platform-process.d.ts.map +1 -1
- package/lib/core/platform-process.js +48 -10
- package/lib/core/platform-process.js.map +1 -1
- package/lib/core/run.d.ts +93 -1
- package/lib/core/run.d.ts.map +1 -1
- package/lib/core/run.js +16 -0
- package/lib/core/run.js.map +1 -1
- package/lib/core/usage.d.ts +5 -0
- package/lib/core/usage.d.ts.map +1 -1
- package/lib/core/usage.js +3 -0
- package/lib/core/usage.js.map +1 -1
- package/lib/drivers/claude-code/index.d.ts +65 -2
- package/lib/drivers/claude-code/index.d.ts.map +1 -1
- package/lib/drivers/claude-code/index.js +30 -3
- package/lib/drivers/claude-code/index.js.map +1 -1
- package/lib/drivers/codex/app-events.d.ts.map +1 -1
- package/lib/drivers/codex/app-events.js +41 -30
- package/lib/drivers/codex/app-events.js.map +1 -1
- package/lib/drivers/codex/exec-events.d.ts +4 -0
- package/lib/drivers/codex/exec-events.d.ts.map +1 -0
- package/lib/drivers/codex/exec-events.js +230 -0
- package/lib/drivers/codex/exec-events.js.map +1 -0
- package/lib/drivers/codex/index.d.ts +76 -4
- package/lib/drivers/codex/index.d.ts.map +1 -1
- package/lib/drivers/codex/index.js +35 -232
- package/lib/drivers/codex/index.js.map +1 -1
- package/lib/drivers/cursor/acp-transport.d.ts +38 -0
- package/lib/drivers/cursor/acp-transport.d.ts.map +1 -0
- package/lib/drivers/cursor/acp-transport.js +152 -0
- package/lib/drivers/cursor/acp-transport.js.map +1 -0
- package/lib/drivers/cursor/config.d.ts +22 -0
- package/lib/drivers/cursor/config.d.ts.map +1 -0
- package/lib/drivers/cursor/config.js +26 -0
- package/lib/drivers/cursor/config.js.map +1 -0
- package/lib/drivers/cursor/events.d.ts +13 -0
- package/lib/drivers/cursor/events.d.ts.map +1 -0
- package/lib/drivers/cursor/events.js +73 -0
- package/lib/drivers/cursor/events.js.map +1 -0
- package/lib/drivers/cursor/index.d.ts +37 -0
- package/lib/drivers/cursor/index.d.ts.map +1 -0
- package/lib/drivers/cursor/index.js +276 -0
- package/lib/drivers/cursor/index.js.map +1 -0
- package/lib/drivers/cursor/interaction.d.ts +7 -0
- package/lib/drivers/cursor/interaction.d.ts.map +1 -0
- package/lib/drivers/cursor/interaction.js +66 -0
- package/lib/drivers/cursor/interaction.js.map +1 -0
- package/lib/drivers/mcp/index.d.ts +35 -2
- package/lib/drivers/mcp/index.d.ts.map +1 -1
- package/lib/drivers/mcp/index.js +16 -3
- package/lib/drivers/mcp/index.js.map +1 -1
- package/lib/drivers/shared/experiment-behavior.d.ts +13 -0
- package/lib/drivers/shared/experiment-behavior.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-behavior.js +197 -0
- package/lib/drivers/shared/experiment-behavior.js.map +1 -0
- package/lib/drivers/shared/experiment-policy.d.ts +4 -0
- package/lib/drivers/shared/experiment-policy.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-policy.js +143 -0
- package/lib/drivers/shared/experiment-policy.js.map +1 -0
- package/lib/drivers/subprocess/index.d.ts +37 -2
- package/lib/drivers/subprocess/index.d.ts.map +1 -1
- package/lib/drivers/subprocess/index.js +46 -6
- package/lib/drivers/subprocess/index.js.map +1 -1
- package/lib/index.d.ts +6 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -2
- package/lib/index.js.map +1 -1
- package/lib/orchestrator/annotation-loader.d.ts +6 -2
- package/lib/orchestrator/annotation-loader.d.ts.map +1 -1
- package/lib/orchestrator/annotation-loader.js +8 -0
- package/lib/orchestrator/annotation-loader.js.map +1 -1
- package/lib/orchestrator/annotation-store.d.ts.map +1 -1
- package/lib/orchestrator/annotation-store.js +16 -2
- package/lib/orchestrator/annotation-store.js.map +1 -1
- package/lib/orchestrator/campaign-lifecycle.d.ts +1 -0
- package/lib/orchestrator/campaign-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/campaign-lifecycle.js +4 -1
- package/lib/orchestrator/campaign-lifecycle.js.map +1 -1
- package/lib/orchestrator/compare.d.ts +4 -0
- package/lib/orchestrator/compare.d.ts.map +1 -1
- package/lib/orchestrator/compare.js +13 -1
- package/lib/orchestrator/compare.js.map +1 -1
- package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
- package/lib/orchestrator/comparison-identity.js +1 -0
- package/lib/orchestrator/comparison-identity.js.map +1 -1
- package/lib/orchestrator/config.d.ts +42 -0
- package/lib/orchestrator/config.d.ts.map +1 -1
- package/lib/orchestrator/config.js +6 -0
- package/lib/orchestrator/config.js.map +1 -1
- package/lib/orchestrator/discover.d.ts +1 -0
- package/lib/orchestrator/discover.d.ts.map +1 -1
- package/lib/orchestrator/discover.js +7 -1
- package/lib/orchestrator/discover.js.map +1 -1
- package/lib/orchestrator/doctor.d.ts.map +1 -1
- package/lib/orchestrator/doctor.js +34 -26
- package/lib/orchestrator/doctor.js.map +1 -1
- package/lib/orchestrator/driver-capabilities.d.ts +3 -0
- package/lib/orchestrator/driver-capabilities.d.ts.map +1 -0
- package/lib/orchestrator/driver-capabilities.js +10 -0
- package/lib/orchestrator/driver-capabilities.js.map +1 -0
- package/lib/orchestrator/driver-identity.d.ts +5 -0
- package/lib/orchestrator/driver-identity.d.ts.map +1 -0
- package/lib/orchestrator/driver-identity.js +41 -0
- package/lib/orchestrator/driver-identity.js.map +1 -0
- package/lib/orchestrator/experiment-context.d.ts +10 -0
- package/lib/orchestrator/experiment-context.d.ts.map +1 -1
- package/lib/orchestrator/experiment-contracts.d.ts +10 -0
- package/lib/orchestrator/experiment-contracts.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.js +17 -19
- package/lib/orchestrator/experiment-corpus.js.map +1 -1
- package/lib/orchestrator/experiment-effects.d.ts +33 -0
- package/lib/orchestrator/experiment-effects.d.ts.map +1 -0
- package/lib/orchestrator/experiment-effects.js +44 -0
- package/lib/orchestrator/experiment-effects.js.map +1 -0
- package/lib/orchestrator/experiment-evaluation.d.ts.map +1 -1
- package/lib/orchestrator/experiment-evaluation.js +36 -3
- package/lib/orchestrator/experiment-evaluation.js.map +1 -1
- package/lib/orchestrator/experiment-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-identity.js +18 -29
- package/lib/orchestrator/experiment-identity.js.map +1 -1
- package/lib/orchestrator/experiment-loader.d.ts +7 -2
- package/lib/orchestrator/experiment-loader.d.ts.map +1 -1
- package/lib/orchestrator/experiment-report.d.ts +70 -0
- package/lib/orchestrator/experiment-report.d.ts.map +1 -1
- package/lib/orchestrator/experiment-report.js +9 -1
- package/lib/orchestrator/experiment-report.js.map +1 -1
- package/lib/orchestrator/experiment-runs.d.ts +22 -1
- package/lib/orchestrator/experiment-runs.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runs.js +13 -5
- package/lib/orchestrator/experiment-runs.js.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.d.ts +0 -16
- package/lib/orchestrator/experiment-runtime-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.js +5 -220
- package/lib/orchestrator/experiment-runtime-identity.js.map +1 -1
- package/lib/orchestrator/experiment-selection.d.ts.map +1 -1
- package/lib/orchestrator/experiment-selection.js +52 -0
- package/lib/orchestrator/experiment-selection.js.map +1 -1
- package/lib/orchestrator/experiment.d.ts +0 -2
- package/lib/orchestrator/experiment.d.ts.map +1 -1
- package/lib/orchestrator/experiment.js +23 -15
- package/lib/orchestrator/experiment.js.map +1 -1
- package/lib/orchestrator/fs-read.d.ts +1 -6
- package/lib/orchestrator/fs-read.d.ts.map +1 -1
- package/lib/orchestrator/fs-read.js +2 -32
- package/lib/orchestrator/fs-read.js.map +1 -1
- package/lib/orchestrator/grader-experiment.d.ts +17 -1
- package/lib/orchestrator/grader-experiment.d.ts.map +1 -1
- package/lib/orchestrator/grader-experiment.js +52 -7
- package/lib/orchestrator/grader-experiment.js.map +1 -1
- package/lib/orchestrator/grading.d.ts.map +1 -1
- package/lib/orchestrator/grading.js +13 -6
- package/lib/orchestrator/grading.js.map +1 -1
- package/lib/orchestrator/list-runs.d.ts +1 -0
- package/lib/orchestrator/list-runs.d.ts.map +1 -1
- package/lib/orchestrator/list-runs.js +27 -6
- package/lib/orchestrator/list-runs.js.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.js +3 -1
- package/lib/orchestrator/optimization-lifecycle.js.map +1 -1
- package/lib/orchestrator/orchestrator.d.ts +6 -1
- package/lib/orchestrator/orchestrator.d.ts.map +1 -1
- package/lib/orchestrator/orchestrator.js +17 -143
- package/lib/orchestrator/orchestrator.js.map +1 -1
- package/lib/orchestrator/paired-effects.d.ts +34 -0
- package/lib/orchestrator/paired-effects.d.ts.map +1 -0
- package/lib/orchestrator/paired-effects.js +158 -0
- package/lib/orchestrator/paired-effects.js.map +1 -0
- package/lib/orchestrator/provenance.d.ts +5 -1
- package/lib/orchestrator/provenance.d.ts.map +1 -1
- package/lib/orchestrator/provenance.js +16 -3
- package/lib/orchestrator/provenance.js.map +1 -1
- package/lib/orchestrator/regrade.d.ts +1 -0
- package/lib/orchestrator/regrade.d.ts.map +1 -1
- package/lib/orchestrator/run-execution.d.ts +2 -0
- package/lib/orchestrator/run-execution.d.ts.map +1 -1
- package/lib/orchestrator/run-execution.js +18 -3
- package/lib/orchestrator/run-execution.js.map +1 -1
- package/lib/orchestrator/run-lifecycle.d.ts +1 -0
- package/lib/orchestrator/run-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/run-lifecycle.js +3 -2
- package/lib/orchestrator/run-lifecycle.js.map +1 -1
- package/lib/orchestrator/suite-runs.d.ts +3 -1
- package/lib/orchestrator/suite-runs.d.ts.map +1 -1
- package/lib/orchestrator/suite-runs.js +12 -2
- package/lib/orchestrator/suite-runs.js.map +1 -1
- package/lib/orchestrator/suite-summary.d.ts.map +1 -1
- package/lib/orchestrator/suite-summary.js +2 -1
- package/lib/orchestrator/suite-summary.js.map +1 -1
- package/lib/previewer/server.d.ts +6 -0
- package/lib/previewer/server.d.ts.map +1 -1
- package/lib/previewer/server.js +21 -5
- package/lib/previewer/server.js.map +1 -1
- package/package.json +2 -2
- package/skills/lux/references/cli.md +5 -2
- package/skills/lux-answerer/SKILL.md +1 -1
- package/src/answerers/claude-code/index.ts +3 -3
- package/src/answerers/persona/index.ts +3 -3
- package/src/answerers/terminal/index.ts +4 -9
- package/src/assertions/core/resource-checks.ts +3 -5
- package/src/assertions/rubric/index.ts +7 -1
- package/src/assertions/rubric/internal.ts +13 -8
- package/src/authoring.ts +331 -2
- package/src/cli/bin.ts +2 -12
- package/src/cli/command-runtime.ts +20 -9
- package/src/cli/init-templates.ts +223 -0
- package/src/cli/init.ts +38 -184
- package/src/cli/output-schemas.ts +106 -0
- package/src/cli/program.ts +621 -548
- package/src/cli/render/reporter.ts +25 -4
- package/src/cli/run-options.ts +8 -25
- package/src/cli/view.ts +45 -84
- package/src/core/annotation.ts +2 -1
- package/src/core/answerer.ts +9 -0
- package/src/core/assertion.ts +3 -0
- package/src/core/case.ts +5 -1
- package/src/core/driver.ts +38 -0
- package/src/core/environment.ts +22 -0
- package/src/core/evaluation-clusters.ts +35 -0
- package/src/core/experiment.ts +60 -23
- package/src/core/file-tree.ts +35 -0
- package/src/core/index.ts +1 -0
- package/src/core/lifecycle-fixtures.ts +4 -2
- package/src/core/platform-process.ts +54 -6
- package/src/core/run.ts +20 -0
- package/src/core/usage.ts +8 -0
- package/src/drivers/claude-code/index.ts +34 -3
- package/src/drivers/codex/app-events.ts +43 -33
- package/src/drivers/codex/exec-events.ts +258 -0
- package/src/drivers/codex/index.ts +37 -262
- package/src/drivers/cursor/README.md +57 -0
- package/src/drivers/cursor/acp-transport.ts +182 -0
- package/src/drivers/cursor/config.ts +29 -0
- package/src/drivers/cursor/events.ts +83 -0
- package/src/drivers/cursor/index.ts +316 -0
- package/src/drivers/cursor/interaction.ts +90 -0
- package/src/drivers/mcp/index.ts +16 -3
- package/src/drivers/shared/experiment-behavior.ts +214 -0
- package/src/drivers/shared/experiment-policy.ts +195 -0
- package/src/drivers/subprocess/index.ts +45 -6
- package/src/index.ts +16 -0
- package/src/orchestrator/annotation-loader.ts +10 -0
- package/src/orchestrator/annotation-store.ts +24 -3
- package/src/orchestrator/campaign-lifecycle.ts +5 -1
- package/src/orchestrator/compare.ts +16 -1
- package/src/orchestrator/comparison-identity.ts +1 -0
- package/src/orchestrator/config.ts +6 -0
- package/src/orchestrator/discover.ts +8 -1
- package/src/orchestrator/doctor.ts +40 -22
- package/src/orchestrator/driver-capabilities.ts +16 -0
- package/src/orchestrator/driver-identity.ts +59 -0
- package/src/orchestrator/experiment-corpus.ts +23 -28
- package/src/orchestrator/experiment-effects.ts +61 -0
- package/src/orchestrator/experiment-evaluation.ts +45 -5
- package/src/orchestrator/experiment-identity.ts +27 -36
- package/src/orchestrator/experiment-report.ts +21 -1
- package/src/orchestrator/experiment-runs.ts +11 -4
- package/src/orchestrator/experiment-runtime-identity.ts +5 -243
- package/src/orchestrator/experiment-selection.ts +77 -0
- package/src/orchestrator/experiment.ts +26 -24
- package/src/orchestrator/fs-read.ts +2 -32
- package/src/orchestrator/grader-experiment.ts +72 -8
- package/src/orchestrator/grading.ts +15 -6
- package/src/orchestrator/list-runs.ts +29 -6
- package/src/orchestrator/optimization-lifecycle.ts +4 -1
- package/src/orchestrator/orchestrator.ts +26 -183
- package/src/orchestrator/paired-effects.ts +209 -0
- package/src/orchestrator/provenance.ts +23 -3
- package/src/orchestrator/run-execution.ts +18 -3
- package/src/orchestrator/run-lifecycle.ts +4 -2
- package/src/orchestrator/suite-runs.ts +10 -1
- package/src/orchestrator/suite-summary.ts +2 -1
- package/src/previewer/server.ts +27 -5
- package/viewer/app.js +27 -6
- package/viewer/detail.js +22 -5
- package/lib/cli/skills.d.ts +0 -38
- package/lib/cli/skills.d.ts.map +0 -1
- package/lib/cli/skills.js +0 -84
- package/lib/cli/skills.js.map +0 -1
- package/src/cli/skills.ts +0 -129
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
type StarterDriver = "subprocess" | "claude-code" | "codex" | "cursor";
|
|
2
|
+
|
|
3
|
+
export const luxConfigBody = (
|
|
4
|
+
withExperiment: boolean,
|
|
5
|
+
driver?: StarterDriver,
|
|
6
|
+
model?: string,
|
|
7
|
+
): string => {
|
|
8
|
+
const subjectRoot = withExperiment ? ' subjectRoot: ".",\n' : "";
|
|
9
|
+
const profiles = withExperiment ? " profiles: { starter: {} },\n" : "";
|
|
10
|
+
const selectedDriver = driver ?? (withExperiment ? undefined : "subprocess");
|
|
11
|
+
const modelField = model ? `model: ${JSON.stringify(model)}, ` : "";
|
|
12
|
+
let defaultDriver: string;
|
|
13
|
+
if (selectedDriver === "subprocess") {
|
|
14
|
+
defaultDriver = ` defaultDriver: { name: "subprocess", config: {
|
|
15
|
+
command: process.execPath,
|
|
16
|
+
args: [fileURLToPath(new URL("./agent/demo.mjs", import.meta.url))],
|
|
17
|
+
inheritEnv: false,
|
|
18
|
+
} },
|
|
19
|
+
`;
|
|
20
|
+
} else if (selectedDriver) {
|
|
21
|
+
const efforts = { "claude-code": 'effort: "low"', codex: 'reasoningEffort: "low"', cursor: "" };
|
|
22
|
+
defaultDriver = ` defaultDriver: { name: ${JSON.stringify(selectedDriver)}, config: { ${modelField}${efforts[selectedDriver]} } },
|
|
23
|
+
`;
|
|
24
|
+
} else {
|
|
25
|
+
defaultDriver = ` // Select a driver with lux init --experiment --driver codex --force.
|
|
26
|
+
// defaultDriver: { name: "codex", config: { reasoningEffort: "low" } },
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
return `${selectedDriver === "subprocess" ? 'import { fileURLToPath } from "node:url";\n' : ""}import type { LuxConfig } from "@prismatic-io/lux";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Lux project configuration. Drivers, answerers, and assertions
|
|
33
|
+
* register here; \`lux run\` discovers cases under \`casesRoot\`.
|
|
34
|
+
*/
|
|
35
|
+
const config: LuxConfig = {
|
|
36
|
+
casesRoot: "./cases",
|
|
37
|
+
fixturesRoot: "./fixtures",
|
|
38
|
+
runsRoot: "./.lux-runs",
|
|
39
|
+
${subjectRoot} // Runners default to cheap models and low effort instead of inheriting CLI defaults.
|
|
40
|
+
${defaultDriver} // Persona answerers and rubric judges default to cheap models and low effort.
|
|
41
|
+
// Override both explicitly when a stronger harness is worth the added cost:
|
|
42
|
+
// harness: { provider: "codex", model: "YOUR_HARNESS_MODEL" },
|
|
43
|
+
defaultAnswerer: "persona",
|
|
44
|
+
${profiles} // drivers: [/* register drivers here */],
|
|
45
|
+
// answerers: [/* register answerers here */],
|
|
46
|
+
// assertions: [/* register custom assertions here */],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default config;
|
|
50
|
+
`;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const DEMO_AGENT_BODY = `import { writeFile } from "node:fs/promises";
|
|
54
|
+
import { join } from "node:path";
|
|
55
|
+
|
|
56
|
+
const send = (event) => process.stdout.write(JSON.stringify(event) + "\\n");
|
|
57
|
+
send({ type: "ready", agentId: "addition-demo" });
|
|
58
|
+
await writeFile(join(process.env.LUX_ARTIFACTS_DIR, "add.mjs"), "export const add = (a, b) => a + b;\\n");
|
|
59
|
+
send({ type: "done", summary: "Wrote add.mjs" });
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
const ADDITION_COMMAND = `node --input-type=module -e "import assert from 'node:assert/strict'; import { add } from './add.mjs'; assert.equal(add(2, 3), 5); assert.equal(add(-2, 2), 0); assert.equal(add(0, 0), 0);"`;
|
|
63
|
+
|
|
64
|
+
export const SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
|
|
65
|
+
|
|
66
|
+
export default defineEvalCase({
|
|
67
|
+
id: "addition",
|
|
68
|
+
prompt: "Write add.mjs exporting add(a, b). It must add two numbers, including negative numbers and zero.",
|
|
69
|
+
assertions: [
|
|
70
|
+
{ id: "completed", type: "run-succeeded" },
|
|
71
|
+
{ id: "module-written", type: "file-exists", path: "add.mjs" },
|
|
72
|
+
{
|
|
73
|
+
id: "adds-correctly",
|
|
74
|
+
type: "command-exits-zero",
|
|
75
|
+
command: ${JSON.stringify(ADDITION_COMMAND)},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
export const EXPERIMENT_SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A starter smoke case. It inherits the default driver from lux.config.ts.
|
|
85
|
+
*/
|
|
86
|
+
export default defineEvalCase({
|
|
87
|
+
id: "hello-world",
|
|
88
|
+
prompt: "Say hello to the world.",
|
|
89
|
+
assertions: [{ id: "completed", type: "run-succeeded" }],
|
|
90
|
+
});
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
export const README_BODY = `# Lux evals
|
|
94
|
+
|
|
95
|
+
This directory holds your evaluation cases.
|
|
96
|
+
|
|
97
|
+
## Layout
|
|
98
|
+
|
|
99
|
+
- \`lux.config.ts\` — project configuration: default driver/answerer and registered plugins.
|
|
100
|
+
- \`cases/\` — one TypeScript file per eval case. Default-export a \`defineEvalCase({...})\`.
|
|
101
|
+
- \`fixtures/\` — starting state for cases that need pre-staged input.
|
|
102
|
+
- \`.lux-runs/\` — run output, gitignored.
|
|
103
|
+
|
|
104
|
+
## Setup
|
|
105
|
+
|
|
106
|
+
Install Lux in the project so authored TypeScript cases can resolve its API:
|
|
107
|
+
|
|
108
|
+
\`\`\`bash
|
|
109
|
+
npm install --save-dev @prismatic-io/lux
|
|
110
|
+
\`\`\`
|
|
111
|
+
|
|
112
|
+
## First result
|
|
113
|
+
|
|
114
|
+
The default starter uses a local deterministic agent and makes no model calls.
|
|
115
|
+
Run \`npm exec -- lux run\`, then \`npm exec -- lux view\` to inspect its
|
|
116
|
+
artifact and behavioral assertions. In \`agent/demo.mjs\`, replace \`a + b\`
|
|
117
|
+
with \`a - b\` and run again: the agent completes, but the behavioral assertion
|
|
118
|
+
fails. Restore addition and rerun to see it pass.
|
|
119
|
+
|
|
120
|
+
For a real coding agent, scaffold with \`lux init --driver claude-code\` or
|
|
121
|
+
\`lux init --driver codex\`. Cursor requires an explicit model:
|
|
122
|
+
\`lux init --driver cursor --model <model-id>\`. These modes make model calls
|
|
123
|
+
when you run cases and require the corresponding authenticated CLI.
|
|
124
|
+
|
|
125
|
+
## Run cases
|
|
126
|
+
|
|
127
|
+
\`lux run\` discovers every case under \`casesRoot\` and runs it. Filter by
|
|
128
|
+
name/path substring, by \`--tag\`, or repeat each matched eval with \`--loop\`:
|
|
129
|
+
|
|
130
|
+
\`\`\`bash
|
|
131
|
+
npm exec -- lux run # every discovered case
|
|
132
|
+
npm exec -- lux run addition # cases whose id/path contains "hello-world"
|
|
133
|
+
npm exec -- lux run cases/addition.ts # one file directly
|
|
134
|
+
npm exec -- lux run --tag smoke # cases tagged "smoke" (meta.tags)
|
|
135
|
+
npm exec -- lux run --loop 5 # run each matched eval 5 times
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
See the [Lux docs](https://github.com/prismatic-io/lux) for the full design.
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
export const STARTER_PROMPT_BODY = `# Starter agent instructions
|
|
142
|
+
|
|
143
|
+
Complete the requested task and verify the result. Ask for clarification when
|
|
144
|
+
missing information changes the correct outcome.
|
|
145
|
+
`;
|
|
146
|
+
|
|
147
|
+
export const experimentCaseBody = (
|
|
148
|
+
id: string,
|
|
149
|
+
split: "train" | "validation" | "test",
|
|
150
|
+
task: string,
|
|
151
|
+
): string => {
|
|
152
|
+
const checks = {
|
|
153
|
+
train: "assert.equal(result(2, 3), 5); assert.equal(result(-2, 2), 0)",
|
|
154
|
+
validation:
|
|
155
|
+
"assert.equal(result(12, 0, 10), 10); assert.equal(result(-1, 0, 10), 0); assert.equal(result(5, 0, 10), 5)",
|
|
156
|
+
test: "assert.equal(result(' Lux REVIEW '), 'lux review'); assert.equal(result(''), '')",
|
|
157
|
+
};
|
|
158
|
+
const command = `node --input-type=module -e "import assert from 'node:assert/strict'; import { result } from './result.mjs'; ${checks[split]};"`;
|
|
159
|
+
return `import { defineEvalCase, subjectPath } from "@prismatic-io/lux";
|
|
160
|
+
|
|
161
|
+
export default defineEvalCase({
|
|
162
|
+
id: ${JSON.stringify(id)},
|
|
163
|
+
prompt: [
|
|
164
|
+
\`Read \${subjectPath("prompts/agent.md")} and use it as task guidance.\`,
|
|
165
|
+
${JSON.stringify(task)},
|
|
166
|
+
].join("\\n\\n"),
|
|
167
|
+
assertions: [
|
|
168
|
+
{ id: "completed", type: "run-succeeded" },
|
|
169
|
+
{ id: "behavior", type: "command-exits-zero", command: ${JSON.stringify(command)} },
|
|
170
|
+
],
|
|
171
|
+
meta: { tags: [${JSON.stringify(split)}] },
|
|
172
|
+
});
|
|
173
|
+
`;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const STARTER_EXPERIMENT_BODY = `import { defineExperiment } from "@prismatic-io/lux";
|
|
177
|
+
|
|
178
|
+
export default defineExperiment({
|
|
179
|
+
id: "starter-agent-improvement",
|
|
180
|
+
subject: {
|
|
181
|
+
root: "..",
|
|
182
|
+
mutable: ["prompts/agent.md"],
|
|
183
|
+
},
|
|
184
|
+
profiles: ["starter"],
|
|
185
|
+
splits: {
|
|
186
|
+
train: { tags: ["train"] },
|
|
187
|
+
validation: { tags: ["validation"] },
|
|
188
|
+
test: { tags: ["test"] },
|
|
189
|
+
},
|
|
190
|
+
repetitions: { search: 1, promotion: 2 },
|
|
191
|
+
objectives: {
|
|
192
|
+
constraints: [
|
|
193
|
+
{ metric: "quality.passRate", min: 1 },
|
|
194
|
+
{ metric: "quality.passRate", min: 1, split: "test" },
|
|
195
|
+
{ metric: "quality.caseRegressions", max: 0 },
|
|
196
|
+
{ metric: "quality.caseRegressions", max: 0, split: "test" },
|
|
197
|
+
],
|
|
198
|
+
minimize: [
|
|
199
|
+
{ metric: "agent.total" },
|
|
200
|
+
{ metric: "subject.bytes" },
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
optimizer: {
|
|
204
|
+
algorithm: "reflective",
|
|
205
|
+
config: {
|
|
206
|
+
provider: "claude-code",
|
|
207
|
+
model: "YOUR_OPTIMIZER_MODEL",
|
|
208
|
+
reasoningEffort: "low",
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
budget: {
|
|
212
|
+
maxCandidates: 4,
|
|
213
|
+
patience: 1,
|
|
214
|
+
maxMetricCalls: 40,
|
|
215
|
+
maxJudgeCalls: 40,
|
|
216
|
+
maxProposalCalls: 3,
|
|
217
|
+
maxTokens: 1_000_000,
|
|
218
|
+
maxCostUsd: 25,
|
|
219
|
+
maxUnpricedModelCalls: 25,
|
|
220
|
+
maxWallTimeMs: 1_800_000,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
`;
|
package/src/cli/init.ts
CHANGED
|
@@ -2,14 +2,34 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { constants, lstat, mkdir, open, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import {
|
|
6
|
+
DEMO_AGENT_BODY,
|
|
7
|
+
EXPERIMENT_SAMPLE_CASE_BODY,
|
|
8
|
+
experimentCaseBody,
|
|
9
|
+
luxConfigBody,
|
|
10
|
+
README_BODY,
|
|
11
|
+
SAMPLE_CASE_BODY,
|
|
12
|
+
STARTER_EXPERIMENT_BODY,
|
|
13
|
+
STARTER_PROMPT_BODY,
|
|
14
|
+
} from "./init-templates.js";
|
|
5
15
|
|
|
6
16
|
const InitOptionsSchema = z
|
|
7
17
|
.object({
|
|
8
18
|
cwd: z.string().min(1),
|
|
9
19
|
force: z.boolean().default(false),
|
|
10
20
|
experiment: z.boolean().default(false),
|
|
21
|
+
driver: z.enum(["subprocess", "claude-code", "codex", "cursor"]).optional(),
|
|
22
|
+
model: z.string().min(1).optional(),
|
|
11
23
|
})
|
|
12
|
-
.strict()
|
|
24
|
+
.strict()
|
|
25
|
+
.refine((options) => options.driver !== "cursor" || options.model !== undefined, {
|
|
26
|
+
path: ["model"],
|
|
27
|
+
message: "Cursor requires an explicit --model",
|
|
28
|
+
})
|
|
29
|
+
.refine((options) => !(options.experiment && options.driver === "subprocess"), {
|
|
30
|
+
path: ["driver"],
|
|
31
|
+
message: "The deterministic starter is for runs; choose a coding agent for experiments",
|
|
32
|
+
});
|
|
13
33
|
type InitOptions = z.input<typeof InitOptionsSchema>;
|
|
14
34
|
|
|
15
35
|
const InitResultSchema = z
|
|
@@ -133,181 +153,6 @@ const appendGitignoreEntry = async (
|
|
|
133
153
|
else result.updated.push(path);
|
|
134
154
|
};
|
|
135
155
|
|
|
136
|
-
const luxConfigBody = (withExperiment: boolean): string => {
|
|
137
|
-
const subjectRoot = withExperiment ? ' subjectRoot: ".",\n' : "";
|
|
138
|
-
const profiles = withExperiment ? " profiles: { starter: {} },\n" : "";
|
|
139
|
-
const defaultDriver = withExperiment
|
|
140
|
-
? ` // Choose one driver before running the scaffold.
|
|
141
|
-
// defaultDriver: { name: "codex", config: { model: "YOUR_CODEX_MODEL", reasoningEffort: "high" } },
|
|
142
|
-
// defaultDriver: { name: "claude-code", config: { model: "YOUR_CLAUDE_MODEL", effort: "high" } },
|
|
143
|
-
`
|
|
144
|
-
: ` // The subprocess command must implement Lux's lux-jsonl protocol.
|
|
145
|
-
// Replace this entire object when using the built-in Codex or Claude Code driver.
|
|
146
|
-
defaultDriver: { name: "subprocess", config: { command: "your-agent-cli" } },
|
|
147
|
-
`;
|
|
148
|
-
return `import type { LuxConfig } from "@prismatic-io/lux";
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Lux project configuration. Drivers, answerers, and assertions
|
|
152
|
-
* register here; \`lux run\` discovers cases under \`casesRoot\`.
|
|
153
|
-
*/
|
|
154
|
-
const config: LuxConfig = {
|
|
155
|
-
casesRoot: "./cases",
|
|
156
|
-
fixturesRoot: "./fixtures",
|
|
157
|
-
runsRoot: "./.lux-runs",
|
|
158
|
-
${subjectRoot} // Runners default to cheap models and low effort instead of inheriting CLI defaults.
|
|
159
|
-
${defaultDriver} // Persona answerers and rubric judges default to cheap models and low effort.
|
|
160
|
-
// Override both explicitly when a stronger harness is worth the added cost:
|
|
161
|
-
// harness: { provider: "codex", model: "YOUR_HARNESS_MODEL" },
|
|
162
|
-
defaultAnswerer: "persona",
|
|
163
|
-
${profiles} // drivers: [/* register drivers here */],
|
|
164
|
-
// answerers: [/* register answerers here */],
|
|
165
|
-
// assertions: [/* register custom assertions here */],
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
export default config;
|
|
169
|
-
`;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* A starter case. It inherits defaultDriver from lux.config.ts.
|
|
176
|
-
* Replace the prompt and persona to match the behavior you need.
|
|
177
|
-
*/
|
|
178
|
-
export default defineEvalCase({
|
|
179
|
-
id: "hello-world",
|
|
180
|
-
prompt: "Say hello to the world.",
|
|
181
|
-
persona: "You are a friendly developer. Keep answers short.",
|
|
182
|
-
assertions: [
|
|
183
|
-
{ id: "completed", type: "run-succeeded" },
|
|
184
|
-
// { type: "contains", text: "hello" },
|
|
185
|
-
// { type: "command-exits-zero", command: "echo done" },
|
|
186
|
-
],
|
|
187
|
-
});
|
|
188
|
-
`;
|
|
189
|
-
|
|
190
|
-
const EXPERIMENT_SAMPLE_CASE_BODY = `import { defineEvalCase } from "@prismatic-io/lux";
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* A starter smoke case. It inherits the default driver from lux.config.ts.
|
|
194
|
-
*/
|
|
195
|
-
export default defineEvalCase({
|
|
196
|
-
id: "hello-world",
|
|
197
|
-
prompt: "Say hello to the world.",
|
|
198
|
-
assertions: [{ id: "completed", type: "run-succeeded" }],
|
|
199
|
-
});
|
|
200
|
-
`;
|
|
201
|
-
|
|
202
|
-
const README_BODY = `# Lux evals
|
|
203
|
-
|
|
204
|
-
This directory holds your evaluation cases.
|
|
205
|
-
|
|
206
|
-
## Layout
|
|
207
|
-
|
|
208
|
-
- \`lux.config.ts\` — project configuration: default driver/answerer and registered plugins.
|
|
209
|
-
- \`cases/\` — one TypeScript file per eval case. Default-export a \`defineEvalCase({...})\`.
|
|
210
|
-
- \`fixtures/\` — starting state for cases that need pre-staged input.
|
|
211
|
-
- \`.lux-runs/\` — run output, gitignored.
|
|
212
|
-
|
|
213
|
-
## Setup
|
|
214
|
-
|
|
215
|
-
Install Lux in the project so authored TypeScript cases can resolve its API:
|
|
216
|
-
|
|
217
|
-
\`\`\`bash
|
|
218
|
-
npm install --save-dev @prismatic-io/lux
|
|
219
|
-
\`\`\`
|
|
220
|
-
|
|
221
|
-
## Run cases
|
|
222
|
-
|
|
223
|
-
\`lux run\` discovers every case under \`casesRoot\` and runs it. Filter by
|
|
224
|
-
name/path substring, by \`--tag\`, or repeat each matched eval with \`--loop\`:
|
|
225
|
-
|
|
226
|
-
\`\`\`bash
|
|
227
|
-
npm exec -- lux run # every discovered case
|
|
228
|
-
npm exec -- lux run hello-world # cases whose id/path contains "hello-world"
|
|
229
|
-
npm exec -- lux run cases/hello-world.ts # one file directly
|
|
230
|
-
npm exec -- lux run --tag smoke # cases tagged "smoke" (meta.tags)
|
|
231
|
-
npm exec -- lux run --loop 5 # run each matched eval 5 times
|
|
232
|
-
\`\`\`
|
|
233
|
-
|
|
234
|
-
See the [Lux docs](https://github.com/prismatic-io/lux) for the full design.
|
|
235
|
-
`;
|
|
236
|
-
|
|
237
|
-
const STARTER_PROMPT_BODY = `# Starter agent instructions
|
|
238
|
-
|
|
239
|
-
Complete the requested task directly. Prefer deterministic work, use the fewest
|
|
240
|
-
tools needed, and ask a question only when proceeding would be unsafe.
|
|
241
|
-
`;
|
|
242
|
-
|
|
243
|
-
const experimentCaseBody = (
|
|
244
|
-
id: string,
|
|
245
|
-
split: "train" | "validation" | "test",
|
|
246
|
-
task: string,
|
|
247
|
-
): string => `import { defineEvalCase, subjectPath } from "@prismatic-io/lux";
|
|
248
|
-
|
|
249
|
-
export default defineEvalCase({
|
|
250
|
-
id: ${JSON.stringify(id)},
|
|
251
|
-
prompt: [
|
|
252
|
-
\`Read \${subjectPath("prompts/agent.md")} and follow it as the system instructions.\`,
|
|
253
|
-
${JSON.stringify(task)},
|
|
254
|
-
].join("\\n\\n"),
|
|
255
|
-
assertions: [{ id: "completed", type: "run-succeeded" }],
|
|
256
|
-
meta: { tags: [${JSON.stringify(split)}] },
|
|
257
|
-
});
|
|
258
|
-
`;
|
|
259
|
-
|
|
260
|
-
const STARTER_EXPERIMENT_BODY = `import { defineExperiment } from "@prismatic-io/lux";
|
|
261
|
-
|
|
262
|
-
export default defineExperiment({
|
|
263
|
-
id: "starter-agent-improvement",
|
|
264
|
-
subject: {
|
|
265
|
-
root: "..",
|
|
266
|
-
mutable: ["prompts/agent.md"],
|
|
267
|
-
},
|
|
268
|
-
profiles: ["starter"],
|
|
269
|
-
splits: {
|
|
270
|
-
train: { tags: ["train"] },
|
|
271
|
-
validation: { tags: ["validation"] },
|
|
272
|
-
test: { tags: ["test"] },
|
|
273
|
-
},
|
|
274
|
-
repetitions: { search: 1, promotion: 2 },
|
|
275
|
-
objectives: {
|
|
276
|
-
constraints: [
|
|
277
|
-
{ metric: "quality.passRate", min: 1 },
|
|
278
|
-
{ metric: "quality.passRate", min: 1, split: "test" },
|
|
279
|
-
{ metric: "quality.caseRegressions", max: 0 },
|
|
280
|
-
{ metric: "quality.caseRegressions", max: 0, split: "test" },
|
|
281
|
-
],
|
|
282
|
-
minimize: [
|
|
283
|
-
{ metric: "agent.total" },
|
|
284
|
-
{ metric: "interrupts.ask" },
|
|
285
|
-
{ metric: "toolCalls" },
|
|
286
|
-
{ metric: "subject.bytes" },
|
|
287
|
-
],
|
|
288
|
-
},
|
|
289
|
-
optimizer: {
|
|
290
|
-
algorithm: "reflective",
|
|
291
|
-
config: {
|
|
292
|
-
provider: "claude-code",
|
|
293
|
-
model: "YOUR_OPTIMIZER_MODEL",
|
|
294
|
-
reasoningEffort: "low",
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
budget: {
|
|
298
|
-
maxCandidates: 4,
|
|
299
|
-
patience: 1,
|
|
300
|
-
maxMetricCalls: 40,
|
|
301
|
-
maxJudgeCalls: 40,
|
|
302
|
-
maxProposalCalls: 3,
|
|
303
|
-
maxTokens: 1_000_000,
|
|
304
|
-
maxCostUsd: 25,
|
|
305
|
-
maxUnpricedModelCalls: 25,
|
|
306
|
-
maxWallTimeMs: 1_800_000,
|
|
307
|
-
},
|
|
308
|
-
});
|
|
309
|
-
`;
|
|
310
|
-
|
|
311
156
|
export const initProject = async (options: InitOptions): Promise<InitResult> => {
|
|
312
157
|
const parsedOptions = InitOptionsSchema.parse(options);
|
|
313
158
|
const experiment = parsedOptions.experiment;
|
|
@@ -317,14 +162,23 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
|
|
|
317
162
|
await mkdir(parsedOptions.cwd, { recursive: true });
|
|
318
163
|
const root = await realpath(parsedOptions.cwd);
|
|
319
164
|
|
|
320
|
-
await writeIfMissing(root, join(root, "lux.config.ts"), luxConfigBody(experiment), result, force);
|
|
321
165
|
await writeIfMissing(
|
|
322
166
|
root,
|
|
323
|
-
join(root, "
|
|
167
|
+
join(root, "lux.config.ts"),
|
|
168
|
+
luxConfigBody(experiment, parsedOptions.driver, parsedOptions.model),
|
|
169
|
+
result,
|
|
170
|
+
force,
|
|
171
|
+
);
|
|
172
|
+
await writeIfMissing(
|
|
173
|
+
root,
|
|
174
|
+
join(root, "cases", experiment ? "hello-world.ts" : "addition.ts"),
|
|
324
175
|
experiment ? EXPERIMENT_SAMPLE_CASE_BODY : SAMPLE_CASE_BODY,
|
|
325
176
|
result,
|
|
326
177
|
force,
|
|
327
178
|
);
|
|
179
|
+
if (!experiment && (!parsedOptions.driver || parsedOptions.driver === "subprocess")) {
|
|
180
|
+
await writeIfMissing(root, join(root, "agent", "demo.mjs"), DEMO_AGENT_BODY, result, force);
|
|
181
|
+
}
|
|
328
182
|
await writeIfMissing(root, join(root, "fixtures", ".gitkeep"), "", result, force);
|
|
329
183
|
// README is the user's to evolve once it exists; `--force` refreshes only
|
|
330
184
|
// the lux-owned scaffold files, never a hand-edited README.
|
|
@@ -344,7 +198,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
|
|
|
344
198
|
experimentCaseBody(
|
|
345
199
|
"starter/train",
|
|
346
200
|
"train",
|
|
347
|
-
"
|
|
201
|
+
"Write result.mjs exporting result(a, b), which adds two numbers including negative numbers.",
|
|
348
202
|
),
|
|
349
203
|
result,
|
|
350
204
|
force,
|
|
@@ -355,7 +209,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
|
|
|
355
209
|
experimentCaseBody(
|
|
356
210
|
"starter/validation",
|
|
357
211
|
"validation",
|
|
358
|
-
"
|
|
212
|
+
"Write result.mjs exporting result(value, min, max), which clamps a number to the inclusive bounds.",
|
|
359
213
|
),
|
|
360
214
|
result,
|
|
361
215
|
force,
|
|
@@ -366,7 +220,7 @@ export const initProject = async (options: InitOptions): Promise<InitResult> =>
|
|
|
366
220
|
experimentCaseBody(
|
|
367
221
|
"starter/test",
|
|
368
222
|
"test",
|
|
369
|
-
"
|
|
223
|
+
"Write result.mjs exporting result(text), which trims surrounding whitespace and lowercases the text.",
|
|
370
224
|
),
|
|
371
225
|
result,
|
|
372
226
|
force,
|
|
@@ -397,14 +251,14 @@ export const formatInitReport = (result: InitResult, cwd: string): string => {
|
|
|
397
251
|
lines.push("");
|
|
398
252
|
lines.push("Next steps:");
|
|
399
253
|
lines.push(" 1. Install @prismatic-io/lux in this project if it is not already present.");
|
|
400
|
-
lines.push(" 2.
|
|
254
|
+
lines.push(" 2. Review lux.config.ts and the selected driver.");
|
|
401
255
|
if (result.experiment) {
|
|
402
256
|
lines.push(" 3. Replace the starter prompt and split cases with representative evidence.");
|
|
403
257
|
lines.push(" 4. lux doctor");
|
|
404
258
|
lines.push(" 5. lux optimize experiments/starter.optimize.ts --plan");
|
|
405
259
|
} else {
|
|
406
|
-
lines.push(" 3.
|
|
407
|
-
lines.push(" 4. lux
|
|
260
|
+
lines.push(" 3. lux run");
|
|
261
|
+
lines.push(" 4. lux view");
|
|
408
262
|
}
|
|
409
263
|
return lines.join("\n");
|
|
410
264
|
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from "incur";
|
|
2
|
+
import {
|
|
3
|
+
ActionTimingSchema,
|
|
4
|
+
AgentActivitySchema,
|
|
5
|
+
DriverMetricsSchema,
|
|
6
|
+
GradingReportSchema,
|
|
7
|
+
PersistedCaseSchema,
|
|
8
|
+
RunEventSchema,
|
|
9
|
+
RunMetadataSchema,
|
|
10
|
+
RunUsageSchema,
|
|
11
|
+
} from "../core/index.js";
|
|
12
|
+
import {
|
|
13
|
+
ExperimentRunSchema,
|
|
14
|
+
SuiteComparisonSchema,
|
|
15
|
+
SuiteRunSchema,
|
|
16
|
+
} from "../orchestrator/index.js";
|
|
17
|
+
|
|
18
|
+
const nullableNumber = z.number().nullable();
|
|
19
|
+
const listedRun = z.object({
|
|
20
|
+
caseSlug: z.string(),
|
|
21
|
+
driverName: z.string(),
|
|
22
|
+
ts: z.string(),
|
|
23
|
+
runDir: z.string(),
|
|
24
|
+
exitReason: RunMetadataSchema.shape.exitReason.nullable(),
|
|
25
|
+
driverAgentId: z.string().nullable(),
|
|
26
|
+
startedAt: z.string().nullable(),
|
|
27
|
+
endedAt: z.string().nullable(),
|
|
28
|
+
durationMs: nullableNumber,
|
|
29
|
+
timeToFirstActionMs: nullableNumber,
|
|
30
|
+
timeToFirstMutationMs: nullableNumber,
|
|
31
|
+
timeToFirstDurableMutationMs: nullableNumber,
|
|
32
|
+
driverMetrics: DriverMetricsSchema,
|
|
33
|
+
subagentCount: z.number(),
|
|
34
|
+
casePassed: z.boolean().nullable(),
|
|
35
|
+
caseScore: nullableNumber,
|
|
36
|
+
assertionPassed: z.number(),
|
|
37
|
+
assertionTotal: z.number(),
|
|
38
|
+
readErrors: z.array(z.string()).optional(),
|
|
39
|
+
});
|
|
40
|
+
const suite = SuiteRunSchema.extend({ suiteDir: z.string() });
|
|
41
|
+
const experiment = ExperimentRunSchema.extend({ experimentDir: z.string() });
|
|
42
|
+
const listing = z.object({
|
|
43
|
+
runsRoot: z.string(),
|
|
44
|
+
readErrors: z.array(z.object({ path: z.string(), message: z.string() })).optional(),
|
|
45
|
+
});
|
|
46
|
+
export const ViewOutputSchema = z.union([
|
|
47
|
+
z.object({
|
|
48
|
+
runDir: z.string(),
|
|
49
|
+
case: PersistedCaseSchema.nullable(),
|
|
50
|
+
metadata: RunMetadataSchema.nullable(),
|
|
51
|
+
grading: GradingReportSchema.nullable(),
|
|
52
|
+
events: z.array(RunEventSchema),
|
|
53
|
+
artifacts: z.array(z.string()),
|
|
54
|
+
}),
|
|
55
|
+
suite,
|
|
56
|
+
experiment,
|
|
57
|
+
listing.extend({ runs: z.array(listedRun), suites: z.array(suite).optional() }),
|
|
58
|
+
listing.extend({ suites: z.array(suite) }),
|
|
59
|
+
listing.extend({ experiments: z.array(experiment) }),
|
|
60
|
+
z.object({ url: z.string(), runsRoot: z.string() }),
|
|
61
|
+
]);
|
|
62
|
+
const interrupts = z.object({ ask: z.number(), approve: z.number(), custom: z.number() });
|
|
63
|
+
const verdict = z.object({ passed: z.boolean(), score: z.number() }).nullable();
|
|
64
|
+
const runComparison = z.object({
|
|
65
|
+
pathA: z.string(),
|
|
66
|
+
pathB: z.string(),
|
|
67
|
+
caseMismatch: z.array(z.object({ field: z.string(), a: z.unknown(), b: z.unknown() })),
|
|
68
|
+
runDelta: z
|
|
69
|
+
.object({
|
|
70
|
+
exitReason: z.object({ a: z.string(), b: z.string() }),
|
|
71
|
+
durationMsA: nullableNumber,
|
|
72
|
+
durationMsB: nullableNumber,
|
|
73
|
+
actionTiming: z.object({ a: ActionTimingSchema, b: ActionTimingSchema }),
|
|
74
|
+
driverMetrics: z.object({ a: DriverMetricsSchema, b: DriverMetricsSchema }),
|
|
75
|
+
agentActivity: z.object({ a: z.array(AgentActivitySchema), b: z.array(AgentActivitySchema) }),
|
|
76
|
+
interruptCounts: z.object({ a: interrupts, b: interrupts }),
|
|
77
|
+
usage: z.object({ a: RunUsageSchema, b: RunUsageSchema }),
|
|
78
|
+
agentUsageAvailable: z.object({ a: z.boolean(), b: z.boolean() }).optional(),
|
|
79
|
+
})
|
|
80
|
+
.nullable(),
|
|
81
|
+
grading: z.object({
|
|
82
|
+
casePassedA: z.boolean().nullable(),
|
|
83
|
+
casePassedB: z.boolean().nullable(),
|
|
84
|
+
caseScoreA: nullableNumber,
|
|
85
|
+
caseScoreB: nullableNumber,
|
|
86
|
+
deltas: z.array(
|
|
87
|
+
z.object({
|
|
88
|
+
id: z.string(),
|
|
89
|
+
type: z.string(),
|
|
90
|
+
name: z.string(),
|
|
91
|
+
before: verdict,
|
|
92
|
+
after: verdict,
|
|
93
|
+
status: z.enum(["added", "removed", "improved", "regressed", "unchanged"]),
|
|
94
|
+
}),
|
|
95
|
+
),
|
|
96
|
+
improvements: z.number(),
|
|
97
|
+
regressions: z.number(),
|
|
98
|
+
}),
|
|
99
|
+
artifactsDelta: z.object({
|
|
100
|
+
added: z.array(z.string()),
|
|
101
|
+
removed: z.array(z.string()),
|
|
102
|
+
changed: z.array(z.string()),
|
|
103
|
+
unchanged: z.array(z.string()),
|
|
104
|
+
}),
|
|
105
|
+
});
|
|
106
|
+
export const CompareOutputSchema = z.union([SuiteComparisonSchema, runComparison]);
|