#!/usr/bin/env node import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import { homedir } from 'node:os'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT = resolve(__dirname, '..'); const OUTPUT_DIR = join(ROOT, 'build', 'yinian-internal'); const OUTPUT_FILE = join(OUTPUT_DIR, 'model-auth-profiles.json'); const SHOULD_BUNDLE = process.env.YINIAN_BUNDLE_MODEL_AUTH === '1'; const SOURCE_AUTH_PROFILES = process.env.YINIAN_MODEL_AUTH_SOURCE ? resolve(process.env.YINIAN_MODEL_AUTH_SOURCE) : join(homedir(), '.openclaw', 'agents', 'main', 'agent', 'auth-profiles.json'); const MODEL_PROVIDER_KEY = (process.env.YINIAN_MODEL_PROVIDER_KEY || 'yinian-model').trim(); const MODEL_ID = (process.env.YINIAN_MODEL_ID || '').trim(); const MODEL_NAME = (process.env.YINIAN_MODEL_NAME || MODEL_ID).trim(); const MODEL_BASE_URL = (process.env.YINIAN_MODEL_BASE_URL || '').trim(); const MODEL_API = (process.env.YINIAN_MODEL_API || 'openai-completions').trim(); const MODEL_AUTH_PROFILE_ID = (process.env.YINIAN_MODEL_AUTH_PROFILE_ID || `${MODEL_PROVIDER_KEY}:default`).trim(); const SOURCE_PROFILE_ID = (process.env.YINIAN_MODEL_AUTH_SOURCE_PROFILE_ID || '').trim(); const MODEL_FALLBACKS = (process.env.YINIAN_MODEL_FALLBACKS || '') .split(',') .map((value) => value.trim()) .filter(Boolean); const LEGACY_SOURCE_PROFILE_IDS = ['minimax:default', 'minimax:cn']; function log(message) { console.log(`[yinian-model-auth] ${message}`); } function fail(message) { console.error(`[yinian-model-auth] ${message}`); process.exit(1); } function readJson(filePath) { try { return JSON.parse(readFileSync(filePath, 'utf8')); } catch { return null; } } function writeManifest(manifest) { mkdirSync(OUTPUT_DIR, { recursive: true }); writeFileSync(OUTPUT_FILE, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8'); } rmSync(OUTPUT_DIR, { recursive: true, force: true }); if (!SHOULD_BUNDLE) { writeManifest({ bundled: false, reason: 'YINIAN_BUNDLE_MODEL_AUTH is not enabled', }); log('pilot model auth bundling disabled. Customer pilot installers must use package:pilot or set YINIAN_BUNDLE_MODEL_AUTH=1.'); process.exit(0); } if (!existsSync(SOURCE_AUTH_PROFILES)) { fail(`source auth profiles not found: ${SOURCE_AUTH_PROFILES}`); } if (!MODEL_PROVIDER_KEY) { fail('YINIAN_MODEL_PROVIDER_KEY is required for model auth bundling.'); } if (!MODEL_ID) { fail('YINIAN_MODEL_ID is required for model auth bundling.'); } if (!MODEL_BASE_URL) { fail('YINIAN_MODEL_BASE_URL is required for model auth bundling.'); } const source = readJson(SOURCE_AUTH_PROFILES); const sourceProfiles = source && typeof source === 'object' && source.profiles && typeof source.profiles === 'object' ? source.profiles : {}; const profiles = {}; const sourceProfileIds = [ SOURCE_PROFILE_ID, MODEL_AUTH_PROFILE_ID, `${MODEL_PROVIDER_KEY}:default`, ...LEGACY_SOURCE_PROFILE_IDS, ].filter(Boolean); const candidateProfileIds = Array.from(new Set([ ...sourceProfileIds, ...Object.keys(sourceProfiles), ])); let bundledKey = ''; for (const profileId of candidateProfileIds) { const profile = sourceProfiles[profileId]; if (!profile || typeof profile !== 'object') continue; if (profile.type !== 'api_key') continue; if (typeof profile.key !== 'string' || profile.key.trim().length < 8) continue; bundledKey = profile.key.trim(); break; } if (bundledKey) { profiles[MODEL_AUTH_PROFILE_ID] = { type: 'api_key', provider: MODEL_PROVIDER_KEY, key: bundledKey, }; } if (!profiles[MODEL_AUTH_PROFILE_ID]) { fail(`API key profile is required for pilot model auth bundling. Set YINIAN_MODEL_AUTH_SOURCE_PROFILE_ID or create ${MODEL_AUTH_PROFILE_ID}.`); } writeManifest({ bundled: true, purpose: 'internal-pilot-only', source: 'local-openclaw-auth-profiles', profileIds: Object.keys(profiles), model: { providerKey: MODEL_PROVIDER_KEY, modelId: MODEL_ID, modelName: MODEL_NAME || MODEL_ID, baseUrl: MODEL_BASE_URL, api: MODEL_API, authProfileId: MODEL_AUTH_PROFILE_ID, fallbackModelRefs: MODEL_FALLBACKS, }, store: { version: 1, profiles, order: { [MODEL_PROVIDER_KEY]: Object.keys(profiles), }, lastGood: { [MODEL_PROVIDER_KEY]: MODEL_AUTH_PROFILE_ID, }, }, }); log(`bundled ${Object.keys(profiles).length} internal pilot model auth profile(s).`);