@xpert-ai/plugin-sdk 3.8.1 → 3.8.4

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.esm.js CHANGED
@@ -936,6 +936,8 @@ BuiltinToolset.provider = '';
936
936
  }
937
937
  }
938
938
 
939
+ const PLUGIN_CONFIG_RESOLVER_TOKEN = 'XPERT_PLUGIN_CONFIG_RESOLVER';
940
+
939
941
  /**
940
942
  * System token for resolving integration read service from plugin context.
941
943
  */ const INTEGRATION_PERMISSION_SERVICE_TOKEN = 'XPERT_PLUGIN_INTEGRATION_PERMISSION_SERVICE';
@@ -1989,11 +1991,11 @@ class LLMUsage {
1989
1991
  }
1990
1992
  plus(other) {
1991
1993
  /**
1992
- * Add two LLMUsage instances together.
1993
- *
1994
- * @param other: Another LLMUsage instance to add
1995
- * @return: A new LLMUsage instance with summed values
1996
- */ if (this.totalTokens === 0) {
1994
+ * Add two LLMUsage instances together.
1995
+ *
1996
+ * @param other: Another LLMUsage instance to add
1997
+ * @return: A new LLMUsage instance with summed values
1998
+ */ if (this.totalTokens === 0) {
1997
1999
  return other;
1998
2000
  } else {
1999
2001
  return new LLMUsage(this.promptTokens + other.promptTokens, other.promptUnitPrice, other.promptPriceUnit, this.promptPrice + other.promptPrice, this.completionTokens + other.completionTokens, other.completionUnitPrice, other.completionPriceUnit, this.completionPrice + other.completionPrice, this.totalTokens + other.totalTokens, this.totalPrice + other.totalPrice, other.currency, this.latency + other.latency);
@@ -2001,11 +2003,11 @@ class LLMUsage {
2001
2003
  }
2002
2004
  add(other) {
2003
2005
  /**
2004
- * Overload the + operator to add two LLMUsage instances.
2005
- *
2006
- * @param other: Another LLMUsage instance to add
2007
- * @return: A new LLMUsage instance with summed values
2008
- */ return this.plus(other);
2006
+ * Overload the + operator to add two LLMUsage instances.
2007
+ *
2008
+ * @param other: Another LLMUsage instance to add
2009
+ * @return: A new LLMUsage instance with summed values
2010
+ */ return this.plus(other);
2009
2011
  }
2010
2012
  constructor(promptTokens, promptUnitPrice, promptPriceUnit, promptPrice, completionTokens, completionUnitPrice, completionPriceUnit, completionPrice, totalTokens, totalPrice, currency, latency){
2011
2013
  this.promptTokens = promptTokens;
@@ -2125,6 +2127,78 @@ class LargeLanguageModel extends AIModel {
2125
2127
  }
2126
2128
  };
2127
2129
  }
2130
+ createHandleVerboseCallbacks(enabled, logger) {
2131
+ if (!enabled) {
2132
+ return [];
2133
+ }
2134
+ const targetLogger = logger != null ? logger : _class_private_field_loose_base(this, _logger)[_logger];
2135
+ return [
2136
+ {
2137
+ handleChatModelStart: (llm, messages, runId, parentRunId, extraParams, tags, metadata, runName)=>{
2138
+ targetLogger.verbose(this.formatVerboseLog('chat_model/start', {
2139
+ runId,
2140
+ parentRunId,
2141
+ runName,
2142
+ model: llm,
2143
+ messages,
2144
+ extraParams,
2145
+ tags,
2146
+ metadata
2147
+ }));
2148
+ },
2149
+ handleLLMStart: (llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName)=>{
2150
+ targetLogger.verbose(this.formatVerboseLog('llm/start', {
2151
+ runId,
2152
+ parentRunId,
2153
+ runName,
2154
+ model: llm,
2155
+ prompts,
2156
+ extraParams,
2157
+ tags,
2158
+ metadata
2159
+ }));
2160
+ },
2161
+ handleLLMEnd: (output, runId, parentRunId, tags, extraParams)=>{
2162
+ targetLogger.verbose(this.formatVerboseLog('llm/end', {
2163
+ runId,
2164
+ parentRunId,
2165
+ output,
2166
+ tags,
2167
+ extraParams
2168
+ }));
2169
+ },
2170
+ handleLLMError: (err, runId, parentRunId, tags, extraParams)=>{
2171
+ targetLogger.verbose(this.formatVerboseLog('llm/error', {
2172
+ runId,
2173
+ parentRunId,
2174
+ error: this.formatError(err),
2175
+ tags,
2176
+ extraParams
2177
+ }));
2178
+ }
2179
+ }
2180
+ ];
2181
+ }
2182
+ formatVerboseLog(event, payload) {
2183
+ return `[langchain][${event}] ${this.stringifyLogPayload(payload)}`;
2184
+ }
2185
+ stringifyLogPayload(payload) {
2186
+ try {
2187
+ return JSON.stringify(payload, null, 2);
2188
+ } catch (error) {
2189
+ return `[unserializable payload: ${this.formatError(error)}]`;
2190
+ }
2191
+ }
2192
+ formatError(error) {
2193
+ if (error instanceof Error) {
2194
+ return {
2195
+ name: error.name,
2196
+ message: error.message,
2197
+ stack: error.stack
2198
+ };
2199
+ }
2200
+ return error;
2201
+ }
2128
2202
  constructor(...args){
2129
2203
  super(...args);
2130
2204
  Object.defineProperty(this, _logger, {
@@ -2615,34 +2689,100 @@ class CancelConversationCommand {
2615
2689
  }
2616
2690
  CancelConversationCommand.type = '[Chat Conversation] Cancel';
2617
2691
 
2692
+ const FILE_STORAGE_PROVIDER = 'FILE_STORAGE_PROVIDER';
2693
+ const FileStorageProvider = (provider)=>applyDecorators(SetMetadata(FILE_STORAGE_PROVIDER, provider), SetMetadata(STRATEGY_META_KEY, FILE_STORAGE_PROVIDER));
2694
+
2695
+ let FileStorageProviderRegistry = class FileStorageProviderRegistry extends BaseStrategyRegistry {
2696
+ constructor(discoveryService, reflector){
2697
+ super(FILE_STORAGE_PROVIDER, discoveryService, reflector);
2698
+ }
2699
+ };
2700
+ FileStorageProviderRegistry = __decorate([
2701
+ Injectable(),
2702
+ __metadata("design:type", Function),
2703
+ __metadata("design:paramtypes", [
2704
+ typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
2705
+ typeof Reflector === "undefined" ? Object : Reflector
2706
+ ])
2707
+ ], FileStorageProviderRegistry);
2708
+
2709
+ const FILE_UPLOAD_TARGET_STRATEGY = 'FILE_UPLOAD_TARGET_STRATEGY';
2710
+ const FileUploadTargetStrategy = (type)=>applyDecorators(SetMetadata(FILE_UPLOAD_TARGET_STRATEGY, type), SetMetadata(STRATEGY_META_KEY, FILE_UPLOAD_TARGET_STRATEGY));
2711
+
2712
+ let FileUploadTargetRegistry = class FileUploadTargetRegistry extends BaseStrategyRegistry {
2713
+ constructor(discoveryService, reflector){
2714
+ super(FILE_UPLOAD_TARGET_STRATEGY, discoveryService, reflector);
2715
+ }
2716
+ };
2717
+ FileUploadTargetRegistry = __decorate([
2718
+ Injectable(),
2719
+ __metadata("design:type", Function),
2720
+ __metadata("design:paramtypes", [
2721
+ typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
2722
+ typeof Reflector === "undefined" ? Object : Reflector
2723
+ ])
2724
+ ], FileUploadTargetRegistry);
2725
+
2726
+ const SANDBOX_SHELL_TIMEOUT_LIMITS_SEC = {
2727
+ min: 1,
2728
+ max: 3600
2729
+ };
2730
+ const DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC = 600;
2731
+ const DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC = 120;
2732
+ const DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC = 120;
2733
+ const DEFAULT_SANDBOX_SHELL_TIMEOUT_MS = DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC * 1000;
2734
+ const DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC * 1000;
2735
+ const DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC * 1000;
2736
+ const DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES = 1024 * 1024;
2737
+ const DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS = {
2738
+ timeoutMs: DEFAULT_SANDBOX_SHELL_TIMEOUT_MS,
2739
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2740
+ };
2741
+ const DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS = {
2742
+ timeoutMs: DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS,
2743
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2744
+ };
2745
+ const DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS = {
2746
+ timeoutMs: DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS,
2747
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2748
+ };
2749
+ function secondsToMilliseconds(seconds) {
2750
+ return Math.trunc(seconds * 1000);
2751
+ }
2752
+ function formatSandboxTimeout(timeoutMs) {
2753
+ const timeoutSeconds = timeoutMs / 1000;
2754
+ const secondsLabel = Number.isInteger(timeoutSeconds) ? String(timeoutSeconds) : Number(timeoutSeconds.toFixed(3)).toString();
2755
+ return `${secondsLabel}s (${timeoutMs}ms)`;
2756
+ }
2757
+ function buildSandboxTimeoutMessage(subject, timeoutMs) {
2758
+ return `${subject} timed out after ${formatSandboxTimeout(timeoutMs)}`;
2759
+ }
2760
+ function appendSandboxMessage(output, message) {
2761
+ return output ? `${output}\n${message}` : message;
2762
+ }
2763
+ function resolveSandboxExecutionOptions(options, defaults = DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS) {
2764
+ const timeoutMs = typeof (options == null ? void 0 : options.timeoutMs) === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0 ? Math.trunc(options.timeoutMs) : typeof defaults.timeoutMs === 'number' && Number.isFinite(defaults.timeoutMs) && defaults.timeoutMs > 0 ? Math.trunc(defaults.timeoutMs) : DEFAULT_SANDBOX_SHELL_TIMEOUT_MS;
2765
+ const maxOutputBytes = typeof (options == null ? void 0 : options.maxOutputBytes) === 'number' && Number.isFinite(options.maxOutputBytes) && options.maxOutputBytes > 0 ? Math.trunc(options.maxOutputBytes) : typeof defaults.maxOutputBytes === 'number' && Number.isFinite(defaults.maxOutputBytes) && defaults.maxOutputBytes > 0 ? Math.trunc(defaults.maxOutputBytes) : DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES;
2766
+ return {
2767
+ timeoutMs,
2768
+ maxOutputBytes
2769
+ };
2770
+ }
2771
+
2618
2772
  /**
2619
- * Protocol definition for pluggable memory backends.
2620
- *
2621
- * This module defines the BackendProtocol that all backend implementations
2622
- * must follow. Backends can store files in different locations (state, filesystem,
2623
- * database, etc.) and provide a uniform interface for file operations.
2624
- */ /**
2625
2773
  * Type guard to check if a backend supports execution.
2626
2774
  *
2627
2775
  * @param backend - Backend instance to check
2628
2776
  * @returns True if the backend implements SandboxBackendProtocol
2629
2777
  */ function isSandboxBackend(backend) {
2630
- return typeof backend.execute === "function" && typeof backend.id === "string";
2778
+ return typeof backend.execute === 'function' && typeof backend.id === 'string';
2631
2779
  }
2632
2780
 
2633
- /**
2634
- * BaseSandbox: Abstract base class for sandbox backends with command execution.
2635
- *
2636
- * This class provides default implementations for all SandboxBackendProtocol
2637
- * methods using shell commands executed via execute(). Concrete implementations
2638
- * only need to implement the execute() method.
2639
- *
2640
- * Requires Node.js 20+ on the sandbox host.
2641
- */ const MAX_LINE_LENGTH = 500;
2781
+ const MAX_LINE_LENGTH = 500;
2642
2782
  const MAX_GREP_LINE_LENGTH = 2000;
2643
2783
  const GREP_RESULT_LIMIT = 100;
2644
2784
  const GLOB_RESULT_LIMIT = 100;
2645
- const WRITE_EXISTS_OUTPUT = "Error: File already exists";
2785
+ const WRITE_EXISTS_OUTPUT = 'Error: File already exists';
2646
2786
  /**
2647
2787
  * UTF-8 safe Base64 encoding function.
2648
2788
  * Replaces btoa() which only supports Latin1 characters.
@@ -2656,17 +2796,17 @@ const WRITE_EXISTS_OUTPUT = "Error: File already exists";
2656
2796
  const truncated = files.length > limit;
2657
2797
  const finalFiles = truncated ? files.slice(0, limit) : files;
2658
2798
  if (finalFiles.length === 0) {
2659
- return "No files found";
2799
+ return 'No files found';
2660
2800
  }
2661
2801
  const lines = [];
2662
2802
  for (const file of finalFiles){
2663
2803
  lines.push(file.path);
2664
2804
  }
2665
2805
  if (truncated) {
2666
- lines.push("");
2667
- lines.push("(Results truncated. Consider using a more specific path or pattern.)");
2806
+ lines.push('');
2807
+ lines.push('(Results truncated. Consider using a more specific path or pattern.)');
2668
2808
  }
2669
- return lines.join("\n");
2809
+ return lines.join('\n');
2670
2810
  }
2671
2811
  /**
2672
2812
  * Format grep matches into human-readable output grouped by file.
@@ -2675,28 +2815,28 @@ const WRITE_EXISTS_OUTPUT = "Error: File already exists";
2675
2815
  const truncated = matches.length > limit;
2676
2816
  const finalMatches = truncated ? matches.slice(0, limit) : matches;
2677
2817
  if (finalMatches.length === 0) {
2678
- return "No matches found";
2818
+ return 'No matches found';
2679
2819
  }
2680
2820
  const lines = [
2681
2821
  `Found ${finalMatches.length} matches`
2682
2822
  ];
2683
- let currentFile = "";
2823
+ let currentFile = '';
2684
2824
  for (const match of finalMatches){
2685
2825
  if (currentFile !== match.path) {
2686
- if (currentFile !== "") {
2687
- lines.push("");
2826
+ if (currentFile !== '') {
2827
+ lines.push('');
2688
2828
  }
2689
2829
  currentFile = match.path;
2690
2830
  lines.push(`${match.path}:`);
2691
2831
  }
2692
- const text = match.text.length > MAX_GREP_LINE_LENGTH ? match.text.substring(0, MAX_GREP_LINE_LENGTH) + "..." : match.text;
2832
+ const text = match.text.length > MAX_GREP_LINE_LENGTH ? match.text.substring(0, MAX_GREP_LINE_LENGTH) + '...' : match.text;
2693
2833
  lines.push(` Line ${match.line}: ${text}`);
2694
2834
  }
2695
2835
  if (truncated) {
2696
- lines.push("");
2697
- lines.push("(Results truncated. Consider using a more specific path or pattern.)");
2836
+ lines.push('');
2837
+ lines.push('(Results truncated. Consider using a more specific path or pattern.)');
2698
2838
  }
2699
- return lines.join("\n");
2839
+ return lines.join('\n');
2700
2840
  }
2701
2841
  /**
2702
2842
  * Node.js command template for glob operations.
@@ -3177,14 +3317,14 @@ console.log(count);
3177
3317
  */ function buildGrepCommand(pattern, searchPath, globPattern) {
3178
3318
  const patternB64 = utf8ToBase64(pattern);
3179
3319
  const pathB64 = utf8ToBase64(searchPath);
3180
- const globB64 = globPattern ? utf8ToBase64(globPattern) : "";
3320
+ const globB64 = globPattern ? utf8ToBase64(globPattern) : '';
3181
3321
  return `node -e "
3182
3322
  const fs = require('fs');
3183
3323
  const path = require('path');
3184
3324
 
3185
3325
  const pattern = Buffer.from('${patternB64}', 'base64').toString('utf-8');
3186
3326
  const searchPath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3187
- const globPattern = ${globPattern ? `Buffer.from('${globB64}', 'base64').toString('utf-8')` : "null"};
3327
+ const globPattern = ${globPattern ? `Buffer.from('${globB64}', 'base64').toString('utf-8')` : 'null'};
3188
3328
 
3189
3329
  let regex;
3190
3330
  try {
@@ -3253,8 +3393,15 @@ try {
3253
3393
  *
3254
3394
  * Requires Node.js 20+ on the sandbox host.
3255
3395
  */ class BaseSandbox {
3256
- async streamExecute(command, onLine) {
3257
- const result = await this.execute(command);
3396
+ /**
3397
+ * Internal hook for file/search operations. Concrete backends can override
3398
+ * this to distinguish "background helper commands" from user-facing shell
3399
+ * execute calls.
3400
+ */ executeOperation(command, options) {
3401
+ return this.execute(command, options);
3402
+ }
3403
+ async streamExecute(command, onLine, options) {
3404
+ const result = await this.execute(command, options);
3258
3405
  if (result.output) {
3259
3406
  onLine(result.output);
3260
3407
  }
@@ -3267,12 +3414,12 @@ try {
3267
3414
  * @returns List of FileInfo objects for files and directories directly in the directory.
3268
3415
  */ async lsInfo(path) {
3269
3416
  const command = buildLsCommand(path);
3270
- const result = await this.execute(command);
3417
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3271
3418
  if (result.exitCode !== 0) {
3272
3419
  return [];
3273
3420
  }
3274
3421
  const infos = [];
3275
- const lines = result.output.trim().split("\n").filter(Boolean);
3422
+ const lines = result.output.trim().split('\n').filter(Boolean);
3276
3423
  for (const line of lines){
3277
3424
  try {
3278
3425
  const parsed = JSON.parse(line);
@@ -3298,16 +3445,16 @@ try {
3298
3445
  * @returns Human-readable directory tree with indentation
3299
3446
  */ async listDir(dirPath, offset = 1, limit = 25, depth = 2) {
3300
3447
  if (offset < 1) {
3301
- return "Error: offset must be a 1-indexed entry number";
3448
+ return 'Error: offset must be a 1-indexed entry number';
3302
3449
  }
3303
3450
  if (limit < 1) {
3304
- return "Error: limit must be greater than zero";
3451
+ return 'Error: limit must be greater than zero';
3305
3452
  }
3306
3453
  if (depth < 1) {
3307
- return "Error: depth must be greater than zero";
3454
+ return 'Error: depth must be greater than zero';
3308
3455
  }
3309
3456
  const command = buildListDirCommand(dirPath, offset, limit, depth);
3310
- const result = await this.execute(command);
3457
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3311
3458
  if (result.exitCode !== 0) {
3312
3459
  return result.output || `Error: Failed to list directory '${dirPath}'`;
3313
3460
  }
@@ -3324,7 +3471,7 @@ try {
3324
3471
  * @returns Formatted file content with line numbers, or error message
3325
3472
  */ async read(filePath, offset = 1, limit = 2000, mode = 'slice', indentation) {
3326
3473
  const command = mode === 'indentation' ? buildIndentationReadCommand(filePath, offset, limit, indentation != null ? indentation : {}) : buildSliceReadCommand(filePath, offset, limit);
3327
- const result = await this.execute(command);
3474
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3328
3475
  if (result.exitCode !== 0) {
3329
3476
  return result.output || `Error: File '${filePath}' not found`;
3330
3477
  }
@@ -3332,17 +3479,17 @@ try {
3332
3479
  }
3333
3480
  /**
3334
3481
  * Structured search results or error string for invalid input.
3335
- */ async grepRaw(pattern, path = "/", include = null) {
3482
+ */ async grepRaw(pattern, path = '/', include = null) {
3336
3483
  const command = buildGrepCommand(pattern, path, include);
3337
- const result = await this.execute(command);
3484
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3338
3485
  if (result.exitCode === 1) {
3339
3486
  // Check if it's a regex error
3340
- if (result.output.includes("Invalid regex:")) {
3487
+ if (result.output.includes('Invalid regex:')) {
3341
3488
  return result.output.trim();
3342
3489
  }
3343
3490
  }
3344
3491
  const matches = [];
3345
- const lines = result.output.trim().split("\n").filter(Boolean);
3492
+ const lines = result.output.trim().split('\n').filter(Boolean);
3346
3493
  for (const line of lines){
3347
3494
  try {
3348
3495
  const parsed = JSON.parse(line);
@@ -3359,23 +3506,23 @@ try {
3359
3506
  }
3360
3507
  /**
3361
3508
  * Search file contents for a regex pattern, returning human-readable output.
3362
- */ async grep(pattern, path = "/", include = null) {
3509
+ */ async grep(pattern, path = '/', include = null) {
3363
3510
  const result = await this.grepRaw(pattern, path, include);
3364
- if (typeof result === "string") {
3511
+ if (typeof result === 'string') {
3365
3512
  return result;
3366
3513
  }
3367
3514
  if (result.length === 0) {
3368
- return "No matches found";
3515
+ return 'No matches found';
3369
3516
  }
3370
3517
  return formatGrepOutput(result);
3371
3518
  }
3372
3519
  /**
3373
3520
  * Structured glob matching returning FileInfo objects.
3374
- */ async globInfo(pattern, path = "/") {
3521
+ */ async globInfo(pattern, path = '/') {
3375
3522
  const command = buildGlobCommand(path, pattern);
3376
- const result = await this.execute(command);
3523
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3377
3524
  const infos = [];
3378
- const lines = result.output.trim().split("\n").filter(Boolean);
3525
+ const lines = result.output.trim().split('\n').filter(Boolean);
3379
3526
  for (const line of lines){
3380
3527
  try {
3381
3528
  const parsed = JSON.parse(line);
@@ -3393,10 +3540,10 @@ try {
3393
3540
  }
3394
3541
  /**
3395
3542
  * Find files matching a glob pattern, returning human-readable output.
3396
- */ async glob(pattern, path = "/") {
3543
+ */ async glob(pattern, path = '/') {
3397
3544
  const files = await this.globInfo(pattern, path);
3398
3545
  if (files.length === 0) {
3399
- return "No files found";
3546
+ return 'No files found';
3400
3547
  }
3401
3548
  return formatGlobOutput(files);
3402
3549
  }
@@ -3404,9 +3551,9 @@ try {
3404
3551
  * Create a new file with content.
3405
3552
  */ async write(filePath, content) {
3406
3553
  const command = buildWriteCommand(filePath, content);
3407
- const result = await this.execute(command);
3554
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3408
3555
  if (result.exitCode !== 0) {
3409
- const output = (result.output || "").trim();
3556
+ const output = (result.output || '').trim();
3410
3557
  if (output.includes(WRITE_EXISTS_OUTPUT)) {
3411
3558
  return {
3412
3559
  error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
@@ -3426,7 +3573,7 @@ try {
3426
3573
  };
3427
3574
  }
3428
3575
  async writeViaUpload(filePath, content) {
3429
- const existsCheck = await this.execute(buildExistsCommand(filePath));
3576
+ const existsCheck = await this.executeOperation(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3430
3577
  if (existsCheck.exitCode === 0) {
3431
3578
  return {
3432
3579
  error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
@@ -3435,7 +3582,7 @@ try {
3435
3582
  const uploads = await this.uploadFiles([
3436
3583
  [
3437
3584
  filePath,
3438
- Buffer.from(content, "utf-8")
3585
+ Buffer.from(content, 'utf-8')
3439
3586
  ]
3440
3587
  ]);
3441
3588
  const first = uploads[0];
@@ -3458,9 +3605,9 @@ try {
3458
3605
  * Append content to a file. Creates the file if it doesn't exist.
3459
3606
  */ async append(filePath, content) {
3460
3607
  const command = buildAppendCommand(filePath, content);
3461
- const result = await this.execute(command);
3608
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3462
3609
  if (result.exitCode !== 0) {
3463
- const output = (result.output || "").trim();
3610
+ const output = (result.output || '').trim();
3464
3611
  return {
3465
3612
  error: output ? `Failed to append to file '${filePath}': ${output}` : `Failed to append to file '${filePath}'.`
3466
3613
  };
@@ -3474,7 +3621,7 @@ try {
3474
3621
  * Edit a file by replacing string occurrences.
3475
3622
  */ async edit(filePath, oldString, newString, replaceAll = false) {
3476
3623
  const command = buildEditCommand(filePath, oldString, newString, replaceAll);
3477
- const result = await this.execute(command);
3624
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3478
3625
  switch(result.exitCode){
3479
3626
  case 0:
3480
3627
  {
@@ -3510,7 +3657,7 @@ try {
3510
3657
  */ async multiEdit(filePath, edits) {
3511
3658
  if (!edits || edits.length === 0) {
3512
3659
  return {
3513
- error: "No edits provided"
3660
+ error: 'No edits provided'
3514
3661
  };
3515
3662
  }
3516
3663
  const results = [];
@@ -3554,4 +3701,4 @@ SandboxProviderRegistry = __decorate([
3554
3701
  ])
3555
3702
  ], SandboxProviderRegistry);
3556
3703
 
3557
- export { AGENT_CHAT_DISPATCH_MESSAGE_TYPE, AGENT_MIDDLEWARE_STRATEGY, AIModelProviderNotFoundException, AIModelProviderRegistry, AIModelProviderStrategy, AI_MODEL_PROVIDER, ANALYTICS_PERMISSION_SERVICE_TOKEN, AdapterDataSourceStrategy, AgentMiddlewareRegistry, AgentMiddlewareStrategy, AiModelNotFoundException, BaseHTTPQueryRunner, BaseQueryRunner, BaseSQLQueryRunner, BaseSandbox, BaseStrategyRegistry, BaseTool, BaseToolset, BuiltinToolset, CHAT_CHANNEL, CHAT_CHANNEL_TEXT_LIMITS, CancelConversationCommand, ChatChannel, ChatChannelRegistry, ChatOAICompatReasoningModel, CommonParameterRules, CreateModelClientCommand, CredentialsValidateFailedError, DATASOURCE_STRATEGY, DBCreateTableMode, DBProtocolEnum, DBSyntaxEnum, DBTableAction, DBTableDataAction, DEFAULT_EXECUTION_CONFIG, DOCUMENT_SOURCE_STRATEGY, DOCUMENT_TRANSFORMER_STRATEGY, DataSourceStrategy, DataSourceStrategyRegistry, DocumentSourceRegistry, DocumentSourceStrategy, DocumentTransformerRegistry, DocumentTransformerStrategy, GLOBAL_ORGANIZATION_SCOPE, HANDOFF_PERMISSION_SERVICE_TOKEN, HANDOFF_PROCESSOR_STRATEGY, HANDOFF_QUEUE_SERVICE_TOKEN, HandoffProcessorRegistry, HandoffProcessorStrategy, IMAGE_UNDERSTANDING_STRATEGY, INTEGRATION_PERMISSION_SERVICE_TOKEN, INTEGRATION_STRATEGY, ImageUnderstandingRegistry, ImageUnderstandingStrategy, IntegrationStrategyKey, IntegrationStrategyRegistry, JUMP_TO_TARGETS, JsonSchemaValidator, KNOWLEDGE_STRATEGY, KnowledgeStrategyKey, KnowledgeStrategyRegistry, LLMUsage, LargeLanguageModel, ModelProvider, ORGANIZATION_METADATA_KEY, OpenAICompatibleReranker, PERMISSION_OPERATION_METADATA_KEY, PLUGIN_METADATA, PLUGIN_METADATA_KEY, PROVIDE_AI_MODEL_LLM, PROVIDE_AI_MODEL_MODERATION, PROVIDE_AI_MODEL_RERANK, PROVIDE_AI_MODEL_SPEECH2TEXT, PROVIDE_AI_MODEL_TEXT_EMBEDDING, PROVIDE_AI_MODEL_TTS, RETRIEVER_STRATEGY, RequestContext, RequestContextMiddleware, RequirePermissionOperation, RerankModel, RetrieverRegistry, RetrieverStrategy, SANDBOX_PROVIDER, STRATEGY_META_KEY, SandboxProviderRegistry, SandboxProviderStrategy, Speech2TextChatModel, SpeechToTextModel, StrategyBus, TEXT_SPLITTER_STRATEGY, TOOLSET_STRATEGY, TextEmbeddingModelManager, TextSplitterRegistry, TextSplitterStrategy, TextToSpeechModel, ToolsetRegistry, ToolsetStrategy, USER_PERMISSION_SERVICE_TOKEN, VECTOR_STORE_STRATEGY, VectorStoreRegistry, VectorStoreStrategy, WORKFLOW_NODE_STRATEGY, WORKFLOW_TRIGGER_STRATEGY, WorkflowNodeRegistry, WorkflowNodeStrategy, WorkflowTriggerRegistry, WorkflowTriggerStrategy, WrapWorkflowNodeExecutionCommand, XpFileSystem, XpertServerPlugin, als, calcTokenUsage, chunkText, countTokensSafe, createI18nInstance, createPluginLogger, defineAgentMessageType, defineChannelMessageType, downloadRemoteFile, getErrorMessage, getModelContextSize, getPermissionOperationMetadata, getPositionList, getPositionMap, getRequestContext, getRequiredPermissionOperation, isRemoteFile, isSandboxBackend, isStructuredMessageType, loadYamlFile, mergeCredentials, mergeParentChildChunks, normalizeContextSize, runWithRequestContext, sumTokenUsage };
3704
+ export { AGENT_CHAT_DISPATCH_MESSAGE_TYPE, AGENT_MIDDLEWARE_STRATEGY, AIModelProviderNotFoundException, AIModelProviderRegistry, AIModelProviderStrategy, AI_MODEL_PROVIDER, ANALYTICS_PERMISSION_SERVICE_TOKEN, AdapterDataSourceStrategy, AgentMiddlewareRegistry, AgentMiddlewareStrategy, AiModelNotFoundException, BaseHTTPQueryRunner, BaseQueryRunner, BaseSQLQueryRunner, BaseSandbox, BaseStrategyRegistry, BaseTool, BaseToolset, BuiltinToolset, CHAT_CHANNEL, CHAT_CHANNEL_TEXT_LIMITS, CancelConversationCommand, ChatChannel, ChatChannelRegistry, ChatOAICompatReasoningModel, CommonParameterRules, CreateModelClientCommand, CredentialsValidateFailedError, DATASOURCE_STRATEGY, DBCreateTableMode, DBProtocolEnum, DBSyntaxEnum, DBTableAction, DBTableDataAction, DEFAULT_EXECUTION_CONFIG, DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS, DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS, DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS, DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS, DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC, DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS, DEFAULT_SANDBOX_SHELL_TIMEOUT_MS, DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC, DOCUMENT_SOURCE_STRATEGY, DOCUMENT_TRANSFORMER_STRATEGY, DataSourceStrategy, DataSourceStrategyRegistry, DocumentSourceRegistry, DocumentSourceStrategy, DocumentTransformerRegistry, DocumentTransformerStrategy, FILE_STORAGE_PROVIDER, FILE_UPLOAD_TARGET_STRATEGY, FileStorageProvider, FileStorageProviderRegistry, FileUploadTargetRegistry, FileUploadTargetStrategy, GLOBAL_ORGANIZATION_SCOPE, HANDOFF_PERMISSION_SERVICE_TOKEN, HANDOFF_PROCESSOR_STRATEGY, HANDOFF_QUEUE_SERVICE_TOKEN, HandoffProcessorRegistry, HandoffProcessorStrategy, IMAGE_UNDERSTANDING_STRATEGY, INTEGRATION_PERMISSION_SERVICE_TOKEN, INTEGRATION_STRATEGY, ImageUnderstandingRegistry, ImageUnderstandingStrategy, IntegrationStrategyKey, IntegrationStrategyRegistry, JUMP_TO_TARGETS, JsonSchemaValidator, KNOWLEDGE_STRATEGY, KnowledgeStrategyKey, KnowledgeStrategyRegistry, LLMUsage, LargeLanguageModel, ModelProvider, ORGANIZATION_METADATA_KEY, OpenAICompatibleReranker, PERMISSION_OPERATION_METADATA_KEY, PLUGIN_CONFIG_RESOLVER_TOKEN, PLUGIN_METADATA, PLUGIN_METADATA_KEY, PROVIDE_AI_MODEL_LLM, PROVIDE_AI_MODEL_MODERATION, PROVIDE_AI_MODEL_RERANK, PROVIDE_AI_MODEL_SPEECH2TEXT, PROVIDE_AI_MODEL_TEXT_EMBEDDING, PROVIDE_AI_MODEL_TTS, RETRIEVER_STRATEGY, RequestContext, RequestContextMiddleware, RequirePermissionOperation, RerankModel, RetrieverRegistry, RetrieverStrategy, SANDBOX_PROVIDER, SANDBOX_SHELL_TIMEOUT_LIMITS_SEC, STRATEGY_META_KEY, SandboxProviderRegistry, SandboxProviderStrategy, Speech2TextChatModel, SpeechToTextModel, StrategyBus, TEXT_SPLITTER_STRATEGY, TOOLSET_STRATEGY, TextEmbeddingModelManager, TextSplitterRegistry, TextSplitterStrategy, TextToSpeechModel, ToolsetRegistry, ToolsetStrategy, USER_PERMISSION_SERVICE_TOKEN, VECTOR_STORE_STRATEGY, VectorStoreRegistry, VectorStoreStrategy, WORKFLOW_NODE_STRATEGY, WORKFLOW_TRIGGER_STRATEGY, WorkflowNodeRegistry, WorkflowNodeStrategy, WorkflowTriggerRegistry, WorkflowTriggerStrategy, WrapWorkflowNodeExecutionCommand, XpFileSystem, XpertServerPlugin, als, appendSandboxMessage, buildSandboxTimeoutMessage, calcTokenUsage, chunkText, countTokensSafe, createI18nInstance, createPluginLogger, defineAgentMessageType, defineChannelMessageType, downloadRemoteFile, formatSandboxTimeout, getErrorMessage, getModelContextSize, getPermissionOperationMetadata, getPositionList, getPositionMap, getRequestContext, getRequiredPermissionOperation, isRemoteFile, isSandboxBackend, isStructuredMessageType, loadYamlFile, mergeCredentials, mergeParentChildChunks, normalizeContextSize, resolveSandboxExecutionOptions, runWithRequestContext, secondsToMilliseconds, sumTokenUsage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpert-ai/plugin-sdk",
3
- "version": "3.8.1",
3
+ "version": "3.8.4",
4
4
  "license": "AGPL-3.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.d.ts CHANGED
@@ -13,5 +13,6 @@ export * from './lib/data/index';
13
13
  export * from './lib/ai-model/index';
14
14
  export * from './lib/agent/index';
15
15
  export * from './lib/channel/index';
16
+ export * from './lib/file/index';
16
17
  export * from './lib/strategy';
17
18
  export * from './lib/sandbox/index';
@@ -41,6 +41,15 @@ export declare abstract class LargeLanguageModel extends AIModel {
41
41
  handleLLMError: (err: any) => void;
42
42
  };
43
43
  protected getCustomizableModelSchemaFromCredentials(model: string, credentials: Record<string, any>): AIModelEntity | null;
44
+ protected createHandleVerboseCallbacks(enabled?: boolean, logger?: Logger): {
45
+ handleChatModelStart: (llm: any, messages: any, runId: any, parentRunId: any, extraParams: any, tags: any, metadata: any, runName: any) => void;
46
+ handleLLMStart: (llm: any, prompts: any, runId: any, parentRunId: any, extraParams: any, tags: any, metadata: any, runName: any) => void;
47
+ handleLLMEnd: (output: any, runId: any, parentRunId: any, tags: any, extraParams: any) => void;
48
+ handleLLMError: (err: any, runId: any, parentRunId: any, tags: any, extraParams: any) => void;
49
+ }[];
50
+ private formatVerboseLog;
51
+ private stringifyLogPayload;
52
+ private formatError;
44
53
  }
45
54
  export declare function calcTokenUsage(output: LLMResult): TTokenUsage;
46
55
  /**
@@ -1,4 +1,5 @@
1
1
  export * from './file-system';
2
+ export * from './plugin-config';
2
3
  export * from './permissions';
3
4
  export * from './schema';
4
5
  export * from './i18n';
@@ -1,4 +1,4 @@
1
- import type { IIntegration } from '@metad/contracts';
1
+ import type { IIntegration, IPagination } from '@metad/contracts';
2
2
  /**
3
3
  * Base Permission type
4
4
  */
@@ -68,4 +68,5 @@ export declare const INTEGRATION_PERMISSION_SERVICE_TOKEN = "XPERT_PLUGIN_INTEGR
68
68
  */
69
69
  export interface IntegrationPermissionService {
70
70
  read<TIntegration = IIntegration>(id: string, options?: Record<string, any>): Promise<TIntegration | null>;
71
+ findAll<TIntegration = IIntegration>(options?: Record<string, any>): Promise<IPagination<TIntegration>>;
71
72
  }
@@ -0,0 +1,9 @@
1
+ export interface PluginConfigResolveOptions<TConfig extends object = Record<string, any>> {
2
+ organizationId?: string;
3
+ fallbackToGlobal?: boolean;
4
+ defaults?: Partial<TConfig>;
5
+ }
6
+ export interface IPluginConfigResolver {
7
+ resolve<TConfig extends object = Record<string, any>>(pluginName: string, options?: PluginConfigResolveOptions<TConfig>): TConfig;
8
+ }
9
+ export declare const PLUGIN_CONFIG_RESOLVER_TOKEN = "XPERT_PLUGIN_CONFIG_RESOLVER";
@@ -0,0 +1,3 @@
1
+ export * from './provider.decorator';
2
+ export * from './provider.interface';
3
+ export * from './provider.registry';
@@ -0,0 +1,2 @@
1
+ export declare const FILE_STORAGE_PROVIDER = "FILE_STORAGE_PROVIDER";
2
+ export declare const FileStorageProvider: (provider: string) => <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { FileStorageOption, FileSystem, UploadedFile } from '@metad/contracts';
4
+ export interface IFileStorageProvider {
5
+ readonly name: string;
6
+ readonly config?: FileSystem & Record<string, any>;
7
+ url(path: string): string;
8
+ path(path: string): string;
9
+ handler(options: FileStorageOption): any;
10
+ getFile(file: string): Promise<Buffer>;
11
+ putFile(fileContent: string | Buffer | URL, path?: string): Promise<UploadedFile>;
12
+ deleteFile(path: string): Promise<void>;
13
+ mapUploadedFile?(file: any): UploadedFile;
14
+ }
@@ -0,0 +1,6 @@
1
+ import { DiscoveryService, Reflector } from '@nestjs/core';
2
+ import { BaseStrategyRegistry } from '../../strategy';
3
+ import { IFileStorageProvider } from './provider.interface';
4
+ export declare class FileStorageProviderRegistry extends BaseStrategyRegistry<IFileStorageProvider> {
5
+ constructor(discoveryService: DiscoveryService, reflector: Reflector);
6
+ }
@@ -0,0 +1,3 @@
1
+ export * from './strategy.decorator';
2
+ export * from './strategy.interface';
3
+ export * from './strategy.registry';
@@ -0,0 +1,2 @@
1
+ export declare const FILE_UPLOAD_TARGET_STRATEGY = "FILE_UPLOAD_TARGET_STRATEGY";
2
+ export declare const FileUploadTargetStrategy: (type: string) => <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
@@ -0,0 +1,25 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { IFileAssetDestination, IFileAssetSource, IStorageFile, IUploadFileTarget } from '@metad/contracts';
4
+ export type TFileUploadRequestContext = {
5
+ tenantId?: string;
6
+ organizationId?: string;
7
+ userId?: string;
8
+ };
9
+ export type TResolvedFileUploadSource = {
10
+ name: string;
11
+ originalName: string;
12
+ mimeType?: string;
13
+ size?: number;
14
+ buffer: Buffer;
15
+ source: IFileAssetSource;
16
+ storageFile?: IStorageFile;
17
+ };
18
+ export type TFileUploadContext = {
19
+ request: TFileUploadRequestContext;
20
+ metadata?: Record<string, any>;
21
+ };
22
+ export type TStorageProviderType = string;
23
+ export interface IFileUploadTargetStrategy<TTarget extends IUploadFileTarget = IUploadFileTarget> {
24
+ upload(source: TResolvedFileUploadSource, target: TTarget, context: TFileUploadContext): Promise<IFileAssetDestination>;
25
+ }
@@ -0,0 +1,6 @@
1
+ import { DiscoveryService, Reflector } from '@nestjs/core';
2
+ import { BaseStrategyRegistry } from '../../strategy';
3
+ import { IFileUploadTargetStrategy } from './strategy.interface';
4
+ export declare class FileUploadTargetRegistry extends BaseStrategyRegistry<IFileUploadTargetStrategy> {
5
+ constructor(discoveryService: DiscoveryService, reflector: Reflector);
6
+ }