Improve LLM model cost unit handling and cache refresh

Adds explicit handling of the cost unit in LLM model creation and update actions, ensuring the unit is always set (defaulting to 'RUN'). Updates the EditModelModal to include a hidden cost_unit input. Refactors backend LLM runtime state refresh logic to improve error handling and logging for cache clearing operations.
This commit is contained in:
Bentlybro
2026-01-16 13:58:19 +00:00
parent 963b8090cc
commit e5c6809d9c
4 changed files with 41 additions and 31 deletions

View File

@@ -19,41 +19,45 @@ router = fastapi.APIRouter(
async def _refresh_runtime_state() -> None:
"""Refresh the LLM registry and clear all related caches to ensure real-time updates."""
logger.info("Refreshing LLM registry runtime state...")
# Refresh registry from database
await llm_registry.refresh_llm_registry()
refresh_llm_costs()
# Clear block schema caches so they're regenerated with updated model options
from backend.data.block import BlockSchema
BlockSchema.clear_all_schema_caches()
logger.info("Cleared all block schema caches")
# Clear the /blocks endpoint cache so frontend gets updated schemas
try:
from backend.api.features.v1 import _get_cached_blocks
# Refresh registry from database
await llm_registry.refresh_llm_registry()
refresh_llm_costs()
_get_cached_blocks.cache_clear()
logger.info("Cleared /blocks endpoint cache")
except Exception as e:
logger.warning("Failed to clear /blocks cache: %s", e)
# Clear block schema caches so they're regenerated with updated model options
from backend.data.block import BlockSchema
# Clear the v2 builder providers cache (if it exists)
try:
from backend.api.features.builder import db as builder_db
BlockSchema.clear_all_schema_caches()
logger.info("Cleared all block schema caches")
if hasattr(builder_db, "_get_all_providers"):
builder_db._get_all_providers.cache_clear()
logger.info("Cleared v2 builder providers cache")
except Exception as e:
logger.debug("Could not clear v2 builder cache: %s", e)
# Clear the /blocks endpoint cache so frontend gets updated schemas
try:
from backend.api.features.v1 import _get_cached_blocks
# Notify all executor services to refresh their registry cache
from backend.data.llm_registry import publish_registry_refresh_notification
_get_cached_blocks.cache_clear()
logger.info("Cleared /blocks endpoint cache")
except Exception as e:
logger.warning("Failed to clear /blocks cache: %s", e)
await publish_registry_refresh_notification()
logger.info("Published registry refresh notification")
# Clear the v2 builder providers cache (if it exists)
try:
from backend.api.features.builder import db as builder_db
if hasattr(builder_db, "_get_all_providers"):
builder_db._get_all_providers.cache_clear()
logger.info("Cleared v2 builder providers cache")
except Exception as e:
logger.debug("Could not clear v2 builder cache: %s", e)
# Notify all executor services to refresh their registry cache
from backend.data.llm_registry import publish_registry_refresh_notification
await publish_registry_refresh_notification()
logger.info("Published registry refresh notification")
except Exception as exc:
logger.exception(
"LLM runtime state refresh failed; caches may be stale: %s", exc
)
@router.get(

View File

@@ -202,7 +202,9 @@ def _refresh_cached_schema() -> None:
# Build new structures
new_options = _build_schema_options()
new_mapping = {slug: entry.metadata.provider for slug, entry in _dynamic_models.items()}
new_mapping = {
slug: entry.metadata.provider for slug, entry in _dynamic_models.items()
}
for slug, metadata in _static_metadata.items():
new_mapping.setdefault(slug, metadata.provider)

View File

@@ -32,6 +32,7 @@ import type { LlmMigrationsResponse } from "@/app/api/__generated__/models/llmMi
import type { LlmCreatorsResponse } from "@/app/api/__generated__/models/llmCreatorsResponse";
import type { UpsertLlmCreatorRequest } from "@/app/api/__generated__/models/upsertLlmCreatorRequest";
import type { LlmModelUsageResponse } from "@/app/api/__generated__/models/llmModelUsageResponse";
import { LlmCostUnit } from "@/app/api/__generated__/models/llmCostUnit";
const ADMIN_LLM_PATH = "/admin/llms";
@@ -121,6 +122,7 @@ export async function createLlmModelAction(formData: FormData) {
metadata: {},
costs: [
{
unit: (formData.get("cost_unit") as LlmCostUnit) || LlmCostUnit.RUN,
credit_cost: Number(formData.get("credit_cost") || 0),
credential_provider:
provider.default_credential_provider || provider.name,
@@ -165,6 +167,7 @@ export async function updateLlmModelAction(formData: FormData) {
costs: formData.get("credit_cost")
? [
{
unit: (formData.get("cost_unit") as LlmCostUnit) || LlmCostUnit.RUN,
credit_cost: Number(formData.get("credit_cost")),
credential_provider: String(
formData.get("credential_provider") || "",

View File

@@ -185,8 +185,9 @@ export function EditModelModal({
</span>
</label>
</div>
{/* Hidden defaults for credential_type */}
{/* Hidden defaults for credential_type and cost_unit */}
<input type="hidden" name="credential_type" value="api_key" />
<input type="hidden" name="cost_unit" value={cost?.unit ?? "RUN"} />
<Dialog.Footer>
<Button