130 lines
4.9 KiB
TypeScript
130 lines
4.9 KiB
TypeScript
import {
|
|
IMPORTED_REASONING_EFFORTS,
|
|
type ImportedModelCapabilities,
|
|
type ImportedModelCapability,
|
|
type ImportedModelWebSearchCapability,
|
|
type ImportedReasoningEffort,
|
|
} from './imported-model-profile';
|
|
|
|
export const NIANCODE_USER_MODEL_ACCOUNT_ID = 'niancode-user-models';
|
|
export const NIANCODE_USER_MODEL_ACCOUNT_LABEL = 'Makelore Models';
|
|
|
|
const WORKS_SQUARE_MODEL_ROUTING_PREFIXES_TO_STRIP = new Set([
|
|
'deepseek',
|
|
]);
|
|
|
|
export interface NianCodeUserModelAccountLike {
|
|
id: string;
|
|
}
|
|
|
|
export function normalizeImportedUserModelId(rawModel: string): string {
|
|
const trimmed = rawModel.trim();
|
|
const slashIndex = trimmed.indexOf('/');
|
|
if (slashIndex <= 0 || slashIndex >= trimmed.length - 1) {
|
|
return trimmed;
|
|
}
|
|
|
|
const prefix = trimmed.slice(0, slashIndex).toLowerCase();
|
|
const modelId = trimmed.slice(slashIndex + 1).trim();
|
|
return WORKS_SQUARE_MODEL_ROUTING_PREFIXES_TO_STRIP.has(prefix) && modelId
|
|
? modelId
|
|
: trimmed;
|
|
}
|
|
|
|
function normalizeImportedModelCapability(value: unknown): ImportedModelCapability | null {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
const record = value as Record<string, unknown>;
|
|
const rawEfforts = record.reasoning_efforts ?? record.reasoningEfforts;
|
|
const reasoningCanDisable = record.reasoning_can_disable ?? record.reasoningCanDisable;
|
|
if (!Array.isArray(rawEfforts) || typeof reasoningCanDisable !== 'boolean') return null;
|
|
const reasoningEfforts = IMPORTED_REASONING_EFFORTS.filter((effort) => (
|
|
rawEfforts.some((candidate) => candidate === effort)
|
|
)) as ImportedReasoningEffort[];
|
|
if (reasoningEfforts.length === 0 && rawEfforts.length > 0) return null;
|
|
const webSearch = normalizeImportedModelWebSearchCapability(
|
|
record.web_search ?? record.webSearch,
|
|
);
|
|
return {
|
|
reasoningEfforts,
|
|
reasoningCanDisable,
|
|
...(webSearch ? { webSearch } : {}),
|
|
};
|
|
}
|
|
|
|
function normalizeImportedModelWebSearchCapability(
|
|
value: unknown,
|
|
): ImportedModelWebSearchCapability | null {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
const record = value as Record<string, unknown>;
|
|
const schemaVersion = record.schema_version ?? record.schemaVersion;
|
|
const rawAdapter = record.adapter;
|
|
const supportsForcedSearch = record.supports_forced_search ?? record.supportsForcedSearch;
|
|
const rawSourceMode = record.source_mode ?? record.sourceMode;
|
|
const rawBillingAuthority = record.billing_authority ?? record.billingAuthority;
|
|
const adapters: Record<string, ImportedModelWebSearchCapability['adapter']> = {
|
|
openai_responses: 'openai-responses',
|
|
'openai-responses': 'openai-responses',
|
|
bailian_responses: 'bailian-responses',
|
|
'bailian-responses': 'bailian-responses',
|
|
bailian_chat_completions: 'bailian-chat-completions',
|
|
'bailian-chat-completions': 'bailian-chat-completions',
|
|
};
|
|
const sourceModes: Record<string, ImportedModelWebSearchCapability['sourceMode']> = {
|
|
structured: 'structured',
|
|
inline_or_structured: 'inline-or-structured',
|
|
'inline-or-structured': 'inline-or-structured',
|
|
};
|
|
const billingAuthorities: Record<string, ImportedModelWebSearchCapability['billingAuthority']> = {
|
|
model_request: 'model-request',
|
|
'model-request': 'model-request',
|
|
};
|
|
const adapter = typeof rawAdapter === 'string' ? adapters[rawAdapter] : undefined;
|
|
const sourceMode = typeof rawSourceMode === 'string' ? sourceModes[rawSourceMode] : undefined;
|
|
const billingAuthority = typeof rawBillingAuthority === 'string'
|
|
? billingAuthorities[rawBillingAuthority]
|
|
: undefined;
|
|
if (
|
|
schemaVersion !== 1
|
|
|| !adapter
|
|
|| supportsForcedSearch !== true
|
|
|| !sourceMode
|
|
|| !billingAuthority
|
|
) {
|
|
return null;
|
|
}
|
|
return {
|
|
schemaVersion: 1,
|
|
adapter,
|
|
supportsForcedSearch: true,
|
|
sourceMode,
|
|
billingAuthority,
|
|
};
|
|
}
|
|
|
|
export function normalizeImportedModelCapabilities(
|
|
value: unknown,
|
|
modelIds?: readonly string[],
|
|
): ImportedModelCapabilities | undefined {
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
|
|
const allowedModelIds = modelIds
|
|
? new Set(modelIds.map(normalizeImportedUserModelId))
|
|
: null;
|
|
const result: ImportedModelCapabilities = {};
|
|
for (const [rawModelId, rawCapability] of Object.entries(value as Record<string, unknown>)) {
|
|
const modelId = normalizeImportedUserModelId(rawModelId);
|
|
if (!modelId || (allowedModelIds && !allowedModelIds.has(modelId))) continue;
|
|
const capability = normalizeImportedModelCapability(rawCapability);
|
|
if (capability && !result[modelId]) result[modelId] = capability;
|
|
}
|
|
return Object.keys(result).length > 0 ? result : undefined;
|
|
}
|
|
|
|
export function selectUserModelRuntimeAccounts<T extends NianCodeUserModelAccountLike>(
|
|
accounts: T[],
|
|
): T[] {
|
|
const importedUserModelAccount = accounts.find((account) => (
|
|
account.id === NIANCODE_USER_MODEL_ACCOUNT_ID
|
|
));
|
|
return importedUserModelAccount ? [importedUserModelAccount] : accounts;
|
|
}
|