@xpert-ai/plugin-sdk 3.8.0 → 3.8.3

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
@@ -531,6 +531,7 @@ exports.WorkflowNodeRegistry = __decorate([
531
531
  ])
532
532
  ], exports.WorkflowNodeRegistry);
533
533
 
534
+ const COMMAND_METADATA$1 = '__command__';
534
535
  /**
535
536
  * Wrap Workflow Node Execution Command
536
537
  */ class WrapWorkflowNodeExecutionCommand extends cqrs.Command {
@@ -541,6 +542,9 @@ exports.WorkflowNodeRegistry = __decorate([
541
542
  }
542
543
  }
543
544
  WrapWorkflowNodeExecutionCommand.type = '[Workflow] Wrap Workflow Node Execution';
545
+ Reflect.defineMetadata(COMMAND_METADATA$1, {
546
+ id: WrapWorkflowNodeExecutionCommand.type
547
+ }, WrapWorkflowNodeExecutionCommand);
544
548
 
545
549
  const VECTOR_STORE_STRATEGY = 'VECTOR_STORE_STRATEGY';
546
550
  const VectorStoreStrategy = (provider)=>common.applyDecorators(common.SetMetadata(VECTOR_STORE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, VECTOR_STORE_STRATEGY));
@@ -952,6 +956,8 @@ BuiltinToolset.provider = '';
952
956
  }
953
957
  }
954
958
 
959
+ const PLUGIN_CONFIG_RESOLVER_TOKEN = 'XPERT_PLUGIN_CONFIG_RESOLVER';
960
+
955
961
  /**
956
962
  * System token for resolving integration read service from plugin context.
957
963
  */ const INTEGRATION_PERMISSION_SERVICE_TOKEN = 'XPERT_PLUGIN_INTEGRATION_PERMISSION_SERVICE';
@@ -2384,6 +2390,7 @@ function normalizeContextSize(value) {
2384
2390
  return undefined;
2385
2391
  }
2386
2392
 
2393
+ const COMMAND_METADATA = '__command__';
2387
2394
  /**
2388
2395
  * Get a Chat Model of copilot model and check it's token limitation, record the token usage
2389
2396
  */ class CreateModelClientCommand extends cqrs.Command {
@@ -2394,6 +2401,9 @@ function normalizeContextSize(value) {
2394
2401
  }
2395
2402
  }
2396
2403
  CreateModelClientCommand.type = '[AI Model] Create Model Client';
2404
+ Reflect.defineMetadata(COMMAND_METADATA, {
2405
+ id: CreateModelClientCommand.type
2406
+ }, CreateModelClientCommand);
2397
2407
 
2398
2408
  const AGENT_MIDDLEWARE_STRATEGY = 'AGENT_MIDDLEWARE_STRATEGY';
2399
2409
  const AgentMiddlewareStrategy = (provider)=>common.applyDecorators(common.SetMetadata(AGENT_MIDDLEWARE_STRATEGY, provider), common.SetMetadata(STRATEGY_META_KEY, AGENT_MIDDLEWARE_STRATEGY));
@@ -2627,41 +2637,167 @@ class CancelConversationCommand {
2627
2637
  }
2628
2638
  CancelConversationCommand.type = '[Chat Conversation] Cancel';
2629
2639
 
2640
+ const FILE_STORAGE_PROVIDER = 'FILE_STORAGE_PROVIDER';
2641
+ const FileStorageProvider = (provider)=>common.applyDecorators(common.SetMetadata(FILE_STORAGE_PROVIDER, provider), common.SetMetadata(STRATEGY_META_KEY, FILE_STORAGE_PROVIDER));
2642
+
2643
+ exports.FileStorageProviderRegistry = class FileStorageProviderRegistry extends BaseStrategyRegistry {
2644
+ constructor(discoveryService, reflector){
2645
+ super(FILE_STORAGE_PROVIDER, discoveryService, reflector);
2646
+ }
2647
+ };
2648
+ exports.FileStorageProviderRegistry = __decorate([
2649
+ common.Injectable(),
2650
+ __metadata("design:type", Function),
2651
+ __metadata("design:paramtypes", [
2652
+ typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService,
2653
+ typeof core.Reflector === "undefined" ? Object : core.Reflector
2654
+ ])
2655
+ ], exports.FileStorageProviderRegistry);
2656
+
2657
+ const FILE_UPLOAD_TARGET_STRATEGY = 'FILE_UPLOAD_TARGET_STRATEGY';
2658
+ const FileUploadTargetStrategy = (type)=>common.applyDecorators(common.SetMetadata(FILE_UPLOAD_TARGET_STRATEGY, type), common.SetMetadata(STRATEGY_META_KEY, FILE_UPLOAD_TARGET_STRATEGY));
2659
+
2660
+ exports.FileUploadTargetRegistry = class FileUploadTargetRegistry extends BaseStrategyRegistry {
2661
+ constructor(discoveryService, reflector){
2662
+ super(FILE_UPLOAD_TARGET_STRATEGY, discoveryService, reflector);
2663
+ }
2664
+ };
2665
+ exports.FileUploadTargetRegistry = __decorate([
2666
+ common.Injectable(),
2667
+ __metadata("design:type", Function),
2668
+ __metadata("design:paramtypes", [
2669
+ typeof core.DiscoveryService === "undefined" ? Object : core.DiscoveryService,
2670
+ typeof core.Reflector === "undefined" ? Object : core.Reflector
2671
+ ])
2672
+ ], exports.FileUploadTargetRegistry);
2673
+
2674
+ const SANDBOX_SHELL_TIMEOUT_LIMITS_SEC = {
2675
+ min: 1,
2676
+ max: 3600
2677
+ };
2678
+ const DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC = 600;
2679
+ const DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC = 120;
2680
+ const DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC = 120;
2681
+ const DEFAULT_SANDBOX_SHELL_TIMEOUT_MS = DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC * 1000;
2682
+ const DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC * 1000;
2683
+ const DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC * 1000;
2684
+ const DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES = 1024 * 1024;
2685
+ const DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS = {
2686
+ timeoutMs: DEFAULT_SANDBOX_SHELL_TIMEOUT_MS,
2687
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2688
+ };
2689
+ const DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS = {
2690
+ timeoutMs: DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS,
2691
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2692
+ };
2693
+ const DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS = {
2694
+ timeoutMs: DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS,
2695
+ maxOutputBytes: DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES
2696
+ };
2697
+ function secondsToMilliseconds(seconds) {
2698
+ return Math.trunc(seconds * 1000);
2699
+ }
2700
+ function formatSandboxTimeout(timeoutMs) {
2701
+ const timeoutSeconds = timeoutMs / 1000;
2702
+ const secondsLabel = Number.isInteger(timeoutSeconds) ? String(timeoutSeconds) : Number(timeoutSeconds.toFixed(3)).toString();
2703
+ return `${secondsLabel}s (${timeoutMs}ms)`;
2704
+ }
2705
+ function buildSandboxTimeoutMessage(subject, timeoutMs) {
2706
+ return `${subject} timed out after ${formatSandboxTimeout(timeoutMs)}`;
2707
+ }
2708
+ function appendSandboxMessage(output, message) {
2709
+ return output ? `${output}\n${message}` : message;
2710
+ }
2711
+ function resolveSandboxExecutionOptions(options, defaults = DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS) {
2712
+ 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;
2713
+ 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;
2714
+ return {
2715
+ timeoutMs,
2716
+ maxOutputBytes
2717
+ };
2718
+ }
2719
+
2630
2720
  /**
2631
- * Protocol definition for pluggable memory backends.
2632
- *
2633
- * This module defines the BackendProtocol that all backend implementations
2634
- * must follow. Backends can store files in different locations (state, filesystem,
2635
- * database, etc.) and provide a uniform interface for file operations.
2636
- */ /**
2637
2721
  * Type guard to check if a backend supports execution.
2638
2722
  *
2639
2723
  * @param backend - Backend instance to check
2640
2724
  * @returns True if the backend implements SandboxBackendProtocol
2641
2725
  */ function isSandboxBackend(backend) {
2642
- return typeof backend.execute === "function" && typeof backend.id === "string";
2726
+ return typeof backend.execute === 'function' && typeof backend.id === 'string';
2643
2727
  }
