diff --git a/frontend/src/components/ui/ModelCard.svelte b/frontend/src/components/ui/ModelCard.svelte
index 5dc4737..c452037 100644
--- a/frontend/src/components/ui/ModelCard.svelte
+++ b/frontend/src/components/ui/ModelCard.svelte
@@ -1,6 +1,6 @@
@@ -59,6 +78,35 @@
Access state-of-the-art language models from leading AI research organizations
+
+ {#if !loading && !error}
+
+
+
+
+
+
+
+
+ {/if}
+
{#if loading}
Loading...
{:else if error}
@@ -67,13 +115,61 @@
{:else}
- {#each models as model}
+ {#each filteredModels as model (model.data.title)}
{/each}
+ {#if filteredModels.length === 0}
+
+ No models match your filters.
+
+ {/if}
{/if}
\ No newline at end of file
+ .search-input {
+ width: 100%;
+ max-width: 420px;
+ padding: 0.5rem 0.75rem;
+ border-radius: 6px;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ background-color: transparent;
+ color: inherit;
+ font-size: 0.875rem;
+ outline: none;
+ transition: border-color 0.15s ease;
+ }
+ :global(.dark) .search-input {
+ border-color: rgba(255, 255, 255, 0.2);
+ }
+ .search-input:focus {
+ border-color: #6366f1;
+ }
+
+ .pill {
+ padding: 0.3rem 0.75rem;
+ border-radius: 9999px;
+ font-size: 0.8rem;
+ font-weight: 600;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ background-color: transparent;
+ color: inherit;
+ cursor: pointer;
+ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
+ }
+ :global(.dark) .pill {
+ border-color: rgba(255, 255, 255, 0.2);
+ }
+ .pill:hover {
+ background-color: rgba(0, 0, 0, 0.05);
+ }
+ :global(.dark) .pill:hover {
+ background-color: rgba(255, 255, 255, 0.08);
+ }
+ .pill.active {
+ background-color: #6366f1;
+ border-color: #6366f1;
+ color: white;
+ }
+
diff --git a/frontend/src/lib/modelMetrics.ts b/frontend/src/lib/modelMetrics.ts
index 6ed756f..4764bbd 100644
--- a/frontend/src/lib/modelMetrics.ts
+++ b/frontend/src/lib/modelMetrics.ts
@@ -1,28 +1,28 @@
-const SGLANG_BASE = "https://metrics.swissai.svc.cscs.ch/d/sglang-monitoring/sglang-monitoring?orgId=1&from=now-15m&to=now&timezone=browser&refresh=5s&var-model=";
-const VLLM_BASE = "https://metrics.swissai.svc.cscs.ch/d/vllm-master-v2/vllm-monitoring-v2?orgId=1&from=now-15m&to=now&timezone=browser&refresh=5s&var-model_name=";
+const METRICS_BASE = "https://metrics.swissai.svc.cscs.ch/d/inference-unified/inference-monitoring-vllm-2b-sglang?orgId=1&from=now-15m&to=now&timezone=browser&var-datasource=PBFA97CFB590B2093&refresh=30s&var-model_name=";
-type Engine = "sglang" | "vllm";
+export type HostingTier = "L2" | "slurm";
-const modelEngines: Record = {
- "swiss-ai/Apertus-8B-Instruct-2509": "sglang",
- "zai-org/GLM-4.7-Flash": "sglang",
- "Snowflake/snowflake-arctic-embed-l-v2.0": "vllm",
- "cais/HarmBench-Llama-2-13b-cls": "vllm",
- "meta-llama/Llama-3.3-70B-Instruct": "sglang",
- "meta-llama/Llama-Guard-4-12B": "vllm",
- "swiss-ai/Apertus-70B-Instruct-2509": "vllm",
- "Qwen/Qwen3.5-27B": "vllm",
+type ModelConfig = {
+ metrics?: boolean;
+ tier?: HostingTier;
+};
+
+const models: Record = {
+ "swiss-ai/Apertus-8B-Instruct-2509": { tier: "L2" },
+ "zai-org/GLM-4.7-Flash": { tier: "L2" },
+ "Snowflake/snowflake-arctic-embed-l-v2.0": { tier: "L2" },
+ "cais/HarmBench-Llama-2-13b-cls": { tier: "L2" },
+ "meta-llama/Llama-3.3-70B-Instruct": { tier: "L2" },
+ "meta-llama/Llama-Guard-4-12B": { tier: "L2" },
+ "swiss-ai/Apertus-70B-Instruct-2509": { tier: "L2" },
+ "Qwen/Qwen3.5-27B": { tier: "L2" },
};
-/**
- * Get the metrics dashboard URL for a model, or null if none exists
- */
export function getModelMetricsUrl(modelName: string): string | null {
- const engine = modelEngines[modelName];
- if (!engine) return null;
+ if (models[modelName]?.metrics === false) return null;
+ return `${METRICS_BASE}${encodeURIComponent(modelName)}`;
+}
- const encoded = encodeURIComponent(modelName);
- return engine === "sglang"
- ? `${SGLANG_BASE}${encoded}`
- : `${VLLM_BASE}${encoded}`;
+export function getModelTier(modelName: string): HostingTier {
+ return models[modelName]?.tier ?? "slurm";
}