diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..7deb951bd601 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "privacy-filter"] + path = privacy-filter + url = https://github.com/funkpopo/privacy-filter.git + branch = main diff --git a/Dockerfile b/Dockerfile index e2788f55b2bd..6e4ee5c0a73a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,23 @@ FROM oven/bun:1@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS builder +ARG NPM_REGISTRY=https://registry.npmmirror.com + WORKDIR /build/web COPY web/package.json web/bun.lock ./ COPY web/default/package.json ./default/package.json COPY web/classic/package.json ./classic/package.json -RUN bun install --frozen-lockfile +RUN bun install --frozen-lockfile --registry "$NPM_REGISTRY" COPY ./web/default ./default COPY ./VERSION /build/VERSION -RUN cd default && DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(cat /build/VERSION) bun run build +RUN cd default && \ + rm -rf dist node_modules/.cache .rsbuild .rspack-cache && \ + DISABLE_ESLINT_PLUGIN='true' VITE_REACT_APP_VERSION=$(cat /build/VERSION) bun run build && \ + find dist/static/js -maxdepth 1 -type f -name 'index.*.js' -print FROM oven/bun:1@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS builder-classic +ARG NPM_REGISTRY=https://registry.npmmirror.com + WORKDIR /build/web COPY web/package.json web/bun.lock ./ COPY web/default/package.json ./default/package.json @@ -18,10 +25,15 @@ COPY web/classic/package.json ./classic/package.json RUN bun install --filter ./classic --frozen-lockfile COPY ./web/classic ./classic COPY ./VERSION /build/VERSION -RUN cd classic && VITE_REACT_APP_VERSION=$(cat /build/VERSION) bun run build +RUN cd classic && \ + rm -rf dist node_modules/.cache .rsbuild .rspack-cache && \ + VITE_REACT_APP_VERSION=$(cat /build/VERSION) bun run build FROM golang:1.26.1-alpine@sha256:2389ebfa5b7f43eeafbd6be0c3700cc46690ef842ad962f6c5bd6be49ed82039 AS builder2 ENV GO111MODULE=on CGO_ENABLED=0 +ARG GOPROXY=https://goproxy.cn,direct +ARG GOSUMDB=sum.golang.google.cn +ENV GOPROXY=${GOPROXY} GOSUMDB=${GOSUMDB} ARG TARGETOS ARG TARGETARCH @@ -34,13 +46,25 @@ ADD go.mod go.sum ./ RUN go mod download COPY . . +RUN rm -rf ./web/default/dist ./web/classic/dist COPY --from=builder /build/web/default/dist ./web/default/dist COPY --from=builder-classic /build/web/classic/dist ./web/classic/dist RUN go build -ldflags "-s -w -X 'github.com/QuantumNous/new-api/common.Version=$(cat VERSION)'" -o new-api FROM debian:bookworm-slim@sha256:f06537653ac770703bc45b4b113475bd402f451e85223f0f2837acbf89ab020a -RUN apt-get update \ +ARG APT_MIRROR=http://mirrors.tuna.tsinghua.edu.cn/debian +ARG APT_SECURITY_MIRROR=http://mirrors.tuna.tsinghua.edu.cn/debian-security + +RUN set -eux; \ + files="$(find /etc/apt -type f \( -name '*.sources' -o -name 'sources.list' \))"; \ + sed -i \ + -e "s#http://deb.debian.org/debian-security#${APT_SECURITY_MIRROR}#g" \ + -e "s#http://security.debian.org/debian-security#${APT_SECURITY_MIRROR}#g" \ + -e "s#http://deb.debian.org/debian#${APT_MIRROR}#g" \ + -e "s#http://security.debian.org/debian#${APT_MIRROR}#g" \ + $files; \ + apt-get update \ && apt-get install -y --no-install-recommends ca-certificates tzdata libasan8 wget \ && rm -rf /var/lib/apt/lists/* \ && update-ca-certificates diff --git a/docker-compose.yml b/docker-compose.yml index afaf82d75d11..126848a9fee2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ version: '3.4' # For compatibility with older Docker versions services: new-api: - image: calciumion/new-api:latest + image: funpp/new-api-privacy:latest container_name: new-api restart: always command: --log-dir /app/logs diff --git a/go.mod b/go.mod index 93914b8589f0..cb7bb601a344 100644 --- a/go.mod +++ b/go.mod @@ -153,7 +153,7 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/arch v0.21.0 // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - google.golang.org/protobuf v1.36.5 // indirect + google.golang.org/protobuf v1.36.11 // indirect modernc.org/libc v1.66.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect diff --git a/go.sum b/go.sum index 2b55853ae713..752e05271131 100644 --- a/go.sum +++ b/go.sum @@ -628,8 +628,6 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= -github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Calcium-Ion/go-epay v0.0.4 h1:C96M7WfRLadcIVscWzwLiYs8etI1wrDmtFMuK2zP22A= github.com/Calcium-Ion/go-epay v0.0.4/go.mod h1:cxo/ZOg8ClvE3VAnCmEzbuyAZINSq7kFEN9oHj5WQ2U= @@ -2966,8 +2964,8 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/web/default/src/features/system-settings/billing/section-registry.tsx b/web/default/src/features/system-settings/billing/section-registry.tsx index 1a1dc8a2f6c7..7d1cdbe829bd 100644 --- a/web/default/src/features/system-settings/billing/section-registry.tsx +++ b/web/default/src/features/system-settings/billing/section-registry.tsx @@ -109,7 +109,7 @@ const BILLING_SECTIONS = [ modelDefaults={getModelDefaults(settings)} groupDefaults={getGroupDefaults(settings)} toolPricesDefault={settings['tool_price_setting.prices']} - visibleTabs={['models', 'tool-prices', 'upstream-sync']} + visibleTabs={['models', 'unpriced-models', 'tool-prices', 'upstream-sync']} /> ), }, diff --git a/web/default/src/features/system-settings/models/model-ratio-form.tsx b/web/default/src/features/system-settings/models/model-ratio-form.tsx index 9a9c345d2ce7..3b1110f390de 100644 --- a/web/default/src/features/system-settings/models/model-ratio-form.tsx +++ b/web/default/src/features/system-settings/models/model-ratio-form.tsx @@ -203,17 +203,15 @@ export const ModelRatioForm = memo(function ModelRatioForm({ {t('Reset prices')} - {editMode === 'json' && ( - - )} + + + + ) +} diff --git a/web/default/src/features/system-settings/models/unpriced-models-editor.tsx b/web/default/src/features/system-settings/models/unpriced-models-editor.tsx new file mode 100644 index 000000000000..4580a011a7e0 --- /dev/null +++ b/web/default/src/features/system-settings/models/unpriced-models-editor.tsx @@ -0,0 +1,340 @@ +/* +Copyright (C) 2023-2026 QuantumNous + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +For commercial licensing, please contact support@quantumnous.com +*/ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { useQuery, useQueryClient } from '@tanstack/react-query' +import { useMediaQuery } from '@/hooks' +import { Edit, Info, Search } from 'lucide-react' +import { useTranslation } from 'react-i18next' +import { toast } from 'sonner' +import { api } from '@/lib/api' +import { Alert, AlertDescription } from '@/components/ui/alert' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Skeleton } from '@/components/ui/skeleton' +import { hasValue } from './model-pricing-core' +import { + ModelPricingEditorPanel, + type ModelPricingEditorPanelHandle, + ModelPricingSheet, + type ModelRatioData, +} from './model-pricing-sheet' +import { UnpricedModelCard } from './unpriced-model-card' +import { useUpdateModelRatios } from './use-update-model-ratios' + +type UnpricedModelsEditorProps = { + modelRatios: Record +} + +type EnabledModel = { + name: string +} + +async function fetchEnabledModels(): Promise { + const res = await api.get<{ + success: boolean + message?: string + data?: string[] + }>('/api/channel/models_enabled') + const response = res.data + + if (!response.success) { + throw new Error(response.message || 'Failed to fetch enabled models') + } + + return (response.data || []).map((name) => ({ name })) +} + +function parseRatioOption(value: string): Record { + if (!value || value.trim() === '') return {} + try { + const parsed = JSON.parse(value) + return parsed && typeof parsed === 'object' ? parsed : {} + } catch { + return {} + } +} + +export function UnpricedModelsEditor({ + modelRatios, +}: UnpricedModelsEditorProps) { + const { t } = useTranslation() + const queryClient = useQueryClient() + const isMobile = useMediaQuery('(max-width: 767px)') + const [searchQuery, setSearchQuery] = useState('') + const [selectedModel, setSelectedModel] = useState( + null + ) + const [sheetOpen, setSheetOpen] = useState(false) + const editorRef = useRef(null) + + const { + data: enabledModels = [], + isLoading, + error, + } = useQuery({ + queryKey: ['enabled-models'], + queryFn: fetchEnabledModels, + staleTime: 30_000, + retry: 2, + }) + + useEffect(() => { + if (error) { + console.error('Failed to load enabled models:', error) + toast.error(t('Failed to load enabled models')) + } + }, [error, t]) + + const parsedRatios = useMemo(() => { + return { + ModelPrice: parseRatioOption(modelRatios.ModelPrice || '{}'), + ModelRatio: parseRatioOption(modelRatios.ModelRatio || '{}'), + CompletionRatio: parseRatioOption(modelRatios.CompletionRatio || '{}'), + CacheRatio: parseRatioOption(modelRatios.CacheRatio || '{}'), + CreateCacheRatio: parseRatioOption(modelRatios.CreateCacheRatio || '{}'), + ImageRatio: parseRatioOption(modelRatios.ImageRatio || '{}'), + AudioRatio: parseRatioOption(modelRatios.AudioRatio || '{}'), + AudioCompletionRatio: parseRatioOption( + modelRatios.AudioCompletionRatio || '{}' + ), + BillingMode: parseRatioOption( + modelRatios['billing_setting.billing_mode'] || '{}' + ), + BillingExpr: parseRatioOption( + modelRatios['billing_setting.billing_expr'] || '{}' + ), + } + }, [modelRatios]) + + // 过滤未定价的模型:在已启用列表中 && 未设置价格 + const unpricedModels = useMemo(() => { + return enabledModels.filter((model) => { + const modelName = model.name + const fixedPrice = parsedRatios.ModelPrice[modelName] + const inputPrice = parsedRatios.ModelRatio[modelName] + const billingMode = parsedRatios.BillingMode[modelName] + + // 表达式计费的模型被视为已定价 + if (billingMode === 'tiered_expr') { + return false + } + + // 模型既没有固定价格也没有基础倍率时为未定价 + return !hasValue(fixedPrice) && !hasValue(inputPrice) + }) + }, [enabledModels, parsedRatios]) + + const filteredModels = useMemo(() => { + if (!searchQuery.trim()) return unpricedModels + + const query = searchQuery.toLowerCase().trim() + return unpricedModels.filter((model) => + model.name.toLowerCase().includes(query) + ) + }, [unpricedModels, searchQuery]) + + const handleSearchChange = useCallback((value: string) => { + setSearchQuery(value) + setSelectedModel(null) + setSheetOpen(false) + }, []) + + const handleEditModel = useCallback( + (modelName: string) => { + const editData: ModelRatioData = { + name: modelName, + billingMode: 'per-token', + price: '', + ratio: '', + cacheRatio: '', + createCacheRatio: '', + completionRatio: '', + imageRatio: '', + audioRatio: '', + audioCompletionRatio: '', + } + + setSelectedModel(editData) + if (isMobile) { + setSheetOpen(true) + } + }, + [isMobile] + ) + + const { mutateAsync: updateModelRatios, isPending: isUpdatingModelRatios } = + useUpdateModelRatios() + + const handleSave = useCallback(async () => { + const draft = await editorRef.current?.commitDraft() + if (!draft) return + + await updateModelRatios(draft) + + setSheetOpen(false) + setSelectedModel(null) + await queryClient.invalidateQueries({ queryKey: ['system-options'] }) + toast.success(t('Model pricing saved successfully')) + }, [queryClient, t, updateModelRatios]) + + useEffect(() => { + if (!sheetOpen) { + setSelectedModel(null) + } + }, [sheetOpen]) + + if (isLoading) { + return ( +
+ +
+
+ +
+ {Array.from({ length: 8 }).map((_, i) => ( + + ))} +
+
+ +
+
+ ) + } + + return ( + <> +
+ + + + {t( + 'This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.' + )} + + + +
+ + +
+ {selectedModel ? ( + + ) : ( +
+
+ {t('Select a model to edit pricing')} +
+

+ {t( + "Update model configuration and click save when you're done." + )} +

+ {filteredModels.length > 0 && ( + + )} +
+ )} +
+
+
+ + {isMobile && ( + + )} + + ) +} diff --git a/web/default/src/features/system-settings/models/use-update-model-ratios.ts b/web/default/src/features/system-settings/models/use-update-model-ratios.ts new file mode 100644 index 000000000000..09247807e52a --- /dev/null +++ b/web/default/src/features/system-settings/models/use-update-model-ratios.ts @@ -0,0 +1,222 @@ +/* +Copyright (C) 2023-2026 QuantumNous + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +For commercial licensing, please contact support@quantumnous.com +*/ +import { useMutation, useQueryClient } from '@tanstack/react-query' +import { api } from '@/lib/api' +import type { ModelRatioData } from './model-pricing-core' + +export function useUpdateModelRatios() { + const queryClient = useQueryClient() + + return useMutation({ + mutationFn: async (data: ModelRatioData) => { + const parseRatioOption = (value: string) => { + if (!value || value.trim() === '') return {} + try { + const parsed = JSON.parse(value) + return parsed && typeof parsed === 'object' ? parsed : {} + } catch { + return {} + } + } + + const getCurrentOptions = async () => { + const res = await api.get<{ + success: boolean + message?: string + data?: Array<{ key: string; value: string }> + }>('/api/option/') + const response = res.data + + if (!response.success) { + throw new Error(response.message || 'Failed to fetch current options') + } + + const optionsMap: Record = {} + response.data?.forEach((opt) => { + optionsMap[opt.key] = opt.value + }) + return optionsMap + } + + const currentOptions = await getCurrentOptions() + + const updates: Array<{ key: string; value: string }> = [] + + // Parse current JSON settings + const currentModelPrice = parseRatioOption(currentOptions.ModelPrice || '{}') + const currentModelRatio = parseRatioOption(currentOptions.ModelRatio || '{}') + const currentCompletionRatio = parseRatioOption( + currentOptions.CompletionRatio || '{}' + ) + const currentCacheRatio = parseRatioOption(currentOptions.CacheRatio || '{}') + const currentCreateCacheRatio = parseRatioOption( + currentOptions.CreateCacheRatio || '{}' + ) + const currentImageRatio = parseRatioOption(currentOptions.ImageRatio || '{}') + const currentAudioRatio = parseRatioOption(currentOptions.AudioRatio || '{}') + const currentAudioCompletionRatio = parseRatioOption( + currentOptions.AudioCompletionRatio || '{}' + ) + const currentBillingMode = parseRatioOption( + currentOptions['billing_setting.billing_mode'] || '{}' + ) + const currentBillingExpr = parseRatioOption( + currentOptions['billing_setting.billing_expr'] || '{}' + ) + + const hasValue = (value: unknown) => + value !== '' && value !== null && value !== undefined && value !== false + + const toNumberOrString = (value?: string) => { + if (!hasValue(value)) return null + const num = Number(value) + return Number.isFinite(num) ? num : null + } + + const modelName = data.name + + // Update billing mode + if (data.billingMode === 'tiered_expr') { + currentBillingMode[modelName] = 'tiered_expr' + currentBillingExpr[modelName] = data.billingExpr || '' + // Clear token-based pricing + delete currentModelPrice[modelName] + delete currentModelRatio[modelName] + delete currentCompletionRatio[modelName] + delete currentCacheRatio[modelName] + delete currentCreateCacheRatio[modelName] + delete currentImageRatio[modelName] + delete currentAudioRatio[modelName] + delete currentAudioCompletionRatio[modelName] + } else if (data.billingMode === 'per-request') { + // Fixed price per request + delete currentBillingMode[modelName] + delete currentBillingExpr[modelName] + + const priceValue = toNumberOrString(data.price) + if (hasValue(priceValue)) { + currentModelPrice[modelName] = priceValue + } else { + delete currentModelPrice[modelName] + } + + // Clear token-based ratios + delete currentModelRatio[modelName] + delete currentCompletionRatio[modelName] + delete currentCacheRatio[modelName] + delete currentCreateCacheRatio[modelName] + delete currentImageRatio[modelName] + delete currentAudioRatio[modelName] + delete currentAudioCompletionRatio[modelName] + } else { + // Per-token pricing + delete currentBillingMode[modelName] + delete currentBillingExpr[modelName] + delete currentModelPrice[modelName] + + const ratioValue = toNumberOrString(data.ratio) + if (hasValue(ratioValue)) { + currentModelRatio[modelName] = ratioValue + } else { + delete currentModelRatio[modelName] + } + + const completionValue = toNumberOrString(data.completionRatio) + if (hasValue(completionValue)) { + currentCompletionRatio[modelName] = completionValue + } else { + delete currentCompletionRatio[modelName] + } + + const cacheValue = toNumberOrString(data.cacheRatio) + if (hasValue(cacheValue)) { + currentCacheRatio[modelName] = cacheValue + } else { + delete currentCacheRatio[modelName] + } + + const createCacheValue = toNumberOrString(data.createCacheRatio) + if (hasValue(createCacheValue)) { + currentCreateCacheRatio[modelName] = createCacheValue + } else { + delete currentCreateCacheRatio[modelName] + } + + const imageValue = toNumberOrString(data.imageRatio) + if (hasValue(imageValue)) { + currentImageRatio[modelName] = imageValue + } else { + delete currentImageRatio[modelName] + } + + const audioValue = toNumberOrString(data.audioRatio) + if (hasValue(audioValue)) { + currentAudioRatio[modelName] = audioValue + } else { + delete currentAudioRatio[modelName] + } + + const audioCompletionValue = toNumberOrString(data.audioCompletionRatio) + if (hasValue(audioCompletionValue)) { + currentAudioCompletionRatio[modelName] = audioCompletionValue + } else { + delete currentAudioCompletionRatio[modelName] + } + } + + // Prepare updates + updates.push( + { key: 'ModelPrice', value: JSON.stringify(currentModelPrice) }, + { key: 'ModelRatio', value: JSON.stringify(currentModelRatio) }, + { key: 'CompletionRatio', value: JSON.stringify(currentCompletionRatio) }, + { key: 'CacheRatio', value: JSON.stringify(currentCacheRatio) }, + { key: 'CreateCacheRatio', value: JSON.stringify(currentCreateCacheRatio) }, + { key: 'ImageRatio', value: JSON.stringify(currentImageRatio) }, + { key: 'AudioRatio', value: JSON.stringify(currentAudioRatio) }, + { + key: 'AudioCompletionRatio', + value: JSON.stringify(currentAudioCompletionRatio), + }, + { + key: 'billing_setting.billing_mode', + value: JSON.stringify(currentBillingMode), + }, + { + key: 'billing_setting.billing_expr', + value: JSON.stringify(currentBillingExpr), + } + ) + + // Send all updates + for (const update of updates) { + const res = await api.put('/api/option/', update) + const response = res.data + if (!response.success) { + throw new Error(response.message || 'Failed to update option') + } + } + + return { success: true } + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['system-options'] }) + queryClient.invalidateQueries({ queryKey: ['enabled-models'] }) + }, + }) +} diff --git a/web/default/src/i18n/locales/en.json b/web/default/src/i18n/locales/en.json index d00f2c188e23..5c9b5625477f 100644 --- a/web/default/src/i18n/locales/en.json +++ b/web/default/src/i18n/locales/en.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "{{count}} incidents in the last 30 days", "{{count}} IP(s)": "{{count}} IP(s)", "{{count}} log entries removed.": "{{count}} log entries removed.", + "{{count}} matching models": "{{count}} matching models", "{{count}} minutes ago": "{{count}} minutes ago", "{{count}} models": "{{count}} models", "{{count}} months ago": "{{count}} months ago", @@ -272,6 +273,7 @@ "All categories": "All categories", "All conditions must match before this tier is used.": "All conditions must match before this tier is used.", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "All edits are overwrite operations. Leave fields empty to keep current values unchanged.", + "All enabled models have been priced": "All enabled models have been priced", "All files exceed the maximum size.": "All files exceed the maximum size.", "All Groups": "All Groups", "All Models": "All Models", @@ -907,6 +909,7 @@ "Configuration required": "Configuration required", "Configure": "Configure", "Configure a Creem product for user recharge options.": "Configure a Creem product for user recharge options.", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.", "Configure a custom ratio for when users use a specific token group.": "Configure a custom ratio for when users use a specific token group.", "Configure a group that users can select when creating API keys.": "Configure a group that users can select when creating API keys.", "Configure a new custom OAuth provider for user authentication.": "Configure a new custom OAuth provider for user authentication.", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "Failed to enable tag channels", "Failed to fetch channel key": "Failed to fetch channel key", "Failed to fetch checkin status": "Failed to fetch check-in status", + "Failed to fetch current options": "Failed to fetch current options", "Failed to fetch deployment details": "Failed to fetch deployment details", "Failed to fetch models": "Failed to fetch models", "Failed to fetch OIDC configuration. Please check the URL and network status": "Failed to fetch OIDC configuration. Please check the URL and network status", @@ -1762,6 +1766,7 @@ "Failed to load": "Failed to load", "Failed to load API keys": "Failed to load API keys", "Failed to load billing history": "Failed to load billing history", + "Failed to load enabled models": "Failed to load enabled models", "Failed to load home page content": "Failed to load home page content", "Failed to load image": "Failed to load image", "Failed to load key status": "Failed to load key status", @@ -1784,6 +1789,7 @@ "Failed to register Passkey": "Failed to register Passkey", "Failed to remove Passkey": "Failed to remove Passkey", "Failed to reset 2FA": "Failed to reset 2FA", + "Failed to load enabled models": "Failed to load enabled models", "Failed to reset model ratios": "Failed to reset model ratios", "Failed to reset Passkey": "Failed to reset Passkey", "Failed to reset usage": "Failed to reset usage", @@ -1818,6 +1824,7 @@ "Failed to update balance": "Failed to update balance", "Failed to update channel": "Failed to update channel", "Failed to update models": "Failed to update models", + "Failed to update option": "Failed to update option", "Failed to update profile": "Failed to update profile", "Failed to update provider": "Failed to update provider", "Failed to update redemption code": "Failed to update redemption code", @@ -2515,6 +2522,7 @@ "model": "model", "Model": "Model", "Model {{model}}": "Model {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "Model {{name}} removed. Click Save to apply changes.", "Model Access": "Model Access", "Model Analytics": "Model Analytics", "Model Analytics Defaults": "Model Analytics Defaults", @@ -2541,6 +2549,7 @@ "Model mapping must be valid JSON": "Model mapping must be valid JSON", "Model mapping must be valid JSON format": "Model mapping must be valid JSON format", "Model mapping values must be strings": "Model mapping values must be strings", + "Model {{name}} removed. Click Save to apply changes.": "Model {{name}} removed. Click Save to apply changes.", "Model name": "Model name", "Model Name": "Model Name", "Model Name *": "Model Name *", @@ -2554,6 +2563,7 @@ "Model prices": "Model prices", "Model prices reset successfully": "Model prices reset successfully", "Model Pricing": "Model Pricing", + "Model pricing saved successfully": "Model pricing saved successfully", "Model pull failed: {{msg}}": "Model pull failed: {{msg}}", "Model ratio": "Model ratio", "Model ratios": "Model ratios", @@ -2763,6 +2773,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "No mappings configured. Click \"Add Row\" to get started.", "No matches found": "No matches found", "No matching items": "No matching items", + "No matching models": "No matching models", "No matching results": "No matching results", "No matching rules": "No matching rules", "No matching token and channel usage was found.": "No matching token and channel usage was found.", @@ -2835,6 +2846,7 @@ "No system tasks yet.": "No system tasks yet.", "No token found.": "No token found.", "No tools configured": "No tools configured", + "No unpriced models": "No unpriced models", "No Upgrade": "No Upgrade", "No upstream price differences found": "No upstream price differences found", "No upstream ratio differences found": "No upstream ratio differences found", @@ -3299,6 +3311,7 @@ "Price estimation description": "After completing the hardware type, deployment location, replica count, etc., the price will be automatically calculated.", "Price ID": "Price ID", "Price mode (USD per 1M tokens)": "Price mode (USD per 1M tokens)", + "Price not set": "Price not set", "Price summary": "Price summary", "price_xxx": "price_xxx", "Price:": "Price:", @@ -3915,6 +3928,7 @@ "Set filters to customize your dashboard statistics and charts.": "Set filters to customize your dashboard statistics and charts.", "Set filters to narrow down your log search results.": "Set filters to narrow down your log search results.", "Set Header": "Set Header", + "Set price": "Set price", "Set Project to io.cloud when creating/selecting key": "Set Project to io.cloud when creating/selecting key", "Set quota amount and limits": "Set quota amount and limits", "Set Request Header": "Set Request Header", @@ -4296,6 +4310,7 @@ "This model is not available in any group, or no group pricing information is configured.": "This model is not available in any group, or no group pricing information is configured.", "This month": "This month", "This page has not been created yet.": "This page has not been created yet.", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.", "This plan does not allow balance redemption": "This plan does not allow balance redemption", "This project must be used in compliance with the": "This project must be used in compliance with the", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.", @@ -4468,6 +4483,7 @@ "Truncate embeddings to this many dimensions": "Truncate embeddings to this many dimensions", "Trusted": "Trusted", "Try adjusting your search": "Try adjusting your search", + "Try adjusting your search query": "Try adjusting your search query", "Try adjusting your search to locate a missing model.": "Try adjusting your search to locate a missing model.", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4536,7 @@ "Unknown version": "Unknown version", "Unlimited": "Unlimited", "Unlimited Quota": "Unlimited Quota", + "Unpriced models": "Unpriced models", "Unsaved changes": "Unsaved changes", "Unset price": "Unset price", "Until": "Until", @@ -4582,9 +4599,18 @@ "Upstream Model Update Check": "Upstream Model Update Check", "Upstream Model Updates": "Upstream Model Updates", "Upstream model updates applied: {{added}} added, {{removed}} removed, {{ignored}} ignored this time, {{totalIgnored}} total ignored models": "Upstream model updates applied: {{added}} added, {{removed}} removed, {{ignored}} ignored this time, {{totalIgnored}} total ignored models", - "Upstream path": "Upstream path", - "Upstream path is required": "Upstream path is required", - "Upstream path must be a full URL or a path starting with /": "Upstream path must be a full URL or a path starting with /", + "All enabled models have been priced": "All enabled models have been priced", + "Model pricing saved successfully": "Model pricing saved successfully", + "No matching models": "No matching models", + "No unpriced models": "No unpriced models", + "Price not set": "Price not set", + "Search model name...": "Search model name...", + "Set price": "Set price", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.", + "Try adjusting your search query": "Try adjusting your search query", + "Unpriced models": "Unpriced models", + "{{count}} matching models": "{{count}} matching models", + "{{count}} unpriced models": "{{count}} unpriced models", "Upstream price sync": "Upstream price sync", "Upstream prices fetched successfully": "Upstream prices fetched successfully", "Upstream ratios fetched successfully": "Upstream ratios fetched successfully", diff --git a/web/default/src/i18n/locales/fr.json b/web/default/src/i18n/locales/fr.json index eac7e5c6b883..09e41d0e04d8 100644 --- a/web/default/src/i18n/locales/fr.json +++ b/web/default/src/i18n/locales/fr.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "{{count}} incidents au cours des 30 derniers jours", "{{count}} IP(s)": "{{count}} IP", "{{count}} log entries removed.": "{{count}} entrées de journal supprimées.", + "{{count}} matching models": "{{count}} modèles correspondants", "{{count}} minutes ago": "il y a {{count}} minutes", "{{count}} models": "{{count}} modèles", "{{count}} months ago": "il y a {{count}} mois", @@ -272,6 +273,7 @@ "All categories": "Toutes catégories", "All conditions must match before this tier is used.": "Toutes les conditions doivent correspondre avant que ce palier soit utilisé.", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Toutes les modifications sont des opérations d'écrasement. Laissez les champs vides pour conserver les valeurs actuelles inchangées.", + "All enabled models have been priced": "Tous les modèles activés ont un prix", "All files exceed the maximum size.": "Tous les fichiers dépassent la taille maximale.", "All Groups": "Tous les groupes", "All Models": "Tous les modèles", @@ -907,6 +909,7 @@ "Configuration required": "Configuration requise", "Configure": "Configurer", "Configure a Creem product for user recharge options.": "Configurez un produit Creem pour les options de recharge utilisateur.", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "Configurez un ratio personnalisé pour les utilisateurs « {{userGroup}} » lorsqu’ils utilisent un groupe de jetons spécifique.", "Configure a custom ratio for when users use a specific token group.": "Configurer un ratio personnalisé lorsque les utilisateurs utilisent un groupe de jetons spécifique.", "Configure a group that users can select when creating API keys.": "Configurer un groupe que les utilisateurs peuvent sélectionner lors de la création de clés API.", "Configure a new custom OAuth provider for user authentication.": "Configurer un nouveau fournisseur OAuth personnalisé pour l'authentification des utilisateurs.", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "Échec de l'activation des canaux de tags", "Failed to fetch channel key": "Échec de la récupération de la clé du canal", "Failed to fetch checkin status": "Échec de la récupération du statut d'enregistrement", + "Failed to fetch current options": "Échec de la récupération des options actuelles", "Failed to fetch deployment details": "Impossible de récupérer les détails du déploiement", "Failed to fetch models": "Échec de la récupération des modèles", "Failed to fetch OIDC configuration. Please check the URL and network status": "Échec de la récupération de la configuration OIDC. Veuillez vérifier l'URL et le statut du réseau", @@ -1762,6 +1766,7 @@ "Failed to load": "Échec du chargement", "Failed to load API keys": "Échec du chargement des Clés API", "Failed to load billing history": "Échec du chargement de l'historique de facturation", + "Failed to load enabled models": "Échec du chargement des modèles activés", "Failed to load home page content": "Échec du chargement du contenu de la page d'accueil", "Failed to load image": "Échec du chargement de l'image", "Failed to load key status": "Échec du chargement du statut des clés", @@ -1818,6 +1823,7 @@ "Failed to update balance": "Échec de la mise à jour du solde", "Failed to update channel": "Échec de la mise à jour du canal", "Failed to update models": "Échec de la mise à jour des modèles", + "Failed to update option": "Échec de la mise à jour de l'option", "Failed to update profile": "Échec de la mise à jour du profil", "Failed to update provider": "Échec de la mise à jour du fournisseur", "Failed to update redemption code": "Échec de la mise à jour du code de rachat", @@ -2515,6 +2521,7 @@ "model": "modèle", "Model": "Modèle", "Model {{model}}": "Modèle {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "Modèle {{name}} supprimé. Cliquez sur Enregistrer pour appliquer les modifications.", "Model Access": "Accès au modèle", "Model Analytics": "Analyse des modèles", "Model Analytics Defaults": "Paramètres par défaut de l’analyse des modèles", @@ -2554,6 +2561,7 @@ "Model prices": "Prix des modèles", "Model prices reset successfully": "Prix des modèles réinitialisés avec succès", "Model Pricing": "Tarification des modèles", + "Model pricing saved successfully": "Tarification du modèle enregistrée", "Model pull failed: {{msg}}": "Échec du téléchargement du modèle : {{msg}}", "Model ratio": "Ratio modèle", "Model ratios": "Ratios de modèle", @@ -2763,6 +2771,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "Aucun mappage configuré. Cliquez sur « Ajouter une ligne » pour commencer.", "No matches found": "Aucune correspondance trouvée", "No matching items": "Aucun élément correspondant", + "No matching models": "Aucun modèle correspondant", "No matching results": "Aucun résultat correspondant", "No matching rules": "Aucune règle correspondante", "No matching token and channel usage was found.": "Aucune utilisation correspondante par jeton et canal n'a été trouvée.", @@ -2835,6 +2844,7 @@ "No system tasks yet.": "Aucune tâche système pour le moment.", "No token found.": "Aucun jeton trouvé.", "No tools configured": "Aucun outil configuré", + "No unpriced models": "Aucun modèle sans prix", "No Upgrade": "Pas de mise à niveau", "No upstream price differences found": "Aucune différence de prix amont trouvée", "No upstream ratio differences found": "Aucune différence de ratio amont trouvée", @@ -3299,6 +3309,7 @@ "Price estimation description": "Après avoir configuré le type de matériel, l'emplacement de déploiement, le nombre de réplicas, etc., le prix sera calculé automatiquement.", "Price ID": "ID du prix", "Price mode (USD per 1M tokens)": "Mode de tarification (USD par 1M de jetons)", + "Price not set": "Prix non défini", "Price summary": "Résumé des prix", "price_xxx": "price_xxx", "Price:": "Prix :", @@ -3915,6 +3926,7 @@ "Set filters to customize your dashboard statistics and charts.": "Définir des filtres pour personnaliser les statistiques et les graphiques de votre tableau de bord.", "Set filters to narrow down your log search results.": "Définir des filtres pour affiner vos résultats de recherche de journaux.", "Set Header": "Définir l'en-tête", + "Set price": "Définir le prix", "Set Project to io.cloud when creating/selecting key": "Définir le projet sur io.cloud lors de la création/sélection de la clé", "Set quota amount and limits": "Définir le quota et les limites", "Set Request Header": "Définir un en-tête de requête", @@ -4296,6 +4308,7 @@ "This model is not available in any group, or no group pricing information is configured.": "Ce modèle n'est disponible dans aucun groupe, ou aucune information de tarification de groupe n'est configurée.", "This month": "Ce mois-ci", "This page has not been created yet.": "Cette page n'a pas encore été créée.", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "Cette page affiche uniquement les modèles sans prix de base. Après l’enregistrement, les modèles configurés seront automatiquement retirés de cette liste.", "This plan does not allow balance redemption": "Ce forfait ne permet pas le paiement avec le solde", "This project must be used in compliance with the": "Ce projet doit être utilisé conformément aux", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Cet enregistrement provient d’une instance avant la mise à niveau et n’inclut pas d’audits. Mettez à jour l’instance pour enregistrer l’IP du serveur, l’IP de callback, le moyen de paiement et la version du système.", @@ -4468,6 +4481,7 @@ "Truncate embeddings to this many dimensions": "Tronquer les vecteurs à autant de dimensions", "Trusted": "Fiable", "Try adjusting your search": "Essayez d'ajuster votre recherche", + "Try adjusting your search query": "Essayez de modifier votre recherche", "Try adjusting your search to locate a missing model.": "Essayez d'ajuster votre recherche pour localiser un modèle manquant.", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4534,7 @@ "Unknown version": "Version inconnue", "Unlimited": "Illimité", "Unlimited Quota": "Quota illimité", + "Unpriced models": "Modèles sans prix", "Unsaved changes": "Modifications non enregistrées", "Unset price": "Prix non défini", "Until": "Jusqu'au", @@ -4537,7 +4552,7 @@ "Update configuration": "Mettre à jour la configuration", "Update failed": "Échec de la mise à jour", "Update Model": "Mettre à jour le modèle", - "Update model configuration and click save when you're done.": "Mettez à jour la configuration du modèle et cliquez sur Enregistrer lorsque vous avez terminé.", + "Update model configuration and click save when you're done.": "Mettez à jour la configuration du modèle, puis cliquez sur Enregistrer.", "Update plan info": "Mettre à jour les informations du plan", "Update Provider": "Mettre à jour le fournisseur", "Update Redemption Code": "Mettre à jour le code d'échange", diff --git a/web/default/src/i18n/locales/ja.json b/web/default/src/i18n/locales/ja.json index 00b5621e030b..f503681949ee 100644 --- a/web/default/src/i18n/locales/ja.json +++ b/web/default/src/i18n/locales/ja.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "過去 30 日間で {{count}} 件のインシデント", "{{count}} IP(s)": "{{count}} IP", "{{count}} log entries removed.": "{{count}} 件のログエントリを削除しました。", + "{{count}} matching models": "{{count}} 件の一致するモデル", "{{count}} minutes ago": "{{count}} 分前", "{{count}} models": "{{count}} モデル", "{{count}} months ago": "{{count}} ヶ月前", @@ -272,6 +273,7 @@ "All categories": "すべてのカテゴリ", "All conditions must match before this tier is used.": "この段階を使用するには、すべての条件に一致する必要があります。", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "すべての編集は上書き操作です。現在の値を変更しないままにするには、フィールドを空のままにしてください。", + "All enabled models have been priced": "有効なモデルはすべて価格設定済みです", "All files exceed the maximum size.": "すべてのファイルが最大サイズを超えています。", "All Groups": "すべてのグループ", "All Models": "すべてのモデル", @@ -907,6 +909,7 @@ "Configuration required": "設定が必要です", "Configure": "設定", "Configure a Creem product for user recharge options.": "ユーザー チャージオプション用の Creem 製品を設定。", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "「{{userGroup}}」ユーザーが特定のトークングループを使用する場合のカスタム倍率を設定します。", "Configure a custom ratio for when users use a specific token group.": "ユーザーが特定のトークングループを使用する際のカスタム倍率を設定します。", "Configure a group that users can select when creating API keys.": "ユーザーがAPIキー作成時に選択できるグループを設定します。", "Configure a new custom OAuth provider for user authentication.": "ユーザー認証のための新しいカスタムOAuthプロバイダーを設定します。", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "タグチャネルの有効化に失敗しました", "Failed to fetch channel key": "チャネルキーの取得に失敗しました", "Failed to fetch checkin status": "チェックインステータスの取得に失敗しました", + "Failed to fetch current options": "現在のオプションの取得に失敗しました", "Failed to fetch deployment details": "デプロイメント詳細の取得に失敗しました", "Failed to fetch models": "モデルの取得に失敗しました", "Failed to fetch OIDC configuration. Please check the URL and network status": "OIDC構成の取得に失敗しました。URLとネットワーク状態を確認してください", @@ -1762,6 +1766,7 @@ "Failed to load": "読み込みに失敗しました", "Failed to load API keys": "APIキーの読み込みに失敗しました", "Failed to load billing history": "請求履歴の読み込みに失敗しました", + "Failed to load enabled models": "有効なモデルの読み込みに失敗しました", "Failed to load home page content": "ホームページの内容の読み込みに失敗しました", "Failed to load image": "画像の読み込みに失敗しました", "Failed to load key status": "キー状態の読み込みに失敗しました", @@ -1818,6 +1823,7 @@ "Failed to update balance": "残高を更新できませんでした", "Failed to update channel": "チャネルの更新に失敗しました", "Failed to update models": "モデルの更新に失敗しました", + "Failed to update option": "オプションの更新に失敗しました", "Failed to update profile": "プロフィールを更新できませんでした", "Failed to update provider": "プロバイダーの更新に失敗しました", "Failed to update redemption code": "引き換えコードの更新に失敗しました", @@ -2515,6 +2521,7 @@ "model": "モデル", "Model": "モデル", "Model {{model}}": "モデル {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "モデル {{name}} を削除しました。変更を適用するには保存をクリックしてください。", "Model Access": "モデルアクセス", "Model Analytics": "モデル分析", "Model Analytics Defaults": "モデル分析のデフォルト設定", @@ -2554,6 +2561,7 @@ "Model prices": "モデル価格", "Model prices reset successfully": "モデル価格が正常にリセットされました", "Model Pricing": "モデル料金", + "Model pricing saved successfully": "モデル価格を保存しました", "Model pull failed: {{msg}}": "モデルのプルに失敗しました: __ PH_0 __", "Model ratio": "モデル倍率", "Model ratios": "モデル比率", @@ -2763,6 +2771,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "マッピングが設定されていません。「行を追加」をクリックして開始してください。", "No matches found": "一致するものが見つかりません", "No matching items": "一致する項目がありません", + "No matching models": "一致するモデルはありません", "No matching results": "一致する結果がありません", "No matching rules": "一致するルールがありません", "No matching token and channel usage was found.": "一致するトークンとチャネルの使用量が見つかりませんでした。", @@ -2835,6 +2844,7 @@ "No system tasks yet.": "システムタスクはまだありません。", "No token found.": "トークンが見つかりません。", "No tools configured": "ツールが未設定です", + "No unpriced models": "未価格設定のモデルはありません", "No Upgrade": "アップグレードなし", "No upstream price differences found": "上流価格の差異は見つかりませんでした", "No upstream ratio differences found": "アップストリームの比率の差は見つかりません", @@ -3299,6 +3309,7 @@ "Price estimation description": "ハードウェアタイプ、デプロイ場所、レプリカ数などを設定すると、料金が自動的に計算されます。", "Price ID": "価格 ID", "Price mode (USD per 1M tokens)": "価格モード (100万トークンあたりのUSD)", + "Price not set": "価格未設定", "Price summary": "価格概要", "price_xxx": "price_xxx", "Price:": "価格:", @@ -3915,6 +3926,7 @@ "Set filters to customize your dashboard statistics and charts.": "ダッシュボードの統計とグラフをカスタマイズするためにフィルターを設定します。", "Set filters to narrow down your log search results.": "ログ検索結果を絞り込むためにフィルターを設定します。", "Set Header": "ヘッダーを設定", + "Set price": "価格を設定", "Set Project to io.cloud when creating/selecting key": "キーを作成/選択する際にプロジェクトを io.cloud に設定", "Set quota amount and limits": "クォータ量と制限を設定", "Set Request Header": "リクエストヘッダーを設定", @@ -4296,6 +4308,7 @@ "This model is not available in any group, or no group pricing information is configured.": "このモデルはどのグループでも利用できないか、グループの料金情報が設定されていません。", "This month": "今月", "This page has not been created yet.": "このページはまだ作成されていません。", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "このページには基本価格が未設定のモデルのみが表示されます。保存後、設定済みのモデルは自動的に一覧から削除されます。", "This plan does not allow balance redemption": "このプランでは残高での交換は許可されていません", "This project must be used in compliance with the": "このプロジェクトは、以下を遵守して使用する必要があります", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "古いバージョンのインスタンスがこの記録を書き込み、監査情報がありません。最新に更新し、サーバーIP・コールバックIP・支払方法・OSバージョンの記録を有効にしてください。", @@ -4468,6 +4481,7 @@ "Truncate embeddings to this many dimensions": "指定した次元数にベクトルを切り詰めます", "Trusted": "信頼済み", "Try adjusting your search": "検索条件を調整してみてください", + "Try adjusting your search query": "検索条件を調整してください", "Try adjusting your search to locate a missing model.": "見つからないモデルを見つけるには、検索を調整してみてください。", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4534,7 @@ "Unknown version": "不明なバージョン", "Unlimited": "無制限", "Unlimited Quota": "無制限のクォータ", + "Unpriced models": "未価格設定モデル", "Unsaved changes": "未保存の変更", "Unset price": "価格未設定", "Until": "まで", diff --git a/web/default/src/i18n/locales/ru.json b/web/default/src/i18n/locales/ru.json index e6339350c9a7..86a8908f797d 100644 --- a/web/default/src/i18n/locales/ru.json +++ b/web/default/src/i18n/locales/ru.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "{{count}} инцидентов за последние 30 дней", "{{count}} IP(s)": "{{count}} IP", "{{count}} log entries removed.": "Удалено {{count}} записей журнала.", + "{{count}} matching models": "{{count}} подходящих моделей", "{{count}} minutes ago": "{{count}} минут назад", "{{count}} models": "моделей: {{count}}", "{{count}} months ago": "{{count}} месяцев назад", @@ -272,6 +273,7 @@ "All categories": "Все категории", "All conditions must match before this tier is used.": "Все условия должны совпасть, прежде чем будет использован этот уровень.", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Все изменения являются операциями перезаписи. Оставьте поля пустыми, чтобы сохранить текущие значения без изменений.", + "All enabled models have been priced": "Для всех включенных моделей задана цена", "All files exceed the maximum size.": "Все файлы превышают максимальный размер.", "All Groups": "Все группы", "All Models": "Все модели", @@ -907,6 +909,7 @@ "Configuration required": "Требуется настройка", "Configure": "Настройка", "Configure a Creem product for user recharge options.": "Настройте продукт Creem для опций пополнения пользователя.", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "Настройте пользовательский коэффициент для пользователей «{{userGroup}}» при использовании определенной группы токенов.", "Configure a custom ratio for when users use a specific token group.": "Настроить пользовательский коэффициент при использовании определённой группы токенов.", "Configure a group that users can select when creating API keys.": "Настройте группу, которую пользователи могут выбрать при создании ключей API.", "Configure a new custom OAuth provider for user authentication.": "Настройка нового пользовательского OAuth-провайдера для аутентификации пользователей.", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "Не удалось включить каналы тегов", "Failed to fetch channel key": "Не удалось получить ключ канала", "Failed to fetch checkin status": "Не удалось получить статус регистрации", + "Failed to fetch current options": "Не удалось получить текущие параметры", "Failed to fetch deployment details": "Не удалось получить сведения о развертывании", "Failed to fetch models": "Не удалось получить модели", "Failed to fetch OIDC configuration. Please check the URL and network status": "Не удалось получить конфигурацию OIDC. Проверьте URL и состояние сети", @@ -1762,6 +1766,7 @@ "Failed to load": "Не удалось загрузить", "Failed to load API keys": "Не удалось загрузить API ключи", "Failed to load billing history": "Не удалось загрузить историю платежей", + "Failed to load enabled models": "Не удалось загрузить включенные модели", "Failed to load home page content": "Не удалось загрузить содержимое главной страницы", "Failed to load image": "Не удалось загрузить изображение", "Failed to load key status": "Не удалось загрузить статус ключей", @@ -1818,6 +1823,7 @@ "Failed to update balance": "Не удалось обновить баланс", "Failed to update channel": "Не удалось обновить канал", "Failed to update models": "Не удалось обновить модели", + "Failed to update option": "Не удалось обновить параметр", "Failed to update profile": "Не удалось обновить профиль", "Failed to update provider": "Не удалось обновить поставщика", "Failed to update redemption code": "Не удалось обновить код активации", @@ -2515,6 +2521,7 @@ "model": "модель", "Model": "Модель", "Model {{model}}": "Модель {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "Модель {{name}} удалена. Нажмите «Сохранить», чтобы применить изменения.", "Model Access": "Доступ к моделям", "Model Analytics": "Аналитика моделей", "Model Analytics Defaults": "Настройки аналитики моделей по умолчанию", @@ -2554,6 +2561,7 @@ "Model prices": "Цены моделей", "Model prices reset successfully": "Цены моделей успешно сброшены", "Model Pricing": "Тарификация моделей", + "Model pricing saved successfully": "Цены модели успешно сохранены", "Model pull failed: {{msg}}": "Ошибка тяги модели: {{msg}}", "Model ratio": "Коэффициент модели", "Model ratios": "Коэффициенты модели", @@ -2763,6 +2771,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "Нет настроенных сопоставлений. Нажмите \"Добавить строку\", чтобы начать.", "No matches found": "Совпадений не найдено", "No matching items": "Нет подходящих элементов", + "No matching models": "Подходящие модели не найдены", "No matching results": "Нет совпадений", "No matching rules": "Нет совпадающих правил", "No matching token and channel usage was found.": "Подходящее использование токенов и каналов не найдено.", @@ -2835,6 +2844,7 @@ "No system tasks yet.": "Пока нет системных задач.", "No token found.": "Токен не найден.", "No tools configured": "Нет настроенных инструментов", + "No unpriced models": "Нет моделей без цены", "No Upgrade": "Без повышения", "No upstream price differences found": "Различий в ценах провайдера не найдено", "No upstream ratio differences found": "Различия в коэффициентах вышестоящего потока не найдены", @@ -3299,6 +3309,7 @@ "Price estimation description": "После настройки типа оборудования, места размещения, количества реплик и т.д. стоимость будет рассчитана автоматически.", "Price ID": "ID цены", "Price mode (USD per 1M tokens)": "Режим ценообразования (USD за 1 млн токенов)", + "Price not set": "Цена не задана", "Price summary": "Сводка цен", "price_xxx": "price_xxx", "Price:": "Цена:", @@ -3915,6 +3926,7 @@ "Set filters to customize your dashboard statistics and charts.": "Установите фильтры, чтобы настроить статистику и диаграммы вашей панели управления.", "Set filters to narrow down your log search results.": "Установите фильтры, чтобы сузить результаты поиска по журналам.", "Set Header": "Установить заголовок", + "Set price": "Задать цену", "Set Project to io.cloud when creating/selecting key": "Установите Проект в io.cloud при создании/выборе ключа", "Set quota amount and limits": "Настройте квоту и лимиты", "Set Request Header": "Установить заголовок запроса", @@ -4296,6 +4308,7 @@ "This model is not available in any group, or no group pricing information is configured.": "Эта модель недоступна ни в одной группе, или информация о ценах для групп не настроена.", "This month": "В этом месяце", "This page has not been created yet.": "Эта страница еще не создана.", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "На этой странице показаны только модели без базовой цены. После сохранения настроенные модели будут автоматически удалены из списка.", "This plan does not allow balance redemption": "Этот план не разрешает оплату балансом", "This project must be used in compliance with the": "Этот проект должен использоваться в соответствии с", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Запись создана экземпляром до обновления и не содержит сведений аудита. Обновите экземпляр, чтобы фиксировать IP сервера, IP callback, способ оплаты и версию ОС.", @@ -4468,6 +4481,7 @@ "Truncate embeddings to this many dimensions": "Усечь эмбеддинги до указанного числа измерений", "Trusted": "Доверенный", "Try adjusting your search": "Попробуйте изменить условия поиска", + "Try adjusting your search query": "Попробуйте изменить поисковый запрос", "Try adjusting your search to locate a missing model.": "Попробуйте изменить параметры поиска, чтобы найти отсутствующую модель.", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4534,7 @@ "Unknown version": "Неизвестная версия", "Unlimited": "Без ограничений", "Unlimited Quota": "Неограниченная квота", + "Unpriced models": "Модели без цены", "Unsaved changes": "Несохранённые изменения", "Unset price": "Цена не задана", "Until": "До", @@ -4537,7 +4552,7 @@ "Update configuration": "Обновить конфигурацию", "Update failed": "Обновление не удалось", "Update Model": "Обновить модель", - "Update model configuration and click save when you're done.": "Обновите конфигурацию модели и нажмите сохранить, когда закончите.", + "Update model configuration and click save when you're done.": "Обновите конфигурацию модели и нажмите «Сохранить», когда закончите.", "Update plan info": "Обновить информацию о плане", "Update Provider": "Обновить поставщика", "Update Redemption Code": "Обновить код активации", diff --git a/web/default/src/i18n/locales/vi.json b/web/default/src/i18n/locales/vi.json index 915cbf2dac43..0fd9db971364 100644 --- a/web/default/src/i18n/locales/vi.json +++ b/web/default/src/i18n/locales/vi.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "{{count}} sự cố trong 30 ngày qua", "{{count}} IP(s)": "{{count}} IP", "{{count}} log entries removed.": "Đã xóa {{count}} mục nhật ký.", + "{{count}} matching models": "{{count}} mô hình khớp", "{{count}} minutes ago": "{{count}} phút trước", "{{count}} models": "{{count}} mô hình", "{{count}} months ago": "{{count}} tháng trước", @@ -272,6 +273,7 @@ "All categories": "Tất cả danh mục", "All conditions must match before this tier is used.": "Tất cả điều kiện phải khớp trước khi tầng này được sử dụng.", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "Tất cả các chỉnh sửa đều là thao tác ghi đè. Để trống các trường để giữ nguyên giá trị hiện tại.", + "All enabled models have been priced": "Tất cả mô hình đã bật đều đã có giá", "All files exceed the maximum size.": "Tất cả các tệp vượt quá kích thước tối đa.", "All Groups": "Tất cả các nhóm", "All Models": "Tất cả các mẫu", @@ -907,6 +909,7 @@ "Configuration required": "Cần cấu hình", "Configure": "Cấu hình", "Configure a Creem product for user recharge options.": "Cấu hình một sản phẩm Creem cho các tùy chọn nạp tiền người dùng.", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "Cấu hình tỷ lệ tùy chỉnh cho người dùng “{{userGroup}}” khi sử dụng một nhóm token cụ thể.", "Configure a custom ratio for when users use a specific token group.": "Cấu hình tỷ lệ tùy chỉnh khi người dùng sử dụng nhóm token cụ thể.", "Configure a group that users can select when creating API keys.": "Cấu hình một nhóm mà người dùng có thể chọn khi tạo khóa API.", "Configure a new custom OAuth provider for user authentication.": "Cấu hình nhà cung cấp OAuth tùy chỉnh mới để xác thực người dùng.", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "Không thể kích hoạt kênh thẻ", "Failed to fetch channel key": "Không thể lấy khóa kênh", "Failed to fetch checkin status": "Không thể tải trạng thái điểm danh", + "Failed to fetch current options": "Không thể lấy các tùy chọn hiện tại", "Failed to fetch deployment details": "Không thể lấy chi tiết triển khai", "Failed to fetch models": "Không thể lấy các mô hình", "Failed to fetch OIDC configuration. Please check the URL and network status": "Không thể lấy cấu hình OIDC. Vui lòng kiểm tra URL và trạng thái mạng", @@ -1762,6 +1766,7 @@ "Failed to load": "Tải thất bại", "Failed to load API keys": "Không thể tải khóa API", "Failed to load billing history": "Không thể tải lịch sử thanh toán", + "Failed to load enabled models": "Không thể tải các mô hình đã bật", "Failed to load home page content": "Không thể tải nội dung trang chủ", "Failed to load image": "Không thể tải ảnh", "Failed to load key status": "Không thể tải trạng thái khóa", @@ -1818,6 +1823,7 @@ "Failed to update balance": "Không thể cập nhật số dư", "Failed to update channel": "Cập nhật kênh không thành công", "Failed to update models": "Không thể cập nhật mô hình", + "Failed to update option": "Không thể cập nhật tùy chọn", "Failed to update profile": "Không thể cập nhật hồ sơ", "Failed to update provider": "Cập nhật nhà cung cấp thất bại", "Failed to update redemption code": "Không thể cập nhật mã đổi thưởng", @@ -2515,6 +2521,7 @@ "model": "mô hình", "Model": "Mô hình", "Model {{model}}": "Mô hình {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "Đã xóa mô hình {{name}}. Nhấn Lưu để áp dụng thay đổi.", "Model Access": "Truy cập mô hình", "Model Analytics": "Phân tích mô hình", "Model Analytics Defaults": "Mặc định phân tích mô hình", @@ -2554,6 +2561,7 @@ "Model prices": "Giá mô hình", "Model prices reset successfully": "Đã đặt lại giá mô hình thành công", "Model Pricing": "Định giá mô hình", + "Model pricing saved successfully": "Đã lưu giá mô hình", "Model pull failed: {{msg}}": "Tải mô hình thất bại: {{msg}}", "Model ratio": "Tỷ lệ mô hình", "Model ratios": "Tỷ lệ mô hình", @@ -2763,6 +2771,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "Chưa có ánh xạ nào được cấu hình. Nhấp vào \"Thêm hàng\" để bắt đầu.", "No matches found": "Không tìm thấy kết quả nào", "No matching items": "Không có mục phù hợp", + "No matching models": "Không có mô hình khớp", "No matching results": "Không có kết quả phù hợp", "No matching rules": "Không có quy tắc phù hợp", "No matching token and channel usage was found.": "Không tìm thấy mức sử dụng token và kênh phù hợp.", @@ -2835,6 +2844,7 @@ "No system tasks yet.": "Chưa có tác vụ hệ thống nào.", "No token found.": "Không tìm thấy mã thông báo.", "No tools configured": "Chưa cấu hình công cụ nào", + "No unpriced models": "Không có mô hình chưa có giá", "No Upgrade": "Không nâng cấp", "No upstream price differences found": "Không tìm thấy sự khác biệt về giá upstream", "No upstream ratio differences found": "Không tìm thấy chênh lệch tỷ lệ thượng nguồn", @@ -3299,6 +3309,7 @@ "Price estimation description": "Sau khi hoàn thành loại phần cứng, vị trí triển khai, số lượng bản sao, v.v., giá sẽ được tính toán tự động.", "Price ID": "Mã giá", "Price mode (USD per 1M tokens)": "Chế độ giá (USD mỗi 1 triệu token)", + "Price not set": "Chưa đặt giá", "Price summary": "Tóm tắt giá", "price_xxx": "price_xxx", "Price:": "Giá:", @@ -3915,6 +3926,7 @@ "Set filters to customize your dashboard statistics and charts.": "Đặt bộ lọc để tùy chỉnh số liệu thống kê và biểu đồ trên bảng điều khiển của bạn.", "Set filters to narrow down your log search results.": "Đặt bộ lọc để thu hẹp kết quả tìm kiếm nhật ký của bạn.", "Set Header": "Đặt tiêu đề", + "Set price": "Đặt giá", "Set Project to io.cloud when creating/selecting key": "Đặt Dự án thành io.cloud khi tạo/chọn khóa", "Set quota amount and limits": "Thiết lập hạn mức và giới hạn", "Set Request Header": "Đặt header yêu cầu", @@ -4296,6 +4308,7 @@ "This model is not available in any group, or no group pricing information is configured.": "Mô hình này không khả dụng trong bất kỳ nhóm nào, hoặc thông tin giá nhóm chưa được cấu hình.", "This month": "Tháng này", "This page has not been created yet.": "Trang này chưa được tạo.", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "Trang này chỉ hiển thị các mô hình chưa có giá cơ bản. Sau khi lưu, các mô hình đã cấu hình sẽ tự động bị xóa khỏi danh sách này.", "This plan does not allow balance redemption": "Gói này không cho phép thanh toán bằng số dư", "This project must be used in compliance with the": "Dự án này phải được sử dụng tuân thủ theo", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "Bản ghi này do bản cũ tạo và thiếu thông tin audit. Nâng cấp bản cài để lưu IP máy chủ, IP callback, hình thức thanh toán và phiên bản hệ thống.", @@ -4468,6 +4481,7 @@ "Truncate embeddings to this many dimensions": "Cắt embedding xuống số chiều này", "Trusted": "Đáng tin cậy", "Try adjusting your search": "Hãy thử điều chỉnh tìm kiếm", + "Try adjusting your search query": "Hãy thử điều chỉnh truy vấn tìm kiếm", "Try adjusting your search to locate a missing model.": "Hãy thử điều chỉnh tìm kiếm của bạn để định vị một mô hình bị thiếu.", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4534,7 @@ "Unknown version": "Phiên bản không xác định", "Unlimited": "Không giới hạn", "Unlimited Quota": "Hạn mức không giới hạn", + "Unpriced models": "Mô hình chưa có giá", "Unsaved changes": "Thay đổi chưa được lưu", "Unset price": "Chưa đặt giá", "Until": "Cho đến", @@ -4537,7 +4552,7 @@ "Update configuration": "Cập nhật cấu hình", "Update failed": "Cập nhật thất bại", "Update Model": "Cập nhật mô hình", - "Update model configuration and click save when you're done.": "Cập nhật cấu hình mô hình và nhấp lưu khi bạn hoàn tất.", + "Update model configuration and click save when you're done.": "Cập nhật cấu hình mô hình và bấm lưu khi hoàn tất.", "Update plan info": "Cập nhật thông tin gói", "Update Provider": "Cập nhật Nhà cung cấp", "Update Redemption Code": "Cập nhật mã đổi thưởng", diff --git a/web/default/src/i18n/locales/zh.json b/web/default/src/i18n/locales/zh.json index 8405a8b24aeb..0b33e4f82635 100644 --- a/web/default/src/i18n/locales/zh.json +++ b/web/default/src/i18n/locales/zh.json @@ -41,6 +41,7 @@ "{{count}} incidents in the last 30 days": "最近 30 天 {{count}} 起事件", "{{count}} IP(s)": "{{count}} 个 IP", "{{count}} log entries removed.": "已删除 {{count}} 条日志。", + "{{count}} matching models": "{{count}} 个匹配模型", "{{count}} minutes ago": "{{count}} 分钟前", "{{count}} models": "{{count}} 个模型", "{{count}} months ago": "{{count}} 个月前", @@ -272,6 +273,7 @@ "All categories": "全部分类", "All conditions must match before this tier is used.": "所有条件都匹配后才会使用此阶梯。", "All edits are overwrite operations. Leave fields empty to keep current values unchanged.": "所有编辑都是覆盖操作。留空字段将保持当前值不变。", + "All enabled models have been priced": "所有已启用模型都已设置价格", "All files exceed the maximum size.": "所有文件都超过最大尺寸。", "All Groups": "所有分组", "All Models": "所有模型", @@ -907,6 +909,7 @@ "Configuration required": "需要配置", "Configure": "配置", "Configure a Creem product for user recharge options.": "为用户充值选项配置 Creem 产品。", + "Configure a custom ratio for \"{{userGroup}}\" users when using a specific token group.": "为“{{userGroup}}”用户使用特定令牌分组时配置自定义倍率。", "Configure a custom ratio for when users use a specific token group.": "配置用户使用特定令牌分组时的自定义倍率。", "Configure a group that users can select when creating API keys.": "配置用户在创建 API 密钥时可以选择的分组。", "Configure a new custom OAuth provider for user authentication.": "配置新的自定义OAuth提供商用于用户认证。", @@ -1747,6 +1750,7 @@ "Failed to enable tag channels": "启用标签渠道失败", "Failed to fetch channel key": "获取渠道密钥失败", "Failed to fetch checkin status": "获取签到状态失败", + "Failed to fetch current options": "获取当前选项失败", "Failed to fetch deployment details": "获取部署详情失败", "Failed to fetch models": "获取模型失败", "Failed to fetch OIDC configuration. Please check the URL and network status": "获取 OIDC 配置失败。请检查 URL 和网络状态", @@ -1762,8 +1766,10 @@ "Failed to load": "加载失败", "Failed to load API keys": "加载 API 密钥失败", "Failed to load billing history": "加载计费历史失败", + "Failed to load enabled models": "加载已启用模型失败", "Failed to load home page content": "加载首页内容失败", "Failed to load image": "无法加载图像", + "Failed to load enabled models": "加载已启用模型失败", "Failed to load key status": "加载密钥状态失败", "Failed to load logs": "加载日志失败", "Failed to load Passkey status": "加载 Passkey 状态失败", @@ -1818,6 +1824,7 @@ "Failed to update balance": "无法更新余额", "Failed to update channel": "更新渠道失败", "Failed to update models": "更新模型失败", + "Failed to update option": "更新选项失败", "Failed to update profile": "无法更新个人资料", "Failed to update provider": "更新提供商失败", "Failed to update redemption code": "更新兑换码失败", @@ -2515,6 +2522,7 @@ "model": "模型", "Model": "模型", "Model {{model}}": "模型 {{model}}", + "Model {{name}} removed. Click Save to apply changes.": "模型 {{name}} 已移除。点击保存以应用更改。", "Model Access": "模型访问", "Model Analytics": "模型数据分析", "Model Analytics Defaults": "模型分析默认设置", @@ -2541,6 +2549,7 @@ "Model mapping must be valid JSON": "模型映射必须是有效的 JSON", "Model mapping must be valid JSON format": "模型映射必须是有效的 JSON 格式", "Model mapping values must be strings": "模型映射的值必须是字符串", + "Model {{name}} removed. Click Save to apply changes.": "模型 {{name}} 已移除。点击保存以应用更改。", "Model name": "模型名称", "Model Name": "模型名称", "Model Name *": "模型名称 *", @@ -2554,6 +2563,7 @@ "Model prices": "模型价格", "Model prices reset successfully": "模型价格重置成功", "Model Pricing": "模型定价", + "Model pricing saved successfully": "模型定价保存成功", "Model pull failed: {{msg}}": "模型拉取失败:{{msg}}", "Model ratio": "模型倍率", "Model ratios": "模型比例", @@ -2763,6 +2773,7 @@ "No mappings configured. Click \"Add Row\" to get started.": "未配置映射。点击 \"添加行\" 开始。", "No matches found": "未找到匹配项", "No matching items": "没有匹配项", + "No matching models": "没有匹配的模型", "No matching results": "无匹配结果", "No matching rules": "没有匹配的规则", "No matching token and channel usage was found.": "未找到匹配的令牌与渠道用量。", @@ -2835,6 +2846,7 @@ "No system tasks yet.": "暂无系统任务。", "No token found.": "未找到令牌。", "No tools configured": "未配置工具", + "No unpriced models": "没有未定价模型", "No Upgrade": "不升级", "No upstream price differences found": "未发现上游价格差异", "No upstream ratio differences found": "未找到上游比例差异", @@ -3299,6 +3311,7 @@ "Price estimation description": "完成硬件类型、部署位置、副本数量等设置后,价格将自动计算。", "Price ID": "价格 ID", "Price mode (USD per 1M tokens)": "价格模式(每 100 万个 token 的美元价格)", + "Price not set": "未设置价格", "Price summary": "价格摘要", "price_xxx": "price_xxx", "Price:": "价格:", @@ -3915,6 +3928,7 @@ "Set filters to customize your dashboard statistics and charts.": "设置筛选器以自定义您的仪表板统计数据和图表。", "Set filters to narrow down your log search results.": "设置筛选器以缩小日志搜索结果范围。", "Set Header": "设请求头", + "Set price": "设置价格", "Set Project to io.cloud when creating/selecting key": "创建/选择密钥时将项目设置为 io.cloud", "Set quota amount and limits": "设置令牌可用额度和数量", "Set Request Header": "设置请求头", @@ -4296,6 +4310,7 @@ "This model is not available in any group, or no group pricing information is configured.": "此模型在任何分组中均不可用,或未配置分组定价信息。", "This month": "本月获得", "This page has not been created yet.": "此页面尚未创建。", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "此页面仅显示未配置基础价格的模型。保存后,已配置价格的模型会自动从列表中移除。", "This plan does not allow balance redemption": "该套餐不允许使用余额兑换", "This project must be used in compliance with the": "此项目的使用必须遵守", "This record was written by a pre-upgrade instance and lacks audit info. Upgrade the instance to record server IP, callback IP, payment method and system version.": "该记录由旧版本实例写入,缺少审计信息,建议将实例升级至最新版本以便记录服务器 IP、回调 IP、支付方式与系统版本等审计字段。", @@ -4468,6 +4483,7 @@ "Truncate embeddings to this many dimensions": "将向量截断到指定维度", "Trusted": "受信任", "Try adjusting your search": "请尝试调整搜索条件", + "Try adjusting your search query": "请尝试调整搜索条件", "Try adjusting your search to locate a missing model.": "尝试调整您的搜索以找到缺失的模型。", "TTFT P50": "TTFT P50", "TTFT P95": "TTFT P95", @@ -4520,6 +4536,7 @@ "Unknown version": "未知版本", "Unlimited": "无限制", "Unlimited Quota": "无限配额", + "Unpriced models": "未定价模型", "Unsaved changes": "未保存的更改", "Unset price": "未设置价格", "Until": "至", @@ -4582,9 +4599,18 @@ "Upstream Model Update Check": "上游模型更新检查", "Upstream Model Updates": "上游模型更新", "Upstream model updates applied: {{added}} added, {{removed}} removed, {{ignored}} ignored this time, {{totalIgnored}} total ignored models": "已处理上游模型更新:加入 {{added}} 个,删除 {{removed}} 个,本次忽略 {{ignored}} 个,当前已忽略模型 {{totalIgnored}} 个", - "Upstream path": "上游路径", - "Upstream path is required": "上游路径不能为空", - "Upstream path must be a full URL or a path starting with /": "上游路径必须是完整 URL,或以 / 开头的路径", + "All enabled models have been priced": "所有已启用的模型都已定价", + "Model pricing saved successfully": "模型定价保存成功", + "No matching models": "没有匹配的模型", + "No unpriced models": "没有未定价的模型", + "Price not set": "未设置价格", + "Search model name...": "搜索模型名称...", + "Set price": "设置价格", + "This page only shows models without base pricing. After saving, configured models will be removed from this list automatically.": "此页面仅显示未设置价格或基础倍率的模型,设置后会自动从列表中移出。", + "Try adjusting your search query": "尝试调整搜索条件", + "Unpriced models": "未定价模型", + "{{count}} matching models": "{{count}} 个匹配的模型", + "{{count}} unpriced models": "{{count}} 个未定价模型", "Upstream price sync": "上游价格同步", "Upstream prices fetched successfully": "已成功获取上游价格", "Upstream ratios fetched successfully": "上游比率获取成功",