mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-17 04:11:23 +00:00
feat(cli): expand fast_provision experiment to images + docker + sandbox (#3398)
* feat(cli): expand fast_provision experiment to images + docker + sandbox
Builds on the existing PostHog `fast_provision` flag (already wired via
shared/feature-flags.ts). The `test` variant now bundles the full
provisioning-speed stack rather than images alone:
- images: pre-built DO marketplace images (cloud-side faster boot)
- docker: Docker CE host image on Hetzner/GCP (cloud-side faster boot)
- sandbox: local agents run in a Docker container (local-side faster boot)
Users who explicitly pass --beta or --fast still take precedence and skip
the experiment bucket. Exposure events are still captured for both
variants so PostHog can compute conversion across the broader bundle.
Bumps CLI to 1.0.39.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 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>
* revert(cli): leave --fast untouched, experiment owns its own bundle
My previous commit (8f87330) added `sandbox` to --fast to align it with
the experiment test variant. That was wrong — --fast is unrelated to
the fast_provision experiment, has its own meaning, and shouldn't
inherit changes from the experiment bundle.
- Restore --fast to [tarball, images, parallel, docker] (its prior set).
- Drop the cross-reference comments tying --fast to the experiment.
- Keep expandFastProvisionVariant() and its unit tests intact — the
experiment bundle still lives in feature-flags.ts as a testable
pure helper, just no longer claims alignment with --fast.
- Bump CLI 1.0.40 -> 1.0.41.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude <claude@anthropic.com>
This commit is contained in:
parent
070be392f5
commit
af8ac24506
4 changed files with 54 additions and 6 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@openrouter/spawn",
|
||||
"version": "1.0.38",
|
||||
"version": "1.0.41",
|
||||
"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";
|
||||
|
|
@ -969,13 +969,16 @@ async function main(): Promise<void> {
|
|||
|
||||
// fast_provision experiment: if the user did NOT pass --beta or --fast,
|
||||
// bucket them on the PostHog `fast_provision` flag. The `test` variant
|
||||
// turns on images by default; control behaves as before.
|
||||
// turns on images + docker + sandbox by default; control behaves as before.
|
||||
// - images: pre-built DO marketplace images (cloud-side faster boot)
|
||||
// - 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");
|
||||
}
|
||||
const variantStr = isString(variant) ? variant : "control";
|
||||
betaFeatures.push(...expandFastProvisionVariant(variantStr));
|
||||
}
|
||||
|
||||
if (betaFeatures.length > 0) {
|
||||
|
|
|
|||
|
|
@ -201,6 +201,26 @@ 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. This is the experiment surface only —
|
||||
* unrelated to `--fast`, which is its own user-facing flag and stays as-is.
|
||||
*/
|
||||
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