@xpert-ai/plugin-sdk 3.7.0 → 3.7.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/index.cjs.js CHANGED
@@ -4,11 +4,16 @@ var common = require('@nestjs/common');
4
4
  var constants = require('@nestjs/common/constants');
5
5
  var lodashEs = require('lodash-es');
6
6
  var core = require('@nestjs/core');
7
+ var rxjs = require('rxjs');
8
+ var contracts = require('@metad/contracts');
9
+ var node_async_hooks = require('node:async_hooks');
10
+ var passportJwt = require('passport-jwt');
11
+ var jsonwebtoken = require('jsonwebtoken');
12
+ var node_crypto = require('node:crypto');
7
13
  var cqrs = require('@nestjs/cqrs');
8
14
  var fs = require('fs');
9
15
  var http = require('http');
10
16
  var https = require('https');
11
- var contracts = require('@metad/contracts');
12
17
  var tools = require('@langchain/core/tools');
13
18
  var zod = require('zod');
14
19
  var fsPromises = require('fs/promises');
@@ -16,10 +21,8 @@ var path = require('path');
16
21
  var i18next = require('i18next');
17
22
  var FsBackend = require('i18next-fs-backend');
18
23
  var yaml = require('yaml');
19
- var node_async_hooks = require('node:async_hooks');
20
- var passportJwt = require('passport-jwt');
21
- var jsonwebtoken = require('jsonwebtoken');
22
- var node_crypto = require('node:crypto');
24
+ var Ajv = require('ajv');
25
+ var schemaDraft04 = require('ajv/dist/refs/json-schema-draft-06.json');
23
26
  var _axios = require('axios');
24
27
  var openai = require('@langchain/openai');
25
28
  var documents = require('@langchain/core/documents');
@@ -84,6 +87,11 @@ var _axios__namespace = /*#__PURE__*/_interopNamespaceDefault(_axios);
84
87
  };
85
88
  }
86
89
 
