MCPcopy
hub / github.com/anomalyco/models.dev / mergeModel

Function mergeModel

packages/core/script/generate-digitalocean.ts:361–471  ·  view source on GitHub ↗
(
  apiModel: z.infer<typeof DoModel>,
  pricing: ModelPricing | undefined,
  existing: ExistingModel | null,
)

Source from the content-addressed store, hash-verified

359// ---------------------------------------------------------------------------
360
361function mergeModel(
362 apiModel: z.infer<typeof DoModel>,
363 pricing: ModelPricing | undefined,
364 existing: ExistingModel | null,
365): MergedModel {
366 const rawInput = apiModel.modalities?.input ?? [];
367 const rawOutput = apiModel.modalities?.output ?? [];
368 const inputMods = filterInputModalities(rawInput.length > 0 ? rawInput : existing?.modalities?.input ?? ["text"]);
369 const outputMods = filterOutputModalities(rawOutput.length > 0 ? rawOutput : existing?.modalities?.output ?? ["text"]);
370
371 const maxTokensSetting = apiModel.settings?.find((s) => s.name === "max_tokens");
372 const maxTokens = maxTokensSetting?.max ?? existing?.limit?.output ?? 0;
373
374 const rawContext = apiModel.context_window;
375 const contextWindow =
376 rawContext !== undefined
377 ? typeof rawContext === "string"
378 ? parseInt(rawContext, 10)
379 : rawContext
380 : (existing?.limit?.context ?? 0);
381
382 const isDeprecated = apiModel.lifecycle_status === "end_of_life";
383
384 // Fields preserved from existing TOML (APIs don't provide these)
385 const family = existing?.family ?? inferFamily(apiModel.id, apiModel.name);
386 const knowledge = existing?.knowledge;
387 const openWeights = existing?.open_weights ?? false;
388 const interleaved = existing?.interleaved;
389 const attachment = existing?.attachment ?? inputMods.some((m) => m !== "text");
390
391 // reasoning: trust existing if set, else use API thinking flag as a hint
392 // (thinking flag is unreliable for non-LLM models so gate on output modality)
393 const isTextOutput = outputMods.includes("text") && !outputMods.includes("image") && !outputMods.includes("video");
394 const reasoning = existing?.reasoning ?? (isTextOutput && (apiModel.thinking ?? false));
395
396 // tool_call: no API signal, preserve existing or default true for text models
397 const toolCall = existing?.tool_call ?? isTextOutput;
398
399 // temperature: no API signal, preserve or default true
400 const temperature = existing?.temperature ?? true;
401
402 // structured_output: no API signal, preserve only
403 const structuredOutput = existing?.structured_output;
404
405 const releaseDate = existing?.release_date ?? apiModel.created_at?.slice(0, 10) ?? getTodayDate();
406
407 const merged: MergedModel = {
408 name: apiModel.name,
409 family,
410 attachment,
411 reasoning,
412 tool_call: toolCall,
413 temperature,
414 release_date: releaseDate,
415 last_updated: getTodayDate(),
416 open_weights: openWeights,
417 ...(structuredOutput !== undefined && { structured_output: structuredOutput }),
418 ...(knowledge && { knowledge }),

Callers 1

mainFunction · 0.70

Calls 5

filterInputModalitiesFunction · 0.85
filterOutputModalitiesFunction · 0.85
inferFamilyFunction · 0.70
getTodayDateFunction · 0.70

Tested by

no test coverage detected