mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-17 07:17:18 +00:00
feat(models): show LangBot Models pricing
This commit is contained in:
@@ -1,30 +1,30 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { LangBotModelAvailability } from '@/app/infra/entities/api';
|
||||
import type { LangBotModelAvailabilityItem } from '@/app/infra/entities/api';
|
||||
import { httpClient } from '@/app/infra/http/HttpClient';
|
||||
|
||||
const CACHE_TTL_MS = 60_000;
|
||||
|
||||
type AvailabilityMap = Record<string, LangBotModelAvailability>;
|
||||
type ModelMetadataMap = Record<string, LangBotModelAvailabilityItem>;
|
||||
|
||||
let cachedAvailability: AvailabilityMap | null = null;
|
||||
let cachedMetadata: ModelMetadataMap | null = null;
|
||||
let cacheExpiresAt = 0;
|
||||
let pendingRequest: Promise<AvailabilityMap> | null = null;
|
||||
let pendingRequest: Promise<ModelMetadataMap> | null = null;
|
||||
|
||||
async function loadAvailability(): Promise<AvailabilityMap> {
|
||||
if (cachedAvailability && Date.now() < cacheExpiresAt) {
|
||||
return cachedAvailability;
|
||||
async function loadMetadata(): Promise<ModelMetadataMap> {
|
||||
if (cachedMetadata && Date.now() < cacheExpiresAt) {
|
||||
return cachedMetadata;
|
||||
}
|
||||
if (pendingRequest) return pendingRequest;
|
||||
|
||||
pendingRequest = httpClient
|
||||
.getLangBotModelAvailability()
|
||||
.then((response) => {
|
||||
const next: AvailabilityMap = {};
|
||||
const next: ModelMetadataMap = {};
|
||||
for (const item of response.models) {
|
||||
next[item.uuid] = item.availability;
|
||||
next[item.model_id] = item.availability;
|
||||
next[item.uuid] = item;
|
||||
next[item.model_id] = item;
|
||||
}
|
||||
cachedAvailability = next;
|
||||
cachedMetadata = next;
|
||||
cacheExpiresAt = Date.now() + CACHE_TTL_MS;
|
||||
return next;
|
||||
})
|
||||
@@ -35,29 +35,29 @@ async function loadAvailability(): Promise<AvailabilityMap> {
|
||||
}
|
||||
|
||||
export function useLangBotModelAvailability(enabled = true) {
|
||||
const [availability, setAvailability] = useState<AvailabilityMap>(
|
||||
cachedAvailability ?? {},
|
||||
const [metadata, setMetadata] = useState<ModelMetadataMap>(
|
||||
cachedMetadata ?? {},
|
||||
);
|
||||
const [loaded, setLoaded] = useState(
|
||||
cachedAvailability !== null && Date.now() < cacheExpiresAt,
|
||||
cachedMetadata !== null && Date.now() < cacheExpiresAt,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
let active = true;
|
||||
loadAvailability()
|
||||
loadMetadata()
|
||||
.then((result) => {
|
||||
if (!active) return;
|
||||
setAvailability(result);
|
||||
setMetadata(result);
|
||||
setLoaded(true);
|
||||
})
|
||||
.catch(() => {
|
||||
// Availability is supplementary; model configuration remains usable.
|
||||
// Catalog metadata is supplementary; model configuration remains usable.
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [enabled]);
|
||||
|
||||
return { availability, loaded };
|
||||
return { metadata, loaded };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user