diff --git a/src/assets/images/workers-ai/blackforestlabs.svg b/src/assets/images/workers-ai/blackforestlabs.svg new file mode 100644 index 000000000000000..12a4ba1d760a458 --- /dev/null +++ b/src/assets/images/workers-ai/blackforestlabs.svg @@ -0,0 +1 @@ +Flux \ No newline at end of file diff --git a/src/assets/images/workers-ai/deepseek.svg b/src/assets/images/workers-ai/deepseek.svg new file mode 100644 index 000000000000000..48b845e459df064 --- /dev/null +++ b/src/assets/images/workers-ai/deepseek.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/workers-ai/qwen.svg b/src/assets/images/workers-ai/qwen.svg new file mode 100644 index 000000000000000..e1199f82845e37e --- /dev/null +++ b/src/assets/images/workers-ai/qwen.svg @@ -0,0 +1 @@ +Qwen \ No newline at end of file diff --git a/src/components/ModelCatalog.tsx b/src/components/ModelCatalog.tsx index 35083fc6e44b0b9..2e4070adbd5d5b1 100644 --- a/src/components/ModelCatalog.tsx +++ b/src/components/ModelCatalog.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState, useMemo } from "react"; import ModelInfo from "./models/ModelInfo"; import ModelBadges from "./models/ModelBadges"; import { authorData } from "./models/data"; @@ -19,6 +19,37 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => { capabilities: [], }); + // List of model names to pin at the top + const pinnedModelNames = [ + "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + "@cf/meta/llama-3.1-8b-instruct-fast", + ]; + + // Sort models by pinned status first, then by created_at date + const sortedModels = useMemo(() => { + return [...models].sort((a, b) => { + // First check if either model is pinned + const isPinnedA = pinnedModelNames.includes(a.name); + const isPinnedB = pinnedModelNames.includes(b.name); + + // If pinned status differs, prioritize pinned models + if (isPinnedA && !isPinnedB) return -1; + if (!isPinnedA && isPinnedB) return 1; + + // If both are pinned, sort by position in pinnedModelNames array (for manual ordering) + if (isPinnedA && isPinnedB) { + return ( + pinnedModelNames.indexOf(a.name) - pinnedModelNames.indexOf(b.name) + ); + } + + // If neither is pinned, sort by created_at date (newest first) + const dateA = a.created_at ? new Date(a.created_at) : new Date(0); + const dateB = b.created_at ? new Date(b.created_at) : new Date(0); + return dateB.getTime() - dateA.getTime(); + }); + }, [models]); + useEffect(() => { const params = new URLSearchParams(window.location.search); @@ -35,7 +66,7 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => { }); }, []); - const mapped = models.map((model) => ({ + const mapped = sortedModels.map((model) => ({ model: { ...model, capabilities: model.properties @@ -237,13 +268,19 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => { const author = model.model.name.split("/")[1]; const authorInfo = authorData[author]; + const isPinned = pinnedModelNames.includes(model.model.name); return ( + {isPinned && ( + + 📌 + + )}
{authorInfo?.logo ? ( { Yes )} - {properties.price && - properties.price.map( - (price: { price: number; unit: string }) => ( - - Pricing - - {currencyFormatter.format(price.price)} {price.unit} - - - ), - )} + {properties.price && properties.price.length > 0 && ( + + Unit Pricing + + {properties.price + .map( + (price: { price: number; unit: string }) => + `${currencyFormatter.format(price.price)} ${price.unit}`, + ) + .join(", ")} + + + )} diff --git a/src/components/models/data.ts b/src/components/models/data.ts index 37093d8088679d0..d3c85fdcce153ee 100644 --- a/src/components/models/data.ts +++ b/src/components/models/data.ts @@ -5,6 +5,9 @@ import mistral from "../../assets/images/workers-ai/mistralai.svg"; import stabilityai from "../../assets/images/workers-ai/stabilityai.svg"; import huggingface from "../../assets/images/workers-ai/huggingface.svg"; import google from "../../assets/images/workers-ai/google.svg"; +import deepseek from "../../assets/images/workers-ai/deepseek.svg"; +import qwen from "../../assets/images/workers-ai/qwen.svg"; +import blackforestlabs from "../../assets/images/workers-ai/blackforestlabs.svg"; export const authorData: Record = { openai: { @@ -39,4 +42,16 @@ export const authorData: Record = { name: "Google", logo: google.src, }, + "deepseek-ai": { + name: "DeepSeek", + logo: deepseek.src, + }, + qwen: { + name: "Qwen", + logo: qwen.src, + }, + "black-forest-labs": { + name: "Black Forest Labs", + logo: blackforestlabs.src, + }, }; diff --git a/src/schemas/workers-ai-models.ts b/src/schemas/workers-ai-models.ts index 843b7f8e3310521..346c8df6f662f4b 100644 --- a/src/schemas/workers-ai-models.ts +++ b/src/schemas/workers-ai-models.ts @@ -12,6 +12,7 @@ export const workersAiModelsSchema = z.object({ name: z.string(), description: z.string(), }), + created_at: z.string().optional(), tags: z.string().array().optional(), properties: z .object({