feat: add native Alibaba Token Plan provider
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
} from "../src/provider-models/descriptor-types";
|
||||
import { PROVIDER_DESCRIPTORS } from "../src/provider-models/descriptors";
|
||||
import {
|
||||
ALIBABA_TOKEN_PLAN_STATIC_MODELS,
|
||||
ANTHROPIC_CURATED_FALLBACK_MODELS,
|
||||
buildFireworksFastSeed,
|
||||
buildXaiOAuthStaticSeed,
|
||||
@@ -104,13 +105,16 @@ async function resolveProviderApiKey(providerId: string, catalog: CatalogDiscove
|
||||
|
||||
return undefined;
|
||||
}
|
||||
type CatalogProviderFetchResult = { models: ModelSpec[]; succeeded: boolean };
|
||||
|
||||
async function fetchProviderModelsFromCatalog(descriptor: CatalogProviderDescriptor): Promise<ModelSpec[]> {
|
||||
async function fetchProviderModelsFromCatalog(
|
||||
descriptor: CatalogProviderDescriptor,
|
||||
): Promise<CatalogProviderFetchResult> {
|
||||
const apiKey = await resolveProviderApiKey(descriptor.providerId, descriptor.catalogDiscovery);
|
||||
|
||||
if (!apiKey && !allowsUnauthenticatedCatalogDiscovery(descriptor)) {
|
||||
console.log(`No ${descriptor.catalogDiscovery.label} credentials found (env or agent.db), using fallback models`);
|
||||
return [];
|
||||
return { models: [], succeeded: false };
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -129,19 +133,19 @@ async function fetchProviderModelsFromCatalog(descriptor: CatalogProviderDescrip
|
||||
console.warn(
|
||||
`${descriptor.catalogDiscovery.label} dynamic fetch failed (stale cache merge), using fallback models`,
|
||||
);
|
||||
return [];
|
||||
return { models: [], succeeded: false };
|
||||
}
|
||||
const models = result.models.filter(model => model.provider === descriptor.providerId);
|
||||
if (models.length === 0) {
|
||||
console.warn(`${descriptor.catalogDiscovery.label} discovery returned no models, using fallback models`);
|
||||
return [];
|
||||
console.warn(`${descriptor.catalogDiscovery.label} discovery returned no models`);
|
||||
return { models: [], succeeded: true };
|
||||
}
|
||||
console.log(`Fetched ${models.length} models from ${descriptor.catalogDiscovery.label} model manager`);
|
||||
// The manager returns built models; models.json stores specs (sparse compat).
|
||||
return models.map(model => toModelSpec(model));
|
||||
return { models: models.map(model => toModelSpec(model)), succeeded: true };
|
||||
} catch (error) {
|
||||
console.error(`Failed to fetch ${descriptor.catalogDiscovery.label} models:`, error);
|
||||
return [];
|
||||
return { models: [], succeeded: false };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,12 +489,12 @@ async function generateModels() {
|
||||
const catalogProviderModelBatches = await Promise.all(
|
||||
catalogProviderDescriptors.map(async descriptor => ({
|
||||
descriptor,
|
||||
models: await fetchProviderModelsFromCatalog(descriptor),
|
||||
...(await fetchProviderModelsFromCatalog(descriptor)),
|
||||
})),
|
||||
);
|
||||
const authoritativeCatalogProviders = new Set(
|
||||
catalogProviderModelBatches
|
||||
.filter(batch => batch.descriptor.dynamicModelsAuthoritative === true && batch.models.length > 0)
|
||||
.filter(batch => batch.descriptor.dynamicModelsAuthoritative === true && batch.succeeded)
|
||||
.map(batch => batch.descriptor.providerId),
|
||||
);
|
||||
const catalogProviderModels = catalogProviderModelBatches.flatMap(batch => batch.models);
|
||||
@@ -517,6 +521,12 @@ async function generateModels() {
|
||||
// persisted `modelRoles.default = "xai-oauth/<id>"` is honored before the
|
||||
// async refresh fires (interactive boot does not await refresh).
|
||||
allModels.push(...buildXaiOAuthStaticSeed());
|
||||
// Seed QwenCloud's documented Token Plan models when credentialed
|
||||
// discovery is unavailable. A successful `/models` response is authoritative
|
||||
// for the subscribed edition and must not be widened by the fallback.
|
||||
if (!authoritativeCatalogProviders.has("alibaba-token-plan")) {
|
||||
allModels.push(...ALIBABA_TOKEN_PLAN_STATIC_MODELS);
|
||||
}
|
||||
// Seed Anthropic models that are live on the first-party API or in limited
|
||||
// release but that models.dev has not catalogued yet (e.g. Claude Fable 5 /
|
||||
// Mythos 5). Deduped behind upstream entries; metadata is pinned in
|
||||
|
||||
Reference in New Issue
Block a user