UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

175 lines (174 loc) 7.14 kB
import { c as isSecretRef } from "./types.secrets-_0JOMGE5.js"; import { i as normalizeProviderId } from "./provider-id-Dq06Bcx6.js"; import { o as resolveAgentEffectiveModelPrimary } from "./agent-scope-MrLta7Pq.js"; import { a as resolveAgentDir, c as resolveDefaultAgentId, o as resolveAgentWorkspaceDir } from "./agent-scope-config-CgCYpZfK.js"; import { n as resolveDefaultAgentWorkspaceDir } from "./workspace-default-B3AjhIK3.js"; import { r as DEFAULT_PROVIDER } from "./defaults-mDjiWzE5.js"; import { i as ensureAuthProfileStoreWithoutExternalProfiles } from "./store-C8spD0DG.js"; import "./auth-profiles-84rzaGag.js"; import { i as resolveAuthProfileOrder } from "./order-CdBVYd7c.js"; import "./model-auth-markers-Sq8HdQFX.js"; import { c as hasRuntimeAvailableProviderAuth } from "./model-auth-DVfmdW0b.js"; import "./workspace-B0bmoo98.js"; import { t as loadModelCatalogForBrowse } from "./model-catalog-browse-CKW2B8Bh.js"; import { n as resolveVisibleModelCatalog, t as isCodexRoutableOpenAIPlatformCatalogEntry } from "./model-catalog-visibility-BYLLfZkR.js"; //#region src/gateway/server-methods/models-list-result.ts let loggedSlowModelsListCatalog = false; const OAUTH_REFRESH_MARGIN_MS = 300 * 1e3; const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses"; function resolveModelsListView(params) { return typeof params.view === "string" ? params.view : "default"; } function omitRuntimeModelParams(entry) { const { params: _params, ...rest } = entry; return rest; } function modelCatalogEntryHasUnknownSecretRefAvailability(cfg, entry) { const providerId = normalizeProviderId(entry.provider); const apiKey = (Object.entries(cfg.models?.providers ?? {}).find(([id]) => normalizeProviderId(id) === providerId)?.[1])?.apiKey; return apiKey === "secretref-managed" || isSecretRef(apiKey) && apiKey.source !== "env"; } function createInFlightProviderAuthChecker(providerAuthChecker) { const pending = /* @__PURE__ */ new Map(); return (provider, modelApi) => { const key = `${normalizeProviderId(provider)}\0${modelApi ?? ""}`; const cached = pending.get(key); if (cached) return cached; const next = Promise.resolve(providerAuthChecker(provider, modelApi)); pending.set(key, next); return next; }; } function hasLiteralSecret(value) { return typeof value === "string" && value.trim().length > 0; } function hasAvailableEnvSecretRef(value) { return isSecretRef(value) && value.source === "env" && hasLiteralSecret(process.env[value.id]); } function hasSecretRef(value) { return isSecretRef(value); } function profileModeAllowedForModel(provider, modelApi, mode) { return normalizeProviderId(provider) !== "openai" || modelApi === void 0 || modelApi === "openai-chatgpt-responses" || mode === "api_key"; } function profileHasReadOnlyAvailableAuth(params) { if (!profileModeAllowedForModel(params.provider, params.modelApi, params.credential.type)) return false; if (params.credential.type === "api_key") { if (hasLiteralSecret(params.credential.key) || hasAvailableEnvSecretRef(params.credential.keyRef)) return true; return hasSecretRef(params.credential.keyRef) ? void 0 : false; } if (params.credential.type === "token") { if (hasLiteralSecret(params.credential.token) || hasAvailableEnvSecretRef(params.credential.tokenRef)) return params.credential.expires === void 0 || params.credential.expires > params.now; return hasSecretRef(params.credential.tokenRef) ? void 0 : false; } return hasLiteralSecret(params.credential.access) && params.credential.expires > params.now + OAUTH_REFRESH_MARGIN_MS; } function hasReadOnlyAvailableProfileAuth(params) { const now = Date.now(); let sawUnknown = false; for (const profileId of resolveAuthProfileOrder({ cfg: params.cfg, store: params.store, provider: params.provider })) { const credential = params.store.profiles[profileId]; if (!credential) continue; const available = profileHasReadOnlyAvailableAuth({ credential, provider: params.provider, modelApi: params.modelApi, now }); if (available === true) return true; if (available === void 0) sawUnknown = true; } return sawUnknown ? void 0 : false; } function createModelsListProviderAuthChecker(params) { const store = ensureAuthProfileStoreWithoutExternalProfiles(resolveAgentDir(params.cfg, params.agentId), { allowKeychainPrompt: false, readOnly: true, syncExternalCli: false }); return createInFlightProviderAuthChecker((provider, modelApi) => hasRuntimeAvailableProviderAuth({ provider, modelApi, cfg: params.cfg, workspaceDir: params.workspaceDir, allowPluginSyntheticAuth: false }) || hasReadOnlyAvailableProfileAuth({ provider, modelApi, cfg: params.cfg, store })); } async function resolveModelsListEntryAvailability(providerAuthChecker, entry) { const primary = await providerAuthChecker(entry.provider, entry.api); if (primary === true || !isCodexRoutableOpenAIPlatformCatalogEntry(entry)) return primary; return await providerAuthChecker(entry.provider, OPENAI_CODEX_RESPONSES_API) ?? primary; } async function buildPublicModelsListEntry(params) { const publicEntry = omitRuntimeModelParams(params.entry); if (modelCatalogEntryHasUnknownSecretRefAvailability(params.cfg, params.entry)) return { ...publicEntry, available: false }; if (!params.providerAuthChecker) return publicEntry; const available = await resolveModelsListEntryAvailability(params.providerAuthChecker, params.entry); return { ...publicEntry, available: available ?? false }; } async function buildPublicModelsListEntries(params) { const providerAuthChecker = createModelsListProviderAuthChecker(params); return await Promise.all(params.catalog.map((entry) => buildPublicModelsListEntry({ entry, cfg: params.cfg, providerAuthChecker }))); } async function buildModelsListResult(params) { const cfg = params.context.getRuntimeConfig(); const agentId = params.agentId ?? resolveDefaultAgentId(cfg); const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId) ?? resolveDefaultAgentWorkspaceDir(); const view = resolveModelsListView(params.params); const catalog = await loadModelCatalogForBrowse({ cfg, view, loadCatalog: async (loadParams) => { const readOnlyLoad = loadParams.readOnly ?? true; if (params.preloadedCatalog && readOnlyLoad) return params.preloadedCatalog; return await params.context.loadGatewayModelCatalog(loadParams); }, onTimeout: (timeoutMs) => { if (loggedSlowModelsListCatalog) return; loggedSlowModelsListCatalog = true; params.context.logGateway.debug(`models.list continuing without model catalog after ${timeoutMs}ms`); } }); if (view === "all") return { models: await buildPublicModelsListEntries({ catalog, cfg, agentId, workspaceDir }) }; return { models: await buildPublicModelsListEntries({ catalog: await resolveVisibleModelCatalog({ cfg, catalog, defaultProvider: DEFAULT_PROVIDER, defaultModel: resolveAgentEffectiveModelPrimary(cfg, agentId), agentId, workspaceDir, view, runtimeAuthDiscovery: false }), cfg, agentId, workspaceDir }) }; } //#endregion export { buildModelsListResult as t };