90
+ const ORGANIZATION_METADATA_KEY = 'xpert:organizationId';
91
+ const PLUGIN_METADATA_KEY = 'xpert:pluginName';
92
+ const GLOBAL_ORGANIZATION_SCOPE = 'global';
93
+ const STRATEGY_META_KEY = 'XPERT_STRATEGY_META_KEY';
94
+
87
95
  function _extends() {
88
96
  _extends = Object.assign || function assign(target) {
89
97
  for(var i = 1; i < arguments.length; i++){
@@ -115,7 +123,7 @@ function createPluginLogger(scope, baseMeta = {}) {
115
123
  }
116
124
 
117
125
  const INTEGRATION_STRATEGY = 'INTEGRATION_STRATEGY';
118
- const IntegrationStrategyKey = (provider)=>common.SetMetadata(INTEGRATION_STRATEGY, provider);
126
+ const IntegrationStrategyKey = (provider)=>common.applyDecorators(common.SetMetadata(INTEGRATION_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, INTEGRATION_STRATEGY));
119
127
 
120
128
  function __decorate(decorators, target, key, desc) {
121
129
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -131,35 +139,346 @@ typeof SuppressedError === "function" ? SuppressedError : function _SuppressedEr
131
139
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
132
140
  };
133
141
 
142
+ // request-context.ts
143
+ class RequestContext {
144
+ static currentRequestContext() {
145
+ const session = getRequestContext();
146
+ return session;
147
+ }
148
+ static currentRequest() {
149
+ const requestContext = RequestContext.currentRequestContext();
150
+ if (requestContext) {
151
+ return requestContext.request;
152
+ }
153
+ return null;
154
+ }
155
+ static currentTenantId() {
156
+ const user = RequestContext.currentUser();
157
+ if (user) {
158
+ return user.tenantId;
159
+ }
160
+ return null;
161
+ }
162
+ static currentUserId() {
163
+ const user = RequestContext.currentUser();
164
+ if (user) {
165
+ return user.id;
166
+ }
167
+ return null;
168
+ }
169
+ static currentRoleId() {
170
+ const user = RequestContext.currentUser();
171
+ if (user) {
172
+ return user.roleId;
173
+ }
174
+ return null;
175
+ }
176
+ static currentUser(throwError) {
177
+ const requestContext = RequestContext.currentRequestContext();
178
+ if (requestContext) {
179
+ // tslint:disable-next-line
180
+ const user = requestContext.request['user'];
181
+ if (user) {
182
+ return user;
183
+ }
184
+ }
185
+ if (throwError) {
186
+ throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
187
+ }
188
+ return null;
189
+ }
190
+ static hasPermission(permission, throwError) {
191
+ return this.hasPermissions([
192
+ permission
193
+ ], throwError);
194
+ }
195
+ /**
196
+ * Retrieves the language code from the headers of the current request.
197
+ * @returns The language code (LanguagesEnum) extracted from the headers, or the default language (ENGLISH) if not found.
198
+ */ static getLanguageCode() {
199
+ // Retrieve the current request
200
+ const req = RequestContext.currentRequest();
201
+ // Variable to store the extracted language code
202
+ let lang;
203
+ // Check if a request exists
204
+ if (req) {
205
+ // Check if the 'language' header exists in the request
206
+ if (req.headers && req.headers['language']) {
207
+ // If found, set the lang variable
208
+ lang = req.headers['language'];
209
+ }
210
+ }
211
+ // Return the extracted language code or the default language (ENGLISH) if not found
212
+ return lang || contracts.LanguagesEnum.English;
213
+ }
214
+ static getOrganizationId() {
215
+ const req = this.currentRequest();
216
+ let organizationId;
217
+ const keys = [
218
+ 'organization-id'
219
+ ];
220
+ if (req) {
221
+ for (const key of keys){
222
+ if (req.headers && req.headers[key]) {
223
+ organizationId = req.headers[key];
224
+ break;
225
+ }
226
+ }
227
+ }
228
+ return organizationId;
229
+ }
230
+ static hasPermissions(findPermissions, throwError) {
231
+ const requestContext = RequestContext.currentRequestContext();
232
+ if (requestContext) {
233
+ // tslint:disable-next-line
234
+ const token = passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
235
+ if (token) {
236
+ const { permissions } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
237
+ if (permissions) {
238
+ const found = permissions.filter((value)=>findPermissions.indexOf(value) >= 0);
239
+ if (found.length === findPermissions.length) {
240
+ return true;
241
+ }
242
+ } else {
243
+ return false;
244
+ }
245
+ }
246
+ }
247
+ if (throwError) {
248
+ throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
249
+ }
250
+ return false;
251
+ }
252
+ static hasAnyPermission(findPermissions, throwError) {
253
+ const requestContext = RequestContext.currentRequestContext();
254
+ if (requestContext) {
255
+ // tslint:disable-next-line
256
+ const token = passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
257
+ if (token) {
258
+ const { permissions } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
259
+ const found = permissions.filter((value)=>findPermissions.indexOf(value) >= 0);
260
+ if (found.length > 0) {
261
+ return true;
262
+ }
263
+ }
264
+ }
265
+ if (throwError) {
266
+ throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
267
+ }
268
+ return false;
269
+ }
270
+ static currentToken(throwError) {
271
+ const requestContext = RequestContext.currentRequestContext();
272
+ if (requestContext) {
273
+ // tslint:disable-next-line
274
+ return passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
275
+ }
276
+ if (throwError) {
277
+ throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
278
+ }
279
+ return null;
280
+ }
281
+ /**
282
+ * Checks if the current user has a specific role.
283
+ * @param {RolesEnum} role - The role to check.
284
+ * @param {boolean} throwError - Flag indicating whether to throw an error if the role is not granted.
285
+ * @returns {boolean} - True if the user has the role, otherwise false.
286
+ */ static hasRole(role, throwError) {
287
+ return this.hasRoles([
288
+ role
289
+ ], throwError);
290
+ }
291
+ /**
292
+ * Checks if the current request context has any of the specified roles.
293
+ *
294
+ * @param roles - An array of roles to check.
295
+ * @param throwError - Whether to throw an error if no roles are found.
296
+ * @returns True if any of the required roles are found, otherwise false.
297
+ */ static hasRoles(roles, throwError) {
298
+ const context = RequestContext.currentRequestContext();
299
+ if (context) {
300
+ try {
301
+ // tslint:disable-next-line
302
+ const token = this.currentToken();
303
+ if (token) {
304
+ const { role } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
305
+ return roles.includes(role != null ? role : null);
306
+ } else if (this.currentUser().role) {
307
+ return roles.includes(this.currentUser().role.name);
308
+ }
309
+ } catch (error) {
310
+ if (error instanceof jsonwebtoken.JsonWebTokenError) {
311
+ return false;
312
+ } else {
313
+ throw error;
314
+ }
315
+ }
316
+ }
317
+ if (throwError) {
318
+ throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
319
+ }
320
+ return false;
321
+ }
322
+ constructor(request, response, reqId, userId, extras = {}){
323
+ this.request = request;
324
+ this.response = response;
325
+ this.reqId = reqId;
326
+ this.userId = userId;
327
+ this.extras = extras;
328
+ }
329
+ }
330
+ const als = new node_async_hooks.AsyncLocalStorage();
331
+ function getRequestContext() {
332
+ return als.getStore();
333
+ }
334
+
335
+ // request-context.middleware.ts
336
+ exports.RequestContextMiddleware = class RequestContextMiddleware {
337
+ use(req, _res, next) {
338
+ var _req_user;
339
+ const reqId = req.headers['x-request-id'] || node_crypto.randomUUID();
340
+ // The userId can be placed in the authentication result here.
341
+ const userId = (_req_user = req['user']) == null ? void 0 : _req_user['id'];
342
+ const ctx = new RequestContext(req, _res, reqId, userId);
343
+ als.run(ctx, next);
344
+ }
345
+ };
346
+ exports.RequestContextMiddleware = __decorate([
347
+ common.Injectable()
348
+ ], exports.RequestContextMiddleware);
349
+ function runWithRequestContext(req, res, next) {
350
+ var _req_user;
351
+ const reqId = req.headers['x-request-id'] || node_crypto.randomUUID();
352
+ const userId = (_req_user = req['user']) == null ? void 0 : _req_user['id'];
353
+ const ctx = new RequestContext(req, res, reqId, userId);
354
+ // Enable ALS scope
355
+ als.run(ctx, next);
356
+ }
357
+
358
+ exports.StrategyBus = class StrategyBus {
359
+ upsert(strategyType, entry) {
360
+ this.subject.next({
361
+ type: 'UPSERT',
362
+ strategyType,
363
+ entry
364
+ });
365
+ }
366
+ remove(orgId, pluginName) {
367
+ this.subject.next({
368
+ type: 'REMOVE',
369
+ orgId,
370
+ pluginName
371
+ });
372
+ }
373
+ constructor(){
374
+ this.subject = new rxjs.Subject();
375
+ this.events$ = this.subject.asObservable();
376
+ }
377
+ };
378
+ exports.StrategyBus = __decorate([
379
+ common.Injectable()
380
+ ], exports.StrategyBus);
381
+
134
382
  class BaseStrategyRegistry {
135
383
  onModuleInit() {
384
+ this.bus.events$.pipe(rxjs.filter((event)=>!event.strategyType || event.strategyType === this.strategyKey)).subscribe((evt)=>{
385
+ if (evt.type === 'UPSERT') {
386
+ this.upsert(evt.entry.instance);
387
+ } else if (evt.type === 'REMOVE') {
388
+ this.remove(evt.orgId, evt.pluginName);
389
+ }
390
+ });
136
391
  const providers = this.discoveryService.getProviders();
137
392
  for (const wrapper of providers){
138
393
  const { instance } = wrapper;
139
394
  if (!instance) continue;
140
- const type = this.reflector.get(this.strategyKey, instance.constructor);
141
- if (type) {
142
- this.strategies.set(type, instance);
395
+ this.upsert(instance);
396
+ }
397
+ }
398
+ upsert(instance) {
399
+ const type = this.reflector.get(this.strategyKey, instance.constructor);
400
+ if (type) {
401
+ var _instance_metatype;
402
+ const target = (_instance_metatype = instance.metatype) != null ? _instance_metatype : instance.constructor;
403
+ var _this_reflector_get;
404
+ const organizationId = (_this_reflector_get = this.reflector.get(ORGANIZATION_METADATA_KEY, target)) != null ? _this_reflector_get : GLOBAL_ORGANIZATION_SCOPE;
405
+ var _this_strategies_get;
406
+ const orgMap = (_this_strategies_get = this.strategies.get(organizationId)) != null ? _this_strategies_get : new Map();
407
+ orgMap.set(type, instance);
408
+ this.strategies.set(organizationId, orgMap);
409
+ const pluginName = this.reflector.get(PLUGIN_METADATA_KEY, target);
410
+ this.logger.debug(`Registered strategy of type ${type} for organization ${organizationId} from plugin ${pluginName}`);
411
+ if (pluginName) {
412
+ var _this_pluginStrategies_get;
413
+ const pluginStrategies = (_this_pluginStrategies_get = this.pluginStrategies.get(pluginName)) != null ? _this_pluginStrategies_get : new Set();
414
+ pluginStrategies.add(type);
415
+ this.pluginStrategies.set(pluginName, pluginStrategies);
143
416
  }
144
417
  }
145
418
  }
146
- get(type) {
147
- const strategy = this.strategies.get(type);
419
+ /**
420
+ * Remove all strategies registered by the given plugin for the given organization.
421
+ */ remove(organizationId, pluginName) {
422
+ const strategies = this.pluginStrategies.get(pluginName);
423
+ const orgMap = this.strategies.get(organizationId);
424
+ for (const type of strategies != null ? strategies : []){
425
+ orgMap == null ? void 0 : orgMap.delete(type);
426
+ }
427
+ }
428
+ /**
429
+ * Resolve organization id, falling back to request context org or global scope.
430
+ */ resolveOrganization(organizationId) {
431
+ var _ref;
432
+ return (_ref = organizationId != null ? organizationId : RequestContext.getOrganizationId()) != null ? _ref : GLOBAL_ORGANIZATION_SCOPE;
433
+ }
434
+ /**
435
+ * Get strategy by type from the given organization including global strategies as fallback.
436
+ *
437
+ * @param type
438
+ * @param organizationId
439
+ * @returns
440
+ */ get(type, organizationId) {
441
+ var _this_strategies_get, _this_strategies_get1;
442
+ organizationId != null ? organizationId : organizationId = RequestContext.getOrganizationId();
443
+ const orgKey = this.resolveOrganization(organizationId);
444
+ var _this_strategies_get_get;
445
+ const strategy = (_this_strategies_get_get = (_this_strategies_get = this.strategies.get(orgKey)) == null ? void 0 : _this_strategies_get.get(type)) != null ? _this_strategies_get_get : orgKey === GLOBAL_ORGANIZATION_SCOPE ? undefined : (_this_strategies_get1 = this.strategies.get(GLOBAL_ORGANIZATION_SCOPE)) == null ? void 0 : _this_strategies_get1.get(type);
148
446
  if (!strategy) {
149
447
  throw new Error(`No strategy found for type ${type}`);
150
448
  }
151
449
  return strategy;
152
450
  }
153
- list() {
154
- return Array.from(this.strategies.values());
451
+ /**
452
+ * List all strategies for the given organization including global strategies, or only global strategies if global org is specified.
453
+ *
454
+ * @param organizationId
455
+ * @returns
456
+ */ list(organizationId) {
457
+ var _this_strategies_get, _this_strategies_get1;
458
+ organizationId != null ? organizationId : organizationId = RequestContext.getOrganizationId();
459
+ const orgKey = this.resolveOrganization(organizationId);
460
+ var _this_strategies_get_values;
461
+ const scoped = (_this_strategies_get_values = (_this_strategies_get = this.strategies.get(orgKey)) == null ? void 0 : _this_strategies_get.values()) != null ? _this_strategies_get_values : [];
462
+ var _this_strategies_get_values1;
463
+ const global = orgKey === GLOBAL_ORGANIZATION_SCOPE ? [] : (_this_strategies_get_values1 = (_this_strategies_get1 = this.strategies.get(GLOBAL_ORGANIZATION_SCOPE)) == null ? void 0 : _this_strategies_get1.values()) != null ? _this_strategies_get_values1 : [];
464
+ return Array.from(new Set([
465
+ ...scoped,
466
+ ...global
467
+ ]));
155
468
  }
156
469
  constructor(strategyKey, discoveryService, reflector){
157
470
  this.strategyKey = strategyKey;
158
471
  this.discoveryService = discoveryService;
159
472
  this.reflector = reflector;
473
+ this.logger = new common.Logger(BaseStrategyRegistry.name);
160
474
  this.strategies = new Map();
475
+ this.pluginStrategies = new Map();
161
476
  }
162
477
  }
478
+ __decorate([
479
+ common.Inject(exports.StrategyBus),
480
+ __metadata("design:type", typeof exports.StrategyBus === "undefined" ? Object : exports.StrategyBus)
481
+ ], BaseStrategyRegistry.prototype, "bus", void 0);
163
482
 
164
483
  exports.IntegrationStrategyRegistry = class IntegrationStrategyRegistry extends BaseStrategyRegistry {
165
484
  constructor(discoveryService, reflector){
@@ -176,7 +495,7 @@ exports.IntegrationStrategyRegistry = __decorate([
176
495
  ], exports.IntegrationStrategyRegistry);
177
496
 
178
497
  const WORKFLOW_TRIGGER_STRATEGY = 'WORKFLOW_TRIGGER_STRATEGY';
179
- const WorkflowTriggerStrategy = (provider)=>common.SetMetadata(WORKFLOW_TRIGGER_STRATEGY, provider);
498
+ const WorkflowTriggerStrategy = (provider)=>common.applyDecorators(common.SetMetadata(WORKFLOW_TRIGGER_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, WORKFLOW_TRIGGER_STRATEGY));
180
499
 
181
500
  exports.WorkflowTriggerRegistry = class WorkflowTriggerRegistry extends BaseStrategyRegistry {
182
501
  constructor(discoveryService, reflector){
@@ -195,7 +514,7 @@ exports.WorkflowTriggerRegistry = __decorate([
195
514
  const WORKFLOW_NODE_STRATEGY = 'WORKFLOW_NODE_STRATEGY';
196
515
  /**
197
516
  * Decorator to mark a provider as a Workflow Node Strategy
198
- */ const WorkflowNodeStrategy = (provider)=>common.SetMetadata(WORKFLOW_NODE_STRATEGY, provider);
517
+ */ const WorkflowNodeStrategy = (provider)=>common.applyDecorators(common.SetMetadata(WORKFLOW_NODE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, WORKFLOW_NODE_STRATEGY));
199
518
 
200
519
  exports.WorkflowNodeRegistry = class WorkflowNodeRegistry extends BaseStrategyRegistry {
201
520
  constructor(discoveryService, reflector){
@@ -223,7 +542,7 @@ exports.WorkflowNodeRegistry = __decorate([
223
542
  WrapWorkflowNodeExecutionCommand.type = '[Workflow] Wrap Workflow Node Execution';
224
543
 
225
544
  const VECTOR_STORE_STRATEGY = 'VECTOR_STORE_STRATEGY';
226
- const VectorStoreStrategy = (provider)=>common.SetMetadata(VECTOR_STORE_STRATEGY, provider);
545
+ const VectorStoreStrategy = (provider)=>common.applyDecorators(common.SetMetadata(VECTOR_STORE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, VECTOR_STORE_STRATEGY));
227
546
 
228
547
  exports.VectorStoreRegistry = class VectorStoreRegistry extends BaseStrategyRegistry {
229
548
  constructor(discoveryService, reflector){
@@ -240,7 +559,7 @@ exports.VectorStoreRegistry = __decorate([
240
559
  ], exports.VectorStoreRegistry);
241
560
 
242
561
  const TEXT_SPLITTER_STRATEGY = 'TEXT_SPLITTER_STRATEGY';
243
- const TextSplitterStrategy = (provider)=>common.SetMetadata(TEXT_SPLITTER_STRATEGY, provider);
562
+ const TextSplitterStrategy = (provider)=>common.applyDecorators(common.SetMetadata(TEXT_SPLITTER_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, TEXT_SPLITTER_STRATEGY));
244
563
 
245
564
  exports.TextSplitterRegistry = class TextSplitterRegistry extends BaseStrategyRegistry {
246
565
  constructor(discoveryService, reflector){
@@ -259,7 +578,7 @@ exports.TextSplitterRegistry = __decorate([
259
578
  const DOCUMENT_SOURCE_STRATEGY = 'DOCUMENT_SOURCE_STRATEGY';
260
579
  /**
261
580
  * Decorator to mark a provider as a Document Source Strategy
262
- */ const DocumentSourceStrategy = (provider)=>common.SetMetadata(DOCUMENT_SOURCE_STRATEGY, provider);
581
+ */ const DocumentSourceStrategy = (provider)=>common.applyDecorators(common.SetMetadata(DOCUMENT_SOURCE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, DOCUMENT_SOURCE_STRATEGY));
263
582
 
264
583
  exports.DocumentSourceRegistry = class DocumentSourceRegistry extends BaseStrategyRegistry {
265
584
  constructor(discoveryService, reflector){
@@ -278,7 +597,7 @@ exports.DocumentSourceRegistry = __decorate([
278
597
  const DOCUMENT_TRANSFORMER_STRATEGY = 'DOCUMENT_TRANSFORMER_STRATEGY';
279
598
  /**
280
599
  * Decorator to mark a provider as a Document Transformer Strategy
281
- */ const DocumentTransformerStrategy = (provider)=>common.SetMetadata(DOCUMENT_TRANSFORMER_STRATEGY, provider);
600
+ */ const DocumentTransformerStrategy = (provider)=>common.applyDecorators(common.SetMetadata(DOCUMENT_TRANSFORMER_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, DOCUMENT_TRANSFORMER_STRATEGY));
282
601
 
283
602
  exports.DocumentTransformerRegistry = class DocumentTransformerRegistry extends BaseStrategyRegistry {
284
603
  constructor(discoveryService, reflector){
@@ -297,7 +616,7 @@ exports.DocumentTransformerRegistry = __decorate([
297
616
  const RETRIEVER_STRATEGY = 'RETRIEVER_STRATEGY';
298
617
  /**
299
618
  * Decorator to mark a provider as a Retriever Strategy
300
- */ const RetrieverStrategy = (provider)=>common.SetMetadata(RETRIEVER_STRATEGY, provider);
619
+ */ const RetrieverStrategy = (provider)=>common.applyDecorators(common.SetMetadata(RETRIEVER_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, RETRIEVER_STRATEGY));
301
620
 
302
621
  exports.RetrieverRegistry = class RetrieverRegistry extends BaseStrategyRegistry {
303
622
  constructor(discoveryService, reflector){
@@ -372,7 +691,7 @@ async function downloadRemoteFile(url, dest) {
372
691
  const IMAGE_UNDERSTANDING_STRATEGY = 'IMAGE_UNDERSTANDING_STRATEGY';
373
692
  /**
374
693
  * Decorator to mark a provider as an Image Understanding Strategy
375
- */ const ImageUnderstandingStrategy = (provider)=>common.SetMetadata(IMAGE_UNDERSTANDING_STRATEGY, provider);
694
+ */ const ImageUnderstandingStrategy = (provider)=>common.applyDecorators(common.SetMetadata(IMAGE_UNDERSTANDING_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, IMAGE_UNDERSTANDING_STRATEGY));
376
695
 
377
696
  exports.ImageUnderstandingRegistry = class ImageUnderstandingRegistry extends BaseStrategyRegistry {
378
697
  constructor(discoveryService, reflector){
@@ -389,7 +708,7 @@ exports.ImageUnderstandingRegistry = __decorate([
389
708
  ], exports.ImageUnderstandingRegistry);
390
709
 
391
710
  const KNOWLEDGE_STRATEGY = 'KNOWLEDGE_STRATEGY';
392
- const KnowledgeStrategyKey = (provider)=>common.SetMetadata(KNOWLEDGE_STRATEGY, provider);
711
+ const KnowledgeStrategyKey = (provider)=>common.applyDecorators(common.SetMetadata(KNOWLEDGE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, KNOWLEDGE_STRATEGY));
393
712
 
394
713
  exports.KnowledgeStrategyRegistry = class KnowledgeStrategyRegistry extends BaseStrategyRegistry {
395
714
  constructor(discoveryService, reflector){
@@ -408,7 +727,7 @@ exports.KnowledgeStrategyRegistry = __decorate([
408
727
  const TOOLSET_STRATEGY = 'TOOLSET_STRATEGY';
409
728
  /**
410
729
  * Decorator to mark a provider as a Toolset Strategy
411
- */ const ToolsetStrategy = (provider)=>common.SetMetadata(TOOLSET_STRATEGY, provider);
730
+ */ const ToolsetStrategy = (provider)=>common.applyDecorators(common.SetMetadata(TOOLSET_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, TOOLSET_STRATEGY));
412
731
 
413
732
  exports.ToolsetRegistry = class ToolsetRegistry extends BaseStrategyRegistry {
414
733
  constructor(discoveryService, reflector){
@@ -600,336 +919,142 @@ BuiltinToolset.provider = '';
600
919
  const url = new URL(filePath, this.baseUrl);
601
920
  return url.href;
602
921
  }
603
- /**
604
- * Delete a file
605
- */ async deleteFile(filePath) {
606
- this.ensureAllowed('delete');
607
- this.ensureInScope(filePath);
608
- await fsPromises.unlink(filePath);
609
- }
610
- /**
611
- * List directory contents
612
- */ async listDir(dirPath) {
613
- this.ensureAllowed('list');
614
- this.ensureInScope(dirPath);
615
- return fsPromises.readdir(dirPath);
616
- }
617
- /**
618
- * Utility: check if a file or directory exists
619
- */ async exists(targetPath) {
620
- try {
621
- await fsPromises.access(targetPath);
622
- return true;
623
- } catch (e) {
624
- return false;
625
- }
626
- }
627
- constructor(permission, basePath, baseUrl){
628
- this.basePath = basePath;
629
- this.baseUrl = baseUrl;
630
- this.allowedOps = new Set(permission.operations);
631
- this.scope = permission.scope;
632
- }
633
- }
634
-
635
- async function createI18nInstance(pluginDir, language) {
636
- const instance = i18next.createInstance();
637
- const i18nDir = path.join(pluginDir, 'i18n');
638
- // detect available languages dynamically
639
- const lngs = fs.readdirSync(i18nDir).filter((f)=>f.endsWith('.json')).map((f)=>f.replace('.json', ''));
640
- await instance.use(FsBackend).init({
641
- lng: language,
642
- fallbackLng: 'en',
643
- preload: lngs,
644
- ns: [
645
- 'default'
646
- ],
647
- defaultNS: 'default',
648
- backend: {
649
- loadPath: path.join(i18nDir, '{{lng}}.json')
650
- },
651
- interpolation: {
652
- escapeValue: false
653
- }
654
- });
655
- return instance;
656
- }
657
-
658
- function loadYamlFile(filePath, logger, ignoreError = true, defaultValue = {}) {
659
- try {
660
- const fileContent = fs.readFileSync(filePath, 'utf-8');
661
- try {
662
- const yamlContent = yaml.parse(fileContent);
663
- return yamlContent || defaultValue;
664
- } catch (e) {
665
- throw new Error(`Failed to load YAML file ${filePath}: ${e}`);
666
- }
667
- } catch (e) {
668
- if (ignoreError) {
669
- logger == null ? void 0 : logger.debug(`Error loading YAML file: ${e}`);
670
- return defaultValue;
671
- } else {
672
- throw e;
673
- }
674
- }
675
- }
676
- /**
677
- * Get the mapping from name to index from a YAML file
678
- *
679
- * @param folderPath
680
- * @param fileName the YAML file name, default to '_position.yaml'
681
- * @return a dict with name as key and index as value
682
- */ function getPositionMap(folderPath, fileName = '_position.yaml', logger) {
683
- const positions = getPositionList(folderPath, fileName, logger);
684
- return positions.reduce((acc, name, index)=>{
685
- acc[name] = index;
686
- return acc;
687
- }, {});
688
- }
689
- function getPositionList(folderPath, fileName = '_position.yaml', logger) {
690
- const positionFilePath = path.join(folderPath, fileName);
691
- const yamlContent = loadYamlFile(positionFilePath, logger, true, []);
692
- const positions = yamlContent == null ? void 0 : yamlContent.filter((item)=>item && typeof item === 'string' && item.trim()).map((item)=>item.trim());
693
- return positions;
694
- }
695
- function getErrorMessage(err) {
696
- let error;
697
- if (typeof err === 'string') {
698
- error = err;
699
- } else if (err && (err.name === "AggregateError" || err.constructor.name === "AggregateError")) {
700
- return err.errors.map((_)=>getErrorMessage(_)).join('\n\n');
701
- } else if (err instanceof Error) {
702
- error = err == null ? void 0 : err.message;
703
- } else if ((err == null ? void 0 : err.error) instanceof Error) {
704
- var _err_error;
705
- error = err == null ? void 0 : (_err_error = err.error) == null ? void 0 : _err_error.message;
706
- } else if (err == null ? void 0 : err.message) {
707
- error = err == null ? void 0 : err.message;
708
- } else if (err) {
709
- // If there is no other way, convert it to JSON string
710
- error = JSON.stringify(err);
711
- }
712
- return error;
713
- }
714
-
715
- // request-context.ts
716
- class RequestContext {
717
- static currentRequestContext() {
718
- const session = getRequestContext();
719
- return session;
720
- }
721
- static currentRequest() {
722
- const requestContext = RequestContext.currentRequestContext();
723
- if (requestContext) {
724
- return requestContext.request;
725
- }
726
- return null;
727
- }
728
- static currentTenantId() {
729
- const user = RequestContext.currentUser();
730
- if (user) {
731
- return user.tenantId;
732
- }
733
- return null;
734
- }
735
- static currentUserId() {
736
- const user = RequestContext.currentUser();
737
- if (user) {
738
- return user.id;
739
- }
740
- return null;
741
- }
742
- static currentRoleId() {
743
- const user = RequestContext.currentUser();
744
- if (user) {
745
- return user.roleId;
746
- }
747
- return null;
748
- }
749
- static currentUser(throwError) {
750
- const requestContext = RequestContext.currentRequestContext();
751
- if (requestContext) {
752
- // tslint:disable-next-line
753
- const user = requestContext.request['user'];
754
- if (user) {
755
- return user;
756
- }
757
- }
758
- if (throwError) {
759
- throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
760
- }
761
- return null;
762
- }
763
- static hasPermission(permission, throwError) {
764
- return this.hasPermissions([
765
- permission
766
- ], throwError);
767
- }
768
- /**
769
- * Retrieves the language code from the headers of the current request.
770
- * @returns The language code (LanguagesEnum) extracted from the headers, or the default language (ENGLISH) if not found.
771
- */ static getLanguageCode() {
772
- // Retrieve the current request
773
- const req = RequestContext.currentRequest();
774
- // Variable to store the extracted language code
775
- let lang;
776
- // Check if a request exists
777
- if (req) {
778
- // Check if the 'language' header exists in the request
779
- if (req.headers && req.headers['language']) {
780
- // If found, set the lang variable
781
- lang = req.headers['language'];
782
- }
783
- }
784
- // Return the extracted language code or the default language (ENGLISH) if not found
785
- return lang || contracts.LanguagesEnum.English;
786
- }
787
- static getOrganizationId() {
788
- const req = this.currentRequest();
789
- let organizationId;
790
- const keys = [
791
- 'organization-id'
792
- ];
793
- if (req) {
794
- for (const key of keys){
795
- if (req.headers && req.headers[key]) {
796
- organizationId = req.headers[key];
797
- break;
798
- }
799
- }
800
- }
801
- return organizationId;
802
- }
803
- static hasPermissions(findPermissions, throwError) {
804
- const requestContext = RequestContext.currentRequestContext();
805
- if (requestContext) {
806
- // tslint:disable-next-line
807
- const token = passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
808
- if (token) {
809
- const { permissions } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
810
- if (permissions) {
811
- const found = permissions.filter((value)=>findPermissions.indexOf(value) >= 0);
812
- if (found.length === findPermissions.length) {
813
- return true;
814
- }
815
- } else {
816
- return false;
817
- }
818
- }
819
- }
820
- if (throwError) {
821
- throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
822
- }
823
- return false;
824
- }
825
- static hasAnyPermission(findPermissions, throwError) {
826
- const requestContext = RequestContext.currentRequestContext();
827
- if (requestContext) {
828
- // tslint:disable-next-line
829
- const token = passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
830
- if (token) {
831
- const { permissions } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
832
- const found = permissions.filter((value)=>findPermissions.indexOf(value) >= 0);
833
- if (found.length > 0) {
834
- return true;
835
- }
836
- }
837
- }
838
- if (throwError) {
839
- throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
840
- }
841
- return false;
842
- }
843
- static currentToken(throwError) {
844
- const requestContext = RequestContext.currentRequestContext();
845
- if (requestContext) {
846
- // tslint:disable-next-line
847
- return passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()(requestContext.request);
848
- }
849
- if (throwError) {
850
- throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
851
- }
852
- return null;
922
+ /**
923
+ * Delete a file
924
+ */ async deleteFile(filePath) {
925
+ this.ensureAllowed('delete');
926
+ this.ensureInScope(filePath);
927
+ await fsPromises.unlink(filePath);
853
928
  }
854
929
  /**
855
- * Checks if the current user has a specific role.
856
- * @param {RolesEnum} role - The role to check.
857
- * @param {boolean} throwError - Flag indicating whether to throw an error if the role is not granted.
858
- * @returns {boolean} - True if the user has the role, otherwise false.
859
- */ static hasRole(role, throwError) {
860
- return this.hasRoles([
861
- role
862
- ], throwError);
930
+ * List directory contents
931
+ */ async listDir(dirPath) {
932
+ this.ensureAllowed('list');
933
+ this.ensureInScope(dirPath);
934
+ return fsPromises.readdir(dirPath);
863
935
  }
864
936
  /**
865
- * Checks if the current request context has any of the specified roles.
866
- *
867
- * @param roles - An array of roles to check.
868
- * @param throwError - Whether to throw an error if no roles are found.
869
- * @returns True if any of the required roles are found, otherwise false.
870
- */ static hasRoles(roles, throwError) {
871
- const context = RequestContext.currentRequestContext();
872
- if (context) {
873
- try {
874
- // tslint:disable-next-line
875
- const token = this.currentToken();
876
- if (token) {
877
- const { role } = jsonwebtoken.verify(token, process.env['JWT_SECRET']);
878
- return roles.includes(role != null ? role : null);
879
- } else if (this.currentUser().role) {
880
- return roles.includes(this.currentUser().role.name);
881
- }
882
- } catch (error) {
883
- if (error instanceof jsonwebtoken.JsonWebTokenError) {
884
- return false;
885
- } else {
886
- throw error;
887
- }
888
- }
889
- }
890
- if (throwError) {
891
- throw new common.HttpException('Unauthorized', common.HttpStatus.UNAUTHORIZED);
937
+ * Utility: check if a file or directory exists
938
+ */ async exists(targetPath) {
939
+ try {
940
+ await fsPromises.access(targetPath);
941
+ return true;
942
+ } catch (e) {
943
+ return false;
892
944
  }
893
- return false;
894
945
  }
895
- constructor(request, response, reqId, userId, extras = {}){
896
- this.request = request;
897
- this.response = response;
898
- this.reqId = reqId;
899
- this.userId = userId;
900
- this.extras = extras;
946
+ constructor(permission, basePath, baseUrl){
947
+ this.basePath = basePath;
948
+ this.baseUrl = baseUrl;
949
+ this.allowedOps = new Set(permission.operations);
950
+ this.scope = permission.scope;
901
951
  }
902
952
  }
903
- const als = new node_async_hooks.AsyncLocalStorage();
904
- function getRequestContext() {
905
- return als.getStore();
953
+
954
+ async function createI18nInstance(pluginDir, language) {
955
+ const instance = i18next.createInstance();
956
+ const i18nDir = path.join(pluginDir, 'i18n');
957
+ // detect available languages dynamically
958
+ const lngs = fs.readdirSync(i18nDir).filter((f)=>f.endsWith('.json')).map((f)=>f.replace('.json', ''));
959
+ await instance.use(FsBackend).init({
960
+ lng: language,
961
+ fallbackLng: 'en',
962
+ preload: lngs,
963
+ ns: [
964
+ 'default'
965
+ ],
966
+ defaultNS: 'default',
967
+ backend: {
968
+ loadPath: path.join(i18nDir, '{{lng}}.json')
969
+ },
970
+ interpolation: {
971
+ escapeValue: false
972
+ }
973
+ });
974
+ return instance;
906
975
  }
907
976
 
908
- // request-context.middleware.ts
909
- exports.RequestContextMiddleware = class RequestContextMiddleware {
910
- use(req, _res, next) {
911
- var _req_user;
912
- const reqId = req.headers['x-request-id'] || node_crypto.randomUUID();
913
- // The userId can be placed in the authentication result here.
914
- const userId = (_req_user = req['user']) == null ? void 0 : _req_user['id'];
915
- const ctx = new RequestContext(req, _res, reqId, userId);
916
- als.run(ctx, next);
977
+ function loadYamlFile(filePath, logger, ignoreError = true, defaultValue = {}) {
978
+ try {
979
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
980
+ try {
981
+ const yamlContent = yaml.parse(fileContent);
982
+ return yamlContent || defaultValue;
983
+ } catch (e) {
984
+ throw new Error(`Failed to load YAML file ${filePath}: ${e}`);
985
+ }
986
+ } catch (e) {
987
+ if (ignoreError) {
988
+ logger == null ? void 0 : logger.debug(`Error loading YAML file: ${e}`);
989
+ return defaultValue;
990
+ } else {
991
+ throw e;
992
+ }
993
+ }
994
+ }
995
+ /**
996
+ * Get the mapping from name to index from a YAML file
997
+ *
998
+ * @param folderPath
999
+ * @param fileName the YAML file name, default to '_position.yaml'
1000
+ * @return a dict with name as key and index as value
1001
+ */ function getPositionMap(folderPath, fileName = '_position.yaml', logger) {
1002
+ const positions = getPositionList(folderPath, fileName, logger);
1003
+ return positions.reduce((acc, name, index)=>{
1004
+ acc[name] = index;
1005
+ return acc;
1006
+ }, {});
1007
+ }
1008
+ function getPositionList(folderPath, fileName = '_position.yaml', logger) {
1009
+ const positionFilePath = path.join(folderPath, fileName);
1010
+ const yamlContent = loadYamlFile(positionFilePath, logger, true, []);
1011
+ const positions = yamlContent == null ? void 0 : yamlContent.filter((item)=>item && typeof item === 'string' && item.trim()).map((item)=>item.trim());
1012
+ return positions;
1013
+ }
1014
+ function getErrorMessage(err) {
1015
+ let error;
1016
+ if (typeof err === 'string') {
1017
+ error = err;
1018
+ } else if (err && (err.name === "AggregateError" || err.constructor.name === "AggregateError")) {
1019
+ return err.errors.map((_)=>getErrorMessage(_)).join('\n\n');
1020
+ } else if (err instanceof Error) {
1021
+ error = err == null ? void 0 : err.message;
1022
+ } else if ((err == null ? void 0 : err.error) instanceof Error) {
1023
+ var _err_error;
1024
+ error = err == null ? void 0 : (_err_error = err.error) == null ? void 0 : _err_error.message;
1025
+ } else if (err == null ? void 0 : err.message) {
1026
+ error = err == null ? void 0 : err.message;
1027
+ } else if (err) {
1028
+ // If there is no other way, convert it to JSON string
1029
+ error = JSON.stringify(err);
1030
+ }
1031
+ return error;
1032
+ }
1033
+ class JsonSchemaValidator {
1034
+ parseAndValidate(schemaStr) {
1035
+ if (!schemaStr) return undefined;
1036
+ let schema;
1037
+ try {
1038
+ schema = JSON.parse(schemaStr);
1039
+ } catch (e) {
1040
+ throw new Error('Schema is not valid JSON');
1041
+ }
1042
+ const validate = this.ajv.getSchema(schemaDraft04.$id);
1043
+ if (!validate(schema)) {
1044
+ throw new Error('Invalid JSON Schema: ' + this.ajv.errorsText(validate.errors));
1045
+ }
1046
+ return schema;
1047
+ }
1048
+ constructor(){
1049
+ this.ajv = new Ajv({
1050
+ strict: false
1051
+ });
1052
+ this.ajv.addMetaSchema(schemaDraft04);
917
1053
  }
918
- };
919
- exports.RequestContextMiddleware = __decorate([
920
- common.Injectable()
921
- ], exports.RequestContextMiddleware);
922
- function runWithRequestContext(req, res, next) {
923
- var _req_user;
924
- const reqId = req.headers['x-request-id'] || node_crypto.randomUUID();
925
- const userId = (_req_user = req['user']) == null ? void 0 : _req_user['id'];
926
- const ctx = new RequestContext(req, res, reqId, userId);
927
- // Enable ALS scope
928
- als.run(ctx, next);
929
1054
  }
930
1055
 
931
1056
  const DATASOURCE_STRATEGY = 'DATASOURCE_STRATEGY';
932
- const DataSourceStrategy = (provider)=>common.SetMetadata(DATASOURCE_STRATEGY, provider);
1057
+ const DataSourceStrategy = (provider)=>common.applyDecorators(common.SetMetadata(DATASOURCE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, DATASOURCE_STRATEGY));
933
1058
 
934
1059
  exports.DataSourceStrategyRegistry = class DataSourceStrategyRegistry extends BaseStrategyRegistry {
935
1060
  constructor(discoveryService, reflector){
@@ -1242,6 +1367,7 @@ function AIModelProviderStrategy(provider) {
1242
1367
  }
1243
1368
  const dir = file ? path.dirname(file) : process.cwd();
1244
1369
  return function(target) {
1370
+ common.SetMetadata(STRATEGY_META_KEY, AI_MODEL_PROVIDER)(target);
1245
1371
  // Ensure NestJS is discoverable
1246
1372
  common.SetMetadata(AI_MODEL_PROVIDER, provider)(target);
1247
1373
  // Write custom path (does not affect Discovery)
@@ -1533,6 +1659,46 @@ const PARAMETER_RULE_TEMPLATE = {
1533
1659
  }
1534
1660
  };
1535
1661
 
1662
+ const CommonParameterRules = [
1663
+ {
1664
+ name: 'temperature',
1665
+ label: {
1666
+ zh_Hans: '温度',
1667
+ en_US: `Temperature`
1668
+ },
1669
+ type: contracts.ParameterType.FLOAT,
1670
+ help: {
1671
+ zh_Hans: '控制模型输出的随机性。较高的值(例如 1.0)使响应更具创意,而较低的值(例如 0.1)使响应更具确定性和重点性。',
1672
+ en_US: `Controls the randomness of the model's output. A higher value (e.g., 1.0) makes responses more creative, while a lower value (e.g., 0.1) makes them more deterministic and focused.`
1673
+ },
1674
+ required: false,
1675
+ default: 0.2,
1676
+ min: 0,
1677
+ max: 1,
1678
+ precision: 0.1
1679
+ },
1680
+ {
1681
+ label: {
1682
+ zh_Hans: '最大尝试次数',
1683
+ en_US: 'The maximum number of attempts'
1684
+ },
1685
+ type: contracts.ParameterType.INT,
1686
+ help: {
1687
+ zh_Hans: '如果请求由于网络超时或速率限制等问题而失败,系统将尝试重新发送请求的最大次数',
1688
+ en_US: 'The maximum number of attempts the system will make to resend a request if it fails due to issues like network timeouts or rate limits'
1689
+ },
1690
+ required: false,
1691
+ default: 6,
1692
+ min: 0,
1693
+ max: 10,
1694
+ precision: 0,
1695
+ name: 'maxRetries'
1696
+ }
1697
+ ];
1698
+ function mergeCredentials(credentials, modelProperties) {
1699
+ return _extends({}, credentials != null ? credentials : {}, modelProperties != null ? modelProperties : {});
1700
+ }
1701
+
1536
1702
  let AIModel = class AIModel {
1537
1703
  getChatModel(copilotModel, options) {
1538
1704
  throw new Error(`Unsupport chat model!`);
@@ -1676,6 +1842,15 @@ let AIModel = class AIModel {
1676
1842
  ...parameterRules.filter((_)=>!CommonParameterRules.some((r)=>r.name === _.name))
1677
1843
  ];
1678
1844
  }
1845
+ getModelProfile(model, credentials) {
1846
+ var _modelSchema_model_properties, _modelSchema_features, _modelSchema_features1, _modelSchema_features2, _modelSchema_features3;
1847
+ const modelSchema = this.getModelSchema(model, credentials);
1848
+ return modelSchema && {
1849
+ maxInputTokens: (_modelSchema_model_properties = modelSchema.model_properties) == null ? void 0 : _modelSchema_model_properties.context_size,
1850
+ toolCalling: ((_modelSchema_features = modelSchema.features) == null ? void 0 : _modelSchema_features.includes(contracts.ModelFeature.TOOL_CALL)) || ((_modelSchema_features1 = modelSchema.features) == null ? void 0 : _modelSchema_features1.includes(contracts.ModelFeature.MULTI_TOOL_CALL)) || ((_modelSchema_features2 = modelSchema.features) == null ? void 0 : _modelSchema_features2.includes(contracts.ModelFeature.STREAM_TOOL_CALL)),
1851
+ structuredOutput: (_modelSchema_features3 = modelSchema.features) == null ? void 0 : _modelSchema_features3.includes(contracts.ModelFeature.STRUCTURED_OUTPUT)
1852
+ };
1853
+ }
1679
1854
  constructor(modelProvider, modelType){
1680
1855
  this.modelProvider = modelProvider;
1681
1856
  this.modelType = modelType;
@@ -1715,46 +1890,6 @@ class RerankModel extends AIModel {
1715
1890
  }
1716
1891
  }
1717
1892
 
1718
- const CommonParameterRules = [
1719
- {
1720
- name: 'temperature',
1721
- label: {
1722
- zh_Hans: '温度',
1723
- en_US: `Temperature`
1724
- },
1725
- type: contracts.ParameterType.FLOAT,
1726
- help: {
1727
- zh_Hans: '控制模型输出的随机性。较高的值(例如 1.0)使响应更具创意,而较低的值(例如 0.1)使响应更具确定性和重点性。',
1728
- en_US: `Controls the randomness of the model's output. A higher value (e.g., 1.0) makes responses more creative, while a lower value (e.g., 0.1) makes them more deterministic and focused.`
1729
- },
1730
- required: false,
1731
- default: 0.2,
1732
- min: 0,
1733
- max: 1,
1734
- precision: 0.1
1735
- },
1736
- {
1737
- label: {
1738
- zh_Hans: '最大尝试次数',
1739
- en_US: 'The maximum number of attempts'
1740
- },
1741
- type: contracts.ParameterType.INT,
1742
- help: {
1743
- zh_Hans: '如果请求由于网络超时或速率限制等问题而失败,系统将尝试重新发送请求的最大次数',
1744
- en_US: 'The maximum number of attempts the system will make to resend a request if it fails due to issues like network timeouts or rate limits'
1745
- },
1746
- required: false,
1747
- default: 6,
1748
- min: 0,
1749
- max: 10,
1750
- precision: 0,
1751
- name: 'maxRetries'
1752
- }
1753
- ];
1754
- function mergeCredentials(credentials, modelProperties) {
1755
- return _extends({}, credentials != null ? credentials : {}, modelProperties != null ? modelProperties : {});
1756
- }
1757
-
1758
1893
  class SpeechToTextModel extends AIModel {
1759
1894
  }
1760
1895
 
@@ -2081,7 +2216,7 @@ class OpenAICompatibleReranker {
2081
2216
  if (!Array.isArray(output)) {
2082
2217
  throw new Error('Invalid response format: missing results array');
2083
2218
  }
2084
- // 收集原始分数并进行归一化处理
2219
+ // Collect raw scores and normalize them.
2085
2220
  const scores = output.map((r)=>r.relevance_score);
2086
2221
  const minScore = Math.min(...scores);
2087
2222
  const maxScore = Math.max(...scores);
@@ -2160,7 +2295,7 @@ class Speech2TextChatModel extends chat_models.BaseChatModel {
2160
2295
  CreateModelClientCommand.type = '[AI Model] Create Model Client';
2161
2296
 
2162
2297
  const AGENT_MIDDLEWARE_STRATEGY = 'AGENT_MIDDLEWARE_STRATEGY';
2163
- const AgentMiddlewareStrategy = (provider)=>common.SetMetadata(AGENT_MIDDLEWARE_STRATEGY, provider);
2298
+ const AgentMiddlewareStrategy = (provider)=>common.applyDecorators(common.SetMetadata(AGENT_MIDDLEWARE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, AGENT_MIDDLEWARE_STRATEGY));
2164
2299
 
2165
2300
  exports.AgentMiddlewareRegistry = class AgentMiddlewareRegistry extends BaseStrategyRegistry {
2166
2301
  constructor(discoveryService, reflector){
@@ -2210,6 +2345,7 @@ exports.AiModelNotFoundException = AiModelNotFoundException;
2210
2345
  exports.BaseHTTPQueryRunner = BaseHTTPQueryRunner;
2211
2346
  exports.BaseQueryRunner = BaseQueryRunner;
2212
2347
  exports.BaseSQLQueryRunner = BaseSQLQueryRunner;
2348
+ exports.BaseStrategyRegistry = BaseStrategyRegistry;
2213
2349
  exports.BaseTool = BaseTool;
2214
2350
  exports.BaseToolset = BaseToolset;
2215
2351
  exports.BuiltinToolset = BuiltinToolset;
@@ -2223,17 +2359,21 @@ exports.DOCUMENT_TRANSFORMER_STRATEGY = DOCUMENT_TRANSFORMER_STRATEGY;
2223
2359
  exports.DataSourceStrategy = DataSourceStrategy;
2224
2360
  exports.DocumentSourceStrategy = DocumentSourceStrategy;
2225
2361
  exports.DocumentTransformerStrategy = DocumentTransformerStrategy;
2362
+ exports.GLOBAL_ORGANIZATION_SCOPE = GLOBAL_ORGANIZATION_SCOPE;
2226
2363
  exports.IMAGE_UNDERSTANDING_STRATEGY = IMAGE_UNDERSTANDING_STRATEGY;
2227
2364
  exports.INTEGRATION_STRATEGY = INTEGRATION_STRATEGY;
2228
2365
  exports.ImageUnderstandingStrategy = ImageUnderstandingStrategy;
2229
2366
  exports.IntegrationStrategyKey = IntegrationStrategyKey;
2230
2367
  exports.JUMP_TO_TARGETS = JUMP_TO_TARGETS;
2368
+ exports.JsonSchemaValidator = JsonSchemaValidator;
2231
2369
  exports.KNOWLEDGE_STRATEGY = KNOWLEDGE_STRATEGY;
2232
2370
  exports.KnowledgeStrategyKey = KnowledgeStrategyKey;
2233
2371
  exports.LLMUsage = LLMUsage;
2234
2372
  exports.LargeLanguageModel = LargeLanguageModel;
2373
+ exports.ORGANIZATION_METADATA_KEY = ORGANIZATION_METADATA_KEY;
2235
2374
  exports.OpenAICompatibleReranker = OpenAICompatibleReranker;
2236
2375
  exports.PLUGIN_METADATA = PLUGIN_METADATA;
2376
+ exports.PLUGIN_METADATA_KEY = PLUGIN_METADATA_KEY;
2237
2377
  exports.PROVIDE_AI_MODEL_LLM = PROVIDE_AI_MODEL_LLM;
2238
2378
  exports.PROVIDE_AI_MODEL_MODERATION = PROVIDE_AI_MODEL_MODERATION;
2239
2379
  exports.PROVIDE_AI_MODEL_RERANK = PROVIDE_AI_MODEL_RERANK;
@@ -2244,6 +2384,7 @@ exports.RETRIEVER_STRATEGY = RETRIEVER_STRATEGY;
2244
2384
  exports.RequestContext = RequestContext;
2245
2385
  exports.RerankModel = RerankModel;
2246
2386
  exports.RetrieverStrategy = RetrieverStrategy;
2387
+ exports.STRATEGY_META_KEY = STRATEGY_META_KEY;
2247
2388
  exports.Speech2TextChatModel = Speech2TextChatModel;
2248
2389
  exports.SpeechToTextModel = SpeechToTextModel;
2249
2390
  exports.TEXT_SPLITTER_STRATEGY = TEXT_SPLITTER_STRATEGY;