import type { ModelSummary, ProviderAccount, ProviderModelEntry, ProviderProtocol, ProviderSecret, } from '../../shared/providers/types'; import { getProviderBackendConfig, getProviderDefaultModel, getProviderDefinition, } from '../../shared/providers/registry'; import type { ProductModelRef } from '../contracts'; import { atomicWriteJson } from '../../coding-projects/atomic-json'; import { NIANCODE_USER_MODEL_ACCOUNT_ID, normalizeImportedUserModelId, selectUserModelRuntimeAccounts, } from '../../../shared/user-model-config'; import { getImportedModelProfile, thinkingLevelMapForImportedModelCapability, } from '../../../shared/imported-model-profile'; const PI_ENV_PREFIX = 'MAKELORE_PI'; const WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE = 'works_square_ai_gateway'; const WORKS_SQUARE_AI_GATEWAY_PROXY_CREDENTIAL_MODE = 'works_square_ai_gateway_proxy'; const providerCatalogWriteTails = new Map>(); export const PI_PROVIDER_APIS = [ 'openai-completions', 'openai-responses', 'anthropic-messages', 'google-generative-ai', ] as const; export type PiProviderApi = (typeof PI_PROVIDER_APIS)[number]; import { unknownManagedModelCapability } from '../../../shared/managed-model-capabilities'; export interface PiProviderModelDescriptor { managedCapability?: import('../../../shared/managed-model-capabilities').ManagedModelCapability; id: string; name: string; input: Array<'text' | 'image'>; reasoning: boolean; contextWindow?: number; maxOutputTokens?: number; compat?: { thinkingFormat?: 'deepseek' | 'openrouter' | 'qwen'; sessionAffinityFormat?: 'openrouter'; supportsDeveloperRole?: boolean; supportsReasoningEffort?: boolean; supportsStore?: boolean; requiresReasoningContentOnAssistantMessages?: boolean; }; thinkingLevelMap?: Partial>; } export interface PiProviderDescriptor { accountId: string; runtimeProviderId: string; api: PiProviderApi; baseUrl?: string; headers: Record; apiKeyEnv?: string; models: PiProviderModelDescriptor[]; } export interface PiModelsFile { providers: Record; models: Array<{ id: string; name: string; reasoning: boolean; input: Array<'text' | 'image'>; contextWindow?: number; maxTokens?: number; cost: { input: number; output: number; cacheRead: number; cacheWrite: number }; compat?: PiProviderModelDescriptor['compat']; thinkingLevelMap?: PiProviderModelDescriptor['thinkingLevelMap']; }>; }>; } export interface PiProviderCatalogSummary { providerCount: number; providers: Array<{ runtimeProviderId: string; api: PiProviderApi; baseUrl?: string; modelIds: string[]; imageInputModelIds: string[]; headerNames: string[]; hasCredentialReference: boolean; }>; } export interface PiProviderCatalogResult { descriptors: PiProviderDescriptor[]; modelsFile: PiModelsFile; summary: PiProviderCatalogSummary; } export interface BuildPiProviderCatalogOptions { accounts: readonly ProviderAccount[]; modelSummaries?: readonly ModelSummary[]; } export async function buildPiProviderCatalogFromProviderService( modelSummaries: readonly ModelSummary[] = [], ): Promise { const { getProviderService } = await import('../../services/providers/provider-service'); return buildPiProviderCatalog({ accounts: await getProviderService().listAccounts(), modelSummaries, }); } export interface PiProviderSelection { managedCapability?: import('../../../shared/managed-model-capabilities').ManagedModelCapability; accountId: string; runtimeProviderId: string; modelId: string; thinkingLevel: ProductModelRef['thinkingLevel']; input: Array<'text' | 'image'>; contextWindow?: number; maxOutputTokens?: number; } export interface BuildPiWorkerCredentialProjectionOptions { account: ProviderAccount; descriptor: PiProviderDescriptor; resolveCredential: (account: ProviderAccount) => Promise; localProxyCredential?: string; } export interface PiWorkerCredentialProjection { env: Record; sensitiveValues: string[]; } export interface PiWorkerCredentialProjectionSummary { envKeys: string[]; sensitiveValueCount: number; } export class PiProviderConfigError extends Error { constructor( public readonly code: 'PROVIDER_INVALID' | 'PROVIDER_AUTH_REQUIRED' | 'MODEL_UNAVAILABLE', message: string, ) { super(message); } } export function credentialValueForProviderSecret(secret: ProviderSecret | null): string | null { if (!secret) return null; if (secret.type === 'api_key') return secret.apiKey.trim() || null; if (secret.type === 'oauth') return secret.accessToken.trim() || null; return secret.apiKey?.trim() || null; } export async function resolvePiProviderCredentialFromSecretStore( account: ProviderAccount, ): Promise { const { getProviderSecret } = await import('../../services/secrets/secret-store'); return credentialValueForProviderSecret(await getProviderSecret(account.id)); } function accountHex(accountId: string): string { const normalized = accountId.trim(); if (!normalized) throw new PiProviderConfigError('PROVIDER_INVALID', 'Provider account id is required'); return Buffer.from(normalized, 'utf8').toString('hex'); } export function resolvePiRuntimeProviderId(accountId: string): string { return `makelore-account-${accountHex(accountId)}`; } function apiKeyEnvForAccount(accountId: string): string { return `${PI_ENV_PREFIX}_ACCOUNT_${accountHex(accountId).toUpperCase()}_API_KEY`; } function headerEnvForAccount(accountId: string, headerName: string): string { const nameHex = Buffer.from(headerName.toLowerCase(), 'utf8').toString('hex').toUpperCase(); return `${PI_ENV_PREFIX}_ACCOUNT_${accountHex(accountId).toUpperCase()}_HEADER_${nameHex}`; } function normalizeBaseUrl(value: string | undefined): string | undefined { const normalized = value?.trim().replace(/\/+$/, ''); return normalized || undefined; } function normalizeWorksGatewayBaseUrl(value: string | undefined): string | undefined { const normalized = normalizeBaseUrl(value); if (!normalized) return undefined; try { const parsed = new URL(normalized); const pathname = parsed.pathname.replace(/\/+$/, ''); if (!pathname || pathname === '/') parsed.pathname = '/v1'; return parsed.toString().replace(/\/+$/, ''); } catch { return normalized; } } function defaultBaseUrlForVendor(vendorId: string): string | undefined { if (vendorId === 'anthropic') return 'https://api.anthropic.com'; if (vendorId === 'google') return 'https://generativelanguage.googleapis.com/v1beta'; return getProviderBackendConfig(vendorId)?.baseUrl ?? getProviderDefinition(vendorId)?.defaultBaseUrl; } function baseUrlForAccount(account: ProviderAccount): string | undefined { const baseUrl = account.baseUrl ?? account.metadata?.worksSquareOneApiBaseUrl ?? defaultBaseUrlForVendor(account.vendorId); return account.metadata?.worksSquareCredentialMode === WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE ? normalizeWorksGatewayBaseUrl(baseUrl) : normalizeBaseUrl(baseUrl); } function protocolForAccount(account: ProviderAccount): ProviderProtocol | 'google-generative-ai' | undefined { if (account.apiProtocol) return account.apiProtocol; const configured = getProviderBackendConfig(account.vendorId)?.api; if (configured) return configured; if (account.vendorId === 'anthropic') return 'anthropic-messages'; if (account.vendorId === 'google') return 'google-generative-ai'; if (account.vendorId === 'openai') return 'openai-responses'; if (account.vendorId === 'openrouter') return 'openrouter'; return undefined; } function mapProtocol(protocol: ReturnType): { api: PiProviderApi; compat?: PiProviderModelDescriptor['compat']; } { if (protocol === 'openrouter') { return { api: 'openai-completions', compat: { thinkingFormat: 'openrouter', sessionAffinityFormat: 'openrouter', }, }; } if (protocol && PI_PROVIDER_APIS.includes(protocol as PiProviderApi)) { return { api: protocol as PiProviderApi }; } throw new PiProviderConfigError('PROVIDER_INVALID', 'Provider protocol is not supported by Pi'); } function normalizeModelId(rawModelId: string | undefined, account: ProviderAccount): string | undefined { const modelId = rawModelId?.trim(); if (!modelId) return undefined; const runtimePrefix = `${resolvePiRuntimeProviderId(account.id)}/`; const unqualified = modelId.startsWith(runtimePrefix) ? modelId.slice(runtimePrefix.length) : modelId; return account.id === NIANCODE_USER_MODEL_ACCOUNT_ID && !account.metadata?.worksSquareModelCapabilitiesV2 ? normalizeImportedUserModelId(unqualified) : unqualified; } function backendModelEntries(account: ProviderAccount): Map { return new Map((getProviderBackendConfig(account.vendorId)?.models ?? []).map((model) => [model.id, model])); } function modelIdsForAccount(account: ProviderAccount): string[] { const seen = new Set(); const result: string[] = []; const configuredModels = getProviderBackendConfig(account.vendorId)?.models ?? []; for (const rawModelId of [ account.model ?? getProviderDefaultModel(account.vendorId), ...(account.fallbackModels ?? []), ...(account.metadata?.customModels ?? []), ...configuredModels.map((model) => model.id), ]) { const modelId = normalizeModelId(rawModelId, account); if (!modelId || seen.has(modelId)) continue; seen.add(modelId); result.push(modelId); } return result; } function finitePositiveInteger(value: unknown): number | undefined { return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined; } function modelDescriptor( account: ProviderAccount, modelId: string, summaries: readonly ModelSummary[], compat: PiProviderModelDescriptor['compat'], backendModels: Map, enforcedCompat: PiProviderModelDescriptor['compat'], ): PiProviderModelDescriptor { const summary = summaries.find((candidate) => ( candidate.id === modelId && (candidate.accountId === account.id || (!candidate.accountId && candidate.vendorId === account.vendorId)) )); const backend = backendModels.get(modelId); const profile = getImportedModelProfile(modelId); const serverCapability = account.metadata?.worksSquareModelCapabilities?.[modelId]; const managed = account.id === 'niancode-user-models' ? account.metadata?.worksSquareModelCapabilitiesV2?.models[modelId] ?? unknownManagedModelCapability() : undefined; const backendInput = Array.isArray(backend?.input) ? backend.input.filter((input): input is 'text' | 'image' => input === 'text' || input === 'image') : []; const supportsImage = managed ? managed.inputModalities?.includes('image') === true : Boolean( summary?.supportsVision || profile?.modalities.input.includes('image') || backendInput.includes('image'), ); const contextWindow = finitePositiveInteger(managed?.limits?.contextWindow) ?? finitePositiveInteger(summary?.contextWindow) ?? finitePositiveInteger(profile?.limit?.context) ?? finitePositiveInteger(backend?.contextWindow); const maxOutputTokens = finitePositiveInteger(managed?.limits?.maxOutputTokens) ?? finitePositiveInteger(profile?.limit?.output) ?? finitePositiveInteger(backend?.maxTokens); return { id: modelId, name: summary?.name || (typeof backend?.name === 'string' && backend.name.trim()) || modelId, input: supportsImage ? ['text', 'image'] : ['text'], ...(managed ? { managedCapability: managed } : {}), reasoning: managed ? managed.reasoning.supported === true : serverCapability ? serverCapability.reasoningEfforts.length > 0 : summary?.supportsReasoning === true || profile?.pi?.reasoning === true || backend?.reasoning === true, ...(contextWindow ? { contextWindow } : {}), ...(maxOutputTokens ? { maxOutputTokens } : {}), ...(compat || profile?.pi?.compat || enforcedCompat || serverCapability || managed ? { compat: { ...compat, ...profile?.pi?.compat, ...enforcedCompat, ...(serverCapability ? { supportsReasoningEffort: true } : {}), ...(managed ? { supportsReasoningEffort: false, thinkingFormat: managed.reasoning.controlFormat ?? undefined, requiresReasoningContentOnAssistantMessages: managed.reasoning.controlFormat !== null, } : {}), }, } : {}), ...(managed ? {} : serverCapability ? { thinkingLevelMap: thinkingLevelMapForImportedModelCapability(serverCapability) } : profile?.pi?.thinkingLevelMap ? { thinkingLevelMap: { ...profile.pi.thinkingLevelMap } } : {}), }; } function rawHeadersForAccount(account: ProviderAccount): Record { const headers: Record = {}; for (const [name, value] of Object.entries({ ...(getProviderBackendConfig(account.vendorId)?.headers ?? {}), ...(account.headers ?? {}), })) { const duplicate = Object.keys(headers).find((candidate) => candidate.toLowerCase() === name.toLowerCase()); if (duplicate) delete headers[duplicate]; headers[name] = value; } return headers; } function headerNamesForAccount(account: ProviderAccount): string[] { const names = Object.keys(rawHeadersForAccount(account)); if ( account.metadata?.worksSquareCredentialMode === WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE && !names.some((name) => name.toLowerCase() === 'authorization') ) { names.push('Authorization'); } return names.sort((left, right) => left.toLowerCase().localeCompare(right.toLowerCase())); } function descriptorForAccount( account: ProviderAccount, summaries: readonly ModelSummary[], ): PiProviderDescriptor { const runtimeProviderId = resolvePiRuntimeProviderId(account.id); const mapping = mapProtocol(protocolForAccount(account)); const baseUrl = baseUrlForAccount(account); if (!baseUrl) { throw new PiProviderConfigError( 'PROVIDER_INVALID', `Provider account ${account.id} has no runtime base URL`, ); } const apiKeyEnv = apiKeyEnvForAccount(account.id); const credentialMode = account.metadata?.worksSquareCredentialMode; const enforcedCompat: PiProviderModelDescriptor['compat'] = mapping.api === 'openai-completions' && (credentialMode === WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE || credentialMode === WORKS_SQUARE_AI_GATEWAY_PROXY_CREDENTIAL_MODE) ? { supportsDeveloperRole: false } : undefined; const models = modelIdsForAccount(account).map((modelId) => modelDescriptor( account, modelId, summaries, mapping.compat, backendModelEntries(account), enforcedCompat, )); if (models.length === 0) { throw new PiProviderConfigError( 'PROVIDER_INVALID', `Provider account ${account.id} has no configured model`, ); } const headers = Object.fromEntries(headerNamesForAccount(account).map((headerName) => [ headerName, `$${headerEnvForAccount(account.id, headerName)}`, ])); return { accountId: account.id, runtimeProviderId, api: mapping.api, baseUrl, headers, apiKeyEnv, models, }; } function modelsFileForDescriptors(descriptors: readonly PiProviderDescriptor[]): PiModelsFile { return { providers: Object.fromEntries(descriptors.map((descriptor) => [ descriptor.runtimeProviderId, { ...(descriptor.baseUrl ? { baseUrl: descriptor.baseUrl } : {}), api: descriptor.api, ...(descriptor.apiKeyEnv ? { apiKey: `$${descriptor.apiKeyEnv}` } : {}), ...(Object.keys(descriptor.headers).length > 0 ? { headers: { ...descriptor.headers } } : {}), models: descriptor.models.map((model) => ({ id: model.id, name: model.name, reasoning: model.reasoning, input: [...model.input], ...(model.contextWindow ? { contextWindow: model.contextWindow } : {}), ...(model.maxOutputTokens ? { maxTokens: model.maxOutputTokens } : {}), cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, ...(model.compat ? { compat: { ...model.compat } } : {}), ...(model.thinkingLevelMap ? { thinkingLevelMap: { ...model.thinkingLevelMap } } : {}), })), }, ])), }; } export function buildPiProviderCatalog( options: BuildPiProviderCatalogOptions, ): PiProviderCatalogResult { const accounts = selectUserModelRuntimeAccounts([...options.accounts]).filter((account) => account.enabled); const accountIds = new Set(); const descriptors = accounts.map((account) => { if (accountIds.has(account.id)) { throw new PiProviderConfigError('PROVIDER_INVALID', `Duplicate Provider account id: ${account.id}`); } accountIds.add(account.id); return descriptorForAccount(account, options.modelSummaries ?? []); }); return { descriptors, modelsFile: modelsFileForDescriptors(descriptors), summary: { providerCount: descriptors.length, providers: descriptors.map((descriptor) => ({ runtimeProviderId: descriptor.runtimeProviderId, api: descriptor.api, ...(descriptor.baseUrl ? { baseUrl: descriptor.baseUrl } : {}), modelIds: descriptor.models.map((model) => model.id), imageInputModelIds: descriptor.models .filter((model) => model.input.includes('image')) .map((model) => model.id), headerNames: Object.keys(descriptor.headers).sort(), hasCredentialReference: Boolean(descriptor.apiKeyEnv), })), }, }; } export function selectPiProviderModel( catalog: PiProviderCatalogResult, modelRef: ProductModelRef, ): PiProviderSelection { const descriptor = catalog.descriptors.find((candidate) => candidate.accountId === modelRef.accountId); const model = descriptor?.models.find((candidate) => candidate.id === modelRef.modelId); if (!descriptor || !model) { throw new PiProviderConfigError( 'MODEL_UNAVAILABLE', 'The selected Provider account or model is unavailable', ); } return { accountId: descriptor.accountId, runtimeProviderId: descriptor.runtimeProviderId, modelId: model.id, thinkingLevel: modelRef.thinkingLevel, input: [...model.input], ...(model.managedCapability ? { managedCapability: model.managedCapability } : {}), ...(model.contextWindow ? { contextWindow: model.contextWindow } : {}), ...(model.maxOutputTokens ? { maxOutputTokens: model.maxOutputTokens } : {}), }; } export async function writePiProviderCatalog( filePath: string, catalog: PiProviderCatalogResult, modelRef?: ProductModelRef, ): Promise { if (modelRef) selectPiProviderModel(catalog, modelRef); const previous = providerCatalogWriteTails.get(filePath) ?? Promise.resolve(); const write = previous .catch(() => undefined) .then(async () => await atomicWriteJson(filePath, catalog.modelsFile)); providerCatalogWriteTails.set(filePath, write); try { await write; } finally { if (providerCatalogWriteTails.get(filePath) === write) { providerCatalogWriteTails.delete(filePath); } } } function replaceCredentialEnvReferences(value: string, credential: string | null): string { if (!value.includes('{env:')) return value; if (!credential) { throw new PiProviderConfigError('PROVIDER_AUTH_REQUIRED', 'Provider credential is unavailable'); } return value.replace(/\{env:[^}]+\}/g, credential); } export async function buildPiWorkerCredentialProjection( options: BuildPiWorkerCredentialProjectionOptions, ): Promise { if (options.account.id !== options.descriptor.accountId) { throw new PiProviderConfigError('PROVIDER_INVALID', 'Provider account does not match descriptor'); } const useLocalProxy = options.account.metadata?.worksSquareCredentialMode === WORKS_SQUARE_AI_GATEWAY_PROXY_CREDENTIAL_MODE; const resolved = useLocalProxy ? options.localProxyCredential?.trim() || null : await options.resolveCredential(options.account); const credential = resolved?.trim() || (options.account.authMode === 'local' ? 'local-provider' : null); if (!credential) { throw new PiProviderConfigError('PROVIDER_AUTH_REQUIRED', 'Provider credential is unavailable'); } const env: Record = {}; if (options.descriptor.apiKeyEnv) env[options.descriptor.apiKeyEnv] = credential; const accountHeaders = rawHeadersForAccount(options.account); for (const headerName of Object.keys(options.descriptor.headers)) { const sourceEntry = Object.entries(accountHeaders).find(([name]) => ( name.toLowerCase() === headerName.toLowerCase() )); let value = sourceEntry?.[1]; if (!value && headerName.toLowerCase() === 'authorization' && options.account.metadata?.worksSquareCredentialMode === WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE) { value = `Bearer ${credential}`; } if (value === undefined) { throw new PiProviderConfigError('PROVIDER_INVALID', `Provider header is unavailable: ${headerName}`); } env[headerEnvForAccount(options.account.id, headerName)] = replaceCredentialEnvReferences(value, credential); } return { env, sensitiveValues: [...new Set(Object.values(env).filter(Boolean))], }; } export function summarizePiWorkerCredentialProjection( projection: PiWorkerCredentialProjection, ): PiWorkerCredentialProjectionSummary { return { envKeys: Object.keys(projection.env).sort(), sensitiveValueCount: projection.sensitiveValues.length, }; }