mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-17 04:11:23 +00:00
refactor(cli): extract fast_provision bundle helper, align --fast
Addresses review feedback on the fast_provision experiment expansion: - Align `--fast` with the experiment `test` variant. Previously --fast pushed [tarball, images, parallel, docker] (no sandbox) while the silent A/B pushed [images, docker, sandbox]. Add `sandbox` to --fast so the explicit user opt-in exercises the same surface as the silent experiment, plus the speed-ups outside the experiment scope. - Extract the experiment bundle into a pure `expandFastProvisionVariant` helper in shared/feature-flags.ts so the bundle composition is testable in isolation from main() arg parsing. Drop-in replacement in index.ts; behavior unchanged for the test variant. - Add unit tests pinning the bundle: test variant -> [images, docker, sandbox], control -> [], unknown variants -> [] (fail-closed). These guard against silent drift when someone tweaks the list later. - Bump CLI 1.0.39 -> 1.0.40 per the version-on-every-cli-change rule. Verified: bunx biome check src/ clean, bun test 2188/2188 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a5f831e9fb
commit
8f873306b7
4 changed files with 59 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@openrouter/spawn",
|
||||
"version": "1.0.39",
|
||||
"version": "1.0.40",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"spawn": "cli.js"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { dirname, join } from "node:path";
|
|||
import {
|
||||
_awaitBackgroundRefreshForTest,
|
||||
_resetFeatureFlagsForTest,
|
||||
expandFastProvisionVariant,
|
||||
getFeatureFlag,
|
||||
initFeatureFlags,
|
||||
} from "../shared/feature-flags.js";
|
||||
|
|
@ -225,4 +226,28 @@ describe("feature flags", () => {
|
|||
expect(getFeatureFlag("unknown", "default")).toBe("default");
|
||||
});
|
||||
});
|
||||
|
||||
describe("expandFastProvisionVariant", () => {
|
||||
// These tests pin the experiment bundle composition so that tweaking the
|
||||
// list in feature-flags.ts forces an explicit test update — drifting the
|
||||
// bundle silently is the failure mode we're guarding against.
|
||||
|
||||
it("returns the full provisioning-speed bundle for the test variant", () => {
|
||||
expect(expandFastProvisionVariant("test")).toEqual([
|
||||
"images",
|
||||
"docker",
|
||||
"sandbox",
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns an empty bundle for the control variant", () => {
|
||||
expect(expandFastProvisionVariant("control")).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns an empty bundle for unknown variants (fail-closed)", () => {
|
||||
expect(expandFastProvisionVariant("")).toEqual([]);
|
||||
expect(expandFastProvisionVariant("rollout")).toEqual([]);
|
||||
expect(expandFastProvisionVariant("totally-made-up")).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import {
|
|||
} from "./commands/index.js";
|
||||
import { expandEqualsFlags, findUnknownFlag } from "./flags.js";
|
||||
import { agentKeys, cloudKeys, getCacheAge, loadManifest } from "./manifest.js";
|
||||
import { getFeatureFlag, initFeatureFlags } from "./shared/feature-flags.js";
|
||||
import { expandFastProvisionVariant, getFeatureFlag, initFeatureFlags } from "./shared/feature-flags.js";
|
||||
import { getInstallRefPath } from "./shared/paths.js";
|
||||
import { asyncTryCatch, asyncTryCatchIf, isFileError, isNetworkError, tryCatch, tryCatchIf } from "./shared/result.js";
|
||||
import { captureError, initTelemetry, setTelemetryContext } from "./shared/telemetry.js";
|
||||
|
|
@ -962,9 +962,14 @@ async function main(): Promise<void> {
|
|||
process.exit(1);
|
||||
}
|
||||
}
|
||||
// --fast implies all beta features
|
||||
// --fast: explicit user opt-in to the full provisioning-speed stack. Kept
|
||||
// aligned with the `fast_provision` experiment's `test` variant (images,
|
||||
// docker, sandbox) so the explicit flag and the silent A/B exercise the same
|
||||
// surface — plus tarball + parallel, which are speed-ups outside the
|
||||
// experiment scope. If you change either bundle, update the other or the
|
||||
// alignment comment in expandFastProvisionVariant().
|
||||
if (process.env.SPAWN_FAST === "1") {
|
||||
betaFeatures.push("tarball", "images", "parallel", "docker");
|
||||
betaFeatures.push("tarball", "images", "parallel", "docker", "sandbox");
|
||||
}
|
||||
|
||||
// fast_provision experiment: if the user did NOT pass --beta or --fast,
|
||||
|
|
@ -974,11 +979,11 @@ async function main(): Promise<void> {
|
|||
// - docker: Docker CE host image on Hetzner/GCP (cloud-side faster boot)
|
||||
// - sandbox: local agents run in a Docker container (local-side faster boot)
|
||||
// Exposure is captured for both variants so PostHog can compute conversion.
|
||||
// Bundle composition lives in expandFastProvisionVariant() for unit testing.
|
||||
if (!userOptedIntoBeta) {
|
||||
const variant = getFeatureFlag("fast_provision", "control");
|
||||
if (variant === "test") {
|
||||
betaFeatures.push("images", "docker", "sandbox");
|
||||
}
|
||||
const variantStr = isString(variant) ? variant : "control";
|
||||
betaFeatures.push(...expandFastProvisionVariant(variantStr));
|
||||
}
|
||||
|
||||
if (betaFeatures.length > 0) {
|
||||
|
|
|
|||
|
|
@ -201,6 +201,28 @@ export function getFeatureFlag<T extends string | boolean>(key: string, fallback
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Beta features bundled by the `fast_provision` PostHog experiment for a given
|
||||
* variant. Returns an empty array for `control` or any unknown variant — the
|
||||
* caller is responsible for de-duping against features the user already passed.
|
||||
*
|
||||
* Kept as a pure, named export so the bundle composition is testable in
|
||||
* isolation from `main()` arg parsing. Keep this in sync with the `--fast`
|
||||
* branch in `index.ts` — both opt the user into the same speed-ups; they only
|
||||
* differ on `tarball` + `parallel`, which `--fast` adds (these aren't part of
|
||||
* the experiment because they're already on by default in most paths).
|
||||
*/
|
||||
export function expandFastProvisionVariant(variant: string): readonly string[] {
|
||||
if (variant === "test") {
|
||||
return [
|
||||
"images",
|
||||
"docker",
|
||||
"sandbox",
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/** Test-only: reset module state between tests. */
|
||||
export function _resetFeatureFlagsForTest(): void {
|
||||
_flags = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue