@hasna/testers 0.0.62 → 0.0.64
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/dist/cli/index.js +316 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -0
- package/dist/lib/model-credentials.d.ts +44 -0
- package/dist/lib/model-credentials.d.ts.map +1 -0
- package/dist/lib/workflow-fanout.d.ts +8 -0
- package/dist/lib/workflow-fanout.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -26847,6 +26847,149 @@ var require_lib3 = __commonJS((exports, module) => {
|
|
|
26847
26847
|
module.exports = Sharp;
|
|
26848
26848
|
});
|
|
26849
26849
|
|
|
26850
|
+
// src/lib/model-credentials.ts
|
|
26851
|
+
function resolveModelCredentialReference(reference, env = process.env, credentialResolver = resolveCredential) {
|
|
26852
|
+
if (reference.startsWith("$?")) {
|
|
26853
|
+
const varName = reference.slice(2).trim();
|
|
26854
|
+
return { source: "optional-env", apiKey: varName ? env[varName] ?? null : null };
|
|
26855
|
+
}
|
|
26856
|
+
if (reference.startsWith("$")) {
|
|
26857
|
+
const varName = reference.slice(1).trim();
|
|
26858
|
+
return { source: "env", apiKey: varName ? env[varName] ?? null : null };
|
|
26859
|
+
}
|
|
26860
|
+
if (reference.startsWith("@secrets:")) {
|
|
26861
|
+
return { source: "secret", apiKey: credentialResolver(reference) };
|
|
26862
|
+
}
|
|
26863
|
+
return { source: "literal", apiKey: reference };
|
|
26864
|
+
}
|
|
26865
|
+
function resolveModelCredential(modelOrPreset, options = {}) {
|
|
26866
|
+
const model = resolveModel(modelOrPreset ?? loadConfig().defaultModel);
|
|
26867
|
+
const provider = detectProvider(model);
|
|
26868
|
+
const envKey = MODEL_PROVIDER_ENV_KEYS[provider];
|
|
26869
|
+
const reference = options.reference ?? `$${envKey}`;
|
|
26870
|
+
const resolved = resolveModelCredentialReference(reference, options.env, options.credentialResolver);
|
|
26871
|
+
return {
|
|
26872
|
+
provider,
|
|
26873
|
+
model,
|
|
26874
|
+
envKey,
|
|
26875
|
+
reference,
|
|
26876
|
+
source: resolved.source,
|
|
26877
|
+
apiKey: resolved.apiKey
|
|
26878
|
+
};
|
|
26879
|
+
}
|
|
26880
|
+
async function validateModelCredential(input) {
|
|
26881
|
+
const endpoint = getModelCredentialValidationEndpoint(input.provider);
|
|
26882
|
+
if (!endpoint) {
|
|
26883
|
+
return { ok: true, message: `No live validation endpoint configured for provider ${input.provider}` };
|
|
26884
|
+
}
|
|
26885
|
+
try {
|
|
26886
|
+
const response = await fetch(endpoint.url, {
|
|
26887
|
+
headers: endpoint.headers(input.apiKey)
|
|
26888
|
+
});
|
|
26889
|
+
if (response.ok)
|
|
26890
|
+
return { ok: true, status: response.status };
|
|
26891
|
+
const text = await response.text().catch(() => "");
|
|
26892
|
+
return {
|
|
26893
|
+
ok: false,
|
|
26894
|
+
status: response.status,
|
|
26895
|
+
message: summarizeModelCredentialValidationError(text) ?? response.statusText
|
|
26896
|
+
};
|
|
26897
|
+
} catch (error) {
|
|
26898
|
+
return {
|
|
26899
|
+
ok: false,
|
|
26900
|
+
message: error instanceof Error ? error.message : String(error)
|
|
26901
|
+
};
|
|
26902
|
+
}
|
|
26903
|
+
}
|
|
26904
|
+
async function checkModelCredential(modelOrPreset, options = {}) {
|
|
26905
|
+
const resolved = resolveModelCredential(modelOrPreset, options);
|
|
26906
|
+
if (!resolved.apiKey) {
|
|
26907
|
+
return {
|
|
26908
|
+
provider: resolved.provider,
|
|
26909
|
+
model: resolved.model,
|
|
26910
|
+
envKey: resolved.envKey,
|
|
26911
|
+
reference: resolved.reference,
|
|
26912
|
+
source: resolved.source,
|
|
26913
|
+
ok: false,
|
|
26914
|
+
message: `Missing ${resolved.envKey} for model provider "${resolved.provider}"`
|
|
26915
|
+
};
|
|
26916
|
+
}
|
|
26917
|
+
const validation = await (options.validator ?? validateModelCredential)({
|
|
26918
|
+
provider: resolved.provider,
|
|
26919
|
+
model: resolved.model,
|
|
26920
|
+
apiKey: resolved.apiKey
|
|
26921
|
+
});
|
|
26922
|
+
return {
|
|
26923
|
+
provider: resolved.provider,
|
|
26924
|
+
model: resolved.model,
|
|
26925
|
+
envKey: resolved.envKey,
|
|
26926
|
+
reference: resolved.reference,
|
|
26927
|
+
source: resolved.source,
|
|
26928
|
+
ok: validation.ok,
|
|
26929
|
+
status: validation.status,
|
|
26930
|
+
message: validation.ok ? validation.message : validation.message ?? "provider rejected the credential"
|
|
26931
|
+
};
|
|
26932
|
+
}
|
|
26933
|
+
function getModelCredentialValidationEndpoint(provider) {
|
|
26934
|
+
if (provider === "anthropic") {
|
|
26935
|
+
return {
|
|
26936
|
+
url: "https://api.anthropic.com/v1/models",
|
|
26937
|
+
headers: (apiKey) => ({
|
|
26938
|
+
"x-api-key": apiKey,
|
|
26939
|
+
"anthropic-version": "2023-06-01"
|
|
26940
|
+
})
|
|
26941
|
+
};
|
|
26942
|
+
}
|
|
26943
|
+
if (provider === "openai") {
|
|
26944
|
+
return {
|
|
26945
|
+
url: "https://api.openai.com/v1/models",
|
|
26946
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
26947
|
+
};
|
|
26948
|
+
}
|
|
26949
|
+
if (provider === "cerebras") {
|
|
26950
|
+
return {
|
|
26951
|
+
url: "https://api.cerebras.ai/v1/models",
|
|
26952
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
26953
|
+
};
|
|
26954
|
+
}
|
|
26955
|
+
if (provider === "zai") {
|
|
26956
|
+
return {
|
|
26957
|
+
url: "https://api.z.ai/api/paas/v4/models",
|
|
26958
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
26959
|
+
};
|
|
26960
|
+
}
|
|
26961
|
+
if (provider === "google") {
|
|
26962
|
+
return {
|
|
26963
|
+
url: "https://generativelanguage.googleapis.com/v1beta/openai/models",
|
|
26964
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
26965
|
+
};
|
|
26966
|
+
}
|
|
26967
|
+
return null;
|
|
26968
|
+
}
|
|
26969
|
+
function summarizeModelCredentialValidationError(text) {
|
|
26970
|
+
if (!text.trim())
|
|
26971
|
+
return;
|
|
26972
|
+
try {
|
|
26973
|
+
const parsed = JSON.parse(text);
|
|
26974
|
+
return parsed.error?.type ?? parsed.error?.code ?? parsed.error?.message ?? parsed.message;
|
|
26975
|
+
} catch {
|
|
26976
|
+
return text.trim().slice(0, 200);
|
|
26977
|
+
}
|
|
26978
|
+
}
|
|
26979
|
+
var MODEL_PROVIDER_ENV_KEYS;
|
|
26980
|
+
var init_model_credentials = __esm(() => {
|
|
26981
|
+
init_ai_client();
|
|
26982
|
+
init_config2();
|
|
26983
|
+
init_secrets_resolver();
|
|
26984
|
+
MODEL_PROVIDER_ENV_KEYS = {
|
|
26985
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
26986
|
+
openai: "OPENAI_API_KEY",
|
|
26987
|
+
google: "GOOGLE_API_KEY",
|
|
26988
|
+
cerebras: "CEREBRAS_API_KEY",
|
|
26989
|
+
zai: "ZAI_API_KEY"
|
|
26990
|
+
};
|
|
26991
|
+
});
|
|
26992
|
+
|
|
26850
26993
|
// src/db/api-checks.ts
|
|
26851
26994
|
function createApiCheck(input) {
|
|
26852
26995
|
const db2 = getDatabase();
|
|
@@ -60782,6 +60925,9 @@ function resolveWorkflowFanoutSelection(options) {
|
|
|
60782
60925
|
async function checkWorkflowFanoutReadiness(workflows, dependencies = {}) {
|
|
60783
60926
|
const checks = [];
|
|
60784
60927
|
const env = dependencies.env ?? process.env;
|
|
60928
|
+
const model = resolveModel(dependencies.model ?? loadConfig().defaultModel);
|
|
60929
|
+
const modelProvider = detectProvider(model);
|
|
60930
|
+
const modelEnvKey = MODEL_PROVIDER_ENV_KEYS[modelProvider];
|
|
60785
60931
|
for (const [provider, providerWorkflows] of groupWorkflowsByProvider(workflows)) {
|
|
60786
60932
|
const envKey = PROVIDER_ENV_KEYS[provider];
|
|
60787
60933
|
if (!envKey) {
|
|
@@ -60857,6 +61003,37 @@ async function checkWorkflowFanoutReadiness(workflows, dependencies = {}) {
|
|
|
60857
61003
|
details: { missing: optionalMissing }
|
|
60858
61004
|
});
|
|
60859
61005
|
}
|
|
61006
|
+
const modelCredentialResolution = collectModelCredentialReadiness(workflows, modelProvider, modelEnvKey, env, dependencies.credentialResolver);
|
|
61007
|
+
checks.push({
|
|
61008
|
+
name: `model:${modelProvider}`,
|
|
61009
|
+
ok: modelCredentialResolution.missing.length === 0,
|
|
61010
|
+
required: true,
|
|
61011
|
+
message: modelCredentialResolution.missing.length === 0 ? `Model provider "${modelProvider}" credential is available for ${workflows.length} workflow(s)` : `Missing sandbox model credential for "${modelProvider}". Add ${modelEnvKey} to workflow sandbox env or choose a model for a provider with credentials`,
|
|
61012
|
+
workflows: modelCredentialResolution.missing.length > 0 ? [...new Set(modelCredentialResolution.missing.map((item) => item.workflowName))] : workflows.map((workflow) => workflow.name),
|
|
61013
|
+
details: {
|
|
61014
|
+
provider: modelProvider,
|
|
61015
|
+
model,
|
|
61016
|
+
envKey: modelEnvKey,
|
|
61017
|
+
...modelCredentialResolution.missing.length > 0 ? { missing: modelCredentialResolution.missing } : {}
|
|
61018
|
+
}
|
|
61019
|
+
});
|
|
61020
|
+
if (dependencies.validateModelCredentials && modelCredentialResolution.available.length > 0) {
|
|
61021
|
+
const validator = dependencies.modelCredentialValidator ?? validateModelCredential;
|
|
61022
|
+
const sample = modelCredentialResolution.available[0];
|
|
61023
|
+
const validation = await validator({ provider: modelProvider, model, apiKey: sample.apiKey });
|
|
61024
|
+
checks.push({
|
|
61025
|
+
name: `model:${modelProvider}:live`,
|
|
61026
|
+
ok: validation.ok,
|
|
61027
|
+
required: true,
|
|
61028
|
+
message: validation.ok ? `Model provider "${modelProvider}" credential passed live validation` : `Model provider "${modelProvider}" credential failed live validation${validation.status ? ` (${validation.status})` : ""}: ${validation.message ?? "provider rejected the credential"}`,
|
|
61029
|
+
workflows: workflows.map((workflow) => workflow.name),
|
|
61030
|
+
details: {
|
|
61031
|
+
provider: modelProvider,
|
|
61032
|
+
model,
|
|
61033
|
+
status: validation.status
|
|
61034
|
+
}
|
|
61035
|
+
});
|
|
61036
|
+
}
|
|
60860
61037
|
return {
|
|
60861
61038
|
ok: checks.every((check) => check.ok || !check.required),
|
|
60862
61039
|
checks
|
|
@@ -60889,6 +61066,9 @@ async function runWorkflowFanout(options, dependencies = {}) {
|
|
|
60889
61066
|
} = dependencies;
|
|
60890
61067
|
const preflight = preflightOverride ? await preflightOverride(workflows) : await checkWorkflowFanoutReadiness(workflows, {
|
|
60891
61068
|
providerApiKeyResolver,
|
|
61069
|
+
model: options.model,
|
|
61070
|
+
validateModelCredentials: options.validateModelCredentials,
|
|
61071
|
+
modelCredentialValidator: dependencies.modelCredentialValidator,
|
|
60892
61072
|
commandExists,
|
|
60893
61073
|
credentialResolver,
|
|
60894
61074
|
env
|
|
@@ -61070,6 +61250,24 @@ function collectMissingSandboxEnvRefs(workflows, env, credentialResolver) {
|
|
|
61070
61250
|
}
|
|
61071
61251
|
return { requiredMissing, optionalMissing };
|
|
61072
61252
|
}
|
|
61253
|
+
function collectModelCredentialReadiness(workflows, provider, envKey, env, credentialResolver) {
|
|
61254
|
+
const missing = [];
|
|
61255
|
+
const available = [];
|
|
61256
|
+
for (const workflow of workflows) {
|
|
61257
|
+
const reference = workflow.execution.env?.[envKey];
|
|
61258
|
+
if (!reference) {
|
|
61259
|
+
missing.push({ workflowId: workflow.id, workflowName: workflow.name, provider, key: envKey });
|
|
61260
|
+
continue;
|
|
61261
|
+
}
|
|
61262
|
+
const resolved = resolveModelCredentialReference(reference, env, credentialResolver ?? resolveCredential).apiKey;
|
|
61263
|
+
if (!resolved) {
|
|
61264
|
+
missing.push({ workflowId: workflow.id, workflowName: workflow.name, provider, key: envKey, reference });
|
|
61265
|
+
continue;
|
|
61266
|
+
}
|
|
61267
|
+
available.push({ workflowId: workflow.id, workflowName: workflow.name, provider, key: envKey, apiKey: resolved });
|
|
61268
|
+
}
|
|
61269
|
+
return { missing, available };
|
|
61270
|
+
}
|
|
61073
61271
|
function isResolvableEnvReference(value) {
|
|
61074
61272
|
return value.startsWith("$") || value.startsWith("@secrets:");
|
|
61075
61273
|
}
|
|
@@ -61089,6 +61287,9 @@ var init_workflow_fanout = __esm(() => {
|
|
|
61089
61287
|
init_workflows();
|
|
61090
61288
|
init_workflow_runner();
|
|
61091
61289
|
init_secrets_resolver();
|
|
61290
|
+
init_ai_client();
|
|
61291
|
+
init_config2();
|
|
61292
|
+
init_model_credentials();
|
|
61092
61293
|
PROVIDER_ENV_KEYS = {
|
|
61093
61294
|
e2b: "E2B_API_KEY",
|
|
61094
61295
|
daytona: "DAYTONA_API_KEY",
|
|
@@ -95753,7 +95954,7 @@ import chalk6 from "chalk";
|
|
|
95753
95954
|
// package.json
|
|
95754
95955
|
var package_default = {
|
|
95755
95956
|
name: "@hasna/testers",
|
|
95756
|
-
version: "0.0.
|
|
95957
|
+
version: "0.0.64",
|
|
95757
95958
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
95758
95959
|
type: "module",
|
|
95759
95960
|
main: "dist/index.js",
|
|
@@ -97515,6 +97716,7 @@ function redactPersonas(personas) {
|
|
|
97515
97716
|
}
|
|
97516
97717
|
|
|
97517
97718
|
// src/cli/index.tsx
|
|
97719
|
+
init_model_credentials();
|
|
97518
97720
|
init_projects();
|
|
97519
97721
|
init_personas();
|
|
97520
97722
|
init_api_checks();
|
|
@@ -98630,6 +98832,64 @@ function splitCsvOption(value) {
|
|
|
98630
98832
|
const items = value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
|
|
98631
98833
|
return items.length > 0 ? items : undefined;
|
|
98632
98834
|
}
|
|
98835
|
+
function splitRepeatedValues(values) {
|
|
98836
|
+
return (values ?? []).flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean);
|
|
98837
|
+
}
|
|
98838
|
+
var MODEL_CREDENTIAL_SAMPLE_MODELS = {
|
|
98839
|
+
anthropic: "quick",
|
|
98840
|
+
openai: "gpt-4o-mini",
|
|
98841
|
+
google: "gemini-2.0-flash",
|
|
98842
|
+
cerebras: "cerebras-fast",
|
|
98843
|
+
zai: "glm-4.6"
|
|
98844
|
+
};
|
|
98845
|
+
function modelCredentialProviderFromTarget(target) {
|
|
98846
|
+
const normalized = target.trim();
|
|
98847
|
+
const providerName = normalized.toLowerCase();
|
|
98848
|
+
const envName = normalized.toUpperCase();
|
|
98849
|
+
for (const provider of Object.keys(MODEL_PROVIDER_ENV_KEYS)) {
|
|
98850
|
+
if (provider === providerName || MODEL_PROVIDER_ENV_KEYS[provider] === envName) {
|
|
98851
|
+
return provider;
|
|
98852
|
+
}
|
|
98853
|
+
}
|
|
98854
|
+
return null;
|
|
98855
|
+
}
|
|
98856
|
+
function parseModelCredentialAssignments(values) {
|
|
98857
|
+
const assignments = {};
|
|
98858
|
+
for (const value of values ?? []) {
|
|
98859
|
+
const separator = value.indexOf("=");
|
|
98860
|
+
if (separator < 0) {
|
|
98861
|
+
throw new Error(`Invalid credential assignment: ${value}. Use provider=reference or ENV_KEY=reference.`);
|
|
98862
|
+
}
|
|
98863
|
+
const target = value.slice(0, separator).trim();
|
|
98864
|
+
const reference = value.slice(separator + 1).trim();
|
|
98865
|
+
if (!reference) {
|
|
98866
|
+
throw new Error(`Invalid credential assignment: ${value}. Reference cannot be empty.`);
|
|
98867
|
+
}
|
|
98868
|
+
const provider = modelCredentialProviderFromTarget(target);
|
|
98869
|
+
if (!provider) {
|
|
98870
|
+
throw new Error(`Unknown model provider or env key: ${target}`);
|
|
98871
|
+
}
|
|
98872
|
+
assignments[provider] = reference;
|
|
98873
|
+
}
|
|
98874
|
+
return assignments;
|
|
98875
|
+
}
|
|
98876
|
+
function sanitizeCredentialReference(reference, source) {
|
|
98877
|
+
if (source === "literal")
|
|
98878
|
+
return "[literal]";
|
|
98879
|
+
return reference;
|
|
98880
|
+
}
|
|
98881
|
+
function toModelCredentialCliItem(check2) {
|
|
98882
|
+
return {
|
|
98883
|
+
provider: check2.provider,
|
|
98884
|
+
model: check2.model,
|
|
98885
|
+
envKey: check2.envKey,
|
|
98886
|
+
reference: sanitizeCredentialReference(check2.reference, check2.source),
|
|
98887
|
+
source: check2.source,
|
|
98888
|
+
ok: check2.ok,
|
|
98889
|
+
...check2.status !== undefined ? { status: check2.status } : {},
|
|
98890
|
+
...check2.message ? { message: check2.message } : {}
|
|
98891
|
+
};
|
|
98892
|
+
}
|
|
98633
98893
|
function describeStoredAssertion(value) {
|
|
98634
98894
|
if (typeof value === "string")
|
|
98635
98895
|
return value;
|
|
@@ -101328,6 +101588,59 @@ envCmd.command("list").description("List all environments").option("--project <i
|
|
|
101328
101588
|
process.exit(1);
|
|
101329
101589
|
}
|
|
101330
101590
|
});
|
|
101591
|
+
envCmd.command("validate-models [models...]").description("Validate model provider credentials without launching browser or sandbox runs").option("--model <model>", "Model or preset to validate (repeatable)", (val, acc) => {
|
|
101592
|
+
acc.push(val);
|
|
101593
|
+
return acc;
|
|
101594
|
+
}, []).option("--credential <assignment>", "Credential reference override, e.g. anthropic=@secrets:path or OPENAI_API_KEY=$OPENAI_API_KEY (repeatable)", (val, acc) => {
|
|
101595
|
+
acc.push(val);
|
|
101596
|
+
return acc;
|
|
101597
|
+
}, []).option("--all-providers", "Validate representative models for every supported model provider", false).option("--json", "Output as JSON", false).action(async (models = [], opts) => {
|
|
101598
|
+
try {
|
|
101599
|
+
const requestedModels = splitRepeatedValues([
|
|
101600
|
+
...models,
|
|
101601
|
+
...opts.model ?? []
|
|
101602
|
+
]);
|
|
101603
|
+
const providerSamples = opts.allProviders ? Object.values(MODEL_CREDENTIAL_SAMPLE_MODELS) : [];
|
|
101604
|
+
const modelsToCheck = [...new Set([...providerSamples, ...requestedModels])];
|
|
101605
|
+
const inputs = modelsToCheck.length > 0 ? modelsToCheck : [undefined];
|
|
101606
|
+
const credentialAssignments = parseModelCredentialAssignments(opts.credential);
|
|
101607
|
+
const checks3 = [];
|
|
101608
|
+
for (const modelInput of inputs) {
|
|
101609
|
+
const resolution = resolveModelCredential(modelInput);
|
|
101610
|
+
const reference = credentialAssignments[resolution.provider] ?? `$${resolution.envKey}`;
|
|
101611
|
+
checks3.push(await checkModelCredential(modelInput, { reference }));
|
|
101612
|
+
}
|
|
101613
|
+
const items = checks3.map(toModelCredentialCliItem);
|
|
101614
|
+
const passed = items.filter((item) => item.ok).length;
|
|
101615
|
+
const failed = items.length - passed;
|
|
101616
|
+
const result = {
|
|
101617
|
+
ok: failed === 0,
|
|
101618
|
+
total: items.length,
|
|
101619
|
+
passed,
|
|
101620
|
+
failed,
|
|
101621
|
+
items
|
|
101622
|
+
};
|
|
101623
|
+
if (opts.json) {
|
|
101624
|
+
log(JSON.stringify(result, null, 2));
|
|
101625
|
+
} else {
|
|
101626
|
+
const heading = result.ok ? chalk6.green(`Model credential validation passed: ${passed}/${items.length}`) : chalk6.red(`Model credential validation failed: ${passed}/${items.length}`);
|
|
101627
|
+
log(chalk6.bold(heading));
|
|
101628
|
+
for (const item of items) {
|
|
101629
|
+
const status = item.status !== undefined ? ` status=${item.status}` : "";
|
|
101630
|
+
const message = item.message ? ` ${item.message}` : "";
|
|
101631
|
+
const state = item.ok ? chalk6.green("OK") : chalk6.red("FAIL");
|
|
101632
|
+
log(` ${state} ${item.model} (${item.provider}, ${item.envKey})${status}${message}`);
|
|
101633
|
+
log(chalk6.dim(` reference: ${item.reference} (${item.source})`));
|
|
101634
|
+
}
|
|
101635
|
+
}
|
|
101636
|
+
if (!result.ok) {
|
|
101637
|
+
process.exit(1);
|
|
101638
|
+
}
|
|
101639
|
+
} catch (error40) {
|
|
101640
|
+
logError(chalk6.red(`Error: ${error40 instanceof Error ? error40.message : String(error40)}`));
|
|
101641
|
+
process.exit(1);
|
|
101642
|
+
}
|
|
101643
|
+
});
|
|
101331
101644
|
envCmd.command("use <name>").description("Set an environment as the default").action((name21) => {
|
|
101332
101645
|
try {
|
|
101333
101646
|
setDefaultEnvironment(name21);
|
|
@@ -102538,7 +102851,7 @@ workflowCmd.command("run <id>").description("Run a saved testing workflow").requ
|
|
|
102538
102851
|
workflowCmd.command("fanout [ids...]").description("Run multiple saved sandbox workflows concurrently").requiredOption("-u, --url <url>", "Target URL").option("--project <id>", "Project ID").option("--tag <tag>", "Workflow scenario tag filter (repeatable)", (val, acc) => {
|
|
102539
102852
|
acc.push(val);
|
|
102540
102853
|
return acc;
|
|
102541
|
-
}, []).option("--all", "Include disabled workflows when selecting by project/tag", false).option("--workers <n>", "Concurrent sandboxes, 1-12 (default: 6)", "6").option("--batch-size <n>", "Limit this run to a batch of selected workflows").option("--batch <n>", "1-based batch number to run with --batch-size").option("--offset <n>", "0-based selected-workflow offset for staged fanout").option("--all-batches", "Run all selected workflow batches sequentially with --batch-size", false).option("--from-batch <n>", "First batch to run when using --all-batches").option("--to-batch <n>", "Last batch to run when using --all-batches").option("--continue-on-failure", "Continue later batches after a failed batch", false).option("-m, --model <model>", "AI model").option("--headed", "Run headed", false).option("--parallel <n>", "Parallel browser workers inside each sandbox").option("--timeout <ms>", "Override workflow timeout").option("--dry-run", "Print resolved sandbox plans without spawning sandboxes", false).option("--json", "Output as JSON", false).action(async (ids, opts) => {
|
|
102854
|
+
}, []).option("--all", "Include disabled workflows when selecting by project/tag", false).option("--workers <n>", "Concurrent sandboxes, 1-12 (default: 6)", "6").option("--batch-size <n>", "Limit this run to a batch of selected workflows").option("--batch <n>", "1-based batch number to run with --batch-size").option("--offset <n>", "0-based selected-workflow offset for staged fanout").option("--all-batches", "Run all selected workflow batches sequentially with --batch-size", false).option("--from-batch <n>", "First batch to run when using --all-batches").option("--to-batch <n>", "Last batch to run when using --all-batches").option("--continue-on-failure", "Continue later batches after a failed batch", false).option("-m, --model <model>", "AI model").option("--headed", "Run headed", false).option("--parallel <n>", "Parallel browser workers inside each sandbox").option("--timeout <ms>", "Override workflow timeout").option("--validate-model-credentials", "Call model provider auth endpoints during fanout preflight", false).option("--dry-run", "Print resolved sandbox plans without spawning sandboxes", false).option("--json", "Output as JSON", false).action(async (ids, opts) => {
|
|
102542
102855
|
try {
|
|
102543
102856
|
const fanoutOptions = {
|
|
102544
102857
|
workflowIds: ids,
|
|
@@ -102557,6 +102870,7 @@ workflowCmd.command("fanout [ids...]").description("Run multiple saved sandbox w
|
|
|
102557
102870
|
headed: opts.headed,
|
|
102558
102871
|
parallel: opts.parallel ? parseInt(opts.parallel, 10) : undefined,
|
|
102559
102872
|
timeout: opts.timeout ? parseInt(opts.timeout, 10) : undefined,
|
|
102873
|
+
validateModelCredentials: opts.validateModelCredentials,
|
|
102560
102874
|
dryRun: opts.dryRun
|
|
102561
102875
|
};
|
|
102562
102876
|
const runAllBatches = opts.allBatches || opts.fromBatch !== undefined || opts.toBatch !== undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export type { Webhook, WebhookPayload } from "./lib/webhooks.js";
|
|
|
42
42
|
export { writeRunMeta, writeScenarioMeta } from "./lib/screenshotter.js";
|
|
43
43
|
export type { CaptureResult } from "./lib/screenshotter.js";
|
|
44
44
|
export { resolveCredential, isCredentialReference } from "./lib/secrets-resolver.js";
|
|
45
|
+
export { MODEL_PROVIDER_ENV_KEYS, checkModelCredential, resolveModelCredential, resolveModelCredentialReference, validateModelCredential, } from "./lib/model-credentials.js";
|
|
46
|
+
export type { ModelCredentialCheck, ModelCredentialResolution, ModelCredentialValidationInput, ModelCredentialValidationResult, } from "./lib/model-credentials.js";
|
|
45
47
|
export { ensurePersonaAuthenticated, loginWithAuthConfig } from "./lib/persona-auth.js";
|
|
46
48
|
export type { LoginResult } from "./lib/persona-auth.js";
|
|
47
49
|
export { discoverRepo, clearDiscoveryCache, getDiscoveryCacheInfo, } from "./lib/repo-discovery.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,QAAQ,EACR,WAAW,EACX,MAAM,EACN,SAAS,EACT,aAAa,EACb,OAAO,EACP,KAAK,EACL,QAAQ,EACR,GAAG,EACH,MAAM,EACN,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,OAAO,EACP,IAAI,EACJ,eAAe,EACf,eAAe,EACf,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,6BAA6B,EAC7B,sBAAsB,EACtB,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,SAAS,EACT,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,GAAG,EACH,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,UAAU,GACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,yBAAyB,EACzB,eAAe,EACf,UAAU,EACV,OAAO,EACP,SAAS,EACT,UAAU,GACX,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,YAAY,IAAI,kBAAkB,EAClC,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,OAAO,EACP,YAAY,EACZ,WAAW,EACX,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,aAAa,EACb,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,0BAA0B,EAC1B,wBAAwB,EACxB,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,cAAc,EACd,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,cAAc,EACd,SAAS,EACT,mBAAmB,EACnB,eAAe,EACf,YAAY,GACb,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,SAAS,EACT,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EACL,WAAW,EACX,eAAe,EACf,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,+BAA+B,EAC/B,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,oBAAoB,EACpB,yBAAyB,EACzB,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACxF,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,QAAQ,EACR,eAAe,EACf,UAAU,EACV,cAAc,EACd,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,YAAY,EACZ,OAAO,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20349,6 +20349,144 @@ async function startWatcher(options) {
|
|
|
20349
20349
|
process.on("SIGTERM", cleanup);
|
|
20350
20350
|
await new Promise(() => {});
|
|
20351
20351
|
}
|
|
20352
|
+
// src/lib/model-credentials.ts
|
|
20353
|
+
init_ai_client();
|
|
20354
|
+
init_config2();
|
|
20355
|
+
var MODEL_PROVIDER_ENV_KEYS = {
|
|
20356
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
20357
|
+
openai: "OPENAI_API_KEY",
|
|
20358
|
+
google: "GOOGLE_API_KEY",
|
|
20359
|
+
cerebras: "CEREBRAS_API_KEY",
|
|
20360
|
+
zai: "ZAI_API_KEY"
|
|
20361
|
+
};
|
|
20362
|
+
function resolveModelCredentialReference(reference, env2 = process.env, credentialResolver = resolveCredential) {
|
|
20363
|
+
if (reference.startsWith("$?")) {
|
|
20364
|
+
const varName = reference.slice(2).trim();
|
|
20365
|
+
return { source: "optional-env", apiKey: varName ? env2[varName] ?? null : null };
|
|
20366
|
+
}
|
|
20367
|
+
if (reference.startsWith("$")) {
|
|
20368
|
+
const varName = reference.slice(1).trim();
|
|
20369
|
+
return { source: "env", apiKey: varName ? env2[varName] ?? null : null };
|
|
20370
|
+
}
|
|
20371
|
+
if (reference.startsWith("@secrets:")) {
|
|
20372
|
+
return { source: "secret", apiKey: credentialResolver(reference) };
|
|
20373
|
+
}
|
|
20374
|
+
return { source: "literal", apiKey: reference };
|
|
20375
|
+
}
|
|
20376
|
+
function resolveModelCredential(modelOrPreset, options = {}) {
|
|
20377
|
+
const model = resolveModel2(modelOrPreset ?? loadConfig().defaultModel);
|
|
20378
|
+
const provider = detectProvider(model);
|
|
20379
|
+
const envKey = MODEL_PROVIDER_ENV_KEYS[provider];
|
|
20380
|
+
const reference = options.reference ?? `$${envKey}`;
|
|
20381
|
+
const resolved = resolveModelCredentialReference(reference, options.env, options.credentialResolver);
|
|
20382
|
+
return {
|
|
20383
|
+
provider,
|
|
20384
|
+
model,
|
|
20385
|
+
envKey,
|
|
20386
|
+
reference,
|
|
20387
|
+
source: resolved.source,
|
|
20388
|
+
apiKey: resolved.apiKey
|
|
20389
|
+
};
|
|
20390
|
+
}
|
|
20391
|
+
async function validateModelCredential(input) {
|
|
20392
|
+
const endpoint = getModelCredentialValidationEndpoint(input.provider);
|
|
20393
|
+
if (!endpoint) {
|
|
20394
|
+
return { ok: true, message: `No live validation endpoint configured for provider ${input.provider}` };
|
|
20395
|
+
}
|
|
20396
|
+
try {
|
|
20397
|
+
const response = await fetch(endpoint.url, {
|
|
20398
|
+
headers: endpoint.headers(input.apiKey)
|
|
20399
|
+
});
|
|
20400
|
+
if (response.ok)
|
|
20401
|
+
return { ok: true, status: response.status };
|
|
20402
|
+
const text = await response.text().catch(() => "");
|
|
20403
|
+
return {
|
|
20404
|
+
ok: false,
|
|
20405
|
+
status: response.status,
|
|
20406
|
+
message: summarizeModelCredentialValidationError(text) ?? response.statusText
|
|
20407
|
+
};
|
|
20408
|
+
} catch (error) {
|
|
20409
|
+
return {
|
|
20410
|
+
ok: false,
|
|
20411
|
+
message: error instanceof Error ? error.message : String(error)
|
|
20412
|
+
};
|
|
20413
|
+
}
|
|
20414
|
+
}
|
|
20415
|
+
async function checkModelCredential(modelOrPreset, options = {}) {
|
|
20416
|
+
const resolved = resolveModelCredential(modelOrPreset, options);
|
|
20417
|
+
if (!resolved.apiKey) {
|
|
20418
|
+
return {
|
|
20419
|
+
provider: resolved.provider,
|
|
20420
|
+
model: resolved.model,
|
|
20421
|
+
envKey: resolved.envKey,
|
|
20422
|
+
reference: resolved.reference,
|
|
20423
|
+
source: resolved.source,
|
|
20424
|
+
ok: false,
|
|
20425
|
+
message: `Missing ${resolved.envKey} for model provider "${resolved.provider}"`
|
|
20426
|
+
};
|
|
20427
|
+
}
|
|
20428
|
+
const validation = await (options.validator ?? validateModelCredential)({
|
|
20429
|
+
provider: resolved.provider,
|
|
20430
|
+
model: resolved.model,
|
|
20431
|
+
apiKey: resolved.apiKey
|
|
20432
|
+
});
|
|
20433
|
+
return {
|
|
20434
|
+
provider: resolved.provider,
|
|
20435
|
+
model: resolved.model,
|
|
20436
|
+
envKey: resolved.envKey,
|
|
20437
|
+
reference: resolved.reference,
|
|
20438
|
+
source: resolved.source,
|
|
20439
|
+
ok: validation.ok,
|
|
20440
|
+
status: validation.status,
|
|
20441
|
+
message: validation.ok ? validation.message : validation.message ?? "provider rejected the credential"
|
|
20442
|
+
};
|
|
20443
|
+
}
|
|
20444
|
+
function getModelCredentialValidationEndpoint(provider) {
|
|
20445
|
+
if (provider === "anthropic") {
|
|
20446
|
+
return {
|
|
20447
|
+
url: "https://api.anthropic.com/v1/models",
|
|
20448
|
+
headers: (apiKey) => ({
|
|
20449
|
+
"x-api-key": apiKey,
|
|
20450
|
+
"anthropic-version": "2023-06-01"
|
|
20451
|
+
})
|
|
20452
|
+
};
|
|
20453
|
+
}
|
|
20454
|
+
if (provider === "openai") {
|
|
20455
|
+
return {
|
|
20456
|
+
url: "https://api.openai.com/v1/models",
|
|
20457
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
20458
|
+
};
|
|
20459
|
+
}
|
|
20460
|
+
if (provider === "cerebras") {
|
|
20461
|
+
return {
|
|
20462
|
+
url: "https://api.cerebras.ai/v1/models",
|
|
20463
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
20464
|
+
};
|
|
20465
|
+
}
|
|
20466
|
+
if (provider === "zai") {
|
|
20467
|
+
return {
|
|
20468
|
+
url: "https://api.z.ai/api/paas/v4/models",
|
|
20469
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
20470
|
+
};
|
|
20471
|
+
}
|
|
20472
|
+
if (provider === "google") {
|
|
20473
|
+
return {
|
|
20474
|
+
url: "https://generativelanguage.googleapis.com/v1beta/openai/models",
|
|
20475
|
+
headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
|
|
20476
|
+
};
|
|
20477
|
+
}
|
|
20478
|
+
return null;
|
|
20479
|
+
}
|
|
20480
|
+
function summarizeModelCredentialValidationError(text) {
|
|
20481
|
+
if (!text.trim())
|
|
20482
|
+
return;
|
|
20483
|
+
try {
|
|
20484
|
+
const parsed = JSON.parse(text);
|
|
20485
|
+
return parsed.error?.type ?? parsed.error?.code ?? parsed.error?.message ?? parsed.message;
|
|
20486
|
+
} catch {
|
|
20487
|
+
return text.trim().slice(0, 200);
|
|
20488
|
+
}
|
|
20489
|
+
}
|
|
20352
20490
|
// src/lib/repo-discovery.ts
|
|
20353
20491
|
init_paths();
|
|
20354
20492
|
import { existsSync as existsSync14, readFileSync as readFileSync5, readdirSync as readdirSync3, statSync as statSync2, writeFileSync as writeFileSync4, mkdirSync as mkdirSync11, unlinkSync } from "fs";
|
|
@@ -21592,6 +21730,7 @@ function sessionFromRow(row) {
|
|
|
21592
21730
|
export {
|
|
21593
21731
|
writeScenarioMeta,
|
|
21594
21732
|
writeRunMeta,
|
|
21733
|
+
validateModelCredential,
|
|
21595
21734
|
uuid,
|
|
21596
21735
|
updateTestingWorkflow,
|
|
21597
21736
|
updateSchedule,
|
|
@@ -21625,6 +21764,8 @@ export {
|
|
|
21625
21764
|
resolveQuickQaSelection,
|
|
21626
21765
|
resolvePullRequestNumber,
|
|
21627
21766
|
resolvePartialId,
|
|
21767
|
+
resolveModelCredentialReference,
|
|
21768
|
+
resolveModelCredential,
|
|
21628
21769
|
resolveModel as resolveModelConfig,
|
|
21629
21770
|
resolveModel2 as resolveModel,
|
|
21630
21771
|
resolveCredential,
|
|
@@ -21755,6 +21896,7 @@ export {
|
|
|
21755
21896
|
closeDatabase,
|
|
21756
21897
|
closeBrowser,
|
|
21757
21898
|
clearDiscoveryCache,
|
|
21899
|
+
checkModelCredential,
|
|
21758
21900
|
checkBudget,
|
|
21759
21901
|
buildWorkflowRunPlan,
|
|
21760
21902
|
buildQuickQaResult,
|
|
@@ -21770,6 +21912,7 @@ export {
|
|
|
21770
21912
|
RunNotFoundError,
|
|
21771
21913
|
ResultNotFoundError,
|
|
21772
21914
|
ProjectNotFoundError,
|
|
21915
|
+
MODEL_PROVIDER_ENV_KEYS,
|
|
21773
21916
|
MODEL_MAP,
|
|
21774
21917
|
FlowNotFoundError,
|
|
21775
21918
|
DependencyCycleError,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type AIProvider } from "./ai-client.js";
|
|
2
|
+
export declare const MODEL_PROVIDER_ENV_KEYS: Record<AIProvider, string>;
|
|
3
|
+
export interface ModelCredentialValidationInput {
|
|
4
|
+
provider: AIProvider;
|
|
5
|
+
model: string;
|
|
6
|
+
apiKey: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ModelCredentialValidationResult {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
status?: number;
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ModelCredentialResolution {
|
|
14
|
+
provider: AIProvider;
|
|
15
|
+
model: string;
|
|
16
|
+
envKey: string;
|
|
17
|
+
reference: string;
|
|
18
|
+
source: "env" | "optional-env" | "secret" | "literal";
|
|
19
|
+
apiKey: string | null;
|
|
20
|
+
}
|
|
21
|
+
export interface ModelCredentialCheck {
|
|
22
|
+
provider: AIProvider;
|
|
23
|
+
model: string;
|
|
24
|
+
envKey: string;
|
|
25
|
+
reference: string;
|
|
26
|
+
source: ModelCredentialResolution["source"];
|
|
27
|
+
ok: boolean;
|
|
28
|
+
status?: number;
|
|
29
|
+
message?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function resolveModelCredentialReference(reference: string, env?: Record<string, string | undefined>, credentialResolver?: (value: string) => string | null): Pick<ModelCredentialResolution, "source" | "apiKey">;
|
|
32
|
+
export declare function resolveModelCredential(modelOrPreset?: string, options?: {
|
|
33
|
+
reference?: string;
|
|
34
|
+
env?: Record<string, string | undefined>;
|
|
35
|
+
credentialResolver?: (value: string) => string | null;
|
|
36
|
+
}): ModelCredentialResolution;
|
|
37
|
+
export declare function validateModelCredential(input: ModelCredentialValidationInput): Promise<ModelCredentialValidationResult>;
|
|
38
|
+
export declare function checkModelCredential(modelOrPreset?: string, options?: {
|
|
39
|
+
reference?: string;
|
|
40
|
+
env?: Record<string, string | undefined>;
|
|
41
|
+
credentialResolver?: (value: string) => string | null;
|
|
42
|
+
validator?: (input: ModelCredentialValidationInput) => Promise<ModelCredentialValidationResult>;
|
|
43
|
+
}): Promise<ModelCredentialCheck>;
|
|
44
|
+
//# sourceMappingURL=model-credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-credentials.d.ts","sourceRoot":"","sources":["../../src/lib/model-credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI/E,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAM9D,CAAC;AAEF,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,GAAG,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAC5C,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,kBAAkB,GAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAwB,GACvE,IAAI,CAAC,yBAAyB,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAatD;AAED,wBAAgB,sBAAsB,CACpC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAClD,GACL,yBAAyB,CAmB3B;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,+BAA+B,CAAC,CAwB1C;AAED,wBAAsB,oBAAoB,CACxC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACtD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,OAAO,CAAC,+BAA+B,CAAC,CAAC;CAC5F,GACL,OAAO,CAAC,oBAAoB,CAAC,CAgC/B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runTestingWorkflow, type WorkflowRunOptions, type WorkflowRunnerDependencies } from "./workflow-runner.js";
|
|
2
|
+
import { type ModelCredentialValidationInput, type ModelCredentialValidationResult } from "./model-credentials.js";
|
|
2
3
|
import type { TestingWorkflow } from "../types/index.js";
|
|
3
4
|
export interface WorkflowFanoutOptions extends WorkflowRunOptions {
|
|
4
5
|
workflowIds?: string[];
|
|
@@ -12,6 +13,7 @@ export interface WorkflowFanoutOptions extends WorkflowRunOptions {
|
|
|
12
13
|
batchStart?: number;
|
|
13
14
|
batchEnd?: number;
|
|
14
15
|
continueOnFailure?: boolean;
|
|
16
|
+
validateModelCredentials?: boolean;
|
|
15
17
|
}
|
|
16
18
|
export interface WorkflowFanoutItem {
|
|
17
19
|
workflowId: string;
|
|
@@ -53,6 +55,7 @@ export interface WorkflowFanoutDependencies extends WorkflowRunnerDependencies {
|
|
|
53
55
|
runTestingWorkflow?: typeof runTestingWorkflow;
|
|
54
56
|
preflight?: (workflows: TestingWorkflow[]) => WorkflowFanoutPreflightResult | Promise<WorkflowFanoutPreflightResult>;
|
|
55
57
|
providerApiKeyResolver?: (provider: string, env: Record<string, string | undefined>) => string | undefined | Promise<string | undefined>;
|
|
58
|
+
modelCredentialValidator?: (input: WorkflowFanoutModelCredentialValidationInput) => Promise<WorkflowFanoutModelCredentialValidationResult>;
|
|
56
59
|
commandExists?: (command: string) => boolean;
|
|
57
60
|
credentialResolver?: (value: string) => string | null;
|
|
58
61
|
env?: Record<string, string | undefined>;
|
|
@@ -79,10 +82,15 @@ export interface WorkflowFanoutSelection {
|
|
|
79
82
|
}
|
|
80
83
|
interface WorkflowFanoutPreflightDependencies {
|
|
81
84
|
providerApiKeyResolver?: WorkflowFanoutDependencies["providerApiKeyResolver"];
|
|
85
|
+
model?: string;
|
|
86
|
+
validateModelCredentials?: boolean;
|
|
87
|
+
modelCredentialValidator?: WorkflowFanoutDependencies["modelCredentialValidator"];
|
|
82
88
|
commandExists?: WorkflowFanoutDependencies["commandExists"];
|
|
83
89
|
credentialResolver?: WorkflowFanoutDependencies["credentialResolver"];
|
|
84
90
|
env?: Record<string, string | undefined>;
|
|
85
91
|
}
|
|
92
|
+
export type WorkflowFanoutModelCredentialValidationInput = ModelCredentialValidationInput;
|
|
93
|
+
export type WorkflowFanoutModelCredentialValidationResult = ModelCredentialValidationResult;
|
|
86
94
|
export declare function normalizeFanoutWorkerCount(value: number | undefined): number;
|
|
87
95
|
export declare function resolveWorkflowFanoutBatch(workflows: TestingWorkflow[], options?: Pick<WorkflowFanoutOptions, "batchSize" | "batch" | "offset">): {
|
|
88
96
|
workflows: TestingWorkflow[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-fanout.d.ts","sourceRoot":"","sources":["../../src/lib/workflow-fanout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-fanout.d.ts","sourceRoot":"","sources":["../../src/lib/workflow-fanout.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.64",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
package/dist/server/index.js
CHANGED
|
@@ -47091,7 +47091,7 @@ import { join as join14 } from "path";
|
|
|
47091
47091
|
// package.json
|
|
47092
47092
|
var package_default = {
|
|
47093
47093
|
name: "@hasna/testers",
|
|
47094
|
-
version: "0.0.
|
|
47094
|
+
version: "0.0.64",
|
|
47095
47095
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
47096
47096
|
type: "module",
|
|
47097
47097
|
main: "dist/index.js",
|