143 lines
4.4 KiB
JavaScript
143 lines
4.4 KiB
JavaScript
#!/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).`);
|