docs/plans/eng-1770.md
promptfoo eval -c <uuid> Cloud Config SupportCurrently, promptfoo redteam run -c <uuid> supports loading configs from Promptfoo Cloud by UUID, but promptfoo eval -c only accepts local file paths. This feature extends the same cloud config loading pattern to the eval command, allowing users to run promptfoo eval -c <cloud-uuid> to fetch and execute a config stored in Promptfoo Cloud.
The ticket (ENG-1770) has two parts:
eval -cpromptfoo eval -c <uuid> command in the Cloud run modal (separate repo)getEvalConfigFromCloud() to src/util/cloud.tsCreate a new function modeled after the existing getConfigFromCloud() (line 88-114) but hitting a different endpoint for eval configs:
export async function getEvalConfigFromCloud(id: string): Promise<UnifiedConfig> {
// Same pattern as getConfigFromCloud but using `configs/${id}` endpoint
}
GET /api/v1/configs/${id} (eval configs, not redteam-specific)makeRequest() helper (line 25) and cloudConfig.isEnabled() check patterngetConfigFromCloudsrc/commands/eval.tsIn doEval() (line 107), add UUID detection before the existing config path processing at line 142. This mirrors the pattern in src/redteam/commands/run.ts:62-79.
// Before the existing config path processing (line 142)
const UUID_REGEX = /^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$/;
if (cmdObj.config?.length === 1 && UUID_REGEX.test(cmdObj.config[0])) {
const cloudConfigObj = await getEvalConfigFromCloud(cmdObj.config[0]);
defaultConfig = cloudConfigObj;
cmdObj.config = undefined;
}
Key behaviors:
defaultConfigcmdObj.config so resolveConfigs uses defaultConfig instead of trying to read a filegetEvalConfigFromCloud from ../../util/cloudUpdate the -c option description at line 903-906 to mention cloud UUID support:
.option(
'-c, --config <paths...>',
'Path to configuration file or cloud config UUID. Automatically loads promptfooconfig.yaml',
)
Create test cases in a new test file or add to existing eval command tests, following the pattern from test/redteam/commands/run.test.ts:
| File | Change |
|---|---|
src/util/cloud.ts | Add getEvalConfigFromCloud() function |
src/commands/eval.ts | Add UUID detection + cloud fetch in doEval(), update -c description |
test/commands/eval.test.ts or new test file | Add tests for UUID cloud config |
makeRequest() from src/util/cloud.ts:25 - authenticated HTTP helpercloudConfig.isEnabled() from src/globalConfig/cloud.ts - auth checksrc/redteam/commands/run.ts:17resolveConfigs() from src/util/config/load.ts:481 - existing config resolution (no changes needed)npm run build should succeednpm run l && npm run fnpx vitest src/commands/eval and npx vitest src/util/cloudnpm run local -- eval -c <valid-uuid> --env-file .env should fetch config from cloudnpm run local -- eval -c path/to/config.yaml should still work as beforenpm run local -- eval -c <invalid-uuid-format> should fall through to file resolutionGET /api/v1/configs/:id returning an envelope ({ config: ... }), not a raw payload.providers and tests; loading must not require additional requests.promptfoo://provider/<uuid>.tests defaults to [] when missing.description falls back to config.name when missing.--watch is not supported when -c <uuid> is used. CLI should fail fast with a clear error.-c <value> matches UUID format but cloud fetch fails (404/auth disabled), hard-fail.-c values are supplied and any value is a UUID, fail with an explicit error stating only one -c value is allowed for cloud UUID mode.test/commands/eval.test.ts for UUID detection/CLI behaviortest/util/cloud.test.ts for getEvalConfigFromCloud() contract/error handlingeval only (not redteam eval).defaultConfigPath for the run to prevent accidental local reload/fallback behavior.providerIds/testCases) into canonical fields (providers/tests).-c values with UUID mode:
Cloud config UUID mode supports exactly one -c value. Use: promptfoo eval -c <cloud-config-uuid>--watch:
--watch is not supported when using a cloud config UUID with -c. Use a local config file path for watch mode.Failed to load cloud eval config "<uuid>". <reason>. Cloud UUID inputs do not fall back to local file paths. Check authentication and that the UUID exists.None.