plugin-ai-api 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -12
- package/dist/client/185.c47663fefaeb0e5b.js +10 -0
- package/dist/client/562.9012cfd1fa04303d.js +10 -0
- package/dist/client/685.b5b1e0a5b825d253.js +10 -0
- package/dist/client/index.js +1 -1
- package/dist/client-v2/185.b552dc91ec2371ba.js +10 -0
- package/dist/client-v2/562.db2984167250b1be.js +10 -0
- package/dist/client-v2/685.cf16e5b829e06f85.js +10 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/externalVersion.js +8 -8
- package/dist/locale/en-US.json +175 -139
- package/dist/locale/vi-VN.json +40 -2
- package/dist/locale/zh-CN.json +40 -2
- package/dist/server/collections/ai-api-model-metadata.js +26 -0
- package/dist/server/collections/ai-api-response-records.js +101 -0
- package/dist/server/collections/ai-api-virtual-models.js +68 -0
- package/dist/server/middleware/response-record-resource.js +66 -0
- package/dist/server/middleware/role-permission.js +43 -18
- package/dist/server/migrations/20260901000000-remove-default-group-members.js +60 -0
- package/dist/server/migrations/20260902000000-seed-default-role-permissions.js +55 -0
- package/dist/server/migrations/20260903000000-seed-sample-response-records.js +170 -0
- package/dist/server/plugin.js +66 -16
- package/dist/server/routes/chat-completions.js +38 -6
- package/dist/server/routes/completions.js +16 -4
- package/dist/server/routes/embeddings.js +25 -6
- package/dist/server/routes/models.js +29 -0
- package/dist/server/routes/responses.js +530 -0
- package/dist/server/routes/router.js +65 -10
- package/dist/server/usage.js +25 -4
- package/dist/server/utils/direct-llm-context.js +1 -1
- package/dist/server/utils/resolve-service.js +24 -0
- package/dist/server/utils/response-store.js +138 -0
- package/dist/server/utils/responses-format.js +686 -0
- package/dist/server/utils/responses-stream.js +330 -0
- package/dist/server/utils/virtual-models.js +238 -0
- package/dist/server/validation.js +44 -2
- package/dist/swagger.js +137 -0
- package/package.json +34 -32
- package/src/__tests__/locale.test.ts +43 -0
- package/src/client/__tests__/settings-registration.test.tsx +1 -0
- package/src/client/plugin.tsx +9 -1
- package/src/client-v2/__tests__/settings-registration.test.tsx +1 -0
- package/src/client-v2/pages/ModelMetadataPage.tsx +44 -0
- package/src/client-v2/pages/ModelRoutingPage.tsx +238 -0
- package/src/client-v2/pages/UsageGroupsPage.tsx +75 -38
- package/src/client-v2/plugin.tsx +8 -0
- package/src/locale/en-US.json +175 -139
- package/src/locale/vi-VN.json +40 -2
- package/src/locale/zh-CN.json +40 -2
- package/src/server/__tests__/embeddings.test.ts +184 -0
- package/src/server/__tests__/models.test.ts +21 -1
- package/src/server/__tests__/response-record-resource.test.ts +50 -0
- package/src/server/__tests__/response-store-integration.test.ts +341 -0
- package/src/server/__tests__/response-store.test.ts +195 -0
- package/src/server/__tests__/responses-contract.test.ts +469 -0
- package/src/server/__tests__/responses-format.test.ts +299 -0
- package/src/server/__tests__/responses-router.test.ts +182 -0
- package/src/server/__tests__/responses-streaming.test.ts +368 -0
- package/src/server/__tests__/responses.test.ts +462 -0
- package/src/server/__tests__/role-permission.test.ts +139 -0
- package/src/server/__tests__/seed-role-permission.test.ts +88 -0
- package/src/server/__tests__/types/responses-sdk.types.test-d.ts +23 -0
- package/src/server/__tests__/usage-groups.test.ts +96 -0
- package/src/server/__tests__/usage-route.test.ts +1 -0
- package/src/server/__tests__/usage.test.ts +14 -0
- package/src/server/__tests__/validation.test.ts +66 -7
- package/src/server/__tests__/virtual-model-routing.test.ts +589 -0
- package/src/server/collections/ai-api-model-metadata.ts +26 -0
- package/src/server/collections/ai-api-response-records.ts +77 -0
- package/src/server/collections/ai-api-virtual-models.ts +58 -0
- package/src/server/middleware/response-record-resource.ts +44 -0
- package/src/server/middleware/role-permission.ts +69 -35
- package/src/server/migrations/20260901000000-remove-default-group-members.ts +56 -0
- package/src/server/migrations/20260902000000-seed-default-role-permissions.ts +46 -0
- package/src/server/migrations/20260903000000-seed-sample-response-records.ts +162 -0
- package/src/server/plugin.ts +84 -20
- package/src/server/resource/ai-api-config.ts +2 -1
- package/src/server/routes/agent-completions.ts +3 -0
- package/src/server/routes/chat-completions.ts +34 -10
- package/src/server/routes/completions.ts +16 -4
- package/src/server/routes/embeddings.ts +32 -10
- package/src/server/routes/models.ts +34 -0
- package/src/server/routes/responses.ts +640 -0
- package/src/server/routes/router.ts +81 -12
- package/src/server/services/__tests__/file-processor.test.ts +1 -0
- package/src/server/usage.ts +29 -2
- package/src/server/utils/app-observability.ts +1 -1
- package/src/server/utils/direct-llm-context.ts +2 -1
- package/src/server/utils/openai-format.ts +1 -0
- package/src/server/utils/resolve-service.ts +39 -1
- package/src/server/utils/response-store.ts +148 -0
- package/src/server/utils/responses-format.ts +974 -0
- package/src/server/utils/responses-stream.ts +384 -0
- package/src/server/utils/virtual-models.ts +320 -0
- package/src/server/validation.ts +49 -0
- package/src/swagger.ts +139 -0
- package/dist/client/562.44b16aad4718b4c7.js +0 -10
- package/dist/client/685.ae483e17b6b49c98.js +0 -10
- package/dist/client-v2/562.45d5c504433be38b.js +0 -10
- package/dist/client-v2/685.1030370b309b7d4b.js +0 -10
- package/dist/server/collections/ai-api-user-permissions.js +0 -67
- package/dist/server/collections/ai-api-user-quota-buckets.js +0 -54
- package/dist/server/collections/ai-api-user-quota-policies.js +0 -63
- package/dist/server/resource/ai-api-usage-groups.js +0 -168
- package/src/server/collections/ai-api-user-permissions.ts +0 -46
- package/src/server/collections/ai-api-user-quota-buckets.ts +0 -24
- package/src/server/collections/ai-api-user-quota-policies.ts +0 -33
- package/src/server/resource/ai-api-usage-groups.ts +0 -171
package/src/server/validation.ts
CHANGED
|
@@ -49,6 +49,16 @@ function requirePositiveIntegerOrNull(value: unknown, field: string): void {
|
|
|
49
49
|
if (!Number.isSafeInteger(parsed) || parsed <= 0) throw new Error(`${field} must be a positive integer.`);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function requireBooleanOrNull(value: unknown, field: string): void {
|
|
53
|
+
if (value === null || value === undefined) return;
|
|
54
|
+
if (typeof value !== 'boolean') throw new Error(`${field} must be a boolean.`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function requireInteger(value: unknown, field: string): void {
|
|
58
|
+
if (value === null || value === undefined || value === '') return;
|
|
59
|
+
if (!Number.isSafeInteger(Number(value))) throw new Error(`${field} must be an integer.`);
|
|
60
|
+
}
|
|
61
|
+
|
|
52
62
|
export function validateModelMetadata(model: Model): void {
|
|
53
63
|
if (!String(model.get('llmService') ?? '').trim()) throw new Error('llmService is required.');
|
|
54
64
|
if (!String(model.get('model') ?? '').trim()) throw new Error('model is required.');
|
|
@@ -58,6 +68,18 @@ export function validateModelMetadata(model: Model): void {
|
|
|
58
68
|
if (systemPrompt !== null && systemPrompt !== undefined && typeof systemPrompt !== 'string') {
|
|
59
69
|
throw new Error('systemPrompt must be a string.');
|
|
60
70
|
}
|
|
71
|
+
requireBooleanOrNull(model.get('supportsVision'), 'supportsVision');
|
|
72
|
+
requireBooleanOrNull(model.get('supportsToolCalling'), 'supportsToolCalling');
|
|
73
|
+
requireBooleanOrNull(model.get('enabled'), 'enabled');
|
|
74
|
+
const reasoningTier = model.get('reasoningTier');
|
|
75
|
+
if (
|
|
76
|
+
reasoningTier !== null &&
|
|
77
|
+
reasoningTier !== undefined &&
|
|
78
|
+
!['cheap', 'general', 'reasoning'].includes(String(reasoningTier))
|
|
79
|
+
) {
|
|
80
|
+
throw new Error('reasoningTier must be cheap, general, or reasoning.');
|
|
81
|
+
}
|
|
82
|
+
requireInteger(model.get('sortOrder'), 'sortOrder');
|
|
61
83
|
|
|
62
84
|
const contextWindow = model.get('contextWindow');
|
|
63
85
|
const maxCompletionTokens = model.get('maxCompletionTokens');
|
|
@@ -74,6 +96,33 @@ export function validateModelMetadata(model: Model): void {
|
|
|
74
96
|
}
|
|
75
97
|
}
|
|
76
98
|
|
|
99
|
+
function requireModelReference(value: unknown, field: string): void {
|
|
100
|
+
const normalized = typeof value === 'string' ? value.trim() : '';
|
|
101
|
+
const slash = normalized.indexOf('/');
|
|
102
|
+
if (slash <= 0 || slash === normalized.length - 1) {
|
|
103
|
+
throw new Error(`${field} must use the service/modelId format.`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function requireModelReferenceList(value: unknown, field: string): void {
|
|
108
|
+
if (value === null || value === undefined) return;
|
|
109
|
+
if (!Array.isArray(value)) throw new Error(`${field} must be an array.`);
|
|
110
|
+
value.forEach((item, index) => requireModelReference(item, `${field}[${index}]`));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function validateVirtualModel(model: Model): void {
|
|
114
|
+
if (!String(model.get('name') ?? '').trim()) throw new Error('name is required.');
|
|
115
|
+
const mode = model.get('mode');
|
|
116
|
+
if (mode !== null && mode !== undefined && !['chat', 'embedding'].includes(String(mode))) {
|
|
117
|
+
throw new Error('mode must be chat or embedding.');
|
|
118
|
+
}
|
|
119
|
+
requireModelReference(model.get('fallbackModel'), 'fallbackModel');
|
|
120
|
+
for (const field of ['visionModels', 'toolModels', 'reasoningModels', 'cheapModels', 'generalModels']) {
|
|
121
|
+
requireModelReferenceList(model.get(field), field);
|
|
122
|
+
}
|
|
123
|
+
requireBooleanOrNull(model.get('enabled'), 'enabled');
|
|
124
|
+
}
|
|
125
|
+
|
|
77
126
|
export function validateQuotaPolicy(model: Model): void {
|
|
78
127
|
if (!['daily', 'monthly'].includes(String(model.get('periodType')))) {
|
|
79
128
|
throw new Error('periodType must be daily or monthly.');
|
package/src/swagger.ts
CHANGED
|
@@ -181,6 +181,145 @@ export default {
|
|
|
181
181
|
},
|
|
182
182
|
},
|
|
183
183
|
},
|
|
184
|
+
'/ai-llm/v1/responses': {
|
|
185
|
+
post: {
|
|
186
|
+
tags: ['ai-llm'],
|
|
187
|
+
summary: 'Create a model response',
|
|
188
|
+
description:
|
|
189
|
+
'OpenAI Responses API endpoint. Supports text/image/file inputs, function calling, streaming, reasoning output when exposed by the provider, and owner-scoped previous_response_id chains. Built-in web_search and file_search tools are not supported.',
|
|
190
|
+
security: [{ BearerAuth: [] }],
|
|
191
|
+
requestBody: {
|
|
192
|
+
required: true,
|
|
193
|
+
content: {
|
|
194
|
+
'application/json': {
|
|
195
|
+
schema: {
|
|
196
|
+
type: 'object',
|
|
197
|
+
properties: {
|
|
198
|
+
model: { type: 'string', example: 'openai/gpt-4o' },
|
|
199
|
+
input: {
|
|
200
|
+
oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'object' } }],
|
|
201
|
+
},
|
|
202
|
+
instructions: { type: 'string' },
|
|
203
|
+
max_output_tokens: { type: 'integer' },
|
|
204
|
+
temperature: { type: 'number', minimum: 0, maximum: 2 },
|
|
205
|
+
top_p: { type: 'number', minimum: 0, maximum: 1 },
|
|
206
|
+
tools: { type: 'array', description: 'Function tools only', items: { type: 'object' } },
|
|
207
|
+
tool_choice: { oneOf: [{ type: 'string' }, { type: 'object' }] },
|
|
208
|
+
metadata: { type: 'object' },
|
|
209
|
+
previous_response_id: { type: 'string' },
|
|
210
|
+
store: { type: 'boolean', default: true },
|
|
211
|
+
stream: { type: 'boolean', default: false },
|
|
212
|
+
truncation: { type: 'string', enum: ['auto', 'disabled'], default: 'disabled' },
|
|
213
|
+
service_tier: { type: 'string', enum: ['auto', 'default', 'flex', 'scale', 'priority'] },
|
|
214
|
+
prompt_cache_key: { type: 'string' },
|
|
215
|
+
prompt_cache_retention: { type: 'string', enum: ['in_memory', '24h'], nullable: true },
|
|
216
|
+
reasoning: { type: 'object' },
|
|
217
|
+
safety_identifier: { type: 'string', maxLength: 64 },
|
|
218
|
+
parallel_tool_calls: { type: 'boolean', default: true },
|
|
219
|
+
text: { type: 'object' },
|
|
220
|
+
},
|
|
221
|
+
required: ['model', 'input'],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
responses: {
|
|
227
|
+
200: {
|
|
228
|
+
description: 'OpenAI Response object, or Responses API SSE events when stream=true',
|
|
229
|
+
content: {
|
|
230
|
+
'application/json': {
|
|
231
|
+
schema: {
|
|
232
|
+
type: 'object',
|
|
233
|
+
properties: {
|
|
234
|
+
id: { type: 'string', example: 'resp_abc123' },
|
|
235
|
+
object: { type: 'string', const: 'response' },
|
|
236
|
+
created_at: { type: 'integer' },
|
|
237
|
+
completed_at: { type: 'integer', nullable: true },
|
|
238
|
+
model: { type: 'string' },
|
|
239
|
+
status: {
|
|
240
|
+
type: 'string',
|
|
241
|
+
enum: ['completed', 'failed', 'in_progress', 'cancelled', 'queued', 'incomplete'],
|
|
242
|
+
},
|
|
243
|
+
output_text: { type: 'string' },
|
|
244
|
+
output: { type: 'array', items: { type: 'object' } },
|
|
245
|
+
usage: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
input_tokens: { type: 'integer' },
|
|
249
|
+
input_tokens_details: {
|
|
250
|
+
type: 'object',
|
|
251
|
+
properties: { cached_tokens: { type: 'integer' } },
|
|
252
|
+
},
|
|
253
|
+
output_tokens: { type: 'integer' },
|
|
254
|
+
output_tokens_details: {
|
|
255
|
+
type: 'object',
|
|
256
|
+
properties: { reasoning_tokens: { type: 'integer' } },
|
|
257
|
+
},
|
|
258
|
+
total_tokens: { type: 'integer' },
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
metadata: { type: 'object', nullable: true },
|
|
262
|
+
previous_response_id: { type: 'string', nullable: true },
|
|
263
|
+
truncation: { type: 'string', enum: ['auto', 'disabled'] },
|
|
264
|
+
error: { type: 'object', nullable: true },
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
'text/event-stream': { schema: { type: 'string' } },
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
400: { description: 'Invalid request or unsupported tool' },
|
|
272
|
+
404: { description: 'Model or previous response not found' },
|
|
273
|
+
429: { description: 'Rate limit or quota exceeded' },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
'/ai-llm/v1/responses/{id}': {
|
|
278
|
+
get: {
|
|
279
|
+
tags: ['ai-llm'],
|
|
280
|
+
summary: 'Retrieve a stored model response',
|
|
281
|
+
description:
|
|
282
|
+
'Returns a non-expired response created by the authenticated user. Responses created with store=false cannot be retrieved.',
|
|
283
|
+
security: [{ BearerAuth: [] }],
|
|
284
|
+
parameters: [
|
|
285
|
+
{
|
|
286
|
+
name: 'id',
|
|
287
|
+
in: 'path',
|
|
288
|
+
required: true,
|
|
289
|
+
schema: { type: 'string', example: 'resp_abc123' },
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: 'stream',
|
|
293
|
+
in: 'query',
|
|
294
|
+
schema: { type: 'boolean', default: false },
|
|
295
|
+
description: 'Only false is currently supported; stream retrieval is rejected.',
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
responses: {
|
|
299
|
+
200: { description: 'Stored OpenAI Response object' },
|
|
300
|
+
400: { description: 'Unsupported retrieve expansion or streaming parameter' },
|
|
301
|
+
404: { description: 'Response not found, expired, or owned by another user' },
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
delete: {
|
|
305
|
+
tags: ['ai-llm'],
|
|
306
|
+
summary: 'Delete a stored model response',
|
|
307
|
+
description: 'Deletes a stored response owned by the authenticated user.',
|
|
308
|
+
security: [{ BearerAuth: [] }],
|
|
309
|
+
parameters: [
|
|
310
|
+
{
|
|
311
|
+
name: 'id',
|
|
312
|
+
in: 'path',
|
|
313
|
+
required: true,
|
|
314
|
+
schema: { type: 'string', example: 'resp_abc123' },
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
responses: {
|
|
318
|
+
204: { description: 'Response deleted' },
|
|
319
|
+
404: { description: 'Response not found, expired, or owned by another user' },
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
184
323
|
'/ai-llm/v1/embeddings': {
|
|
185
324
|
post: {
|
|
186
325
|
tags: ['ai-llm'],
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).push([["562"],{641:function(e,t,r){r.r(t),r.d(t,{default:function(){return b}});var n=r(155),o=r.n(n),a=r(59),l=r(694),i=r(650),u=r(630);function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function s(e,t,r,n,o,a,l){try{var i=e[a](l),u=i.value}catch(e){r(e);return}i.done?t(u):Promise.resolve(u).then(n,o)}function m(e){return function(){var t=this,r=arguments;return new Promise(function(n,o){var a=e.apply(t,r);function l(e){s(a,n,o,l,i,"next",e)}function i(e){s(a,n,o,l,i,"throw",e)}l(void 0)})}}function d(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){var n;n=r[t],t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n})}return e}function p(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,o=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var a=[],l=!0,i=!1;try{for(o=o.call(e);!(l=(r=o.next()).done)&&(a.push(r.value),!t||a.length!==t);l=!0);}catch(e){i=!0,n=e}finally{try{l||null==o.return||o.return()}finally{if(i)throw n}}return a}}(e,t)||y(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(e,t){if(e){if("string"==typeof e)return c(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return c(e,t)}}function f(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},l=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(l,"next",{value:u(0)}),i(l,"throw",{value:u(1)}),i(l,"return",{value:u(2)}),"function"==typeof Symbol&&i(l,Symbol.iterator,{value:function(){return this}}),l;function u(i){return function(u){var c=[i,u];if(r)throw TypeError("Generator is already executing.");for(;l&&(l=0,c[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&c[0]?n.return:c[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,c[1])).done)return o;switch(n=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return a.label++,{value:c[1],done:!1};case 5:a.label++,n=c[1],c=[0];continue;case 7:c=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===c[0]||2===c[0])){a=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){a.label=c[1];break}if(6===c[0]&&a.label<o[1]){a.label=o[1],o=c;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(c);break}o[2]&&a.ops.pop(),a.trys.pop();continue}c=t.call(e,a)}catch(e){c=[6,e],n=0}finally{r=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}function b(){var e=(0,l.useFlowContext)(),t=(0,i.k)(),r=p(a.Form.useForm(),1)[0],s=a.Form.useWatch("llmService",r),b=p((0,n.useState)([]),2),v=b[0],h=b[1],w=p((0,n.useState)([]),2),g=w[0],S=w[1],E=p((0,n.useState)([]),2),k=E[0],O=E[1],x=p((0,n.useState)(!1),2),I=x[0],P=x[1],F=p((0,n.useState)(!1),2),j=F[0],C=F[1],M=p((0,n.useState)(!1),2),A=M[0],T=M[1],L=p((0,n.useState)(),2),D=L[0],N=L[1],B=p((0,n.useState)(!1),2),q=B[0],W=B[1],U=(0,n.useCallback)(function(){return m(function(){var t,r,n,o;return f(this,function(l){switch(l.label){case 0:C(!0),l.label=1;case 1:return l.trys.push([1,3,4,5]),[4,Promise.all([e.api.request({url:"aiApiModelMetadata:list",method:"get",params:{pageSize:200,sort:"llmService"}}),e.api.request({url:"ai:listLLMServices",method:"get"})])];case 2:return r=(t=p.apply(void 0,[l.sent(),2]))[0],n=t[1],h((0,u.m)(r,[])),S((0,u.m)(n,[])),[3,5];case 3:return o=l.sent(),a.message.error((0,u.g)(o)),[3,5];case 4:return C(!1),[7];case 5:return[2]}})})()},[e.api]);(0,n.useEffect)(function(){U()},[U]);var _=(0,n.useCallback)(function(r,n){return m(function(){var o,l,i;return f(this,function(s){switch(s.label){case 0:P(!0),s.label=1;case 1:return s.trys.push([1,3,4,5]),[4,e.api.request({url:"ai:listModels",method:"get",params:{llmService:r}})];case 2:return o=s.sent(),l=(0,u.m)(o,[]),O(n&&!l.some(function(e){return e.id===n})?[{id:n}].concat(function(e){if(Array.isArray(e))return c(e)}(l)||function(e){if("u">typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(l)||y(l)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):l),[3,5];case 3:return i=s.sent(),O(n?[{id:n}]:[]),a.message.error("".concat(t("Failed to load models"),": ").concat((0,u.g)(i))),[3,5];case 4:return P(!1),[7];case 5:return[2]}})})()},[e.api,t]),V=function(e){N(e),r.setFieldsValue(d({},e)),W(!0),_(e.llmService,e.model)},z=[{title:t("LLM service"),dataIndex:"llmService",key:"llmService",width:160},{title:t("Model"),dataIndex:"model",key:"model",width:180},{title:t("Context window"),dataIndex:"contextWindow",key:"contextWindow",width:140},{title:t("Max completion tokens"),dataIndex:"maxCompletionTokens",key:"maxCompletionTokens",width:170},{title:t("Owned by"),dataIndex:"ownedByOverride",key:"ownedByOverride",width:140},{title:t("Display name"),dataIndex:"displayName",key:"displayName",width:160},{title:t("Initial system prompt"),dataIndex:"systemPrompt",key:"systemPrompt",width:220,ellipsis:!0,render:function(e){return e||"-"}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return o().createElement(a.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",fixed:"right",width:150,render:function(r,n){return o().createElement(a.Space,null,o().createElement(a.Button,{type:"link",onClick:function(){return V(n)}},t("Edit")),o().createElement(a.Popconfirm,{title:t("Delete this override?"),onConfirm:function(){var r;return r=n.id,m(function(){var n;return f(this,function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiModelMetadata:destroy/".concat(r),method:"post"})];case 1:return o.sent(),a.message.success(t("Deleted successfully")),[4,U()];case 2:return o.sent(),[3,4];case 3:return n=o.sent(),a.message.error((0,u.g)(n)),[3,4];case 4:return[2]}})})()}},o().createElement(a.Button,{type:"link",danger:!0},t("Delete"))))}}];return o().createElement(a.Card,{title:t("Model metadata"),extra:o().createElement(a.Button,{type:"primary",onClick:function(){N(void 0),O([]),r.resetFields(),r.setFieldsValue({enabled:!0}),W(!0)}},t("Add override"))},o().createElement(a.Table,{rowKey:"id",columns:z,dataSource:v,loading:j,scroll:{x:1450}}),o().createElement(a.Modal,{title:D?t("Edit override"):t("Add override"),open:q,onCancel:function(){return W(!1)},onOk:function(){return m(function(){var n,o,l,i,c,s,m,p,y;return f(this,function(f){switch(f.label){case 0:return[4,r.validateFields()];case 1:var b,v;b=d({},m=f.sent()),v=v={contextWindow:null!=(n=m.contextWindow)?n:null,maxCompletionTokens:null!=(o=m.maxCompletionTokens)?o:null,ownedByOverride:(null==(l=m.ownedByOverride)?void 0:l.trim())||null,displayName:(null==(i=m.displayName)?void 0:i.trim())||null,description:(null==(c=m.description)?void 0:c.trim())||null,systemPrompt:(null==(s=m.systemPrompt)?void 0:s.trim())||null},Object.getOwnPropertyDescriptors?Object.defineProperties(b,Object.getOwnPropertyDescriptors(v)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t})(Object(v)).forEach(function(e){Object.defineProperty(b,e,Object.getOwnPropertyDescriptor(v,e))}),p=b,T(!0),f.label=2;case 2:return f.trys.push([2,5,6,7]),[4,e.api.request({url:D?"aiApiModelMetadata:update/".concat(D.id):"aiApiModelMetadata:create",method:"post",data:p})];case 3:return f.sent(),a.message.success(t("Saved successfully")),W(!1),[4,U()];case 4:return f.sent(),[3,7];case 5:return y=f.sent(),a.message.error((0,u.g)(y)),[3,7];case 6:return T(!1),[7];case 7:return[2]}})})()},confirmLoading:A,destroyOnClose:!0},o().createElement(a.Form,{form:r,layout:"vertical",preserve:!1},o().createElement(a.Form.Item,{name:"llmService",label:t("LLM service"),rules:[{required:!0}]},o().createElement(a.Select,{showSearch:!0,optionFilterProp:"label",onChange:function(e){r.setFieldValue("model",void 0),O([]),_(e)},options:g.map(function(e){return{label:e.title||e.name,value:e.name}})})),o().createElement(a.Form.Item,{name:"model",label:t("Model"),rules:[{required:!0}]},o().createElement(a.Select,{showSearch:!0,optionFilterProp:"label",loading:I,disabled:!s,placeholder:t("Select a model"),options:k.map(function(e){return{label:e.id,value:e.id}})})),o().createElement(a.Form.Item,{name:"contextWindow",label:t("Context window"),tooltip:t("Total input + output token capacity reported to clients.")},o().createElement(a.InputNumber,{min:1,precision:0,style:{width:"100%"},placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"maxCompletionTokens",label:t("Max completion tokens"),tooltip:t("Maximum output tokens reported to clients.")},o().createElement(a.InputNumber,{min:1,precision:0,style:{width:"100%"},placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"ownedByOverride",label:t("Owned by")},o().createElement(a.Input,{placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"displayName",label:t("Display name")},o().createElement(a.Input,{placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"description",label:t("Description")},o().createElement(a.Input.TextArea,{rows:3})),o().createElement(a.Form.Item,{name:"systemPrompt",label:t("Initial system prompt"),tooltip:t("Prepended as the first system message, before any system prompt sent by the client. If the client sends no system prompt, this becomes the system prompt sent to the provider.")},o().createElement(a.Input.TextArea,{rows:4,placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},o().createElement(a.Switch,null)))))}},650:function(e,t,r){r.d(t,{k:function(){return l}});var n=r(155),o=r(694),a=JSON.parse('{"UU":"plugin-ai-api"}');function l(){var e=(0,o.useFlowEngine)();return(0,n.useCallback)(function(t){return e.context.t(t,{ns:[a.UU,"client"]})},[e])}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function o(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return o},m:function(){return n}})}}]);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunkplugin_ai_api=self.webpackChunkplugin_ai_api||[]).push([["685"],{244:function(e,t,r){r.r(t),r.d(t,{default:function(){return f}});var n=r(155),a=r.n(n),l=r(59),o=r(694),u=r(650),s=r(630);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function c(e,t,r,n,a,l,o){try{var u=e[l](o),s=u.value}catch(e){r(e);return}u.done?t(s):Promise.resolve(s).then(n,a)}function m(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var l=e.apply(t,r);function o(e){c(l,n,a,o,u,"next",e)}function u(e){c(l,n,a,o,u,"throw",e)}o(void 0)})}}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var l=[],o=!0,u=!1;try{for(a=a.call(e);!(o=(r=a.next()).done)&&(l.push(r.value),!t||l.length!==t);o=!0);}catch(e){u=!0,n=e}finally{try{o||null==a.return||a.return()}finally{if(u)throw n}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return i(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return i(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){var r,n,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(o,"next",{value:s(0)}),u(o,"throw",{value:s(1)}),u(o,"return",{value:s(2)}),"function"==typeof Symbol&&u(o,Symbol.iterator,{value:function(){return this}}),o;function s(u){return function(s){var i=[u,s];if(r)throw TypeError("Generator is already executing.");for(;o&&(o=0,i[0]&&(l=0)),l;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return l.label++,{value:i[1],done:!1};case 5:l.label++,n=i[1],i=[0];continue;case 7:i=l.ops.pop(),l.trys.pop();continue;default:if(!(a=(a=l.trys).length>0&&a[a.length-1])&&(6===i[0]||2===i[0])){l=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]<a[3])){l.label=i[1];break}if(6===i[0]&&l.label<a[1]){l.label=a[1],a=i;break}if(a&&l.label<a[2]){l.label=a[2],l.ops.push(i);break}a[2]&&l.ops.pop(),l.trys.pop();continue}i=t.call(e,l)}catch(e){i=[6,e],n=0}finally{r=a=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}}}function f(){var e=(0,o.useFlowContext)(),t=(0,u.k)(),r=d(l.Form.useForm(),1)[0],i=d(l.Form.useForm(),1)[0],c=l.Form.useWatch("allowedLlmServices",r),f=l.Form.useWatch("allowAllModels",r),h=d((0,n.useState)([]),2),b=h[0],g=h[1],v=d((0,n.useState)([]),2),y=v[0],w=v[1],E=d((0,n.useState)(!1),2),S=E[0],I=E[1],F=d((0,n.useState)(!1),2),k=F[0],M=F[1],A=d((0,n.useState)(),2),U=A[0],C=A[1],q=d((0,n.useState)(!1),2),T=q[0],x=q[1],P=d((0,n.useState)([]),2),j=P[0],L=P[1],D=d((0,n.useState)(!1),2),B=D[0],z=D[1],G=d((0,n.useState)([]),2),N=G[0],O=G[1],R=d((0,n.useState)(""),2),_=R[0],K=R[1],W=d((0,n.useState)(null),2),V=W[0],J=W[1],$=(0,n.useCallback)(function(){return m(function(){var r,n,a,o;return p(this,function(u){switch(u.label){case 0:I(!0),u.label=1;case 1:return u.trys.push([1,3,4,5]),[4,e.api.request({url:"aiApiUsageGroups:list",method:"get",params:{pageSize:200,sort:"-updatedAt"}})];case 2:return r=u.sent(),g((0,s.m)(r,[])),[3,5];case 3:return n=u.sent(),l.message.error((0,s.g)(n)),[3,5];case 4:return I(!1),[7];case 5:return u.trys.push([5,7,,8]),[4,e.api.request({url:"ai:listAllEnabledModels",method:"get"})];case 6:return a=u.sent(),w((0,s.m)(a,[])),[3,8];case 7:return o=u.sent(),w([]),l.message.error("".concat(t("Failed to load models"),": ").concat((0,s.g)(o))),[3,8];case 8:return[2]}})})()},[e.api,t]),H=(0,n.useCallback)(function(t){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:z(!0),a.label=1;case 1:return a.trys.push([1,3,4,5]),[4,e.api.request({url:"aiApiGroupMembers:list",method:"get",params:{filter:{groupId:t},pageSize:1e3,appends:["user"]}})];case 2:return r=a.sent(),L((0,s.m)(r,[])),[3,5];case 3:return n=a.sent(),l.message.error((0,s.g)(n)),[3,5];case 4:return z(!1),[7];case 5:return[2]}})})()},[e.api]),Q=(0,n.useCallback)(function(t){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),[4,e.api.request({url:"aiApiUsageGroups:listUnassignedUsers",method:"get",params:{keyword:t,pageSize:100}})];case 1:return r=a.sent(),O((0,s.m)(r,[])),[3,3];case 2:return n=a.sent(),l.message.error((0,s.g)(n)),[3,3];case 3:return[2]}})})()},[e.api]);(0,n.useEffect)(function(){$()},[$]);var X=function(e){var t;return(null==e?void 0:e.nickname)||(null==e?void 0:e.username)||(null==e?void 0:e.email)||String(null!=(t=null==e?void 0:e.id)?t:"")},Y=(0,n.useMemo)(function(){return y.map(function(e){return{label:e.llmServiceTitle||e.llmService,value:e.llmService}})},[y]),Z=(0,n.useMemo)(function(){var e=new Set(c||[]);return y.filter(function(t){return e.has(t.llmService)}).flatMap(function(e){return(e.enabledModels||[]).map(function(t){return{label:"".concat(e.llmServiceTitle||e.llmService," / ").concat(t.label||t.value),value:"".concat(e.llmService,"/").concat(t.value)}})})},[y,c]),ee=function(e){var t;return(null==(t=Y.find(function(t){return t.value===e}))?void 0:t.label)||e},et=[{title:t("Name"),dataIndex:"name",key:"name",width:180},{title:t("Default"),dataIndex:"isDefault",key:"isDefault",width:100,render:function(e){return e?a().createElement(l.Tag,{color:"blue"},t("Default")):null}},{title:t("Mode"),dataIndex:"quotaMode",key:"quotaMode",width:120},{title:t("Rate limit/min"),dataIndex:"rateLimitPerMinute",key:"rateLimitPerMinute",width:140},{title:t("Model access"),key:"modelAccess",width:240,render:function(e,r){var n=r.allowedLlmServices||[],o=r.allowedModels||[],u=0===n.length,s=!1!==r.allowAllModels;return u&&s?a().createElement(l.Tag,{color:"blue"},t("All models")):a().createElement(l.Space,{size:[0,4],wrap:!0},a().createElement(l.Tag,null,u?t("All services"):n.map(function(e){return ee(e)}).join(", ")),a().createElement(l.Tag,{color:s?"blue":void 0},s?t("All models"):o.length?o.join(", "):t("No models")))}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return a().createElement(l.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",width:150,fixed:"right",render:function(n,o){return a().createElement(l.Space,{size:0},a().createElement(l.Button,{type:"link",onClick:function(){return m(function(){return p(this,function(e){switch(e.label){case 0:return C(o),r.setFieldsValue(o),x(!0),[4,H(o.id)];case 1:if(e.sent(),o.isDefault)return[3,3];return[4,Q()];case 2:e.sent(),e.label=3;case 3:return[2]}})})()}},t("Edit")),!o.isDefault&&a().createElement(l.Popconfirm,{title:t("Delete this group?"),onConfirm:function(){return m(function(){var r;return p(this,function(n){switch(n.label){case 0:return n.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiUsageGroups:destroy/".concat(o.id),method:"post"})];case 1:return n.sent(),l.message.success(t("Deleted successfully")),[4,$()];case 2:return n.sent(),[3,4];case 3:return r=n.sent(),l.message.error((0,s.g)(r)),[3,4];case 4:return[2]}})})()}},a().createElement(l.Button,{type:"link",danger:!0},t("Delete"))))}}],er=[{title:t("User"),key:"user",render:function(e,t){return X(t.user)||String(t.userId)}},{title:t("Actions"),key:"actions",width:120,render:function(r,n){return a().createElement(l.Popconfirm,{title:t("Remove member?"),onConfirm:function(){return m(function(){var r;return p(this,function(a){switch(a.label){case 0:return a.trys.push([0,5,,6]),[4,e.api.request({url:"aiApiUsageGroups:removeMember",method:"post",data:{groupId:n.groupId,userId:n.userId}})];case 1:if(a.sent(),l.message.success(t("Member removed")),!U)return[3,4];return[4,H(U.id)];case 2:return a.sent(),[4,Q()];case 3:a.sent(),a.label=4;case 4:return[3,6];case 5:return r=a.sent(),l.message.error((0,s.g)(r)),[3,6];case 6:return[2]}})})()}},a().createElement(l.Button,{type:"link",danger:!0},t("Remove")))}}];return a().createElement(l.Card,{title:t("Usage groups"),extra:a().createElement(l.Button,{type:"primary",onClick:function(){C(void 0),L([]),r.setFieldsValue({name:"",quotaMode:"per_user",rateLimitPerMinute:60,enabled:!0,periodType:"monthly",timezone:"UTC",currency:"USD",rejectUnpricedModel:!0,missingUsageBehavior:"use_reserved",contextOverflowBehavior:"reject",allowedLlmServices:[],allowAllModels:!0,allowedModels:[]}),x(!0)}},t("Add group"))},a().createElement(l.Row,{gutter:[16,16],style:{marginBottom:16}},a().createElement(l.Col,{span:12},a().createElement(l.Input.Search,{placeholder:t("Search group by user"),value:_,onChange:function(e){return K(e.target.value)},onSearch:function(){return m(function(){var r,n,a,o;return p(this,function(u){switch(u.label){case 0:if(!_.trim())return[2];u.label=1;case 1:return u.trys.push([1,4,,5]),[4,e.api.request({url:"aiApiUsageGroups:searchUsers",method:"get",params:{keyword:_,pageSize:1}})];case 2:if(r=u.sent(),0===(n=(0,s.m)(r,[])).length)return l.message.warning(t("User not found")),J(null),[2];return[4,e.api.request({url:"aiApiUsageGroups:getByUser",method:"get",params:{userId:n[0].id}})];case 3:return a=u.sent(),J((0,s.m)(a,null)),[3,5];case 4:return o=u.sent(),l.message.error((0,s.g)(o)),[3,5];case 5:return[2]}})})()},enterButton:!0})),a().createElement(l.Col,{span:12},V&&a().createElement(l.Tag,{color:"blue"},t("User belongs to"),": ",V.name))),a().createElement(l.Table,{rowKey:"id",columns:et,dataSource:b,loading:S,scroll:{x:700}}),a().createElement(l.Modal,{title:U?t("Edit group"):t("Add group"),open:T,onCancel:function(){return x(!1)},onOk:function(){return m(function(){var n,a;return p(this,function(o){switch(o.label){case 0:return[4,r.validateFields()];case 1:n=o.sent(),M(!0),o.label=2;case 2:return o.trys.push([2,5,6,7]),[4,e.api.request({url:U?"aiApiUsageGroups:update/".concat(U.id):"aiApiUsageGroups:create",method:"post",data:n})];case 3:return o.sent(),l.message.success(t("Saved successfully")),x(!1),[4,$()];case 4:return o.sent(),[3,7];case 5:return a=o.sent(),l.message.error((0,s.g)(a)),[3,7];case 6:return M(!1),[7];case 7:return[2]}})})()},confirmLoading:k,destroyOnClose:!0,width:720},a().createElement(l.Form,{form:r,layout:"vertical",preserve:!1},a().createElement(l.Form.Item,{name:"name",label:t("Name"),rules:[{required:!0}]},a().createElement(l.Input,{disabled:null==U?void 0:U.isDefault})),a().createElement(l.Form.Item,{name:"quotaMode",label:t("Mode"),rules:[{required:!0}]},a().createElement(l.Select,{disabled:!!U,options:[{label:t("Share"),value:"share"},{label:t("Per user"),value:"per_user"}]})),a().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:t("Rate limit per minute"),rules:[{required:!0}]},a().createElement(l.InputNumber,{min:1,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"periodType",label:t("Period"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Daily"),value:"daily"},{label:t("Monthly"),value:"monthly"}]})),a().createElement(l.Form.Item,{name:"timezone",label:t("Timezone"),rules:[{required:!0}]},a().createElement(l.Input,{placeholder:"UTC"})),a().createElement(l.Form.Item,{name:"requestLimit",label:t("Request limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"totalTokenLimit",label:t("Token limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"costLimit",label:t("Cost limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"currency",label:t("Currency"),rules:[{required:!0}]},a().createElement(l.Input,null)),a().createElement(l.Form.Item,{name:"rejectUnpricedModel",label:t("Reject unpriced models"),valuePropName:"checked"},a().createElement(l.Switch,null)),a().createElement(l.Form.Item,{name:"missingUsageBehavior",label:t("Missing usage behavior"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Use reserved estimate"),value:"use_reserved"},{label:t("Allow without token charge"),value:"allow"}]})),a().createElement(l.Form.Item,{name:"contextOverflowBehavior",label:t("Context overflow behavior"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Reject request"),value:"reject"},{label:t("Truncate oldest conversation turns"),value:"truncate"}]})),a().createElement(l.Form.Item,{name:"allowedLlmServices",label:t("Allowed LLM services"),extra:t("Leave empty to allow every service enabled in the general configuration.")},a().createElement(l.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:Y})),a().createElement(l.Form.Item,{name:"allowAllModels",label:t("Allow all models"),valuePropName:"checked"},a().createElement(l.Switch,null)),!1===f&&a().createElement(l.Form.Item,{name:"allowedModels",label:t("Allowed models")},a().createElement(l.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:Z})),a().createElement(l.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},a().createElement(l.Switch,null))),U&&a().createElement(l.Card,{title:t("Members"),size:"small",style:{marginTop:24}},U.isDefault?a().createElement(a().Fragment,null,a().createElement(l.Alert,{type:"info",showIcon:!0,message:t("Users who do not belong to any other group automatically use this default group — no need to add members."),style:{marginBottom:12*(j.length>0)}}),j.length>0&&a().createElement(l.Table,{rowKey:"id",columns:er,dataSource:j,loading:B,pagination:!1,size:"small"})):a().createElement(a().Fragment,null,a().createElement(l.Form,{form:i,layout:"inline"},a().createElement(l.Form.Item,{name:"userId",label:t("User"),rules:[{required:!0}],style:{minWidth:240}},a().createElement(l.Select,{showSearch:!0,optionFilterProp:"label",options:N.map(function(e){return{label:X(e),value:e.id}}),onFocus:function(){return Q()}})),a().createElement(l.Form.Item,null,a().createElement(l.Button,{type:"primary",onClick:function(){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:if(!U)return[2];return[4,i.validateFields()];case 1:r=a.sent(),a.label=2;case 2:return a.trys.push([2,6,,7]),[4,e.api.request({url:"aiApiUsageGroups:addMember",method:"post",data:{groupId:U.id,userId:r.userId}})];case 3:return a.sent(),l.message.success(t("Member added")),i.resetFields(),[4,H(U.id)];case 4:return a.sent(),[4,Q()];case 5:return a.sent(),[3,7];case 6:return n=a.sent(),l.message.error((0,s.g)(n)),[3,7];case 7:return[2]}})})()}},t("Add member")))),a().createElement(l.Table,{rowKey:"id",columns:er,dataSource:j,loading:B,pagination:!1,size:"small"})))))}},650:function(e,t,r){r.d(t,{k:function(){return o}});var n=r(155),a=r(694),l=JSON.parse('{"UU":"plugin-ai-api"}');function o(){var e=(0,a.useFlowEngine)();return(0,n.useCallback)(function(t){return e.context.t(t,{ns:[l.UU,"client"]})},[e])}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function a(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return a},m:function(){return n}})}}]);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).push([["562"],{641:function(e,t,r){r.r(t),r.d(t,{default:function(){return b}});var n=r(155),o=r.n(n),a=r(59),l=r(694),i=r(650),c=r(630);function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function s(e,t,r,n,o,a,l){try{var i=e[a](l),c=i.value}catch(e){r(e);return}i.done?t(c):Promise.resolve(c).then(n,o)}function m(e){return function(){var t=this,r=arguments;return new Promise(function(n,o){var a=e.apply(t,r);function l(e){s(a,n,o,l,i,"next",e)}function i(e){s(a,n,o,l,i,"throw",e)}l(void 0)})}}function d(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){var n;n=r[t],t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n})}return e}function p(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,o=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var a=[],l=!0,i=!1;try{for(o=o.call(e);!(l=(r=o.next()).done)&&(a.push(r.value),!t||a.length!==t);l=!0);}catch(e){i=!0,n=e}finally{try{l||null==o.return||o.return()}finally{if(i)throw n}}return a}}(e,t)||y(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(e,t){if(e){if("string"==typeof e)return u(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return u(e,t)}}function f(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},l=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(l,"next",{value:c(0)}),i(l,"throw",{value:c(1)}),i(l,"return",{value:c(2)}),"function"==typeof Symbol&&i(l,Symbol.iterator,{value:function(){return this}}),l;function c(i){return function(c){var u=[i,c];if(r)throw TypeError("Generator is already executing.");for(;l&&(l=0,u[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&u[0]?n.return:u[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,u[1])).done)return o;switch(n=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,n=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===u[0]||2===u[0])){a=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){a.label=u[1];break}if(6===u[0]&&a.label<o[1]){a.label=o[1],o=u;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(u);break}o[2]&&a.ops.pop(),a.trys.pop();continue}u=t.call(e,a)}catch(e){u=[6,e],n=0}finally{r=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}}}function b(){var e=(0,l.useFlowContext)(),t=(0,i.k)(),r=p(a.Form.useForm(),1)[0],s=a.Form.useWatch("llmService",r),b=p((0,n.useState)([]),2),v=b[0],h=b[1],w=p((0,n.useState)([]),2),g=w[0],S=w[1],E=p((0,n.useState)([]),2),k=E[0],O=E[1],x=p((0,n.useState)(!1),2),I=x[0],P=x[1],F=p((0,n.useState)(!1),2),j=F[0],C=F[1],M=p((0,n.useState)(!1),2),A=M[0],T=M[1],L=p((0,n.useState)(),2),D=L[0],N=L[1],B=p((0,n.useState)(!1),2),_=B[0],q=B[1],W=(0,n.useCallback)(function(){return m(function(){var t,r,n,o;return f(this,function(l){switch(l.label){case 0:C(!0),l.label=1;case 1:return l.trys.push([1,3,4,5]),[4,Promise.all([e.api.request({url:"aiApiModelMetadata:list",method:"get",params:{pageSize:200,sort:"llmService"}}),e.api.request({url:"ai:listLLMServices",method:"get"})])];case 2:return r=(t=p.apply(void 0,[l.sent(),2]))[0],n=t[1],h((0,c.m)(r,[])),S((0,c.m)(n,[])),[3,5];case 3:return o=l.sent(),a.message.error((0,c.g)(o)),[3,5];case 4:return C(!1),[7];case 5:return[2]}})})()},[e.api]);(0,n.useEffect)(function(){W()},[W]);var U=(0,n.useCallback)(function(r,n){return m(function(){var o,l,i;return f(this,function(s){switch(s.label){case 0:P(!0),s.label=1;case 1:return s.trys.push([1,3,4,5]),[4,e.api.request({url:"ai:listModels",method:"get",params:{llmService:r}})];case 2:return o=s.sent(),l=(0,c.m)(o,[]),O(n&&!l.some(function(e){return e.id===n})?[{id:n}].concat(function(e){if(Array.isArray(e))return u(e)}(l)||function(e){if("u">typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(l)||y(l)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()):l),[3,5];case 3:return i=s.sent(),O(n?[{id:n}]:[]),a.message.error("".concat(t("Failed to load models"),": ").concat((0,c.g)(i))),[3,5];case 4:return P(!1),[7];case 5:return[2]}})})()},[e.api,t]),V=function(e){N(e),r.setFieldsValue(d({},e)),q(!0),U(e.llmService,e.model)},z=[{title:t("LLM service"),dataIndex:"llmService",key:"llmService",width:160},{title:t("Model"),dataIndex:"model",key:"model",width:180},{title:t("Context window"),dataIndex:"contextWindow",key:"contextWindow",width:140},{title:t("Max completion tokens"),dataIndex:"maxCompletionTokens",key:"maxCompletionTokens",width:170},{title:t("Owned by"),dataIndex:"ownedByOverride",key:"ownedByOverride",width:140},{title:t("Display name"),dataIndex:"displayName",key:"displayName",width:160},{title:t("Initial system prompt"),dataIndex:"systemPrompt",key:"systemPrompt",width:220,ellipsis:!0,render:function(e){return e||"-"}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return o().createElement(a.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",fixed:"right",width:150,render:function(r,n){return o().createElement(a.Space,null,o().createElement(a.Button,{type:"link",onClick:function(){return V(n)}},t("Edit")),o().createElement(a.Popconfirm,{title:t("Delete this override?"),onConfirm:function(){var r;return r=n.id,m(function(){var n;return f(this,function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiModelMetadata:destroy/".concat(r),method:"post"})];case 1:return o.sent(),a.message.success(t("Deleted successfully")),[4,W()];case 2:return o.sent(),[3,4];case 3:return n=o.sent(),a.message.error((0,c.g)(n)),[3,4];case 4:return[2]}})})()}},o().createElement(a.Button,{type:"link",danger:!0},t("Delete"))))}}];return o().createElement(a.Card,{title:t("Model metadata"),extra:o().createElement(a.Button,{type:"primary",onClick:function(){N(void 0),O([]),r.resetFields(),r.setFieldsValue({enabled:!0}),q(!0)}},t("Add override"))},o().createElement(a.Table,{rowKey:"id",columns:z,dataSource:v,loading:j,scroll:{x:1450}}),o().createElement(a.Modal,{title:D?t("Edit override"):t("Add override"),open:_,onCancel:function(){return q(!1)},onOk:function(){return m(function(){var n,o,l,i,u,s,m,p,y;return f(this,function(f){switch(f.label){case 0:return[4,r.validateFields()];case 1:var b,v;b=d({},m=f.sent()),v=v={contextWindow:null!=(n=m.contextWindow)?n:null,maxCompletionTokens:null!=(o=m.maxCompletionTokens)?o:null,ownedByOverride:(null==(l=m.ownedByOverride)?void 0:l.trim())||null,displayName:(null==(i=m.displayName)?void 0:i.trim())||null,description:(null==(u=m.description)?void 0:u.trim())||null,systemPrompt:(null==(s=m.systemPrompt)?void 0:s.trim())||null},Object.getOwnPropertyDescriptors?Object.defineProperties(b,Object.getOwnPropertyDescriptors(v)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t})(Object(v)).forEach(function(e){Object.defineProperty(b,e,Object.getOwnPropertyDescriptor(v,e))}),p=b,T(!0),f.label=2;case 2:return f.trys.push([2,5,6,7]),[4,e.api.request({url:D?"aiApiModelMetadata:update/".concat(D.id):"aiApiModelMetadata:create",method:"post",data:p})];case 3:return f.sent(),a.message.success(t("Saved successfully")),q(!1),[4,W()];case 4:return f.sent(),[3,7];case 5:return y=f.sent(),a.message.error((0,c.g)(y)),[3,7];case 6:return T(!1),[7];case 7:return[2]}})})()},confirmLoading:A,destroyOnClose:!0},o().createElement(a.Form,{form:r,layout:"vertical",preserve:!1},o().createElement(a.Form.Item,{name:"llmService",label:t("LLM service"),rules:[{required:!0}]},o().createElement(a.Select,{showSearch:!0,optionFilterProp:"label",onChange:function(e){r.setFieldValue("model",void 0),O([]),U(e)},options:g.map(function(e){return{label:e.title||e.name,value:e.name}})})),o().createElement(a.Form.Item,{name:"model",label:t("Model"),rules:[{required:!0}]},o().createElement(a.Select,{showSearch:!0,optionFilterProp:"label",loading:I,disabled:!s,placeholder:t("Select a model"),options:k.map(function(e){return{label:e.id,value:e.id}})})),o().createElement(a.Form.Item,{name:"contextWindow",label:t("Context window"),tooltip:t("Total input + output token capacity reported to clients.")},o().createElement(a.InputNumber,{min:1,precision:0,style:{width:"100%"},placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"maxCompletionTokens",label:t("Max completion tokens"),tooltip:t("Maximum output tokens reported to clients.")},o().createElement(a.InputNumber,{min:1,precision:0,style:{width:"100%"},placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"ownedByOverride",label:t("Owned by")},o().createElement(a.Input,{placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"displayName",label:t("Display name")},o().createElement(a.Input,{placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"description",label:t("Description")},o().createElement(a.Input.TextArea,{rows:3})),o().createElement(a.Form.Item,{name:"systemPrompt",label:t("Initial system prompt"),tooltip:t("Prepended as the first system message, before any system prompt sent by the client. If the client sends no system prompt, this becomes the system prompt sent to the provider.")},o().createElement(a.Input.TextArea,{rows:4,placeholder:t("Leave empty to not override")})),o().createElement(a.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},o().createElement(a.Switch,null)))))}},650:function(e,t,r){r.d(t,{k:function(){return l}});var n=r(155),o=r(694),a=JSON.parse('{"UU":"plugin-ai-api"}');function l(){var e=(0,o.useFlowEngine)();return(0,n.useCallback)(function(t){return e.context.t(t,{ns:[a.UU,"client"]})},[e])}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function o(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return o},m:function(){return n}})}}]);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunkplugin_ai_api_client_v2=self.webpackChunkplugin_ai_api_client_v2||[]).push([["685"],{244:function(e,t,r){r.r(t),r.d(t,{default:function(){return f}});var n=r(155),a=r.n(n),l=r(59),o=r(694),u=r(650),s=r(630);function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function c(e,t,r,n,a,l,o){try{var u=e[l](o),s=u.value}catch(e){r(e);return}u.done?t(s):Promise.resolve(s).then(n,a)}function m(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var l=e.apply(t,r);function o(e){c(l,n,a,o,u,"next",e)}function u(e){c(l,n,a,o,u,"throw",e)}o(void 0)})}}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r,n,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var l=[],o=!0,u=!1;try{for(a=a.call(e);!(o=(r=a.next()).done)&&(l.push(r.value),!t||l.length!==t);o=!0);}catch(e){u=!0,n=e}finally{try{o||null==a.return||a.return()}finally{if(u)throw n}}return l}}(e,t)||function(e,t){if(e){if("string"==typeof e)return i(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);if("Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r)return Array.from(r);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return i(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){var r,n,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},o=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(o,"next",{value:s(0)}),u(o,"throw",{value:s(1)}),u(o,"return",{value:s(2)}),"function"==typeof Symbol&&u(o,Symbol.iterator,{value:function(){return this}}),o;function s(u){return function(s){var i=[u,s];if(r)throw TypeError("Generator is already executing.");for(;o&&(o=0,i[0]&&(l=0)),l;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return l.label++,{value:i[1],done:!1};case 5:l.label++,n=i[1],i=[0];continue;case 7:i=l.ops.pop(),l.trys.pop();continue;default:if(!(a=(a=l.trys).length>0&&a[a.length-1])&&(6===i[0]||2===i[0])){l=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]<a[3])){l.label=i[1];break}if(6===i[0]&&l.label<a[1]){l.label=a[1],a=i;break}if(a&&l.label<a[2]){l.label=a[2],l.ops.push(i);break}a[2]&&l.ops.pop(),l.trys.pop();continue}i=t.call(e,l)}catch(e){i=[6,e],n=0}finally{r=a=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}}}function f(){var e=(0,o.useFlowContext)(),t=(0,u.k)(),r=d(l.Form.useForm(),1)[0],i=d(l.Form.useForm(),1)[0],c=l.Form.useWatch("allowedLlmServices",r),f=l.Form.useWatch("allowAllModels",r),h=d((0,n.useState)([]),2),b=h[0],g=h[1],v=d((0,n.useState)([]),2),y=v[0],w=v[1],E=d((0,n.useState)(!1),2),S=E[0],I=E[1],F=d((0,n.useState)(!1),2),k=F[0],M=F[1],A=d((0,n.useState)(),2),U=A[0],C=A[1],q=d((0,n.useState)(!1),2),T=q[0],x=q[1],P=d((0,n.useState)([]),2),j=P[0],L=P[1],D=d((0,n.useState)(!1),2),B=D[0],z=D[1],_=d((0,n.useState)([]),2),G=_[0],N=_[1],O=d((0,n.useState)(""),2),R=O[0],K=O[1],W=d((0,n.useState)(null),2),V=W[0],J=W[1],$=(0,n.useCallback)(function(){return m(function(){var r,n,a,o;return p(this,function(u){switch(u.label){case 0:I(!0),u.label=1;case 1:return u.trys.push([1,3,4,5]),[4,e.api.request({url:"aiApiUsageGroups:list",method:"get",params:{pageSize:200,sort:"-updatedAt"}})];case 2:return r=u.sent(),g((0,s.m)(r,[])),[3,5];case 3:return n=u.sent(),l.message.error((0,s.g)(n)),[3,5];case 4:return I(!1),[7];case 5:return u.trys.push([5,7,,8]),[4,e.api.request({url:"ai:listAllEnabledModels",method:"get"})];case 6:return a=u.sent(),w((0,s.m)(a,[])),[3,8];case 7:return o=u.sent(),w([]),l.message.error("".concat(t("Failed to load models"),": ").concat((0,s.g)(o))),[3,8];case 8:return[2]}})})()},[e.api,t]),H=(0,n.useCallback)(function(t){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:z(!0),a.label=1;case 1:return a.trys.push([1,3,4,5]),[4,e.api.request({url:"aiApiGroupMembers:list",method:"get",params:{filter:{groupId:t},pageSize:1e3,appends:["user"]}})];case 2:return r=a.sent(),L((0,s.m)(r,[])),[3,5];case 3:return n=a.sent(),l.message.error((0,s.g)(n)),[3,5];case 4:return z(!1),[7];case 5:return[2]}})})()},[e.api]),Q=(0,n.useCallback)(function(t){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),[4,e.api.request({url:"aiApiUsageGroups:listUnassignedUsers",method:"get",params:{keyword:t,pageSize:100}})];case 1:return r=a.sent(),N((0,s.m)(r,[])),[3,3];case 2:return n=a.sent(),l.message.error((0,s.g)(n)),[3,3];case 3:return[2]}})})()},[e.api]);(0,n.useEffect)(function(){$()},[$]);var X=function(e){var t;return(null==e?void 0:e.nickname)||(null==e?void 0:e.username)||(null==e?void 0:e.email)||String(null!=(t=null==e?void 0:e.id)?t:"")},Y=(0,n.useMemo)(function(){return y.map(function(e){return{label:e.llmServiceTitle||e.llmService,value:e.llmService}})},[y]),Z=(0,n.useMemo)(function(){var e=new Set(c||[]);return y.filter(function(t){return e.has(t.llmService)}).flatMap(function(e){return(e.enabledModels||[]).map(function(t){return{label:"".concat(e.llmServiceTitle||e.llmService," / ").concat(t.label||t.value),value:"".concat(e.llmService,"/").concat(t.value)}})})},[y,c]),ee=function(e){var t;return(null==(t=Y.find(function(t){return t.value===e}))?void 0:t.label)||e},et=[{title:t("Name"),dataIndex:"name",key:"name",width:180},{title:t("Default"),dataIndex:"isDefault",key:"isDefault",width:100,render:function(e){return e?a().createElement(l.Tag,{color:"blue"},t("Default")):null}},{title:t("Mode"),dataIndex:"quotaMode",key:"quotaMode",width:120},{title:t("Rate limit/min"),dataIndex:"rateLimitPerMinute",key:"rateLimitPerMinute",width:140},{title:t("Model access"),key:"modelAccess",width:240,render:function(e,r){var n=r.allowedLlmServices||[],o=r.allowedModels||[],u=0===n.length,s=!1!==r.allowAllModels;return u&&s?a().createElement(l.Tag,{color:"blue"},t("All models")):a().createElement(l.Space,{size:[0,4],wrap:!0},a().createElement(l.Tag,null,u?t("All services"):n.map(function(e){return ee(e)}).join(", ")),a().createElement(l.Tag,{color:s?"blue":void 0},s?t("All models"):o.length?o.join(", "):t("No models")))}},{title:t("Status"),dataIndex:"enabled",key:"enabled",width:100,render:function(e){return a().createElement(l.Tag,{color:e?"green":"default"},e?t("Enabled"):t("Disabled"))}},{title:t("Actions"),key:"actions",width:150,fixed:"right",render:function(n,o){return a().createElement(l.Space,{size:0},a().createElement(l.Button,{type:"link",onClick:function(){return m(function(){return p(this,function(e){switch(e.label){case 0:return C(o),r.setFieldsValue(o),x(!0),[4,H(o.id)];case 1:if(e.sent(),o.isDefault)return[3,3];return[4,Q()];case 2:e.sent(),e.label=3;case 3:return[2]}})})()}},t("Edit")),!o.isDefault&&a().createElement(l.Popconfirm,{title:t("Delete this group?"),onConfirm:function(){return m(function(){var r;return p(this,function(n){switch(n.label){case 0:return n.trys.push([0,3,,4]),[4,e.api.request({url:"aiApiUsageGroups:destroy/".concat(o.id),method:"post"})];case 1:return n.sent(),l.message.success(t("Deleted successfully")),[4,$()];case 2:return n.sent(),[3,4];case 3:return r=n.sent(),l.message.error((0,s.g)(r)),[3,4];case 4:return[2]}})})()}},a().createElement(l.Button,{type:"link",danger:!0},t("Delete"))))}}],er=[{title:t("User"),key:"user",render:function(e,t){return X(t.user)||String(t.userId)}},{title:t("Actions"),key:"actions",width:120,render:function(r,n){return a().createElement(l.Popconfirm,{title:t("Remove member?"),onConfirm:function(){return m(function(){var r;return p(this,function(a){switch(a.label){case 0:return a.trys.push([0,5,,6]),[4,e.api.request({url:"aiApiUsageGroups:removeMember",method:"post",data:{groupId:n.groupId,userId:n.userId}})];case 1:if(a.sent(),l.message.success(t("Member removed")),!U)return[3,4];return[4,H(U.id)];case 2:return a.sent(),[4,Q()];case 3:a.sent(),a.label=4;case 4:return[3,6];case 5:return r=a.sent(),l.message.error((0,s.g)(r)),[3,6];case 6:return[2]}})})()}},a().createElement(l.Button,{type:"link",danger:!0},t("Remove")))}}];return a().createElement(l.Card,{title:t("Usage groups"),extra:a().createElement(l.Button,{type:"primary",onClick:function(){C(void 0),L([]),r.setFieldsValue({name:"",quotaMode:"per_user",rateLimitPerMinute:60,enabled:!0,periodType:"monthly",timezone:"UTC",currency:"USD",rejectUnpricedModel:!0,missingUsageBehavior:"use_reserved",contextOverflowBehavior:"reject",allowedLlmServices:[],allowAllModels:!0,allowedModels:[]}),x(!0)}},t("Add group"))},a().createElement(l.Row,{gutter:[16,16],style:{marginBottom:16}},a().createElement(l.Col,{span:12},a().createElement(l.Input.Search,{placeholder:t("Search group by user"),value:R,onChange:function(e){return K(e.target.value)},onSearch:function(){return m(function(){var r,n,a,o;return p(this,function(u){switch(u.label){case 0:if(!R.trim())return[2];u.label=1;case 1:return u.trys.push([1,4,,5]),[4,e.api.request({url:"aiApiUsageGroups:searchUsers",method:"get",params:{keyword:R,pageSize:1}})];case 2:if(r=u.sent(),0===(n=(0,s.m)(r,[])).length)return l.message.warning(t("User not found")),J(null),[2];return[4,e.api.request({url:"aiApiUsageGroups:getByUser",method:"get",params:{userId:n[0].id}})];case 3:return a=u.sent(),J((0,s.m)(a,null)),[3,5];case 4:return o=u.sent(),l.message.error((0,s.g)(o)),[3,5];case 5:return[2]}})})()},enterButton:!0})),a().createElement(l.Col,{span:12},V&&a().createElement(l.Tag,{color:"blue"},t("User belongs to"),": ",V.name))),a().createElement(l.Table,{rowKey:"id",columns:et,dataSource:b,loading:S,scroll:{x:700}}),a().createElement(l.Modal,{title:U?t("Edit group"):t("Add group"),open:T,onCancel:function(){return x(!1)},onOk:function(){return m(function(){var n,a;return p(this,function(o){switch(o.label){case 0:return[4,r.validateFields()];case 1:n=o.sent(),M(!0),o.label=2;case 2:return o.trys.push([2,5,6,7]),[4,e.api.request({url:U?"aiApiUsageGroups:update/".concat(U.id):"aiApiUsageGroups:create",method:"post",data:n})];case 3:return o.sent(),l.message.success(t("Saved successfully")),x(!1),[4,$()];case 4:return o.sent(),[3,7];case 5:return a=o.sent(),l.message.error((0,s.g)(a)),[3,7];case 6:return M(!1),[7];case 7:return[2]}})})()},confirmLoading:k,destroyOnClose:!0,width:720},a().createElement(l.Form,{form:r,layout:"vertical",preserve:!1},a().createElement(l.Form.Item,{name:"name",label:t("Name"),rules:[{required:!0}]},a().createElement(l.Input,{disabled:null==U?void 0:U.isDefault})),a().createElement(l.Form.Item,{name:"quotaMode",label:t("Mode"),rules:[{required:!0}]},a().createElement(l.Select,{disabled:!!U,options:[{label:t("Share"),value:"share"},{label:t("Per user"),value:"per_user"}]})),a().createElement(l.Form.Item,{name:"rateLimitPerMinute",label:t("Rate limit per minute"),rules:[{required:!0}]},a().createElement(l.InputNumber,{min:1,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"periodType",label:t("Period"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Daily"),value:"daily"},{label:t("Monthly"),value:"monthly"}]})),a().createElement(l.Form.Item,{name:"timezone",label:t("Timezone"),rules:[{required:!0}]},a().createElement(l.Input,{placeholder:"UTC"})),a().createElement(l.Form.Item,{name:"requestLimit",label:t("Request limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"totalTokenLimit",label:t("Token limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"costLimit",label:t("Cost limit")},a().createElement(l.InputNumber,{min:0,stringMode:!0,style:{width:"100%"}})),a().createElement(l.Form.Item,{name:"currency",label:t("Currency"),rules:[{required:!0}]},a().createElement(l.Input,null)),a().createElement(l.Form.Item,{name:"rejectUnpricedModel",label:t("Reject unpriced models"),valuePropName:"checked"},a().createElement(l.Switch,null)),a().createElement(l.Form.Item,{name:"missingUsageBehavior",label:t("Missing usage behavior"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Use reserved estimate"),value:"use_reserved"},{label:t("Allow without token charge"),value:"allow"}]})),a().createElement(l.Form.Item,{name:"contextOverflowBehavior",label:t("Context overflow behavior"),rules:[{required:!0}]},a().createElement(l.Select,{options:[{label:t("Reject request"),value:"reject"},{label:t("Truncate oldest conversation turns"),value:"truncate"}]})),a().createElement(l.Form.Item,{name:"allowedLlmServices",label:t("Allowed LLM services"),extra:t("Leave empty to allow every service enabled in the general configuration.")},a().createElement(l.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:Y})),a().createElement(l.Form.Item,{name:"allowAllModels",label:t("Allow all models"),valuePropName:"checked"},a().createElement(l.Switch,null)),!1===f&&a().createElement(l.Form.Item,{name:"allowedModels",label:t("Allowed models")},a().createElement(l.Select,{mode:"multiple",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:Z})),a().createElement(l.Form.Item,{name:"enabled",label:t("Enabled"),valuePropName:"checked"},a().createElement(l.Switch,null))),U&&a().createElement(l.Card,{title:t("Members"),size:"small",style:{marginTop:24}},U.isDefault?a().createElement(a().Fragment,null,a().createElement(l.Alert,{type:"info",showIcon:!0,message:t("Users who do not belong to any other group automatically use this default group — no need to add members."),style:{marginBottom:12*(j.length>0)}}),j.length>0&&a().createElement(l.Table,{rowKey:"id",columns:er,dataSource:j,loading:B,pagination:!1,size:"small"})):a().createElement(a().Fragment,null,a().createElement(l.Form,{form:i,layout:"inline"},a().createElement(l.Form.Item,{name:"userId",label:t("User"),rules:[{required:!0}],style:{minWidth:240}},a().createElement(l.Select,{showSearch:!0,optionFilterProp:"label",options:G.map(function(e){return{label:X(e),value:e.id}}),onFocus:function(){return Q()}})),a().createElement(l.Form.Item,null,a().createElement(l.Button,{type:"primary",onClick:function(){return m(function(){var r,n;return p(this,function(a){switch(a.label){case 0:if(!U)return[2];return[4,i.validateFields()];case 1:r=a.sent(),a.label=2;case 2:return a.trys.push([2,6,,7]),[4,e.api.request({url:"aiApiUsageGroups:addMember",method:"post",data:{groupId:U.id,userId:r.userId}})];case 3:return a.sent(),l.message.success(t("Member added")),i.resetFields(),[4,H(U.id)];case 4:return a.sent(),[4,Q()];case 5:return a.sent(),[3,7];case 6:return n=a.sent(),l.message.error((0,s.g)(n)),[3,7];case 7:return[2]}})})()}},t("Add member")))),a().createElement(l.Table,{rowKey:"id",columns:er,dataSource:j,loading:B,pagination:!1,size:"small"})))))}},650:function(e,t,r){r.d(t,{k:function(){return o}});var n=r(155),a=r(694),l=JSON.parse('{"UU":"plugin-ai-api"}');function o(){var e=(0,a.useFlowEngine)();return(0,n.useCallback)(function(t){return e.context.t(t,{ns:[l.UU,"client"]})},[e])}},630:function(e,t,r){function n(e,t){var r,n;return e&&(void 0===e?"undefined":e&&"u">typeof Symbol&&e.constructor===Symbol?"symbol":typeof e)=="object"?null!=(r=null==(n=e.data)?void 0:n.data)?r:t:t}function a(e){var t;return(null!=(t=Error)&&"u">typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t)?e.message:String(e)}r.d(t,{g:function(){return a},m:function(){return n}})}}]);
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
var __defProp = Object.defineProperty;
|
|
11
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __export = (target, all) => {
|
|
15
|
-
for (var name in all)
|
|
16
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let key of __getOwnPropNames(from))
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
-
}
|
|
24
|
-
return to;
|
|
25
|
-
};
|
|
26
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var ai_api_user_permissions_exports = {};
|
|
28
|
-
__export(ai_api_user_permissions_exports, {
|
|
29
|
-
default: () => ai_api_user_permissions_default
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(ai_api_user_permissions_exports);
|
|
32
|
-
var import_database = require("@nocobase/database");
|
|
33
|
-
var ai_api_user_permissions_default = (0, import_database.defineCollection)({
|
|
34
|
-
name: "aiApiUserPermissions",
|
|
35
|
-
autoGenId: true,
|
|
36
|
-
fields: [
|
|
37
|
-
{ name: "userId", type: "bigInt", allowNull: false, index: true },
|
|
38
|
-
{
|
|
39
|
-
name: "user",
|
|
40
|
-
type: "belongsTo",
|
|
41
|
-
target: "users",
|
|
42
|
-
targetKey: "id",
|
|
43
|
-
foreignKey: "userId",
|
|
44
|
-
constraints: false
|
|
45
|
-
},
|
|
46
|
-
{ name: "enabled", type: "boolean", defaultValue: true, index: true },
|
|
47
|
-
{
|
|
48
|
-
name: "allowedLlmServices",
|
|
49
|
-
type: "json",
|
|
50
|
-
defaultValue: [],
|
|
51
|
-
comment: "LLM service names/titles this user may use. Empty means the user is denied every service."
|
|
52
|
-
},
|
|
53
|
-
{ name: "allowAllModels", type: "boolean", defaultValue: true },
|
|
54
|
-
{
|
|
55
|
-
name: "allowedModels",
|
|
56
|
-
type: "json",
|
|
57
|
-
defaultValue: [],
|
|
58
|
-
comment: 'Array of "serviceName/modelId" this user may use (when allowAllModels=false)'
|
|
59
|
-
}
|
|
60
|
-
],
|
|
61
|
-
indexes: [
|
|
62
|
-
{
|
|
63
|
-
fields: ["userId"],
|
|
64
|
-
unique: true
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
});
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
var __defProp = Object.defineProperty;
|
|
11
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __export = (target, all) => {
|
|
15
|
-
for (var name in all)
|
|
16
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let key of __getOwnPropNames(from))
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
-
}
|
|
24
|
-
return to;
|
|
25
|
-
};
|
|
26
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var ai_api_user_quota_buckets_exports = {};
|
|
28
|
-
__export(ai_api_user_quota_buckets_exports, {
|
|
29
|
-
default: () => ai_api_user_quota_buckets_default
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(ai_api_user_quota_buckets_exports);
|
|
32
|
-
var import_database = require("@nocobase/database");
|
|
33
|
-
var ai_api_user_quota_buckets_default = (0, import_database.defineCollection)({
|
|
34
|
-
name: "aiApiUserQuotaBuckets",
|
|
35
|
-
autoGenId: true,
|
|
36
|
-
fields: [
|
|
37
|
-
{ name: "policyId", type: "bigInt", allowNull: false, index: true },
|
|
38
|
-
{ name: "userId", type: "bigInt", allowNull: false, index: true },
|
|
39
|
-
{ name: "periodStart", type: "datetimeTz", allowNull: false, index: true },
|
|
40
|
-
{ name: "periodEnd", type: "datetimeTz", allowNull: false, index: true },
|
|
41
|
-
{ name: "requestCount", type: "bigInt", allowNull: false, defaultValue: 0 },
|
|
42
|
-
{ name: "totalTokens", type: "bigInt", allowNull: false, defaultValue: 0 },
|
|
43
|
-
{ name: "cost", type: "decimal", precision: 20, scale: 8, allowNull: false, defaultValue: 0 },
|
|
44
|
-
{ name: "reservedRequests", type: "bigInt", allowNull: false, defaultValue: 0 },
|
|
45
|
-
{ name: "reservedTokens", type: "bigInt", allowNull: false, defaultValue: 0 },
|
|
46
|
-
{ name: "reservedCost", type: "decimal", precision: 20, scale: 8, allowNull: false, defaultValue: 0 }
|
|
47
|
-
],
|
|
48
|
-
indexes: [
|
|
49
|
-
{
|
|
50
|
-
fields: ["policyId", "periodStart"],
|
|
51
|
-
unique: true
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
var __defProp = Object.defineProperty;
|
|
11
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __export = (target, all) => {
|
|
15
|
-
for (var name in all)
|
|
16
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let key of __getOwnPropNames(from))
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
-
}
|
|
24
|
-
return to;
|
|
25
|
-
};
|
|
26
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var ai_api_user_quota_policies_exports = {};
|
|
28
|
-
__export(ai_api_user_quota_policies_exports, {
|
|
29
|
-
default: () => ai_api_user_quota_policies_default
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(ai_api_user_quota_policies_exports);
|
|
32
|
-
var import_database = require("@nocobase/database");
|
|
33
|
-
var ai_api_user_quota_policies_default = (0, import_database.defineCollection)({
|
|
34
|
-
name: "aiApiUserQuotaPolicies",
|
|
35
|
-
autoGenId: true,
|
|
36
|
-
fields: [
|
|
37
|
-
{ name: "userId", type: "bigInt", allowNull: false, index: true },
|
|
38
|
-
{
|
|
39
|
-
name: "user",
|
|
40
|
-
type: "belongsTo",
|
|
41
|
-
target: "users",
|
|
42
|
-
targetKey: "id",
|
|
43
|
-
foreignKey: "userId",
|
|
44
|
-
constraints: false
|
|
45
|
-
},
|
|
46
|
-
{ name: "enabled", type: "boolean", defaultValue: true, index: true },
|
|
47
|
-
{ name: "periodType", type: "string", allowNull: false, defaultValue: "monthly" },
|
|
48
|
-
{ name: "timezone", type: "string", allowNull: false, defaultValue: "UTC" },
|
|
49
|
-
{ name: "requestLimit", type: "bigInt", allowNull: true },
|
|
50
|
-
{ name: "totalTokenLimit", type: "bigInt", allowNull: true },
|
|
51
|
-
{ name: "costLimit", type: "decimal", precision: 20, scale: 8, allowNull: true },
|
|
52
|
-
{ name: "currency", type: "string", allowNull: false, defaultValue: "USD" },
|
|
53
|
-
{ name: "rejectUnpricedModel", type: "boolean", defaultValue: true },
|
|
54
|
-
{ name: "missingUsageBehavior", type: "string", allowNull: false, defaultValue: "use_reserved" },
|
|
55
|
-
{ name: "contextOverflowBehavior", type: "string", allowNull: false, defaultValue: "reject" }
|
|
56
|
-
],
|
|
57
|
-
indexes: [
|
|
58
|
-
{
|
|
59
|
-
fields: ["userId"],
|
|
60
|
-
unique: true
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
});
|