diff --git a/lib/Service/OpenAiSettingsService.php b/lib/Service/OpenAiSettingsService.php index 415427fd..833023c8 100644 --- a/lib/Service/OpenAiSettingsService.php +++ b/lib/Service/OpenAiSettingsService.php @@ -219,7 +219,7 @@ public function getQuotas(): array { // Make sure all quota types are set in the json encoded app value (in case new quota types are added in the future) if (count($quotas) !== count(Application::DEFAULT_QUOTAS)) { foreach (Application::DEFAULT_QUOTAS as $quotaType => $_) { - if (!isset($quotas[$quotaType])) { + if (!isset($quotas[$quotaType]) || !is_int($quotas[$quotaType]) || $quotas[$quotaType] < 0) { $quotas[$quotaType] = Application::DEFAULT_QUOTAS[$quotaType]; } } diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue index 659f9c50..fba69594 100644 --- a/src/components/AdminSettings.vue +++ b/src/components/AdminSettings.vue @@ -296,6 +296,36 @@ +
+ + + + + + + + +
+
+ + {{ t('integration_openai', 'Use "{newParam}" parameter instead of the deprecated "{deprecatedParam}"', { newParam: 'max_completion_tokens', deprecatedParam: 'max_tokens' }) }} + +

@@ -352,11 +382,13 @@

- - {{ t('integration_openai', 'Use authentication for image retrieval request') }} - +
+ + {{ t('integration_openai', 'Use authentication for image retrieval request') }} + +

@@ -482,9 +514,13 @@

-

+

{{ t('integration_openai', 'Usage quotas per time period') }} -

+ + + {{ t('integration_openai', 'A per-user quota for each quota type can be set. If the user has not provided their own API key, this quota will be enforced.') }} + {{ t('integration_openai', '"0" means unlimited usage for a particular quota type.') }} + @@ -520,34 +556,6 @@
-
- - - - - - - - -
- - {{ t('integration_openai', 'Use "{newParam}" parameter instead of the deprecated "{deprecatedParam}"', { newParam: 'max_completion_tokens', deprecatedParam: 'max_tokens' }) }} -

@@ -831,6 +839,8 @@ export default { } }, 2000), onInput: debounce(async function() { + // sanitize quotas + this.state.quotas = this.state.quotas.map(e => parseInt(e)).map(e => isNaN(e) || e < 0 ? 0 : e) const values = { service_name: this.state.service_name, request_timeout: parseInt(this.state.request_timeout),