ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: суточные квоты Voice Tasker по workspace и контурам
This commit is contained in:
@@ -133,7 +133,9 @@ function getVoiceTaskErrorMessage(error: unknown, fallback: string) {
|
||||
const retryAfter = "retry_after" in error ? formatRetryAfter(error.retry_after) : "позже";
|
||||
const used = "used" in error && typeof error.used === "number" ? error.used : null;
|
||||
const limit = "limit" in error && typeof error.limit === "number" ? error.limit : null;
|
||||
const usageText = used !== null && limit !== null ? ` Использовано ${used} из ${limit} за последний час.` : "";
|
||||
const limitWindow = "limit_window" in error ? String(error.limit_window) : "hour";
|
||||
const windowText = limitWindow === "day" ? "за последние сутки" : "за последний час";
|
||||
const usageText = used !== null && limit !== null ? ` Использовано ${used} из ${limit} ${windowText}.` : "";
|
||||
|
||||
if (code === "voice_task_user_hourly_limit_exceeded") {
|
||||
return `Лимит Voice Tasker для пользователя исчерпан. Повторите ${retryAfter}.${usageText}`;
|
||||
@@ -143,6 +145,19 @@ function getVoiceTaskErrorMessage(error: unknown, fallback: string) {
|
||||
return `Лимит Voice Tasker для workspace исчерпан. Повторите ${retryAfter}.${usageText}`;
|
||||
}
|
||||
|
||||
if (code === "voice_task_user_daily_limit_exceeded") {
|
||||
return `Суточный лимит Voice Tasker для пользователя исчерпан. Повторите ${retryAfter}.${usageText}`;
|
||||
}
|
||||
|
||||
if (code === "voice_task_workspace_daily_limit_exceeded") {
|
||||
return `Суточный лимит Voice Tasker для workspace исчерпан. Повторите ${retryAfter}.${usageText}`;
|
||||
}
|
||||
|
||||
if (code === "voice_task_project_daily_limit_exceeded") {
|
||||
const projectName = "project_name" in error && error.project_name ? ` для контура ${String(error.project_name)}` : "";
|
||||
return `Суточный лимит Voice Tasker${projectName} исчерпан. Повторите ${retryAfter}.${usageText}`;
|
||||
}
|
||||
|
||||
if ("error" in error && error.error) return String(error.error);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ type TFormState = {
|
||||
max_audio_duration_seconds: number;
|
||||
per_user_hourly_limit: number;
|
||||
workspace_hourly_limit: number;
|
||||
per_user_daily_limit: number;
|
||||
workspace_daily_limit: number;
|
||||
project_daily_limit: number;
|
||||
openai_api_key: string;
|
||||
};
|
||||
|
||||
@@ -65,6 +68,9 @@ const getInitialFormState = (settings?: TWorkspaceAISettings): TFormState => ({
|
||||
max_audio_duration_seconds: settings?.max_audio_duration_seconds ?? 120,
|
||||
per_user_hourly_limit: settings?.per_user_hourly_limit ?? 30,
|
||||
workspace_hourly_limit: settings?.workspace_hourly_limit ?? 300,
|
||||
per_user_daily_limit: settings?.per_user_daily_limit ?? 100,
|
||||
workspace_daily_limit: settings?.workspace_daily_limit ?? 1000,
|
||||
project_daily_limit: settings?.project_daily_limit ?? 300,
|
||||
openai_api_key: "",
|
||||
});
|
||||
|
||||
@@ -184,6 +190,9 @@ export const AIVoiceTaskerSettingsContent = observer(function AIVoiceTaskerSetti
|
||||
max_audio_duration_seconds: formState.max_audio_duration_seconds,
|
||||
per_user_hourly_limit: formState.per_user_hourly_limit,
|
||||
workspace_hourly_limit: formState.workspace_hourly_limit,
|
||||
per_user_daily_limit: formState.per_user_daily_limit,
|
||||
workspace_daily_limit: formState.workspace_daily_limit,
|
||||
project_daily_limit: formState.project_daily_limit,
|
||||
};
|
||||
|
||||
if (formState.openai_api_key.trim()) payload.openai_api_key = formState.openai_api_key.trim();
|
||||
@@ -339,7 +348,7 @@ export const AIVoiceTaskerSettingsContent = observer(function AIVoiceTaskerSetti
|
||||
<SectionHeader
|
||||
icon={BrainCircuit}
|
||||
title="Models and limits"
|
||||
description="MVP использует один workspace key для транскрибации и структурирования."
|
||||
description="Один workspace key обслуживает всех пользователей. Лимиты срабатывают до отправки аудио в OpenAI."
|
||||
/>
|
||||
<div className="grid gap-5 px-5 py-5 md:grid-cols-2">
|
||||
<Field label="Transcription model">
|
||||
@@ -356,24 +365,51 @@ export const AIVoiceTaskerSettingsContent = observer(function AIVoiceTaskerSetti
|
||||
className="nodedc-settings-input w-full"
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Per-user limit">
|
||||
<Field label="Лимит пользователя за час">
|
||||
<NumberInput
|
||||
value={formState.per_user_hourly_limit}
|
||||
min={1}
|
||||
max={1000}
|
||||
suffix="tasks/hour"
|
||||
suffix="за час"
|
||||
onChange={(value) => updateFormValue("per_user_hourly_limit", value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Workspace limit">
|
||||
<Field label="Лимит workspace за час">
|
||||
<NumberInput
|
||||
value={formState.workspace_hourly_limit}
|
||||
min={1}
|
||||
max={10000}
|
||||
suffix="tasks/hour"
|
||||
suffix="за час"
|
||||
onChange={(value) => updateFormValue("workspace_hourly_limit", value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Суточная квота пользователя">
|
||||
<NumberInput
|
||||
value={formState.per_user_daily_limit}
|
||||
min={1}
|
||||
max={10000}
|
||||
suffix="за сутки"
|
||||
onChange={(value) => updateFormValue("per_user_daily_limit", value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Суточная квота workspace">
|
||||
<NumberInput
|
||||
value={formState.workspace_daily_limit}
|
||||
min={1}
|
||||
max={100000}
|
||||
suffix="за сутки"
|
||||
onChange={(value) => updateFormValue("workspace_daily_limit", value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Суточная квота контура">
|
||||
<NumberInput
|
||||
value={formState.project_daily_limit}
|
||||
min={1}
|
||||
max={50000}
|
||||
suffix="за сутки"
|
||||
onChange={(value) => updateFormValue("project_daily_limit", value)}
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user