@vorionsys/atsf-core 0.2.2 → 0.2.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/CHANGELOG.md +3 -3
- package/README.md +77 -11
- package/dist/api/server.d.ts +4 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +3 -3
- package/dist/api/server.js.map +1 -1
- package/dist/basis/parser.d.ts +14 -14
- package/dist/common/adapters.d.ts +16 -9
- package/dist/common/adapters.d.ts.map +1 -1
- package/dist/common/adapters.js +69 -58
- package/dist/common/adapters.js.map +1 -1
- package/dist/common/config.d.ts +4 -3
- package/dist/common/config.d.ts.map +1 -1
- package/dist/common/config.js +2 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/types.d.ts +3 -3
- package/dist/crewai/callback.d.ts +91 -0
- package/dist/crewai/callback.d.ts.map +1 -0
- package/dist/crewai/callback.js +271 -0
- package/dist/crewai/callback.js.map +1 -0
- package/dist/crewai/executor.d.ts +226 -0
- package/dist/crewai/executor.d.ts.map +1 -0
- package/dist/crewai/executor.js +822 -0
- package/dist/crewai/executor.js.map +1 -0
- package/dist/crewai/index.d.ts +12 -0
- package/dist/crewai/index.d.ts.map +1 -0
- package/dist/crewai/index.js +12 -0
- package/dist/crewai/index.js.map +1 -0
- package/dist/crewai/tools.d.ts +21 -0
- package/dist/crewai/tools.d.ts.map +1 -0
- package/dist/crewai/tools.js +163 -0
- package/dist/crewai/tools.js.map +1 -0
- package/dist/crewai/types.d.ts +202 -0
- package/dist/crewai/types.d.ts.map +1 -0
- package/dist/crewai/types.js +9 -0
- package/dist/crewai/types.js.map +1 -0
- package/dist/enforce/index.d.ts +50 -2
- package/dist/enforce/index.d.ts.map +1 -1
- package/dist/enforce/index.js +73 -4
- package/dist/enforce/index.js.map +1 -1
- package/dist/enforce/trust-aware-enforcement-service.d.ts +121 -0
- package/dist/enforce/trust-aware-enforcement-service.d.ts.map +1 -0
- package/dist/enforce/trust-aware-enforcement-service.js +583 -0
- package/dist/enforce/trust-aware-enforcement-service.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/intent/index.d.ts +18 -3
- package/dist/intent/index.d.ts.map +1 -1
- package/dist/intent/index.js +37 -6
- package/dist/intent/index.js.map +1 -1
- package/dist/intent/persistent-intent-service.d.ts +68 -0
- package/dist/intent/persistent-intent-service.d.ts.map +1 -0
- package/dist/intent/persistent-intent-service.js +265 -0
- package/dist/intent/persistent-intent-service.js.map +1 -0
- package/dist/intent/supabase-intent-repository.d.ts +124 -0
- package/dist/intent/supabase-intent-repository.d.ts.map +1 -0
- package/dist/intent/supabase-intent-repository.js +404 -0
- package/dist/intent/supabase-intent-repository.js.map +1 -0
- package/dist/langchain/tools.d.ts.map +1 -1
- package/dist/langchain/tools.js +1 -3
- package/dist/langchain/tools.js.map +1 -1
- package/dist/layers/implementations/L0-request-format.d.ts +37 -0
- package/dist/layers/implementations/L0-request-format.d.ts.map +1 -0
- package/dist/layers/implementations/L0-request-format.js +216 -0
- package/dist/layers/implementations/L0-request-format.js.map +1 -0
- package/dist/layers/implementations/L1-input-size.d.ts +36 -0
- package/dist/layers/implementations/L1-input-size.d.ts.map +1 -0
- package/dist/layers/implementations/L1-input-size.js +150 -0
- package/dist/layers/implementations/L1-input-size.js.map +1 -0
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts +28 -0
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts.map +1 -0
- package/dist/layers/implementations/L2-charset-sanitizer.js +220 -0
- package/dist/layers/implementations/L2-charset-sanitizer.js.map +1 -0
- package/dist/layers/implementations/L3-schema-conformance.d.ts +47 -0
- package/dist/layers/implementations/L3-schema-conformance.d.ts.map +1 -0
- package/dist/layers/implementations/L3-schema-conformance.js +258 -0
- package/dist/layers/implementations/L3-schema-conformance.js.map +1 -0
- package/dist/layers/implementations/L4-injection-detector.d.ts +47 -0
- package/dist/layers/implementations/L4-injection-detector.d.ts.map +1 -0
- package/dist/layers/implementations/L4-injection-detector.js +256 -0
- package/dist/layers/implementations/L4-injection-detector.js.map +1 -0
- package/dist/layers/implementations/L5-rate-limiter.d.ts +51 -0
- package/dist/layers/implementations/L5-rate-limiter.d.ts.map +1 -0
- package/dist/layers/implementations/L5-rate-limiter.js +183 -0
- package/dist/layers/implementations/L5-rate-limiter.js.map +1 -0
- package/dist/layers/implementations/index.d.ts +16 -0
- package/dist/layers/implementations/index.d.ts.map +1 -0
- package/dist/layers/implementations/index.js +16 -0
- package/dist/layers/implementations/index.js.map +1 -0
- package/dist/persistence/sqlite.d.ts.map +1 -1
- package/dist/persistence/sqlite.js +4 -3
- package/dist/persistence/sqlite.js.map +1 -1
- package/dist/persistence/supabase.js +2 -2
- package/dist/persistence/supabase.js.map +1 -1
- package/dist/phase6/ceiling.js +5 -5
- package/dist/phase6/ceiling.js.map +1 -1
- package/dist/phase6/context.js +6 -6
- package/dist/phase6/context.js.map +1 -1
- package/dist/phase6/index.d.ts +1 -1
- package/dist/phase6/index.js +1 -1
- package/dist/phase6/role-gates.js +2 -2
- package/dist/phase6/role-gates.js.map +1 -1
- package/dist/phase6/types.d.ts +31 -30
- package/dist/phase6/types.d.ts.map +1 -1
- package/dist/phase6/types.js +17 -12
- package/dist/phase6/types.js.map +1 -1
- package/dist/phase6/weight-presets/canonical.d.ts +2 -2
- package/dist/phase6/weight-presets/canonical.js +2 -2
- package/dist/phase6/weight-presets/index.d.ts +1 -1
- package/dist/phase6/weight-presets/index.js +1 -1
- package/dist/phase6/weight-presets/merger.d.ts +1 -1
- package/dist/phase6/weight-presets/merger.js +1 -1
- package/dist/proof/merkle.d.ts +21 -0
- package/dist/proof/merkle.d.ts.map +1 -1
- package/dist/proof/merkle.js +92 -7
- package/dist/proof/merkle.js.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts +11 -9
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/kernel.js +25 -19
- package/dist/trust-engine/ceiling-enforcement/kernel.js.map +1 -1
- package/dist/trust-engine/decay-profiles.d.ts +37 -136
- package/dist/trust-engine/decay-profiles.d.ts.map +1 -1
- package/dist/trust-engine/decay-profiles.js +68 -178
- package/dist/trust-engine/decay-profiles.js.map +1 -1
- package/dist/trust-engine/index.d.ts +96 -63
- package/dist/trust-engine/index.d.ts.map +1 -1
- package/dist/trust-engine/index.js +183 -112
- package/dist/trust-engine/index.js.map +1 -1
- package/dist/trust-engine/phase6-types.d.ts +10 -3
- package/dist/trust-engine/phase6-types.d.ts.map +1 -1
- package/dist/trust-engine/phase6-types.js +19 -13
- package/dist/trust-engine/phase6-types.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,822 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-Aware CrewAI Executor
|
|
3
|
+
*
|
|
4
|
+
* Wraps CrewAI crews and tasks with trust-based access control.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
import { createLogger } from '../common/logger.js';
|
|
9
|
+
import { TrustInsufficientError } from '../common/types.js';
|
|
10
|
+
import { TRUST_LEVEL_NAMES } from '../trust-engine/index.js';
|
|
11
|
+
import { createCrewTrustCallback } from './callback.js';
|
|
12
|
+
const logger = createLogger({ component: 'crewai-executor' });
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// CREW AGENT EXECUTOR
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Trust-aware executor for a single crew agent
|
|
18
|
+
*
|
|
19
|
+
* Provides trust-gated task execution and delegation for CrewAI agents.
|
|
20
|
+
*/
|
|
21
|
+
export class CrewAgentExecutor {
|
|
22
|
+
trustEngine;
|
|
23
|
+
callback;
|
|
24
|
+
config;
|
|
25
|
+
constructor(trustEngine, config) {
|
|
26
|
+
this.trustEngine = trustEngine;
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.callback = createCrewTrustCallback(trustEngine, config);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the callback handler
|
|
32
|
+
*/
|
|
33
|
+
get callbackHandler() {
|
|
34
|
+
return this.callback;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the agent ID
|
|
38
|
+
*/
|
|
39
|
+
get agentId() {
|
|
40
|
+
return this.config.agentId;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the agent role
|
|
44
|
+
*/
|
|
45
|
+
get role() {
|
|
46
|
+
return this.config.role;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Initialize the executor
|
|
50
|
+
*/
|
|
51
|
+
async initialize() {
|
|
52
|
+
await this.callback.initialize();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if the agent has sufficient trust
|
|
56
|
+
*/
|
|
57
|
+
async checkTrust(requiredLevel) {
|
|
58
|
+
const minLevel = requiredLevel ?? this.config.minTrustLevel ?? 1;
|
|
59
|
+
const record = await this.trustEngine.getScore(this.config.agentId);
|
|
60
|
+
if (!record) {
|
|
61
|
+
return {
|
|
62
|
+
allowed: false,
|
|
63
|
+
agentId: this.config.agentId,
|
|
64
|
+
currentLevel: 0,
|
|
65
|
+
currentScore: 0,
|
|
66
|
+
requiredLevel: minLevel,
|
|
67
|
+
reason: 'Agent not initialized in trust engine',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const allowed = record.level >= minLevel;
|
|
71
|
+
return {
|
|
72
|
+
allowed,
|
|
73
|
+
agentId: this.config.agentId,
|
|
74
|
+
currentLevel: record.level,
|
|
75
|
+
currentScore: record.score,
|
|
76
|
+
requiredLevel: minLevel,
|
|
77
|
+
reason: allowed
|
|
78
|
+
? `Trust level ${TRUST_LEVEL_NAMES[record.level]} meets requirement`
|
|
79
|
+
: `Trust level ${TRUST_LEVEL_NAMES[record.level]} below required ${TRUST_LEVEL_NAMES[minLevel]}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Execute a task with trust gating
|
|
84
|
+
*
|
|
85
|
+
* @param task - Task configuration
|
|
86
|
+
* @param fn - The function to execute (typically the actual CrewAI task runner)
|
|
87
|
+
* @throws TrustInsufficientError if trust is too low
|
|
88
|
+
*/
|
|
89
|
+
async executeTask(task, fn) {
|
|
90
|
+
const requiredLevel = task.minTrustLevel ?? this.config.minTrustLevel ?? 1;
|
|
91
|
+
const trustCheck = await this.checkTrust(requiredLevel);
|
|
92
|
+
if (!trustCheck.allowed) {
|
|
93
|
+
logger.warn({
|
|
94
|
+
agentId: this.config.agentId,
|
|
95
|
+
taskId: task.taskId,
|
|
96
|
+
currentLevel: trustCheck.currentLevel,
|
|
97
|
+
requiredLevel: trustCheck.requiredLevel,
|
|
98
|
+
}, 'Task execution blocked due to insufficient trust');
|
|
99
|
+
throw new TrustInsufficientError(trustCheck.requiredLevel, trustCheck.currentLevel);
|
|
100
|
+
}
|
|
101
|
+
const runId = crypto.randomUUID();
|
|
102
|
+
const initialSignals = this.callback.signalsRecorded;
|
|
103
|
+
await this.callback.handleTaskStart(task.taskId, runId);
|
|
104
|
+
try {
|
|
105
|
+
const result = await fn();
|
|
106
|
+
await this.callback.handleTaskEnd(task.taskId, runId);
|
|
107
|
+
const finalRecord = await this.trustEngine.getScore(this.config.agentId);
|
|
108
|
+
logger.info({
|
|
109
|
+
agentId: this.config.agentId,
|
|
110
|
+
taskId: task.taskId,
|
|
111
|
+
signalsRecorded: this.callback.signalsRecorded - initialSignals,
|
|
112
|
+
finalScore: finalRecord?.score,
|
|
113
|
+
}, 'Trusted task execution completed');
|
|
114
|
+
return {
|
|
115
|
+
result,
|
|
116
|
+
taskId: task.taskId,
|
|
117
|
+
agentId: this.config.agentId,
|
|
118
|
+
trustCheck,
|
|
119
|
+
signalsRecorded: this.callback.signalsRecorded - initialSignals,
|
|
120
|
+
finalScore: finalRecord?.score ?? 0,
|
|
121
|
+
finalLevel: finalRecord?.level ?? 0,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
await this.callback.handleTaskError(task.taskId, error instanceof Error ? error : new Error(String(error)), runId);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Delegate a task to another agent with trust gating on both sides
|
|
131
|
+
*
|
|
132
|
+
* @param task - Task to delegate
|
|
133
|
+
* @param targetExecutor - The target agent's executor
|
|
134
|
+
* @param fn - The function to execute on the target agent
|
|
135
|
+
* @throws TrustInsufficientError if either agent lacks trust
|
|
136
|
+
*/
|
|
137
|
+
async delegateTask(task, targetExecutor, fn) {
|
|
138
|
+
if (this.config.allowDelegation === false) {
|
|
139
|
+
throw new Error(`Agent ${this.config.agentId} is not allowed to delegate tasks`);
|
|
140
|
+
}
|
|
141
|
+
// Check delegator trust
|
|
142
|
+
const delegatorCheck = await this.checkTrust();
|
|
143
|
+
if (!delegatorCheck.allowed) {
|
|
144
|
+
throw new TrustInsufficientError(delegatorCheck.requiredLevel, delegatorCheck.currentLevel);
|
|
145
|
+
}
|
|
146
|
+
// Check delegatee trust
|
|
147
|
+
const delegateeCheck = await targetExecutor.checkTrust(task.minTrustLevel ?? this.config.minTrustLevel ?? 1);
|
|
148
|
+
if (!delegateeCheck.allowed) {
|
|
149
|
+
throw new TrustInsufficientError(delegateeCheck.requiredLevel, delegateeCheck.currentLevel);
|
|
150
|
+
}
|
|
151
|
+
const runId = crypto.randomUUID();
|
|
152
|
+
await this.callback.handleDelegationStart(targetExecutor.agentId, task.taskId, runId);
|
|
153
|
+
try {
|
|
154
|
+
const result = await fn();
|
|
155
|
+
await this.callback.handleDelegationEnd(targetExecutor.agentId, task.taskId, runId);
|
|
156
|
+
logger.info({
|
|
157
|
+
from: this.config.agentId,
|
|
158
|
+
to: targetExecutor.agentId,
|
|
159
|
+
taskId: task.taskId,
|
|
160
|
+
}, 'Task delegation completed');
|
|
161
|
+
return {
|
|
162
|
+
result,
|
|
163
|
+
fromAgentId: this.config.agentId,
|
|
164
|
+
toAgentId: targetExecutor.agentId,
|
|
165
|
+
trustCheck: delegatorCheck,
|
|
166
|
+
delegateeTrustCheck: delegateeCheck,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
await this.callback.handleDelegationError(targetExecutor.agentId, task.taskId, error instanceof Error ? error : new Error(String(error)), runId);
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get current trust record for the agent
|
|
176
|
+
*/
|
|
177
|
+
async getTrustRecord() {
|
|
178
|
+
return this.trustEngine.getScore(this.config.agentId);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Manually record a positive signal
|
|
182
|
+
*/
|
|
183
|
+
async recordSuccess(type, value = 0.85) {
|
|
184
|
+
await this.trustEngine.recordSignal({
|
|
185
|
+
id: crypto.randomUUID(),
|
|
186
|
+
entityId: this.config.agentId,
|
|
187
|
+
type: `behavioral.${type}`,
|
|
188
|
+
value,
|
|
189
|
+
source: 'crewai-manual',
|
|
190
|
+
timestamp: new Date().toISOString(),
|
|
191
|
+
metadata: { role: this.config.role },
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Manually record a negative signal
|
|
196
|
+
*/
|
|
197
|
+
async recordFailure(type, value = 0.1) {
|
|
198
|
+
await this.trustEngine.recordSignal({
|
|
199
|
+
id: crypto.randomUUID(),
|
|
200
|
+
entityId: this.config.agentId,
|
|
201
|
+
type: `behavioral.${type}`,
|
|
202
|
+
value,
|
|
203
|
+
source: 'crewai-manual',
|
|
204
|
+
timestamp: new Date().toISOString(),
|
|
205
|
+
metadata: { role: this.config.role },
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// =============================================================================
|
|
210
|
+
// CREW EXECUTOR
|
|
211
|
+
// =============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Trust-aware crew executor
|
|
214
|
+
*
|
|
215
|
+
* Manages a crew of agents with collective trust governance.
|
|
216
|
+
* Ensures all agents meet minimum trust requirements before crew execution.
|
|
217
|
+
*/
|
|
218
|
+
export class CrewExecutor {
|
|
219
|
+
trustEngine;
|
|
220
|
+
config;
|
|
221
|
+
agents = new Map();
|
|
222
|
+
constructor(trustEngine, config) {
|
|
223
|
+
this.trustEngine = trustEngine;
|
|
224
|
+
this.config = {
|
|
225
|
+
crewId: config.crewId,
|
|
226
|
+
process: config.process ?? 'sequential',
|
|
227
|
+
minCrewTrust: config.minCrewTrust ?? 1,
|
|
228
|
+
maxTaskFailures: config.maxTaskFailures ?? 0,
|
|
229
|
+
recordCrewEvents: config.recordCrewEvents ?? true,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get the crew ID
|
|
234
|
+
*/
|
|
235
|
+
get crewId() {
|
|
236
|
+
return this.config.crewId;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get the execution process type
|
|
240
|
+
*/
|
|
241
|
+
get process() {
|
|
242
|
+
return this.config.process;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get all agent executors
|
|
246
|
+
*/
|
|
247
|
+
get agentExecutors() {
|
|
248
|
+
return Array.from(this.agents.values());
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Add an agent to the crew
|
|
252
|
+
*/
|
|
253
|
+
addAgent(executor) {
|
|
254
|
+
this.agents.set(executor.agentId, executor);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get an agent executor by ID
|
|
258
|
+
*/
|
|
259
|
+
getAgent(agentId) {
|
|
260
|
+
return this.agents.get(agentId);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Initialize all agents in the crew
|
|
264
|
+
*/
|
|
265
|
+
async initialize() {
|
|
266
|
+
for (const agent of this.agents.values()) {
|
|
267
|
+
await agent.initialize();
|
|
268
|
+
}
|
|
269
|
+
logger.info({ crewId: this.config.crewId, agentCount: this.agents.size }, 'Crew initialized');
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get the average trust level across all crew members
|
|
273
|
+
*/
|
|
274
|
+
async getCrewTrust() {
|
|
275
|
+
if (this.agents.size === 0) {
|
|
276
|
+
return { averageScore: 0, averageLevel: 0, allMeetMinimum: false };
|
|
277
|
+
}
|
|
278
|
+
let totalScore = 0;
|
|
279
|
+
let totalLevel = 0;
|
|
280
|
+
let allMeet = true;
|
|
281
|
+
for (const agent of this.agents.values()) {
|
|
282
|
+
const record = await this.trustEngine.getScore(agent.agentId);
|
|
283
|
+
const score = record?.score ?? 0;
|
|
284
|
+
const level = record?.level ?? 0;
|
|
285
|
+
totalScore += score;
|
|
286
|
+
totalLevel += level;
|
|
287
|
+
if (level < this.config.minCrewTrust) {
|
|
288
|
+
allMeet = false;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
averageScore: totalScore / this.agents.size,
|
|
293
|
+
averageLevel: totalLevel / this.agents.size,
|
|
294
|
+
allMeetMinimum: allMeet,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Execute a set of tasks with the crew
|
|
299
|
+
*
|
|
300
|
+
* Tasks are assigned to agents based on the configured process (sequential/hierarchical).
|
|
301
|
+
* All agents must meet the minimum crew trust requirement.
|
|
302
|
+
*
|
|
303
|
+
* @param tasks - Tasks to execute
|
|
304
|
+
* @param taskRunner - Function that runs a single task given task config and agent executor
|
|
305
|
+
* @throws TrustInsufficientError if any agent fails trust check
|
|
306
|
+
*/
|
|
307
|
+
async kickoff(tasks, taskRunner) {
|
|
308
|
+
// Check crew-level trust
|
|
309
|
+
const crewTrust = await this.getCrewTrust();
|
|
310
|
+
if (!crewTrust.allMeetMinimum) {
|
|
311
|
+
throw new TrustInsufficientError(this.config.minCrewTrust, Math.floor(crewTrust.averageLevel));
|
|
312
|
+
}
|
|
313
|
+
const agentList = Array.from(this.agents.values());
|
|
314
|
+
if (agentList.length === 0) {
|
|
315
|
+
throw new Error('Crew has no agents');
|
|
316
|
+
}
|
|
317
|
+
const results = [];
|
|
318
|
+
let tasksFailed = 0;
|
|
319
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
320
|
+
const task = tasks[i];
|
|
321
|
+
// Determine which agent handles this task
|
|
322
|
+
let agent;
|
|
323
|
+
if (task.assignedAgentId && this.agents.has(task.assignedAgentId)) {
|
|
324
|
+
agent = this.agents.get(task.assignedAgentId);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
// Round-robin assignment
|
|
328
|
+
agent = agentList[i % agentList.length];
|
|
329
|
+
}
|
|
330
|
+
try {
|
|
331
|
+
const taskResult = await agent.executeTask(task, () => taskRunner(task, agent));
|
|
332
|
+
results.push(taskResult);
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
tasksFailed++;
|
|
336
|
+
if (tasksFailed > this.config.maxTaskFailures) {
|
|
337
|
+
logger.warn({
|
|
338
|
+
crewId: this.config.crewId,
|
|
339
|
+
tasksFailed,
|
|
340
|
+
maxAllowed: this.config.maxTaskFailures,
|
|
341
|
+
}, 'Crew aborted due to too many task failures');
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
344
|
+
logger.warn({
|
|
345
|
+
crewId: this.config.crewId,
|
|
346
|
+
taskId: task.taskId,
|
|
347
|
+
agentId: agent.agentId,
|
|
348
|
+
error: error instanceof Error ? error.message : String(error),
|
|
349
|
+
}, 'Task failed within tolerance, continuing');
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
let totalSignals = 0;
|
|
353
|
+
for (const agent of this.agents.values()) {
|
|
354
|
+
totalSignals += agent.callbackHandler.signalsRecorded;
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
results,
|
|
358
|
+
crewId: this.config.crewId,
|
|
359
|
+
crewTrust: crewTrust.averageScore,
|
|
360
|
+
totalSignalsRecorded: totalSignals,
|
|
361
|
+
tasksFailed,
|
|
362
|
+
tasksCompleted: results.length,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// =============================================================================
|
|
367
|
+
// FACTORY FUNCTIONS
|
|
368
|
+
// =============================================================================
|
|
369
|
+
/**
|
|
370
|
+
* Create a trust-aware crew agent executor
|
|
371
|
+
*/
|
|
372
|
+
export function createCrewAgentExecutor(trustEngine, config) {
|
|
373
|
+
return new CrewAgentExecutor(trustEngine, config);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Create a trust-aware crew executor
|
|
377
|
+
*/
|
|
378
|
+
export function createCrewExecutor(trustEngine, config) {
|
|
379
|
+
return new CrewExecutor(trustEngine, config);
|
|
380
|
+
}
|
|
381
|
+
// =============================================================================
|
|
382
|
+
// TRUST-GATED CREW EXECUTOR
|
|
383
|
+
// =============================================================================
|
|
384
|
+
const gatedLogger = createLogger({ component: 'trust-gated-crew-executor' });
|
|
385
|
+
/**
|
|
386
|
+
* Trust-Gated Crew Executor
|
|
387
|
+
*
|
|
388
|
+
* High-level wrapper that composes TrustEngine + CrewExecutor + TrustAwareEnforcementService
|
|
389
|
+
* to provide a full intent -> enforce -> execute pipeline with live trust gating.
|
|
390
|
+
*
|
|
391
|
+
* Features:
|
|
392
|
+
* - Pre-task trust score checks with configurable thresholds
|
|
393
|
+
* - Optional enforcement service integration (intent -> enforce -> execute)
|
|
394
|
+
* - Automatic trust decay signals on task failures
|
|
395
|
+
* - Automatic trust recovery signals on task successes
|
|
396
|
+
* - Detailed logging of all trust decisions
|
|
397
|
+
* - Backwards-compatible: enforcement service is optional
|
|
398
|
+
*/
|
|
399
|
+
export class TrustGatedCrewExecutor {
|
|
400
|
+
trustEngine;
|
|
401
|
+
crewExecutor;
|
|
402
|
+
enforcementService;
|
|
403
|
+
config;
|
|
404
|
+
constructor(trustEngine, config, enforcementService) {
|
|
405
|
+
this.trustEngine = trustEngine;
|
|
406
|
+
this.enforcementService = enforcementService ?? null;
|
|
407
|
+
this.config = {
|
|
408
|
+
crew: config.crew,
|
|
409
|
+
agents: config.agents,
|
|
410
|
+
trustScoreThreshold: config.trustScoreThreshold ?? 200,
|
|
411
|
+
trustLevelThreshold: config.trustLevelThreshold ?? 1,
|
|
412
|
+
failureDecaySignalValue: config.failureDecaySignalValue ?? 0.1,
|
|
413
|
+
successRecoverySignalValue: config.successRecoverySignalValue ?? 0.85,
|
|
414
|
+
tenantId: config.tenantId ?? 'default',
|
|
415
|
+
enableEnforcement: config.enableEnforcement ?? true,
|
|
416
|
+
};
|
|
417
|
+
// Create the inner crew executor
|
|
418
|
+
this.crewExecutor = new CrewExecutor(trustEngine, config.crew);
|
|
419
|
+
// Create and add agent executors
|
|
420
|
+
for (const agentConfig of this.config.agents) {
|
|
421
|
+
const agentExecutor = new CrewAgentExecutor(trustEngine, agentConfig);
|
|
422
|
+
this.crewExecutor.addAgent(agentExecutor);
|
|
423
|
+
}
|
|
424
|
+
gatedLogger.info({
|
|
425
|
+
crewId: config.crew.crewId,
|
|
426
|
+
agentCount: config.agents.length,
|
|
427
|
+
trustScoreThreshold: this.config.trustScoreThreshold,
|
|
428
|
+
trustLevelThreshold: this.config.trustLevelThreshold,
|
|
429
|
+
enforcementEnabled: this.config.enableEnforcement && this.enforcementService !== null,
|
|
430
|
+
}, 'TrustGatedCrewExecutor created');
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Get the inner CrewExecutor
|
|
434
|
+
*/
|
|
435
|
+
get executor() {
|
|
436
|
+
return this.crewExecutor;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get the TrustEngine instance
|
|
440
|
+
*/
|
|
441
|
+
get engine() {
|
|
442
|
+
return this.trustEngine;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Get the crew ID
|
|
446
|
+
*/
|
|
447
|
+
get crewId() {
|
|
448
|
+
return this.crewExecutor.crewId;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Initialize all agents in the crew
|
|
452
|
+
*/
|
|
453
|
+
async initialize() {
|
|
454
|
+
await this.crewExecutor.initialize();
|
|
455
|
+
gatedLogger.info({ crewId: this.crewId }, 'TrustGatedCrewExecutor initialized');
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Check if an agent passes the trust gate for a task.
|
|
459
|
+
*
|
|
460
|
+
* Performs two checks:
|
|
461
|
+
* 1. Trust score threshold check (score >= configured threshold)
|
|
462
|
+
* 2. Trust level threshold check (level >= configured threshold)
|
|
463
|
+
*
|
|
464
|
+
* If enforcement service is available and enabled, also runs full enforcement.
|
|
465
|
+
*/
|
|
466
|
+
async checkTrustGate(agentId, task) {
|
|
467
|
+
const t0 = performance.now();
|
|
468
|
+
const record = await this.trustEngine.getScore(agentId);
|
|
469
|
+
if (!record) {
|
|
470
|
+
gatedLogger.warn({ agentId, taskId: task.taskId }, 'Trust gate denied: agent has no trust record');
|
|
471
|
+
return {
|
|
472
|
+
allowed: false,
|
|
473
|
+
trustScore: 0,
|
|
474
|
+
trustLevel: 0,
|
|
475
|
+
reason: `Agent ${agentId} has no trust record in the engine`,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
const currentScore = record.score;
|
|
479
|
+
const currentLevel = record.level;
|
|
480
|
+
// Check score threshold
|
|
481
|
+
if (currentScore < this.config.trustScoreThreshold) {
|
|
482
|
+
const reason = `Trust score ${currentScore} is below threshold ${this.config.trustScoreThreshold}`;
|
|
483
|
+
gatedLogger.warn({
|
|
484
|
+
agentId,
|
|
485
|
+
taskId: task.taskId,
|
|
486
|
+
currentScore,
|
|
487
|
+
threshold: this.config.trustScoreThreshold,
|
|
488
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
489
|
+
}, `Trust gate denied: ${reason}`);
|
|
490
|
+
return { allowed: false, trustScore: currentScore, trustLevel: currentLevel, reason };
|
|
491
|
+
}
|
|
492
|
+
// Check level threshold
|
|
493
|
+
const requiredLevel = task.minTrustLevel ?? this.config.trustLevelThreshold;
|
|
494
|
+
if (currentLevel < requiredLevel) {
|
|
495
|
+
const reason = `Trust level ${TRUST_LEVEL_NAMES[currentLevel]} (T${currentLevel}) is below required ${TRUST_LEVEL_NAMES[requiredLevel]} (T${requiredLevel})`;
|
|
496
|
+
gatedLogger.warn({
|
|
497
|
+
agentId,
|
|
498
|
+
taskId: task.taskId,
|
|
499
|
+
currentLevel,
|
|
500
|
+
requiredLevel,
|
|
501
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
502
|
+
}, `Trust gate denied: ${reason}`);
|
|
503
|
+
return { allowed: false, trustScore: currentScore, trustLevel: currentLevel, reason };
|
|
504
|
+
}
|
|
505
|
+
// If enforcement service is available and enabled, run full enforcement
|
|
506
|
+
if (this.enforcementService && this.config.enableEnforcement) {
|
|
507
|
+
const enforcementResult = await this.runEnforcement(agentId, task, currentScore, currentLevel);
|
|
508
|
+
if (enforcementResult) {
|
|
509
|
+
const tier = enforcementResult.tier;
|
|
510
|
+
if (tier === 'RED') {
|
|
511
|
+
const reason = `Enforcement denied (RED): ${enforcementResult.decision.denialReason ?? 'policy violation'}`;
|
|
512
|
+
gatedLogger.warn({
|
|
513
|
+
agentId,
|
|
514
|
+
taskId: task.taskId,
|
|
515
|
+
tier,
|
|
516
|
+
decisionId: enforcementResult.decision.id,
|
|
517
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
518
|
+
}, `Trust gate denied via enforcement: ${reason}`);
|
|
519
|
+
return {
|
|
520
|
+
allowed: false,
|
|
521
|
+
trustScore: currentScore,
|
|
522
|
+
trustLevel: currentLevel,
|
|
523
|
+
enforcementResult,
|
|
524
|
+
reason,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
if (tier === 'YELLOW') {
|
|
528
|
+
const reason = `Enforcement requires refinement (YELLOW): ${enforcementResult.decision.reasoning.join('; ')}`;
|
|
529
|
+
gatedLogger.info({
|
|
530
|
+
agentId,
|
|
531
|
+
taskId: task.taskId,
|
|
532
|
+
tier,
|
|
533
|
+
decisionId: enforcementResult.decision.id,
|
|
534
|
+
refinementOptions: enforcementResult.refinementOptions?.length ?? 0,
|
|
535
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
536
|
+
}, `Trust gate pending refinement: ${reason}`);
|
|
537
|
+
// YELLOW is treated as denied for automatic execution; callers can refine manually
|
|
538
|
+
return {
|
|
539
|
+
allowed: false,
|
|
540
|
+
trustScore: currentScore,
|
|
541
|
+
trustLevel: currentLevel,
|
|
542
|
+
enforcementResult,
|
|
543
|
+
reason,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
// GREEN - allowed
|
|
547
|
+
gatedLogger.info({
|
|
548
|
+
agentId,
|
|
549
|
+
taskId: task.taskId,
|
|
550
|
+
tier,
|
|
551
|
+
decisionId: enforcementResult.decision.id,
|
|
552
|
+
trustScore: currentScore,
|
|
553
|
+
trustLevel: currentLevel,
|
|
554
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
555
|
+
}, 'Trust gate allowed via enforcement (GREEN)');
|
|
556
|
+
return {
|
|
557
|
+
allowed: true,
|
|
558
|
+
trustScore: currentScore,
|
|
559
|
+
trustLevel: currentLevel,
|
|
560
|
+
enforcementResult,
|
|
561
|
+
reason: `Enforcement approved (GREEN): trust T${currentLevel} (${TRUST_LEVEL_NAMES[currentLevel]}), score ${currentScore}`,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// No enforcement service or enforcement disabled - use direct trust check
|
|
566
|
+
const reason = `Trust gate passed: T${currentLevel} (${TRUST_LEVEL_NAMES[currentLevel]}), score ${currentScore}`;
|
|
567
|
+
gatedLogger.info({
|
|
568
|
+
agentId,
|
|
569
|
+
taskId: task.taskId,
|
|
570
|
+
trustScore: currentScore,
|
|
571
|
+
trustLevel: currentLevel,
|
|
572
|
+
latencyMs: Math.round(performance.now() - t0),
|
|
573
|
+
}, reason);
|
|
574
|
+
return { allowed: true, trustScore: currentScore, trustLevel: currentLevel, reason };
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Execute a single task through the trust gate.
|
|
578
|
+
*
|
|
579
|
+
* Pipeline: check trust -> (optional) enforce -> execute -> record signals
|
|
580
|
+
*/
|
|
581
|
+
async executeGatedTask(task, taskRunner) {
|
|
582
|
+
const t0 = performance.now();
|
|
583
|
+
// Resolve agent
|
|
584
|
+
const agent = this.resolveAgent(task);
|
|
585
|
+
if (!agent) {
|
|
586
|
+
return {
|
|
587
|
+
allowed: false,
|
|
588
|
+
agentId: task.assignedAgentId ?? 'unassigned',
|
|
589
|
+
taskId: task.taskId,
|
|
590
|
+
trustScoreAtDecision: 0,
|
|
591
|
+
trustLevelAtDecision: 0,
|
|
592
|
+
reason: `No agent available for task ${task.taskId}`,
|
|
593
|
+
gatingLatencyMs: Math.round(performance.now() - t0),
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
// Check trust gate
|
|
597
|
+
const gateResult = await this.checkTrustGate(agent.agentId, task);
|
|
598
|
+
const gatingLatencyMs = Math.round(performance.now() - t0);
|
|
599
|
+
if (!gateResult.allowed) {
|
|
600
|
+
// Record failure signal for trust decay on denial
|
|
601
|
+
await this.recordTrustSignal(agent.agentId, 'behavioral.task_gated_denied', this.config.failureDecaySignalValue, { taskId: task.taskId, reason: gateResult.reason });
|
|
602
|
+
return {
|
|
603
|
+
allowed: false,
|
|
604
|
+
agentId: agent.agentId,
|
|
605
|
+
taskId: task.taskId,
|
|
606
|
+
trustScoreAtDecision: gateResult.trustScore,
|
|
607
|
+
trustLevelAtDecision: gateResult.trustLevel,
|
|
608
|
+
enforcementTier: gateResult.enforcementResult?.tier,
|
|
609
|
+
reason: gateResult.reason,
|
|
610
|
+
gatingLatencyMs,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
// Execute the task through the agent executor
|
|
614
|
+
try {
|
|
615
|
+
const taskResult = await agent.executeTask(task, () => taskRunner(task, agent));
|
|
616
|
+
// Record success signal for trust recovery
|
|
617
|
+
await this.recordTrustSignal(agent.agentId, 'behavioral.task_gated_success', this.config.successRecoverySignalValue, { taskId: task.taskId });
|
|
618
|
+
gatedLogger.info({
|
|
619
|
+
agentId: agent.agentId,
|
|
620
|
+
taskId: task.taskId,
|
|
621
|
+
finalScore: taskResult.finalScore,
|
|
622
|
+
finalLevel: taskResult.finalLevel,
|
|
623
|
+
gatingLatencyMs,
|
|
624
|
+
}, 'Trust-gated task completed successfully');
|
|
625
|
+
return {
|
|
626
|
+
allowed: true,
|
|
627
|
+
result: taskResult,
|
|
628
|
+
agentId: agent.agentId,
|
|
629
|
+
taskId: task.taskId,
|
|
630
|
+
trustScoreAtDecision: gateResult.trustScore,
|
|
631
|
+
trustLevelAtDecision: gateResult.trustLevel,
|
|
632
|
+
enforcementTier: gateResult.enforcementResult?.tier,
|
|
633
|
+
reason: gateResult.reason,
|
|
634
|
+
gatingLatencyMs,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
catch (error) {
|
|
638
|
+
// Record failure signal for trust decay
|
|
639
|
+
await this.recordTrustSignal(agent.agentId, 'behavioral.task_gated_failure', this.config.failureDecaySignalValue, {
|
|
640
|
+
taskId: task.taskId,
|
|
641
|
+
error: error instanceof Error ? error.message : String(error),
|
|
642
|
+
});
|
|
643
|
+
gatedLogger.warn({
|
|
644
|
+
agentId: agent.agentId,
|
|
645
|
+
taskId: task.taskId,
|
|
646
|
+
error: error instanceof Error ? error.message : String(error),
|
|
647
|
+
gatingLatencyMs,
|
|
648
|
+
}, 'Trust-gated task failed during execution');
|
|
649
|
+
throw error;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Execute a full crew kickoff with trust gating on every task.
|
|
654
|
+
*
|
|
655
|
+
* Unlike the inner CrewExecutor.kickoff(), this method:
|
|
656
|
+
* - Checks trust gate before each task individually
|
|
657
|
+
* - Skips tasks that fail the trust gate (instead of throwing)
|
|
658
|
+
* - Records trust signals after each success/failure
|
|
659
|
+
* - Returns a comprehensive result including denied tasks
|
|
660
|
+
*/
|
|
661
|
+
async kickoff(tasks, taskRunner) {
|
|
662
|
+
gatedLogger.info({ crewId: this.crewId, taskCount: tasks.length }, 'Trust-gated crew kickoff starting');
|
|
663
|
+
const taskResults = [];
|
|
664
|
+
let tasksCompleted = 0;
|
|
665
|
+
let tasksDeniedByTrust = 0;
|
|
666
|
+
let tasksFailed = 0;
|
|
667
|
+
for (const task of tasks) {
|
|
668
|
+
try {
|
|
669
|
+
const result = await this.executeGatedTask(task, taskRunner);
|
|
670
|
+
taskResults.push(result);
|
|
671
|
+
if (result.allowed && result.result) {
|
|
672
|
+
tasksCompleted++;
|
|
673
|
+
}
|
|
674
|
+
else if (!result.allowed) {
|
|
675
|
+
tasksDeniedByTrust++;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
tasksFailed++;
|
|
680
|
+
// Capture as a failed result rather than propagating
|
|
681
|
+
const agent = this.resolveAgent(task);
|
|
682
|
+
taskResults.push({
|
|
683
|
+
allowed: true, // it was allowed, but failed during execution
|
|
684
|
+
agentId: agent?.agentId ?? task.assignedAgentId ?? 'unknown',
|
|
685
|
+
taskId: task.taskId,
|
|
686
|
+
trustScoreAtDecision: 0,
|
|
687
|
+
trustLevelAtDecision: 0,
|
|
688
|
+
reason: `Task execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
689
|
+
gatingLatencyMs: 0,
|
|
690
|
+
});
|
|
691
|
+
// Check if we've exceeded max task failures
|
|
692
|
+
if (tasksFailed > (this.config.crew.maxTaskFailures ?? 0)) {
|
|
693
|
+
gatedLogger.warn({
|
|
694
|
+
crewId: this.crewId,
|
|
695
|
+
tasksFailed,
|
|
696
|
+
maxAllowed: this.config.crew.maxTaskFailures ?? 0,
|
|
697
|
+
}, 'Trust-gated crew aborted due to too many task failures');
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
gatedLogger.info({
|
|
703
|
+
crewId: this.crewId,
|
|
704
|
+
totalTasks: tasks.length,
|
|
705
|
+
tasksCompleted,
|
|
706
|
+
tasksDeniedByTrust,
|
|
707
|
+
tasksFailed,
|
|
708
|
+
}, 'Trust-gated crew kickoff completed');
|
|
709
|
+
return {
|
|
710
|
+
taskResults,
|
|
711
|
+
totalTasks: tasks.length,
|
|
712
|
+
tasksCompleted,
|
|
713
|
+
tasksDeniedByTrust,
|
|
714
|
+
tasksFailed,
|
|
715
|
+
crewId: this.crewId,
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
// ===========================================================================
|
|
719
|
+
// Private helpers
|
|
720
|
+
// ===========================================================================
|
|
721
|
+
/**
|
|
722
|
+
* Resolve the agent executor for a given task
|
|
723
|
+
*/
|
|
724
|
+
resolveAgent(task) {
|
|
725
|
+
if (task.assignedAgentId) {
|
|
726
|
+
return this.crewExecutor.getAgent(task.assignedAgentId);
|
|
727
|
+
}
|
|
728
|
+
// Return the first available agent as fallback
|
|
729
|
+
const agents = this.crewExecutor.agentExecutors;
|
|
730
|
+
return agents.length > 0 ? agents[0] : undefined;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Run enforcement pipeline: build intent -> call TrustAwareEnforcementService.decide()
|
|
734
|
+
*/
|
|
735
|
+
async runEnforcement(agentId, task, trustScore, trustLevel) {
|
|
736
|
+
if (!this.enforcementService)
|
|
737
|
+
return null;
|
|
738
|
+
try {
|
|
739
|
+
// Build a synthetic intent from the task
|
|
740
|
+
const intent = {
|
|
741
|
+
id: `crew-task-${task.taskId}-${crypto.randomUUID()}`,
|
|
742
|
+
entityId: agentId,
|
|
743
|
+
goal: task.description,
|
|
744
|
+
context: { taskId: task.taskId, crewId: this.crewId },
|
|
745
|
+
metadata: { source: 'trust-gated-crew-executor', expectedOutput: task.expectedOutput },
|
|
746
|
+
status: 'pending',
|
|
747
|
+
createdAt: new Date().toISOString(),
|
|
748
|
+
updatedAt: new Date().toISOString(),
|
|
749
|
+
actionType: 'execute',
|
|
750
|
+
dataSensitivity: 'CONFIDENTIAL',
|
|
751
|
+
reversibility: 'REVERSIBLE',
|
|
752
|
+
};
|
|
753
|
+
// Build a minimal passing evaluation (the trust check is what matters)
|
|
754
|
+
const evaluation = {
|
|
755
|
+
passed: true,
|
|
756
|
+
finalAction: 'allow',
|
|
757
|
+
rulesEvaluated: [],
|
|
758
|
+
violatedRules: [],
|
|
759
|
+
totalDurationMs: 0,
|
|
760
|
+
evaluatedAt: new Date().toISOString(),
|
|
761
|
+
};
|
|
762
|
+
const context = {
|
|
763
|
+
intent,
|
|
764
|
+
evaluation,
|
|
765
|
+
trustScore,
|
|
766
|
+
trustLevel,
|
|
767
|
+
tenantId: this.config.tenantId,
|
|
768
|
+
};
|
|
769
|
+
const result = await this.enforcementService.decide(context);
|
|
770
|
+
gatedLogger.debug({
|
|
771
|
+
agentId,
|
|
772
|
+
taskId: task.taskId,
|
|
773
|
+
tier: result.tier,
|
|
774
|
+
decisionId: result.decision.id,
|
|
775
|
+
}, 'Enforcement decision completed for trust-gated task');
|
|
776
|
+
return result;
|
|
777
|
+
}
|
|
778
|
+
catch (error) {
|
|
779
|
+
gatedLogger.error({
|
|
780
|
+
agentId,
|
|
781
|
+
taskId: task.taskId,
|
|
782
|
+
error: error instanceof Error ? error.message : String(error),
|
|
783
|
+
}, 'Enforcement service error during trust-gated execution; falling back to trust-only check');
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Record a trust signal to the engine
|
|
789
|
+
*/
|
|
790
|
+
async recordTrustSignal(agentId, type, value, metadata) {
|
|
791
|
+
try {
|
|
792
|
+
await this.trustEngine.recordSignal({
|
|
793
|
+
id: crypto.randomUUID(),
|
|
794
|
+
entityId: agentId,
|
|
795
|
+
type,
|
|
796
|
+
value,
|
|
797
|
+
source: 'trust-gated-crew-executor',
|
|
798
|
+
timestamp: new Date().toISOString(),
|
|
799
|
+
metadata: { ...metadata, crewId: this.crewId },
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
catch (error) {
|
|
803
|
+
gatedLogger.error({
|
|
804
|
+
agentId,
|
|
805
|
+
type,
|
|
806
|
+
value,
|
|
807
|
+
error: error instanceof Error ? error.message : String(error),
|
|
808
|
+
}, 'Failed to record trust signal');
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Create a TrustGatedCrewExecutor
|
|
814
|
+
*
|
|
815
|
+
* @param trustEngine - The TrustEngine instance for score lookups and signal recording
|
|
816
|
+
* @param config - Configuration for the gated executor
|
|
817
|
+
* @param enforcementService - Optional TrustAwareEnforcementService for full intent enforcement
|
|
818
|
+
*/
|
|
819
|
+
export function createTrustGatedCrewExecutor(trustEngine, config, enforcementService) {
|
|
820
|
+
return new TrustGatedCrewExecutor(trustEngine, config, enforcementService);
|
|
821
|
+
}
|
|
822
|
+
//# sourceMappingURL=executor.js.map
|