@xpert-ai/plugin-sdk 3.8.3 → 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.cjs.js CHANGED
@@ -2011,11 +2011,11 @@ class LLMUsage {
2011
2011
  }
2012
2012
  plus(other) {
2013
2013
  /**
2014
- * Add two LLMUsage instances together.
2015
- *
2016
- * @param other: Another LLMUsage instance to add
2017
- * @return: A new LLMUsage instance with summed values
2018
- */ if (this.totalTokens === 0) {
2014
+ * Add two LLMUsage instances together.
2015
+ *
2016
+ * @param other: Another LLMUsage instance to add
2017
+ * @return: A new LLMUsage instance with summed values
2018
+ */ if (this.totalTokens === 0) {
2019
2019
  return other;
2020
2020
  } else {
2021
2021
  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);
@@ -2023,11 +2023,11 @@ class LLMUsage {
2023
2023
  }
2024
2024
  add(other) {
2025
2025
  /**
2026
- * Overload the + operator to add two LLMUsage instances.
2027
- *
2028
- * @param other: Another LLMUsage instance to add
2029
- * @return: A new LLMUsage instance with summed values
2030
- */ return this.plus(other);
2026
+ * Overload the + operator to add two LLMUsage instances.
2027
+ *
2028
+ * @param other: Another LLMUsage instance to add
2029
+ * @return: A new LLMUsage instance with summed values
2030
+ */ return this.plus(other);
2031
2031
  }
2032
2032
  constructor(promptTokens, promptUnitPrice, promptPriceUnit, promptPrice, completionTokens, completionUnitPrice, completionPriceUnit, completionPrice, totalTokens, totalPrice, currency, latency){
2033
2033
  this.promptTokens = promptTokens;
@@ -2147,6 +2147,78 @@ class LargeLanguageModel extends AIModel {
2147
2147
  }
2148
2148
  };
2149
2149
  }
2150
+ createHandleVerboseCallbacks(enabled, logger) {
2151
+ if (!enabled) {
2152
+ return [];
2153
+ }
2154
+ const targetLogger = logger != null ? logger : _class_private_field_loose_base(this, _logger)[_logger];
2155
+ return [
2156
+ {
2157
+ handleChatModelStart: (llm, messages, runId, parentRunId, extraParams, tags, metadata, runName)=>{
2158
+ targetLogger.verbose(this.formatVerboseLog('chat_model/start', {
2159
+ runId,
2160
+ parentRunId,
2161
+ runName,
2162
+ model: llm,
2163
+ messages,
2164
+ extraParams,
2165
+ tags,
2166
+ metadata
2167
+ }));
2168
+ },
2169
+ handleLLMStart: (llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName)=>{
2170
+ targetLogger.verbose(this.formatVerboseLog('llm/start', {
2171
+ runId,
2172
+ parentRunId,
2173
+ runName,
2174
+ model: llm,
2175
+ prompts,
2176
+ extraParams,
2177
+ tags,
2178
+ metadata
2179
+ }));
2180
+ },
2181
+ handleLLMEnd: (output, runId, parentRunId, tags, extraParams)=>{
2182
+ targetLogger.verbose(this.formatVerboseLog('llm/end', {
2183
+ runId,
2184
+ parentRunId,
2185
+ output,
2186
+ tags,
2187
+ extraParams
2188
+ }));
2189
+ },
2190
+ handleLLMError: (err, runId, parentRunId, tags, extraParams)=>{
2191
+ targetLogger.verbose(this.formatVerboseLog('llm/error', {
2192
+ runId,
2193
+ parentRunId,
2194
+ error: this.formatError(err),
2195
+ tags,
2196
+ extraParams
2197
+ }));
2198
+ }
2199
+ }
2200
+ ];
2201
+ }
2202
+ formatVerboseLog(event, payload) {
2203
+ return `[langchain][${event}] ${this.stringifyLogPayload(payload)}`;
2204
+ }
2205
+ stringifyLogPayload(payload) {
2206
+ try {
2207
+ return JSON.stringify(payload, null, 2);
2208
+ } catch (error) {
2209
+ return `[unserializable payload: ${this.formatError(error)}]`;
2210
+ }
2211
+ }
2212
+ formatError(error) {
2213
+ if (error instanceof Error) {
2214
+ return {
2215
+ name: error.name,
2216
+ message: error.message,
2217
+ stack: error.stack
2218
+ };
2219
+ }
2220
+ return error;
2221
+ }
2150
2222
  constructor(...args){
2151
2223
  super(...args);
2152
2224
  Object.defineProperty(this, _logger, {
@@ -3341,6 +3413,13 @@ try {
3341
3413
  *
3342
3414
  * Requires Node.js 20+ on the sandbox host.
3343
3415
  */ class BaseSandbox {
3416
+ /**
3417
+ * Internal hook for file/search operations. Concrete backends can override
3418
+ * this to distinguish "background helper commands" from user-facing shell
3419
+ * execute calls.
3420
+ */ executeOperation(command, options) {
3421
+ return this.execute(command, options);
3422
+ }
3344
3423
  async streamExecute(command, onLine, options) {
3345
3424
  const result = await this.execute(command, options);
3346
3425
  if (result.output) {
@@ -3355,7 +3434,7 @@ try {
3355
3434
  * @returns List of FileInfo objects for files and directories directly in the directory.
3356
3435
  */ async lsInfo(path) {
3357
3436
  const command = buildLsCommand(path);
3358
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3437
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3359
3438
  if (result.exitCode !== 0) {
3360
3439
  return [];
3361
3440
  }
@@ -3395,7 +3474,7 @@ try {
3395
3474
  return 'Error: depth must be greater than zero';
3396
3475
  }
3397
3476
  const command = buildListDirCommand(dirPath, offset, limit, depth);
3398
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3477
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3399
3478
  if (result.exitCode !== 0) {
3400
3479
  return result.output || `Error: Failed to list directory '${dirPath}'`;
3401
3480
  }
@@ -3412,7 +3491,7 @@ try {
3412
3491
  * @returns Formatted file content with line numbers, or error message
3413
3492
  */ async read(filePath, offset = 1, limit = 2000, mode = 'slice', indentation) {
3414
3493
  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);
3494
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3416
3495
  if (result.exitCode !== 0) {
3417
3496
  return result.output || `Error: File '${filePath}' not found`;
3418
3497
  }
@@ -3422,7 +3501,7 @@ try {
3422
3501
  * Structured search results or error string for invalid input.
3423
3502
  */ async grepRaw(pattern, path = '/', include = null) {
3424
3503
  const command = buildGrepCommand(pattern, path, include);
3425
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3504
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3426
3505
  if (result.exitCode === 1) {
3427
3506
  // Check if it's a regex error
3428
3507
  if (result.output.includes('Invalid regex:')) {
@@ -3461,7 +3540,7 @@ try {
3461
3540
  * Structured glob matching returning FileInfo objects.
3462
3541
  */ async globInfo(pattern, path = '/') {
3463
3542
  const command = buildGlobCommand(path, pattern);
3464
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3543
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3465
3544
  const infos = [];
3466
3545
  const lines = result.output.trim().split('\n').filter(Boolean);
3467
3546
  for (const line of lines){
@@ -3492,7 +3571,7 @@ try {
3492
3571
  * Create a new file with content.
3493
3572
  */ async write(filePath, content) {
3494
3573
  const command = buildWriteCommand(filePath, content);
3495
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3574
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3496
3575
  if (result.exitCode !== 0) {
3497
3576
  const output = (result.output || '').trim();
3498
3577
  if (output.includes(WRITE_EXISTS_OUTPUT)) {
@@ -3514,7 +3593,7 @@ try {
3514
3593
  };
3515
3594
  }
3516
3595
  async writeViaUpload(filePath, content) {
3517
- const existsCheck = await this.execute(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3596
+ const existsCheck = await this.executeOperation(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3518
3597
  if (existsCheck.exitCode === 0) {
3519
3598
  return {
3520
3599
  error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
@@ -3546,7 +3625,7 @@ try {
3546
3625
  * Append content to a file. Creates the file if it doesn't exist.
3547
3626
  */ async append(filePath, content) {
3548
3627
  const command = buildAppendCommand(filePath, content);
3549
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3628
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3550
3629
  if (result.exitCode !== 0) {
3551
3630
  const output = (result.output || '').trim();
3552
3631
  return {
@@ -3562,7 +3641,7 @@ try {
3562
3641
  * Edit a file by replacing string occurrences.
3563
3642
  */ async edit(filePath, oldString, newString, replaceAll = false) {
3564
3643
  const command = buildEditCommand(filePath, oldString, newString, replaceAll);
3565
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3644
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3566
3645
  switch(result.exitCode){
3567
3646
  case 0:
3568
3647
  {
package/index.esm.js CHANGED
@@ -1991,11 +1991,11 @@ class LLMUsage {
1991
1991
  }
1992
1992
  plus(other) {
1993
1993
  /**
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) {
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) {
1999
1999
  return other;
2000
2000
  } else {
2001
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);
@@ -2003,11 +2003,11 @@ class LLMUsage {
2003
2003
  }
2004
2004
  add(other) {
2005
2005
  /**
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);
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);
2011
2011
  }
2012
2012
  constructor(promptTokens, promptUnitPrice, promptPriceUnit, promptPrice, completionTokens, completionUnitPrice, completionPriceUnit, completionPrice, totalTokens, totalPrice, currency, latency){
2013
2013
  this.promptTokens = promptTokens;
@@ -2127,6 +2127,78 @@ class LargeLanguageModel extends AIModel {
2127
2127
  }
2128
2128
  };
2129
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
+ }
2130
2202
  constructor(...args){
2131
2203
  super(...args);
2132
2204
  Object.defineProperty(this, _logger, {
@@ -3321,6 +3393,13 @@ try {
3321
3393
  *
3322
3394
  * Requires Node.js 20+ on the sandbox host.
3323
3395
  */ class BaseSandbox {
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
+ }
3324
3403
  async streamExecute(command, onLine, options) {
3325
3404
  const result = await this.execute(command, options);
3326
3405
  if (result.output) {
@@ -3335,7 +3414,7 @@ try {
3335
3414
  * @returns List of FileInfo objects for files and directories directly in the directory.
3336
3415
  */ async lsInfo(path) {
3337
3416
  const command = buildLsCommand(path);
3338
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3417
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3339
3418
  if (result.exitCode !== 0) {
3340
3419
  return [];
3341
3420
  }
@@ -3375,7 +3454,7 @@ try {
3375
3454
  return 'Error: depth must be greater than zero';
3376
3455
  }
3377
3456
  const command = buildListDirCommand(dirPath, offset, limit, depth);
3378
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3457
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3379
3458
  if (result.exitCode !== 0) {
3380
3459
  return result.output || `Error: Failed to list directory '${dirPath}'`;
3381
3460
  }
@@ -3392,7 +3471,7 @@ try {
3392
3471
  * @returns Formatted file content with line numbers, or error message
3393
3472
  */ async read(filePath, offset = 1, limit = 2000, mode = 'slice', indentation) {
3394
3473
  const command = mode === 'indentation' ? buildIndentationReadCommand(filePath, offset, limit, indentation != null ? indentation : {}) : buildSliceReadCommand(filePath, offset, limit);
3395
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3474
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3396
3475
  if (result.exitCode !== 0) {
3397
3476
  return result.output || `Error: File '${filePath}' not found`;
3398
3477
  }
@@ -3402,7 +3481,7 @@ try {
3402
3481
  * Structured search results or error string for invalid input.
3403
3482
  */ async grepRaw(pattern, path = '/', include = null) {
3404
3483
  const command = buildGrepCommand(pattern, path, include);
3405
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3484
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3406
3485
  if (result.exitCode === 1) {
3407
3486
  // Check if it's a regex error
3408
3487
  if (result.output.includes('Invalid regex:')) {
@@ -3441,7 +3520,7 @@ try {
3441
3520
  * Structured glob matching returning FileInfo objects.
3442
3521
  */ async globInfo(pattern, path = '/') {
3443
3522
  const command = buildGlobCommand(path, pattern);
3444
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3523
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_SEARCH_EXECUTION_OPTIONS);
3445
3524
  const infos = [];
3446
3525
  const lines = result.output.trim().split('\n').filter(Boolean);
3447
3526
  for (const line of lines){
@@ -3472,7 +3551,7 @@ try {
3472
3551
  * Create a new file with content.
3473
3552
  */ async write(filePath, content) {
3474
3553
  const command = buildWriteCommand(filePath, content);
3475
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3554
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3476
3555
  if (result.exitCode !== 0) {
3477
3556
  const output = (result.output || '').trim();
3478
3557
  if (output.includes(WRITE_EXISTS_OUTPUT)) {
@@ -3494,7 +3573,7 @@ try {
3494
3573
  };
3495
3574
  }
3496
3575
  async writeViaUpload(filePath, content) {
3497
- const existsCheck = await this.execute(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3576
+ const existsCheck = await this.executeOperation(buildExistsCommand(filePath), DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3498
3577
  if (existsCheck.exitCode === 0) {
3499
3578
  return {
3500
3579
  error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`
@@ -3526,7 +3605,7 @@ try {
3526
3605
  * Append content to a file. Creates the file if it doesn't exist.
3527
3606
  */ async append(filePath, content) {
3528
3607
  const command = buildAppendCommand(filePath, content);
3529
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3608
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3530
3609
  if (result.exitCode !== 0) {
3531
3610
  const output = (result.output || '').trim();
3532
3611
  return {
@@ -3542,7 +3621,7 @@ try {
3542
3621
  * Edit a file by replacing string occurrences.
3543
3622
  */ async edit(filePath, oldString, newString, replaceAll = false) {
3544
3623
  const command = buildEditCommand(filePath, oldString, newString, replaceAll);
3545
- const result = await this.execute(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3624
+ const result = await this.executeOperation(command, DEFAULT_SANDBOX_FILE_OPERATION_EXECUTION_OPTIONS);
3546
3625
  switch(result.exitCode){
3547
3626
  case 0:
3548
3627
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpert-ai/plugin-sdk",
3
- "version": "3.8.3",
3
+ "version": "3.8.4",
4
4
  "license": "AGPL-3.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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,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
  }
@@ -2,10 +2,22 @@ import { IIntegration, TIntegrationProvider } from '@metad/contracts';
2
2
  export type TIntegrationStrategyParams = {
3
3
  query: string;
4
4
  };
5
+ export type IntegrationTestProbe = {
6
+ connected?: boolean;
7
+ state?: string;
8
+ lastError?: string | null;
9
+ checkedAt?: number | null;
10
+ };
11
+ export type IntegrationTestResult = {
12
+ webhookUrl?: string;
13
+ mode?: string;
14
+ warnings?: string[];
15
+ probe?: IntegrationTestProbe;
16
+ } & Record<string, unknown>;
5
17
  export interface IntegrationStrategy<T = unknown> {
6
18
  meta: TIntegrationProvider;
7
19
  execute(integration: IIntegration<T>, payload: TIntegrationStrategyParams): Promise<any>;
8
- validateConfig?(config: T, integration?: IIntegration<T>): Promise<void | {
9
- webhookUrl: string;
10
- }>;
20
+ onUpdate?(previous: IIntegration<T>, current: IIntegration<any>): Promise<void> | void;
21
+ onDelete?(integration: IIntegration<T>): Promise<void> | void;
22
+ validateConfig?(config: T, integration?: IIntegration<T>): Promise<void | IntegrationTestResult>;
11
23
  }
@@ -343,6 +343,8 @@ export interface SandboxBackendProtocol extends BackendProtocol {
343
343
  streamExecute?(command: string, onLine: (line: string) => void, options?: SandboxExecutionOptions): MaybePromise<ExecuteResponse>;
344
344
  /** Unique identifier for the sandbox backend instance */
345
345
  readonly id: string;
346
+ /** Canonical sandbox environment identifier bound to this backend */
347
+ readonly environmentId?: string | null;
346
348
  }
347
349
  /**
348
350
  * Type guard to check if a backend supports execution.
@@ -22,6 +22,12 @@ export declare abstract class BaseSandbox implements SandboxBackendProtocol {
22
22
  workingDirectory: string;
23
23
  /** Unique identifier for the sandbox backend */
24
24
  abstract readonly id: string;
25
+ /**
26
+ * Internal hook for file/search operations. Concrete backends can override
27
+ * this to distinguish "background helper commands" from user-facing shell
28
+ * execute calls.
29
+ */
30
+ protected executeOperation(command: string, options?: SandboxExecutionOptions): MaybePromise<ExecuteResponse>;
25
31
  /**
26
32
  * Execute a command in the sandbox.
27
33
  * This is the only method concrete implementations must provide.
@@ -1,26 +1,22 @@
1
- import { TSandboxProviderMeta } from "@metad/contracts";
2
- import { SandboxBackendProtocol } from "./protocol";
1
+ import { TSandboxProviderMeta, TSandboxWorkForType } from '@metad/contracts';
2
+ import { SandboxBackendProtocol } from './protocol';
3
3
  export type SandboxProviderCreateOptions = {
4
4
  /**
5
5
  * Working space directory for the sandbox instance
6
6
  */
7
7
  workingDirectory?: string;
8
8
  /**
9
- * Sandbox container environment identifier
9
+ * Canonical sandbox environment identifier that owns the container lifecycle.
10
10
  */
11
11
  environmentId?: string;
12
12
  /**
13
13
  * Tenant identifier
14
14
  */
15
15
  tenantId?: string;
16
- /**
17
- * User identifier
18
- */
19
- userId?: string;
20
- /**
21
- * Project identifier
22
- */
23
- projectId?: string;
16
+ workFor: {
17
+ type: TSandboxWorkForType;
18
+ id: string;
19
+ };
24
20
  };
25
21
  export interface ISandboxProvider<T extends SandboxBackendProtocol = SandboxBackendProtocol> {
26
22
  type: string;