2644
2728
 
2729
+ const MAX_LINE_LENGTH = 500;
2730
+ const MAX_GREP_LINE_LENGTH = 2000;
2731
+ const GREP_RESULT_LIMIT = 100;
2732
+ const GLOB_RESULT_LIMIT = 100;
2733
+ const WRITE_EXISTS_OUTPUT = 'Error: File already exists';
2734
+ /**
2735
+ * UTF-8 safe Base64 encoding function.
2736
+ * Replaces btoa() which only supports Latin1 characters.
2737
+ */ function utf8ToBase64(str) {
2738
+ return Buffer.from(str, 'utf-8').toString('base64');
2739
+ }
2740
+ /**
2741
+ * Format glob results into human-readable output.
2742
+ */ function formatGlobOutput(files, pattern) {
2743
+ const limit = GLOB_RESULT_LIMIT;
2744
+ const truncated = files.length > limit;
2745
+ const finalFiles = truncated ? files.slice(0, limit) : files;
2746
+ if (finalFiles.length === 0) {
2747
+ return 'No files found';
2748
+ }
2749
+ const lines = [];
2750
+ for (const file of finalFiles){
2751
+ lines.push(file.path);
2752
+ }
2753
+ if (truncated) {
2754
+ lines.push('');
2755
+ lines.push('(Results truncated. Consider using a more specific path or pattern.)');
2756
+ }
2757
+ return lines.join('\n');
2758
+ }
2759
+ /**
2760
+ * Format grep matches into human-readable output grouped by file.
2761
+ */ function formatGrepOutput(matches) {
2762
+ const limit = GREP_RESULT_LIMIT;
2763
+ const truncated = matches.length > limit;
2764
+ const finalMatches = truncated ? matches.slice(0, limit) : matches;
2765
+ if (finalMatches.length === 0) {
2766
+ return 'No matches found';
2767
+ }
2768
+ const lines = [
2769
+ `Found ${finalMatches.length} matches`
2770
+ ];
2771
+ let currentFile = '';
2772
+ for (const match of finalMatches){
2773
+ if (currentFile !== match.path) {
2774
+ if (currentFile !== '') {
2775
+ lines.push('');
2776
+ }
2777
+ currentFile = match.path;
2778
+ lines.push(`${match.path}:`);
2779
+ }
2780
+ const text = match.text.length > MAX_GREP_LINE_LENGTH ? match.text.substring(0, MAX_GREP_LINE_LENGTH) + '...' : match.text;
2781
+ lines.push(` Line ${match.line}: ${text}`);
2782
+ }
2783
+ if (truncated) {
2784
+ lines.push('');
2785
+ lines.push('(Results truncated. Consider using a more specific path or pattern.)');
2786
+ }
2787
+ return lines.join('\n');
2788
+ }
2645
2789
  /**
2646
- * BaseSandbox: Abstract base class for sandbox backends with command execution.
2647
- *
2648
- * This class provides default implementations for all SandboxBackendProtocol
2649
- * methods using shell commands executed via execute(). Concrete implementations
2650
- * only need to implement the execute() method.
2651
- *
2652
- * Requires Node.js 20+ on the sandbox host.
2653
- */ /**
2654
2790
  * Node.js command template for glob operations.
2655
2791
  * Uses web-standard atob() for base64 decoding.
2656
2792
  */ function buildGlobCommand(searchPath, pattern) {
2657
- const pathB64 = btoa(searchPath);
2658
- const patternB64 = btoa(pattern);
2793
+ const pathB64 = utf8ToBase64(searchPath);
2794
+ const patternB64 = utf8ToBase64(pattern);
2659
2795
  return `node -e "
2660
2796
  const fs = require('fs');
2661
2797
  const path = require('path');
2662
2798
 
2663
- const searchPath = atob('${pathB64}');
2664
- const pattern = atob('${patternB64}');
2799
+ const searchPath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
2800
+ const pattern = Buffer.from('${patternB64}', 'base64').toString('utf-8');
2665
2801
 
2666
2802
  function globMatch(relativePath, pattern) {
2667
2803
  const regexPattern = pattern
@@ -2706,12 +2842,12 @@ try {
2706
2842
  /**
2707
2843
  * Node.js command template for listing directory contents.
2708
2844
  */ function buildLsCommand(dirPath) {
2709
- const pathB64 = btoa(dirPath);
2845
+ const pathB64 = utf8ToBase64(dirPath);
2710
2846
  return `node -e "
2711
2847
  const fs = require('fs');
2712
2848
  const path = require('path');
2713
2849
 
2714
- const dirPath = atob('${pathB64}');
2850
+ const dirPath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
2715
2851
 
2716
2852
  try {
2717
2853
  const entries = fs.readdirSync(dirPath, { withFileTypes: true });
@@ -2731,17 +2867,129 @@ try {
2731
2867
  }
2732
2868
  "`;
2733
2869
  }
2870
+ const INDENTATION_SPACES = 2;
2871
+ const MAX_ENTRY_LENGTH = 500;
2872
+ /**
2873
+ * Node.js command template for recursive directory listing with depth control.
2874
+ */ function buildListDirCommand(dirPath, offset, limit, depth) {
2875
+ const pathB64 = utf8ToBase64(dirPath);
2876
+ const safeOffset = Number.isFinite(offset) && offset > 0 ? Math.floor(offset) : 1;
2877
+ const safeLimit = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : 25;
2878
+ const safeDepth = Number.isFinite(depth) && depth > 0 ? Math.floor(depth) : 2;
2879
+ return `node -e "
2880
+ const fs = require('fs');
2881
+ const path = require('path');
2882
+
2883
+ const dirPath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
2884
+ const offset = ${safeOffset};
2885
+ const limit = ${safeLimit};
2886
+ const maxDepth = ${safeDepth};
2887
+ const INDENTATION_SPACES = ${INDENTATION_SPACES};
2888
+ const MAX_ENTRY_LENGTH = ${MAX_ENTRY_LENGTH};
2889
+
2890
+ if (!path.isAbsolute(dirPath)) {
2891
+ console.error('Error: dir_path must be an absolute path');
2892
+ process.exit(1);
2893
+ }
2894
+
2895
+ if (!fs.existsSync(dirPath)) {
2896
+ console.error('Error: Directory not found');
2897
+ process.exit(1);
2898
+ }
2899
+
2900
+ if (!fs.statSync(dirPath).isDirectory()) {
2901
+ console.error('Error: Path is not a directory');
2902
+ process.exit(1);
2903
+ }
2904
+
2905
+ function collectEntries(currentPath, relativePrefix, remainingDepth, entries) {
2906
+ if (remainingDepth === 0) return;
2907
+
2908
+ try {
2909
+ const dirEntries = fs.readdirSync(currentPath, { withFileTypes: true });
2910
+ const sortedEntries = dirEntries
2911
+ .map(entry => {
2912
+ const fullPath = path.join(currentPath, entry.name);
2913
+ const relativePath = path.join(relativePrefix, entry.name);
2914
+ const displayName = entry.name.length > MAX_ENTRY_LENGTH
2915
+ ? entry.name.substring(0, MAX_ENTRY_LENGTH)
2916
+ : entry.name;
2917
+
2918
+ let kind = 'file';
2919
+ if (entry.isSymbolicLink()) kind = 'symlink';
2920
+ else if (entry.isDirectory()) kind = 'directory';
2921
+
2922
+ return {
2923
+ fullPath,
2924
+ relativePath,
2925
+ displayName,
2926
+ kind,
2927
+ depth: relativePrefix.split(path.sep).filter(Boolean).length
2928
+ };
2929
+ })
2930
+ .sort((a, b) => a.relativePath.localeCompare(b.relativePath));
2931
+
2932
+ for (const entry of sortedEntries) {
2933
+ entries.push(entry);
2934
+ if (entry.kind === 'directory' && remainingDepth > 1) {
2935
+ collectEntries(entry.fullPath, entry.relativePath, remainingDepth - 1, entries);
2936
+ }
2937
+ }
2938
+ } catch (e) {
2939
+ // Skip unreadable directories
2940
+ }
2941
+ }
2942
+
2943
+ const allEntries = [];
2944
+ collectEntries(dirPath, '', maxDepth, allEntries);
2945
+
2946
+ if (allEntries.length === 0) {
2947
+ console.log('Absolute path: ' + dirPath);
2948
+ console.log('(Empty directory)');
2949
+ process.exit(0);
2950
+ }
2951
+
2952
+ const startIndex = offset - 1;
2953
+ if (startIndex >= allEntries.length) {
2954
+ console.error('Error: offset exceeds directory entry count');
2955
+ process.exit(1);
2956
+ }
2957
+
2958
+ const endIndex = Math.min(startIndex + limit, allEntries.length);
2959
+ const selectedEntries = allEntries.slice(startIndex, endIndex);
2960
+
2961
+ console.log('Absolute path: ' + dirPath);
2962
+
2963
+ for (const entry of selectedEntries) {
2964
+ const indent = ' '.repeat(entry.depth * INDENTATION_SPACES);
2965
+ let name = entry.displayName;
2966
+ if (entry.kind === 'directory') name += '/';
2967
+ else if (entry.kind === 'symlink') name += '@';
2968
+ console.log(indent + name);
2969
+ }
2970
+
2971
+ if (endIndex < allEntries.length) {
2972
+ console.log('More than ' + limit + ' entries found');
2973
+ }
2974
+ "`;
2975
+ }
2976
+ const TAB_WIDTH = 4;
2977
+ const COMMENT_PREFIXES = [
2978
+ '#',
2979
+ '//',
2980
+ '--'
2981
+ ];
2734
2982
  /**
2735
- * Node.js command template for reading files.
2736
- */ function buildReadCommand(filePath, offset, limit) {
2737
- const pathB64 = btoa(filePath);
2738
- // Coerce offset and limit to safe non-negative integers before embedding in the shell command.
2739
- const safeOffset = Number.isFinite(offset) && offset > 0 ? Math.floor(offset) : 0;
2740
- const safeLimit = Number.isFinite(limit) && limit > 0 && limit < Number.MAX_SAFE_INTEGER ? Math.floor(limit) : 0;
2983
+ * Node.js command template for slice mode reading.
2984
+ */ function buildSliceReadCommand(filePath, offset, limit) {
2985
+ const pathB64 = utf8ToBase64(filePath);
2986
+ const safeOffset = Number.isFinite(offset) && offset > 0 ? Math.floor(offset) - 1 : 0;
2987
+ const safeLimit = Number.isFinite(limit) && limit > 0 && limit < Number.MAX_SAFE_INTEGER ? Math.floor(limit) : 2000;
2741
2988
  return `node -e "
2742
2989
  const fs = require('fs');
2990
+ const MAX_LINE_LENGTH = ${MAX_LINE_LENGTH};
2743
2991
 
2744
- const filePath = atob('${pathB64}');
2992
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
2745
2993
  const offset = ${safeOffset};
2746
2994
  const limit = ${safeLimit};
2747
2995
 
@@ -2758,28 +3006,188 @@ if (stat.size === 0) {
2758
3006
 
2759
3007
  const content = fs.readFileSync(filePath, 'utf-8');
2760
3008
  const lines = content.split('\\n');
3009
+
3010
+ if (offset >= lines.length) {
3011
+ console.log('Error: offset exceeds file length');
3012
+ process.exit(1);
3013
+ }
3014
+
2761
3015
  const selected = lines.slice(offset, offset + limit);
2762
3016
 
2763
3017
  for (let i = 0; i < selected.length; i++) {
2764
3018
  const lineNum = offset + i + 1;
2765
- console.log(String(lineNum).padStart(6) + '\\t' + selected[i]);
3019
+ let line = selected[i];
3020
+ if (line.length > MAX_LINE_LENGTH) {
3021
+ line = line.substring(0, MAX_LINE_LENGTH);
3022
+ }
3023
+ console.log('L' + lineNum + ': ' + line);
3024
+ }
3025
+ "`;
3026
+ }
3027
+ /**
3028
+ * Node.js command template for indentation mode reading.
3029
+ */ function buildIndentationReadCommand(filePath, offset, limit, options) {
3030
+ const pathB64 = utf8ToBase64(filePath);
3031
+ const safeOffset = Number.isFinite(offset) && offset > 0 ? Math.floor(offset) : 1;
3032
+ const safeLimit = Number.isFinite(limit) && limit > 0 && limit < Number.MAX_SAFE_INTEGER ? Math.floor(limit) : 2000;
3033
+ var _options_anchor_line;
3034
+ const anchorLine = (_options_anchor_line = options.anchor_line) != null ? _options_anchor_line : safeOffset;
3035
+ var _options_max_levels;
3036
+ const maxLevels = (_options_max_levels = options.max_levels) != null ? _options_max_levels : 0;
3037
+ var _options_include_siblings;
3038
+ const includeSiblings = (_options_include_siblings = options.include_siblings) != null ? _options_include_siblings : false;
3039
+ var _options_include_header;
3040
+ const includeHeader = (_options_include_header = options.include_header) != null ? _options_include_header : true;
3041
+ var _options_max_lines;
3042
+ const maxLines = (_options_max_lines = options.max_lines) != null ? _options_max_lines : safeLimit;
3043
+ return `node -e "
3044
+ const fs = require('fs');
3045
+ const MAX_LINE_LENGTH = ${MAX_LINE_LENGTH};
3046
+ const TAB_WIDTH = ${TAB_WIDTH};
3047
+ const COMMENT_PREFIXES = ${JSON.stringify(COMMENT_PREFIXES)};
3048
+
3049
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3050
+ const anchorLine = ${anchorLine};
3051
+ const limit = ${safeLimit};
3052
+ const maxLevels = ${maxLevels};
3053
+ const includeSiblings = ${includeSiblings};
3054
+ const includeHeader = ${includeHeader};
3055
+ const maxLines = ${maxLines};
3056
+
3057
+ if (!fs.existsSync(filePath)) {
3058
+ console.log('Error: File not found');
3059
+ process.exit(1);
3060
+ }
3061
+
3062
+ const content = fs.readFileSync(filePath, 'utf-8');
3063
+ const rawLines = content.split('\\n');
3064
+
3065
+ if (rawLines.length === 0 || anchorLine > rawLines.length) {
3066
+ console.log('Error: anchor_line exceeds file length');
3067
+ process.exit(1);
3068
+ }
3069
+
3070
+ function measureIndent(line) {
3071
+ let indent = 0;
3072
+ for (const c of line) {
3073
+ if (c === ' ') indent++;
3074
+ else if (c === '\\t') indent += TAB_WIDTH;
3075
+ else break;
3076
+ }
3077
+ return indent;
3078
+ }
3079
+
3080
+ function isBlank(line) { return line.trim() === ''; }
3081
+ function isComment(line) { return COMMENT_PREFIXES.some(p => line.trim().startsWith(p)); }
3082
+ function formatLine(line) { return line.length > MAX_LINE_LENGTH ? line.substring(0, MAX_LINE_LENGTH) : line; }
3083
+
3084
+ const records = rawLines.map((raw, i) => ({
3085
+ number: i + 1,
3086
+ raw,
3087
+ display: formatLine(raw),
3088
+ indent: measureIndent(raw)
3089
+ }));
3090
+
3091
+ const effectiveIndents = [];
3092
+ let prevIndent = 0;
3093
+ for (const r of records) {
3094
+ if (isBlank(r.raw)) {
3095
+ effectiveIndents.push(prevIndent);
3096
+ } else {
3097
+ prevIndent = r.indent;
3098
+ effectiveIndents.push(prevIndent);
3099
+ }
3100
+ }
3101
+
3102
+ const anchorIndex = anchorLine - 1;
3103
+ const anchorIndent = effectiveIndents[anchorIndex];
3104
+ const minIndent = maxLevels === 0 ? 0 : Math.max(0, anchorIndent - maxLevels * TAB_WIDTH);
3105
+ const finalLimit = Math.min(limit, maxLines, records.length);
3106
+
3107
+ if (finalLimit === 1) {
3108
+ console.log('L' + records[anchorIndex].number + ': ' + records[anchorIndex].display);
3109
+ process.exit(0);
3110
+ }
3111
+
3112
+ const out = [records[anchorIndex]];
3113
+ let i = anchorIndex - 1;
3114
+ let j = anchorIndex + 1;
3115
+ let iCounterMinIndent = 0;
3116
+ let jCounterMinIndent = 0;
3117
+
3118
+ while (out.length < finalLimit) {
3119
+ let progressed = 0;
3120
+
3121
+ if (i >= 0) {
3122
+ if (effectiveIndents[i] >= minIndent) {
3123
+ out.unshift(records[i]);
3124
+ progressed++;
3125
+ const curI = i;
3126
+ i--;
3127
+
3128
+ if (effectiveIndents[curI] === minIndent && !includeSiblings) {
3129
+ const allowHeaderComment = includeHeader && isComment(records[curI].raw);
3130
+ const canTakeLine = allowHeaderComment || iCounterMinIndent === 0;
3131
+ if (canTakeLine) {
3132
+ iCounterMinIndent++;
3133
+ } else {
3134
+ out.shift();
3135
+ progressed--;
3136
+ i = -1;
3137
+ }
3138
+ }
3139
+
3140
+ if (out.length >= finalLimit) break;
3141
+ } else {
3142
+ i = -1;
3143
+ }
3144
+ }
3145
+
3146
+ if (j < records.length) {
3147
+ if (effectiveIndents[j] >= minIndent) {
3148
+ out.push(records[j]);
3149
+ progressed++;
3150
+ const curJ = j;
3151
+ j++;
3152
+
3153
+ if (effectiveIndents[curJ] === minIndent && !includeSiblings) {
3154
+ if (jCounterMinIndent > 0) {
3155
+ out.pop();
3156
+ progressed--;
3157
+ j = records.length;
3158
+ }
3159
+ jCounterMinIndent++;
3160
+ }
3161
+ } else {
3162
+ j = records.length;
3163
+ }
3164
+ }
3165
+
3166
+ if (progressed === 0) break;
3167
+ }
3168
+
3169
+ while (out.length > 0 && isBlank(out[0].raw)) out.shift();
3170
+ while (out.length > 0 && isBlank(out[out.length - 1].raw)) out.pop();
3171
+
3172
+ for (const r of out) {
3173
+ console.log('L' + r.number + ': ' + r.display);
2766
3174
  }
2767
3175
  "`;
2768
3176
  }
2769
3177
  /**
2770
3178
  * Node.js command template for writing files.
2771
3179
  */ function buildWriteCommand(filePath, content) {
2772
- const pathB64 = btoa(filePath);
2773
- const contentB64 = btoa(content);
3180
+ const pathB64 = utf8ToBase64(filePath);
3181
+ const contentB64 = utf8ToBase64(content);
2774
3182
  return `node -e "
2775
3183
  const fs = require('fs');
2776
3184
  const path = require('path');
2777
3185
 
2778
- const filePath = atob('${pathB64}');
2779
- const content = atob('${contentB64}');
3186
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3187
+ const content = Buffer.from('${contentB64}', 'base64').toString('utf-8');
2780
3188
 
2781
3189
  if (fs.existsSync(filePath)) {
2782
- console.error('Error: File already exists');
3190
+ console.error('${WRITE_EXISTS_OUTPUT}');
2783
3191
  process.exit(1);
2784
3192
  }
2785
3193
 
@@ -2790,18 +3198,45 @@ fs.writeFileSync(filePath, content, 'utf-8');
2790
3198
  console.log('OK');
2791
3199
  "`;
2792
3200
  }
3201
+ function buildExistsCommand(filePath) {
3202
+ const pathB64 = utf8ToBase64(filePath);
3203
+ return `node -e "
3204
+ const fs = require('fs');
3205
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3206
+ process.exit(fs.existsSync(filePath) ? 0 : 1);
3207
+ "`;
3208
+ }
3209
+ /**
3210
+ * Node.js command template for appending to files.
3211
+ */ function buildAppendCommand(filePath, content) {
3212
+ const pathB64 = utf8ToBase64(filePath);
3213
+ const contentB64 = utf8ToBase64(content);
3214
+ return `node -e "
3215
+ const fs = require('fs');
3216
+ const path = require('path');
3217
+
3218
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3219
+ const content = Buffer.from('${contentB64}', 'base64').toString('utf-8');
3220
+
3221
+ const parentDir = path.dirname(filePath) || '.';
3222
+ fs.mkdirSync(parentDir, { recursive: true });
3223
+
3224
+ fs.appendFileSync(filePath, content, 'utf-8');
3225
+ console.log('OK');
3226
+ "`;
3227
+ }
2793
3228
  /**
2794
3229
  * Node.js command template for editing files.
2795
3230
  */ function buildEditCommand(filePath, oldStr, newStr, replaceAll) {
2796
- const pathB64 = btoa(filePath);
2797
- const oldB64 = btoa(oldStr);
2798
- const newB64 = btoa(newStr);
3231
+ const pathB64 = utf8ToBase64(filePath);
3232
+ const oldB64 = utf8ToBase64(oldStr);
3233
+ const newB64 = utf8ToBase64(newStr);
2799
3234
  return `node -e "
2800
3235
  const fs = require('fs');
2801
3236
 
2802
- const filePath = atob('${pathB64}');
2803
- const oldStr = atob('${oldB64}');
2804
- const newStr = atob('${newB64}');
3237
+ const filePath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3238
+ const oldStr = Buffer.from('${oldB64}', 'base64').toString('utf-8');
3239
+ const newStr = Buffer.from('${newB64}', 'base64').toString('utf-8');
2805
3240
  const replaceAll = ${Boolean(replaceAll)};
2806
3241
 
2807
3242
  let text;
@@ -2828,16 +3263,16 @@ console.log(count);
2828
3263
  /**
2829
3264
  * Node.js command template for grep operations.
2830
3265
  */ function buildGrepCommand(pattern, searchPath, globPattern) {
2831
- const patternB64 = btoa(pattern);
2832
- const pathB64 = btoa(searchPath);
2833
- const globB64 = globPattern ? btoa(globPattern) : "";
3266
+ const patternB64 = utf8ToBase64(pattern);
3267
+ const pathB64 = utf8ToBase64(searchPath);
3268
+ const globB64 = globPattern ? utf8ToBase64(globPattern) : '';
2834
3269
  return `node -e "
2835
3270
  const fs = require('fs');
2836
3271
  const path = require('path');
2837
3272
 
2838
- const pattern = atob('${patternB64}');
2839
- const searchPath = atob('${pathB64}');
2840
- const globPattern = ${globPattern ? `atob('${globB64}')` : "null"};
3273
+ const pattern = Buffer.from('${patternB64}', 'base64').toString('utf-8');
3274
+ const searchPath = Buffer.from('${pathB64}', 'base64').toString('utf-8');
3275
+ const globPattern = ${globPattern ? `Buffer.from('${globB64}', 'base64').toString('utf-8')` : 'null'};
2841
3276
 
2842
3277
  let regex;
2843
3278
  try {
@@ -2906,6 +3341,13 @@ try {
2906
3341
  *
2907
3342
  * Requires Node.js 20+ on the sandbox host.
2908
3343
  */ class BaseSandbox {
3344
+ async streamExecute(command, onLine, options) {
3345
+ const result = await this.execute(command, options);
3346
+ if (result.output) {
3347
+ onLine(result.output);
3348
+ }
3349
+ return result;
3350
+ }
2909
3351
  /**
2910
3352
  * List files and directories in the specified directory (non-recursive).
2911
3353
  *
@@ -2913,12 +3355,12 @@ try {
2913
3355
  * @returns List of FileInfo objects for files and directories directly in the directory.
2914
3356
  */ async lsInfo(path) {
2915
3357
  const command = buildLsCommand(path);
2916
- const result = await this.execute(command);
3358
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
2917
3359
  if (result.exitCode !== 0) {
2918
3360
  return [];
2919
3361
  }
2920
3362
  const infos = [];
2921
- const lines = result.output.trim().split("\n").filter(Boolean);
3363
+ const lines = result.output.trim().split('\n').filter(Boolean);
2922
3364
  for (const line of lines){
2923
3365
  try {
2924
3366
  const parsed = JSON.parse(line);
@@ -2935,33 +3377,60 @@ try {
2935
3377
  return infos;
2936
3378
  }
2937
3379
  /**
3380
+ * List directory contents recursively with depth control and pagination.
3381
+ *
3382
+ * @param dirPath - Absolute path to directory
3383
+ * @param offset - 1-indexed entry number to start from (default: 1)
3384
+ * @param limit - Maximum number of entries to return (default: 25)
3385
+ * @param depth - Maximum depth to traverse (default: 2)
3386
+ * @returns Human-readable directory tree with indentation
3387
+ */ async listDir(dirPath, offset = 1, limit = 25, depth = 2) {
3388
+ if (offset < 1) {
3389
+ return 'Error: offset must be a 1-indexed entry number';
3390
+ }
3391
+ if (limit < 1) {
3392
+ return 'Error: limit must be greater than zero';
3393
+ }
3394
+ if (depth < 1) {
3395
+ return 'Error: depth must be greater than zero';
3396
+ }
3397
+ const command = buildListDirCommand(dirPath, offset, limit, depth);
3398
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3399
+ if (result.exitCode !== 0) {
3400
+ return result.output || `Error: Failed to list directory '${dirPath}'`;
3401
+ }
3402
+ return result.output;
3403
+ }
3404
+ /**
2938
3405
  * Read file content with line numbers.
2939
3406
  *
2940
3407
  * @param filePath - Absolute file path
2941
- * @param offset - Line offset to start reading from (0-indexed)
3408
+ * @param offset - Line offset to start reading from (1-indexed)
2942
3409
  * @param limit - Maximum number of lines to read
3410
+ * @param mode - Read mode: 'slice' (default) or 'indentation'
3411
+ * @param indentation - Configuration for indentation mode
2943
3412
  * @returns Formatted file content with line numbers, or error message
2944
- */ async read(filePath, offset = 0, limit = 500) {
2945
- const command = buildReadCommand(filePath, offset, limit);
2946
- const result = await this.execute(command);
3413
+ */ async read(filePath, offset = 1, limit = 2000, mode = 'slice', indentation) {
3414
+ const command = mode === 'indentation' ? buildIndentationReadCommand(filePath, offset, limit, indentation != null ? indentation : {}) : buildSliceReadCommand(filePath, offset, limit);
3415
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
2947
3416
  if (result.exitCode !== 0) {
2948
- return `Error: File '${filePath}' not found`;
3417
+ return result.output || `Error: File '${filePath}' not found`;
2949
3418
  }
2950
3419
  return result.output;
2951
3420
  }
2952
3421
  /**
2953
3422
  * Structured search results or error string for invalid input.
2954
- */ async grepRaw(pattern, path = "/", glob = null) {
2955
- const command = buildGrepCommand(pattern, path, glob);
2956
- const result = await this.execute(command);
3423
+ */ async grepRaw(pattern, path = '/', include = null) {
3424
+ const command = buildGrepCommand(pattern, path, include);
3425
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
2957
3426
  if (result.exitCode === 1) {
2958
3427
  // Check if it's a regex error
2959
- if (result.output.includes("Invalid regex:")) {
3428
+ if (result.output.includes('Invalid regex:')) {
2960
3429
  return result.output.trim();
2961
3430
  }
2962
3431
  }
2963
3432
  const matches = [];
2964
- const lines = result.output.trim().split("\n").filter(Boolean);
3433
+ const lines = result.output.trim().split('\n').filter(Boolean);
2965
3434
  for (const line of lines){
2966
3435
  try {
2967
3436
  const parsed = JSON.parse(line);
@@ -2977,12 +3446,24 @@ try {
2977
3446
  return matches;
2978
3447
  }
2979
3448
  /**
3449
+ * Search file contents for a regex pattern, returning human-readable output.
3450
+ */ async grep(pattern, path = '/', include = null) {
3451
+ const result = await this.grepRaw(pattern, path, include);
3452
+ if (typeof result === 'string') {
3453
+ return result;
3454
+ }
3455
+ if (result.length === 0) {
3456
+ return 'No matches found';
3457
+ }
3458
+ return formatGrepOutput(result);
3459
+ }
3460
+ /**
2980
3461
  * Structured glob matching returning FileInfo objects.
2981
- */ async globInfo(pattern, path = "/") {
3462
+ */ async globInfo(pattern, path = '/') {
2982
3463
  const command = buildGlobCommand(path, pattern);
2983
- const result = await this.execute(command);
3464
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
2984
3465
  const infos = [];
2985
- const lines = result.output.trim().split("\n").filter(Boolean);
3466
+ const lines = result.output.trim().split('\n').filter(Boolean);
2986
3467
  for (const line of lines){
2987
3468
  try {
2988
3469
  const parsed = JSON.parse(line);
@@ -2999,15 +3480,79 @@ try {
2999
3480
  return infos;
3000
3481
  }
3001
3482
  /**
3483
+ * Find files matching a glob pattern, returning human-readable output.
3484
+ */ async glob(pattern, path = '/') {
3485
+ const files = await this.globInfo(pattern, path);
3486
+ if (files.length === 0) {
3487
+ return 'No files found';
3488
+ }
3489
+ return formatGlobOutput(files);
3490
+ }
3491
+ /**
3002
3492
  * Create a new file with content.
3003
3493
  */ async write(filePath, content) {
3004
3494
  const command = buildWriteCommand(filePath, content);
3005
- const result = await this.execute(command);
3495
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3006
3496
  if (result.exitCode !== 0) {
3497
+ const output = (result.output || '').trim();
3498
+ if (output.includes(WRITE_EXISTS_OUTPUT)) {
3499
+ return {
3500
+ error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
3501
+ };
3502
+ }
3503
+ const fallback = await this.writeViaUpload(filePath, content);
3504
+ if (!fallback.error) {
3505
+ return fallback;
3506
+ }
3507
+ return {
3508
+ error: output ? `Failed to write file '${filePath}': ${output}` : `Failed to write file '${filePath}'.`
3509
+ };
3510
+ }
3511
+ return {
3512
+ path: filePath,
3513
+ filesUpdate: null
3514
+ };
3515
+ }
3516
+ async writeViaUpload(filePath, content) {
3517
+ const existsCheck = await this.execute(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3518
+ if (existsCheck.exitCode === 0) {
3007
3519
  return {
3008
3520
  error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
3009
3521
  };
3010
3522
  }
3523
+ const uploads = await this.uploadFiles([
3524
+ [
3525
+ filePath,
3526
+ Buffer.from(content, 'utf-8')
3527
+ ]
3528
+ ]);
3529
+ const first = uploads[0];
3530
+ if (!first) {
3531
+ return {
3532
+ error: `Failed to write file '${filePath}': upload returned no result.`
3533
+ };
3534
+ }
3535
+ if (first.error) {
3536
+ return {
3537
+ error: `Failed to write file '${filePath}': ${first.error}`
3538
+ };
3539
+ }
3540
+ return {
3541
+ path: filePath,
3542
+ filesUpdate: null
3543
+ };
3544
+ }
3545
+ /**
3546
+ * Append content to a file. Creates the file if it doesn't exist.
3547
+ */ async append(filePath, content) {
3548
+ const command = buildAppendCommand(filePath, content);
3549
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3550
+ if (result.exitCode !== 0) {
3551
+ const output = (result.output || '').trim();
3552
+ return {
3553
+ error: output ? `Failed to append to file '${filePath}': ${output}` : `Failed to append to file '${filePath}'.`
3554
+ };
3555
+ }
3011
3556
  return {
3012
3557
  path: filePath,
3013
3558
  filesUpdate: null
@@ -3017,7 +3562,7 @@ try {
3017
3562
  * Edit a file by replacing string occurrences.
3018
3563
  */ async edit(filePath, oldString, newString, replaceAll = false) {
3019
3564
  const command = buildEditCommand(filePath, oldString, newString, replaceAll);
3020
- const result = await this.execute(command);
3565
+ const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3021
3566
  switch(result.exitCode){
3022
3567
  case 0:
3023
3568
  {
@@ -3046,6 +3591,38 @@ try {
3046
3591
  };
3047
3592
  }
3048
3593
  }
3594
+ /**
3595
+ * Perform multiple sequential edits on a single file.
3596
+ * All edits are applied sequentially, with each edit operating on the result of the previous edit.
3597
+ * All edits must succeed for the operation to succeed (atomic).
3598
+ */ async multiEdit(filePath, edits) {
3599
+ if (!edits || edits.length === 0) {
3600
+ return {
3601
+ error: 'No edits provided'
3602
+ };
3603
+ }
3604
+ const results = [];
3605
+ for (const edit of edits){
3606
+ var _edit_replaceAll;
3607
+ const result = await this.edit(filePath, edit.oldString, edit.newString, (_edit_replaceAll = edit.replaceAll) != null ? _edit_replaceAll : false);
3608
+ results.push(result);
3609
+ // If any edit fails, return immediately with error
3610
+ if (result.error) {
3611
+ return {
3612
+ error: `Multi-edit failed at edit ${results.length}: ${result.error}`,
3613
+ path: filePath,
3614
+ filesUpdate: null,
3615
+ results
3616
+ };
3617
+ }
3618
+ }
3619
+ // All edits succeeded
3620
+ return {
3621
+ path: filePath,
3622
+ filesUpdate: null,
3623
+ results
3624
+ };
3625
+ }
3049
3626
  }
3050
3627
 
3051
3628
  const SANDBOX_PROVIDER = 'SANDBOX_PROVIDER';
@@ -3108,11 +3685,25 @@ exports.CreateModelClientCommand = CreateModelClientCommand;
3108
3685
  exports.CredentialsValidateFailedError = CredentialsValidateFailedError;
3109
3686
  exports.DATASOURCE_STRATEGY = DATASOURCE_STRATEGY;
3110
3687
  exports.DEFAULT_EXECUTION_CONFIG = DEFAULT_EXECUTION_CONFIG;
3688
+ exports.DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES = DEFAULT_SANDBOX_EXECUTION_MAX_OUTPUT_BYTES;
3689
+ exports.DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS = DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS;
3690
+ exports.DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_MS;
3691
+ exports.DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC = DEFAULT_SANDBOX_FILE_OPERATION_TIMEOUT_SEC;
3692
+ exports.DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS = DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS;
3693
+ exports.DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS = DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_MS;
3694
+ exports.DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC = DEFAULT_SANDBOX_FILE_SEARCH_TIMEOUT_SEC;
3695
+ exports.DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS = DEFAULT_SANDBOX_SHELL_EXECUTION_OPTIONS;
3696
+ exports.DEFAULT_SANDBOX_SHELL_TIMEOUT_MS = DEFAULT_SANDBOX_SHELL_TIMEOUT_MS;
3697
+ exports.DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC = DEFAULT_SANDBOX_SHELL_TIMEOUT_SEC;
3111
3698
  exports.DOCUMENT_SOURCE_STRATEGY = DOCUMENT_SOURCE_STRATEGY;
3112
3699
  exports.DOCUMENT_TRANSFORMER_STRATEGY = DOCUMENT_TRANSFORMER_STRATEGY;
3113
3700
  exports.DataSourceStrategy = DataSourceStrategy;
3114
3701
  exports.DocumentSourceStrategy = DocumentSourceStrategy;
3115
3702
  exports.DocumentTransformerStrategy = DocumentTransformerStrategy;
3703
+ exports.FILE_STORAGE_PROVIDER = FILE_STORAGE_PROVIDER;
3704
+ exports.FILE_UPLOAD_TARGET_STRATEGY = FILE_UPLOAD_TARGET_STRATEGY;
3705
+ exports.FileStorageProvider = FileStorageProvider;
3706
+ exports.FileUploadTargetStrategy = FileUploadTargetStrategy;
3116
3707
  exports.GLOBAL_ORGANIZATION_SCOPE = GLOBAL_ORGANIZATION_SCOPE;
3117
3708
  exports.HANDOFF_PERMISSION_SERVICE_TOKEN = HANDOFF_PERMISSION_SERVICE_TOKEN;
3118
3709
  exports.HANDOFF_PROCESSOR_STRATEGY = HANDOFF_PROCESSOR_STRATEGY;
@@ -3132,6 +3723,7 @@ exports.LargeLanguageModel = LargeLanguageModel;
3132
3723
  exports.ORGANIZATION_METADATA_KEY = ORGANIZATION_METADATA_KEY;
3133
3724
  exports.OpenAICompatibleReranker = OpenAICompatibleReranker;
3134
3725
  exports.PERMISSION_OPERATION_METADATA_KEY = PERMISSION_OPERATION_METADATA_KEY;
3726
+ exports.PLUGIN_CONFIG_RESOLVER_TOKEN = PLUGIN_CONFIG_RESOLVER_TOKEN;
3135
3727
  exports.PLUGIN_METADATA = PLUGIN_METADATA;
3136
3728
  exports.PLUGIN_METADATA_KEY = PLUGIN_METADATA_KEY;
3137
3729
  exports.PROVIDE_AI_MODEL_LLM = PROVIDE_AI_MODEL_LLM;
@@ -3146,6 +3738,7 @@ exports.RequirePermissionOperation = RequirePermissionOperation;
3146
3738
  exports.RerankModel = RerankModel;
3147
3739
  exports.RetrieverStrategy = RetrieverStrategy;
3148
3740
  exports.SANDBOX_PROVIDER = SANDBOX_PROVIDER;
3741
+ exports.SANDBOX_SHELL_TIMEOUT_LIMITS_SEC = SANDBOX_SHELL_TIMEOUT_LIMITS_SEC;
3149
3742
  exports.STRATEGY_META_KEY = STRATEGY_META_KEY;
3150
3743
  exports.SandboxProviderStrategy = SandboxProviderStrategy;
3151
3744
  exports.Speech2TextChatModel = Speech2TextChatModel;
@@ -3167,6 +3760,8 @@ exports.WrapWorkflowNodeExecutionCommand = WrapWorkflowNodeExecutionCommand;
3167
3760
  exports.XpFileSystem = XpFileSystem;
3168
3761
  exports.XpertServerPlugin = XpertServerPlugin;
3169
3762
  exports.als = als;
3763
+ exports.appendSandboxMessage = appendSandboxMessage;
3764
+ exports.buildSandboxTimeoutMessage = buildSandboxTimeoutMessage;
3170
3765
  exports.calcTokenUsage = calcTokenUsage;
3171
3766
  exports.chunkText = chunkText;
3172
3767
  exports.countTokensSafe = countTokensSafe;
@@ -3175,6 +3770,7 @@ exports.createPluginLogger = createPluginLogger;
3175
3770
  exports.defineAgentMessageType = defineAgentMessageType;
3176
3771
  exports.defineChannelMessageType = defineChannelMessageType;
3177
3772
  exports.downloadRemoteFile = downloadRemoteFile;
3773
+ exports.formatSandboxTimeout = formatSandboxTimeout;
3178
3774
  exports.getErrorMessage = getErrorMessage;
3179
3775
  exports.getModelContextSize = getModelContextSize;
3180
3776
  exports.getPermissionOperationMetadata = getPermissionOperationMetadata;
@@ -3189,5 +3785,7 @@ exports.loadYamlFile = loadYamlFile;
3189
3785
  exports.mergeCredentials = mergeCredentials;
3190
3786
  exports.mergeParentChildChunks = mergeParentChildChunks;
3191
3787
  exports.normalizeContextSize = normalizeContextSize;
3788
+ exports.resolveSandboxExecutionOptions = resolveSandboxExecutionOptions;
3192
3789
  exports.runWithRequestContext = runWithRequestContext;
3790
+ exports.secondsToMilliseconds = secondsToMilliseconds;
3193
3791
  exports.sumTokenUsage = sumTokenUsage;