openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
773 lines (772 loc) • 29.9 kB
JavaScript
import { h as normalizeUniqueStringEntries } from "./string-normalization-DsCfAx8q.js";
import { t as createLazyImportLoader } from "./lazy-promise-DGqyc4Y4.js";
import { t as formatCliCommand } from "./command-format-C7YfyMTd.js";
import { m as resolveAgentWorkspaceDir, u as resolveAgentDir, y as resolveDefaultAgentId } from "./agent-scope-config-DcbEhP0R.js";
import { n as resolveDefaultAgentWorkspaceDir } from "./workspace-default-DPT1Dhad.js";
import { h as normalizeSecretInputString, l as hasConfiguredSecretInput, v as resolveSecretInputRef } from "./types.secrets-kC0nOetj.js";
import { i as resolveMergedModelProviderEntry } from "./model-provider-config-DX4Bzd5F.js";
import { c as normalizeProviderId } from "./model-ref-shared-Dz7QU0Lx.js";
import { o as resolveSessionStorePathCore } from "./paths-CXdaYWF_.js";
import { n as copyConfigResolutionFacts, r as copyConfigResolutionFactsExcept, u as resolveConfigSecretRef } from "./resolution-facts-Dks1tbik.js";
import { r as DEFAULT_PROVIDER } from "./defaults-CdX9UGcX.js";
import "./agent-scope-DbtJyKUL.js";
import { n as parseModelRef, t as findNormalizedProviderValue } from "./model-selection-normalize-D1HuPOqZ.js";
import { n as resolveProviderIdForAuth } from "./provider-auth-aliases-DhA9c2am.js";
import { t as resolveSecretRefString } from "./resolve-224YoYfx.js";
import { s as disposeOpenClawAgentDatabaseByPath } from "./openclaw-agent-db-CWtDoRbC.js";
import { h as resolveAuthProfileDatabasePath } from "./sqlite-MN_7y26V.js";
import { n as clearRuntimeAuthProfileStoreSnapshot, r as ensureAuthProfileStore } from "./store-F1B2duCT.js";
import { d as upsertAuthProfileWithLock } from "./profiles-DOTqXcYA.js";
import { n as listProfilesForProvider } from "./profile-list-DyfWX-d2.js";
import { i as resolveAuthProfileEligibility, o as resolveAuthProfileOrderWithMetadata } from "./order-CC2RBzI5.js";
import { c as isNonSecretApiKeyMarker } from "./model-auth-markers-jBKQn38x.js";
import { t as resolveEnvApiKey } from "./model-auth-env-Dq9W4xg9.js";
import "./workspace-ConDEamr.js";
import { i as externalCliDiscoveryScoped } from "./external-cli-discovery-CbeZXk1q.js";
import { S as resolveUsableCustomProviderApiKey, a as hasSyntheticLocalProviderAuthConfig, b as resolveProviderEntryApiKeyProfileReference, o as hasUsableCustomProviderApiKey, y as resolveProviderEntryApiKeyBinding } from "./model-auth-provider-config-C_kr_q2g.js";
import { a as loadPreparedModelCatalog } from "./prepared-model-catalog-Bt4dYhnY.js";
import { t as resolveAuthProfileDisplayLabel } from "./auth-profiles-BdUEhE7u.js";
import "./model-auth-C48_DZ-I.js";
import "./model-selection-di2kjKCB.js";
import { o as prepareSystemAgentRunAdmission } from "./admitted-run-context-CHY5SdVF.js";
import { i as describeFailoverError } from "./failover-error-BkNxlp8A.js";
import { n as prepareInternalSessionEffectsSession, r as removeInternalSessionEffectsSession } from "./internal-session-effects-DEul8D8G.js";
import { r as extractAgentRunTerminalError, t as agentRunHasVisibleReply } from "./agent-run-result-JlQhspoW.js";
import { n as formatMs } from "./shared-CZFRGTsE.js";
import { i as redactStatusSecrets } from "./format-q3Hb37m-.js";
import path from "node:path";
import fs from "node:fs/promises";
import os from "node:os";
import crypto from "node:crypto";
import pMap from "p-map";
//#region src/commands/models/list.probe.models.ts
/** Groups configured model candidates by their requested provider identity. */
function buildProbeCandidateMap(modelCandidates) {
const map = /* @__PURE__ */ new Map();
for (const raw of modelCandidates) {
const parsed = parseModelRef(raw ?? "", DEFAULT_PROVIDER);
if (!parsed) continue;
const list = map.get(parsed.provider) ?? [];
if (!list.includes(parsed.model)) list.push(parsed.model);
map.set(parsed.provider, list);
}
return map;
}
function probePriority(provider, modelId) {
const id = modelId.trim().toLowerCase();
if (provider !== "anthropic") return 50;
if (/^claude-haiku-4-5-\d{8}$/.test(id)) return 0;
if (id === "claude-haiku-4-5") return 1;
if (id === "claude-sonnet-5" || id.startsWith("claude-sonnet-5-")) return 2;
if (id === "claude-sonnet-4-6" || id.startsWith("claude-sonnet-4-6-")) return 3;
if (id.startsWith("claude-sonnet-4-")) return 4;
if (id.startsWith("claude-3-")) return 100;
return 50;
}
/** Selects a requested-provider candidate before falling back to its catalog rows. */
function selectProbeModel(params) {
const { provider, candidates, catalog } = params;
const direct = candidates.get(provider)?.[0];
if (direct) return {
provider,
model: direct
};
const fromCatalog = catalog.filter((entry) => normalizeProviderId(entry.provider) === provider && entry.status !== "deprecated" && entry.status !== "disabled").toSorted((a, b) => probePriority(provider, a.id) - probePriority(provider, b.id))[0];
return fromCatalog ? {
provider,
model: fromCatalog.id
} : null;
}
//#endregion
//#region src/commands/models/list.probe.ts
/** Auth probe planning and execution helpers for model diagnostics. */
const PROBE_PROMPT = "Reply with OK. Do not use tools.";
/** Scrubs credential-shaped text before probe failures cross a UI or CLI boundary. */
function redactAuthProbeError(error) {
return redactStatusSecrets(error);
}
const embeddedRunnerModuleLoader = createLazyImportLoader(() => import("./embedded-agent-CUhbhIMN.js"));
function loadEmbeddedRunnerModule() {
return embeddedRunnerModuleLoader.load();
}
const PROBE_STATUS_BY_FAILOVER_REASON = {
auth: "auth",
auth_permanent: "auth",
format: "format",
rate_limit: "rate_limit",
overloaded: "rate_limit",
billing: "billing",
server_error: "unknown",
timeout: "timeout",
tls_certificate: "unknown",
context_overflow: "unknown",
model_not_found: "format",
session_expired: "unknown",
empty_response: "unknown",
no_error_details: "unknown",
unclassified: "unknown",
unknown: "unknown"
};
/** Maps runtime failover reasons into stable auth probe status buckets. */
function mapFailoverReasonToProbeStatus(reason) {
return reason ? PROBE_STATUS_BY_FAILOVER_REASON[reason] ?? "unknown" : "unknown";
}
function mapEligibilityReasonToProbeReasonCode(reasonCode) {
if (reasonCode === "missing_credential") return "missing_credential";
if (reasonCode === "expired") return "expired";
if (reasonCode === "invalid_expires") return "invalid_expires";
if (reasonCode === "unresolved_ref") return "unresolved_ref";
return "ineligible_profile";
}
function formatMissingCredentialProbeError(reasonCode) {
const legacyLine = "Auth profile credentials are missing or expired.";
if (reasonCode === "expired") return `${legacyLine}\n↳ Auth reason [expired]: token credentials are expired.`;
if (reasonCode === "invalid_expires") return `${legacyLine}\n↳ Auth reason [invalid_expires]: token expires must be a positive Unix ms timestamp.`;
if (reasonCode === "missing_credential") return `${legacyLine}\n↳ Auth reason [missing_credential]: no inline credential or SecretRef is configured.`;
if (reasonCode === "unresolved_ref") return `${legacyLine}\n↳ Auth reason [unresolved_ref]: configured SecretRef could not be resolved.`;
return `${legacyLine}\n↳ Auth reason [ineligible_profile]: profile is incompatible with provider config.`;
}
function resolveProbeSecretRef(profile, cfg) {
const defaults = cfg.secrets?.defaults;
if (profile.type === "api_key") return resolveSecretInputRef({
value: profile.key,
refValue: profile.keyRef,
defaults
}).ref;
if (profile.type === "token") return resolveSecretInputRef({
value: profile.token,
refValue: profile.tokenRef,
defaults
}).ref;
return null;
}
function formatUnresolvedRefProbeError(refLabel) {
return `Auth profile credentials are missing or expired.\n↳ Auth reason [unresolved_ref]: could not resolve SecretRef "${refLabel}".`;
}
function withDirectCredential(cfg, provider, value, mode) {
const providers = cfg.models?.providers ?? {};
const configuredEntry = resolveMergedModelProviderEntry(cfg, provider);
const configKey = configuredEntry?.providerKey ?? provider;
const configured = configuredEntry?.providerConfig;
if (!configured) return withoutProfileFallback(cfg, provider);
const auth = mode === "oauth" || mode === "token" ? mode : "api-key";
const next = {
...cfg,
models: {
...cfg.models,
providers: {
...providers,
[configKey]: {
...configured,
apiKey: value,
auth
}
}
},
auth: {
...cfg.auth,
order: {
...cfg.auth?.order,
[provider]: []
}
}
};
copyConfigResolutionFactsExcept(cfg, next, [`models.providers.${configKey}.apiKey`]);
return next;
}
function withoutProfileFallback(cfg, provider) {
const next = {
...cfg,
auth: {
...cfg.auth,
order: {
...cfg.auth?.order,
[provider]: []
}
}
};
copyConfigResolutionFacts(cfg, next);
return next;
}
async function resolveConfiguredProbeCredential(params) {
const ref = resolveConfigSecretRef({
config: params.cfg,
path: params.path,
value: params.input,
defaults: params.cfg.secrets?.defaults
});
if (!ref) return normalizeSecretInputString(params.input) ?? null;
try {
return await resolveSecretRefString(ref, {
config: params.cfg,
env: process.env,
cache: params.cache
});
} catch {
return null;
}
}
async function maybeResolveUnresolvedRefIssue(params) {
if (!params.profile) return null;
const ref = resolveProbeSecretRef(params.profile, params.cfg);
if (!ref) return null;
try {
await resolveSecretRefString(ref, {
config: params.cfg,
env: process.env,
cache: params.cache
});
return null;
} catch {
return {
reasonCode: "unresolved_ref",
error: formatUnresolvedRefProbeError(`${ref.source}:${ref.provider}:${ref.id}`)
};
}
}
/** Builds probe targets plus preflight failures for missing/invalid credentials. */
async function buildProbeTargets(params) {
const { cfg, agentDir, providers, modelCandidates, options, workspaceDir } = params;
const authAliasLookupParams = {
config: cfg,
workspaceDir
};
const store = ensureAuthProfileStore(agentDir, { externalCli: externalCliDiscoveryScoped({
config: cfg,
allowKeychainPrompt: false,
providerIds: providers.map((provider) => resolveProviderIdForAuth(provider, authAliasLookupParams)),
profileIds: options.profileIds
}) });
const providerFilter = options.provider?.trim();
const providerFilterKey = providerFilter ? normalizeProviderId(providerFilter) : null;
const profileFilter = new Set(normalizeUniqueStringEntries(options.profileIds));
const refResolveCache = {};
const catalog = await loadPreparedModelCatalog({
config: cfg,
...params.agentId ? { agentId: params.agentId } : {},
...agentDir ? { agentDir } : {},
...workspaceDir ? { workspaceDir } : {},
readOnly: true,
providerDiscoveryProviderIds: providers
});
const candidates = buildProbeCandidateMap(modelCandidates);
const targets = [];
const results = [];
for (const provider of providers) {
const providerKey = normalizeProviderId(provider);
const authProviderKey = resolveProviderIdForAuth(providerKey, authAliasLookupParams);
if (providerFilterKey && providerKey !== providerFilterKey) continue;
const model = selectProbeModel({
provider: providerKey,
candidates,
catalog
});
const configuredProviderEntry = resolveMergedModelProviderEntry(cfg, providerKey);
const configuredProvider = configuredProviderEntry?.providerConfig;
const hasConfiguredProviderSecretRef = Boolean(configuredProviderEntry && resolveConfigSecretRef({
config: cfg,
path: `models.providers.${configuredProviderEntry.providerKey}.apiKey`,
value: configuredProvider?.apiKey,
defaults: cfg.secrets?.defaults
}));
const includeDirectKeys = options.includeDirectKeys === true && profileFilter.size === 0;
const includeConfigKey = includeDirectKeys && profileFilter.size === 0 && hasConfiguredSecretInput(configuredProvider?.apiKey, cfg.secrets?.defaults);
const profileIds = [.../* @__PURE__ */ new Set([...listProfilesForProvider(store, authProviderKey), ...authProviderKey === providerKey ? [] : listProfilesForProvider(store, providerKey)])];
const configuredReference = includeConfigKey ? resolveProviderEntryApiKeyProfileReference({
cfg,
provider: providerKey,
store
}) : { kind: "none" };
const configuredBinding = configuredReference.kind === "profile" && !profileIds.includes(configuredReference.profileId) ? await resolveProviderEntryApiKeyBinding({
cfg,
provider: providerKey,
store,
agentDir
}) : null;
const configuredValue = configuredProviderEntry && includeConfigKey && configuredReference.kind !== "profile" && configuredReference.kind !== "profile-incompatible" ? configuredReference.kind === "marker" ? resolveUsableCustomProviderApiKey({
cfg,
provider: providerKey,
env: process.env
})?.apiKey ?? null : await resolveConfiguredProbeCredential({
cfg,
input: configuredProvider?.apiKey,
path: `models.providers.${configuredProviderEntry.providerKey}.apiKey`,
cache: refResolveCache
}) : null;
const configuredMode = configuredProvider?.auth === "oauth" || configuredProvider?.auth === "token" ? configuredProvider.auth : "api_key";
const resolvedEnvironmentValue = includeDirectKeys && !hasConfiguredProviderSecretRef ? resolveEnvApiKey(authProviderKey, process.env, {
config: cfg,
workspaceDir
}) : null;
const environmentValue = resolvedEnvironmentValue?.apiKey === configuredValue ? null : resolvedEnvironmentValue;
const configuredTargetLabel = configuredReference.kind === "marker" && configuredValue && isNonSecretApiKeyMarker(configuredValue, { includeEnvVarName: false }) ? "provider" : "config";
const appendDirectTargets = () => {
if (includeConfigKey) {
if (configuredReference.kind === "profile-incompatible") results.push({
provider: providerKey,
model: model ? `${model.provider}/${model.model}` : void 0,
profileId: configuredReference.profileId,
label: "config",
source: "models.json",
mode: configuredMode,
status: "unknown",
reasonCode: "ineligible_profile",
error: "Configured API key references an incompatible auth profile."
});
else if (configuredReference.kind === "profile") {
if (!profileIds.includes(configuredReference.profileId)) {
if (configuredBinding?.kind === "profile-resolved" && model) targets.push({
provider: providerKey,
model,
profileId: configuredBinding.auth.profileId,
label: "config",
source: "models.json",
mode: configuredBinding.auth.mode,
boundValue: configuredBinding.auth.apiKey
});
else results.push({
provider: providerKey,
model: model ? `${model.provider}/${model.model}` : void 0,
profileId: configuredReference.profileId,
label: "config",
source: "models.json",
mode: configuredMode,
status: model ? "unknown" : "no_model",
reasonCode: model ? "unresolved_ref" : "no_model",
error: model ? "Configured auth profile could not be resolved." : "No model available for probe"
});
}
} else if (!configuredValue) results.push({
provider: providerKey,
model: model ? `${model.provider}/${model.model}` : void 0,
label: "config",
source: "models.json",
mode: configuredMode,
status: model ? "unknown" : "no_model",
reasonCode: model ? "unresolved_ref" : "no_model",
error: model ? "Configured API key could not be resolved." : "No model available for probe"
});
else if (model) targets.push({
provider: providerKey,
model,
label: configuredTargetLabel,
source: "models.json",
mode: configuredMode,
boundValue: configuredValue,
...configuredReference.kind === "marker" ? { useRuntimeAuth: true } : {}
});
else results.push({
provider: providerKey,
model: void 0,
label: configuredTargetLabel,
source: "models.json",
mode: configuredMode,
status: "no_model",
reasonCode: "no_model",
error: "No model available for probe"
});
}
if (environmentValue) {
const mode = configuredProvider?.auth === "oauth" || configuredProvider?.auth === "token" ? configuredProvider.auth : environmentValue.source.includes("OAUTH_TOKEN") ? "oauth" : "api_key";
if (model) targets.push({
provider: providerKey,
model,
label: environmentValue.source,
source: "env",
mode,
boundValue: environmentValue.apiKey
});
else results.push({
provider: providerKey,
model: void 0,
label: environmentValue.source,
source: "env",
mode,
status: "no_model",
reasonCode: "no_model",
error: "No model available for probe"
});
}
};
const explicitOrder = findNormalizedProviderValue(store.order, authProviderKey) ?? findNormalizedProviderValue(store.order, providerKey) ?? findNormalizedProviderValue(cfg?.auth?.order, authProviderKey) ?? findNormalizedProviderValue(cfg?.auth?.order, providerKey);
const orderResolution = resolveAuthProfileOrderWithMetadata({
cfg,
store,
provider: providerKey,
forModel: model?.model
});
const allowedProfiles = orderResolution.hasExplicitOrder ? new Set(orderResolution.profileIds) : null;
const filteredProfiles = profileFilter.size ? profileIds.filter((id) => profileFilter.has(id)) : profileIds;
if (filteredProfiles.length > 0) {
for (const profileId of filteredProfiles) {
const profile = store.profiles[profileId];
const mode = profile?.type;
const label = resolveAuthProfileDisplayLabel({
cfg,
store,
profileId
});
const isConfigBoundProfile = includeConfigKey && configuredReference.kind === "profile" && profileId === configuredReference.profileId;
if (!isConfigBoundProfile && explicitOrder && !explicitOrder.includes(profileId)) {
results.push({
provider: providerKey,
profileId,
model: model ? `${model.provider}/${model.model}` : void 0,
label,
source: "profile",
mode,
status: "unknown",
reasonCode: "excluded_by_auth_order",
error: "Excluded by auth.order for this provider."
});
continue;
}
if (!isConfigBoundProfile && allowedProfiles && !allowedProfiles.has(profileId)) {
const reasonCode = mapEligibilityReasonToProbeReasonCode(resolveAuthProfileEligibility({
cfg,
store,
provider: providerKey,
profileId
}).reasonCode);
results.push({
provider: providerKey,
model: model ? `${model.provider}/${model.model}` : void 0,
profileId,
label,
source: "profile",
mode,
status: "unknown",
reasonCode,
error: formatMissingCredentialProbeError(reasonCode)
});
continue;
}
const unresolvedRefIssue = await maybeResolveUnresolvedRefIssue({
cfg,
profile,
cache: refResolveCache
});
if (unresolvedRefIssue) {
results.push({
provider: providerKey,
model: model ? `${model.provider}/${model.model}` : void 0,
profileId,
label,
source: "profile",
mode,
status: "unknown",
reasonCode: unresolvedRefIssue.reasonCode,
error: unresolvedRefIssue.error
});
continue;
}
if (!model) {
results.push({
provider: providerKey,
model: void 0,
profileId,
label,
source: "profile",
mode,
status: "no_model",
reasonCode: "no_model",
error: "No model available for probe"
});
continue;
}
targets.push({
provider: providerKey,
model,
profileId,
label,
source: "profile",
mode
});
}
appendDirectTargets();
continue;
}
if (profileFilter.size > 0) continue;
appendDirectTargets();
if (includeConfigKey || environmentValue) continue;
const hasUsableModelsJsonKey = hasUsableCustomProviderApiKey(cfg, providerKey);
const hasSyntheticLocalAuth = hasSyntheticLocalProviderAuthConfig({
cfg,
provider: providerKey
});
if (orderResolution.hasExplicitOrder && !hasUsableModelsJsonKey && !hasSyntheticLocalAuth) continue;
const envKey = orderResolution.hasExplicitOrder || hasConfiguredProviderSecretRef ? null : resolveEnvApiKey(authProviderKey, process.env, {
config: cfg,
workspaceDir
});
if (!envKey && !hasUsableModelsJsonKey && !hasSyntheticLocalAuth) continue;
const label = envKey ? "env" : "models.json";
const source = envKey ? "env" : "models.json";
const mode = envKey?.source.includes("OAUTH_TOKEN") ? "oauth" : "api_key";
if (!model) {
results.push({
provider: providerKey,
model: void 0,
label,
source,
mode,
status: "no_model",
reasonCode: "no_model",
error: "No model available for probe"
});
continue;
}
targets.push({
provider: providerKey,
model,
label,
source,
mode,
...hasSyntheticLocalAuth && !envKey && !hasUsableModelsJsonKey ? { useRuntimeAuth: true } : {}
});
}
return {
targets,
results
};
}
async function probeTarget(params) {
const { cfg, agentId, agentDir, workspaceDir, storePath, target, timeoutMs, maxTokens } = params;
const probeConfig = target.useRuntimeAuth ? withoutProfileFallback(cfg, target.provider) : !target.boundValue ? cfg : withDirectCredential(cfg, target.provider, target.boundValue, target.mode);
if (!target.model) return {
provider: target.provider,
model: void 0,
profileId: target.profileId,
label: target.label,
source: target.source,
mode: target.mode,
status: "no_model",
reasonCode: "no_model",
error: "No model available for probe"
};
const model = target.model;
const runId = `probe-${target.provider}-${crypto.randomUUID()}`;
let isolatedAgentDir = null;
let isolatedProfileId;
let sessionTarget;
let preparedRunAdmission;
const start = Date.now();
const buildResult = (status, error) => ({
provider: target.provider,
model: `${model.provider}/${model.model}`,
profileId: target.profileId,
label: target.label,
source: target.source,
mode: target.mode,
status,
...error ? { error } : {},
latencyMs: Date.now() - start
});
try {
sessionTarget = await prepareInternalSessionEffectsSession({
agentId,
cwd: workspaceDir,
runId,
storePath
});
if (target.boundValue || target.useRuntimeAuth) isolatedAgentDir = await fs.realpath(await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-auth-probe-")));
if (target.boundValue && !target.useRuntimeAuth && isolatedAgentDir) {
isolatedProfileId = `${target.provider}:probe-${crypto.randomUUID()}`;
const value = target.boundValue;
const profile = target.mode === "oauth" ? {
type: "oauth",
provider: target.provider,
access: value,
refresh: "not-a-real",
expires: Date.now() + 36e5
} : target.mode === "token" ? {
type: "token",
provider: target.provider,
token: value
} : {
type: "api_key",
provider: target.provider,
key: value
};
if (!await upsertAuthProfileWithLock({
profileId: isolatedProfileId,
credential: profile,
agentDir: isolatedAgentDir
})) throw new Error("Could not prepare isolated auth probe profile");
}
const { runEmbeddedAgent } = await loadEmbeddedRunnerModule();
preparedRunAdmission = prepareSystemAgentRunAdmission(probeConfig, runId, agentId, "models.auth-probe");
const runResult = await runEmbeddedAgent({
preparedRunAdmission,
sessionId: sessionTarget.sessionId,
sessionKey: sessionTarget.sessionKey,
sessionTarget,
agentId,
workspaceDir,
agentDir: isolatedAgentDir ?? agentDir,
config: probeConfig,
prompt: PROBE_PROMPT,
provider: target.model.provider,
model: target.model.model,
modelFallbacksOverride: [],
authProfileId: isolatedProfileId ?? target.profileId,
authProfileIdSource: isolatedProfileId || target.profileId ? "user" : void 0,
timeoutMs,
runId,
lane: `auth-probe:${target.provider}:${target.profileId ?? target.source}`,
thinkLevel: "off",
reasoningLevel: "off",
verboseLevel: "off",
streamParams: { maxTokens },
agentHarnessRuntimeOverride: "openclaw",
disableTools: true,
modelRun: true,
cleanupBundleMcpOnRunEnd: true,
...isolatedAgentDir ? { preparedModelRuntimeMode: "isolated-read-only" } : {},
abortSignal: params.abortSignal
});
const terminalError = extractAgentRunTerminalError(runResult);
if (terminalError) {
const described = describeFailoverError(new Error(terminalError));
return buildResult(mapFailoverReasonToProbeStatus(described.reason), redactAuthProbeError(described.message));
}
if (!agentRunHasVisibleReply(runResult)) return buildResult("format", "The model did not return a visible probe response.");
return buildResult("ok");
} catch (err) {
const described = describeFailoverError(err);
return buildResult(mapFailoverReasonToProbeStatus(described.reason), redactAuthProbeError(described.message));
} finally {
preparedRunAdmission?.close();
await removeInternalSessionEffectsSession(sessionTarget);
if (isolatedAgentDir) {
clearRuntimeAuthProfileStoreSnapshot(isolatedAgentDir);
disposeOpenClawAgentDatabaseByPath(resolveAuthProfileDatabasePath(isolatedAgentDir));
await fs.rm(isolatedAgentDir, {
recursive: true,
force: true
});
}
}
}
async function runTargetsWithConcurrency(params) {
const { cfg, targets, timeoutMs, maxTokens, onProgress } = params;
const concurrency = Math.max(1, Math.min(targets.length || 1, params.concurrency));
const agentId = params.agentId ?? resolveDefaultAgentId(cfg);
const agentDir = params.agentDir ?? resolveAgentDir(cfg, agentId);
const workspaceDir = params.workspaceDir ?? resolveAgentWorkspaceDir(cfg, agentId) ?? resolveDefaultAgentWorkspaceDir();
const storePath = resolveSessionStorePathCore(cfg.session?.store, { agentId });
await fs.mkdir(workspaceDir, { recursive: true });
let completed = 0;
return await pMap(targets, async (target) => {
onProgress?.({
completed,
total: targets.length,
label: `Probing ${target.provider}${target.profileId ? ` (${target.label})` : ""}`
});
const result = await probeTarget({
cfg,
agentId,
agentDir,
workspaceDir,
storePath,
target,
timeoutMs,
maxTokens,
abortSignal: params.abortSignal
});
completed += 1;
onProgress?.({
completed,
total: targets.length
});
return result;
}, {
concurrency,
stopOnError: true,
...params.abortSignal ? { signal: params.abortSignal } : {}
});
}
function formatActiveGatewayModelsProbeRefusal(identity) {
return `A Gateway is running for this state directory (pid ${identity.pid}, port ${identity.port}). Stop the Gateway first (${formatCliCommand("openclaw gateway stop")}), then rerun models status --probe.`;
}
/** Own canonical state only for direct CLI probes; Gateway RPC probes already run under its lock. */
async function withAuthProbeStateOwnership(ownership, run) {
if (!ownership) return await run();
const { acquireEmbeddedStateLock, createEmbeddedStateSignalBridge } = await import("./embedded-state-lock-6tAlep1Z.js");
const signalBridge = createEmbeddedStateSignalBridge(ownership.process ?? process);
let stateLock;
try {
stateLock = await acquireEmbeddedStateLock({
options: ownership.gatewayLockOptions,
signal: signalBridge.signal,
formatActiveGatewayRefusal: formatActiveGatewayModelsProbeRefusal
});
return await run(signalBridge.signal);
} finally {
await stateLock?.release();
signalBridge.dispose();
}
}
/** Runs all auth probes with bounded concurrency and returns a summary. */
async function runAuthProbes(params) {
return await withAuthProbeStateOwnership(params.stateOwnership, async (abortSignal) => {
const startedAt = Date.now();
const plan = await buildProbeTargets({
cfg: params.cfg,
...params.agentId ? { agentId: params.agentId } : {},
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
providers: params.providers,
modelCandidates: params.modelCandidates,
options: params.options
});
const totalTargets = plan.targets.length;
params.onProgress?.({
completed: 0,
total: totalTargets
});
const results = totalTargets ? await runTargetsWithConcurrency({
cfg: params.cfg,
agentId: params.agentId,
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
targets: plan.targets,
timeoutMs: params.options.timeoutMs,
maxTokens: params.options.maxTokens,
concurrency: params.options.concurrency,
onProgress: params.onProgress,
abortSignal
}) : [];
const finishedAt = Date.now();
return {
startedAt,
finishedAt,
durationMs: finishedAt - startedAt,
totalTargets,
options: params.options,
results: [...plan.results, ...results]
};
});
}
/** Formats probe latency for table output. */
function formatProbeLatency(latencyMs) {
if (!latencyMs && latencyMs !== 0) return "-";
return formatMs(latencyMs);
}
/** Sorts probe results by provider and display label. */
function sortProbeResults(results) {
return results.slice().toSorted((a, b) => {
const provider = a.provider.localeCompare(b.provider);
if (provider !== 0) return provider;
const aLabel = a.label || a.profileId || "";
const bLabel = b.label || b.profileId || "";
return aLabel.localeCompare(bLabel);
});
}
/** Produces the terse completion line for auth probe output. */
function describeProbeSummary(summary) {
if (summary.totalTargets === 0) return "No probe targets.";
return `Probed ${summary.totalTargets} target${summary.totalTargets === 1 ? "" : "s"} in ${formatMs(summary.durationMs)}`;
}
//#endregion
export { redactAuthProbeError as a, withAuthProbeStateOwnership as c, mapFailoverReasonToProbeStatus as i, describeProbeSummary as n, runAuthProbes as o, formatProbeLatency as r, sortProbeResults as s, buildProbeTargets as t };