+
+
+
+
+
+
+ setDescription(e.target.value)}
+ variant="medium"
+ fullWidth
+ placeholder="Brief model description"
+ />
+
+
+
+
+
+
+
{/* Pricing tiers */}
diff --git a/apps/webapp/app/routes/admin.llm-models._index.tsx b/apps/webapp/app/routes/admin.llm-models._index.tsx
index fb2f6fdc491..ea2eff72541 100644
--- a/apps/webapp/app/routes/admin.llm-models._index.tsx
+++ b/apps/webapp/app/routes/admin.llm-models._index.tsx
@@ -20,7 +20,7 @@ import {
import { prisma } from "~/db.server";
import { requireUserId } from "~/services/session.server";
import { createSearchParams } from "~/utils/searchParams";
-import { seedLlmPricing } from "@internal/llm-pricing";
+import { seedLlmPricing, syncLlmCatalog } from "@internal/llm-model-catalog";
import { llmPricingRegistry } from "~/v3/llmPricingRegistry.server";
const PAGE_SIZE = 50;
@@ -87,12 +87,24 @@ export async function action({ request }: ActionFunctionArgs) {
if (_action === "seed") {
console.log("[admin] seed action started");
const result = await seedLlmPricing(prisma);
- console.log(`[admin] seed complete: ${result.modelsCreated} created, ${result.modelsSkipped} skipped`);
+ console.log(`[admin] seed complete: ${result.modelsCreated} created, ${result.modelsSkipped} skipped, ${result.modelsUpdated} updated`);
await llmPricingRegistry?.reload();
console.log("[admin] registry reloaded after seed");
return typedjson({
success: true,
- message: `Seeded: ${result.modelsCreated} created, ${result.modelsSkipped} skipped`,
+ message: `Seeded: ${result.modelsCreated} created, ${result.modelsSkipped} skipped, ${result.modelsUpdated} updated`,
+ });
+ }
+
+ if (_action === "sync") {
+ console.log("[admin] sync catalog action started");
+ const result = await syncLlmCatalog(prisma);
+ console.log(`[admin] sync complete: ${result.modelsUpdated} updated, ${result.modelsSkipped} skipped`);
+ await llmPricingRegistry?.reload();
+ console.log("[admin] registry reloaded after sync");
+ return typedjson({
+ success: true,
+ message: `Synced: ${result.modelsUpdated} updated, ${result.modelsSkipped} skipped`,
});
}
@@ -138,6 +150,7 @@ export default function AdminLlmModelsRoute() {
const { models, filters, page, pageCount, total } =
useTypedLoaderData();
const seedFetcher = useFetcher();
+ const syncFetcher = useFetcher();
const reloadFetcher = useFetcher();
const testFetcher = useFetcher<{
testResult?: {
@@ -179,6 +192,17 @@ export default function AdminLlmModelsRoute() {
+
+
+
+
+
+ {/* Catalog metadata */}
+
+
+
+
+
+
+
+ setDescription(e.target.value)}
+ variant="medium"
+ fullWidth
+ placeholder="Brief model description"
+ />
+
+
+
+
+
+
+
{/* Pricing tiers */}