@hasna/testers 0.0.63 → 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 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();
@@ -60875,7 +61018,7 @@ async function checkWorkflowFanoutReadiness(workflows, dependencies = {}) {
60875
61018
  }
60876
61019
  });
60877
61020
  if (dependencies.validateModelCredentials && modelCredentialResolution.available.length > 0) {
60878
- const validator = dependencies.modelCredentialValidator ?? defaultModelCredentialValidator;
61021
+ const validator = dependencies.modelCredentialValidator ?? validateModelCredential;
60879
61022
  const sample = modelCredentialResolution.available[0];
60880
61023
  const validation = await validator({ provider: modelProvider, model, apiKey: sample.apiKey });
60881
61024
  checks.push({
@@ -61116,7 +61259,7 @@ function collectModelCredentialReadiness(workflows, provider, envKey, env, crede
61116
61259
  missing.push({ workflowId: workflow.id, workflowName: workflow.name, provider, key: envKey });
61117
61260
  continue;
61118
61261
  }
61119
- const resolved = reference.startsWith("$?") ? resolveOptionalSandboxEnvReference(reference, env) : isResolvableEnvReference(reference) ? resolveSandboxEnvReference(reference, env, credentialResolver) : reference;
61262
+ const resolved = resolveModelCredentialReference(reference, env, credentialResolver ?? resolveCredential).apiKey;
61120
61263
  if (!resolved) {
61121
61264
  missing.push({ workflowId: workflow.id, workflowName: workflow.name, provider, key: envKey, reference });
61122
61265
  continue;
@@ -61125,10 +61268,6 @@ function collectModelCredentialReadiness(workflows, provider, envKey, env, crede
61125
61268
  }
61126
61269
  return { missing, available };
61127
61270
  }
61128
- function resolveOptionalSandboxEnvReference(value, env) {
61129
- const varName = value.slice(2).trim();
61130
- return varName ? env[varName] ?? null : null;
61131
- }
61132
61271
  function isResolvableEnvReference(value) {
61133
61272
  return value.startsWith("$") || value.startsWith("@secrets:");
61134
61273
  }
@@ -61139,99 +61278,23 @@ function resolveSandboxEnvReference(value, env, credentialResolver) {
61139
61278
  }
61140
61279
  return (credentialResolver ?? resolveCredential)(value);
61141
61280
  }
61142
- async function defaultModelCredentialValidator(input) {
61143
- const endpoint = getModelCredentialValidationEndpoint(input.provider);
61144
- if (!endpoint) {
61145
- return { ok: true, message: `No live validation endpoint configured for provider ${input.provider}` };
61146
- }
61147
- try {
61148
- const response = await fetch(endpoint.url, {
61149
- headers: endpoint.headers(input.apiKey)
61150
- });
61151
- if (response.ok)
61152
- return { ok: true, status: response.status };
61153
- const text = await response.text().catch(() => "");
61154
- return {
61155
- ok: false,
61156
- status: response.status,
61157
- message: summarizeModelCredentialValidationError(text) ?? response.statusText
61158
- };
61159
- } catch (error) {
61160
- return {
61161
- ok: false,
61162
- message: error instanceof Error ? error.message : String(error)
61163
- };
61164
- }
61165
- }
61166
- function getModelCredentialValidationEndpoint(provider) {
61167
- if (provider === "anthropic") {
61168
- return {
61169
- url: "https://api.anthropic.com/v1/models",
61170
- headers: (apiKey) => ({
61171
- "x-api-key": apiKey,
61172
- "anthropic-version": "2023-06-01"
61173
- })
61174
- };
61175
- }
61176
- if (provider === "openai") {
61177
- return {
61178
- url: "https://api.openai.com/v1/models",
61179
- headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
61180
- };
61181
- }
61182
- if (provider === "cerebras") {
61183
- return {
61184
- url: "https://api.cerebras.ai/v1/models",
61185
- headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
61186
- };
61187
- }
61188
- if (provider === "zai") {
61189
- return {
61190
- url: "https://api.z.ai/api/paas/v4/models",
61191
- headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
61192
- };
61193
- }
61194
- if (provider === "google") {
61195
- return {
61196
- url: "https://generativelanguage.googleapis.com/v1beta/openai/models",
61197
- headers: (apiKey) => ({ Authorization: `Bearer ${apiKey}` })
61198
- };
61199
- }
61200
- return null;
61201
- }
61202
- function summarizeModelCredentialValidationError(text) {
61203
- if (!text.trim())
61204
- return;
61205
- try {
61206
- const parsed = JSON.parse(text);
61207
- return parsed.error?.type ?? parsed.error?.code ?? parsed.error?.message ?? parsed.message;
61208
- } catch {
61209
- return text.trim().slice(0, 200);
61210
- }
61211
- }
61212
61281
  function summarizePreflightFailures(preflight) {
61213
61282
  const requiredFailures = preflight.checks.filter((check) => !check.ok && check.required);
61214
61283
  return requiredFailures.length > 0 ? requiredFailures.map((check) => check.message).join("; ") : "required checks did not pass";
61215
61284
  }
61216
- var PROVIDER_ENV_KEYS, MODEL_PROVIDER_ENV_KEYS;
61285
+ var PROVIDER_ENV_KEYS;
61217
61286
  var init_workflow_fanout = __esm(() => {
61218
61287
  init_workflows();
61219
61288
  init_workflow_runner();
61220
61289
  init_secrets_resolver();
61221
61290
  init_ai_client();
61222
61291
  init_config2();
61292
+ init_model_credentials();
61223
61293
  PROVIDER_ENV_KEYS = {
61224
61294
  e2b: "E2B_API_KEY",
61225
61295
  daytona: "DAYTONA_API_KEY",
61226
61296
  modal: "MODAL_TOKEN_ID"
61227
61297
  };
61228
- MODEL_PROVIDER_ENV_KEYS = {
61229
- anthropic: "ANTHROPIC_API_KEY",
61230
- openai: "OPENAI_API_KEY",
61231
- google: "GOOGLE_API_KEY",
61232
- cerebras: "CEREBRAS_API_KEY",
61233
- zai: "ZAI_API_KEY"
61234
- };
61235
61298
  });
61236
61299
 
61237
61300
  // node_modules/@ai-sdk/provider/dist/index.mjs
@@ -95891,7 +95954,7 @@ import chalk6 from "chalk";
95891
95954
  // package.json
95892
95955
  var package_default = {
95893
95956
  name: "@hasna/testers",
95894
- version: "0.0.63",
95957
+ version: "0.0.64",
95895
95958
  description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
95896
95959
  type: "module",
95897
95960
  main: "dist/index.js",
@@ -97653,6 +97716,7 @@ function redactPersonas(personas) {
97653
97716
  }
97654
97717
 
97655
97718
  // src/cli/index.tsx
97719
+ init_model_credentials();
97656
97720
  init_projects();
97657
97721
  init_personas();
97658
97722
  init_api_checks();
@@ -98768,6 +98832,64 @@ function splitCsvOption(value) {
98768
98832
  const items = value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
98769
98833
  return items.length > 0 ? items : undefined;
98770
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
+ }
98771
98893
  function describeStoredAssertion(value) {
98772
98894
  if (typeof value === "string")
98773
98895
  return value;
@@ -101466,6 +101588,59 @@ envCmd.command("list").description("List all environments").option("--project <i
101466
101588
  process.exit(1);
101467
101589
  }
101468
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
+ });
101469
101644
  envCmd.command("use <name>").description("Set an environment as the default").action((name21) => {
101470
101645
  try {
101471
101646
  setDefaultEnvironment(name21);
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";
@@ -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":"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"}
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,5 +1,5 @@
1
1
  import { runTestingWorkflow, type WorkflowRunOptions, type WorkflowRunnerDependencies } from "./workflow-runner.js";
2
- import { type AIProvider } from "./ai-client.js";
2
+ import { type ModelCredentialValidationInput, type ModelCredentialValidationResult } from "./model-credentials.js";
3
3
  import type { TestingWorkflow } from "../types/index.js";
4
4
  export interface WorkflowFanoutOptions extends WorkflowRunOptions {
5
5
  workflowIds?: string[];
@@ -89,16 +89,8 @@ interface WorkflowFanoutPreflightDependencies {
89
89
  credentialResolver?: WorkflowFanoutDependencies["credentialResolver"];
90
90
  env?: Record<string, string | undefined>;
91
91
  }
92
- export interface WorkflowFanoutModelCredentialValidationInput {
93
- provider: AIProvider;
94
- model: string;
95
- apiKey: string;
96
- }
97
- export interface WorkflowFanoutModelCredentialValidationResult {
98
- ok: boolean;
99
- status?: number;
100
- message?: string;
101
- }
92
+ export type WorkflowFanoutModelCredentialValidationInput = ModelCredentialValidationInput;
93
+ export type WorkflowFanoutModelCredentialValidationResult = ModelCredentialValidationResult;
102
94
  export declare function normalizeFanoutWorkerCount(value: number | undefined): number;
103
95
  export declare function resolveWorkflowFanoutBatch(workflows: TestingWorkflow[], options?: Pick<WorkflowFanoutOptions, "batchSize" | "batch" | "offset">): {
104
96
  workflows: TestingWorkflow[];
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-fanout.d.ts","sourceRoot":"","sources":["../../src/lib/workflow-fanout.ts"],"names":[],"mappings":"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"}
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.63",
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",
@@ -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.63",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/testers",
3
- "version": "0.0.63",
3
+ "version": "0.0.64",
4
4
  "description": "AI-powered QA testing CLI — spawns cheap AI agents to test web apps with headless browsers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",