40
/** Resolves a model identifier using vendor-level catalog readiness. */
41
export function resolveModelIdentifierFromCatalog(
43
>
identifier: string | undefined,
44
>
vendorResolution: IModelVendorResolution,
45
>
): ModelIdentifierResolution {
46
>
if (!identifier) {
47
return { kind: 'notRequested' };
48
}
50
>
const separator = identifier.search(/[/:]/);
51
>
const vendor = separator === -1 ? undefined : identifier.substring(0, separator);
52
>
const hasLive = vendor ? vendorResolution.hasLiveModels(vendor) : false;
53
>
// Agent-host vendors publish their models asynchronously after the agent host connects, so an
54
>
// empty (not-yet-populated) list is transient: keep the remembered/restored model `pending`
55
>
// (wait) rather than `unavailable` (give up). Once the vendor HAS live models, an absent model
56
>
// is genuinely gone, so stay conclusive. This grace is scoped to restore *resolution* only —
57
>
// cache-retention (`mergeModelsWithCache`) and send-availability keep treating a resolved-empty
58
>
// list as authoritative. The vendor id equals the session type for agent-host models, so
59
>
// `isAgentHostTarget` classifies it directly.
60
>
const isAbsenceConclusive = !vendor || (isLanguageModelVendorAbsenceConclusive(
61
>
vendor,
62
>
hasLive,
63
>
vendorResolution.hasResolved(vendor),
64
>
) && (hasLive || !isAgentHostTarget(vendor)));
65
>
return resolveModelIdentifier(models, identifier, isAbsenceConclusive);
66
>
}
67
68
export function getRegisteredLanguageModels(languageModelsService: Pick<ILanguageModelsService, 'getLanguageModelIds' | 'lookupLanguageModel'>): ILanguageModelChatMetadataAndIdentifier[] {