agent-swarm-kit 1.1.59 → 1.1.61
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/build/index.cjs +118 -15
- package/build/index.mjs +118 -15
- package/package.json +1 -1
- package/types.d.ts +72 -0
package/build/index.cjs
CHANGED
|
@@ -104,6 +104,7 @@ const validationServices$1 = {
|
|
|
104
104
|
computeValidationService: Symbol('computeValidationService'),
|
|
105
105
|
stateValidationService: Symbol('stateValidationService'),
|
|
106
106
|
pipelineValidationService: Symbol('pipelineValidationService'),
|
|
107
|
+
executionValidationService: Symbol('executionValidationService'),
|
|
107
108
|
};
|
|
108
109
|
const TYPES = {
|
|
109
110
|
...baseServices$1,
|
|
@@ -2443,27 +2444,16 @@ const nameToTitle = (name) => {
|
|
|
2443
2444
|
*/
|
|
2444
2445
|
const beginContext = (run) => (...args) => {
|
|
2445
2446
|
let fn = () => run(...args);
|
|
2447
|
+
if (ExecutionContextService.hasContext()) {
|
|
2448
|
+
const { clientId, executionId } = swarm$1.executionContextService.context;
|
|
2449
|
+
swarm$1.executionValidationService.incrementCount(executionId, clientId);
|
|
2450
|
+
}
|
|
2446
2451
|
if (MethodContextService.hasContext()) {
|
|
2447
2452
|
fn = MethodContextService.runOutOfContext(fn);
|
|
2448
2453
|
}
|
|
2449
2454
|
if (ExecutionContextService.hasContext()) {
|
|
2450
2455
|
fn = ExecutionContextService.runOutOfContext(fn);
|
|
2451
2456
|
}
|
|
2452
|
-
/*
|
|
2453
|
-
|
|
2454
|
-
// TODO: wait for asyncLocalStorage.disable() stability
|
|
2455
|
-
if (
|
|
2456
|
-
MethodContextService.hasContext() ||
|
|
2457
|
-
ExecutionContextService.hasContext()
|
|
2458
|
-
) {
|
|
2459
|
-
const resource = new AsyncResource("UNTRACKED");
|
|
2460
|
-
const result = resource.runInAsyncScope(() => run(...args));
|
|
2461
|
-
resource.emitDestroy();
|
|
2462
|
-
return result;
|
|
2463
|
-
}
|
|
2464
|
-
return run(...args);
|
|
2465
|
-
|
|
2466
|
-
*/
|
|
2467
2457
|
return fn();
|
|
2468
2458
|
};
|
|
2469
2459
|
|
|
@@ -3115,6 +3105,11 @@ const CC_ENABLE_OPERATOR_TIMEOUT = false;
|
|
|
3115
3105
|
* Disable fetch of data from all storages. Quite usefull for unit tests
|
|
3116
3106
|
*/
|
|
3117
3107
|
const CC_STORAGE_DISABLE_GET_DATA = false;
|
|
3108
|
+
/**
|
|
3109
|
+
* When the model run more than 10 nested tool call iterations including
|
|
3110
|
+
* navigations throw an exeption
|
|
3111
|
+
*/
|
|
3112
|
+
const CC_MAX_NESTED_EXECUTIONS = 10;
|
|
3118
3113
|
const GLOBAL_CONFIG = {
|
|
3119
3114
|
CC_TOOL_CALL_EXCEPTION_FLUSH_PROMPT,
|
|
3120
3115
|
CC_TOOL_CALL_EXCEPTION_RECOMPLETE_PROMPT,
|
|
@@ -3166,6 +3161,7 @@ const GLOBAL_CONFIG = {
|
|
|
3166
3161
|
CC_DEFAULT_CONNECT_OPERATOR,
|
|
3167
3162
|
CC_ENABLE_OPERATOR_TIMEOUT,
|
|
3168
3163
|
CC_STORAGE_DISABLE_GET_DATA,
|
|
3164
|
+
CC_MAX_NESTED_EXECUTIONS,
|
|
3169
3165
|
};
|
|
3170
3166
|
GLOBAL_CONFIG.CC_RESQUE_STRATEGY = "flush";
|
|
3171
3167
|
/**
|
|
@@ -5010,6 +5006,7 @@ const executeInternal = beginContext(async (content, clientId, agentName) => {
|
|
|
5010
5006
|
if (!isFinished) {
|
|
5011
5007
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
5012
5008
|
}
|
|
5009
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
5013
5010
|
}
|
|
5014
5011
|
}, {
|
|
5015
5012
|
clientId,
|
|
@@ -8846,6 +8843,13 @@ class SessionPublicService {
|
|
|
8846
8843
|
* @private
|
|
8847
8844
|
*/
|
|
8848
8845
|
this.perfService = inject(TYPES.perfService);
|
|
8846
|
+
/**
|
|
8847
|
+
* Service for execution validation to prevent the model to call the tools
|
|
8848
|
+
* recursively
|
|
8849
|
+
* @type {ExecutionValidationService}
|
|
8850
|
+
* @private
|
|
8851
|
+
*/
|
|
8852
|
+
this.executionValidationService = inject(TYPES.executionValidationService);
|
|
8849
8853
|
/**
|
|
8850
8854
|
* Session connection service instance, injected via DI, for underlying session operations.
|
|
8851
8855
|
* Provides core functionality (e.g., emit, execute) called by public methods, supporting ClientAgent’s session model.
|
|
@@ -9036,6 +9040,7 @@ class SessionPublicService {
|
|
|
9036
9040
|
if (!isFinished) {
|
|
9037
9041
|
this.perfService.endExecution(executionId, clientId, 0);
|
|
9038
9042
|
}
|
|
9043
|
+
this.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
9039
9044
|
}
|
|
9040
9045
|
}, {
|
|
9041
9046
|
clientId,
|
|
@@ -17682,6 +17687,96 @@ class PipelineValidationService {
|
|
|
17682
17687
|
}
|
|
17683
17688
|
}
|
|
17684
17689
|
|
|
17690
|
+
/**
|
|
17691
|
+
* @module ExecutionValidationService
|
|
17692
|
+
* @description Service for validating and managing execution counts for client sessions in a swarm context.
|
|
17693
|
+
*/
|
|
17694
|
+
/**
|
|
17695
|
+
* @class ExecutionValidationService
|
|
17696
|
+
* @description Manages execution count validation to prevent excessive nested executions within a swarm.
|
|
17697
|
+
*/
|
|
17698
|
+
class ExecutionValidationService {
|
|
17699
|
+
constructor() {
|
|
17700
|
+
/**
|
|
17701
|
+
* @private
|
|
17702
|
+
* @type {LoggerService}
|
|
17703
|
+
* @description Injected logger service for logging execution-related information.
|
|
17704
|
+
*/
|
|
17705
|
+
this.loggerService = inject(TYPES.loggerService);
|
|
17706
|
+
/**
|
|
17707
|
+
* @private
|
|
17708
|
+
* @type {SessionValidationService}
|
|
17709
|
+
* @description Injected session validation service for checking client sessions and swarm associations.
|
|
17710
|
+
*/
|
|
17711
|
+
this.sessionValidationService = inject(TYPES.sessionValidationService);
|
|
17712
|
+
/**
|
|
17713
|
+
* Retrieves a memoized set of execution IDs for a given client and swarm.
|
|
17714
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17715
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17716
|
+
* @returns {Set<ExecutionId>} A set containing execution IDs for the client and swarm.
|
|
17717
|
+
*/
|
|
17718
|
+
this.getExecutionCount = functoolsKit.memoize(([clientId, swarmName]) => `${clientId}-${swarmName}`, () => new Set());
|
|
17719
|
+
/**
|
|
17720
|
+
* Increments the execution count for a client and checks for excessive nested executions.
|
|
17721
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
17722
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17723
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17724
|
+
* @throws {Error} If the maximum nested execution limit is reached.
|
|
17725
|
+
* @returns {void}
|
|
17726
|
+
*/
|
|
17727
|
+
this.incrementCount = (executionId, clientId) => {
|
|
17728
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17729
|
+
this.loggerService.info("executionValidationService incrementCount", {
|
|
17730
|
+
clientId,
|
|
17731
|
+
executionId,
|
|
17732
|
+
});
|
|
17733
|
+
if (!this.sessionValidationService.hasSession(clientId)) {
|
|
17734
|
+
return;
|
|
17735
|
+
}
|
|
17736
|
+
const swarmName = this.sessionValidationService.getSwarm(clientId);
|
|
17737
|
+
const { size } = this.getExecutionCount(clientId, swarmName).add(executionId);
|
|
17738
|
+
if (size >= GLOBAL_CONFIG.CC_MAX_NESTED_EXECUTIONS) {
|
|
17739
|
+
const msg = `agent-swarm recursive execution prevented for clientId=${clientId} swarmName=${swarmName} executionId=${executionId} size=${size}`;
|
|
17740
|
+
console.error(msg);
|
|
17741
|
+
throw new Error(msg);
|
|
17742
|
+
}
|
|
17743
|
+
};
|
|
17744
|
+
/**
|
|
17745
|
+
* Resets the execution count for a client and swarm.
|
|
17746
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
17747
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17748
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17749
|
+
* @returns {void}
|
|
17750
|
+
*/
|
|
17751
|
+
this.decrementCount = (executionId, clientId, swarmName) => {
|
|
17752
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17753
|
+
this.loggerService.info("executionValidationService decrementCount", {
|
|
17754
|
+
clientId,
|
|
17755
|
+
executionId,
|
|
17756
|
+
swarmName,
|
|
17757
|
+
});
|
|
17758
|
+
if (!this.sessionValidationService.hasSession(clientId)) {
|
|
17759
|
+
return;
|
|
17760
|
+
}
|
|
17761
|
+
this.getExecutionCount(clientId, swarmName).delete(executionId);
|
|
17762
|
+
};
|
|
17763
|
+
/**
|
|
17764
|
+
* Clears the memoized execution count for a specific client and swarm.
|
|
17765
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17766
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17767
|
+
* @returns {void}
|
|
17768
|
+
*/
|
|
17769
|
+
this.dispose = (clientId, swarmName) => {
|
|
17770
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17771
|
+
this.loggerService.info("executionValidationService dispose", {
|
|
17772
|
+
clientId,
|
|
17773
|
+
swarmName,
|
|
17774
|
+
});
|
|
17775
|
+
this.getExecutionCount.clear(`${clientId}-${swarmName}`);
|
|
17776
|
+
};
|
|
17777
|
+
}
|
|
17778
|
+
}
|
|
17779
|
+
|
|
17685
17780
|
{
|
|
17686
17781
|
provide(TYPES.docService, () => new DocService());
|
|
17687
17782
|
provide(TYPES.busService, () => new BusService());
|
|
@@ -17757,6 +17852,7 @@ class PipelineValidationService {
|
|
|
17757
17852
|
provide(TYPES.computeValidationService, () => new ComputeValidationService());
|
|
17758
17853
|
provide(TYPES.stateValidationService, () => new StateValidationService());
|
|
17759
17854
|
provide(TYPES.pipelineValidationService, () => new PipelineValidationService());
|
|
17855
|
+
provide(TYPES.executionValidationService, () => new ExecutionValidationService());
|
|
17760
17856
|
}
|
|
17761
17857
|
|
|
17762
17858
|
const baseServices = {
|
|
@@ -17834,6 +17930,7 @@ const validationServices = {
|
|
|
17834
17930
|
computeValidationService: inject(TYPES.computeValidationService),
|
|
17835
17931
|
stateValidationService: inject(TYPES.stateValidationService),
|
|
17836
17932
|
pipelineValidationService: inject(TYPES.pipelineValidationService),
|
|
17933
|
+
executionValidationService: inject(TYPES.executionValidationService),
|
|
17837
17934
|
};
|
|
17838
17935
|
/** @inheritDoc */
|
|
17839
17936
|
const swarm = {
|
|
@@ -18366,6 +18463,7 @@ const executeForceInternal = beginContext(async (content, clientId) => {
|
|
|
18366
18463
|
if (!isFinished) {
|
|
18367
18464
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
18368
18465
|
}
|
|
18466
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
18369
18467
|
}
|
|
18370
18468
|
}, {
|
|
18371
18469
|
clientId,
|
|
@@ -20437,6 +20535,7 @@ const disposeConnection = beginContext(async (clientId, swarmName, methodName =
|
|
|
20437
20535
|
{
|
|
20438
20536
|
swarm$1.sessionValidationService.removeSession(clientId);
|
|
20439
20537
|
swarm$1.navigationValidationService.dispose(clientId, swarmName);
|
|
20538
|
+
swarm$1.executionValidationService.dispose(clientId, swarmName);
|
|
20440
20539
|
}
|
|
20441
20540
|
PersistMemoryAdapter.dispose(clientId);
|
|
20442
20541
|
});
|
|
@@ -20654,6 +20753,7 @@ const runStatelessInternal = beginContext(async (content, clientId, agentName) =
|
|
|
20654
20753
|
if (!isFinished) {
|
|
20655
20754
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
20656
20755
|
}
|
|
20756
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
20657
20757
|
}
|
|
20658
20758
|
}, {
|
|
20659
20759
|
clientId,
|
|
@@ -20715,6 +20815,7 @@ const runStatelessForceInternal = beginContext(async (content, clientId) => {
|
|
|
20715
20815
|
if (!isFinished) {
|
|
20716
20816
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
20717
20817
|
}
|
|
20818
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
20718
20819
|
}
|
|
20719
20820
|
}, {
|
|
20720
20821
|
clientId,
|
|
@@ -21013,6 +21114,7 @@ const complete = beginContext(async (content, clientId, swarmName, payload = nul
|
|
|
21013
21114
|
if (!isFinished) {
|
|
21014
21115
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
21015
21116
|
}
|
|
21117
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
21016
21118
|
}
|
|
21017
21119
|
}, {
|
|
21018
21120
|
clientId,
|
|
@@ -21074,6 +21176,7 @@ const sessionInternal = (clientId, swarmName, { onDispose = () => { } } = {}) =>
|
|
|
21074
21176
|
if (!isFinished) {
|
|
21075
21177
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
21076
21178
|
}
|
|
21179
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
21077
21180
|
}
|
|
21078
21181
|
}, {
|
|
21079
21182
|
clientId,
|
package/build/index.mjs
CHANGED
|
@@ -102,6 +102,7 @@ const validationServices$1 = {
|
|
|
102
102
|
computeValidationService: Symbol('computeValidationService'),
|
|
103
103
|
stateValidationService: Symbol('stateValidationService'),
|
|
104
104
|
pipelineValidationService: Symbol('pipelineValidationService'),
|
|
105
|
+
executionValidationService: Symbol('executionValidationService'),
|
|
105
106
|
};
|
|
106
107
|
const TYPES = {
|
|
107
108
|
...baseServices$1,
|
|
@@ -2441,27 +2442,16 @@ const nameToTitle = (name) => {
|
|
|
2441
2442
|
*/
|
|
2442
2443
|
const beginContext = (run) => (...args) => {
|
|
2443
2444
|
let fn = () => run(...args);
|
|
2445
|
+
if (ExecutionContextService.hasContext()) {
|
|
2446
|
+
const { clientId, executionId } = swarm$1.executionContextService.context;
|
|
2447
|
+
swarm$1.executionValidationService.incrementCount(executionId, clientId);
|
|
2448
|
+
}
|
|
2444
2449
|
if (MethodContextService.hasContext()) {
|
|
2445
2450
|
fn = MethodContextService.runOutOfContext(fn);
|
|
2446
2451
|
}
|
|
2447
2452
|
if (ExecutionContextService.hasContext()) {
|
|
2448
2453
|
fn = ExecutionContextService.runOutOfContext(fn);
|
|
2449
2454
|
}
|
|
2450
|
-
/*
|
|
2451
|
-
|
|
2452
|
-
// TODO: wait for asyncLocalStorage.disable() stability
|
|
2453
|
-
if (
|
|
2454
|
-
MethodContextService.hasContext() ||
|
|
2455
|
-
ExecutionContextService.hasContext()
|
|
2456
|
-
) {
|
|
2457
|
-
const resource = new AsyncResource("UNTRACKED");
|
|
2458
|
-
const result = resource.runInAsyncScope(() => run(...args));
|
|
2459
|
-
resource.emitDestroy();
|
|
2460
|
-
return result;
|
|
2461
|
-
}
|
|
2462
|
-
return run(...args);
|
|
2463
|
-
|
|
2464
|
-
*/
|
|
2465
2455
|
return fn();
|
|
2466
2456
|
};
|
|
2467
2457
|
|
|
@@ -3113,6 +3103,11 @@ const CC_ENABLE_OPERATOR_TIMEOUT = false;
|
|
|
3113
3103
|
* Disable fetch of data from all storages. Quite usefull for unit tests
|
|
3114
3104
|
*/
|
|
3115
3105
|
const CC_STORAGE_DISABLE_GET_DATA = false;
|
|
3106
|
+
/**
|
|
3107
|
+
* When the model run more than 10 nested tool call iterations including
|
|
3108
|
+
* navigations throw an exeption
|
|
3109
|
+
*/
|
|
3110
|
+
const CC_MAX_NESTED_EXECUTIONS = 10;
|
|
3116
3111
|
const GLOBAL_CONFIG = {
|
|
3117
3112
|
CC_TOOL_CALL_EXCEPTION_FLUSH_PROMPT,
|
|
3118
3113
|
CC_TOOL_CALL_EXCEPTION_RECOMPLETE_PROMPT,
|
|
@@ -3164,6 +3159,7 @@ const GLOBAL_CONFIG = {
|
|
|
3164
3159
|
CC_DEFAULT_CONNECT_OPERATOR,
|
|
3165
3160
|
CC_ENABLE_OPERATOR_TIMEOUT,
|
|
3166
3161
|
CC_STORAGE_DISABLE_GET_DATA,
|
|
3162
|
+
CC_MAX_NESTED_EXECUTIONS,
|
|
3167
3163
|
};
|
|
3168
3164
|
GLOBAL_CONFIG.CC_RESQUE_STRATEGY = "flush";
|
|
3169
3165
|
/**
|
|
@@ -5008,6 +5004,7 @@ const executeInternal = beginContext(async (content, clientId, agentName) => {
|
|
|
5008
5004
|
if (!isFinished) {
|
|
5009
5005
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
5010
5006
|
}
|
|
5007
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
5011
5008
|
}
|
|
5012
5009
|
}, {
|
|
5013
5010
|
clientId,
|
|
@@ -8844,6 +8841,13 @@ class SessionPublicService {
|
|
|
8844
8841
|
* @private
|
|
8845
8842
|
*/
|
|
8846
8843
|
this.perfService = inject(TYPES.perfService);
|
|
8844
|
+
/**
|
|
8845
|
+
* Service for execution validation to prevent the model to call the tools
|
|
8846
|
+
* recursively
|
|
8847
|
+
* @type {ExecutionValidationService}
|
|
8848
|
+
* @private
|
|
8849
|
+
*/
|
|
8850
|
+
this.executionValidationService = inject(TYPES.executionValidationService);
|
|
8847
8851
|
/**
|
|
8848
8852
|
* Session connection service instance, injected via DI, for underlying session operations.
|
|
8849
8853
|
* Provides core functionality (e.g., emit, execute) called by public methods, supporting ClientAgent’s session model.
|
|
@@ -9034,6 +9038,7 @@ class SessionPublicService {
|
|
|
9034
9038
|
if (!isFinished) {
|
|
9035
9039
|
this.perfService.endExecution(executionId, clientId, 0);
|
|
9036
9040
|
}
|
|
9041
|
+
this.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
9037
9042
|
}
|
|
9038
9043
|
}, {
|
|
9039
9044
|
clientId,
|
|
@@ -17680,6 +17685,96 @@ class PipelineValidationService {
|
|
|
17680
17685
|
}
|
|
17681
17686
|
}
|
|
17682
17687
|
|
|
17688
|
+
/**
|
|
17689
|
+
* @module ExecutionValidationService
|
|
17690
|
+
* @description Service for validating and managing execution counts for client sessions in a swarm context.
|
|
17691
|
+
*/
|
|
17692
|
+
/**
|
|
17693
|
+
* @class ExecutionValidationService
|
|
17694
|
+
* @description Manages execution count validation to prevent excessive nested executions within a swarm.
|
|
17695
|
+
*/
|
|
17696
|
+
class ExecutionValidationService {
|
|
17697
|
+
constructor() {
|
|
17698
|
+
/**
|
|
17699
|
+
* @private
|
|
17700
|
+
* @type {LoggerService}
|
|
17701
|
+
* @description Injected logger service for logging execution-related information.
|
|
17702
|
+
*/
|
|
17703
|
+
this.loggerService = inject(TYPES.loggerService);
|
|
17704
|
+
/**
|
|
17705
|
+
* @private
|
|
17706
|
+
* @type {SessionValidationService}
|
|
17707
|
+
* @description Injected session validation service for checking client sessions and swarm associations.
|
|
17708
|
+
*/
|
|
17709
|
+
this.sessionValidationService = inject(TYPES.sessionValidationService);
|
|
17710
|
+
/**
|
|
17711
|
+
* Retrieves a memoized set of execution IDs for a given client and swarm.
|
|
17712
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17713
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17714
|
+
* @returns {Set<ExecutionId>} A set containing execution IDs for the client and swarm.
|
|
17715
|
+
*/
|
|
17716
|
+
this.getExecutionCount = memoize(([clientId, swarmName]) => `${clientId}-${swarmName}`, () => new Set());
|
|
17717
|
+
/**
|
|
17718
|
+
* Increments the execution count for a client and checks for excessive nested executions.
|
|
17719
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
17720
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17721
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17722
|
+
* @throws {Error} If the maximum nested execution limit is reached.
|
|
17723
|
+
* @returns {void}
|
|
17724
|
+
*/
|
|
17725
|
+
this.incrementCount = (executionId, clientId) => {
|
|
17726
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17727
|
+
this.loggerService.info("executionValidationService incrementCount", {
|
|
17728
|
+
clientId,
|
|
17729
|
+
executionId,
|
|
17730
|
+
});
|
|
17731
|
+
if (!this.sessionValidationService.hasSession(clientId)) {
|
|
17732
|
+
return;
|
|
17733
|
+
}
|
|
17734
|
+
const swarmName = this.sessionValidationService.getSwarm(clientId);
|
|
17735
|
+
const { size } = this.getExecutionCount(clientId, swarmName).add(executionId);
|
|
17736
|
+
if (size >= GLOBAL_CONFIG.CC_MAX_NESTED_EXECUTIONS) {
|
|
17737
|
+
const msg = `agent-swarm recursive execution prevented for clientId=${clientId} swarmName=${swarmName} executionId=${executionId} size=${size}`;
|
|
17738
|
+
console.error(msg);
|
|
17739
|
+
throw new Error(msg);
|
|
17740
|
+
}
|
|
17741
|
+
};
|
|
17742
|
+
/**
|
|
17743
|
+
* Resets the execution count for a client and swarm.
|
|
17744
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
17745
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17746
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17747
|
+
* @returns {void}
|
|
17748
|
+
*/
|
|
17749
|
+
this.decrementCount = (executionId, clientId, swarmName) => {
|
|
17750
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17751
|
+
this.loggerService.info("executionValidationService decrementCount", {
|
|
17752
|
+
clientId,
|
|
17753
|
+
executionId,
|
|
17754
|
+
swarmName,
|
|
17755
|
+
});
|
|
17756
|
+
if (!this.sessionValidationService.hasSession(clientId)) {
|
|
17757
|
+
return;
|
|
17758
|
+
}
|
|
17759
|
+
this.getExecutionCount(clientId, swarmName).delete(executionId);
|
|
17760
|
+
};
|
|
17761
|
+
/**
|
|
17762
|
+
* Clears the memoized execution count for a specific client and swarm.
|
|
17763
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
17764
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
17765
|
+
* @returns {void}
|
|
17766
|
+
*/
|
|
17767
|
+
this.dispose = (clientId, swarmName) => {
|
|
17768
|
+
GLOBAL_CONFIG.CC_LOGGER_ENABLE_INFO &&
|
|
17769
|
+
this.loggerService.info("executionValidationService dispose", {
|
|
17770
|
+
clientId,
|
|
17771
|
+
swarmName,
|
|
17772
|
+
});
|
|
17773
|
+
this.getExecutionCount.clear(`${clientId}-${swarmName}`);
|
|
17774
|
+
};
|
|
17775
|
+
}
|
|
17776
|
+
}
|
|
17777
|
+
|
|
17683
17778
|
{
|
|
17684
17779
|
provide(TYPES.docService, () => new DocService());
|
|
17685
17780
|
provide(TYPES.busService, () => new BusService());
|
|
@@ -17755,6 +17850,7 @@ class PipelineValidationService {
|
|
|
17755
17850
|
provide(TYPES.computeValidationService, () => new ComputeValidationService());
|
|
17756
17851
|
provide(TYPES.stateValidationService, () => new StateValidationService());
|
|
17757
17852
|
provide(TYPES.pipelineValidationService, () => new PipelineValidationService());
|
|
17853
|
+
provide(TYPES.executionValidationService, () => new ExecutionValidationService());
|
|
17758
17854
|
}
|
|
17759
17855
|
|
|
17760
17856
|
const baseServices = {
|
|
@@ -17832,6 +17928,7 @@ const validationServices = {
|
|
|
17832
17928
|
computeValidationService: inject(TYPES.computeValidationService),
|
|
17833
17929
|
stateValidationService: inject(TYPES.stateValidationService),
|
|
17834
17930
|
pipelineValidationService: inject(TYPES.pipelineValidationService),
|
|
17931
|
+
executionValidationService: inject(TYPES.executionValidationService),
|
|
17835
17932
|
};
|
|
17836
17933
|
/** @inheritDoc */
|
|
17837
17934
|
const swarm = {
|
|
@@ -18364,6 +18461,7 @@ const executeForceInternal = beginContext(async (content, clientId) => {
|
|
|
18364
18461
|
if (!isFinished) {
|
|
18365
18462
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
18366
18463
|
}
|
|
18464
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
18367
18465
|
}
|
|
18368
18466
|
}, {
|
|
18369
18467
|
clientId,
|
|
@@ -20435,6 +20533,7 @@ const disposeConnection = beginContext(async (clientId, swarmName, methodName =
|
|
|
20435
20533
|
{
|
|
20436
20534
|
swarm$1.sessionValidationService.removeSession(clientId);
|
|
20437
20535
|
swarm$1.navigationValidationService.dispose(clientId, swarmName);
|
|
20536
|
+
swarm$1.executionValidationService.dispose(clientId, swarmName);
|
|
20438
20537
|
}
|
|
20439
20538
|
PersistMemoryAdapter.dispose(clientId);
|
|
20440
20539
|
});
|
|
@@ -20652,6 +20751,7 @@ const runStatelessInternal = beginContext(async (content, clientId, agentName) =
|
|
|
20652
20751
|
if (!isFinished) {
|
|
20653
20752
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
20654
20753
|
}
|
|
20754
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
20655
20755
|
}
|
|
20656
20756
|
}, {
|
|
20657
20757
|
clientId,
|
|
@@ -20713,6 +20813,7 @@ const runStatelessForceInternal = beginContext(async (content, clientId) => {
|
|
|
20713
20813
|
if (!isFinished) {
|
|
20714
20814
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
20715
20815
|
}
|
|
20816
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
20716
20817
|
}
|
|
20717
20818
|
}, {
|
|
20718
20819
|
clientId,
|
|
@@ -21011,6 +21112,7 @@ const complete = beginContext(async (content, clientId, swarmName, payload = nul
|
|
|
21011
21112
|
if (!isFinished) {
|
|
21012
21113
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
21013
21114
|
}
|
|
21115
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
21014
21116
|
}
|
|
21015
21117
|
}, {
|
|
21016
21118
|
clientId,
|
|
@@ -21072,6 +21174,7 @@ const sessionInternal = (clientId, swarmName, { onDispose = () => { } } = {}) =>
|
|
|
21072
21174
|
if (!isFinished) {
|
|
21073
21175
|
swarm$1.perfService.endExecution(executionId, clientId, 0);
|
|
21074
21176
|
}
|
|
21177
|
+
swarm$1.executionValidationService.decrementCount(executionId, clientId, swarmName);
|
|
21075
21178
|
}
|
|
21076
21179
|
}, {
|
|
21077
21180
|
clientId,
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -6006,6 +6006,13 @@ declare class SessionPublicService implements TSessionConnectionService {
|
|
|
6006
6006
|
* @private
|
|
6007
6007
|
*/
|
|
6008
6008
|
private readonly perfService;
|
|
6009
|
+
/**
|
|
6010
|
+
* Service for execution validation to prevent the model to call the tools
|
|
6011
|
+
* recursively
|
|
6012
|
+
* @type {ExecutionValidationService}
|
|
6013
|
+
* @private
|
|
6014
|
+
*/
|
|
6015
|
+
private readonly executionValidationService;
|
|
6009
6016
|
/**
|
|
6010
6017
|
* Session connection service instance, injected via DI, for underlying session operations.
|
|
6011
6018
|
* Provides core functionality (e.g., emit, execute) called by public methods, supporting ClientAgent’s session model.
|
|
@@ -10597,6 +10604,61 @@ declare class PipelineValidationService {
|
|
|
10597
10604
|
validate: (pipelineName: PipelineName, source: string) => void;
|
|
10598
10605
|
}
|
|
10599
10606
|
|
|
10607
|
+
/**
|
|
10608
|
+
* @typedef {string} ExecutionId
|
|
10609
|
+
* @description A unique identifier for an execution instance.
|
|
10610
|
+
*/
|
|
10611
|
+
type ExecutionId = string;
|
|
10612
|
+
/**
|
|
10613
|
+
* @class ExecutionValidationService
|
|
10614
|
+
* @description Manages execution count validation to prevent excessive nested executions within a swarm.
|
|
10615
|
+
*/
|
|
10616
|
+
declare class ExecutionValidationService {
|
|
10617
|
+
/**
|
|
10618
|
+
* @private
|
|
10619
|
+
* @type {LoggerService}
|
|
10620
|
+
* @description Injected logger service for logging execution-related information.
|
|
10621
|
+
*/
|
|
10622
|
+
private readonly loggerService;
|
|
10623
|
+
/**
|
|
10624
|
+
* @private
|
|
10625
|
+
* @type {SessionValidationService}
|
|
10626
|
+
* @description Injected session validation service for checking client sessions and swarm associations.
|
|
10627
|
+
*/
|
|
10628
|
+
private readonly sessionValidationService;
|
|
10629
|
+
/**
|
|
10630
|
+
* Retrieves a memoized set of execution IDs for a given client and swarm.
|
|
10631
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
10632
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
10633
|
+
* @returns {Set<ExecutionId>} A set containing execution IDs for the client and swarm.
|
|
10634
|
+
*/
|
|
10635
|
+
getExecutionCount: ((clientId: string, swarmName: SwarmName) => Set<ExecutionId>) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, Set<string>>;
|
|
10636
|
+
/**
|
|
10637
|
+
* Increments the execution count for a client and checks for excessive nested executions.
|
|
10638
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
10639
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
10640
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
10641
|
+
* @throws {Error} If the maximum nested execution limit is reached.
|
|
10642
|
+
* @returns {void}
|
|
10643
|
+
*/
|
|
10644
|
+
incrementCount: (executionId: string, clientId: string) => void;
|
|
10645
|
+
/**
|
|
10646
|
+
* Resets the execution count for a client and swarm.
|
|
10647
|
+
* @param {string} executionId - The unique identifier for the execution.
|
|
10648
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
10649
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
10650
|
+
* @returns {void}
|
|
10651
|
+
*/
|
|
10652
|
+
decrementCount: (executionId: string, clientId: string, swarmName: SwarmName) => void;
|
|
10653
|
+
/**
|
|
10654
|
+
* Clears the memoized execution count for a specific client and swarm.
|
|
10655
|
+
* @param {string} clientId - The unique identifier for the client.
|
|
10656
|
+
* @param {SwarmName} swarmName - The name of the swarm associated with the client.
|
|
10657
|
+
* @returns {void}
|
|
10658
|
+
*/
|
|
10659
|
+
dispose: (clientId: string, swarmName: SwarmName) => void;
|
|
10660
|
+
}
|
|
10661
|
+
|
|
10600
10662
|
/**
|
|
10601
10663
|
* Interface defining the structure of the dependency injection container for the swarm system.
|
|
10602
10664
|
* Aggregates all services providing core functionality, context management, connectivity, schema definitions,
|
|
@@ -10911,6 +10973,11 @@ interface ISwarmDI {
|
|
|
10911
10973
|
* Ensures pipeline integrity via `PipelineValidationService`.
|
|
10912
10974
|
*/
|
|
10913
10975
|
pipelineValidationService: PipelineValidationService;
|
|
10976
|
+
/**
|
|
10977
|
+
* Service for validating nested executions
|
|
10978
|
+
* Used to prevent the model to call tools recursively
|
|
10979
|
+
*/
|
|
10980
|
+
executionValidationService: ExecutionValidationService;
|
|
10914
10981
|
}
|
|
10915
10982
|
|
|
10916
10983
|
/** @inheritDoc */
|
|
@@ -13752,6 +13819,11 @@ interface IGlobalConfig {
|
|
|
13752
13819
|
* Disable fetch of data from all storages. Quite usefull for unit tests
|
|
13753
13820
|
*/
|
|
13754
13821
|
CC_STORAGE_DISABLE_GET_DATA: boolean;
|
|
13822
|
+
/**
|
|
13823
|
+
* When the model run more than 10 nested tool call iterations including
|
|
13824
|
+
* navigations throw an exeption
|
|
13825
|
+
*/
|
|
13826
|
+
CC_MAX_NESTED_EXECUTIONS: number;
|
|
13755
13827
|
}
|
|
13756
13828
|
|
|
13757
13829
|
declare const GLOBAL_CONFIG: IGlobalConfig;
|